diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml new file mode 100644 index 0000000..759fd5a --- /dev/null +++ b/.github/workflows/CI.yml @@ -0,0 +1,48 @@ +# Copyright 2021-2026 The Khronos Group Inc. +# SPDX-License-Identifier: Apache-2.0 + +# GitHub CI file for Data Format spec +# See .gitlab-ci.yml for non-Actions comments and step dependencies. + +name: CI + +# Controls when the action will run. +on: + # Triggers the workflow on push or manual dispatch + push: + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + # When a pull request is opened from a local branch or fork + pull_request: + +jobs: + license-check: + name: Verify repository license compliance + runs-on: ubuntu-latest + container: khronosgroup/docker-images@sha256:f1ca671f3bdb10ad49e238b9bf28853088a21af49504498fc9084c9b4fea4762 + + steps: + - uses: actions/checkout@v5 + - name: REUSE license checker + run: reuse lint + + spec-generate: + name: Build the Data Format specification + runs-on: ubuntu-latest + container: khronosgroup/docker-images@sha256:f1ca671f3bdb10ad49e238b9bf28853088a21af49504498fc9084c9b4fea4762 + + steps: + - uses: actions/checkout@v5 + - name: Build the Data Format specification + run: make html pdf + - name: Package generated spec + # https://github.com/actions/upload-artifact#limitations + # upload-artifact would upload many different files individually to + # GitHub, which can take a lot of time. + # Tar it to upload just one large file instead. + run: tar -cvf spec-outputs.tar out + - name: Archive generated spec + uses: actions/upload-artifact@v7 + with: + name: spec-outputs + path: spec-outputs.tar diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..f92e0fa --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,42 @@ +# Copyright 2018-2026 The Khronos Group Inc. +# SPDX-License-Identifier: Apache-2.0 + +# Gitlab CI file for Data Format spec + +# All stages use the same Docker image, so there are no prerequisites +# Refer to the container by its SHA instead of the name, to prevent +# caching problems when updating the image. +# image: khronosgroup/docker-images:asciidoctor-spec.202506 +image: khronosgroup/docker-images@sha256:f1ca671f3bdb10ad49e238b9bf28853088a21af49504498fc9084c9b4fea4762 + +# Specify which gitlab runner to use +default: + tags: + - khrmedium + +# Verify repository license compliance +license-check: + stage: build + before_script: + # Nothing, all prerequisites are in the Docker image + script: + - reuse lint + allow_failure: false + +# Build the Data Format specification in HTML and PDF form +spec-generate: + stage: build + before_script: + # Nothing, all prerequisites are in the Docker image + script: + - NODE_PATH="/usr/lib/node_modules" + - export NODE_PATH + # Build the core-only spec, to catch some incorrect ifdef errors + - ./makeSpec -clean -spec core -genpath gencore QUIET= -j${nproc} -Otarget html manhtmlpages + # Build the HTML and PDF specs + - make html pdf + artifacts: + when: always + paths: + - out/ + expire_in: 1 week diff --git a/BUILD.adoc b/BUILD.adoc new file mode 100644 index 0000000..f1bc944 --- /dev/null +++ b/BUILD.adoc @@ -0,0 +1,211 @@ +// Copyright 2014-2026 The Khronos Group Inc. +// SPDX-License-Identifier: CC-BY-4.0 + += Khronos^(TM) Data Format Specification Build Instructions and Notes +:toc2: +:toclevels: 2 + +ifdef::env-github[] +:note-caption: :information_source: +endif::[] + + +NEW == Building the Specification + +The build system relies on +link:http://www.methods.co.nz/asciidoc/index.html[asciidoc], which is +available as part of many Linux distributions. +The PDF build subsequently depends on +link:http://dblatex.sourceforge.net[dblatex]. + +All forms of the specification may be built with a simple `make` +or `make all` command, with an output into the `out` directory. + +Use `make pdf` to build just the PDF specification. + +Use `make html` to build the HTML version of the specification +without inline images, which are accessed from the `out` directory; +this is smaller than the `inlinehtml` version. + +Use `make inlinehtml` to create the HTML and then generate a version +with inlined images, allowing it to be transferred as a single +file; note that the HTML still relies on access to +link:http://www.mathjax.org[MathJax] and is therefore not completely +stand-alone. +This build option requires PERL. +Since the inline HTML file is very large, `make compressedinlinehtml` +produces a gzip-compressed version of the output. + +`make header` copies the header file into the `out/headers` directory. + +`make clean` removes the contents out `out` and temporary files. + + + +[[intro]] +== Introduction + +This README describes how to build the Data Format Specification and other +related targets. + +It documents how to set up your build environment, build steps and targets, +and contains some troubleshooting advice. + + +[[building]] +== Building the Spec + +First, clone the Khronos GitHub repository containing the Data Format +Specification to your local Linux, Windows, or Mac PC. +The repository is located at https://github.com/KhronosGroup/DataFormat/ . + +Next, install all the necessary build tools (see <> below). +If you are using the <>, +which we strongly recommend, two ways to build using the image are: + + $ # assuming a Linux docker host + $ scripts/runDocker + + $ # assuming a Linux podman host + $ scripts/runPodman + +executed from the specification repository root. + +`runDocker` runs the Docker image with the cloned repository mounted under +/spec and accesses it as a specified user (set to your own user and group +ID), so that it does not get filled with files owned by another user. +The script leaves you inside a bash shell in the running image. +Execute the commands: + + $ cd /spec + $ make clean html pdf + +to build HTML5 and PDF specification outputs for the Data Format 1.3 +Specification. + +There are many other ways of using the image, including inside a Continuous +Integration pipeline; locally with persistent Docker volume storage of the +repository; and so on. + +If you are not using our Docker image to build with, and you have a +<> with the entire +toolchain installed, you can just invoke the same `make` commands from the +repository root. + +[NOTE] +==== +You can modify the `runDocker` script to change the `docker` command-line +options, but it is important to always use the Docker image specified in +that script, so you have the latest version of the spec toolchain. +==== + +[NOTE] +==== + * The `pdf` target takes a long time to run. + The `html` target just generates the HTML output, which is often all + that is needed for spec bugfixes not involving extensions. +==== + +These targets generate output documents in the directory +specified by the Makefile variable `$(OUTDIR)` (by default, `out/`). + +Data Format Specification:: + * `html` -- Single-file HTML5 in `$(OUTDIR)/html/dataformat.html`, and KaTeX + dependency in $(OUTDIR)/katex + * `pdf` -- PDF in `$(OUTDIR)/pdf/dataformat.pdf` + + +=== Images Used in the Specification + +All images used in the specification are in the `images/` directory in the +SVG or PNG format. +We recommend using Inkscape to modify or create new images, due to problems +using SVG files created by some other tools; especially in the PDF builds. + + +[[styles]] +== Our Stylesheets + +We use an HTML stylesheet `config/khronos.css` derived from the +https://asciidoctor.org/docs/produce-custom-themes-using-asciidoctor-stylesheet-factory/[Asciidoctor +stylesheet factory] "`colony`" theme, with the default Arial font family +replaced by the sans-serif https://en.wikipedia.org/wiki/Noto_fonts[Noto +font family]. + + +[[depends]] +== Software Dependencies + +This section describes the software components used by the Data Format +specification toolchain. + + +[[depends-docker]] +=== Khronos-Provided Docker Image + +Khronos has published a Docker image containing a Debian Linux distribution +with the entire toolchain preinstalled. + +We will occasionally update this image if needed, and we recommend people +needing to build from this repository use the Docker image. + +Docker installation is beyond the scope of this document. +Refer to link:https://docs.docker.com/get-docker/[the Docker website] for +information about installing Docker on Linux, Windows, and MacOS X. + +Another way to execute the Docker image is using the open source podman +container tool. +See link:https://podman.io/get-started[the Podman website] for information +about installing podman on Linux, Windows, and MacOS X. + +The build image is *named* `khronosgroup/docker-images:asciidoctor-spec`. +However, due to local and CI caching problems when this image is updated on +dockerhub, we use the SHA256 of the latest image update, rather than the +image name. +The SHA256 can be determined from + + $ git grep -h sha256: .gitlab-ci.yml + +which will print a line like + + image: khronosgroup/docker-images@sha256:5e021da240f12121f064d2135e06320c021ac231c9ae8abbf6205b6130deb58b + +Everything following `image: ` is the to use. +The first time you try to run a container with this , as is done +by the `runDocker` and `runPodman` scripts described above under <>, the image will be pulled from Dockerhub and cached +locally on your machine. + +This image is used to build Specification output documents or other Makefile +targets. + +[NOTE] +==== +When we update the image on Dockerhub, it is to add new components or update +versions of components used in the specification toolchain. +To save space, you may want to periodically purge old images using `docker +images` and `docker rmi -f`. +==== + + +[[depends-nondocker]] +=== Non-Docker Build Environments + +We do not actively support building outside of our Docker image, but it is +straightforward to reproduce our toolchain in a Debian (or similar APT-based +Linux) distribution by executing the same steps as the +link:https://github.com/KhronosGroup/DockerContainers/blob/main/asciidoctor-spec.Dockerfile[Dockerfile] +used to build our Docker image. + +It should be possible to apply the same steps in a Windows Subsystem for +Linux (WSL2) environment on Windows 10, as well. + +[NOTE] +==== +While you do not have to use our Docker image, we cannot support every +possible build environment. +The Docker image is a straightforward way to build the specification in most +modern desktop environments, without needing to install and update the spec +toolchain yourself. +==== diff --git a/CODE_OF_CONDUCT.adoc b/CODE_OF_CONDUCT.adoc new file mode 100644 index 0000000..8aa4b1a --- /dev/null +++ b/CODE_OF_CONDUCT.adoc @@ -0,0 +1,10 @@ +// Copyright 2018-2026 The Khronos Group Inc. +// SPDX-License-Identifier: CC-BY-4.0 + += Code of Conduct + +A reminder that this repository is managed by the Khronos Group. +Interactions here should follow the +https://www.khronos.org/about/code-of-conduct[Khronos Code of Conduct], +which prohibits aggressive or derogatory language. Please keep the +discussion friendly and civil. diff --git a/CONTRIBUTING.adoc b/CONTRIBUTING.adoc new file mode 100644 index 0000000..8cb75e5 --- /dev/null +++ b/CONTRIBUTING.adoc @@ -0,0 +1,39 @@ +// Copyright 2020-2026 The Khronos Group Inc. +// SPDX-License-Identifier: CC-BY-4.0 + += Contributing + +Contributions to the DataFormat repository are welcome. + +Contributions may be in the form of Issues proposing a change, or Pull +Requests containing fixes for, or additions to: + + * Specification text and other documentation + * Specification scripting / build toolchains and related infrastructure + +Please keep contributions focused on solving a single issue or bug. + + +== Copyright Notice and License Template + +If you are adding a new file, it must be under one of the following +licenses: + + * Creative Commons Attribution 4.0 International, for specification text + (for example, link:dataformat.adoc[`dataformat.adoc]) + * Apache 2.0, for all other changes (for example, + link:scripts/runDocker[`runDocker`]) + +We use a short license in each file consisting of just the copyright +statement and the SPDX license identifier of the license applying to that +file, and link to the full license text from +link:LICENSE.adoc[`LICENSE.adoc`]. + + +== Contributor License Agreement + +When you propose a pull request, you must execute the +link:https://www.khronos.org/legal/Khronos_mixed_repository_CLA[Khronos +Mixed Repository Contributor License Agreement], to confirm you own your +work and are granting Khronos the necessary permissions to redistribute it +under our licenses. diff --git a/COPYING.adoc b/COPYING.adoc new file mode 100644 index 0000000..75725d3 --- /dev/null +++ b/COPYING.adoc @@ -0,0 +1,67 @@ +// Copyright 2020-2026 The Khronos Group Inc. +// SPDX-License-Identifier: CC-BY-4.0 + += COPYING File for the KhronosGroup/DataFormat Project + +== Licenses + +The DataFormat repository uses several licenses. + +* The source files (in asciidoctor and other formats) for the DataFormat + Specification and supporting documentation are licensed under the Creative + Commons Attribution 4.0 International License (SPDX license identifier + "`CC-BY-4.0`"). +* Header files, scripts, and other tooling used or generated as part of the + build process are typically licensed under the Apache License, Version 2.0 + (SPDX license identifier "`Apache-2.0`"). +* There are a few remaining files adopted from other open source projects, + such as a copy of the KaTeX distribution. + Such files continue under their original MIT licenses, or in a few cases, + like link:scripts/htmldiff/htmldiff[`scripts/htmldiff/htmldiff`], had no + license statement. + We have not added SPDX license identifiers to such externally originated + files. + +Users outside Khronos who create and post DataFormat Specifications, whether +modified or not, should use the CC-BY-4.0 license on the *output* documents +(HTML, PDF, etc.) they generate. +This is the default when building the Specification. + + +== Frequently Asked Questions + +Q: Why are the HTML and PDF Specifications posted on Khronos' website under +a license which is neither CC-BY nor Apache-2.0? + +A: The Specifications posted by Khronos in the DataFormat Registry are +licensed under the proprietary Khronos Specification License. +Only these Specifications are Ratified by the Khronos Board of Promoters, +and therefore they are the only Specifications covered by the Khronos +Intellectual Property Rights Policy. + + +Q: Does Khronos allow the creation and distribution of modified versions of +the Data Format Specification, such as translations to other languages? + +A: Yes. Such modified Specifications, since they are not created by Khronos, +should be placed under the CC-BY license. If you believe your modifications +are of general interest, consider contributing them back by making a pull +request (PR) in the KhronosGroup/DataFormat repository. + + +Q: Can I contribute changes to the Data Format Specification? + +A: Yes, by opening an Issue or Pull Request (PR) on the +link:https://github.com/KhronosGroup/DataFormat[DataFormat] GitHub project. +You must execute a click-through Contributor License Agreement, which brings +your changes under the umbrella of the Khronos IP policy. + + +Q: Can you change the license on your files so they are compatible with my +license? + +A: If you *require* GPL compatibility for use of Apache-2.0 licensed files +in our repository, please raise an issue identifying the files and the +reason for the request, and we will consider changing those specific files +to a dual Apache 2.0 - MIT license. + diff --git a/LICENSE.adoc b/LICENSE.adoc new file mode 100644 index 0000000..740266b --- /dev/null +++ b/LICENSE.adoc @@ -0,0 +1,34 @@ +// Copyright 2020-2026 The Khronos Group Inc. +// SPDX-License-Identifier: CC-BY-4.0 + += LICENSE File for the KhronosGroup/Vulkan-Docs Project + +Files in this repository fall under one of these licenses: + + * SPDX license identifier: "`Apache-2.0 OR MIT`" + ** Apache License 2.0 OR MIT License + ** For scripts and XML which need to be usable in GPL-licensed projects. + + * SPDX license identifier: "`Apache-2.0`" + ** Apache License 2.0 + ** For other scripts + + * SPDX license identifier: "`CC-BY-4.0`" + ** Creative Commons Attribution 4.0 International + ** For specification source documents + + * SPDX license identifier: "`MIT`" + ** MIT License + ** For files copied from other MIT-licensed projects + + * SPDX license identifier: "`LicenseRef-MPLUS`" + ** M+ Font License + ** For fonts derived from the M+ Font Project + ** This license is open source, but not OSI approved + +Full license text of these licenses is available at: + + * Apache-2.0: https://opensource.org/licenses/Apache-2.0 + * MIT: https://opensource.org/licenses/MIT + * CC-BY-4.0: https://creativecommons.org/licenses/by/4.0/legalcode + * LicenseRef-MPLUS: https://osdn.net/softwaremap/trove_list.php?form_cat=370 diff --git a/LICENSES/Apache-2.0.txt b/LICENSES/Apache-2.0.txt new file mode 100644 index 0000000..4ed90b9 --- /dev/null +++ b/LICENSES/Apache-2.0.txt @@ -0,0 +1,208 @@ +Apache License + +Version 2.0, January 2004 + +http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, +AND DISTRIBUTION + + 1. Definitions. + + + +"License" shall mean the terms and conditions for use, reproduction, and distribution +as defined by Sections 1 through 9 of this document. + + + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + + + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct +or indirect, to cause the direction or management of such entity, whether +by contract or otherwise, or (ii) ownership of fifty percent (50%) or more +of the outstanding shares, or (iii) beneficial ownership of such entity. + + + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions +granted by this License. + + + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + + + +"Object" form shall mean any form resulting from mechanical transformation +or translation of a Source form, including but not limited to compiled object +code, generated documentation, and conversions to other media types. + + + +"Work" shall mean the work of authorship, whether in Source or Object form, +made available under the License, as indicated by a copyright notice that +is included in or attached to the work (an example is provided in the Appendix +below). + + + +"Derivative Works" shall mean any work, whether in Source or Object form, +that is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative +Works shall not include works that remain separable from, or merely link (or +bind by name) to the interfaces of, the Work and Derivative Works thereof. + + + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative +Works thereof, that is intentionally submitted to Licensor for inclusion in +the Work by the copyright owner or by an individual or Legal Entity authorized +to submit on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication +sent to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor +for the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + + + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently incorporated +within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this +License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable copyright license to reproduce, prepare +Derivative Works of, publicly display, publicly perform, sublicense, and distribute +the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, +each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) patent +license to make, have made, use, offer to sell, sell, import, and otherwise +transfer the Work, where such license applies only to those patent claims +licensable by such Contributor that are necessarily infringed by their Contribution(s) +alone or by combination of their Contribution(s) with the Work to which such +Contribution(s) was submitted. If You institute patent litigation against +any entity (including a cross-claim or counterclaim in a lawsuit) alleging +that the Work or a Contribution incorporated within the Work constitutes direct +or contributory patent infringement, then any patent licenses granted to You +under this License for that Work shall terminate as of the date such litigation +is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or +Derivative Works thereof in any medium, with or without modifications, and +in Source or Object form, provided that You meet the following conditions: + +(a) You must give any other recipients of the Work or Derivative Works a copy +of this License; and + +(b) You must cause any modified files to carry prominent notices stating that +You changed the files; and + +(c) You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source +form of the Work, excluding those notices that do not pertain to any part +of the Derivative Works; and + +(d) If the Work includes a "NOTICE" text file as part of its distribution, +then any Derivative Works that You distribute must include a readable copy +of the attribution notices contained within such NOTICE file, excluding those +notices that do not pertain to any part of the Derivative Works, in at least +one of the following places: within a NOTICE text file distributed as part +of the Derivative Works; within the Source form or documentation, if provided +along with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents +of the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works +that You distribute, alongside or as an addendum to the NOTICE text from the +Work, provided that such additional attribution notices cannot be construed +as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, +or distribution of Your modifications, or for any such Derivative Works as +a whole, provided Your use, reproduction, and distribution of the Work otherwise +complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any +Contribution intentionally submitted for inclusion in the Work by You to the +Licensor shall be under the terms and conditions of this License, without +any additional terms or conditions. Notwithstanding the above, nothing herein +shall supersede or modify the terms of any separate license agreement you +may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, +trademarks, service marks, or product names of the Licensor, except as required +for reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to +in writing, Licensor provides the Work (and each Contributor provides its +Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied, including, without limitation, any warranties +or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR +A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness +of using or redistributing the Work and assume any risks associated with Your +exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether +in tort (including negligence), contract, or otherwise, unless required by +applicable law (such as deliberate and grossly negligent acts) or agreed to +in writing, shall any Contributor be liable to You for damages, including +any direct, indirect, special, incidental, or consequential damages of any +character arising as a result of this License or out of the use or inability +to use the Work (including but not limited to damages for loss of goodwill, +work stoppage, computer failure or malfunction, or any and all other commercial +damages or losses), even if such Contributor has been advised of the possibility +of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work +or Derivative Works thereof, You may choose to offer, and charge a fee for, +acceptance of support, warranty, indemnity, or other liability obligations +and/or rights consistent with this License. However, in accepting such obligations, +You may act only on Your own behalf and on Your sole responsibility, not on +behalf of any other Contributor, and only if You agree to indemnify, defend, +and hold each Contributor harmless for any liability incurred by, or claims +asserted against, such Contributor by reason of your accepting any such warranty +or additional liability. END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own identifying +information. (Don't include the brackets!) The text should be enclosed in +the appropriate comment syntax for the file format. We also recommend that +a file or class name and description of purpose be included on the same "printed +page" as the copyright notice for easier identification within third-party +archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); + +you may not use this file except in compliance with the License. + +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software + +distributed under the License is distributed on an "AS IS" BASIS, + +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + +See the License for the specific language governing permissions and + +limitations under the License. diff --git a/LICENSES/CC-BY-4.0.txt b/LICENSES/CC-BY-4.0.txt new file mode 100644 index 0000000..3f92dfc --- /dev/null +++ b/LICENSES/CC-BY-4.0.txt @@ -0,0 +1,324 @@ +Creative Commons Attribution 4.0 International Creative Commons Corporation +("Creative Commons") is not a law firm and does not provide legal services +or legal advice. Distribution of Creative Commons public licenses does not +create a lawyer-client or other relationship. Creative Commons makes its licenses +and related information available on an "as-is" basis. Creative Commons gives +no warranties regarding its licenses, any material licensed under their terms +and conditions, or any related information. Creative Commons disclaims all +liability for damages resulting from their use to the fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and conditions +that creators and other rights holders may use to share original works of +authorship and other material subject to copyright and certain other rights +specified in the public license below. The following considerations are for +informational purposes only, are not exhaustive, and do not form part of our +licenses. + +Considerations for licensors: Our public licenses are intended for use by +those authorized to give the public permission to use material in ways otherwise +restricted by copyright and certain other rights. Our licenses are irrevocable. +Licensors should read and understand the terms and conditions of the license +they choose before applying it. Licensors should also secure all rights necessary +before applying our licenses so that the public can reuse the material as +expected. Licensors should clearly mark any material not subject to the license. +This includes other CC-licensed material, or material used under an exception +or limitation to copyright. More considerations for licensors : wiki.creativecommons.org/Considerations_for_licensors + +Considerations for the public: By using one of our public licenses, a licensor +grants the public permission to use the licensed material under specified +terms and conditions. If the licensor's permission is not necessary for any +reason–for example, because of any applicable exception or limitation to copyright–then +that use is not regulated by the license. Our licenses grant only permissions +under copyright and certain other rights that a licensor has authority to +grant. Use of the licensed material may still be restricted for other reasons, +including because others have copyright or other rights in the material. A +licensor may make special requests, such as asking that all changes be marked +or described. Although not required by our licenses, you are encouraged to +respect those requests where reasonable. More considerations for the public +: wiki.creativecommons.org/Considerations_for_licensees Creative Commons Attribution +4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree to +be bound by the terms and conditions of this Creative Commons Attribution +4.0 International Public License ("Public License"). To the extent this Public +License may be interpreted as a contract, You are granted the Licensed Rights +in consideration of Your acceptance of these terms and conditions, and the +Licensor grants You such rights in consideration of benefits the Licensor +receives from making the Licensed Material available under these terms and +conditions. + +Section 1 – Definitions. + +a. Adapted Material means material subject to Copyright and Similar Rights +that is derived from or based upon the Licensed Material and in which the +Licensed Material is translated, altered, arranged, transformed, or otherwise +modified in a manner requiring permission under the Copyright and Similar +Rights held by the Licensor. For purposes of this Public License, where the +Licensed Material is a musical work, performance, or sound recording, Adapted +Material is always produced where the Licensed Material is synched in timed +relation with a moving image. + +b. Adapter's License means the license You apply to Your Copyright and Similar +Rights in Your contributions to Adapted Material in accordance with the terms +and conditions of this Public License. + +c. Copyright and Similar Rights means copyright and/or similar rights closely +related to copyright including, without limitation, performance, broadcast, +sound recording, and Sui Generis Database Rights, without regard to how the +rights are labeled or categorized. For purposes of this Public License, the +rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. + +d. Effective Technological Measures means those measures that, in the absence +of proper authority, may not be circumvented under laws fulfilling obligations +under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, +and/or similar international agreements. + +e. Exceptions and Limitations means fair use, fair dealing, and/or any other +exception or limitation to Copyright and Similar Rights that applies to Your +use of the Licensed Material. + +f. Licensed Material means the artistic or literary work, database, or other +material to which the Licensor applied this Public License. + +g. Licensed Rights means the rights granted to You subject to the terms and +conditions of this Public License, which are limited to all Copyright and +Similar Rights that apply to Your use of the Licensed Material and that the +Licensor has authority to license. + +h. Licensor means the individual(s) or entity(ies) granting rights under this +Public License. + +i. Share means to provide material to the public by any means or process that +requires permission under the Licensed Rights, such as reproduction, public +display, public performance, distribution, dissemination, communication, or +importation, and to make material available to the public including in ways +that members of the public may access the material from a place and at a time +individually chosen by them. + +j. Sui Generis Database Rights means rights other than copyright resulting +from Directive 96/9/EC of the European Parliament and of the Council of 11 +March 1996 on the legal protection of databases, as amended and/or succeeded, +as well as other essentially equivalent rights anywhere in the world. + +k. You means the individual or entity exercising the Licensed Rights under +this Public License. Your has a corresponding meaning. + +Section 2 – Scope. + + a. License grant. + +1. Subject to the terms and conditions of this Public License, the Licensor +hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, +irrevocable license to exercise the Licensed Rights in the Licensed Material +to: + + A. reproduce and Share the Licensed Material, in whole or in part; and + + B. produce, reproduce, and Share Adapted Material. + +2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions +and Limitations apply to Your use, this Public License does not apply, and +You do not need to comply with its terms and conditions. + + 3. Term. The term of this Public License is specified in Section 6(a). + +4. Media and formats; technical modifications allowed. The Licensor authorizes +You to exercise the Licensed Rights in all media and formats whether now known +or hereafter created, and to make technical modifications necessary to do +so. The Licensor waives and/or agrees not to assert any right or authority +to forbid You from making technical modifications necessary to exercise the +Licensed Rights, including technical modifications necessary to circumvent +Effective Technological Measures. For purposes of this Public License, simply +making modifications authorized by this Section 2(a)(4) never produces Adapted +Material. + + 5. Downstream recipients. + +A. Offer from the Licensor – Licensed Material. Every recipient of the Licensed +Material automatically receives an offer from the Licensor to exercise the +Licensed Rights under the terms and conditions of this Public License. + +B. No downstream restrictions. You may not offer or impose any additional +or different terms or conditions on, or apply any Effective Technological +Measures to, the Licensed Material if doing so restricts exercise of the Licensed +Rights by any recipient of the Licensed Material. + +6. No endorsement. Nothing in this Public License constitutes or may be construed +as permission to assert or imply that You are, or that Your use of the Licensed +Material is, connected with, or sponsored, endorsed, or granted official status +by, the Licensor or others designated to receive attribution as provided in +Section 3(a)(1)(A)(i). + + b. Other rights. + +1. Moral rights, such as the right of integrity, are not licensed under this +Public License, nor are publicity, privacy, and/or other similar personality +rights; however, to the extent possible, the Licensor waives and/or agrees +not to assert any such rights held by the Licensor to the limited extent necessary +to allow You to exercise the Licensed Rights, but not otherwise. + +2. Patent and trademark rights are not licensed under this Public License. + +3. To the extent possible, the Licensor waives any right to collect royalties +from You for the exercise of the Licensed Rights, whether directly or through +a collecting society under any voluntary or waivable statutory or compulsory +licensing scheme. In all other cases the Licensor expressly reserves any right +to collect such royalties. + +Section 3 – License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the following +conditions. + + a. Attribution. + +1. If You Share the Licensed Material (including in modified form), You must: + +A. retain the following if it is supplied by the Licensor with the Licensed +Material: + +i. identification of the creator(s) of the Licensed Material and any others +designated to receive attribution, in any reasonable manner requested by the +Licensor (including by pseudonym if designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of warranties; + +v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable; + +B. indicate if You modified the Licensed Material and retain an indication +of any previous modifications; and + +C. indicate the Licensed Material is licensed under this Public License, and +include the text of, or the URI or hyperlink to, this Public License. + +2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner +based on the medium, means, and context in which You Share the Licensed Material. +For example, it may be reasonable to satisfy the conditions by providing a +URI or hyperlink to a resource that includes the required information. + +3. If requested by the Licensor, You must remove any of the information required +by Section 3(a)(1)(A) to the extent reasonably practicable. + +4. If You Share Adapted Material You produce, the Adapter's License You apply +must not prevent recipients of the Adapted Material from complying with this +Public License. + +Section 4 – Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that apply to +Your use of the Licensed Material: + +a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, +reuse, reproduce, and Share all or a substantial portion of the contents of +the database; + +b. if You include all or a substantial portion of the database contents in +a database in which You have Sui Generis Database Rights, then the database +in which You have Sui Generis Database Rights (but not its individual contents) +is Adapted Material; and + +c. You must comply with the conditions in Section 3(a) if You Share all or +a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not replace +Your obligations under this Public License where the Licensed Rights include +other Copyright and Similar Rights. + +Section 5 – Disclaimer of Warranties and Limitation of Liability. + +a. Unless otherwise separately undertaken by the Licensor, to the extent possible, +the Licensor offers the Licensed Material as-is and as-available, and makes +no representations or warranties of any kind concerning the Licensed Material, +whether express, implied, statutory, or other. This includes, without limitation, +warranties of title, merchantability, fitness for a particular purpose, non-infringement, +absence of latent or other defects, accuracy, or the presence or absence of +errors, whether or not known or discoverable. Where disclaimers of warranties +are not allowed in full or in part, this disclaimer may not apply to You. + +b. To the extent possible, in no event will the Licensor be liable to You +on any legal theory (including, without limitation, negligence) or otherwise +for any direct, special, indirect, incidental, consequential, punitive, exemplary, +or other losses, costs, expenses, or damages arising out of this Public License +or use of the Licensed Material, even if the Licensor has been advised of +the possibility of such losses, costs, expenses, or damages. Where a limitation +of liability is not allowed in full or in part, this limitation may not apply +to You. + +c. The disclaimer of warranties and limitation of liability provided above +shall be interpreted in a manner that, to the extent possible, most closely +approximates an absolute disclaimer and waiver of all liability. + +Section 6 – Term and Termination. + +a. This Public License applies for the term of the Copyright and Similar Rights +licensed here. However, if You fail to comply with this Public License, then +Your rights under this Public License terminate automatically. + +b. Where Your right to use the Licensed Material has terminated under Section +6(a), it reinstates: + +1. automatically as of the date the violation is cured, provided it is cured +within 30 days of Your discovery of the violation; or + + 2. upon express reinstatement by the Licensor. + +c. For the avoidance of doubt, this Section 6(b) does not affect any right +the Licensor may have to seek remedies for Your violations of this Public +License. + +d. For the avoidance of doubt, the Licensor may also offer the Licensed Material +under separate terms or conditions or stop distributing the Licensed Material +at any time; however, doing so will not terminate this Public License. + + e. Sections 1, 5, 6, 7, and 8 survive termination of this Public License. + +Section 7 – Other Terms and Conditions. + +a. The Licensor shall not be bound by any additional or different terms or +conditions communicated by You unless expressly agreed. + +b. Any arrangements, understandings, or agreements regarding the Licensed +Material not stated herein are separate from and independent of the terms +and conditions of this Public License. + +Section 8 – Interpretation. + +a. For the avoidance of doubt, this Public License does not, and shall not +be interpreted to, reduce, limit, restrict, or impose conditions on any use +of the Licensed Material that could lawfully be made without permission under +this Public License. + +b. To the extent possible, if any provision of this Public License is deemed +unenforceable, it shall be automatically reformed to the minimum extent necessary +to make it enforceable. If the provision cannot be reformed, it shall be severed +from this Public License without affecting the enforceability of the remaining +terms and conditions. + +c. No term or condition of this Public License will be waived and no failure +to comply consented to unless expressly agreed to by the Licensor. + +d. Nothing in this Public License constitutes or may be interpreted as a limitation +upon, or waiver of, any privileges and immunities that apply to the Licensor +or You, including from the legal processes of any jurisdiction or authority. + +Creative Commons is not a party to its public licenses. Notwithstanding, Creative +Commons may elect to apply one of its public licenses to material it publishes +and in those instances will be considered the "Licensor." The text of the +Creative Commons public licenses is dedicated to the public domain under the +CC0 Public Domain Dedication. Except for the limited purpose of indicating +that material is shared under a Creative Commons public license or as otherwise +permitted by the Creative Commons policies published at creativecommons.org/policies, +Creative Commons does not authorize the use of the trademark "Creative Commons" +or any other trademark or logo of Creative Commons without its prior written +consent including, without limitation, in connection with any unauthorized +modifications to any of its public licenses or any other arrangements, understandings, +or agreements concerning use of licensed material. For the avoidance of doubt, +this paragraph does not form part of the public licenses. + +Creative Commons may be contacted at creativecommons.org. diff --git a/LICENSES/LicenseRef-KhronosSpecCopyright.adoc b/LICENSES/LicenseRef-KhronosSpecCopyright.adoc new file mode 100644 index 0000000..e3db2fe --- /dev/null +++ b/LICENSES/LicenseRef-KhronosSpecCopyright.adoc @@ -0,0 +1,136 @@ +Copyright 2014-2026 The Khronos Group Inc. + +This Specification is protected by copyright laws and contains material +proprietary to Khronos. Except as described by these terms, it or any +components may not be reproduced, republished, distributed, transmitted, +displayed, broadcast or otherwise exploited in any manner without the +express prior written permission of Khronos. + +Khronos grants a conditional copyright license to use and reproduce the +unmodified Specification for any purpose, without fee or royalty, EXCEPT no +licenses to any patent, trademark or other intellectual property rights are +granted under these terms. + +Khronos makes no, and expressly disclaims any, representations or +warranties, express or implied, regarding this Specification, including, +without limitation: merchantability, fitness for a particular purpose, +non-infringement of any intellectual property, correctness, accuracy, +completeness, timeliness, and reliability. Under no circumstances will +Khronos, or any of its Promoters, Contributors or Members, or their +respective partners, officers, directors, employees, agents or +representatives be liable for any damages, whether direct, indirect, special +or consequential damages for lost revenues, lost profits, or otherwise, +arising from or in connection with these materials. + +// "Ratified Specifications" sections + +// Specifications that contain no non-ratified extensions +ifdef::ratified_core_spec[] +This Specification has been created under the Khronos Intellectual Property +Rights Policy, which is Attachment A of the Khronos Group Membership +Agreement available at https://www.khronos.org/files/member_agreement.pdf. +Parties desiring to implement the Specification and make use of Khronos +trademarks in relation to that implementation, and receive reciprocal patent +license protection under the Khronos Intellectual Property Rights Policy +must become Adopters and confirm the implementation as conformant under the +process defined by Khronos for this Specification; see +https://www.khronos.org/adopters. +endif::ratified_core_spec[] + +// Specifications that include non-ratified extensions +ifndef::ratified_core_spec[] + +ifndef::VKSC_VERSION_1_0[] +:apinameCR: Vulkan +:apiUrlCore: https://registry.khronos.org/vulkan/specs/1.3/html/vkspec.html +:apiUrlKHR: https://registry.khronos.org/vulkan/specs/1.3-khr-extensions/html/vkspec.html +endif::VKSC_VERSION_1_0[] + +ifdef::VKSC_VERSION_1_0[] +:apinameCR: Vulkan SC +:apiUrlCore: https://registry.khronos.org/vulkansc/specs/1.0/html/vkspec.html +:apiUrlKHR: https://registry.khronos.org/vulkansc/specs/1.0-khr-extensions/html/vkspec.html +endif::VKSC_VERSION_1_0[] + +This document contains extensions which are not ratified by Khronos, and as +such is not a ratified Specification, though it contains text from (and is a +superset of) the ratified {apinameCR} Specification. The ratified versions +of the {apinameCR} Specification can be found at {apiUrlCore} (core only) +ifndef::VKSC_VERSION_1_0[] +and {apiUrlKHR} (core with all ratified extensions) +endif::VKSC_VERSION_1_0[] +. +endif::ratified_core_spec[] + +// "Successor Specification" section + +This Specification contains substantially unmodified functionality from, and +is a successor to, Khronos specifications including +ifdef::VKSC_VERSION_1_0[Vulkan, OpenGL SC] +OpenGL, OpenGL ES and OpenCL. + +// "Normative Wording" section + +The Khronos Intellectual Property Rights Policy defines the terms 'Scope', +'Compliant Portion', and 'Necessary Patent Claims'. + +Some parts of this Specification are purely informative and so are EXCLUDED +the Scope of this Specification. The <> section of +the <> defines how these parts of the Specification are +identified. + +Where this Specification uses <>, defined in the <> or otherwise, +that refer to enabling technologies that are not expressly set forth in this +Specification, those enabling technologies are EXCLUDED from the Scope of +this Specification. For clarity, enabling technologies not disclosed with +particularity in this Specification (e.g. semiconductor manufacturing +technology, hardware architecture, processor architecture or +microarchitecture, memory architecture, compiler technology, object oriented +technology, basic operating system technology, compression technology, +algorithms, and so on) are NOT to be considered expressly set forth; only +those application program interfaces and data structures disclosed with +particularity are included in the Scope of this Specification. + +For purposes of the Khronos Intellectual Property Rights Policy as it +relates to the definition of Necessary Patent Claims, all recommended or +optional features, behaviors and functionality set forth in this +Specification, if implemented, are considered to be included as Compliant +Portions. + +// "Normative References" section + +Where this Specification identifies specific sections of external +references, only those specifically identified sections define +<> +functionality. The Khronos Intellectual Property Rights Policy excludes +external references to materials and associated enabling technology not +created by Khronos from the Scope of this Specification, and any licenses +that may be required to implement such referenced materials and associated +technologies must be obtained separately and may involve royalty payments. + +Khronos and Vulkan are registered trademarks, and SPIR-V is a trademark of +The Khronos Group Inc. OpenCL is a trademark of Apple Inc., used under +license by Khronos. OpenGL is a registered trademark and the OpenGL ES logo +is a trademark of Hewlett Packard Enterprise, used under license by Khronos. +ASTC is a trademark of ARM Holdings PLC. All other product names, +trademarks, and/or company names are used solely for identification and +belong to their respective owners. + +// This is version V10_Feb23 of the Khronos Specification Copyright License +// Header, adapted for asciidoc markup and for the specific requirements of +// the Vulkan Specification: +// +// - The "Ratified Specifications" language is surrounding by mutually +// exclusive conditional directives, allowing either form to be included +// in the output Specifications depending on which extension(s) they are +// built with. The non-ratified section includes links to the ratified +// Vulkan 1.3 Specifications in the Vulkan Registry. +// - The "Successor Specification" section cites OpenGL, OpenGL ES, and +// OpenCL. +// - The "Normative Wording" section links to the Vulkan Specification +// introduction instead of the "[Document Conventions]" placeholder, and +// links to sections describing technical terminology and the glossary. +// - The "Normative References" section links to the "Normative References" +// section of the Specification. +// - The trademarks section cites only those trademarks relevant to Vulkan. diff --git a/LICENSES/MIT.txt b/LICENSES/MIT.txt new file mode 100644 index 0000000..204b93d --- /dev/null +++ b/LICENSES/MIT.txt @@ -0,0 +1,19 @@ +MIT License Copyright (c) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Makefile b/Makefile index a929b28..a6c305b 100644 --- a/Makefile +++ b/Makefile @@ -1,79 +1,198 @@ -# Copyright (c) 2014-2019 The Khronos Group Inc. -# Copyright notice at https://www.khronos.org/registry/speccopyright.html -all: compressedinlinehtml pdf header - -XMLLINT = --no-xmllint - -A2XOPTS = -a mathjax \ - --asciidoc-opts="-f config/mathjax-docbook.conf" \ - --xsltproc-opts="--param generate.consistent.ids 1" \ - $(XMLLINT) $(VERBOSE) --icons - -sources := df.txt \ - df-docinfo.xml \ - conversions.txt \ - conversionintro.txt \ - transferfunctions.txt \ - primaries.txt \ - colormodels.txt \ - quantization.txt \ - compformats.txt \ - compintro.txt \ - s3tc.txt \ - rgtc.txt \ - bptc.txt \ - etc1.txt \ - etc2.txt \ - astc.txt \ - pvrtc.txt \ - references.txt - -html_config := docbook-xsl/xhtml.xsl df-xhtml.css -html_config := $(addprefix config/,${html_config}) - -pdf_config := mathjax-docbook.conf docbook-xsl/pdf.xsl -pdf_config := $(addprefix config/,${pdf_config}) - -version := 1.3 -outbasename := out/dataformat.$(version) - -html: $(outbasename).html out/config/df-xhtml.css out/images/Khronos_Dec14.svg out/images/icons/note.png -inlinehtml: $(outbasename).inline.html -compressedinlinehtml: $(outbasename).inline.html.gz -pdf: $(outbasename).pdf -header: out/headers/khr_df.h - -$(outbasename).html: $(sources) $(html_config) | out - a2x $(A2XOPTS) -f xhtml df.txt -a svgpdf=svg -a a2xhtml=html -a docinfo --xsl-file=config/docbook-xsl/xhtml.xsl -a toc2 -a toclevels=2 -D out - ./simplifyhtmllinks.pl out/df.html out/df2.html - rm out/df.html - mv out/df2.html out/dataformat.1.3.html - -out/config/df-xhtml.css: config/df-xhtml.css | out out/config - cp $< $@ - -out/images/Khronos_Dec14.svg: images/Khronos_Dec14.svg | out/images - cp $< $@ - -out/images/icons/note.png: images/icons/note.png | out/images/icons - cp $< $@ - -out out/config out/headers out/images out/images/icons: - mkdir -p $@ - -$(outbasename).inline.html: $(outbasename).html inlinecss.pl inlineimages.pl - ./inlinecss.pl < out/dataformat.1.3.html | ./inlineimages.pl > $@ - -$(outbasename).inline.html.gz: $(outbasename).inline.html - gzip -9 -c < out/dataformat.1.3.inline.html > out/dataformat.1.3.inline.html.gz - -$(outbasename).pdf: $(sources) $(pdf_config) | out - asciidoc -d book -b docbook -a numbered -f config/mathjax-docbook.conf -a svgpdf=pdf -a a2x-format=pdf -a docinfo df.txt && \ - dblatex -b pdftex -p config/docbook-xsl/pdf.xsl -s dblatex/df.sty df.xml -o $@ - -out/headers/khr_df.h: headers/khr_df.h out/headers - cp $< $@ - -clean: - rm -f out/dataformat.1.3.pdf df.xml out/dataformat.1.3.html out/dataformat.1.3.inline.html out/dataformat.1.3.inline.html.gz - rm -rf out/config out/images out/headers +# Copyright 2024-2026 The Khronos Group Inc. +# SPDX-License-Identifier: Apache-2.0 + +# Khronos Data Format Specification Makefile + +# If a recipe fails, delete its target file. Without this cleanup, the leftover +# file from the failed recipe can falsely satisfy dependencies on subsequent +# runs of `make`. +.DELETE_ON_ERROR: + +# APITITLE can be set to extra text to append to the document title, +# normally used when building with extensions included. +APITITLE = + +# IMAGEOPTS is normally set to generate inline SVG images, but can be +# overridden to an empty string, since the inline option doesn't work +# well with our HTML diffs. +IMAGEOPTS = inline + +# The default 'all' target builds the following sub-targets: +# html - HTML5 single-page API specification +# pdf - PDF single-page API specification + +all: html pdf + +QUIET ?= @ +PYTHON ?= python3 +ASCIIDOC ?= asciidoctor +RUBY = ruby +NODEJS = node +PATCH = patch +RM = rm -f +RMRF = rm -rf +MKDIR = mkdir -p +CP = cp +ECHO = echo + +# Where the repo root is +ROOTDIR = $(CURDIR) +# Where the spec files are +SPECDIR = $(CURDIR) + +# Path to scripts used in generation +SCRIPTS = $(ROOTDIR)/scripts +# Path to configs and asciidoc extensions used in generation +CONFIGS = $(ROOTDIR)/config + +# Target directories for output files +# HTMLDIR - 'html' target +# PDFDIR - 'pdf' target +OUTDIR = $(CURDIR)/out +HTMLDIR = $(OUTDIR)/html +PDFDIR = $(OUTDIR)/pdf + +# PDF Equations are written to SVGs, this dictates the location to store those files (temporary) +PDFMATHDIR = $(OUTDIR)/equations_temp + +# Set VERBOSE to -v to see what asciidoc is doing. +VERBOSE = + +# asciidoc attributes to set (defaults are usually OK) +# NOTEOPTS sets options controlling which NOTEs are generated +# PATCHVERSION is the minor document release version +# ATTRIBOPTS sets the API revision and enables KaTeX generation +# EXTRAATTRIBS sets additional attributes, if passed to make +# ADOCMISCOPTS miscellaneous options controlling error behavior, etc. +# ADOCEXTS asciidoctor extensions to load +# ADOCOPTS options for asciidoc->HTML5 output + +NOTEOPTS = +PATCHVERSION = 1 +SPECREVISION = 1.3.$(PATCHVERSION) + +# Spell out ISO 8601 format as not all date commands support --rfc-3339 +SPECDATE = $(shell echo `date -u "+%Y-%m-%d %TZ"`) + +# Generate Asciidoc attributes for spec remark +# Could use `git log -1 --format="%cd"` to get branch commit date +# The dependency on HEAD is per the suggestion in +# http://neugierig.org/software/blog/2014/11/binary-revisions.html +SPECREMARK = from git branch: $(shell echo `git symbolic-ref --short HEAD 2> /dev/null || echo Git branch not available`) \ + commit: $(shell echo `git log -1 --format="%H" 2> /dev/null || echo Git commit not available`) + +# Some of the attributes used in building all spec documents: +# chapters - absolute path to chapter sources +# appendices - absolute path to appendix sources +# images - absolute path to images +ATTRIBOPTS = -a revnumber="$(SPECREVISION)" \ + -a revdate="$(SPECDATE)" \ + -a revremark="$(SPECREMARK)" \ + -a apititle="$(APITITLE)" \ + -a stem=latexmath \ + -a imageopts="$(IMAGEOPTS)" \ + -a config=$(ROOTDIR)/config \ + -a appendices=$(SPECDIR)/appendices \ + -a chapters=$(SPECDIR)/chapters \ + -a images=$(IMAGEPATH) \ + $(EXTRAATTRIBS) +ADOCMISCOPTS = --failure-level ERROR +# Non target-specific Asciidoctor extensions and options +ADOCEXTS = -r $(CONFIGS)/open_listing_block.rb +ADOCOPTS = -d book $(ADOCMISCOPTS) $(ATTRIBOPTS) $(NOTEOPTS) $(VERBOSE) $(ADOCEXTS) + +# HTML target-specific Asciidoctor extensions and options +ADOCHTMLEXTS = -r $(CONFIGS)/katex_replace.rb \ + -r $(CONFIGS)/loadable_html.rb + +# ADOCHTMLOPTS relies on the relative runtime path from the output HTML +# file to the katex scripts being set with KATEXDIR. This is overridden +# by some targets. +# KaTeX source is copied from KATEXSRCDIR in the repository to +# KATEXINSTDIR in the output directory. +# KATEXDIR is the relative path from a target to KATEXINSTDIR, since +# that is coded into CSS, and set separately for each HTML target. +# ADOCHTMLOPTS also relies on the absolute build-time path to the +# 'stylesdir' containing our custom CSS. +KATEXSRCDIR = $(ROOTDIR)/katex +KATEXINSTDIR = $(OUTDIR)/katex +ADOCHTMLOPTS = $(ADOCHTMLEXTS) -a katexpath=$(KATEXDIR) \ + -a stylesheet=khronos.css \ + -a stylesdir=$(ROOTDIR)/config \ + -a sectanchors + +# PDF target-specific Asciidoctor extensions and options +ADOCPDFEXTS = -r asciidoctor-pdf \ + -r asciidoctor-mathematical \ + -r $(CONFIGS)/asciidoctor-mathematical-ext.rb +ADOCPDFOPTS = $(ADOCPDFEXTS) -a mathematical-format=svg \ + -a imagesoutdir=$(PDFMATHDIR) \ + -a pdf-stylesdir=$(CONFIGS)/themes -a pdf-style=pdf + +.PHONY: directories + +# Images used by the specification. +# These are included in generated HTML now. +IMAGEPATH = $(SPECDIR)/images +SVGFILES = $(wildcard $(IMAGEPATH)/*.svg) + +# Top-level spec source file +SPECSRC = $(SPECDIR)/dataformat.adoc +# Static files making up sections of the specification. +SPECFILES = $(wildcard chapters/[A-Za-z]*.adoc appendices/[A-Za-z]*.adoc) + +# All non-format-specific dependencies +COMMONDOCS = $(SPECFILES) + +# Script to translate math at build time +TRANSLATEMATH = $(NODEJS) $(SCRIPTS)/translate_math.js $(KATEXSRCDIR)/katex.min.js + +# Install katex in KATEXINSTDIR ($(OUTDIR)/katex) to be shared by all +# HTML targets. +# We currently only need the css and fonts, but copy all of KATEXSRCDIR anyway. +$(KATEXINSTDIR): $(KATEXSRCDIR) + $(QUIET)$(MKDIR) $(KATEXINSTDIR) + $(QUIET)$(RMRF) $(KATEXINSTDIR) + $(QUIET)$(CP) -rf $(KATEXSRCDIR) $(KATEXINSTDIR) + +# Spec targets +# There is some complexity to try and avoid short virtual targets like 'html' +# causing specs to *always* be regenerated. + +html: $(HTMLDIR)/dataformat.html $(SPECSRC) $(COMMONDOCS) + +$(HTMLDIR)/dataformat.html: KATEXDIR = ../katex +$(HTMLDIR)/dataformat.html: $(SPECSRC) $(COMMONDOCS) $(KATEXINSTDIR) + $(QUIET)$(ASCIIDOC) -b html5 $(ADOCOPTS) $(ADOCHTMLOPTS) -o $@ $(SPECSRC) + $(QUIET)$(TRANSLATEMATH) $@ + +# PDF optimizer - usage $(OPTIMIZEPDF) in.pdf out.pdf +# OPTIMIZEPDFOPTS=--compress-pages is slightly better, but much slower +OPTIMIZEPDF = hexapdf optimize $(OPTIMIZEPDFOPTS) + +pdf: $(PDFDIR)/dataformat.pdf $(SPECSRC) $(COMMONDOCS) + +$(PDFDIR)/dataformat.pdf: $(SPECSRC) $(COMMONDOCS) + $(QUIET)$(MKDIR) $(PDFDIR) + $(QUIET)$(MKDIR) $(PDFMATHDIR) + $(QUIET)$(ASCIIDOC) -b pdf $(ADOCOPTS) $(ADOCPDFOPTS) -o $@ $(SPECSRC) + $(QUIET)$(OPTIMIZEPDF) $@ $@.out.pdf && mv $@.out.pdf $@ + $(QUIET)rm -rf $(PDFMATHDIR) + +# Clean generated and output files + +clean: clean_html clean_pdf clean_generated + +clean_html: + $(QUIET)$(RMRF) $(HTMLDIR) $(OUTDIR)/katex + $(QUIET)$(RM) $(OUTDIR)/dataformat.html + +clean_pdf: + $(QUIET)$(RMRF) $(PDFDIR) $(OUTDIR)/dataformat.pdf + +# Generated directories and files to remove +CLEAN_GEN_PATHS = \ + $(PDFMATHDIR) + +clean_generated: + $(QUIET)$(RMRF) $(CLEAN_GEN_PATHS) diff --git a/README.adoc b/README.adoc index e32e6ef..5ef1030 100644 --- a/README.adoc +++ b/README.adoc @@ -1,13 +1,18 @@ -Khronos^(TM)^ Data Format Specification -======================================= +// Copyright 2014-2026 The Khronos Group Inc. +// SPDX-License-Identifier: CC-BY-4.0 -This repository contains source for the Khronos Data Format Specification. +ifdef::env-github[] +:note-caption: :information_source: +endif::[] + += Khronos^(TM)^ Data Format Specification The Khronos Data Format Specification describes a portable mechanism for describing a wide range of image/texture formats and other forms of data. It solely describes the format of what may be considered to be a single -"pixel" or a repeating group of pixels considered to be a "texture block". +"`pixel`" or a repeating group of pixels considered to be a "`texture +block`". A wide variety of incompatible mechanisms exist in the industry for describing formats that may be supported by an API. @@ -25,38 +30,71 @@ This specification also contains a detailed description of the in-memory representation of a number of compressed texture formats, and describes some common color spaces. -Building the Specification -========================== -The build system relies on -link:http://www.methods.co.nz/asciidoc/index.html[asciidoc], which is -available as part of many Linux distributions. -The PDF build subsequently depends on -link:http://dblatex.sourceforge.net[dblatex]. +== Repository Structure + +The link:https://github.com/KhronosGroup/DataFormat[DataFormat] repository, +and the equivalent internal Khronos tracking repository, contain sources for +the formal documentation of the Khronos Data Format Specification. +These include: + +[options="compact"] + * The Data Format Specification + * The `khr_df.h` C header file + * Related tools and scripts + +The repository hosts a public issue tracker, and outside developers can file +proposed changes (Pull Requests) against the Specification, subject to +approval by Khronos. + + +== External Contributions + +Khronos welcomes feedback in GitHub Issues, and proposed changes in GitHub +Pull Requests (PRs), but will not necessarily accept all such changes. + +Please keep your issues and pull requests focused on solving a single +problem. Broader feedback that tries to solve multiple problems, or touches +many parts of the Specification at once, is difficult for Khronos to review +in a timely fashion. + + +== Branch Structure + +The current Specification (Data Format 1.3) is maintained in the default +branch (currently `main`) of the repository. + + +== Directory Structure -All forms of the specification may be built with a simple "make" -or "make all" command, with an output into the "out" directory. +The directory structure is as follows: -Use "make pdf" to build just the PDF specification. +``` +README.adoc This file +BUILD.adoc Documents how to build the specifications +CONTRIBUTING.adoc Requirements for external contributions to the repository +COPYING.adoc Copyright and licensing information +CODE_OF_CONDUCT.adoc Code of Conduct +LICENSE.adoc Summary of licenses used by files in the repository +Makefile Makefile (see BUILD.adoc) +appendices/ Specification appendices +chapters/ Specification chapters +config/ Asciidoctor configuration, CSS, and index generator +images/ Images (figures, diagrams, icons) +out/ Default directory for the generated documents +scripts/ Helper scripts used in specification, header, and reference page generation +``` -Use "make html" to build the HTML version of the specification -without inline images, which are accessed from the "out" directory; -this is smaller than the "inlinehtml" version. -Use "make inlinehtml" to create the HTML and then generate a version -with inlined images, allowing it to be transferred as a single -file; note that the HTML still relies on access to -link:http://www.mathjax.org[MathJax] and is therefore not completely -stand-alone. -This build option requires PERL. -Since the inline HTML file is very large, "make compressedinlinehtml" -produces a gzip-compressed version of the output. +== Building the Specification and Reference Pages -"make header" copies the header file into the "out/headers" directory. +The document sources are marked up in Asciidoc format, and we use +`asciidoctor` and related toolchain components to generate output documents. +See link:BUILD.adoc[BUILD.adoc] for more information on installing the +toolchain and building the Specification. -"make clean" removes the contents out "out" and temporary files. -Default Branch Renaming -======================= +== Generating Headers and Related Files -The default branch of this repository was renamed from "master" to "main" on 2024-02-01. +The `khr_df.h` C header file defines structures and enums for specifying the +layout of images in memory. diff --git a/REUSE.toml b/REUSE.toml new file mode 100644 index 0000000..e9e3966 --- /dev/null +++ b/REUSE.toml @@ -0,0 +1,27 @@ +version = 1 +SPDX-PackageName = "DataFormat" +SPDX-PackageDownloadLocation = "https://github.com/KhronosGroup/DataFormat" + +[[annotations]] +path = ["images/**.svg", "config/**/docinfo-header.html"] +precedence = "aggregate" +SPDX-FileCopyrightText = "2015-2026 The Khronos Group Inc." +SPDX-License-Identifier = "CC-BY-4.0" + +[[annotations]] +path = "katex/**" +precedence = "aggregate" +SPDX-FileCopyrightText = "2013-2019 Khan Academy and other contributors" +SPDX-License-Identifier = "MIT" + +[[annotations]] +path = "config/khronos.css" +precedence = "aggregate" +SPDX-FileCopyrightText = "2013 Dan Allen" +SPDX-License-Identifier = "MIT" + +[[annotations]] +path = "config/copyright-spec.adoc" +precedence = "aggregate" +SPDX-FileCopyrightText = "2014-2026 The Khronos Group Inc" +SPDX-License-Identifier = "LicenseRef-KhronosSpecCopyright" diff --git a/astc.txt b/chapters/astc.adoc similarity index 90% rename from astc.txt rename to chapters/astc.adoc index bbca306..33cbbd5 100644 --- a/astc.txt +++ b/chapters/astc.adoc @@ -1,5 +1,6 @@ -// Copyright (c) 2014-2019 The Khronos Group Inc. -// Copyright notice at https://www.khronos.org/registry/speccopyright.html +// Copyright 2014-2026 The Khronos Group Inc. +// SPDX-License-Identifier: CC-BY-4.0 + [[ASTC]] == ASTC Compressed Texture Image Formats @@ -19,7 +20,7 @@ ASTC textures may be encoded using either high or low dynamic range. Low dynamic range images may optionally be specified using the sRGB transfer function for the _RGB_ channels. -Two sub-profiles (``LDR Profile'' and ``HDR Profile'') may be implemented, +Two sub-profiles ("`LDR Profile`" and "`HDR Profile`") may be implemented, which support only 2D images at low or high dynamic range respectively. ASTC textures may be encoded as 1, 2, 3 or 4 components, but they are @@ -41,7 +42,7 @@ The design goals for the format are as follows: rates, leaving content developers with only coarse control over the size/quality tradeoff. * Scalable and long-lived. The format should support existing _R_, _RG_, - _RGB_ and _RGBA_ image types, and also have high ``headroom'', allowing + _RGB_ and _RGBA_ image types, and also have high "`headroom`", allowing continuing use for several years and the ability to innovate in encoders. Part of this is the choice to include HDR and 3D. * Feature orthogonality. The choices for the various features of the @@ -66,10 +67,10 @@ is divided into a number of blocks of uniform size, which makes it possible to quickly determine which block a given texel resides in. Each block has a fixed memory footprint of 128 bits, but these bits -can represent varying numbers of texels (the block ``footprint''). +can represent varying numbers of texels (the block "`footprint`"). -NOTE: The term ``block footprint'' in ASTC refers to the same concept -as ``compressed texel block dimensions'' elsewhere in the Data Format +NOTE: The term "`block footprint`" in ASTC refers to the same concept +as "`compressed texel block dimensions`" elsewhere in the Data Format Specification. Block footprint sizes are not confined to powers-of-two, and are @@ -86,7 +87,7 @@ simplifies cache design, reduces bandwidth and improves encoder throughput. To understand how the blocks are stored and decoded, it is useful to start with a simple example, and then introduce additional features. -The simplest block encoding starts by defining two color ``endpoints''. The +The simplest block encoding starts by defining two color "`endpoints`". The endpoints define two colors, and a number of additional colors are generated by interpolating between them. We can define these colors using 1, 2, 3, or 4 components (usually corresponding to _R_, _RG_, _RGB_ and _RGBA_ textures), @@ -115,7 +116,7 @@ For blocks which have a mixture of disparate colors, a single line in the color space is not a good fit to the colors of the pixels in the original image. It is therefore possible to partition the texels into multiple sets, the pixels within each set having similar colors. For each of these -``partitions'', we specify separate endpoint pairs, and choose which pair of +"`partitions`", we specify separate endpoint pairs, and choose which pair of endpoints to use for a particular texel by looking up the partition index from a partitioning pattern table. In ASTC, this partition table is actually implemented as a function. @@ -125,7 +126,7 @@ The endpoint encoding for each partition is independent. For blocks which have uncorrelated channels -- for example an image with a transparency mask, or an image used as a normal map -- it may be necessary to specify two weights for each texel. Interpolation between the components -of the endpoint colors can then proceed independently for each ``plane'' of +of the endpoint colors can then proceed independently for each "`plane`" of the image. The assignment of channels to planes is selectable. Since each of the above options is independent, it is possible to specify any @@ -139,12 +140,12 @@ which are nevertheless highly amenable to hardware decode. All of the values used as weights and color endpoint values can be specified with a variable number of bits. The encoding scheme used allows a fine-grained -tradeoff between weight bits and color endpoint bits using ``integer -sequence encoding''. This can pack adjacent values together, allowing us to +tradeoff between weight bits and color endpoint bits using "`integer +sequence encoding`". This can pack adjacent values together, allowing us to use fractional numbers of bits per value. -Finally, a block may be just a single color. This is a so-called ``void -extent block'' and has a special coding which also allows it to identify +Finally, a block may be just a single color. This is a so-called "`void +extent block`" and has a special coding which also allows it to identify nearby regions of single color. This may be used to short-circuit fetching of what would be identical blocks, and further reduce memory bandwidth. @@ -161,14 +162,14 @@ The two modes differ in various ways, as shown in <>. @@ -176,12 +177,12 @@ the decoding mode as shown in <>. [[astc_decoding_modes]] .ASTC decoding modes [options="header"] -|================ -| Decode mode | LDR mode |  HDR mode +|==== +| Decode mode | LDR mode |{nbsp} HDR mode | decode_float16 2+| Vector of FP16 values -| decode_unorm8 | Vector of 8-bit unsigned normalized values |  invalid -| decode_rgb9e5 2+|  Vector using a shared exponent format -|================ +| decode_unorm8 | Vector of 8-bit unsigned normalized values |{nbsp} invalid +| decode_rgb9e5 2+|{nbsp} Vector using a shared exponent format +|==== Using the decode_unorm8 decoding mode in HDR mode gives undefined results. @@ -189,12 +190,12 @@ For sRGB, the decoding mode is ignored, ad the decoding always returns a vector of 8-bit unsigned normalized values. The error color is opaque fully-saturated magenta -(_R_,_G_,_B_,_A_) = (0xFF, 0x00, 0xFF, 0xFF). +(_R_,_G_,_B_,_A_){nbsp}={nbsp}(0xFF,{nbsp}0x00,{nbsp}0xFF,{nbsp}0xFF). This has been chosen as it is much more noticeable than black or white, and occurs far less often in valid images. For linear _RGB_ decode, the error color may be either opaque fully-saturated -magenta (_R_,_G_,_B_,_A_) = (1.0, 0.0, 1.0, 1.0) or a vector of four _NaNs_ +magenta (_R_,_G_,_B_,_A_) = (1.0,{nbsp}0.0,{nbsp}1.0,{nbsp}1.0) or a vector of four _NaNs_ (_R_,_G_,_B_,_A_) = (_NaN_, _NaN_, _NaN_, _NaN_). In the latter case, the recommended _NaN_ value returned is 0xFFFF. @@ -236,7 +237,8 @@ The data specified per block are as follows: To decode one texel: -------------------- +[source] +---- (Optimization: If within known void-extent, immediately return single color) Find block containing texel @@ -258,7 +260,7 @@ Read color endpoint mode and endpoint data for selected partition Unquantize color endpoints Interpolate color endpoints using weight (or weights in dual-plane mode) Return interpolated color -------------------- +---- <<< @@ -276,7 +278,7 @@ For square and nearly-square blocks, this gives the bit rates in [[astc_footprint_2D]] .ASTC 2D footprint and bit rates [cols="1,1,1,1",width="50%"] -|====================== +|==== 2+^| *Footprint* .2+^.^| *Bit Rate* .2+^.^| *Increment* ^| *Width* ^| *Height* ^| 4 ^| 4 ^| 8.00 ^| 125% @@ -293,9 +295,9 @@ For square and nearly-square blocks, this gives the bit rates in ^| 10 ^| 10 ^| 1.28 ^| 120% ^| 12 ^| 10 ^| 1.07 ^| 120% ^| 12 ^| 12 ^| 0.89 ^| -|============= +|==== -The ``Increment'' column indicates the ratio of bit rate against the next +The "`Increment`" column indicates the ratio of bit rate against the next lower available rate. A consistent value in this column indicates an even spread of bit rates. @@ -308,7 +310,7 @@ For cubic and near-cubic blocks, this gives the bit rates in [[astc_footprint_3D]] .ASTC 3D footprint and bit rates [cols="1,1,1,1,1",width="60%"] -|====================== +|==== 3+^| *Block Footprint* .2+^.^| *Bit Rate* .2+^.^| *Increment* ^| *Width* ^| *Height* ^| *Depth* ^| 3 ^| 3 ^| 3 ^| 4.74 ^| 133% @@ -321,7 +323,7 @@ For cubic and near-cubic blocks, this gives the bit rates in ^| 6 ^| 5 ^| 5 ^| 0.85 ^| 120% ^| 6 ^| 6 ^| 5 ^| 0.71 ^| 120% ^| 6 ^| 6 ^| 6 ^| 0.59 ^| -|====================== +|==== The full profile supports only those block footprints listed in <> and <>. Other block sizes are not supported. @@ -338,31 +340,31 @@ Given an image which is _W_ {times} _H_ {times} _D_ pixels in size, with block s _w_ {times} _h_ {times} _d_, the size of the image in blocks is: [latexmath] -++++++++++++++++++++++ +++++ \begin{align*} \textrm{B}_\textrm{w} & = \left\lceil { W \over w } \right\rceil \\ \textrm{B}_\textrm{h} & = \left\lceil { H \over h } \right\rceil \\ \textrm{B}_\textrm{d} & = \left\lceil { D \over d } \right\rceil \end{align*} -++++++++++++++++++++++ +++++ For a 3D image built from 2D slices, each 2D slice is a single texel thick, so that for an image which is _W_ {times} _H_ {times} _D_ pixels in size, with block size _w_ {times} _h_, the size of the image in blocks is: [latexmath] -++++++++++++++++++++++ +++++ \begin{align*} \textrm{B}_\textrm{w} & = \left\lceil { W \over w } \right\rceil \\ \textrm{B}_\textrm{h} & = \left\lceil { H \over h } \right\rceil \\ \textrm{B}_\textrm{d} & = D \end{align*} -++++++++++++++++++++++ +++++ === Block Layout Each block in the image is stored as a single 128-bit block in memory. These -blocks are laid out in raster order, starting with the block at (0, 0, 0), then +blocks are laid out in raster order, starting with the block at (0,{nbsp}0,{nbsp}0), then ordered sequentially by X, Y and finally Z (if present). They are aligned to 128-bit boundaries in memory. @@ -375,32 +377,32 @@ Each block has the same basic layout, shown in <>. [[astc-block-layout]] .ASTC block layout [width="97%",cols="1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1"] -|==================== +|==== ^| ~127~ ^| ~126~ ^| ~125~ ^| ~124~ ^| ~123~ ^| ~122~ ^| ~121~ ^| ~120~ ^| ~119~ ^| ~118~ ^| ~117~ ^| ~116~ ^| ~115~ ^| ~114~ ^| ~113~ ^| ~112~ -12+|   Texel weight data (variable width) 4+|   Fill direction latexmath:[$\rightarrow$] +12+| {nbsp} Texel weight data (variable width) 4+| {nbsp} Fill direction latexmath:[\rightarrow] ^| ~111~ ^| ~110~ ^| ~109~ ^| ~108~ ^| ~107~ ^| ~106~ ^| ~105~ ^| ~104~ ^| ~103~ ^| ~102~ ^| ~101~ ^| ~100~ ^| ~99~ ^| ~98~ ^| ~97~ ^| ~96~ -16+|   Texel weight data +16+| {nbsp} Texel weight data ^| ~95~ ^| ~94~ ^| ~93~ ^| ~92~ ^| ~91~ ^| ~90~ ^| ~89~ ^| ~88~ ^| ~87~ ^| ~86~ ^| ~85~ ^| ~84~ ^| ~83~ ^| ~82~ ^| ~81~ ^| ~80~ -16+|   Texel weight data +16+| {nbsp} Texel weight data ^| ~79~ ^| ~78~ ^| ~77~ ^| ~76~ ^| ~75~ ^| ~74~ ^| ~73~ ^| ~72~ ^| ~71~ ^| ~70~ ^| ~69~ ^| ~68~ ^| ~67~ ^| ~66~ ^| ~65~ ^| ~64~ -16+|   Texel weight data +16+| {nbsp} Texel weight data ^| ~63~ ^| ~62~ ^| ~61~ ^| ~60~ ^| ~59~ ^| ~58~ ^| ~57~ ^| ~56~ ^| ~55~ ^| ~54~ ^| ~53~ ^| ~52~ ^| ~51~ ^| ~50~ ^| ~49~ ^| ~48~ -5+| 6+|   More config data 5+| +5+| 6+| {nbsp} More config data 5+| ^| ~47~ ^| ~46~ ^| ~45~ ^| ~44~ ^| ~43~ ^| ~42~ ^| ~41~ ^| ~40~ ^| ~39~ ^| ~38~ ^| ~37~ ^| ~36~ ^| ~35~ ^| ~34~ ^| ~33~ ^| ~32~ -8+|   latexmath:[$\leftarrow$] Fill direction 8+|   Color endpoint data +8+| {nbsp} latexmath:[\leftarrow] Fill direction 8+| {nbsp} Color endpoint data ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ -4+| 12+|   Extra configuration data +4+| 12+| {nbsp} Extra configuration data ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ -3+|   Extra 2+|   Part 11+|   Block mode -|==================== +3+| {nbsp} Extra 2+| {nbsp} Part 11+| {nbsp} Block mode +|==== -Since the size of the ``texel weight data'' field is variable, the -positions shown for the ``more config data'' field and ``color endpoint -data'' field are only representative and not fixed. +Since the size of the "`texel weight data`" field is variable, the +positions shown for the "`more config data`" field and "`color endpoint +data`" field are only representative and not fixed. -The ``Block mode'' field specifies how the Texel Weight Data is encoded. +The "`Block mode`" field specifies how the Texel Weight Data is encoded. -The ``Part'' field specifies the number of partitions, minus one. If dual +The "`Part`" field specifies the number of partitions, minus one. If dual plane mode is enabled, the number of partitions must be 3 or fewer. If 4 partitions are specified, the error value is returned for all texels in the block. @@ -412,12 +414,12 @@ in <> (only the bottom 32 bits are shown). [[astc-single-partition-layout]] .ASTC single-partition block layout [width="97%",cols="1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1"] -|==================== +|==== ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ -15+|   Color endpoint data ^| CEM +15+| {nbsp} Color endpoint data ^| CEM ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ -3+|   CEM ^| 0 ^| 0 11+|   Block mode -|==================== +3+| {nbsp} CEM ^| 0 ^| 0 11+| {nbsp} Block mode +|==== CEM is the color endpoint mode field, which determines how the Color Endpoint Data is encoded. @@ -428,12 +430,12 @@ directly below the weight bits, as shown in <>. [[astc-multi-partition-layout]] .ASTC multi-partition block layout [width="97%",cols="1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1"] -|==================== +|==== ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ -3+| 6+|   CEM 7+|   Partition index +3+| 6+| {nbsp} CEM 7+| {nbsp} Partition index ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ -3+|   Partition index 2+|   Part 11+|   Block mode -|==================== +3+| {nbsp} Partition index 2+| {nbsp} Part 11+| {nbsp} Block mode +|==== The Partition Index field specifies which partition layout to use. CEM is the first 6 bits of color endpoint mode information for the various @@ -444,7 +446,7 @@ weight data. If dual-plane mode is active, the color component selector bits then appear directly below the additional CEM bits. -The final special case is that if bits [8..0] of the block are ``111111100'', +The final special case is that if bits [8..0] of the block are "`111111100`", then the block is a void-extent block, which has a separate encoding described in <>. @@ -469,7 +471,7 @@ and Bits. The details of this encoding can be found in [[astc-weight-range-encodings]] .ASTC weight range encodings [width="97%",cols="1,2,1,1,1,2,1,1,1"] -|==================== +|==== 1.2+^.^| *{rho}^2..0^* 4+^.^| *Low-precision range (_P_=0)* 4+^.^| *High-precision range (_P_=1)* ^.^| *Weight range* ^.^| *Trits* ^.^| *Quints* ^.^| *Bits* ^.^| *Weight range* ^.^| *Trits* ^.^| *Quints* ^.^| *Bits* ^| 000 4+^| Invalid 4+^| Invalid @@ -480,7 +482,7 @@ and Bits. The details of this encoding can be found in ^| 101 ^| 0..4 ^| ^| 1 ^| ^| 0..19 ^| ^| 1 ^| 2 ^| 110 ^| 0..5 ^| 1 ^| ^| 1 ^| 0..23 ^| 1 ^| ^| 3 ^| 111 ^| 0..7 ^| ^| ^| 3 ^| 0..31 ^| ^| ^| 5 -|==================== +|==== For 2D blocks, the Block Mode field is laid out as shown in <>. @@ -488,7 +490,7 @@ For 2D blocks, the Block Mode field is laid out as shown in [[astc-2d-block-mode-layout]] .ASTC 2D block mode layout, weight grid width and height [width="97%",cols="1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1"] -|==================== +|==== ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 2+^| *W~width~* 2+^| *W~height~* 3+^| *Notes* ^| _D~P~_ ^| _P_ 2+^| _W_ 2+^| _H_ ^| {rho}^0^ ^| 0 ^| 0 ^| {rho}^2^ ^| {rho}^1^ 2+^| _W_+4 2+^| _H_+2 3+| ^| _D~P~_ ^| _P_ 2+^| _W_ 2+^| _H_ ^| {rho}^0^ ^| 0 ^| 1 ^| {rho}^2^ ^| {rho}^1^ 2+^| _W_+8 2+^| _H_+2 3+| @@ -503,7 +505,7 @@ For 2D blocks, the Block Mode field is laid out as shown in ^| x ^| x ^| 1 ^| 1 ^| 1 ^| 1 ^| 1 ^| 1 ^| 1 ^| 0 ^| 0 2+^| - 2+^| - 3+^| Void-extent ^| x ^| x ^| 1 ^| 1 ^| 1 ^| x ^| x ^| x ^| x ^| 0 ^| 0 2+^| - 2+^| - 3+^| Reserved* ^| x ^| x ^| x ^| x ^| x ^| x ^| x ^| 0 ^| 0 ^| 0 ^| 0 2+^| - 2+^| - 3+^| Reserved -|==================== +|==== Note that, due to the encoding of the {rho} field, as described in the previous page, bits {rho}^2^ and {rho}^1^ cannot both be zero, which disambiguates @@ -524,7 +526,7 @@ For 3D blocks, the Block Mode field is laid out as shown in <>. [[astc-color-endpoint-modes]] .ASTC color endpoint modes [cols="2,11,2",options="header",width="55%"] -|==================== -^| CEM |   Description ^| Class ->| 0    |   LDR Luminance, direct ^| 0 ->| 1    |   LDR Luminance, base+offset ^| 0 ->| 2    |   HDR Luminance, large range ^| 0 ->| 3    |   HDR Luminance, small range ^| 0 ->| 4    |   LDR Luminance+Alpha, direct ^| 1 ->| 5    |   LDR Luminance+Alpha, base+offset ^| 1 ->| 6    |   LDR _RGB_, base+scale ^| 1 ->| 7    |   HDR _RGB_, base+scale ^| 1 ->| 8    |   LDR _RGB_, direct ^| 2 ->| 9    |   LDR _RGB_, base+offset ^| 2 ->| 10    |   LDR _RGB_, base+scale plus two _A_ ^| 2 ->| 11    |   HDR _RGB_, direct ^| 2 ->| 12    |   LDR _RGBA_, direct ^| 3 ->| 13    |   LDR _RGBA_, base+offset ^| 3 ->| 14    |   HDR _RGB_, direct + LDR Alpha ^| 3 ->| 15    |   HDR _RGB_, direct + HDR Alpha ^| 3 -|==================== +|==== +^| CEM | {nbsp} Description ^| Class +>| 0 {nbsp}{nbsp} | {nbsp} LDR Luminance, direct ^| 0 +>| 1 {nbsp}{nbsp} | {nbsp} LDR Luminance, base+offset ^| 0 +>| 2 {nbsp}{nbsp} | {nbsp} HDR Luminance, large range ^| 0 +>| 3 {nbsp}{nbsp} | {nbsp} HDR Luminance, small range ^| 0 +>| 4 {nbsp}{nbsp} | {nbsp} LDR Luminance+Alpha, direct ^| 1 +>| 5 {nbsp}{nbsp} | {nbsp} LDR Luminance+Alpha, base+offset ^| 1 +>| 6 {nbsp}{nbsp} | {nbsp} LDR _RGB_, base+scale ^| 1 +>| 7 {nbsp}{nbsp} | {nbsp} HDR _RGB_, base+scale ^| 1 +>| 8 {nbsp}{nbsp} | {nbsp} LDR _RGB_, direct ^| 2 +>| 9 {nbsp}{nbsp} | {nbsp} LDR _RGB_, base+offset ^| 2 +>| 10 {nbsp}{nbsp} | {nbsp} LDR _RGB_, base+scale plus two _A_ ^| 2 +>| 11 {nbsp}{nbsp} | {nbsp} HDR _RGB_, direct ^| 2 +>| 12 {nbsp}{nbsp} | {nbsp} LDR _RGBA_, direct ^| 3 +>| 13 {nbsp}{nbsp} | {nbsp} LDR _RGBA_, base+offset ^| 3 +>| 14 {nbsp}{nbsp} | {nbsp} HDR _RGB_, direct + LDR Alpha ^| 3 +>| 15 {nbsp}{nbsp} | {nbsp} HDR _RGB_, direct + HDR Alpha ^| 3 +|==== In multi-partition mode, the CEM field is of variable width, from 6 to 14 bits. The lowest 2 bits of the CEM field specify how the endpoint mode @@ -588,18 +590,18 @@ for each partition is calculated as shown in <> @@ -608,21 +610,21 @@ and <>. [[astc-multi-partition-color-endpoint-mode-layout]] .ASTC multi-partition color endpoint mode layout [cols="2,1,2,1,1,1,1,1,1,1,1,1",width="90%"] -|==================== +|==== ^| *Part* ^| ^| ^| ~n~ ^| ~m~ ^| ~l~ ^| ~k~ ^| ~j~ ^| ~i~ ^| ~h~ ^| ~g~ ^| ^| 2 ^| ... ^| Weight 2+^| M~1~ 6+| | ... ^| 3 ^| ... ^| Weight 2+^| M~2~ 2+^| M~1~ ^| M~0~ 3+| | ... ^| 4 ^| ... ^| Weight 2+^| M~3~ 2+^| M~2~ 2+^| M~1~ 2+^| M~0~ | ... -|==================== +|==== [[astc-multi-partition-color-endpoint-mode-layout-2]] .ASTC multi-partition color endpoint mode layout (2) [cols="2,1,1,1,1,1,1",width="60%"] -|==================== +|==== ^| *Part* ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| 2 2+^| M~0~ ^| C~1~ ^| C~0~ 2+^| CEM ^| 3 ^| M~0~ ^| C~2~ ^| C~1~ ^| C~0~ 2+^| CEM ^| 4 ^| C~3~ ^| C~2~ ^| C~1~ ^| C~0~ 2+^| CEM -|==================== +|==== In this view, each partition _i_ has two fields. C~_i_~ is the class selector bit, choosing between the two possible CEM classes (0 indicates the @@ -648,7 +650,7 @@ value in a sequence (e.g. a color weight) is constrained. Since it is often the case that the most efficient range for these values is not a power of two, each value sequence is encoded using a -technique known as ``integer sequence encoding''. This allows efficient, +technique known as "`integer sequence encoding`". This allows efficient, hardware-friendly packing and unpacking of values with non-power-of-two ranges. @@ -659,22 +661,22 @@ in one of the forms shown in <> and [[astc-range-forms]] .ASTC range forms [options="header",width="65%",cols="2,3,3"] -|==================== -|   Value range |   MSB encoding |   LSB encoding -|   latexmath:[$0 \dots 2^n-1$] |   - |   _n_-bit value _m_ (_n_ {leq} 8) -|   latexmath:[$0 \dots (3 \times 2^n)-1$] |   Base-3 ``trit'' value _t_ |   _n_-bit value _m_ (_n_ {leq} 6) -|   latexmath:[$0 \dots (5 \times 2^n)-1$] |   Base-5 ``quint'' value _q_ |   _n_-bit value _m_ (_n_ {leq} 5) -|==================== +|==== +| {nbsp} Value range | {nbsp} MSB encoding | {nbsp} LSB encoding +| {nbsp} latexmath:[0 \dots 2^n-1] | {nbsp} - | {nbsp} _n_-bit value _m_ (_n_ {leq} 8) +| {nbsp} latexmath:[0 \dots (3 \times 2^n)-1] | {nbsp} Base-3 "`trit`" value _t_ | {nbsp} _n_-bit value _m_ (_n_ {leq} 6) +| {nbsp} latexmath:[0 \dots (5 \times 2^n)-1] | {nbsp} Base-5 "`quint`" value _q_ | {nbsp} _n_-bit value _m_ (_n_ {leq} 5) +|==== [[astc-range-encodings]] .ASTC encoding for different ranges [options="header",width="60%",cols="4,3,2,5"] -|==================== -|   Value range |   Value |   Block |   Packed block size -|   latexmath:[$0 \dots 2^n-1$] |   _m_ |   1 |   _n_ -|   latexmath:[$0 \dots (3 \times 2^n)-1$] |   latexmath:[$t \times 2^n + m$] |   5 |   8 {plus} 5 {times} _n_ -|   latexmath:[$0 \dots (5 \times 2^n)-1$] |   latexmath:[$q \times 2^n + m$] |   3 |   7 {plus} 3 {times} _n_ -|==================== +|==== +| {nbsp} Value range | {nbsp} Value | {nbsp} Block | {nbsp} Packed block size +| {nbsp} latexmath:[0 \dots 2^n-1] | {nbsp} _m_ | {nbsp} 1 | {nbsp} _n_ +| {nbsp} latexmath:[0 \dots (3 \times 2^n)-1] | {nbsp} latexmath:[t \times 2^n + m] | {nbsp} 5 | {nbsp} 8 {plus} 5 {times} _n_ +| {nbsp} latexmath:[0 \dots (5 \times 2^n)-1] | {nbsp} latexmath:[q \times 2^n + m] | {nbsp} 3 | {nbsp} 7 {plus} 3 {times} _n_ +|==== Since 3^5^ is 243, it is possible to pack five trits into 8 bits (which has 256 possible values), so a trit can effectively be encoded as 1.6 bits. @@ -695,30 +697,31 @@ To decode the bits for value number _i_ in a sequence of bits _b_, both indexed from 0, perform the following: If the range is encoded as _n_ bits per value, then the value is bits -latexmath:[$b^{i\times n + n - 1 .. i \times n}$] -- a simple multiplexing operation. +latexmath:[b^{i\times n + n - 1 .. i \times n}] -- a simple multiplexing operation. If the range is encoded using a trit, then each block contains 5 values (v~0~ to v~4~), each of which contains a trit (t~0~ to t~4~) and a corresponding LSB value (m~0~ to m~4~). The first bit of the packed block is bit -latexmath:[$\left\lfloor {i\over 5} \right\rfloor \times (8 + 5 \times n)$]. The bits in the +latexmath:[\left\lfloor {i\over 5} \right\rfloor \times (8 + 5 \times n)]. The bits in the block are packed as shown in <> (in this example, _n_ is 4). [[astc-trit-based-packing]] .ASTC trit-based packing [width="80%"] -|=========================================== +|==== 4+^| ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ 4+^| ^| T^7^ 4+^| m~4~ ^| T^6^ ^| T^5^ 4+^| m~3~ ^| T^4^ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ -4+^| m~2~ ^| T^3^ ^| T^2^ 4+^| m~1~ ^| T^1^ ^| T^0^ 4+^| m~0~ ^| -|=========================================== +4+^| m~2~ ^| T^3^ ^| T^2^ 4+^| m~1~ ^| T^1^ ^| T^0^ 4+^| m~0~ +|==== <<< The five trits t~0~ to t~4~ are obtained by bit manipulations of the 8 bits T^7..0^ as follows: ------ +[source] +---- if T[4:2] = 111 C = { T[7:5], T[1:0] }; t4 = t3 = 2 else @@ -734,12 +737,12 @@ else if C[3:2] = 11 t2 = 2; t1 = 2; t0 = C[1:0] else t2 = C[4]; t1 = C[3:2]; t0 = { C[1], C[0]&~C[1] } ------ +---- If the range is encoded using a quint, then each block contains 3 values (v~0~ to v~2~), each of which contains a quint (q~0~ to q~2~) and a corresponding LSB value (m~0~ to m~2~). The first bit of the packed block is bit -latexmath:[$ \left\lfloor {i\over 3} \right\rfloor \times (7+3 \times n)$]. +latexmath:[\left\lfloor {i\over 3} \right\rfloor \times (7 + 3 \times n)]. The bits in the block are packed as described in <> and <> (in this example, _n_ is 4). @@ -747,23 +750,24 @@ The bits in the block are packed as described in <> an [[astc-quint-based-packing]] .ASTC quint-based packing [width="20%"] -|=========== +|==== ^| ~18~ ^| ~17~ ^| ~16~ ^| Q^6^ ^| Q^5^ ^| m~2~ -|=========== +|==== [[astc-quint-based-packing-2]] .ASTC quint-based packing (2) [width="80%"] -|=========== +|==== ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 3+^| m~2~ ^| Q^4^ ^| Q^3^ 4+^| m~1~ ^| Q^2^ ^| Q^1^ ^| Q^0^ 4+^| m~0~ -|=========== +|==== The three quints q~0~ to q~2~ are obtained by bit manipulations of the 7 bits Q^6..0^ as follows: ------ +[source] +---- if Q[2:1] = 11 and Q[6:5] = 00 q2 = { Q[0], Q[4]&~Q[0], Q[3]&~Q[0] }; q1 = q0 = 4 else @@ -776,7 +780,7 @@ else q1 = 4; q0 = C[4:3] else q1 = C[4:3]; q0 = C[2:0] ------ +---- Both these procedures ensure a valid decoding for all 128 possible values (even though a few are duplicates). They can also be implemented @@ -814,7 +818,7 @@ range as described in <>. [[astc-color-unquantization-parameters]] .ASTC color unquantization parameters [cols="4,3,4,3,5,6,6,3,8",width="95%",options="header"] -|============ +|==== ^| Range ^| #Trits ^| #Quints ^| #Bits ^| Bit layout ^| ++A++ ^| ++B++ ^| ++C++ ^| ++D++ ^| 0..5 ^| 1 ^| ^| 1 ^| a ^| aaaaaaaaa ^| 000000000 ^| 204 ^| Trit value ^| 0..9 ^| ^| 1 ^| 1 ^| a ^| aaaaaaaaa ^| 000000000 ^| 113 ^| Quint value @@ -827,15 +831,16 @@ range as described in <>. ^| 0..95 ^| 1 ^| ^| 5 ^| edcba ^| aaaaaaaaa ^| edcb000ed ^| 11 ^| Trit value ^| 0..159 ^| ^| 1 ^| 5 ^| edcba ^| aaaaaaaaa ^| edcb0000e ^| 6 ^| Quint value ^| 0..191 ^| 1 ^| ^| 6 ^| fedcba ^| aaaaaaaaa ^| fedcb000f ^| 5 ^| Trit value -|============ +|==== These are then processed as follows: ------ +[source] +---- unq = D * C + B; unq = unq ^ A; unq = (A & 0x80) | (unq >> 2); ------ +---- Note that the multiply in the first line is nearly trivial as it only needs to multiply by 0, 1, 2, 3 or 4. @@ -859,25 +864,25 @@ The methods can be summarized as shown in <>. [[astc-ldr-color-endpoint-modes]] .ASTC LDR color endpoint modes [options="header",cols="2,3,11,1",width="55%"] -|============== -^| CEM ^| Range |   Description ^| _n_ ->| 0   ^| LDR |   Luminance, direct ^| 2 ->| 1   ^| LDR |   Luminance, base+offset ^| 2 ->| 2   ^| HDR |   Luminance, large range ^| 2 ->| 3   ^| HDR |   Luminance, small range ^| 2 ->| 4   ^| LDR |   Luminance+Alpha, direct ^| 4 ->| 5   ^| LDR |   Luminance+Alpha, base+offset ^| 4 ->| 6   ^| LDR |   _RGB_, base+scale ^| 4 ->| 7   ^| HDR |   _RGB_, base+scale ^| 4 ->| 8   ^| LDR |   _RGB_, direct ^| 6 ->| 9   ^| LDR |   _RGB_, base+offset ^| 6 ->| 10   ^| LDR |   _RGB_, base+scale plus two _A_ ^| 6 ->| 11   ^| HDR |   _RGB_ ^| 6 ->| 12   ^| LDR |   _RGBA_, direct ^| 8 ->| 13   ^| LDR |   _RGBA_, base+offset ^| 8 ->| 14   ^| HDR |   _RGB_ + LDR Alpha ^| 8 ->| 15   ^| HDR |   _RGB_ + HDR Alpha ^| 8 -|============== +|==== +^| CEM ^| Range | {nbsp} Description ^| _n_ +>| 0 {nbsp} ^| LDR | {nbsp} Luminance, direct ^| 2 +>| 1 {nbsp} ^| LDR | {nbsp} Luminance, base+offset ^| 2 +>| 2 {nbsp} ^| HDR | {nbsp} Luminance, large range ^| 2 +>| 3 {nbsp} ^| HDR | {nbsp} Luminance, small range ^| 2 +>| 4 {nbsp} ^| LDR | {nbsp} Luminance+Alpha, direct ^| 4 +>| 5 {nbsp} ^| LDR | {nbsp} Luminance+Alpha, base+offset ^| 4 +>| 6 {nbsp} ^| LDR | {nbsp} _RGB_, base+scale ^| 4 +>| 7 {nbsp} ^| HDR | {nbsp} _RGB_, base+scale ^| 4 +>| 8 {nbsp} ^| LDR | {nbsp} _RGB_, direct ^| 6 +>| 9 {nbsp} ^| LDR | {nbsp} _RGB_, base+offset ^| 6 +>| 10 {nbsp} ^| LDR | {nbsp} _RGB_, base+scale plus two _A_ ^| 6 +>| 11 {nbsp} ^| HDR | {nbsp} _RGB_ ^| 6 +>| 12 {nbsp} ^| LDR | {nbsp} _RGBA_, direct ^| 8 +>| 13 {nbsp} ^| LDR | {nbsp} _RGBA_, base+offset ^| 8 +>| 14 {nbsp} ^| HDR | {nbsp} _RGB_ + LDR Alpha ^| 8 +>| 15 {nbsp} ^| HDR | {nbsp} _RGB_ + HDR Alpha ^| 8 +|==== Mode 14 is special in that the alpha values are interpolated linearly, but the color components are interpolated logarithmically. This is the @@ -888,53 +893,60 @@ Decode the different LDR endpoint modes as follows: ==== Mode 0 LDR Luminance, direct ------ +[source] +---- e0=(v0,v0,v0,0xFF); e1=(v1,v1,v1,0xFF); ------ +---- ==== Mode 1 LDR Luminance, base+offset ------ +[source] +---- L0 = (v0>>2)|(v1&0xC0); L1=L0+(v1&0x3F); if (L1>0xFF) { L1=0xFF; } e0=(L0,L0,L0,0xFF); e1=(L1,L1,L1,0xFF); ------ +---- ==== Mode 4 LDR Luminance+Alpha,direct ------ +[source] +---- e0=(v0,v0,v0,v2); e1=(v1,v1,v1,v3); ------ +---- ==== Mode 5 LDR Luminance+Alpha, base+offset ------ +[source] +---- bit_transfer_signed(v1,v0); bit_transfer_signed(v3,v2); e0=(v0,v0,v0,v2); e1=(v0+v1,v0+v1,v0+v1,v2+v3); clamp_unorm8(e0); clamp_unorm8(e1); ------ +---- ==== Mode 6 LDR _RGB_, base+scale ------ +[source] +---- e0=(v0*v3>>8,v1*v3>>8,v2*v3>>8, 0xFF); e1=(v0,v1,v2,0xFF); ------ +---- ==== Mode 8 LDR _RGB_, Direct ------ +[source] +---- s0= v0+v2+v4; s1= v1+v3+v5; if (s1>=s0){e0=(v0,v2,v4,0xFF); e1=(v1,v3,v5,0xFF); } else { e0=blue_contract(v1,v3,v5,0xFF); e1=blue_contract(v0,v2,v4,0xFF); } ------ +---- ==== Mode 9 LDR _RGB_, base+offset ------ +[source] +---- bit_transfer_signed(v1,v0); bit_transfer_signed(v3,v2); bit_transfer_signed(v5,v4); @@ -944,28 +956,31 @@ else { e0=blue_contract(v0+v1,v2+v3,v4+v5,0xFF); e1=blue_contract(v0,v2,v4,0xFF); } clamp_unorm8(e0); clamp_unorm8(e1); ------ +---- ==== Mode 10 LDR _RGB_, base+scale plus two _A_ ------ +[source] +---- e0=(v0*v3>>8,v1*v3>>8,v2*v3>>8, v4); e1=(v0,v1,v2, v5); ------ +---- ==== Mode 12 LDR _RGBA_, direct ------ +[source] +---- s0= v0+v2+v4; s1= v1+v3+v5; if (s1>=s0){e0=(v0,v2,v4,v6); e1=(v1,v3,v5,v7); } else { e0=blue_contract(v1,v3,v5,v7); e1=blue_contract(v0,v2,v4,v6); } ------ +---- ==== Mode 13 LDR _RGBA_, base+offset ------ +[source] +---- bit_transfer_signed(v1,v0); bit_transfer_signed(v3,v2); bit_transfer_signed(v5,v4); @@ -975,7 +990,7 @@ if(v1+v3+v5>=0) { e0=(v0,v2,v4,v6); else { e0=blue_contract(v0+v1,v2+v3,v4+v5,v6+v7); e1=blue_contract(v0,v2,v4,v6); } clamp_unorm8(e0); clamp_unorm8(e1); ------ +---- The `bit_transfer_signed()` procedure transfers a bit from one value (_a_) to another (_b_). Initially, both _a_ and _b_ are in the range 0..255. @@ -983,7 +998,8 @@ After calling this procedure, _a_'s range becomes -32..31, and _b_ remains in the range 0..255. Note that, as is often the case, this is easier to express in hardware than in C: ------ +[source] +---- bit_transfer_signed(int& a, int& b) { b >>= 1; @@ -992,12 +1008,13 @@ bit_transfer_signed(int& a, int& b) a &= 0x3F; if( (a&0x20)!=0 ) a-=0x40; } ------ +---- The `blue_contract()` procedure is used to give additional precision to _RGB_ colors near gray: ------ +[source] +---- color blue_contract( int r, int g, int b, int a ) { color c; @@ -1007,12 +1024,13 @@ color blue_contract( int r, int g, int b, int a ) c.a = a; return c; } ------ +---- The `clamp_unorm8()` procedure is used to clamp a color into 8-bit unsigned normalized fixed-point range: ------ +[source] +---- void clamp_unorm8(color c) { if(c.r < 0) {c.r=0;} else if(c.r > 255) {c.r=255;} @@ -1020,7 +1038,7 @@ void clamp_unorm8(color c) if(c.b < 0) {c.b=0;} else if(c.b > 255) {c.b=255;} if(c.a < 0) {c.a=0;} else if(c.a > 255) {c.a=255;} } ------ +---- <<< @@ -1034,7 +1052,8 @@ pseudo-logarithmic representation. Mode 2 represents luminance-only data with a large range. It encodes using two values (v~0~, v~1~). The complete decoding procedure is as follows: ------ +[source] +---- if(v1 >= v0) { y0 = (v0 << 4); @@ -1048,7 +1067,7 @@ else // Construct RGBA result (0x780 is 1.0f) e0 = (y0, y0, y0, 0x780); e1 = (y1, y1, y1, 0x780); ------ +---- ==== HDR Endpoint Mode 3 @@ -1059,18 +1078,19 @@ bits for a base luminance value, together with an offset, into two values [[astc-hdr-mode-3-value-layout]] .ASTC HDR mode 3 value layout [width="60%",cols="2h,1,1,1,1,1,1,1,1"] -|===================== +|==== ^| *Value* ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ ^| v~0~ ^| M 7+^| L^6..0^ ^| v~1~ 4+^| X^3..0^ 4+^| d^3..0^ -|===================== +|==== The bit field marked as X allocates different bits to L or d depending on the value of the mode bit M. The complete decoding procedure is as follows: ------ +[source] +---- // Check mode bit and extract. if((v0&0x80) !=0) { @@ -1090,7 +1110,7 @@ if(y1 > 0xFFF) { y1 = 0xFFF; } // Construct RGBA result (0x780 is 1.0f) e0 = (y0, y0, y0, 0x780); e1 = (y1, y1, y1, 0x780); ------ +---- <<< @@ -1103,13 +1123,13 @@ mode bits into the four values (v~0~, v~1~, v~2~, v~3~), as shown in [[astc-hdr-mode-7-value-layout]] .ASTC HDR mode 7 value layout [width="50%",cols="3,1,1,1,1,1,1,1,1"] -|=================== +|==== ^| *Value* ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ ^|v~0~ 2+^|M^3..2^ 6+^| _R_^5..0^ ^|v~1~ ^|M^1^ ^|X^0^ ^|X^1^ 5+^| _G_^4..0^ ^|v~2~ ^|M^0^ ^|X^2^ ^|X^3^ 5+^| _B_^4..0^ ^|v~3~ ^|X^4^ ^|X^5^ ^|X^6^ 5+^| S^4..0^ -|=================== +|==== The mode bits M^0^ to M^3^ are a packed representation of an endpoint bit mode, together with the major component index. For modes 0 to 4, the @@ -1123,7 +1143,7 @@ extra bits X^0^ to X^6^, as shown in <>. [[astc-hdr-mode-7-endpoint-bit-mode]] .ASTC HDR mode 7 endpoint bit mode [width="85%",cols="2h,1,1,1,1,1,2,2,2,2,2,2,2"] -|=============== +|==== | 4+^| *Number of bits* | 7+^| *Destination of extra bits* ^| Mode ^| *_R_* ^| *_G_* ^| *_B_* ^| *S* | ^| *X^0^* ^| *X^1^* ^| *X^2^* ^| *X^3^* ^| *X^4^* ^| *X^5^* ^| *X^6^* ^| 0 ^| 11 ^| 5 ^| 5 ^| 7 ^| ^| _R_^9^ ^| _R_^8^ ^| _R_^7^ ^| _R_^10^ ^| _R_^6^ ^| S^6^ ^| S^5^ @@ -1132,7 +1152,7 @@ extra bits X^0^ to X^6^, as shown in <>. ^| 3 ^| 9 ^| 6 ^| 6 ^| 7 ^| ^| _R_^8^ ^| _G_^5^ ^| _R_^7^ ^| _B_^5^ ^| _R_^6^ ^| S^6^ ^| S^5^ ^| 4 ^| 8 ^| 7 ^| 7 ^| 6 ^| ^| _G_^6^ ^| _G_^5^ ^| _B_^6^ ^| _B_^5^ ^| _R_^6^ ^| _R_^7^ ^| S^5^ ^| 5 ^| 7 ^| 7 ^| 7 ^| 7 ^| ^| _G_^6^ ^| _G_^5^ ^| _B_^6^ ^| _B_^5^ ^| _R_^6^ ^| S^6^ ^| S^5^ -|=============== +|==== As noted before, this appears complex when expressed in C, but much easier to achieve in hardware: bit masking, extraction, shifting @@ -1142,7 +1162,8 @@ The complete decoding procedure is as follows: <<< ------ +[source] +---- // Extract mode bits and unpack to major component and mode. int majcomp; int mode; int modeval = ((v0&0xC0)>>6) | ((v1&0x80)>>5) | ((v2&0x80)>>4); @@ -1204,7 +1225,7 @@ e0.r = clamp( red - scale, 0, 0xFFF ); e0.g = clamp( green - scale, 0, 0xFFF ); e0.b = clamp( blue - scale, 0, 0xFFF ); e0.alpha = 0x780; ------ +---- ==== HDR Endpoint Mode 11 @@ -1216,7 +1237,7 @@ mode bits into the six values (v~0~, v~1~, v~2~, v~3~, v~4~, v~5~) as shown in [[astc-hdr-mode-11-value-layout]] .ASTC HDR mode 11 value layout [cols="3h,1,1,1,1,1,1,1,1",width="50%"] -|====================== +|==== ^| *Value* ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ ^| v~0~ 8+^| a^7..0^ ^| v~1~ ^|m~0~ ^|a^8^ 6+^| c^5..0^ @@ -1224,7 +1245,7 @@ mode bits into the six values (v~0~, v~1~, v~2~, v~3~, v~4~, v~5~) as shown in ^| v~3~ ^|m~2~ ^|X^1^ 6+^| b~1~^5..0^ ^| v~4~ ^|mj~0~ ^|X^2^ ^|X^4^ 5+^| d~0~^4..0^ ^| v~5~ ^|mj~1~ ^|X^3^ ^|X^5^ 5+^| d~1~^4..0^ -|====================== +|==== If the major component bits mj^1..0^ are both 1, then the _RGB_ values are specified directly by <>. @@ -1232,7 +1253,7 @@ are specified directly by <>. [[astc-hdr-mode-11-direct-value-layout]] .ASTC HDR mode 11 direct value layout [cols="3h,1,1,1,1,1,1,1,1",width="50%"] -|=================== +|==== ^| *Value* ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ ^| v~0~ 8+^| _R_~0~^11..4^ ^| v~1~ 8+^| _R_~1~^11..4^ @@ -1240,7 +1261,7 @@ are specified directly by <>. ^| v~3~ 8+^| _G_~1~^11..4^ ^| v~4~ ^| 1 7+^| _B_~0~^11..5^ ^| v~5~ ^| 1 7+^| _B_~1~^11..5^ -|=================== +|==== The mode bits m^2..0^ specify the bit allocation for the different values, and the destinations of the extra bits X^0^ to X^5^ as shown @@ -1249,7 +1270,7 @@ in <>. [[astc-hdr-mode-11-endpoint-bit-mode]] .ASTC HDR mode 11 endpoint bit mode [cols="2h,1,1,1,1,1,2,2,2,2,2,2",width="85%"] -|================= +|==== ^| 4+^| *Number of bits* | 6+^| *Destination of extra bits* ^| Mode ^| *a* ^| *b* ^| *c* ^| *d* ^| ^| *X^0^* ^| *X^1^* ^| *X^2^* ^| *X^3^* ^| *X^4^* ^| *X^5^* ^| 0 ^| 9 ^| 7 ^| 6 ^| 7 ^| ^| b~0~^6^ ^| b~1~^6^ ^| d~0~^6^ ^| d~1~^6^ ^| d~0~^5^ ^| d~1~^5^ @@ -1260,13 +1281,14 @@ in <>. ^| 5 ^| 11 ^| 6 ^| 7 ^| 6 ^| ^| a^9^ ^| a^10^ ^| c^7^ ^| c^6^ ^| d~0~^5^ ^| d~1~^5^ ^| 6 ^| 12 ^| 7 ^| 7 ^| 5 ^| ^| b~0~^6^ ^| b~1~^6^ ^| a^11^ ^| c^6^ ^| a^9^ ^| a^10^ ^| 7 ^| 12 ^| 6 ^| 7 ^| 6 ^| ^| a^9^ ^| a^10^ ^| a^11^ ^| c^6^ ^| d~0~^5^ ^| d~1~^5^ -|================= +|==== The complete decoding procedure is as follows: <<< ------ +[source] +---- // Find major component int majcomp = ((v4 & 0x80) >> 7) | ((v5 & 0x80) >> 6); @@ -1328,7 +1350,7 @@ e0.alpha = 0x780; if( majcomp == 1 ) { swap( e0.r, e0.g ); swap( e1.r, e1.g ); } else if( majcomp == 2 ) { swap( e0.r, e0.b ); swap( e1.r, e1.b ); } ------ +---- ==== HDR Endpoint Mode 14 @@ -1337,14 +1359,15 @@ v~2~, v~3~, v~4~, v~5~, v~6~, v~7~). First, the _RGB_ values are decoded from (v~0~..v~5~) using the method from Mode 11, then the alpha values are filled in from v~6~ and v~7~: ------ +[source] +---- // Decode RGB as for mode 11 (e0,e1) = decode_mode_11(v0,v1,v2,v3,v4,v5) // Now fill in the alphas e0.alpha = v6; e1.alpha = v7; ------ +---- Note that in this mode, the alpha values are interpreted (and interpolated) as 8-bit unsigned normalized values, as in the LDR modes. @@ -1363,15 +1386,16 @@ in <>. [[astc-hdr-mode-15-alpha-value-layout]] .ASTC HDR mode 15 alpha value layout [cols="h,1,1,1,1,1,1,1,1",width="75%"] -|==================== +|==== ^| *Value* ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ ^| v~6~ ^| _M_^0^ 7+^| A^6..0^ ^| v~7~ ^| _M_^1^ 7+^| B^6..0^ -|==================== +|==== The alpha values are decoded from v~6~ and v~7~ as follows: ------ +[source] +---- // Decode RGB as for mode 11 (e0,e1) = decode_mode_11(v0,v1,v2,v3,v4,v5) @@ -1399,7 +1423,7 @@ else v7 = clamp(v7, 0, 0xFFF); e0.alpha = v6; e1.alpha = v7; } ------ +---- Note that in this mode, the alpha values are interpreted (and interpolated) as 12-bit HDR values, and are interpolated as @@ -1442,11 +1466,11 @@ in <>. [[astc-weight-unquantization-values]] .ASTC weight unquantization values [cols="3,1,1,1,1,1",width="40%",options="header"] -|=========== +|==== ^| Range ^| 0 ^| 1 ^| 2 ^| 3 ^| 4 ^| 0..2 ^| 0 ^| 32 ^| 63 ^| - ^| - ^| 0..4 ^| 0 ^| 16 ^| 32 ^| 47 ^| 63 -|=========== +|==== For other values, we calculate the initial inputs to a bit manipulation procedure. These are denoted ++A++ (7 bits), ++B++ (7 bits), ++C++ (7 bits), @@ -1456,22 +1480,23 @@ and ++D++ (3 bits) and are decoded using the range as shown in [[astc-weight-unquantization-parameters]] .ASTC weight unquantization parameters [cols="4,3,4,3,5,6,6,3,8",width="95%",options="header"] -|============ +|==== ^| Range ^| #Trits ^| #Quints ^| #Bits ^| Bit layout ^| ++A++ ^| ++B++ ^| ++C++ ^| ++D++ ^| 0..5 ^| 1 ^| ^| 1 ^| a ^| aaaaaaa ^| 0000000 ^| 50 ^| Trit value ^| 0..9 ^| ^| 1 ^| 1 ^| a ^| aaaaaaa ^| 0000000 ^| 28 ^| Quint value ^| 0..11 ^| 1 ^| ^| 2 ^| ba ^| aaaaaaa ^| b000b0b ^| 23 ^| Trit value ^| 0..19 ^| ^| 1 ^| 2 ^| ba ^| aaaaaaa ^| b0000b0 ^| 13 ^| Quint value ^| 0..23 ^| 1 ^| ^| 3 ^| cba ^| aaaaaaa ^| cb000cb ^| 11 ^| Trit value -|=========== +|==== These are then processed as follows: ------ +[source] +---- unq = D * C + B; unq = unq ^ A; unq = (A & 0x20) | (unq >> 2); ------ +---- Note that the multiply in the first line is nearly trivial as it only needs to multiply by 0, 1, 2, 3 or 4. @@ -1479,9 +1504,10 @@ needs to multiply by 0, 1, 2, 3 or 4. As a final step, for all types of value, the range is expanded from 0..63 up to 0..64 as follows: ------ +[source] +---- if (unq > 32) { unq += 1; } ------ +---- This allows the implementation to use 64 as a divisor during interpolation, which is much easier than using 63. @@ -1497,29 +1523,30 @@ results. The block size is specified as three dimensions along the _s_, _t_ and _r_ axes (B~s~, B~t~, B~r~). -Texel coordinates within the block (b~s~, b~t~, b~r~) can +Texel coordinates within the block (b~s~,{nbsp}b~t~,{nbsp}b~r~) can have values from 0 to one less than the block dimension in that axis. For each block dimension, we compute scale factors (_D~s~_, _D~t~_, _D~r~_): [latexmath] -+++++++++++++ +++++ \begin{align*} D_s = \left\lfloor {\left(1024 + \left\lfloor { \textrm{B}_\textrm{s} \over 2 }\right\rfloor\right) \over (\textrm{B}_\textrm{s}-1) } \right\rfloor \\ D_t = \left\lfloor {\left(1024 + \left\lfloor { \textrm{B}_\textrm{t} \over 2 }\right\rfloor\right) \over (\textrm{B}_\textrm{t}-1) } \right\rfloor \\ D_r = \left\lfloor {\left(1024 + \left\lfloor { \textrm{B}_\textrm{r} \over 2 }\right\rfloor\right) \over (\textrm{B}_\textrm{r}-1) } \right\rfloor \end{align*} -+++++++++++++ +++++ Since the block dimensions are constrained, these are easily looked up in a table. These scale factors are then used to scale the (b~s~, b~t~, b~r~) coordinates to a homogeneous coordinate (c~s~, c~t~, c~r~): ------ +[source] +---- cs = Ds * bs; ct = Dt * bt; cr = Dr * br; ------ +---- This homogeneous coordinate (c~s~, c~t~, c~r~) is then scaled again to give a coordinate (g~s~, g~t~, g~r~) in the weight-grid space. @@ -1527,11 +1554,12 @@ The weight-grid is of size (W~width~, W~height~, W~depth~), as specified in the block mode field (<> and <>): ------ +[source] +---- gs = (cs*(Wwidth-1)+32) >> 6; gt = (ct*(Wheight-1)+32) >> 6; gr = (cr*(Wdepth-1)+32) >> 6; ------ +---- The resulting coordinates may be in the range 0..176. These are interpreted as 4:4 unsigned fixed point numbers in the range 0.0 .. 11.0. @@ -1539,24 +1567,26 @@ as 4:4 unsigned fixed point numbers in the range 0.0 .. 11.0. If we label the integral parts of these (j~s~, j~t~, j~r~) and the fractional parts (f~s~, f~t~, f~r~), then: ------ +[source] +---- js = gs >> 4; fs = gs & 0x0F; jt = gt >> 4; ft = gt & 0x0F; jr = gr >> 4; fr = gr & 0x0F; ------ +---- These values are then used to interpolate between the stored weights. This process differs for 2D and 3D. For 2D, bilinear interpolation is used: ------ +[source] +---- v0 = js + jt*Wwidth; p00 = decode_weight(v0); p01 = decode_weight(v0 + 1); p10 = decode_weight(v0 + Wwidth); p11 = decode_weight(v0 + Wwidth + 1); ------ +---- The function `decode_weight(n)` decodes the _n_^th^ weight in the stored weight stream. @@ -1564,15 +1594,16 @@ The values p~00~ to p~11~ are the weights at the corner of the square in which the texel position resides. These are then weighted using the fractional position to produce the effective weight _i_ as follows: ------ +[source] +---- w11 = (fs*ft+8) >> 4; w10 = ft - w11; w01 = fs - w11; w00 = 16 - fs - ft + w11; i = (p00*w00 + p01*w01 + p10*w10 + p11*w11 + 8) >> 4; ------ +---- -For 3D, simplex interpolation is used as it is cheaper than a naïve +For 3D, simplex interpolation is used as it is cheaper than a native trilinear interpolation. First, we pick some parameters for the interpolation based on comparisons of the fractional parts of the texel position as shown in <>. @@ -1580,7 +1611,7 @@ position as shown in <>. [[astc-simplex-interpolation-parameters]] .ASTC simplex interpolation parameters [options="header",width="90%",cols="1,1,1,2,2,1,1,1,1"] -|================== +|==== ^| _f~s~_ > _f~t~_ ^| _f~t~_ > _f~r~_ ^| _f~s~_ > _f~r~_ ^| _s_~1~ ^| _s_~2~ ^| _w_~0~ ^| _w_~1~ ^| _w_~2~ ^| _w_~3~ ^| True ^| True ^| _True_ ^| 1 ^| W~width~ ^| 16 - _f~s~_ ^| _f~s~_ - _f~t~_ ^| _f~t~_ - _f~r~_ ^| _f~r~_ ^| False ^| _True_ ^| True ^| W~width~ ^| 1 ^| 16 - _f~t~_ ^| _f~t~_ - _f~s~_ ^| _f~s~_ - _f~r~_ ^| _f~r~_ @@ -1588,19 +1619,20 @@ position as shown in <>. ^| True ^| _False_ ^| False ^| W~width~ {times} W~height~ ^| 1 ^| 16 - _f~r~_ ^| _f~r~_ - _f~s~_ ^| _f~s~_ - _f~t~_ ^| _f~t~_ ^| _False_ ^| True ^| False ^| W~width~ ^| W~width~ {times} W~height~ ^| 16 - _f~t~_ ^| _f~t~_ - _f~r~_ ^| _f~r~_ - _f~s~_ ^| _f~s~_ ^| False ^| False ^| _False_ ^| W~width~ {times} W~height~ ^| W~width~ ^| 16 - _f~r~_ ^| _f~r~_ - _f~t~_ ^| _f~t~_ - _f~s~_ ^| _f~s~_ -|================== +|==== Italicized test results are implied by the others. The effective weight _i_ is then calculated as: ------ +[source] +---- v0 = js + jt*Wwidth + jr*Wwidth*Wheight; p0 = decode_index(v0); p1 = decode_index(v0 + s1); p2 = decode_index(v0 + s1 + s2); p3 = decode_index(v0 + Wwidth*Wheight + Wwidth + 1); i = (p0*w0 + p1*w1 + p2*w2 + p3*w3 + 8) >> 4; ------ +---- <<< @@ -1616,22 +1648,25 @@ corresponding 8-bit endpoint components C~0~ and C~1~ as follows: If sRGB conversion is not enabled, or for the alpha channel in any case, C~0~ and C~1~ are first expanded to 16 bits by bit replication: ------ +[source] +---- C0 = (C0 << 8) | C0; C1 = (C1 << 8) | C1; ------ +---- If sRGB conversion is enabled, C~0~ and C~1~ for the _R_, _G_, and _B_ channels are expanded to 16 bits differently, as follows: ------ +[source] +---- C0 = (C0 << 8) | 0x80; C1 = (C1 << 8) | 0x80; ------ +---- C~0~ and C~1~ are then interpolated to produce a UNORM16 result C: ------ +[source] +---- C = floor( (C0*(64-i) + C1*i + 32)/64 ) ------ +---- If sRGB conversion is not enabled and the decoding mode is decode_float16, then if C = 65535 the final result is 1.0 (0x3C00); otherwise C is @@ -1646,7 +1681,8 @@ If sRGB conversion is not enabled and the decoding mode is decode_rgb9e5, then the final result is a combination of the (UNORM16) values of C for the three color components (_C~r~_, _C~g~_ and _C~b~_) computed as follows: ------ +[source] +---- int lz = clz17(Cr | Cg | Cb | 1); if (Cr == 65535) { Cr = 65536; lz = 0; } if (Cg == 65535) { Cg = 65536; lz = 0; } @@ -1657,7 +1693,7 @@ Cg = (Cg >> 8) & 0x1FF; Cb = (Cb >> 8) & 0x1FF; uint32_t exponent = 16 - lz; uint32_t texel = (exponent << 27) | (Cb << 18) | Cg << 9) | Cr; ------ +---- The ++clz17()++ function counts leading zeroes in a 17-bit value. @@ -1679,14 +1715,15 @@ are interpolated in the same way as LDR. The 16-bit value C is then decomposed into the top five bits, E, and the bottom 11 bits M, which are then processed and recombined with E to form the final value C~f~: ------ +[source] +---- C = floor( (C0*(64-i) + C1*i + 32)/64 ) E = (C & 0xF800) >> 11; M = C & 0x7FF; if (M < 512) { Mt = 3*M; } else if (M >= 1536) { Mt = 5*M - 2048; } else { Mt = 4*M - 512; } Cf = (E<<10) + (Mt>>3); ------ +---- This interpolation is a considerably closer approximation to a logarithmic space than simple 16-bit interpolation. @@ -1701,7 +1738,8 @@ If the decoding mode is decode_rgb9e5, then the final result is a combination fo the (IEEE FP16) values of C~f~ for the three color components (_C~r~_, _C~g~_ and _C~b~_) computed as follows: ------ +[source] +---- if( Cr > 0x7c00 ) Cr = 0; else if( Cr == 0x7c00 ) Cr = 0x7bff; if( Cg > 0x7c00 ) Cg = 0; else if( Cg == 0x7c00 ) Cg = 0x7bff; if( Cb > 0x7c00 ) Cb = 0; else if( Cb == 0x7c00 ) Cb = 0x7bff; @@ -1749,7 +1787,7 @@ Gm = (Gm >> gshift) & 0x1FF; Bm = (Bm >> bshift) & 0x1FF; uint32_t texel = (expo << 27) | (Bm << 18) | (Gm << 9) | (Rm << 0); ------ +---- <<< @@ -1769,13 +1807,13 @@ Component Selector (CCS) field as shown in <= d ) return 2; else return 3; } ------ +---- As has been observed before, the bit selections are much easier to express in hardware than in C. @@ -1860,7 +1899,8 @@ express in hardware than in C. The seed is expanded using a hash function `hash52()`, which is defined as follows: ------ +[source] +---- uint32_t hash52( uint32_t p ) { p ^= p >> 15; p -= p << 17; p += p << 7; p += p << 4; @@ -1868,7 +1908,7 @@ uint32_t hash52( uint32_t p ) p ^= p << 6; p ^= p >> 17; return p; } ------ +---- This assumes that all operations act on 32-bit values @@ -1878,7 +1918,8 @@ The size of the data used to represent color endpoints is not explicitly specified. Instead, it is determined from the block mode and number of partitions as follows: ------ +[source] +---- config_bits = 17; if(num_partitions>1) if(single_CEM) @@ -1899,7 +1940,7 @@ weight_bits = ceil(num_weights*8*trits_in_weight_range/5) + remaining_bits = 128 - config_bits - weight_bits; num_CEM_pairs = base_CEM_class+1 + count_bits(extra_CEM_bits); ------ +---- The CEM value range is then looked up from a table indexed by remaining bits and `num_CEM_pairs`. @@ -1910,7 +1951,8 @@ remaining bits. An equivalent iterative algorithm would be: ------ +[source] +---- num_CEM_values = num_CEM_pairs*2; for(range = each possible CEM range in descending order of size) @@ -1923,7 +1965,7 @@ for(range = each possible CEM range in descending order of size) break; } return range; ------ +---- In cases where this procedure results in unallocated bits, these bits are not read by the decoding process and can have any value. @@ -1945,7 +1987,7 @@ The layout of a 2D Void-Extent block is as shown in <>. [[astc-3d-void-extend-block-layout-overview]] .ASTC 3D void-extent block layout overview [cols="1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1",width="97%"] -|================= +|==== ^| ~127~ ^| ~126~ ^| ~125~ ^| ~124~ ^| ~123~ ^| ~122~ ^| ~121~ ^| ~120~ ^| ~119~ ^| ~118~ ^| ~117~ ^| ~116~ ^| ~115~ ^| ~114~ ^| ~113~ ^| ~112~ 16+^| Block color _A_ component^15..0^ ^| ~111~ ^| ~110~ ^| ~109~ ^| ~108~ ^| ~107~ ^| ~106~ ^| ~105~ ^| ~104~ ^| ~103~ ^| ~102~ ^| ~101~ ^| ~100~ ^| ~99~ ^| ~98~ ^| ~97~ ^| ~96~ @@ -1986,7 +2028,7 @@ The layout of a 3D Void-Extent block is as shown in <>. + [NOTE] ==== Per texel block, _CB_ = 3(each of _R_, _G_, @@ -101,38 +103,39 @@ _AB_ = 2(endpoints){times}NS(#subsets){times}AB(bits/endpoint). {_IB_,_IB~2~_} = 16(texels){times}{IB,IB~2~}(#index bits/texel) - NS(1bit/subset). ==== -[[table-bptcmodes]] -.Mode-dependent BPTC parameters -[width="97%",cols="7%,4%,4%,4%,4%,9%,9%,11%,9%,5%,4%,1%,3%,4%,4%,5%,5%,4%,4%"] -|============ -^| *Mode* ^| *NS* ^| *PB* ^| *RB* ^| *ISB* ^| *CB* ^| *AB* ^| *EPB* ^| *SPB* ^| *IB* ^| *IB~2~* 1.10+^| ^| *M* ^| *_CB_* ^| *_AB_* ^| *_EPB_* ^| *_SPB_* ^| *_IB_* ^| *_IB~2~_* -2+^| *Bits per...* 3+^| ...texel block 2+^| ...channel/endpoint ^| ...endpoint ^| ...subset 2+^| ...texel 7+^| Bits per texel block (total) -^| *0* ^| 3 ^| 4 ^| 0 ^| 0 ^| 4 ^| 0 ^| 1 ^| 0 ^| 3 ^| 0 ^| 1 ^| 72 ^| 0 ^| 6 ^| 0 ^| 45 ^| 0 -^| *1* ^| 2 ^| 6 ^| 0 ^| 0 ^| 6 ^| 0 ^| 0 ^| 1 ^| 3 ^| 0 ^| 2 ^| 72 ^| 0 ^| 0 ^| 2 ^| 46 ^| 0 -^| *2* ^| 3 ^| 6 ^| 0 ^| 0 ^| 5 ^| 0 ^| 0 ^| 0 ^| 2 ^| 0 ^| 3 ^| 90 ^| 0 ^| 0 ^| 0 ^| 29 ^| 0 -^| *3* ^| 2 ^| 6 ^| 0 ^| 0 ^| 7 ^| 0 ^| 1 ^| 0 ^| 2 ^| 0 ^| 4 ^| 84 ^| 0 ^| 4 ^| 0 ^| 30 ^| 0 -^| *4* ^| 1 ^| 0 ^| 2 ^| 1 ^| 5 ^| 6 ^| 0 ^| 0 ^| 2 ^| 3 ^| 5 ^| 30 ^| 12 ^| 0 ^| 0 ^| 31 ^| 47 -^| *5* ^| 1 ^| 0 ^| 2 ^| 0 ^| 7 ^| 8 ^| 0 ^| 0 ^| 2 ^| 2 ^| 6 ^| 42 ^| 16 ^| 0 ^| 0 ^| 31 ^| 31 -^| *6* ^| 1 ^| 0 ^| 0 ^| 0 ^| 7 ^| 7 ^| 1 ^| 0 ^| 4 ^| 0 ^| 7 ^| 42 ^| 14 ^| 2 ^| 0 ^| 63 ^| 0 -^| *7* ^| 2 ^| 6 ^| 0 ^| 0 ^| 5 ^| 5 ^| 1 ^| 0 ^| 2 ^| 0 ^| 8 ^| 60 ^| 20 ^| 4 ^| 0 ^| 30 ^| 0 -|============ + +//@ [[table-bptcmodes]] +//@ .Mode-dependent BPTC parameters +//@ [width="97%",cols="7%,4%,4%,4%,4%,9%,9%,11%,9%,5%,4%,1%,3%,4%,4%,5%,5%,4%,4%"] +//@ |==== +//@ ^| *Mode* ^| *NS* ^| *PB* ^| *RB* ^| *ISB* ^| *CB* ^| *AB* ^| *EPB* ^| *SPB* ^| *IB* ^| *IB~2~* 1.10+^| ^| *M* ^| *_CB_* ^| *_AB_* ^| *_EPB_* ^| *_SPB_* ^| *_IB_* ^| *_IB~2~_* +//@ 2+^| *Bits per...* 3+^| ...texel block 2+^| ...channel/endpoint ^| ...endpoint ^| ...subset 2+^| ...texel 7+^| Bits per texel block (total) +//@ ^| *0* ^| 3 ^| 4 ^| 0 ^| 0 ^| 4 ^| 0 ^| 1 ^| 0 ^| 3 ^| 0 ^| 1 ^| 72 ^| 0 ^| 6 ^| 0 ^| 45 ^| 0 +//@ ^| *1* ^| 2 ^| 6 ^| 0 ^| 0 ^| 6 ^| 0 ^| 0 ^| 1 ^| 3 ^| 0 ^| 2 ^| 72 ^| 0 ^| 0 ^| 2 ^| 46 ^| 0 +//@ ^| *2* ^| 3 ^| 6 ^| 0 ^| 0 ^| 5 ^| 0 ^| 0 ^| 0 ^| 2 ^| 0 ^| 3 ^| 90 ^| 0 ^| 0 ^| 0 ^| 29 ^| 0 +//@ ^| *3* ^| 2 ^| 6 ^| 0 ^| 0 ^| 7 ^| 0 ^| 1 ^| 0 ^| 2 ^| 0 ^| 4 ^| 84 ^| 0 ^| 4 ^| 0 ^| 30 ^| 0 +//@ ^| *4* ^| 1 ^| 0 ^| 2 ^| 1 ^| 5 ^| 6 ^| 0 ^| 0 ^| 2 ^| 3 ^| 5 ^| 30 ^| 12 ^| 0 ^| 0 ^| 31 ^| 47 +//@ ^| *5* ^| 1 ^| 0 ^| 2 ^| 0 ^| 7 ^| 8 ^| 0 ^| 0 ^| 2 ^| 2 ^| 6 ^| 42 ^| 16 ^| 0 ^| 0 ^| 31 ^| 31 +//@ ^| *6* ^| 1 ^| 0 ^| 0 ^| 0 ^| 7 ^| 7 ^| 1 ^| 0 ^| 4 ^| 0 ^| 7 ^| 42 ^| 14 ^| 2 ^| 0 ^| 63 ^| 0 +//@ ^| *7* ^| 2 ^| 6 ^| 0 ^| 0 ^| 5 ^| 5 ^| 1 ^| 0 ^| 2 ^| 0 ^| 8 ^| 60 ^| 20 ^| 4 ^| 0 ^| 30 ^| 0 +//@ |==== [[table-bptcmodedescriptions]] .Full descriptions of the BPTC mode columns [cols="1,6",width="40%"] -|============ -^| *M* |   Mode identifier bits -^| *NS* |   Number of subsets -^| *PB* |   Partition selection bits -^| *RB* |   Rotation bits -^| *ISB* |   Index selection bit -^| *CB* |   Color bits -^| *AB* |   Alpha bits -^| *EPB* |   Endpoint P-bits (all channels) -^| *SPB* |   Shared P-bits -^| *IB* |   Index bits -^| *IB~2~* |   Secondary index bits -|============ +|==== +^| *M* | {nbsp} Mode identifier bits +^| *NS* | {nbsp} Number of subsets +^| *PB* | {nbsp} Partition selection bits +^| *RB* | {nbsp} Rotation bits +^| *ISB* | {nbsp} Index selection bit +^| *CB* | {nbsp} Color bits +^| *AB* | {nbsp} Alpha bits +^| *EPB* | {nbsp} Endpoint P-bits (all channels) +^| *SPB* | {nbsp} Shared P-bits +^| *IB* | {nbsp} Index bits +^| *IB~2~* | {nbsp} Secondary index bits +|==== Each block can be divided into between 1 and 3 groups of pixels called _subsets_, which have different endpoints. There are two endpoint colors per subset, grouped first by endpoint, @@ -165,7 +168,7 @@ each endpoint color bit for each mode. [[table-bptcmodebits]] .Bit layout for BC7 modes (LSB..MSB) [cols="7*1"] -|============ +|==== 1.6+^.^| Mode {nbsp}0 2+^| ~_0:_~ *M^0^ = 1* 4+^| ~_1..4:_~ PB^0..3^ @@ -218,16 +221,12 @@ each endpoint color bit for each mode. ^| ~_54..58:_~ _B_~0~^0..4^ ^| ~_59..63:_~ _B_~1~^0..4^ ^| ~_64..68:_~ _B_~2~^0..4^ ^| ~_69..73:_~ _B_~3~^0..4^ ^| ~_74..78:_~ _A_~0~^0..4^ ^| ~_79..83:_~ _A_~1~^0..4^ ^| ~_84..88:_~ _A_~2~^0..4^ ^| ~_89..93:_~ _A_~3~^0..4^ ^| ~_94:_~ EPB~0~^0^ ^| ~_95:_~ EPB~1~^0^ ^| ~_96:_~ EPB~2~^0^ ^| ~_97:_~ EPB~3~^0^ 2+^| ~_98..127:_~ IB^0..29^ -|============ - -ifndef::a2xhtml[] -  -endif::[] +|==== [[table-bptcsourcebits]] .Bit sources for BC7 endpoints (modes 0..2, MSB..LSB per channel) [cols="32*1",width="97%"] -|============ +|==== 32+^| *Mode 0* 8+^| _E_~_R0_~^7..0^ 8+^| _E_~_G0_~^7..0^ 8+^| _E_~_B0_~^7..0^ 8+^| _E_~_A0_~^7..0^ ^| 8 ^| 7 ^| 6 ^| 5 ^| 77 ^| 8 ^| 7 ^| 6 @@ -311,16 +310,12 @@ endif::[] ^| 68 ^| 67 ^| 66 ^| 65 ^| 64 ^| 68 ^| 67 ^| 66 ^| 98 ^| 97 ^| 96 ^| 95 ^| 94 ^| 98 ^| 97 ^| 96 8+^| _255_ -|============ - -ifndef::a2xhtml[] -  -endif::[] +|==== [[table-bptcsourcebits2]] .Bit sources for BC7 endpoints (modes 3..7, MSB..LSB per channel) [cols="32*1",width="97%"] -|============ +|==== 32+^| *Mode 3* 8+^| _E_~_R0_~^7..0^ 8+^| _E_~_G0_~^7..0^ 8+^| _E_~_B0_~^7..0^ 8+^| _E_~_A0_~^7..0^ ^| 16 ^| 15 ^| 14 ^| 13 ^| 12 ^| 11 ^| 10 ^| 94 @@ -396,25 +391,7 @@ endif::[] ^| 53 ^| 52 ^| 51 ^| 50 ^| 49 ^| 97 ^| 53 ^| 52 ^| 73 ^| 72 ^| 71 ^| 70 ^| 69 ^| 97 ^| 73 ^| 72 ^| 93 ^| 92 ^| 91 ^| 90 ^| 89 ^| 97 ^| 93 ^| 92 -|============ - -ifndef::a2xhtml[] - -<<< - -  - -<<< - -  - -<<< - -  - -<<< - -endif::[] +|==== A texel in a block with one subset is always considered to be in subset zero. Otherwise, a number encoded in the partition bits is used to look up a @@ -453,7 +430,7 @@ In summary, the bit offset for index data with relative _x,y_ coordinates within block is: [latexmath] -++++++++++++++ +++++ \begin{align*} \textrm{index offset}_{x,y} &= \begin{cases} 0, & x = y = 0 \\ @@ -465,7 +442,7 @@ block is: \textrm{IB} \times (x + 4\times y) - 2, & \textrm{NS} = 3,\ \textrm{otherwise} \\ \end{cases} \\ \end{align*} -++++++++++++++ +++++ where anchor~2~ is <>, anchor~3,2~ is <>, anchor~3,3~ is <>, and _part_ is encoded in the partition @@ -513,7 +490,7 @@ using <> with weights from the two-bit index row of [[bptcP2subset]] .Partition table for 2-subset BPTC, with the 4×4 block of values for each partition number [cols="5,5,5,5,1,5,5,5,5,1,5,5,5,5,1,5,5,5,5,1,5,5,5,5,1,5,5,5,5,1,5,5,5,5,1,5,5,5,5",width="97%"] -|================== +|==== 4+^| ~0~ 1.40+| 4+^| ~1~ 1.40+| 4+^| ~2~ 1.40+| 4+^| ~3~ 1.40+| 4+^| ~4~ 1.40+| 4+^| ~5~ 1.40+| 4+^| ~6~ 1.40+| 4+^| ~7~ ^| *_0_* ^| 0 ^| 1 ^| 1 ^| *_0_* ^| 0 ^| 0 ^| 1 ^| *_0_* ^| 1 ^| 1 ^| 1 ^| *_0_* ^| 0 ^| 0 ^| 1 ^| *_0_* ^| 0 ^| 0 ^| 0 ^| *_0_* ^| 0 ^| 1 ^| 1 ^| *_0_* ^| 0 ^| 0 ^| 1 ^| *_0_* ^| 0 ^| 0 ^| 0 ^| 0 ^| 0 ^| 1 ^| 1 ^| 0 ^| 0 ^| 0 ^| 1 ^| 0 ^| 1 ^| 1 ^| 1 ^| 0 ^| 0 ^| 1 ^| 1 ^| 0 ^| 0 ^| 0 ^| 1 ^| 0 ^| 1 ^| 1 ^| 1 ^| 0 ^| 0 ^| 1 ^| 1 ^| 0 ^| 0 ^| 0 ^| 1 @@ -561,12 +538,12 @@ using <> with weights from the two-bit index row of ^| 1 ^| 1 ^| 0 ^| 0 ^| 0 ^| 0 ^| 1 ^| 1 ^| 1 ^| 1 ^| 1 ^| 0 ^| 1 ^| 0 ^| 0 ^| 0 ^| 1 ^| 1 ^| 1 ^| 1 ^| 0 ^| 0 ^| 1 ^| 1 ^| 0 ^| 0 ^| 1 ^| 0 ^| 0 ^| 1 ^| 0 ^| 0 ^| 1 ^| 1 ^| 0 ^| 0 ^| 0 ^| 0 ^| 1 ^| 1 ^| 1 ^| 0 ^| 0 ^| 0 ^| 1 ^| 1 ^| 1 ^| 0 ^| 0 ^| 0 ^| 1 ^| 1 ^| 1 ^| 1 ^| 1 ^| 1 ^| 1 ^| 1 ^| 1 ^| 0 ^| 0 ^| 1 ^| 1 ^| 1 ^| 1 ^| 0 ^| 0 ^| *_1_* ^| 1 ^| 0 ^| 0 ^| *_1_* ^| 0 ^| 0 ^| 0 ^| *_1_* ^| 0 ^| 1 ^| 1 ^| *_1_* ^| 0 ^| 0 ^| 1 ^| *_1_* ^| 0 ^| 0 ^| 0 ^| 0 ^| 1 ^| 1 ^| 1 ^| 0 ^| 0 ^| 1 ^| 1 ^| *_1_* -|================== +|==== [[bptcP3subset]] .Partition table for 3-subset BPTC, with the 4×4 block of values for each partition number [cols="5,5,5,5,1,5,5,5,5,1,5,5,5,5,1,5,5,5,5,1,5,5,5,5,1,5,5,5,5,1,5,5,5,5,1,5,5,5,5",width="97%"] -|=============== +|==== 4+^| ~0~ 1.40+| 4+^| ~1~ 1.40+| 4+^| ~2~ 1.40+| 4+^| ~3~ 1.40+| 4+^| ~4~ 1.40+| 4+^| ~5~ 1.40+| 4+^| ~6~ 1.40+| 4+^| ~7~ ^| *_0_* ^| 0 ^| 1 ^| *_1_* ^| *_0_* ^| 0 ^| 0 ^| *_1_* ^| *_0_* ^| 0 ^| 0 ^| 0 ^| *_0_* ^| 2 ^| 2 ^| *_2_* ^| *_0_* ^| 0 ^| 0 ^| 0 ^| *_0_* ^| 0 ^| 1 ^| *_1_* ^| *_0_* ^| 0 ^| 2 ^| *_2_* ^| *_0_* ^| 0 ^| 1 ^| 1 ^| 0 ^| 0 ^| 1 ^| 1 ^| 0 ^| 0 ^| 1 ^| 1 ^| 2 ^| 0 ^| 0 ^| 1 ^| 0 ^| 0 ^| 2 ^| 2 ^| 0 ^| 0 ^| 0 ^| 0 ^| 0 ^| 0 ^| 1 ^| 1 ^| 0 ^| 0 ^| 2 ^| 2 ^| 0 ^| 0 ^| 1 ^| 1 @@ -614,12 +591,12 @@ using <> with weights from the two-bit index row of ^| 0 ^| *_1_* ^| 1 ^| 0 ^| 0 ^| 0 ^| 1 ^| 1 ^| 1 ^| 1 ^| 2 ^| 2 ^| 0 ^| 0 ^| 0 ^| 0 ^| 0 ^| 0 ^| 0 ^| 1 ^| 1 ^| 2 ^| 2 ^| 2 ^| 2 ^| 2 ^| 2 ^| 2 ^| 2 ^| 0 ^| 1 ^| 1 ^| 2 ^| 2 ^| 2 ^| 2 ^| 0 ^| 0 ^| *_1_* ^| 1 ^| *_1_* ^| 1 ^| 2 ^| 2 ^| 0 ^| 0 ^| 0 ^| 0 ^| 0 ^| 0 ^| 0 ^| 2 ^| 0 ^| 2 ^| 2 ^| 2 ^| 2 ^| 2 ^| 2 ^| 2 ^| *_2_* ^| 2 ^| 0 ^| 1 ^| 2 ^| 2 ^| 2 ^| *_2_* ^| 0 ^| 0 ^| 2 ^| *_2_* ^| 0 ^| 0 ^| 2 ^| *_2_* ^| 2 ^| *_1_* ^| 1 ^| *_2_* ^| 0 ^| 0 ^| 0 ^| *_1_* ^| *_1_* ^| 2 ^| 2 ^| *_2_* ^| 2 ^| 2 ^| 2 ^| *_2_* ^| 2 ^| 2 ^| 2 ^| 0 -|========== +|==== [[bptcA32index]] .BPTC anchor index values for the second subset of three-subset partitioning, by partition number [width="40%"] -|================ +|==== ^| ~0~ ^| ~1~ ^| ~2~ ^| ~3~ ^| ~4~ ^| ~5~ ^| ~6~ ^| ~7~ ^| 3 ^| 3 ^| 15 ^| 15 ^| 8 ^| 3 ^| 15 ^| 15 ^| ~8~ ^| ~9~ ^| ~10~ ^| ~11~ ^| ~12~ ^| ~13~ ^| ~14~ ^| ~15~ @@ -636,12 +613,12 @@ using <> with weights from the two-bit index row of ^| 3 ^| 15 ^| 5 ^| 5 ^| 5 ^| 8 ^| 5 ^| 10 ^| ~56~ ^| ~57~ ^| ~58~ ^| ~59~ ^| ~60~ ^| ~61~ ^| ~62~ ^| ~63~ ^| 5 ^| 10 ^| 8 ^| 13 ^| 15 ^| 12 ^| 3 ^| 3 -|================ +|==== [[bptcA33index]] .BPTC anchor index values for the third subset of three-subset partitioning, by partition number [width="40%"] -|=============== +|==== ^| ~0~ ^| ~1~ ^| ~2~ ^| ~3~ ^| ~4~ ^| ~5~ ^| ~6~ ^| ~7~ ^| 15 ^| 8 ^| 8 ^| 3 ^| 15 ^| 15 ^| 3 ^| 8 ^| ~8~ ^| ~9~ ^| ~10~ ^| ~11~ ^| ~12~ ^| ~13~ ^| ~14~ ^| ~15~ @@ -658,21 +635,13 @@ using <> with weights from the two-bit index row of ^| 15 ^| 3 ^| 15 ^| 15 ^| 15 ^| 15 ^| 15 ^| 15 ^| ~56~ ^| ~57~ ^| ~58~ ^| ~59~ ^| ~60~ ^| ~61~ ^| ~62~ ^| ~63~ ^| 15 ^| 15 ^| 15 ^| 15 ^| 3 ^| 15 ^| 15 ^| 8 -|=============== - - -ifndef::a2xhtml[] -<<< - -  +|==== -<<< -endif::[] [[bptcA2index]] .BPTC anchor index values for the second subset of two-subset partitioning, by partition number [width="40%"] -|============== +|==== ^| ~0~ ^| ~1~ ^| ~2~ ^| ~3~ ^| ~4~ ^| ~5~ ^| ~6~ ^| ~7~ ^| 15 ^| 15 ^| 15 ^| 15 ^| 15 ^| 15 ^| 15 ^| 15 ^| ~8~ ^| ~9~ ^| ~10~ ^| ~11~ ^| ~12~ ^| ~13~ ^| ~14~ ^| ~15~ @@ -689,19 +658,7 @@ endif::[] ^| 6 ^| 2 ^| 6 ^| 8 ^| 15 ^| 15 ^| 2 ^| 2 ^| ~56~ ^| ~57~ ^| ~58~ ^| ~59~ ^| ~60~ ^| ~61~ ^| ~62~ ^| ~63~ ^| 15 ^| 15 ^| 15 ^| 15 ^| 15 ^| 2 ^| 2 ^| 15 -|============== - -ifndef::a2xhtml[] -<<< - -  - -<<< - -  - -<<< -endif::[] +|==== Interpolation is always performed using a 6-bit interpolation factor. The effective interpolation factors for 2-, 3-, and 4-bit indices are @@ -710,14 +667,14 @@ given in <>. [[BPTCInterpolation]] .BPTC interpolation factors [cols="h,18*",width="85%"] -|========== +|==== .2+^.^| 2 2+^| Index 4+^| ~0~ 4+^| ~1~ 4+^| ~2~ 4+^| ~3~ 2+^| _Weight_ 4+^| 0 4+^| 21 4+^| 43 4+^| 64 .2+^.^| 3 2+^| Index 2+^| ~0~ 2+^| ~1~ 2+^| ~2~ 2+^| ~3~ 2+^| ~4~ 2+^| ~5~ 2+^| ~6~ 2+^| ~7~ 2+^| _Weight_ 2+^| 0 2+^| 9 2+^| 18 2+^| 27 2+^| 37 2+^| 46 2+^| 55 2+^| 64 .2+^.^| 4 2+^| Index ^| ~0~ ^| ~1~ ^| ~2~ ^| ~3~ ^| ~4~ ^| ~5~ ^| ~6~ ^| ~7~ ^| ~8~ ^| ~9~ ^| ~10~ ^| ~11~ ^| ~12~ ^| ~13~ ^| ~14~ ^| ~15~ 2+^| _Weight_ ^| 0 ^| 4 ^| 9 ^| 13 ^| 17 ^| 21 ^| 26 ^| 30 ^| 34 ^| 38 ^| 43 ^| 47 ^| 51 ^| 55 ^| 60 ^| 64 -|========== +|==== // Note: The interpolation formula is not explicitly present in the OpenGL Specification. // Since bit-exact interpolation is mandated by some implementations, the following formula is @@ -729,13 +686,13 @@ as an unsigned integer interpolation factor from <>: [[BPTCinterpolation]] .BPTC endpoint interpolation formula [latexmath] -++++++++++++++ +++++ \begin{align*} \mathit{interpolated\ value} & = ((64 - \mathit{weight}) \times \textit{E}_0 + \mathit{weight} \times \textit{E}_1 + 32) \gg 6 \end{align*} -++++++++++++++ +++++ -where latexmath:[$\gg$] performs a (truncating) bitwise right-shift, and +where latexmath:[\gg] performs a (truncating) bitwise right-shift, and _interpolated value_ is an (unsigned) integer in the range [0..255]. The interpolation results in an _RGBA_ color. If rotation bits are present, this interpolated color is remapped according to <>. @@ -743,15 +700,15 @@ this interpolated color is remapped according to <>. [[BPTCRotation]] .BPTC Rotation bits [cols="h,3",width="20%"] -|============ +|==== ^| 0 ^| no change ^| 1 ^| _swap_(_A_, _R_) ^| 2 ^| _swap_(_A_, _G_) ^| 3 ^| _swap_(_A_, _B_) -|============ +|==== These 8-bit values should be interpreted as _RGBA_ 8-bit normalized channels, -either linearly encoded (by multiplying by latexmath:[$1\over 255$]) or +either linearly encoded (by multiplying by latexmath:[1\over 255]) or with the <>. <<< @@ -765,7 +722,7 @@ In the description and pseudocode below, _signed_ will be used as a condition wh for the signed version of the format and false for the unsigned version of the format. Both formats only contain _RGB_ data, so the returned alpha value is 1.0. If a block uses a reserved or invalid encoding, the return value is -(0.0, 0.0, 0.0, 1.0). +(0.0,{nbsp}0.0,{nbsp}0.0,{nbsp}1.0). [NOTE] ==== @@ -778,12 +735,12 @@ Each block can contain data in one of 14 modes. The mode number is encoded in either the low two bits or the low five bits. If the low two bits are less than two, that is the mode number, otherwise the low five bits is the mode number. Mode numbers not listed in <> -(19, 23, 27, and 31) are reserved. +(19,{nbsp}23,{nbsp}27,{nbsp}and{nbsp}31) are reserved. [[table-bptcblockmodes]] .Endpoint and partition parameters for BPTC block modes [width="100%",cols="10%,15%,20%,20%,10%,1%,7%,10%,7%"] -|============== +|==== .2+^.^| *Mode number* .2+^.^| *Transformed endpoints* ^.^| *Partition bits (PB)* ^.^| *Endpoint bits (EPB)* ^.^| *Delta bits* 1.16+| ^.^| *Mode* ^.^| *Endpoint* ^.^| *Delta* ^| Bits per texel block 2+^| {_R_,_G_,_B_} bits per endpoint 3+^| Bits per texel block (total) ^| *0* ^| {check} ^| 5 ^| {10, 10, 10} ^| {5, 5, 5} ^| 2 ^| 30 ^| 45 @@ -800,7 +757,7 @@ number. Mode numbers not listed in <> ^| *7* ^| {check} ^| 0 ^| {11, 11, 11} ^| {9, 9, 9} ^| 5 ^| 33 ^| 27 ^| *11* ^| {check} ^| 0 ^| {12, 12, 12} ^| {8, 8, 8} ^| 5 ^| 36 ^| 24 ^| *15* ^| {check} ^| 0 ^| {16, 16, 16} ^| {4, 4, 4} ^| 5 ^| 48 ^| 12 -|============== +|==== The data for the compressed blocks is stored in a different manner for each mode. @@ -828,7 +785,7 @@ The partition number references the first half of <>. [[table-bptcblockformat]] .Block descriptions for BC6H block modes (LSB..MSB) [options="header",cols="3,13",width="85%"] -|=========================== +|==== ^| Mode Number ^| Block description ^.^| 0 ^.^| M^1..0^, _G_~2~^4^, _B_~2~^4^, _B_~3~^4^, _R_~0~^9..0^, _G_~0~^9..0^, _B_~0~^9..0^, _R_~1~^4..0^, _G_~3~^4^, _G_~2~^3..0^, _G_~1~^4..0^, _B_~3~^0^, _G_~3~^3..0^, _B_~1~^4..0^, _B_~3~^1^, _B_~2~^3..0^, @@ -869,7 +826,7 @@ The partition number references the first half of <>. _G_~0~^10..11^, _B_~1~^7..0^, _B_~0~^10..11^ ^.^| 15 ^.^| M^4..0^, _R_~0~^9..0^, _G_~0~^9..0^, _B_~0~^9..0^, _R_~1~^3..0^, _R_~0~^10..15^, _G_~1~^3..0^, _G_~0~^10..15^, _B_~1~^3..0^, _B_~0~^10..15^ -|========================== +|==== Indices are read in the same way as the BC7 formats including obeying the anchor values for index 0 and as needed by <>. @@ -884,7 +841,7 @@ In both cases, index bits are stored in y-major offset order by increasing little-endian bit number, with the bits for each index stored consecutively: [latexmath] -++++++++++++++ +++++ \begin{align*} {\textrm{Bit offset of IB}_{x,y}}^0 &= \begin{cases} 65, & 1\ \textrm{subset},\ x = y = 0 \\ @@ -894,105 +851,105 @@ little-endian bit number, with the bits for each index stored consecutively: 82 + 3 \times (x + 4\times y) - 2, & 2\ \textrm{subsets},\ \textrm{anchor}_2[\mathit{part}] < x + 4\times y \\ \end{cases} \\ \end{align*} -++++++++++++++ +++++ [[table-bptcbc6hbits]] .Interpretation of lower bits for BC6H block modes [width="85%", cols=">1,14*^1"] -|================ +|==== >| 14+^| *Mode* ^| *Bit* | *0* | *1* | *2* | *6* | *10* | *14* | *18* | *22* | *26* | *30* | *3* | *7* | *11* | *15* ->| *0*   | M^0^: *0* | M^0^: *1* | M^0^: *0* | M^0^: *0* | M^0^: *0* | M^0^: *0* | M^0^: *0* | M^0^: *0* | M^0^: *0* | M^0^: *0* | M^0^: *1* | M^0^: *1* | M^0^: *1* | M^0^: *1* ->| *1*   | M^1^: *0* | M^1^: *0* | M^1^: *1* | M^1^: *1* | M^1^: *1* | M^1^: *1* | M^1^: *1* | M^1^: *1* | M^1^: *1* | M^1^: *1* | M^1^: *1* | M^1^: *1* | M^1^: *1* | M^1^: *1* ->| *2*   | _G_~2~^4^ | _G_~2~^5^ | M^2^: *0* | M^2^: *1* | M^2^: *0* | M^2^: *1* | M^2^: *0* | M^2^: *1* | M^2^: *0* | M^2^: *1* | M^2^: *0* | M^2^: *1* | M^2^: *0* | M^2^: *1* ->| *3*   | _B_~2~^4^ | _G_~3~^4^ | M^3^: *0* | M^3^: *0* | M^3^: *1* | M^3^: *1* | M^3^: *0* | M^3^: *0* | M^3^: *1* | M^3^: *1* | M^3^: *0* | M^3^: *0* | M^3^: *1* | M^3^: *1* ->| *4*   | _B_~3~^4^ | _G_~3~^5^ | M^4^: *0* | M^4^: *0* | M^4^: *0* | M^4^: *0* | M^4^: *1* | M^4^: *1* | M^4^: *1* | M^4^: *1* | M^4^: *0* | M^4^: *0* | M^4^: *0* | M^4^: *0* ->| *5*   | _R_~0~^0^ | _R_~0~^0^ | _R_~0~^0^ | _R_~0~^0^ | _R_~0~^0^ | _R_~0~^0^ | _R_~0~^0^ | _R_~0~^0^ | _R_~0~^0^ | _R_~0~^0^ | _R_~0~^0^ | _R_~0~^0^ | _R_~0~^0^ | _R_~0~^0^ ->| *6*   | _R_~0~^1^ | _R_~0~^1^ | _R_~0~^1^ | _R_~0~^1^ | _R_~0~^1^ | _R_~0~^1^ | _R_~0~^1^ | _R_~0~^1^ | _R_~0~^1^ | _R_~0~^1^ | _R_~0~^1^ | _R_~0~^1^ | _R_~0~^1^ | _R_~0~^1^ ->| *7*   | _R_~0~^2^ | _R_~0~^2^ | _R_~0~^2^ | _R_~0~^2^ | _R_~0~^2^ | _R_~0~^2^ | _R_~0~^2^ | _R_~0~^2^ | _R_~0~^2^ | _R_~0~^2^ | _R_~0~^2^ | _R_~0~^2^ | _R_~0~^2^ | _R_~0~^2^ ->| *8*   | _R_~0~^3^ | _R_~0~^3^ | _R_~0~^3^ | _R_~0~^3^ | _R_~0~^3^ | _R_~0~^3^ | _R_~0~^3^ | _R_~0~^3^ | _R_~0~^3^ | _R_~0~^3^ | _R_~0~^3^ | _R_~0~^3^ | _R_~0~^3^ | _R_~0~^3^ ->| *9*   | _R_~0~^4^ | _R_~0~^4^ | _R_~0~^4^ | _R_~0~^4^ | _R_~0~^4^ | _R_~0~^4^ | _R_~0~^4^ | _R_~0~^4^ | _R_~0~^4^ | _R_~0~^4^ | _R_~0~^4^ | _R_~0~^4^ | _R_~0~^4^ | _R_~0~^4^ ->| *10*   | _R_~0~^5^ | _R_~0~^5^ | _R_~0~^5^ | _R_~0~^5^ | _R_~0~^5^ | _R_~0~^5^ | _R_~0~^5^ | _R_~0~^5^ | _R_~0~^5^ | _R_~0~^5^ | _R_~0~^5^ | _R_~0~^5^ | _R_~0~^5^ | _R_~0~^5^ ->| *11*   | _R_~0~^6^ | _R_~0~^6^ | _R_~0~^6^ | _R_~0~^6^ | _R_~0~^6^ | _R_~0~^6^ | _R_~0~^6^ | _R_~0~^6^ | _R_~0~^6^ | _G_~3~^4^ | _R_~0~^6^ | _R_~0~^6^ | _R_~0~^6^ | _R_~0~^6^ ->| *12*   | _R_~0~^7^ | _B_~3~^0^ | _R_~0~^7^ | _R_~0~^7^ | _R_~0~^7^ | _R_~0~^7^ | _R_~0~^7^ | _R_~0~^7^ | _R_~0~^7^ | _B_~3~^0^ | _R_~0~^7^ | _R_~0~^7^ | _R_~0~^7^ | _R_~0~^7^ ->| *13*   | _R_~0~^8^ | _B_~3~^1^ | _R_~0~^8^ | _R_~0~^8^ | _R_~0~^8^ | _R_~0~^8^ | _G_~3~^4^ | _B_~3~^0^ | _B_~3~^1^ | _B_~3~^1^ | _R_~0~^8^ | _R_~0~^8^ | _R_~0~^8^ | _R_~0~^8^ ->| *14*   | _R_~0~^9^ | _B_~2~^4^ | _R_~0~^9^ | _R_~0~^9^ | _R_~0~^9^ | _B_~2~^4^ | _B_~2~^4^ | _B_~2~^4^ | _B_~2~^4^ | _B_~2~^4^ | _R_~0~^9^ | _R_~0~^9^ | _R_~0~^9^ | _R_~0~^9^ ->| *15*   | _G_~0~^0^ | _G_~0~^0^ | _G_~0~^0^ | _G_~0~^0^ | _G_~0~^0^ | _G_~0~^0^ | _G_~0~^0^ | _G_~0~^0^ | _G_~0~^0^ | _G_~0~^0^ | _G_~0~^0^ | _G_~0~^0^ | _G_~0~^0^ | _G_~0~^0^ ->| *16*   | _G_~0~^1^ | _G_~0~^1^ | _G_~0~^1^ | _G_~0~^1^ | _G_~0~^1^ | _G_~0~^1^ | _G_~0~^1^ | _G_~0~^1^ | _G_~0~^1^ | _G_~0~^1^ | _G_~0~^1^ | _G_~0~^1^ | _G_~0~^1^ | _G_~0~^1^ ->| *17*   | _G_~0~^2^ | _G_~0~^2^ | _G_~0~^2^ | _G_~0~^2^ | _G_~0~^2^ | _G_~0~^2^ | _G_~0~^2^ | _G_~0~^2^ | _G_~0~^2^ | _G_~0~^2^ | _G_~0~^2^ | _G_~0~^2^ | _G_~0~^2^ | _G_~0~^2^ ->| *18*   | _G_~0~^3^ | _G_~0~^3^ | _G_~0~^3^ | _G_~0~^3^ | _G_~0~^3^ | _G_~0~^3^ | _G_~0~^3^ | _G_~0~^3^ | _G_~0~^3^ | _G_~0~^3^ | _G_~0~^3^ | _G_~0~^3^ | _G_~0~^3^ | _G_~0~^3^ ->| *19*   | _G_~0~^4^ | _G_~0~^4^ | _G_~0~^4^ | _G_~0~^4^ | _G_~0~^4^ | _G_~0~^4^ | _G_~0~^4^ | _G_~0~^4^ | _G_~0~^4^ | _G_~0~^4^ | _G_~0~^4^ | _G_~0~^4^ | _G_~0~^4^ | _G_~0~^4^ ->| *20*   | _G_~0~^5^ | _G_~0~^5^ | _G_~0~^5^ | _G_~0~^5^ | _G_~0~^5^ | _G_~0~^5^ | _G_~0~^5^ | _G_~0~^5^ | _G_~0~^5^ | _G_~0~^5^ | _G_~0~^5^ | _G_~0~^5^ | _G_~0~^5^ | _G_~0~^5^ ->| *21*   | _G_~0~^6^ | _G_~0~^6^ | _G_~0~^6^ | _G_~0~^6^ | _G_~0~^6^ | _G_~0~^6^ | _G_~0~^6^ | _G_~0~^6^ | _G_~0~^6^ | _G_~2~^5^ | _G_~0~^6^ | _G_~0~^6^ | _G_~0~^6^ | _G_~0~^6^ ->| *22*   | _G_~0~^7^ | _B_~2~^5^ | _G_~0~^7^ | _G_~0~^7^ | _G_~0~^7^ | _G_~0~^7^ | _G_~0~^7^ | _G_~0~^7^ | _G_~0~^7^ | _B_~2~^5^ | _G_~0~^7^ | _G_~0~^7^ | _G_~0~^7^ | _G_~0~^7^ ->| *23*   | _G_~0~^8^ | _B_~3~^2^ | _G_~0~^8^ | _G_~0~^8^ | _G_~0~^8^ | _G_~0~^8^ | _B_~3~^2^ | _G_~2~^5^ | _B_~2~^5^ | _B_~3~^2^ | _G_~0~^8^ | _G_~0~^8^ | _G_~0~^8^ | _G_~0~^8^ ->| *24*   | _G_~0~^9^ | _G_~2~^4^ | _G_~0~^9^ | _G_~0~^9^ | _G_~0~^9^ | _G_~2~^4^ | _G_~2~^4^ | _G_~2~^4^ | _G_~2~^4^ | _G_~2~^4^ | _G_~0~^9^ | _G_~0~^9^ | _G_~0~^9^ | _G_~0~^9^ ->| *25*   | _B_~0~^0^ | _B_~0~^0^ | _B_~0~^0^ | _B_~0~^0^ | _B_~0~^0^ | _B_~0~^0^ | _B_~0~^0^ | _B_~0~^0^ | _B_~0~^0^ | _B_~0~^0^ | _B_~0~^0^ | _B_~0~^0^ | _B_~0~^0^ | _B_~0~^0^ ->| *26*   | _B_~0~^1^ | _B_~0~^1^ | _B_~0~^1^ | _B_~0~^1^ | _B_~0~^1^ | _B_~0~^1^ | _B_~0~^1^ | _B_~0~^1^ | _B_~0~^1^ | _B_~0~^1^ | _B_~0~^1^ | _B_~0~^1^ | _B_~0~^1^ | _B_~0~^1^ ->| *27*   | _B_~0~^2^ | _B_~0~^2^ | _B_~0~^2^ | _B_~0~^2^ | _B_~0~^2^ | _B_~0~^2^ | _B_~0~^2^ | _B_~0~^2^ | _B_~0~^2^ | _B_~0~^2^ | _B_~0~^2^ | _B_~0~^2^ | _B_~0~^2^ | _B_~0~^2^ ->| *28*   | _B_~0~^3^ | _B_~0~^3^ | _B_~0~^3^ | _B_~0~^3^ | _B_~0~^3^ | _B_~0~^3^ | _B_~0~^3^ | _B_~0~^3^ | _B_~0~^3^ | _B_~0~^3^ | _B_~0~^3^ | _B_~0~^3^ | _B_~0~^3^ | _B_~0~^3^ ->| *29*   | _B_~0~^4^ | _B_~0~^4^ | _B_~0~^4^ | _B_~0~^4^ | _B_~0~^4^ | _B_~0~^4^ | _B_~0~^4^ | _B_~0~^4^ | _B_~0~^4^ | _B_~0~^4^ | _B_~0~^4^ | _B_~0~^4^ | _B_~0~^4^ | _B_~0~^4^ ->| *30*   | _B_~0~^5^ | _B_~0~^5^ | _B_~0~^5^ | _B_~0~^5^ | _B_~0~^5^ | _B_~0~^5^ | _B_~0~^5^ | _B_~0~^5^ | _B_~0~^5^ | _B_~0~^5^ | _B_~0~^5^ | _B_~0~^5^ | _B_~0~^5^ | _B_~0~^5^ ->| *31*   | _B_~0~^6^ | _B_~0~^6^ | _B_~0~^6^ | _B_~0~^6^ | _B_~0~^6^ | _B_~0~^6^ | _B_~0~^6^ | _B_~0~^6^ | _B_~0~^6^ | _G_~3~^5^ | _B_~0~^6^ | _B_~0~^6^ | _B_~0~^6^ | _B_~0~^6^ ->| *32*   | _B_~0~^7^ | _B_~3~^3^ | _B_~0~^7^ | _B_~0~^7^ | _B_~0~^7^ | _B_~0~^7^ | _B_~0~^7^ | _B_~0~^7^ | _B_~0~^7^ | _B_~3~^3^ | _B_~0~^7^ | _B_~0~^7^ | _B_~0~^7^ | _B_~0~^7^ ->| *33*   | _B_~0~^8^ | _B_~3~^5^ | _B_~0~^8^ | _B_~0~^8^ | _B_~0~^8^ | _B_~0~^8^ | _B_~3~^3^ | _G_~3~^5^ | _B_~3~^5^ | _B_~3~^5^ | _B_~0~^8^ | _B_~0~^8^ | _B_~0~^8^ | _B_~0~^8^ ->| *34*   | _B_~0~^9^ | _B_~3~^4^ | _B_~0~^9^ | _B_~0~^9^ | _B_~0~^9^ | _B_~3~^4^ | _B_~3~^4^ | _B_~3~^4^ | _B_~3~^4^ | _B_~3~^4^ | _B_~0~^9^ | _B_~0~^9^ | _B_~0~^9^ | _B_~0~^9^ ->| *35*   | _R_~1~^0^ | _R_~1~^0^ | _R_~1~^0^ | _R_~1~^0^ | _R_~1~^0^ | _R_~1~^0^ | _R_~1~^0^ | _R_~1~^0^ | _R_~1~^0^ | _R_~1~^0^ | _R_~1~^0^ | _R_~1~^0^ | _R_~1~^0^ | _R_~1~^0^ ->| *36*   | _R_~1~^1^ | _R_~1~^1^ | _R_~1~^1^ | _R_~1~^1^ | _R_~1~^1^ | _R_~1~^1^ | _R_~1~^1^ | _R_~1~^1^ | _R_~1~^1^ | _R_~1~^1^ | _R_~1~^1^ | _R_~1~^1^ | _R_~1~^1^ | _R_~1~^1^ ->| *37*   | _R_~1~^2^ | _R_~1~^2^ | _R_~1~^2^ | _R_~1~^2^ | _R_~1~^2^ | _R_~1~^2^ | _R_~1~^2^ | _R_~1~^2^ | _R_~1~^2^ | _R_~1~^2^ | _R_~1~^2^ | _R_~1~^2^ | _R_~1~^2^ | _R_~1~^2^ ->| *38*   | _R_~1~^3^ | _R_~1~^3^ | _R_~1~^3^ | _R_~1~^3^ | _R_~1~^3^ | _R_~1~^3^ | _R_~1~^3^ | _R_~1~^3^ | _R_~1~^3^ | _R_~1~^3^ | _R_~1~^3^ | _R_~1~^3^ | _R_~1~^3^ | _R_~1~^3^ ->| *39*   | _R_~1~^4^ | _R_~1~^4^ | _R_~1~^4^ | _R_~0~^10^ | _R_~0~^10^ | _R_~1~^4^ | _R_~1~^4^ | _R_~1~^4^ | _R_~1~^4^ | _R_~1~^4^ | _R_~1~^4^ | _R_~1~^4^ | _R_~1~^4^ | _R_~0~^15^ ->| *40*   | _G_~3~^4^ | _R_~1~^5^ | _R_~0~^10^ | _G_~3~^4^ | _B_~2~^4^ | _G_~3~^4^ | _R_~1~^5^ | _G_~3~^4^ | _G_~3~^4^ | _R_~1~^5^ | _R_~1~^5^ | _R_~1~^5^ | _R_~1~^5^ | _R_~0~^14^ -|================ +>| *0* {nbsp} | M^0^: *0* | M^0^: *1* | M^0^: *0* | M^0^: *0* | M^0^: *0* | M^0^: *0* | M^0^: *0* | M^0^: *0* | M^0^: *0* | M^0^: *0* | M^0^: *1* | M^0^: *1* | M^0^: *1* | M^0^: *1* +>| *1* {nbsp} | M^1^: *0* | M^1^: *0* | M^1^: *1* | M^1^: *1* | M^1^: *1* | M^1^: *1* | M^1^: *1* | M^1^: *1* | M^1^: *1* | M^1^: *1* | M^1^: *1* | M^1^: *1* | M^1^: *1* | M^1^: *1* +>| *2* {nbsp} | _G_~2~^4^ | _G_~2~^5^ | M^2^: *0* | M^2^: *1* | M^2^: *0* | M^2^: *1* | M^2^: *0* | M^2^: *1* | M^2^: *0* | M^2^: *1* | M^2^: *0* | M^2^: *1* | M^2^: *0* | M^2^: *1* +>| *3* {nbsp} | _B_~2~^4^ | _G_~3~^4^ | M^3^: *0* | M^3^: *0* | M^3^: *1* | M^3^: *1* | M^3^: *0* | M^3^: *0* | M^3^: *1* | M^3^: *1* | M^3^: *0* | M^3^: *0* | M^3^: *1* | M^3^: *1* +>| *4* {nbsp} | _B_~3~^4^ | _G_~3~^5^ | M^4^: *0* | M^4^: *0* | M^4^: *0* | M^4^: *0* | M^4^: *1* | M^4^: *1* | M^4^: *1* | M^4^: *1* | M^4^: *0* | M^4^: *0* | M^4^: *0* | M^4^: *0* +>| *5* {nbsp} | _R_~0~^0^ | _R_~0~^0^ | _R_~0~^0^ | _R_~0~^0^ | _R_~0~^0^ | _R_~0~^0^ | _R_~0~^0^ | _R_~0~^0^ | _R_~0~^0^ | _R_~0~^0^ | _R_~0~^0^ | _R_~0~^0^ | _R_~0~^0^ | _R_~0~^0^ +>| *6* {nbsp} | _R_~0~^1^ | _R_~0~^1^ | _R_~0~^1^ | _R_~0~^1^ | _R_~0~^1^ | _R_~0~^1^ | _R_~0~^1^ | _R_~0~^1^ | _R_~0~^1^ | _R_~0~^1^ | _R_~0~^1^ | _R_~0~^1^ | _R_~0~^1^ | _R_~0~^1^ +>| *7* {nbsp} | _R_~0~^2^ | _R_~0~^2^ | _R_~0~^2^ | _R_~0~^2^ | _R_~0~^2^ | _R_~0~^2^ | _R_~0~^2^ | _R_~0~^2^ | _R_~0~^2^ | _R_~0~^2^ | _R_~0~^2^ | _R_~0~^2^ | _R_~0~^2^ | _R_~0~^2^ +>| *8* {nbsp} | _R_~0~^3^ | _R_~0~^3^ | _R_~0~^3^ | _R_~0~^3^ | _R_~0~^3^ | _R_~0~^3^ | _R_~0~^3^ | _R_~0~^3^ | _R_~0~^3^ | _R_~0~^3^ | _R_~0~^3^ | _R_~0~^3^ | _R_~0~^3^ | _R_~0~^3^ +>| *9* {nbsp} | _R_~0~^4^ | _R_~0~^4^ | _R_~0~^4^ | _R_~0~^4^ | _R_~0~^4^ | _R_~0~^4^ | _R_~0~^4^ | _R_~0~^4^ | _R_~0~^4^ | _R_~0~^4^ | _R_~0~^4^ | _R_~0~^4^ | _R_~0~^4^ | _R_~0~^4^ +>| *10* {nbsp} | _R_~0~^5^ | _R_~0~^5^ | _R_~0~^5^ | _R_~0~^5^ | _R_~0~^5^ | _R_~0~^5^ | _R_~0~^5^ | _R_~0~^5^ | _R_~0~^5^ | _R_~0~^5^ | _R_~0~^5^ | _R_~0~^5^ | _R_~0~^5^ | _R_~0~^5^ +>| *11* {nbsp} | _R_~0~^6^ | _R_~0~^6^ | _R_~0~^6^ | _R_~0~^6^ | _R_~0~^6^ | _R_~0~^6^ | _R_~0~^6^ | _R_~0~^6^ | _R_~0~^6^ | _G_~3~^4^ | _R_~0~^6^ | _R_~0~^6^ | _R_~0~^6^ | _R_~0~^6^ +>| *12* {nbsp} | _R_~0~^7^ | _B_~3~^0^ | _R_~0~^7^ | _R_~0~^7^ | _R_~0~^7^ | _R_~0~^7^ | _R_~0~^7^ | _R_~0~^7^ | _R_~0~^7^ | _B_~3~^0^ | _R_~0~^7^ | _R_~0~^7^ | _R_~0~^7^ | _R_~0~^7^ +>| *13* {nbsp} | _R_~0~^8^ | _B_~3~^1^ | _R_~0~^8^ | _R_~0~^8^ | _R_~0~^8^ | _R_~0~^8^ | _G_~3~^4^ | _B_~3~^0^ | _B_~3~^1^ | _B_~3~^1^ | _R_~0~^8^ | _R_~0~^8^ | _R_~0~^8^ | _R_~0~^8^ +>| *14* {nbsp} | _R_~0~^9^ | _B_~2~^4^ | _R_~0~^9^ | _R_~0~^9^ | _R_~0~^9^ | _B_~2~^4^ | _B_~2~^4^ | _B_~2~^4^ | _B_~2~^4^ | _B_~2~^4^ | _R_~0~^9^ | _R_~0~^9^ | _R_~0~^9^ | _R_~0~^9^ +>| *15* {nbsp} | _G_~0~^0^ | _G_~0~^0^ | _G_~0~^0^ | _G_~0~^0^ | _G_~0~^0^ | _G_~0~^0^ | _G_~0~^0^ | _G_~0~^0^ | _G_~0~^0^ | _G_~0~^0^ | _G_~0~^0^ | _G_~0~^0^ | _G_~0~^0^ | _G_~0~^0^ +>| *16* {nbsp} | _G_~0~^1^ | _G_~0~^1^ | _G_~0~^1^ | _G_~0~^1^ | _G_~0~^1^ | _G_~0~^1^ | _G_~0~^1^ | _G_~0~^1^ | _G_~0~^1^ | _G_~0~^1^ | _G_~0~^1^ | _G_~0~^1^ | _G_~0~^1^ | _G_~0~^1^ +>| *17* {nbsp} | _G_~0~^2^ | _G_~0~^2^ | _G_~0~^2^ | _G_~0~^2^ | _G_~0~^2^ | _G_~0~^2^ | _G_~0~^2^ | _G_~0~^2^ | _G_~0~^2^ | _G_~0~^2^ | _G_~0~^2^ | _G_~0~^2^ | _G_~0~^2^ | _G_~0~^2^ +>| *18* {nbsp} | _G_~0~^3^ | _G_~0~^3^ | _G_~0~^3^ | _G_~0~^3^ | _G_~0~^3^ | _G_~0~^3^ | _G_~0~^3^ | _G_~0~^3^ | _G_~0~^3^ | _G_~0~^3^ | _G_~0~^3^ | _G_~0~^3^ | _G_~0~^3^ | _G_~0~^3^ +>| *19* {nbsp} | _G_~0~^4^ | _G_~0~^4^ | _G_~0~^4^ | _G_~0~^4^ | _G_~0~^4^ | _G_~0~^4^ | _G_~0~^4^ | _G_~0~^4^ | _G_~0~^4^ | _G_~0~^4^ | _G_~0~^4^ | _G_~0~^4^ | _G_~0~^4^ | _G_~0~^4^ +>| *20* {nbsp} | _G_~0~^5^ | _G_~0~^5^ | _G_~0~^5^ | _G_~0~^5^ | _G_~0~^5^ | _G_~0~^5^ | _G_~0~^5^ | _G_~0~^5^ | _G_~0~^5^ | _G_~0~^5^ | _G_~0~^5^ | _G_~0~^5^ | _G_~0~^5^ | _G_~0~^5^ +>| *21* {nbsp} | _G_~0~^6^ | _G_~0~^6^ | _G_~0~^6^ | _G_~0~^6^ | _G_~0~^6^ | _G_~0~^6^ | _G_~0~^6^ | _G_~0~^6^ | _G_~0~^6^ | _G_~2~^5^ | _G_~0~^6^ | _G_~0~^6^ | _G_~0~^6^ | _G_~0~^6^ +>| *22* {nbsp} | _G_~0~^7^ | _B_~2~^5^ | _G_~0~^7^ | _G_~0~^7^ | _G_~0~^7^ | _G_~0~^7^ | _G_~0~^7^ | _G_~0~^7^ | _G_~0~^7^ | _B_~2~^5^ | _G_~0~^7^ | _G_~0~^7^ | _G_~0~^7^ | _G_~0~^7^ +>| *23* {nbsp} | _G_~0~^8^ | _B_~3~^2^ | _G_~0~^8^ | _G_~0~^8^ | _G_~0~^8^ | _G_~0~^8^ | _B_~3~^2^ | _G_~2~^5^ | _B_~2~^5^ | _B_~3~^2^ | _G_~0~^8^ | _G_~0~^8^ | _G_~0~^8^ | _G_~0~^8^ +>| *24* {nbsp} | _G_~0~^9^ | _G_~2~^4^ | _G_~0~^9^ | _G_~0~^9^ | _G_~0~^9^ | _G_~2~^4^ | _G_~2~^4^ | _G_~2~^4^ | _G_~2~^4^ | _G_~2~^4^ | _G_~0~^9^ | _G_~0~^9^ | _G_~0~^9^ | _G_~0~^9^ +>| *25* {nbsp} | _B_~0~^0^ | _B_~0~^0^ | _B_~0~^0^ | _B_~0~^0^ | _B_~0~^0^ | _B_~0~^0^ | _B_~0~^0^ | _B_~0~^0^ | _B_~0~^0^ | _B_~0~^0^ | _B_~0~^0^ | _B_~0~^0^ | _B_~0~^0^ | _B_~0~^0^ +>| *26* {nbsp} | _B_~0~^1^ | _B_~0~^1^ | _B_~0~^1^ | _B_~0~^1^ | _B_~0~^1^ | _B_~0~^1^ | _B_~0~^1^ | _B_~0~^1^ | _B_~0~^1^ | _B_~0~^1^ | _B_~0~^1^ | _B_~0~^1^ | _B_~0~^1^ | _B_~0~^1^ +>| *27* {nbsp} | _B_~0~^2^ | _B_~0~^2^ | _B_~0~^2^ | _B_~0~^2^ | _B_~0~^2^ | _B_~0~^2^ | _B_~0~^2^ | _B_~0~^2^ | _B_~0~^2^ | _B_~0~^2^ | _B_~0~^2^ | _B_~0~^2^ | _B_~0~^2^ | _B_~0~^2^ +>| *28* {nbsp} | _B_~0~^3^ | _B_~0~^3^ | _B_~0~^3^ | _B_~0~^3^ | _B_~0~^3^ | _B_~0~^3^ | _B_~0~^3^ | _B_~0~^3^ | _B_~0~^3^ | _B_~0~^3^ | _B_~0~^3^ | _B_~0~^3^ | _B_~0~^3^ | _B_~0~^3^ +>| *29* {nbsp} | _B_~0~^4^ | _B_~0~^4^ | _B_~0~^4^ | _B_~0~^4^ | _B_~0~^4^ | _B_~0~^4^ | _B_~0~^4^ | _B_~0~^4^ | _B_~0~^4^ | _B_~0~^4^ | _B_~0~^4^ | _B_~0~^4^ | _B_~0~^4^ | _B_~0~^4^ +>| *30* {nbsp} | _B_~0~^5^ | _B_~0~^5^ | _B_~0~^5^ | _B_~0~^5^ | _B_~0~^5^ | _B_~0~^5^ | _B_~0~^5^ | _B_~0~^5^ | _B_~0~^5^ | _B_~0~^5^ | _B_~0~^5^ | _B_~0~^5^ | _B_~0~^5^ | _B_~0~^5^ +>| *31* {nbsp} | _B_~0~^6^ | _B_~0~^6^ | _B_~0~^6^ | _B_~0~^6^ | _B_~0~^6^ | _B_~0~^6^ | _B_~0~^6^ | _B_~0~^6^ | _B_~0~^6^ | _G_~3~^5^ | _B_~0~^6^ | _B_~0~^6^ | _B_~0~^6^ | _B_~0~^6^ +>| *32* {nbsp} | _B_~0~^7^ | _B_~3~^3^ | _B_~0~^7^ | _B_~0~^7^ | _B_~0~^7^ | _B_~0~^7^ | _B_~0~^7^ | _B_~0~^7^ | _B_~0~^7^ | _B_~3~^3^ | _B_~0~^7^ | _B_~0~^7^ | _B_~0~^7^ | _B_~0~^7^ +>| *33* {nbsp} | _B_~0~^8^ | _B_~3~^5^ | _B_~0~^8^ | _B_~0~^8^ | _B_~0~^8^ | _B_~0~^8^ | _B_~3~^3^ | _G_~3~^5^ | _B_~3~^5^ | _B_~3~^5^ | _B_~0~^8^ | _B_~0~^8^ | _B_~0~^8^ | _B_~0~^8^ +>| *34* {nbsp} | _B_~0~^9^ | _B_~3~^4^ | _B_~0~^9^ | _B_~0~^9^ | _B_~0~^9^ | _B_~3~^4^ | _B_~3~^4^ | _B_~3~^4^ | _B_~3~^4^ | _B_~3~^4^ | _B_~0~^9^ | _B_~0~^9^ | _B_~0~^9^ | _B_~0~^9^ +>| *35* {nbsp} | _R_~1~^0^ | _R_~1~^0^ | _R_~1~^0^ | _R_~1~^0^ | _R_~1~^0^ | _R_~1~^0^ | _R_~1~^0^ | _R_~1~^0^ | _R_~1~^0^ | _R_~1~^0^ | _R_~1~^0^ | _R_~1~^0^ | _R_~1~^0^ | _R_~1~^0^ +>| *36* {nbsp} | _R_~1~^1^ | _R_~1~^1^ | _R_~1~^1^ | _R_~1~^1^ | _R_~1~^1^ | _R_~1~^1^ | _R_~1~^1^ | _R_~1~^1^ | _R_~1~^1^ | _R_~1~^1^ | _R_~1~^1^ | _R_~1~^1^ | _R_~1~^1^ | _R_~1~^1^ +>| *37* {nbsp} | _R_~1~^2^ | _R_~1~^2^ | _R_~1~^2^ | _R_~1~^2^ | _R_~1~^2^ | _R_~1~^2^ | _R_~1~^2^ | _R_~1~^2^ | _R_~1~^2^ | _R_~1~^2^ | _R_~1~^2^ | _R_~1~^2^ | _R_~1~^2^ | _R_~1~^2^ +>| *38* {nbsp} | _R_~1~^3^ | _R_~1~^3^ | _R_~1~^3^ | _R_~1~^3^ | _R_~1~^3^ | _R_~1~^3^ | _R_~1~^3^ | _R_~1~^3^ | _R_~1~^3^ | _R_~1~^3^ | _R_~1~^3^ | _R_~1~^3^ | _R_~1~^3^ | _R_~1~^3^ +>| *39* {nbsp} | _R_~1~^4^ | _R_~1~^4^ | _R_~1~^4^ | _R_~0~^10^ | _R_~0~^10^ | _R_~1~^4^ | _R_~1~^4^ | _R_~1~^4^ | _R_~1~^4^ | _R_~1~^4^ | _R_~1~^4^ | _R_~1~^4^ | _R_~1~^4^ | _R_~0~^15^ +>| *40* {nbsp} | _G_~3~^4^ | _R_~1~^5^ | _R_~0~^10^ | _G_~3~^4^ | _B_~2~^4^ | _G_~3~^4^ | _R_~1~^5^ | _G_~3~^4^ | _G_~3~^4^ | _R_~1~^5^ | _R_~1~^5^ | _R_~1~^5^ | _R_~1~^5^ | _R_~0~^14^ +|==== [[table-bptcbc6hbits2]] .Interpretation of upper bits for BC6H block modes [width="80%", cols=">1,14*^1"] -|================ +|==== >| 14+^| *Mode* ^| *Bit* | *0* | *1* | *2* | *6* | *10* | *14* | *18* | *22* | *26* | *30* | *3* | *7* | *11* | *15* ->| *41*   | _G_~2~^0^ | _G_~2~^0^ | _G_~2~^0^ | _G_~2~^0^ | _G_~2~^0^ | _G_~2~^0^ | _G_~2~^0^ | _G_~2~^0^ | _G_~2~^0^ | _G_~2~^0^ | _R_~1~^6^ | _R_~1~^6^ | _R_~1~^6^ | _R_~0~^13^ ->| *42*   | _G_~2~^1^ | _G_~2~^1^ | _G_~2~^1^ | _G_~2~^1^ | _G_~2~^1^ | _G_~2~^1^ | _G_~2~^1^ | _G_~2~^1^ | _G_~2~^1^ | _G_~2~^1^ | _R_~1~^7^ | _R_~1~^7^ | _R_~1~^7^ | _R_~0~^12^ ->| *43*   | _G_~2~^2^ | _G_~2~^2^ | _G_~2~^2^ | _G_~2~^2^ | _G_~2~^2^ | _G_~2~^2^ | _G_~2~^2^ | _G_~2~^2^ | _G_~2~^2^ | _G_~2~^2^ | _R_~1~^8^ | _R_~1~^8^ | _R_~0~^11^ | _R_~0~^11^ ->| *44*   | _G_~2~^3^ | _G_~2~^3^ | _G_~2~^3^ | _G_~2~^3^ | _G_~2~^3^ | _G_~2~^3^ | _G_~2~^3^ | _G_~2~^3^ | _G_~2~^3^ | _G_~2~^3^ | _R_~1~^9^ | _R_~0~^10^ | _R_~0~^10^ | _R_~0~^10^ ->| *45*   | _G_~1~^0^ | _G_~1~^0^ | _G_~1~^0^ | _G_~1~^0^ | _G_~1~^0^ | _G_~1~^0^ | _G_~1~^0^ | _G_~1~^0^ | _G_~1~^0^ | _G_~1~^0^ | _G_~1~^0^ | _G_~1~^0^ | _G_~1~^0^ | _G_~1~^0^ ->| *46*   | _G_~1~^1^ | _G_~1~^1^ | _G_~1~^1^ | _G_~1~^1^ | _G_~1~^1^ | _G_~1~^1^ | _G_~1~^1^ | _G_~1~^1^ | _G_~1~^1^ | _G_~1~^1^ | _G_~1~^1^ | _G_~1~^1^ | _G_~1~^1^ | _G_~1~^1^ ->| *47*   | _G_~1~^2^ | _G_~1~^2^ | _G_~1~^2^ | _G_~1~^2^ | _G_~1~^2^ | _G_~1~^2^ | _G_~1~^2^ | _G_~1~^2^ | _G_~1~^2^ | _G_~1~^2^ | _G_~1~^2^ | _G_~1~^2^ | _G_~1~^2^ | _G_~1~^2^ ->| *48*   | _G_~1~^3^ | _G_~1~^3^ | _G_~1~^3^ | _G_~1~^3^ | _G_~1~^3^ | _G_~1~^3^ | _G_~1~^3^ | _G_~1~^3^ | _G_~1~^3^ | _G_~1~^3^ | _G_~1~^3^ | _G_~1~^3^ | _G_~1~^3^ | _G_~1~^3^ ->| *49*   | _G_~1~^4^ | _G_~1~^4^ | _G_~0~^10^ | _G_~1~^4^ | _G_~0~^10^ | _G_~1~^4^ | _G_~1~^4^ | _G_~1~^4^ | _G_~1~^4^ | _G_~1~^4^ | _G_~1~^4^ | _G_~1~^4^ | _G_~1~^4^ | _G_~0~^15^ ->| *50*   | _B_~3~^0^ | _G_~1~^5^ | _B_~3~^0^ | _G_~0~^10^ | _B_~3~^0^ | _B_~3~^0^ | _B_~3~^0^ | _G_~1~^5^ | _B_~3~^0^ | _G_~1~^5^ | _G_~1~^5^ | _G_~1~^5^ | _G_~1~^5^ | _G_~0~^14^ ->| *51*   | _G_~3~^0^ | _G_~3~^0^ | _G_~3~^0^ | _G_~3~^0^ | _G_~3~^0^ | _G_~3~^0^ | _G_~3~^0^ | _G_~3~^0^ | _G_~3~^0^ | _G_~3~^0^ | _G_~1~^6^ | _G_~1~^6^ | _G_~1~^6^ | _G_~0~^13^ ->| *52*   | _G_~3~^1^ | _G_~3~^1^ | _G_~3~^1^ | _G_~3~^1^ | _G_~3~^1^ | _G_~3~^1^ | _G_~3~^1^ | _G_~3~^1^ | _G_~3~^1^ | _G_~3~^1^ | _G_~1~^7^ | _G_~1~^7^ | _G_~1~^7^ | _G_~0~^12^ ->| *53*   | _G_~3~^2^ | _G_~3~^2^ | _G_~3~^2^ | _G_~3~^2^ | _G_~3~^2^ | _G_~3~^2^ | _G_~3~^2^ | _G_~3~^2^ | _G_~3~^2^ | _G_~3~^2^ | _G_~1~^8^ | _G_~1~^8^ | _G_~0~^11^ | _G_~0~^11^ ->| *54*   | _G_~3~^3^ | _G_~3~^3^ | _G_~3~^3^ | _G_~3~^3^ | _G_~3~^3^ | _G_~3~^3^ | _G_~3~^3^ | _G_~3~^3^ | _G_~3~^3^ | _G_~3~^3^ | _G_~1~^9^ | _G_~0~^10^ | _G_~0~^10^ | _G_~0~^10^ ->| *55*   | _B_~1~^0^ | _B_~1~^0^ | _B_~1~^0^ | _B_~1~^0^ | _B_~1~^0^ | _B_~1~^0^ | _B_~1~^0^ | _B_~1~^0^ | _B_~1~^0^ | _B_~1~^0^ | _B_~1~^0^ | _B_~1~^0^ | _B_~1~^0^ | _B_~1~^0^ ->| *56*   | _B_~1~^1^ | _B_~1~^1^ | _B_~1~^1^ | _B_~1~^1^ | _B_~1~^1^ | _B_~1~^1^ | _B_~1~^1^ | _B_~1~^1^ | _B_~1~^1^ | _B_~1~^1^ | _B_~1~^1^ | _B_~1~^1^ | _B_~1~^1^ | _B_~1~^1^ ->| *57*   | _B_~1~^2^ | _B_~1~^2^ | _B_~1~^2^ | _B_~1~^2^ | _B_~1~^2^ | _B_~1~^2^ | _B_~1~^2^ | _B_~1~^2^ | _B_~1~^2^ | _B_~1~^2^ | _B_~1~^2^ | _B_~1~^2^ | _B_~1~^2^ | _B_~1~^2^ ->| *58*   | _B_~1~^3^ | _B_~1~^3^ | _B_~1~^3^ | _B_~1~^3^ | _B_~1~^3^ | _B_~1~^3^ | _B_~1~^3^ | _B_~1~^3^ | _B_~1~^3^ | _B_~1~^3^ | _B_~1~^3^ | _B_~1~^3^ | _B_~1~^3^ | _B_~1~^3^ ->| *59*   | _B_~1~^4^ | _B_~1~^4^ | _B_~0~^10^ | _B_~0~^10^ | _B_~1~^4^ | _B_~1~^4^ | _B_~1~^4^ | _B_~1~^4^ | _B_~1~^4^ | _B_~1~^4^ | _B_~1~^4^ | _B_~1~^4^ | _B_~1~^4^ | _B_~0~^15^ ->| *60*   | _B_~3~^1^ | _B_~1~^5^ | _B_~3~^1^ | _B_~3~^1^ | _B_~0~^10^ | _B_~3~^1^ | _B_~3~^1^ | _B_~3~^1^ | _B_~1~^5^ | _B_~1~^5^ | _B_~1~^5^ | _B_~1~^5^ | _B_~1~^5^ | _B_~0~^14^ ->| *61*   | _B_~2~^0^ | _B_~2~^0^ | _B_~2~^0^ | _B_~2~^0^ | _B_~2~^0^ | _B_~2~^0^ | _B_~2~^0^ | _B_~2~^0^ | _B_~2~^0^ | _B_~2~^0^ | _B_~1~^6^ | _B_~1~^6^ | _B_~1~^6^ | _B_~0~^13^ ->| *62*   | _B_~2~^1^ | _B_~2~^1^ | _B_~2~^1^ | _B_~2~^1^ | _B_~2~^1^ | _B_~2~^1^ | _B_~2~^1^ | _B_~2~^1^ | _B_~2~^1^ | _B_~2~^1^ | _B_~1~^7^ | _B_~1~^7^ | _B_~1~^7^ | _B_~0~^12^ ->| *63*   | _B_~2~^2^ | _B_~2~^2^ | _B_~2~^2^ | _B_~2~^2^ | _B_~2~^2^ | _B_~2~^2^ | _B_~2~^2^ | _B_~2~^2^ | _B_~2~^2^ | _B_~2~^2^ | _B_~1~^8^ | _B_~1~^8^ | _B_~0~^11^ | _B_~0~^11^ ->| *64*   | _B_~2~^3^ | _B_~2~^3^ | _B_~2~^3^ | _B_~2~^3^ | _B_~2~^3^ | _B_~2~^3^ | _B_~2~^3^ | _B_~2~^3^ | _B_~2~^3^ | _B_~2~^3^ | _B_~1~^9^ | _B_~0~^10^ | _B_~0~^10^ | _B_~0~^10^ ->| *65*   | _R_~2~^0^ | _R_~2~^0^ | _R_~2~^0^ | _R_~2~^0^ | _R_~2~^0^ | _R_~2~^0^ | _R_~2~^0^ | _R_~2~^0^ | _R_~2~^0^ | _R_~2~^0^ | IB~0,0~^0^ | IB~0,0~^0^ | IB~0,0~^0^ | IB~0,0~^0^ ->| *66*   | _R_~2~^1^ | _R_~2~^1^ | _R_~2~^1^ | _R_~2~^1^ | _R_~2~^1^ | _R_~2~^1^ | _R_~2~^1^ | _R_~2~^1^ | _R_~2~^1^ | _R_~2~^1^ | IB~0,0~^1^ | IB~0,0~^1^ | IB~0,0~^1^ | IB~0,0~^1^ ->| *67*   | _R_~2~^2^ | _R_~2~^2^ | _R_~2~^2^ | _R_~2~^2^ | _R_~2~^2^ | _R_~2~^2^ | _R_~2~^2^ | _R_~2~^2^ | _R_~2~^2^ | _R_~2~^2^ | IB~0,0~^2^ | IB~0,0~^2^ | IB~0,0~^2^ | IB~0,0~^2^ ->| *68*   | _R_~2~^3^ | _R_~2~^3^ | _R_~2~^3^ | _R_~2~^3^ | _R_~2~^3^ | _R_~2~^3^ | _R_~2~^3^ | _R_~2~^3^ | _R_~2~^3^ | _R_~2~^3^ | IB~1,0~^0^ | IB~1,0~^0^ | IB~1,0~^0^ | IB~1,0~^0^ ->| *69*   | _R_~2~^4^ | _R_~2~^4^ | _R_~2~^4^ | _B_~3~^0^ | _B_~3~^1^ | _R_~2~^4^ | _R_~2~^4^ | _R_~2~^4^ | _R_~2~^4^ | _R_~2~^4^ | IB~1,0~^1^ | IB~1,0~^1^ | IB~1,0~^1^ | IB~1,0~^1^ ->| *70*   | _B_~3~^2^ | _R_~2~^5^ | _B_~3~^2^ | _B_~3~^2^ | _B_~3~^2^ | _B_~3~^2^ | _R_~2~^5^ | _B_~3~^2^ | _B_~3~^2^ | _R_~2~^5^ | IB~1,0~^2^ | IB~1,0~^2^ | IB~1,0~^2^ | IB~1,0~^2^ ->| *71*   | _R_~3~^0^ | _R_~3~^0^ | _R_~3~^0^ | _R_~3~^0^ | _R_~3~^0^ | _R_~3~^0^ | _R_~3~^0^ | _R_~3~^0^ | _R_~3~^0^ | _R_~3~^0^ | IB~1,0~^3^ | IB~1,0~^3^ | IB~1,0~^3^ | IB~1,0~^3^ ->| *72*   | _R_~3~^1^ | _R_~3~^1^ | _R_~3~^1^ | _R_~3~^1^ | _R_~3~^1^ | _R_~3~^1^ | _R_~3~^1^ | _R_~3~^1^ | _R_~3~^1^ | _R_~3~^1^ | IB~2,0~^0^ | IB~2,0~^0^ | IB~2,0~^0^ | IB~2,0~^0^ ->| *73*   | _R_~3~^2^ | _R_~3~^2^ | _R_~3~^2^ | _R_~3~^2^ | _R_~3~^2^ | _R_~3~^2^ | _R_~3~^2^ | _R_~3~^2^ | _R_~3~^2^ | _R_~3~^2^ | IB~2,0~^1^ | IB~2,0~^1^ | IB~2,0~^1^ | IB~2,0~^1^ ->| *74*   | _R_~3~^3^ | _R_~3~^3^ | _R_~3~^3^ | _R_~3~^3^ | _R_~3~^3^ | _R_~3~^3^ | _R_~3~^3^ | _R_~3~^3^ | _R_~3~^3^ | _R_~3~^3^ | IB~2,0~^2^ | IB~2,0~^2^ | IB~2,0~^2^ | IB~2,0~^2^ ->| *75*   | _R_~3~^4^ | _R_~3~^4^ | _R_~3~^4^ | _G_~2~^4^ | _B_~3~^4^ | _R_~3~^4^ | _R_~3~^4^ | _R_~3~^4^ | _R_~3~^4^ | _R_~3~^4^ | IB~2,0~^3^ | IB~2,0~^3^ | IB~2,0~^3^ | IB~2,0~^3^ ->| *76*   | _B_~3~^3^ | _R_~3~^5^ | _B_~3~^3^ | _B_~3~^3^ | _B_~3~^3^ | _B_~3~^3^ | _R_~3~^5^ | _B_~3~^3^ | _B_~3~^3^ | _R_~3~^5^ | IB~3,0~^0^ | IB~3,0~^0^ | IB~3,0~^0^ | IB~3,0~^0^ ->| *77*   | PB^0^ | PB^0^ | PB^0^ | PB^0^ | PB^0^ | PB^0^ | PB^0^ | PB^0^ | PB^0^ | PB^0^ | IB~3,0~^1^ | IB~3,0~^1^ | IB~3,0~^1^ | IB~3,0~^1^ ->| *78*   | PB^1^ | PB^1^ | PB^1^ | PB^1^ | PB^1^ | PB^1^ | PB^1^ | PB^1^ | PB^1^ | PB^1^ | IB~3,0~^2^ | IB~3,0~^2^ | IB~3,0~^2^ | IB~3,0~^2^ ->| *79*   | PB^2^ | PB^2^ | PB^2^ | PB^2^ | PB^2^ | PB^2^ | PB^2^ | PB^2^ | PB^2^ | PB^2^ | IB~3,0~^3^ | IB~3,0~^3^ | IB~3,0~^3^ | IB~3,0~^3^ ->| *80*   | PB^3^ | PB^3^ | PB^3^ | PB^3^ | PB^3^ | PB^3^ | PB^3^ | PB^3^ | PB^3^ | PB^3^ | IB~0,1~^0^ | IB~0,1~^0^ | IB~0,1~^0^ | IB~0,1~^0^ ->| *81*   | PB^4^ | PB^4^ | PB^4^ | PB^4^ | PB^4^ | PB^4^ | PB^4^ | PB^4^ | PB^4^ | PB^4^ | IB~0,1~^1^ | IB~0,1~^1^ | IB~0,1~^1^ | IB~0,1~^1^ -|================ +>| *41* {nbsp} | _G_~2~^0^ | _G_~2~^0^ | _G_~2~^0^ | _G_~2~^0^ | _G_~2~^0^ | _G_~2~^0^ | _G_~2~^0^ | _G_~2~^0^ | _G_~2~^0^ | _G_~2~^0^ | _R_~1~^6^ | _R_~1~^6^ | _R_~1~^6^ | _R_~0~^13^ +>| *42* {nbsp} | _G_~2~^1^ | _G_~2~^1^ | _G_~2~^1^ | _G_~2~^1^ | _G_~2~^1^ | _G_~2~^1^ | _G_~2~^1^ | _G_~2~^1^ | _G_~2~^1^ | _G_~2~^1^ | _R_~1~^7^ | _R_~1~^7^ | _R_~1~^7^ | _R_~0~^12^ +>| *43* {nbsp} | _G_~2~^2^ | _G_~2~^2^ | _G_~2~^2^ | _G_~2~^2^ | _G_~2~^2^ | _G_~2~^2^ | _G_~2~^2^ | _G_~2~^2^ | _G_~2~^2^ | _G_~2~^2^ | _R_~1~^8^ | _R_~1~^8^ | _R_~0~^11^ | _R_~0~^11^ +>| *44* {nbsp} | _G_~2~^3^ | _G_~2~^3^ | _G_~2~^3^ | _G_~2~^3^ | _G_~2~^3^ | _G_~2~^3^ | _G_~2~^3^ | _G_~2~^3^ | _G_~2~^3^ | _G_~2~^3^ | _R_~1~^9^ | _R_~0~^10^ | _R_~0~^10^ | _R_~0~^10^ +>| *45* {nbsp} | _G_~1~^0^ | _G_~1~^0^ | _G_~1~^0^ | _G_~1~^0^ | _G_~1~^0^ | _G_~1~^0^ | _G_~1~^0^ | _G_~1~^0^ | _G_~1~^0^ | _G_~1~^0^ | _G_~1~^0^ | _G_~1~^0^ | _G_~1~^0^ | _G_~1~^0^ +>| *46* {nbsp} | _G_~1~^1^ | _G_~1~^1^ | _G_~1~^1^ | _G_~1~^1^ | _G_~1~^1^ | _G_~1~^1^ | _G_~1~^1^ | _G_~1~^1^ | _G_~1~^1^ | _G_~1~^1^ | _G_~1~^1^ | _G_~1~^1^ | _G_~1~^1^ | _G_~1~^1^ +>| *47* {nbsp} | _G_~1~^2^ | _G_~1~^2^ | _G_~1~^2^ | _G_~1~^2^ | _G_~1~^2^ | _G_~1~^2^ | _G_~1~^2^ | _G_~1~^2^ | _G_~1~^2^ | _G_~1~^2^ | _G_~1~^2^ | _G_~1~^2^ | _G_~1~^2^ | _G_~1~^2^ +>| *48* {nbsp} | _G_~1~^3^ | _G_~1~^3^ | _G_~1~^3^ | _G_~1~^3^ | _G_~1~^3^ | _G_~1~^3^ | _G_~1~^3^ | _G_~1~^3^ | _G_~1~^3^ | _G_~1~^3^ | _G_~1~^3^ | _G_~1~^3^ | _G_~1~^3^ | _G_~1~^3^ +>| *49* {nbsp} | _G_~1~^4^ | _G_~1~^4^ | _G_~0~^10^ | _G_~1~^4^ | _G_~0~^10^ | _G_~1~^4^ | _G_~1~^4^ | _G_~1~^4^ | _G_~1~^4^ | _G_~1~^4^ | _G_~1~^4^ | _G_~1~^4^ | _G_~1~^4^ | _G_~0~^15^ +>| *50* {nbsp} | _B_~3~^0^ | _G_~1~^5^ | _B_~3~^0^ | _G_~0~^10^ | _B_~3~^0^ | _B_~3~^0^ | _B_~3~^0^ | _G_~1~^5^ | _B_~3~^0^ | _G_~1~^5^ | _G_~1~^5^ | _G_~1~^5^ | _G_~1~^5^ | _G_~0~^14^ +>| *51* {nbsp} | _G_~3~^0^ | _G_~3~^0^ | _G_~3~^0^ | _G_~3~^0^ | _G_~3~^0^ | _G_~3~^0^ | _G_~3~^0^ | _G_~3~^0^ | _G_~3~^0^ | _G_~3~^0^ | _G_~1~^6^ | _G_~1~^6^ | _G_~1~^6^ | _G_~0~^13^ +>| *52* {nbsp} | _G_~3~^1^ | _G_~3~^1^ | _G_~3~^1^ | _G_~3~^1^ | _G_~3~^1^ | _G_~3~^1^ | _G_~3~^1^ | _G_~3~^1^ | _G_~3~^1^ | _G_~3~^1^ | _G_~1~^7^ | _G_~1~^7^ | _G_~1~^7^ | _G_~0~^12^ +>| *53* {nbsp} | _G_~3~^2^ | _G_~3~^2^ | _G_~3~^2^ | _G_~3~^2^ | _G_~3~^2^ | _G_~3~^2^ | _G_~3~^2^ | _G_~3~^2^ | _G_~3~^2^ | _G_~3~^2^ | _G_~1~^8^ | _G_~1~^8^ | _G_~0~^11^ | _G_~0~^11^ +>| *54* {nbsp} | _G_~3~^3^ | _G_~3~^3^ | _G_~3~^3^ | _G_~3~^3^ | _G_~3~^3^ | _G_~3~^3^ | _G_~3~^3^ | _G_~3~^3^ | _G_~3~^3^ | _G_~3~^3^ | _G_~1~^9^ | _G_~0~^10^ | _G_~0~^10^ | _G_~0~^10^ +>| *55* {nbsp} | _B_~1~^0^ | _B_~1~^0^ | _B_~1~^0^ | _B_~1~^0^ | _B_~1~^0^ | _B_~1~^0^ | _B_~1~^0^ | _B_~1~^0^ | _B_~1~^0^ | _B_~1~^0^ | _B_~1~^0^ | _B_~1~^0^ | _B_~1~^0^ | _B_~1~^0^ +>| *56* {nbsp} | _B_~1~^1^ | _B_~1~^1^ | _B_~1~^1^ | _B_~1~^1^ | _B_~1~^1^ | _B_~1~^1^ | _B_~1~^1^ | _B_~1~^1^ | _B_~1~^1^ | _B_~1~^1^ | _B_~1~^1^ | _B_~1~^1^ | _B_~1~^1^ | _B_~1~^1^ +>| *57* {nbsp} | _B_~1~^2^ | _B_~1~^2^ | _B_~1~^2^ | _B_~1~^2^ | _B_~1~^2^ | _B_~1~^2^ | _B_~1~^2^ | _B_~1~^2^ | _B_~1~^2^ | _B_~1~^2^ | _B_~1~^2^ | _B_~1~^2^ | _B_~1~^2^ | _B_~1~^2^ +>| *58* {nbsp} | _B_~1~^3^ | _B_~1~^3^ | _B_~1~^3^ | _B_~1~^3^ | _B_~1~^3^ | _B_~1~^3^ | _B_~1~^3^ | _B_~1~^3^ | _B_~1~^3^ | _B_~1~^3^ | _B_~1~^3^ | _B_~1~^3^ | _B_~1~^3^ | _B_~1~^3^ +>| *59* {nbsp} | _B_~1~^4^ | _B_~1~^4^ | _B_~0~^10^ | _B_~0~^10^ | _B_~1~^4^ | _B_~1~^4^ | _B_~1~^4^ | _B_~1~^4^ | _B_~1~^4^ | _B_~1~^4^ | _B_~1~^4^ | _B_~1~^4^ | _B_~1~^4^ | _B_~0~^15^ +>| *60* {nbsp} | _B_~3~^1^ | _B_~1~^5^ | _B_~3~^1^ | _B_~3~^1^ | _B_~0~^10^ | _B_~3~^1^ | _B_~3~^1^ | _B_~3~^1^ | _B_~1~^5^ | _B_~1~^5^ | _B_~1~^5^ | _B_~1~^5^ | _B_~1~^5^ | _B_~0~^14^ +>| *61* {nbsp} | _B_~2~^0^ | _B_~2~^0^ | _B_~2~^0^ | _B_~2~^0^ | _B_~2~^0^ | _B_~2~^0^ | _B_~2~^0^ | _B_~2~^0^ | _B_~2~^0^ | _B_~2~^0^ | _B_~1~^6^ | _B_~1~^6^ | _B_~1~^6^ | _B_~0~^13^ +>| *62* {nbsp} | _B_~2~^1^ | _B_~2~^1^ | _B_~2~^1^ | _B_~2~^1^ | _B_~2~^1^ | _B_~2~^1^ | _B_~2~^1^ | _B_~2~^1^ | _B_~2~^1^ | _B_~2~^1^ | _B_~1~^7^ | _B_~1~^7^ | _B_~1~^7^ | _B_~0~^12^ +>| *63* {nbsp} | _B_~2~^2^ | _B_~2~^2^ | _B_~2~^2^ | _B_~2~^2^ | _B_~2~^2^ | _B_~2~^2^ | _B_~2~^2^ | _B_~2~^2^ | _B_~2~^2^ | _B_~2~^2^ | _B_~1~^8^ | _B_~1~^8^ | _B_~0~^11^ | _B_~0~^11^ +>| *64* {nbsp} | _B_~2~^3^ | _B_~2~^3^ | _B_~2~^3^ | _B_~2~^3^ | _B_~2~^3^ | _B_~2~^3^ | _B_~2~^3^ | _B_~2~^3^ | _B_~2~^3^ | _B_~2~^3^ | _B_~1~^9^ | _B_~0~^10^ | _B_~0~^10^ | _B_~0~^10^ +>| *65* {nbsp} | _R_~2~^0^ | _R_~2~^0^ | _R_~2~^0^ | _R_~2~^0^ | _R_~2~^0^ | _R_~2~^0^ | _R_~2~^0^ | _R_~2~^0^ | _R_~2~^0^ | _R_~2~^0^ | IB~0,0~^0^ | IB~0,0~^0^ | IB~0,0~^0^ | IB~0,0~^0^ +>| *66* {nbsp} | _R_~2~^1^ | _R_~2~^1^ | _R_~2~^1^ | _R_~2~^1^ | _R_~2~^1^ | _R_~2~^1^ | _R_~2~^1^ | _R_~2~^1^ | _R_~2~^1^ | _R_~2~^1^ | IB~0,0~^1^ | IB~0,0~^1^ | IB~0,0~^1^ | IB~0,0~^1^ +>| *67* {nbsp} | _R_~2~^2^ | _R_~2~^2^ | _R_~2~^2^ | _R_~2~^2^ | _R_~2~^2^ | _R_~2~^2^ | _R_~2~^2^ | _R_~2~^2^ | _R_~2~^2^ | _R_~2~^2^ | IB~0,0~^2^ | IB~0,0~^2^ | IB~0,0~^2^ | IB~0,0~^2^ +>| *68* {nbsp} | _R_~2~^3^ | _R_~2~^3^ | _R_~2~^3^ | _R_~2~^3^ | _R_~2~^3^ | _R_~2~^3^ | _R_~2~^3^ | _R_~2~^3^ | _R_~2~^3^ | _R_~2~^3^ | IB~1,0~^0^ | IB~1,0~^0^ | IB~1,0~^0^ | IB~1,0~^0^ +>| *69* {nbsp} | _R_~2~^4^ | _R_~2~^4^ | _R_~2~^4^ | _B_~3~^0^ | _B_~3~^1^ | _R_~2~^4^ | _R_~2~^4^ | _R_~2~^4^ | _R_~2~^4^ | _R_~2~^4^ | IB~1,0~^1^ | IB~1,0~^1^ | IB~1,0~^1^ | IB~1,0~^1^ +>| *70* {nbsp} | _B_~3~^2^ | _R_~2~^5^ | _B_~3~^2^ | _B_~3~^2^ | _B_~3~^2^ | _B_~3~^2^ | _R_~2~^5^ | _B_~3~^2^ | _B_~3~^2^ | _R_~2~^5^ | IB~1,0~^2^ | IB~1,0~^2^ | IB~1,0~^2^ | IB~1,0~^2^ +>| *71* {nbsp} | _R_~3~^0^ | _R_~3~^0^ | _R_~3~^0^ | _R_~3~^0^ | _R_~3~^0^ | _R_~3~^0^ | _R_~3~^0^ | _R_~3~^0^ | _R_~3~^0^ | _R_~3~^0^ | IB~1,0~^3^ | IB~1,0~^3^ | IB~1,0~^3^ | IB~1,0~^3^ +>| *72* {nbsp} | _R_~3~^1^ | _R_~3~^1^ | _R_~3~^1^ | _R_~3~^1^ | _R_~3~^1^ | _R_~3~^1^ | _R_~3~^1^ | _R_~3~^1^ | _R_~3~^1^ | _R_~3~^1^ | IB~2,0~^0^ | IB~2,0~^0^ | IB~2,0~^0^ | IB~2,0~^0^ +>| *73* {nbsp} | _R_~3~^2^ | _R_~3~^2^ | _R_~3~^2^ | _R_~3~^2^ | _R_~3~^2^ | _R_~3~^2^ | _R_~3~^2^ | _R_~3~^2^ | _R_~3~^2^ | _R_~3~^2^ | IB~2,0~^1^ | IB~2,0~^1^ | IB~2,0~^1^ | IB~2,0~^1^ +>| *74* {nbsp} | _R_~3~^3^ | _R_~3~^3^ | _R_~3~^3^ | _R_~3~^3^ | _R_~3~^3^ | _R_~3~^3^ | _R_~3~^3^ | _R_~3~^3^ | _R_~3~^3^ | _R_~3~^3^ | IB~2,0~^2^ | IB~2,0~^2^ | IB~2,0~^2^ | IB~2,0~^2^ +>| *75* {nbsp} | _R_~3~^4^ | _R_~3~^4^ | _R_~3~^4^ | _G_~2~^4^ | _B_~3~^4^ | _R_~3~^4^ | _R_~3~^4^ | _R_~3~^4^ | _R_~3~^4^ | _R_~3~^4^ | IB~2,0~^3^ | IB~2,0~^3^ | IB~2,0~^3^ | IB~2,0~^3^ +>| *76* {nbsp} | _B_~3~^3^ | _R_~3~^5^ | _B_~3~^3^ | _B_~3~^3^ | _B_~3~^3^ | _B_~3~^3^ | _R_~3~^5^ | _B_~3~^3^ | _B_~3~^3^ | _R_~3~^5^ | IB~3,0~^0^ | IB~3,0~^0^ | IB~3,0~^0^ | IB~3,0~^0^ +>| *77* {nbsp} | PB^0^ | PB^0^ | PB^0^ | PB^0^ | PB^0^ | PB^0^ | PB^0^ | PB^0^ | PB^0^ | PB^0^ | IB~3,0~^1^ | IB~3,0~^1^ | IB~3,0~^1^ | IB~3,0~^1^ +>| *78* {nbsp} | PB^1^ | PB^1^ | PB^1^ | PB^1^ | PB^1^ | PB^1^ | PB^1^ | PB^1^ | PB^1^ | PB^1^ | IB~3,0~^2^ | IB~3,0~^2^ | IB~3,0~^2^ | IB~3,0~^2^ +>| *79* {nbsp} | PB^2^ | PB^2^ | PB^2^ | PB^2^ | PB^2^ | PB^2^ | PB^2^ | PB^2^ | PB^2^ | PB^2^ | IB~3,0~^3^ | IB~3,0~^3^ | IB~3,0~^3^ | IB~3,0~^3^ +>| *80* {nbsp} | PB^3^ | PB^3^ | PB^3^ | PB^3^ | PB^3^ | PB^3^ | PB^3^ | PB^3^ | PB^3^ | PB^3^ | IB~0,1~^0^ | IB~0,1~^0^ | IB~0,1~^0^ | IB~0,1~^0^ +>| *81* {nbsp} | PB^4^ | PB^4^ | PB^4^ | PB^4^ | PB^4^ | PB^4^ | PB^4^ | PB^4^ | PB^4^ | PB^4^ | IB~0,1~^1^ | IB~0,1~^1^ | IB~0,1~^1^ | IB~0,1~^1^ +|==== [NOTE] ==== @@ -1023,7 +980,7 @@ sign-extended if the format of the texture is signed or if the block mode has transformed endpoints. If the mode has transformed endpoints, the values from _E_~0~ are used as a base to offset all other endpoints, wrapped at the number of endpoint bits. -For example, _R_~1~ = (_R_~0~ {plus} _R_~1~) & latexmath:[$((1 \ll \mathrm{EPB})-1)$]. +For example, _R_~1~ = (_R_~0~ {plus} _R_~1~) & latexmath:[((1 \ll \mathrm{EPB})-1)]. [NOTE] ==== @@ -1051,7 +1008,8 @@ The following pseudocode assumes the computation uses sufficiently large intermediate values to avoid overflow. For the unsigned float format, we unquantize a value _x_ to _unq_ by: ------ +[source] +---- if (EPB >= 15) unq = x; else if (x == 0) @@ -1060,12 +1018,13 @@ else if (x == ((1 << EPB)-1)) unq = 0xFFFF; else unq = ((x << 15) + 0x4000) >> (EPB-1); ------ +---- The signed float unquantization is similar, but needs to worry about orienting the negative range: ------ +[source] +---- s = 0; if (EPB >= 16) { unq = x; @@ -1085,7 +1044,7 @@ if (EPB >= 16) { if (s) unq = -unq; } ------ +---- After the endpoints are unquantized, interpolation proceeds as in the fixed-point formats above using <>, including the interpolation @@ -1100,37 +1059,39 @@ represent [0.0..65504.0], where 65504.0 is the largest finite value representable in a half float. The bit pattern that represents 65504.0 is integer 0x7BFF, so the integer input range 0..0xFFFF can be mapped to this range by scaling the -interpolated integer i by latexmath:[$31\over 64$]: +interpolated integer i by latexmath:[31\over 64]: ------ +[source] +---- out = (i * 31) >> 6; ------ +---- For the signed format, the final unquantization step limits the range of the integer representation to the bit sequences which, when interpreted as -a 16-bit half float, represent the range [latexmath:[$-\infty$]..65504.0], -where latexmath:[$-\infty$] is represented in half float as the bit +a 16-bit half float, represent the range [latexmath:[-\infty]..65504.0], +where latexmath:[-\infty] is represented in half float as the bit pattern 0xFC00. The signed 16-bit integer range [-0x8000..0x7FFF] is remapped to this float representation by taking the absolute value of the interpolated -value i, scaling it by latexmath:[$31\over 32$], and restoring the sign bit: +value i, scaling it by latexmath:[31\over 32], and restoring the sign bit: ------ +[source] +---- out = i < 0 ? (((-i) * 31) >> 5) | 0x8000 : (i * 31) >> 5; ------ +---- The resultant bit pattern should be interpreted as a 16-bit half float. [NOTE] ==== -The ability to support latexmath:[$-\infty$] is considered ``accidental'' +The ability to support latexmath:[-\infty] is considered "`accidental`" due to the asymmetry of two's complement representation: in order to map integer 0x7FFF to 65504.0 and 0x0000 to 0.0, -0x7FFF maps to the largest finite negative value, -65504.0, represented as 0xFBFF. A two's complement signed integer can also represent -0x8000; it happens that the same unquantization formula maps 0x8000 to 0xFC00, -which is the half float bit pattern for latexmath:[$-\infty$]. +which is the half float bit pattern for latexmath:[-\infty]. Although decoders for BC6H should be bit-exact, encoders for this format -are encouraged to map latexmath:[$-\infty$] to -65504.0 (and to map -latexmath:[$\infty$] to 65504.0 and NaN values to 0.0) prior to encoding. +are encouraged to map latexmath:[-\infty] to -65504.0 (and to map +latexmath:[\infty] to 65504.0 and NaN values to 0.0) prior to encoding. ==== diff --git a/colormodels.txt b/chapters/colormodels.adoc similarity index 69% rename from colormodels.txt rename to chapters/colormodels.adoc index f764f9e..d9a811d 100644 --- a/colormodels.txt +++ b/chapters/colormodels.adoc @@ -1,5 +1,5 @@ -// Copyright (c) 2017 The Khronos Group Inc. -// Copyright notice at https://www.khronos.org/registry/speccopyright.html +// Copyright 2017-2026 The Khronos Group Inc. +// SPDX-License-Identifier: CC-BY-4.0 [[MODEL_CONVERSION]] == Color models @@ -16,7 +16,7 @@ the color primaries independently - for example by encoding the chroma information at a reduced spatial resolution. [[MODEL_YUV]] -=== _Y′C~B~C~R~_ color model +=== _Y{prime}C~B~C~R~_ color model Color models based on color differences are often referred to with incorrect or ambiguous terminology, the most common of which is @@ -24,16 +24,16 @@ _YUV_. In the broadcast standards which define these models: -* A prime mark (′) is used to refer to the ``gamma - pre-corrected'' version of a value. That is, an approximation to a +* A prime mark ({prime}) is used to refer to the "`gamma + pre-corrected`" version of a value. That is, an approximation to a perceptually linear mapping between value and intensity. The absence of a prime mark indicates that the value is linear in intensity. -* _R′G′B′_ is used to refer to the red, green and blue - reference values in ``gamma pre-corrected'' form. - That is, _R′_, _G′_ and _B′_ have a non-linear transfer +* _R{prime}G{prime}B{prime}_ is used to refer to the red, green and blue + reference values in "`gamma pre-corrected`" form. + That is, _R{prime}_, _G{prime}_ and _B{prime}_ have a non-linear transfer function, whereas _R_, _G_ and _B_ are linear with respect to light intensity. - The transfer function used resembles an exponentiation ``gamma correction'' + The transfer function used resembles an exponentiation "`gamma correction`" operation, with a linear segment near zero for mathematical stability. See <> for details of the transfer function typically used in these cases. @@ -41,115 +41,115 @@ In the broadcast standards which define these models: to refer to a continuous signal value in the range [0..1], mirroring the terminology in analog standards such as <> and <>. - For example, in these standards, the continuous encoding of latexmath:[$R'$] - is written latexmath:[$E_R'$]. + For example, in these standards, the continuous encoding of latexmath:[R'] + is written latexmath:[E_R']. <> and <> no longer use the _E_ convention, - and refer to continuous values as, for example, _R′_ directly. + and refer to continuous values as, for example, _R{prime}_ directly. For brevity, this specification does not use the _E_-prefix convention for model conversions, and all values can be assumed to be continuous. <> refers to the quantized digital version of - latexmath:[$E'_R$], latexmath:[$E'_G$] and latexmath:[$E'_B$] as - latexmath:[$E'_{R_D}$], latexmath:[$E'_{G_D}$] and latexmath:[$E'_{B_D}$]. + latexmath:[E'_R], latexmath:[E'_G] and latexmath:[E'_B] as + latexmath:[E'_{R_D}], latexmath:[E'_{G_D}] and latexmath:[E'_{B_D}]. In <> the quantized digital representation is instead - latexmath:[$D'_R$], latexmath:[$D'_G$] and latexmath:[$D'_B$], in - <> and <> written as _DR′_, - _DG′_ and _DB′_. -* _Y′_ is a weighted sum of _R′_, _G′_ - and _B′_ values, and represents non-physically-linear + latexmath:[D'_R], latexmath:[D'_G] and latexmath:[D'_B], in + <> and <> written as _DR{prime}_, + _DG{prime}_ and _DB{prime}_. +* _Y{prime}_ is a weighted sum of _R{prime}_, _G{prime}_ + and _B{prime}_ values, and represents non-physically-linear (but perceptually-linear) light intensity, as distinct from physically-linear light intensity. - Note that the ITU broadcast standards use ``luminance'' for - _Y′_ despite some authorities reserving that term for a + Note that the ITU broadcast standards use "`luminance`" for + _Y{prime}_ despite some authorities reserving that term for a linear intensity representation. - Since this is a weighted sum of non-linear values, latexmath:[$Y'$] is + Since this is a weighted sum of non-linear values, latexmath:[Y'] is not mathematically equivalent to applying the non-linear transfer function to a weighted sum of linear _R_, _G_ and _B_ values: - latexmath:[$R^{\gamma}+G^{\gamma}+B^{\gamma} \neq (R + G + B)^{\gamma}$]. - The prime symbol is often omitted so that _Y′_ is confusingly + latexmath:[R^{\gamma}+G^{\gamma}+B^{\gamma} \neq (R + G + B)^{\gamma}]. + The prime symbol is often omitted so that _Y{prime}_ is confusingly written _Y_. <> and <> refers to the continuous non-linear - ``luminance'' signal as latexmath:[$E'_Y$]; in <> and - <> this value is just _Y′_. - The quantized digital representation is written as simply _Y′_ - in <>, as latexmath:[$D'_Y$] in <>, and as - _DY′_ in <> and <>. - In this standard, _Y′_ refers to a continuous value. + "`luminance`" signal as latexmath:[E'_Y]; in <> and + <> this value is just _Y{prime}_. + The quantized digital representation is written as simply _Y{prime}_ + in <>, as latexmath:[D'_Y] in <>, and as + _DY{prime}_ in <> and <>. + In this standard, _Y{prime}_ refers to a continuous value. <<< * For the purposes of this section, we will refer to the weighting factor - applied to _R′_ as _K~R~_ and the weighting factor - applied to _B′_ as _K~B~_. The weighting factor of - _G′_ is therefore latexmath:[$1-K_R-K_B$]. Thus - latexmath:[$Y' = K_R \times R' + (1-K_R-K_B) \times G' + Kb \times B'$]. + applied to _R{prime}_ as _K~R~_ and the weighting factor + applied to _B{prime}_ as _K~B~_. The weighting factor of + _G{prime}_ is therefore latexmath:[1-K_R-K_B]. Thus + latexmath:[Y' = K_R \times R' + (1-K_R-K_B) \times G' + Kb \times B']. -Color differences are calculated from the non-linear _Y′_ and +Color differences are calculated from the non-linear _Y{prime}_ and color components as: [latexmath] -++++++ +++++ \begin{align*} B'-Y' &= (1-K_B) \times B' - (1-K_R-K_B) \times G' - K_R \times R' \\ R'-Y' &= (1-K_R) \times R' - (1-K_R-K_B) \times G' - K_B \times B' \end{align*} -++++++ -Note that, for _R′_, _G′_, _B′_ in the range [0..1]: +++++ +Note that, for _R{prime}_, _G{prime}_, _B{prime}_ in the range [0..1]: [latexmath] -++++++ +++++ \begin{align*} (1-K_B) \geq B'-Y' \geq -(1-K_B) \\ (1-K_R) \geq R'-Y' \geq -(1-K_R) \end{align*} -++++++ +++++ -* latexmath:[$(B'-Y')$] scaled appropriately for incorporation into a PAL +* latexmath:[(B'-Y')] scaled appropriately for incorporation into a PAL sub-carrier signal is referred to in <> as _U_; note that the scale factor (0.493) is not the same as that used for digital encoding of this color difference. _U_ is colloquially used for other representations of this value. -* latexmath:[$(R'-Y')$] scaled appropriately for incorporation into a PAL +* latexmath:[(R'-Y')] scaled appropriately for incorporation into a PAL sub-carrier signal is referred to in <> as _V_; note that the scale factor (0.877) is not the same as that used for digital encoding of this color difference. _V_ is colloquially used for other representations of this value. -* latexmath:[$(B'-Y')$] scaled to the range [latexmath:[$-0.5..0.5$]] is +* latexmath:[(B'-Y')] scaled to the range [latexmath:[-0.5..0.5]] is referred to in <> and <> as - latexmath:[$E'_{C_B}$], and in <> and <> as - simply latexmath:[$C'_B$]. - In <> this value is referred to as latexmath:[$E'_\mathit{PB}$], + latexmath:[E'_{C_B}], and in <> and <> as + simply latexmath:[C'_B]. + In <> this value is referred to as latexmath:[E'_\mathit{PB}], and the analog signal is colloquially known as _P~B~_. - This standard uses the latexmath:[$C'_B$] terminology for brevity - and consistency with latexmath:[$Y'_CC'_\mathit{BC}C'_\mathit{RC}$]. + This standard uses the latexmath:[C'_B] terminology for brevity + and consistency with latexmath:[Y'_CC'_\mathit{BC}C'_\mathit{RC}]. It is common, especially in the name of a color model, to omit the prime symbol and write simply _C~B~_. -* latexmath:[$(R'-Y')$] scaled to the range [latexmath:[$-0.5..0.5$]] is +* latexmath:[(R'-Y')] scaled to the range [latexmath:[-0.5..0.5]] is referred to in <> and <> as - latexmath:[$E'_{C_R}$], and in <> and <> as - simply latexmath:[$C'_R$]. - In <> this value is referred to as latexmath:[$E'_\mathit{PR}$], + latexmath:[E'_{C_R}], and in <> and <> as + simply latexmath:[C'_R]. + In <> this value is referred to as latexmath:[E'_\mathit{PR}], and the analog signal is colloquially known as _P~R~_. - This standard uses the latexmath:[$C'_R$] terminology for brevity - and consistency with latexmath:[$Y'_CC'_\mathit{BC}C'_\mathit{RC}$]. + This standard uses the latexmath:[C'_R] terminology for brevity + and consistency with latexmath:[Y'_CC'_\mathit{BC}C'_\mathit{RC}]. It is common, especially in the name of a color model, to omit the prime symbol and write simply _C~R~_. -* latexmath:[$(B'-Y')$] scaled and quantized for digital representation is - known as simply latexmath:[$C'_B$] in <>, - latexmath:[$D'_\mathit{CB}$] in <> and latexmath:[$DC_B'$] +* latexmath:[(B'-Y')] scaled and quantized for digital representation is + known as simply latexmath:[C'_B] in <>, + latexmath:[D'_\mathit{CB}] in <> and latexmath:[DC_B'] in <> and <>. -* latexmath:[$(R'-Y')$] scaled and quantized for digital representation is - known as simply latexmath:[$C'_R$] in <>, - latexmath:[$D'_\mathit{CR}$] in <> and latexmath:[$DC_R'$] +* latexmath:[(R'-Y')] scaled and quantized for digital representation is + known as simply latexmath:[C'_R] in <>, + latexmath:[D'_\mathit{CR}] in <> and latexmath:[DC_R'] in <> and <>. * This section considers the color channels in continuous terms; - the terminology latexmath:[$DC_B'$] and latexmath:[$DC_R'$] is used + the terminology latexmath:[DC_B'] and latexmath:[DC_R'] is used in <>. Using this terminology, the following conversion formulae can be derived: [latexmath] -++++++ +++++ \begin{align*} Y' & = K_r \times R' + (1-K_R-K_B) \times G' + K_B \times B' \\ C'_B & = {(B' - Y')\over{2(1-K_B)}} \\ @@ -157,23 +157,23 @@ C'_B & = {(B' - Y')\over{2(1-K_B)}} \\ C'_R & = {(R' - Y')\over{2(1-K_R)}} \\ & = {R'\over{2}} - {{K_B \times B' + (1 - K_R - K_B) \times G'}\over{2(1-K_R)}} \end{align*} -++++++ +++++ <<< For the inverse conversion: [latexmath] -++++++ +++++ \begin{align*} R' & = Y' + 2(1-K_R)\times C'_R \\ B' & = Y' + 2(1-K_B)\times C'_B \end{align*} -++++++ -The formula for _G′_ can be derived by substituting the formulae -for _R′_ and _B′_ into the derivation of _Y′_: +++++ +The formula for _G{prime}_ can be derived by substituting the formulae +for _R{prime}_ and _B{prime}_ into the derivation of _Y{prime}_: [latexmath] -++++++ +++++ \begin{align*} Y' = &\ K_R \times R' + (1-K_R-K_B) \times G' + K_B \times B' \\ = &\ K_R \times (Y'+2(1-K_R)\times C'_R) + \\ @@ -184,15 +184,15 @@ Y'\times(1-K_R-K_B) = &\ (1-K_R-K_B)\times G' + \\ &\ K_B\times 2(1-K_B)\times C'_B \\ G' = &\ Y' - {2(K_R(1-K_R)\times C'_R + K_B(1-K_B)\times C'_B)\over{1-K_R-K_B}} \end{align*} -++++++ +++++ The values chosen for _K~R~_ and _K~B~_ vary between standards. [NOTE] ==== -The required color model conversion between latexmath:[$Y'C_BC_R$] -and latexmath:[$R'G'B'$] can typically be deduced from other color +The required color model conversion between latexmath:[Y'C_BC_R] +and latexmath:[R'G'B'] can typically be deduced from other color space parameters: [options="header",cols="18%,18%,14%,18%,14%,18%"] @@ -230,26 +230,26 @@ space parameters: <<< [[MODEL_BT709]] -==== BT.709 _Y′C~B~C~R~_ conversion +==== BT.709 _Y{prime}C~B~C~R~_ conversion <> defines _K~R~_ = 0.2126 and _K~B~_ = 0.0722. -That is, for conversion between (_R′_,_ G′_,_ B′_) +That is, for conversion between (_R{prime}_,_{nbsp}G{prime}_,_{nbsp}B{prime}_) defined in <> and using the <>: [latexmath] -++++++ +++++ \begin{align*} Y' & = 0.2126 \times R' + 0.7152 \times G' + 0.0722 \times B' \\ C'_B & = {(B' - Y')\over{1.8556}} \\ C'_R & = {(R' - Y')\over{1.5748}} \\ \end{align*} -++++++ +++++ Alternatively: [latexmath] -++++++ - $$\left(\begin{array}{c}Y' \\ +++++ +\left(\begin{array}{c}Y' \\ C'_B \\ C'_R\end{array}\right) = \left(\begin{array}{ccc}0.2126, & 0.7152, & 0.0722 \\ @@ -257,13 +257,13 @@ Alternatively: 0.5, & -{0.7152\over{1.5748}}, & -{0.0722\over{1.5748}}\end{array}\right) \left(\begin{array}{c}R'\\ G'\\ - B'\end{array}\right)$$ -++++++ + B'\end{array}\right) +++++ For the inverse conversion: [latexmath] -++++++ - $$\left(\begin{array}{c}R'\\ +++++ +\left(\begin{array}{c}R'\\ G'\\ B'\end{array}\right) = \left(\begin{array}{ccc}1, & 0, & 1.5748\\ @@ -271,31 +271,31 @@ For the inverse conversion: 1, & 1.8556, & 0\end{array}\right) \left(\begin{array}{c}Y'\\ C'_B\\ - C'_R\end{array}\right)$$ -++++++ + C'_R\end{array}\right) +++++ [[MODEL_BT601]] -==== BT.601 _Y′C~B~C~R~_ conversion +==== BT.601 _Y{prime}C~B~C~R~_ conversion <> defines _K~R~_ = 0.299 and _K~B~_ = 0.114. -That is, for conversion between (_R′_,_ G′_,_ B′_) +That is, for conversion between (_R{prime}_,_{nbsp}G{prime}_,_{nbsp}B{prime}_) defined in <> or <>, and using the <>: [latexmath] -++++++ +++++ \begin{align*} Y' & = 0.299 \times R' + 0.587 \times G' + 0.114 \times B' \\ C'_B & = {(B' - Y')\over{1.772}} \\ C'_R & = {(R' - Y')\over{1.402}} \\ \end{align*} -++++++ +++++ Alternatively: [latexmath] -++++++ - $$\left(\begin{array}{c}Y' \\ +++++ +\left(\begin{array}{c}Y' \\ C'_B \\ C'_R\end{array}\right) = \left(\begin{array}{ccc}0.299, & 0.587, & 0.114 \\ @@ -303,13 +303,13 @@ Alternatively: 0.5, & -{0.587\over{1.402}}, & -{0.114\over{1.402}}\end{array}\right) \left(\begin{array}{c}R'\\ G'\\ - B'\end{array}\right)$$ -++++++ + B'\end{array}\right) +++++ For the inverse conversion: [latexmath] -++++++ - $$\left(\begin{array}{c}R'\\ +++++ +\left(\begin{array}{c}R'\\ G'\\ B'\end{array}\right) = \left(\begin{array}{ccc}1, & 0, & 1.402\\ @@ -317,32 +317,32 @@ For the inverse conversion: 1, & 1.772, & 0\end{array}\right) \left(\begin{array}{c}Y'\\ C'_B\\ - C'_R\end{array}\right)$$ -++++++ + C'_R\end{array}\right) +++++ <<< [[MODEL_BT2020]] -==== BT.2020 _Y′C~B~C~R~_ conversion +==== BT.2020 _Y{prime}C~B~C~R~_ conversion <> and <> define _K~R~_ = 0.2627 and _K~B~_ = 0.0593. -That is, for conversion between (_R′_,_ G′_,_ B′_) +That is, for conversion between (_R{prime}_,_{nbsp}G{prime}_,_{nbsp}B{prime}_) defined in <> and using the <>: [latexmath] -++++++ +++++ \begin{align*} Y' & = 0.2627 \times R' + 0.6780 \times G' + 0.0593 \times B' \\ C'_B & = {(B' - Y')\over{1.8814}} \\ C'_R & = {(R' - Y')\over{1.4746}} \\ \end{align*} -++++++ +++++ Alternatively: [latexmath] -++++++ - $$\left(\begin{array}{c}Y' \\ +++++ +\left(\begin{array}{c}Y' \\ C'_B \\ C'_R\end{array}\right) = \left(\begin{array}{ccc}0.2627, & 0.6780, & 0.0593 \\ @@ -350,13 +350,13 @@ Alternatively: 0.5, & -{0.6780\over{1.4746}}, & -{0.0593\over{1.4746}}\end{array}\right) \left(\begin{array}{c}R'\\ G'\\ - B'\end{array}\right)$$ -++++++ + B'\end{array}\right) +++++ For the inverse conversion: [latexmath] -++++++ - $$\left(\begin{array}{c}R'\\ +++++ +\left(\begin{array}{c}R'\\ G'\\ B'\end{array}\right) = \left(\begin{array}{ccc}1, & 0, & 1.4746\\ @@ -364,11 +364,11 @@ For the inverse conversion: 1, & 1.8814, & 0\end{array}\right) \left(\begin{array}{c}Y'\\ C'_B\\ - C'_R\end{array}\right)$$ -++++++ + C'_R\end{array}\right) +++++ [[MODEL_ST240]] -==== ST-240/SMPTE 240M _Y′C~B~C~R~_ conversion +==== ST-240/SMPTE 240M _Y{prime}C~B~C~R~_ conversion <>, formerly SMPTE 240M, defines _K~R~_ = 0.212 and _K~B~_ = 0.087. @@ -377,17 +377,17 @@ That is, for conversion using the <>: [latexmath] -++++++ +++++ \begin{align*} Y' & = 0.212 \times R' + 0.701 \times G' + 0.087 \times B' \\ C'_B & = {(B' - Y')\over{1.826}} \\ C'_R & = {(R' - Y')\over{1.576}} \\ \end{align*} -++++++ +++++ Alternatively: [latexmath] -++++++ - $$\left(\begin{array}{c}Y' \\ +++++ +\left(\begin{array}{c}Y' \\ C'_B \\ C'_R\end{array}\right) = \left(\begin{array}{ccc}0.212, & 0.701, & 0.087 \\ @@ -395,13 +395,13 @@ Alternatively: 0.5, & -{0.701\over{1.576}}, & -{0.087\over{1.576}}\end{array}\right) \left(\begin{array}{c}R'\\ G'\\ - B'\end{array}\right)$$ -++++++ + B'\end{array}\right) +++++ For the inverse conversion: [latexmath] -++++++ - $$\left(\begin{array}{c}R'\\ +++++ +\left(\begin{array}{c}R'\\ G'\\ B'\end{array}\right) = \left(\begin{array}{ccc}1, & 0, & 1.576\\ @@ -409,19 +409,19 @@ For the inverse conversion: 1, & 1.826, & 0\end{array}\right) \left(\begin{array}{c}Y'\\ C'_B\\ - C'_R\end{array}\right)$$ -++++++ + C'_R\end{array}\right) +++++ <<< [[MODEL_YCCBCCRC]] -=== _Y′~C~C′~BC~C′~CR~_ constant luminance color model +=== _Y{prime}~C~C{prime}~BC~C{prime}~CR~_ constant luminance color model -<> introduced a ``constant luminance'' +<> introduced a "`constant luminance`" color representation as an alternative representation to -_Y′C~B~C~R~_: +_Y{prime}C~B~C~R~_: [latexmath] -++++++ +++++ \begin{align*} Y'_C & = (0.2627R + 0.6780G + 0.0593B)' \\ C'_\mathit{BC} & = \begin{cases} @@ -431,25 +431,25 @@ C'_\mathit{RC} & = \begin{cases} {{R'-Y'_C}\over{1.7184}}, & -0.8592 \leq R'-Y'_C \leq 0 \\ {{R'-Y'_C}\over{0.9936}}, & 0 < R'-Y'_C \leq 0.4968\end{cases} \end{align*} -++++++ +++++ This terminology follow's BT.2020's convention of describing the -continuous values as latexmath:[$Y'_C$], latexmath:[$C'_\mathit{BC}$] and -latexmath:[$C'_\mathit{RC}$]; BT.2020 uses latexmath:[$\mathit{DY}'_C$], -latexmath:[$\mathit{DC}'_\mathit{BC}$] and -latexmath:[$\mathit{DC}'_\mathit{RC}$] to represent the +continuous values as latexmath:[Y'_C], latexmath:[C'_\mathit{BC}] and +latexmath:[C'_\mathit{RC}]; BT.2020 uses latexmath:[\mathit{DY}'_C], +latexmath:[\mathit{DC}'_\mathit{BC}] and +latexmath:[\mathit{DC}'_\mathit{RC}] to represent the quantized integer representations of the same values. -NOTE: latexmath:[$Y'_C$] is derived from applying a non-linear transfer -function to a combination of linear latexmath:[$\mathit{RGB}$] components +NOTE: latexmath:[Y'_C] is derived from applying a non-linear transfer +function to a combination of linear latexmath:[\mathit{RGB}] components and applying a non-linear transfer function to the result, but the -latexmath:[$C'_\mathit{BC}$] and latexmath:[$C'_\mathit{RC}$] color differences +latexmath:[C'_\mathit{BC}] and latexmath:[C'_\mathit{RC}] color differences still encode differences between non-linear values. The inverse transformation can be derived from the above: [latexmath] -++++++ +++++ \begin{align*} B' & = \begin{cases} Y'_C + 1.9404C'_\mathit{BC}, & C'_\mathit{BC} \leq 0 \\ @@ -459,7 +459,7 @@ R' & = \begin{cases} Y'_C + 0.9936C'_\mathit{RC}, & C'_\mathit{RC} > 0\end{cases}\\ G & = Y_C - 0.2627R - 0.0593B \end{align*} -++++++ +++++ NOTE: Performing these calculations requires conversion between a linear representation and a non-linear transfer function during @@ -469,12 +469,12 @@ case, which is a simple matrix transform. [[MODEL_ICTCP]] === _IC~T~C~P~_ constant intensity color model -<> introduced a ``constant intensity'' +<> introduced a "`constant intensity`" color representation as an alternative representation to -_Y′C~B~C~R~_: +_Y{prime}C~B~C~R~_: [latexmath] -++++++ +++++ \begin{align*} L & = {(1688R + 2146G + 262B)\over{4096}}\\ M & = {(683R + 2951G + 462B)\over{4096}}\\ @@ -492,7 +492,7 @@ I & = 0.5L' + 0.5M'\\ C_T & = {(6610L' - 13613M' + 7003S')\over{4096}}\\ C_P & = {(17933L' - 17390M' - 543S')\over{4096}} \end{align*} -++++++ +++++ Note that the suffix ~D~ indicates that PQ encoding is _display-referred_ and the suffix ~S~ indicates that HLG @@ -501,9 +501,11 @@ display and scene light respectively. To invert this, it can be observed that: +//@ To be checked - Jon + [latexmath] -++++++ - $$\left(\begin{array}{c}L' \\ +++++ +\left(\begin{array}{c}L' \\ M' \\ S' \end{array}\right) = 4096\times @@ -512,8 +514,8 @@ To invert this, it can be observed that: 17933, & -17390, & -543\end{array}\right)^{-1} \left(\begin{array}{c}I\\ C_T\\ - C_P\end{array}\right)$$ - $$\left(\begin{array}{c}L' \\ + C_P\end{array}\right) +\left(\begin{array}{c}L' \\ M' \\ S' \end{array}\right) = \left(\begin{array}{rrr}1, & 1112064/129174029, & 14342144/129174029 \\ @@ -521,8 +523,8 @@ To invert this, it can be observed that: 1, & 72341504/129174029, & -41416704/129174029\end{array}\right) \left(\begin{array}{c}I\\ C_T\\ - C_P\end{array}\right)$$ - $$\left(\begin{array}{c}L' \\ + C_P\end{array}\right) +\left(\begin{array}{c}L' \\ M' \\ S' \end{array}\right) \approx \left(\begin{array}{rrr}1, & 0.0086090370, & 0.1110296250 \\ @@ -530,10 +532,10 @@ To invert this, it can be observed that: 1, & 0.5600313357, & -0.3206271750\end{array}\right) \left(\begin{array}{c}I\\ C_T\\ - C_P\end{array}\right)$$ - $$\{L_D,M_D,S_D\} = \textrm{EOTF}_{\textrm{PQ}}(\{L',M',S'\})$$ - $$\{L_S,M_S,S_S\} = \textrm{OETF}_{\textrm{HLG}}^{-1}(\{L',M',S'\})$$ - $$\left(\begin{array}{c}R \\ + C_P\end{array}\right) +\{L_D,M_D,S_D\} = \textrm{EOTF}_{\textrm{PQ}}(\{L',M',S'\}) +\{L_S,M_S,S_S\} = \textrm{OETF}_{\textrm{HLG}}^{-1}(\{L',M',S'\}) +\left(\begin{array}{c}R \\ G \\ B\end{array}\right) = 4096\times @@ -542,8 +544,8 @@ To invert this, it can be observed that: 99, & 309, & 3688\end{array}\right)^{-1} \left(\begin{array}{c}L\\ M\\ - S\end{array}\right)$$ - $$\left(\begin{array}{c}R \\ + S\end{array}\right) +\left(\begin{array}{c}R \\ G \\ B \end{array}\right) = {4096\over 12801351680}\times \left(\begin{array}{rrr}10740530, & -7833490, & 218290 \\ @@ -551,8 +553,8 @@ To invert this, it can be observed that: -81102, & -309138, & 3515570\end{array}\right) \left(\begin{array}{c}L\\ M\\ - S\end{array}\right)$$ - $$\left(\begin{array}{c}R \\ + S\end{array}\right) +\left(\begin{array}{c}R \\ G \\ B \end{array}\right) \approx \left(\begin{array}{rrr}3.4366066943, & -2.5064521187, & 0.0698454243 \\ @@ -560,5 +562,5 @@ To invert this, it can be observed that: -0.0259498997, & -0.0989137147, & 1.1248636144\end{array}\right) \left(\begin{array}{c}L\\ M\\ - S\end{array}\right)$$ -++++++ + S\end{array}\right) +++++ diff --git a/chapters/compformats.adoc b/chapters/compformats.adoc new file mode 100644 index 0000000..917e5e8 --- /dev/null +++ b/chapters/compformats.adoc @@ -0,0 +1,18 @@ +// Copyright 2014-2026 The Khronos Group Inc. +// SPDX-License-Identifier: CC-BY-4.0 + +include::{chapters}/compintro.adoc[] + +include::{chapters}/s3tc.adoc[] + +include::{chapters}/rgtc.adoc[] + +include::{chapters}/bptc.adoc[] + +include::{chapters}/etc1.adoc[] + +include::{chapters}/etc2.adoc[] + +include::{chapters}/astc.adoc[] + +include::{chapters}/pvrtc.adoc[] diff --git a/compintro.txt b/chapters/compintro.adoc similarity index 70% rename from compintro.txt rename to chapters/compintro.adoc index 2a2ab8b..55bd504 100644 --- a/compintro.txt +++ b/chapters/compintro.adoc @@ -1,45 +1,48 @@ +// Copyright 2014-2026 The Khronos Group Inc. +// SPDX-License-Identifier: CC-BY-4.0 + == Compressed Texture Image Formats For computer graphics, a number of texture compression schemes exist which reduce both the overall texture memory footprint and the bandwidth requirements of using the textures. -In this context, ``texture compression'' is distinct from ``image -compression'' in that texture compression schemes are designed to +In this context, "`texture compression`" is distinct from "`image +compression`" in that texture compression schemes are designed to allow efficient random access as part of texture sampling: -``image compression'' can further reduce image redundancy by +"`image compression`" can further reduce image redundancy by considering the image as a whole, but doing so is impractical for efficient texture access operations. -The common texture compression schemes are ``block-based'', +The common texture compression schemes are "`block-based`", relying on similarities between nearby texel regions to describe -``blocks'' of nearby texels in a unit: +"`blocks`" of nearby texels in a unit: -* ``<>'' describes a block of 4{times}4 _RGB_ texels - in terms of a low-precision pair of color ``endpoints'', and +* "`<>`" describes a block of 4{times}4 _RGB_ texels + in terms of a low-precision pair of color "`endpoints`", and allow each texel to specify an interpolation point between these endpoints. Alpha channels, if present, may be described similarly or with an explict per-texel alpha value. -* ``<>'' provides one- and two-channel schemes for - interpolating between two ``endpoints'' per 4{times}4 texel +* "`<>`" provides one- and two-channel schemes for + interpolating between two "`endpoints`" per 4{times}4 texel block, and are intended to provide efficient schemes for normal encoding, complementing the three-channel approach of S3TC. -* ``<>'' offers a number of ways of encoding and +* "`<>`" offers a number of ways of encoding and interpolating endpoints, and allows the 4{times}4 texel block - to be divided into multiple ``subsets'' which can be encoded + to be divided into multiple "`subsets`" which can be encoded independently, which can be useful for managing different regions with sharp transitions. -* ``<>'' provides ways of encoding 4{times}4 texel blocks +* "`<>`" provides ways of encoding 4{times}4 texel blocks as two regions of 2{times}4 or 4{times}2 texels, each of which are specified as a base color; texels are then encoded as offsets relative to these bases, varying by a grayscale offset. -* ``<>'' is a superset of ETC1, adding schemes for color +* "`<>`" is a superset of ETC1, adding schemes for color patterns that would fit poorly into ETC1 options. -* ``<>'' allows a wide range of ways of encoding each +* "`<>`" allows a wide range of ways of encoding each color block, and supports choosing different block sizes to encode the texture, providing a range of compression ratios; it also supports 3D and HDR textures. -* ``<>'' describes several encoding schemes with two colors +* "`<>`" describes several encoding schemes with two colors per block of 4{times}4 or 8{times}4 texels, interpolated between adjacent texel blocks, and means of modulating between them. diff --git a/conversionintro.txt b/chapters/conversionintro.adoc similarity index 77% rename from conversionintro.txt rename to chapters/conversionintro.adoc index 6d89c64..b961e32 100644 --- a/conversionintro.txt +++ b/chapters/conversionintro.adoc @@ -1,10 +1,11 @@ -// Copyright (c) 2019 The Khronos Group Inc. -// Copyright notice at https://www.khronos.org/registry/speccopyright.html +// Copyright 2019-2026 The Khronos Group Inc. +// SPDX-License-Identifier: CC-BY-4.0 == Introduction to color conversions + === Color space composition -A ``color space'' determines the meaning of decoded numerical +A "`color space`" determines the meaning of decoded numerical color values: that is, it is distinct from the bit patterns, compression schemes and locations in memory used to store the data. @@ -17,19 +18,19 @@ A color space consists of three basic components: non-linear, a non-linear encoding scheme typically allows improved visual quality at reduced storage cost. ** An opto-electrical transfer function (OETF) describes the - conversion from ``scene-referred'' normalized linear light + conversion from "`scene-referred`" normalized linear light intensity to a (typically) non-linear electronic representation. - The inverse function is written ``OETF^ -1^''. + The inverse function is written "`OETF^{nbsp}-1^`". ** An electro-optical transfer function (EOTF) describes the conversion from the electronic representation to - ``display-referred'' normalized linear light intensity in + "`display-referred`" normalized linear light intensity in the display system. - The inverse function is written ``EOTF^ -1^''. + The inverse function is written "`EOTF^{nbsp}-1^`". ** An opto-optical transfer function (OOTF) describes the relationship between the linear scene light intensity and linear display light intensity: OOTF(x) = EOTF(OETF(x)). - OETF = EOTF^ -1^ and - EOTF = OETF^ -1^ only if the OOTF is linear. + OETF{nbsp}={nbsp}EOTF^{nbsp}-1^ and + EOTF{nbsp}={nbsp}OETF^{nbsp}-1^ only if the OOTF is linear. ** Historically, a non-linear transfer function has been implicit due to the non-linear relationship between voltage and intensity provided by a CRT display. @@ -40,8 +41,8 @@ A color space consists of three basic components: which have too much or too little contrast or saturation, particularly in mid-tones. * <> define the spectral - response of a ``pure color'' in an additive color model - - typically, what is meant by ``red'', ``green'' and ``blue'' + response of a "`pure color`" in an additive color model - + typically, what is meant by "`red`", "`green`" and "`blue`" for a given system, and (allowing for the relative intensity of the primaries) consequently define the system's white balance. @@ -66,11 +67,11 @@ A color space consists of three basic components: composing a color, many formats benefit from transforming the color representation into one which can separate these aspects of color. - Color models are frequently ``named'' by listing their + Color models are frequently "`named`" by listing their component color channels. ** For example, a color model might directly represent additive primaries (_RGB_), simple color difference values - (_Y′C~B~C~R~_ -- colloquially _YUV_), or + (_Y{prime}C~B~C~R~_ -- colloquially _YUV_), or separate hue, saturation and intensity (_HSV_/_HSL_). ** Interpreting an image with an incorrect color model typically results in wildly incorrect colors: a (0,0,0) triple in an @@ -86,21 +87,21 @@ separate conversion operations: * Conversion between representations with different <> can be performed directly. If the input and output of the conversion do not share the same - color primaries, this transformation forms the ``core'' of the + color primaries, this transformation forms the "`core`" of the conversion. * The color primary conversion operates on linear _RGB_ additive color values; if the input or output are not defined in linear terms but with a non-linear <>, any color primary conversion must be ``wrapped'' with + function>>, any color primary conversion must be "`wrapped`" with any transfer functions; conventionally, non-linear _RGB_ - values are written _R′G′B′_. + values are written _R{prime}G{prime}B{prime}_. * If the input or output <> is not defined in terms of additive primaries (for example, - _Y′C~B~C~R~_ -- colloquially known as _YUV_), the model - conversion is applied to the non-linear _R′G′B′_ - values; the _Y′~C~C′~CB~C′~CR~_ and _IC~T~C~P~_ + _Y{prime}C~B~C~R~_ -- colloquially known as _YUV_), the model + conversion is applied to the non-linear _R{prime}G{prime}B{prime}_ + values; the _Y{prime}~C~C{prime}~CB~C{prime}~CR~_ and _IC~T~C~P~_ color models are created from both linear and non-linear _RGB_. @@ -126,21 +127,21 @@ the legal framework required for implementation. <<< -Common cases such as converting a _Y′C~B~C~R~_ image -encoded for 625-line <> to a _Y′C~B~C~R~_ +Common cases such as converting a _Y{prime}C~B~C~R~_ image +encoded for 625-line <> to a _Y{prime}C~B~C~R~_ image encoded for <> can involve multiple costly operations. An example is shown in the following diagram, which represents -sampling from a _Y′C~B~C~R~_ texture in one color space, +sampling from a _Y{prime}C~B~C~R~_ texture in one color space, and the operations needed to generate a different set of -_Y′C~B~C~R~_ values representing the color of the sample +_Y{prime}C~B~C~R~_ values representing the color of the sample position in a different color space: [[conversionexample]] .Example sampling in one space and converting to a different space -image::images/colorconversion_accurate.{svgpdf}[width="{svgpdf@pdf:475pt:576}",align="center"] +image::{images}/colorconversion_accurate.svg[width="{svgpdf@pdf:475pt:576}",align="center"] -In this diagram, non-linear luma _Y′_ channels are shown +In this diagram, non-linear luma _Y{prime}_ channels are shown in black and white, color difference _C~B~_/_C~R~_ channels are shown with the colors at the extremes of their range, and color primary channels are shown as the primary color and black. @@ -155,7 +156,7 @@ As described below, the diagram shows a 2{times}3 grid of input chroma texel values, corresponding to a 4{times}6 grid of luma texel values, since the chroma channels are stored at half the horizontal and half the vertical resolution of the luma -channel (i.e. in ``4:2:0'' representation). +channel (i.e. in "`4:2:0`" representation). Grayed-out texel values do not contribute to the final output, and are shown only to indicate relative alignment of the coordinates. @@ -164,13 +165,13 @@ shown only to indicate relative alignment of the coordinates. The stages numbered in <> show the following operations: . Arranging the channels from the representation correctly for the - conversion operations (a ``swizzle''). + conversion operations (a "`swizzle`"). In this example, the implementation requires that the _C~B~_ and _C~R~_ values be swapped. . Range expansion to the correct range for the values in the color - model (handled differently, for example, for ``<>'' - and ``<>'' ranges); in this example, the result + model (handled differently, for example, for "`<>`" + and "`<>`" ranges); in this example, the result is to increase the effective dynamic range of the encoding: contrast and saturation are increased. + @@ -179,7 +180,7 @@ sparse matrix multiplication of the input channels, although actual implementations may wish to take advantage of the sparseness. . Reconstruction to full resolution of channels which are not at the - full sampling resolution (``chroma reconstruction''), for example by + full sampling resolution ("`chroma reconstruction`"), for example by replication or interpolation at the sites of the luma samples, allowing for the chroma sample positions; this example assumes that the chroma samples are being reconstructed through linear interpolation. @@ -190,27 +191,27 @@ implementations may wish to take advantage of the sparseness. align the chroma samples differently. Note that interpolation for channel reconstruction necessarily happens in a non-linear representation for color difference representations - such as _Y′C~B~C~R~_: creating a linear representation would + such as _Y{prime}C~B~C~R~_: creating a linear representation would require converting to _RGB_, which in turn requires a full - set of _Y′C~B~C~R~_ samples for a given location. + set of _Y{prime}C~B~C~R~_ samples for a given location. . Conversion between color models -- in this example, from non-linear - _Y′C~B~C~R~_ to non-linear _R′G′B′_. + _Y{prime}C~B~C~R~_ to non-linear _R{prime}G{prime}B{prime}_. For example, the conversion might be that between BT.601 - _Y′C~B~C~R~_ and BT.601 non-linear _R′G′B′_ + _Y{prime}C~B~C~R~_ and BT.601 non-linear _R{prime}G{prime}B{prime}_ described in <>. - For _Y′C~B~C~R~_ to _R′G′B′_, this + For _Y{prime}C~B~C~R~_ to _R{prime}G{prime}B{prime}_, this conversion is a sparse matrix multiplication. . Application of a transfer function to convert from non-linear - _R′G′B′_ to linear _RGB_, using the + _R{prime}G{prime}B{prime}_ to linear _RGB_, using the color primaries of the input representation. - In this case, the conversion might be the EOTF^ -1^ described + In this case, the conversion might be the EOTF^{nbsp}-1^ described in <>. + -The separation of stages 4 and 5 is specific to the _Y′C~B~C~R~_ -to _R′G′B′_ color model conversion. -Other representations such as _Y′~C~C′~BC~C′~RC~_ and +The separation of stages 4 and 5 is specific to the _Y{prime}C~B~C~R~_ +to _R{prime}G{prime}B{prime}_ color model conversion. +Other representations such as _Y{prime}~C~C{prime}~BC~C{prime}~RC~_ and _IC~T~C~P~_ have more complex interactions between the color model conversion and the transfer function. @@ -225,11 +226,11 @@ model conversion and the transfer function. <>. . Convert from the linear _RGB_ representation using the - target primaries to a non-linear _R′G′B′_ + target primaries to a non-linear _R{prime}G{prime}B{prime}_ representation, for example the OETF described in <>. -. Conversion from non-linear _R′G′B′_ to the - _Y′C~B~C~R~_ color model, for example as defined +. Conversion from non-linear _R{prime}G{prime}B{prime}_ to the + _Y{prime}C~B~C~R~_ color model, for example as defined in as defined in <> (a matrix multiplication). @@ -241,22 +242,22 @@ operation if the source space chroma values are generated by interpolation. In this example, generating the four linear _RGB_ values required for linear interpolation at the magenta cross position requires _six_ chroma samples. -In the example shown, all four _Y′_ values fall between the +In the example shown, all four _Y{prime}_ values fall between the same two chroma sample centers on the horizontal axis, and therefore recreation of these samples by linear blending on the horizontal axis only requires two horizontally-adjacent samples. -However, the upper pair of _Y′_ values are sited above +However, the upper pair of _Y{prime}_ values are sited above the sample position of the middle row of chroma sample centers, and therefore reconstruction of the corresponding chroma values requires interpolation between the upper four source chroma values. -The lower pair of _Y′_ values are sited below the sample +The lower pair of _Y{prime}_ values are sited below the sample position of the middle row of chroma sample centers, and therefore reconstruction of the corresponding chroma values requires interpolation between the lower four source chroma values. In general, reconstructing four chroma values by interpolation may require four, six or nine source chroma values, depending on which samples are required. -The worst case is reduced if chroma samples are aligned (``co-sited'') +The worst case is reduced if chroma samples are aligned ("`co-sited`") with the luma values, or if chroma channel reconstruction uses replication (nearest-neighbor filtering) rather than interpolation. @@ -267,7 +268,7 @@ depicted in <>: [[approximateconversionexample]] .Example approximated sampling in one space and converting to a different space -image::images/colorconversion_approximate.{svgpdf}[width="{svgpdf@pdf:475pt:576}",align="center"] +image::{images}/colorconversion_approximate.svg[width="{svgpdf@pdf:475pt:576}",align="center"] A performance-optimized approximation to our example conversion may use the following steps: @@ -279,12 +280,12 @@ use the following steps: approximated by adjusting the sample locations to compensate for the reduced resolution and sample positions of the chroma channels, resulting in a single set of non-linear - _Y′C~B~C~R~_ values. -. Model conversion from _Y′C~B~C~R~_ to _R′G′B′_ + _Y{prime}C~B~C~R~_ values. +. Model conversion from _Y{prime}C~B~C~R~_ to _R{prime}G{prime}B{prime}_ as described in <>, here performed _after_ the sampling/filtering operation. -. Conversion from non-linear _R′G′B′_ to linear - _RGB_, using the EOTF^ -1^ described +. Conversion from non-linear _R{prime}G{prime}B{prime}_ to linear + _RGB_, using the EOTF^{nbsp}-1^ described in <>. . Conversion of color primaries, corresponding to step 7 of the previous example. @@ -310,7 +311,7 @@ However, there are two sources of errors near color boundaries: but can introduce both intensity and color shifts. Note that applying a non-linear transfer function as part of filtering does not improve accuracy for color models other than - _R′G′B′_ since the non-linear additive values have been + _R{prime}G{prime}B{prime}_ since the non-linear additive values have been transformed as part of the color model representation. . When chroma reconstruction is bilinear and the final sample operation is bilinear, the interpolation operation now only access a maximum of @@ -330,29 +331,29 @@ sequence of operations in two cases: coordinate position is adjusted to the nearest luma sample location. As another example, the conversion from BT.709-encoded -_Y′C~B~C~R~_ to sRGB _R′G′B′_ may be considered +_Y{prime}C~B~C~R~_ to sRGB _R{prime}G{prime}B{prime}_ may be considered to be a simple <> (to -<> _R′G′B′_ non-linear primaries -using the ``<>'' OETF), since sRGB shares the BT.709 +<> _R{prime}G{prime}B{prime}_ non-linear primaries +using the "`<>`" OETF), since sRGB shares the BT.709 color primaries and is defined as a complementary <> intended to be combined with BT.709's OETF. -This interpretation imposes a latexmath:[$\gamma \approx$] 1.1 +This interpretation imposes a latexmath:[\gamma \approx] 1.1 OOTF. Matching the OOTF of a <>-<> system, -for which latexmath:[$\gamma \approx$] 1.2, implies using the +for which latexmath:[\gamma \approx] 1.2, implies using the <> EOTF to convert to linear light, -then the <> EOTF^ -1^ to convert back +then the <> EOTF^{nbsp}-1^ to convert back to sRGB non-linear space. Encoding linear scene light with linear OOTF means applying -the <> OETF^ -1^; if the sRGB -_R′G′B′_ target is itself intended to represent -a linear OOTF, then the {_R′~sRGB~_, _G′~sRGB~_, -_B′~sRGB~_} should be calculated as: +the <> OETF^{nbsp}-1^; if the sRGB +_R{prime}G{prime}B{prime}_ target is itself intended to represent +a linear OOTF, then the {_R{prime}~sRGB~_, _G{prime}~sRGB~_, +_B{prime}~sRGB~_} should be calculated as: [latexmath] -+++++ -$$\{\mathit{R}'_\mathit{sRGB},\mathit{G}'_\mathit{sRGB},\mathit{B}'_\mathit{sRGB}\} = +++++ +\{\mathit{R}'_\mathit{sRGB},\mathit{G}'_\mathit{sRGB},\mathit{B}'_\mathit{sRGB}\} = \textrm{EOTF}^{-1}_{sRGB}(\textrm{OETF}^{-1}_{\mathit{BT}.709} -(\{\mathit{R}'_{\mathit{BT}.709},\mathit{G}'_{\mathit{BT}.709},\mathit{B}'_{\mathit{BT}.709}\}))$$ -+++++ +(\{\mathit{R}'_{\mathit{BT}.709},\mathit{G}'_{\mathit{BT}.709},\mathit{B}'_{\mathit{BT}.709}\})) +++++ diff --git a/chapters/conversions.adoc b/chapters/conversions.adoc new file mode 100644 index 0000000..5d325af --- /dev/null +++ b/chapters/conversions.adoc @@ -0,0 +1,12 @@ +// Copyright 2017-2026 The Khronos Group Inc. +// SPDX-License-Identifier: CC-BY-4.0 + +include::{chapters}/conversionintro.adoc[] + +include::{chapters}/transferfunctions.adoc[] + +include::{chapters}/primaries.adoc[] + +include::{chapters}/colormodels.adoc[] + +include::{chapters}/quantization.adoc[] diff --git a/df.txt b/chapters/df.adoc similarity index 83% rename from df.txt rename to chapters/df.adoc index 6c8d6ba..839f23a 100644 --- a/df.txt +++ b/chapters/df.adoc @@ -1,10 +1,8 @@ -// Copyright (c) 2014-2019 The Khronos Group Inc. -// Copyright notice at https://www.khronos.org/registry/speccopyright.html -ifdef::a2xhtml[] -= Khronos Data Format Specification v1.3.1 = -endif::[] -[abstract] +// Copyright 2014-2026 The Khronos Group Inc. +// SPDX-License-Identifier: CC-BY-4.0 +[abstract] +-- This document describes a data format specification for non-opaque (user-visible) representations of user data to be used by, and shared between, Khronos standards. The intent of this specification is to @@ -16,25 +14,9 @@ allowing formats to be shared and compared. This document also acts as a reference for the memory layout of a number of common compressed texture formats, and describes conversion between a number of common color spaces. +-- -// Symbols... -:times: × -:plus: + -:check: ✓ -:alpha: α -:beta: β -:gamma: γ -:rho: ρ -:leq: ≤ -:geq: ≥ -:cdot: · -:asciidoc-numbered: - -ifndef::a2xhtml[] -= Introduction -endif::[] - -== Introduction == +== Introduction Many APIs operate on bulk data -- buffers, images, volumes, etc. -- each composed of many elements with a fixed and often simple representation. @@ -95,11 +77,11 @@ Later sections describe some of the common color space conversion operations and provide a description of the memory layout of a number of common texture compression formats. -ifndef::a2xhtml[] -= The Khronos Data Format Descriptor Block +ifndef::backend-html5[] += The Khronos Data Format Descriptor Block endif::[] -== Formats and texel access == +== Formats and texel access This document describes a standard layout for a data structure that can be used to define the representation of simple, portable, bulk data. Using such @@ -109,7 +91,7 @@ a data structure has the following benefits: * Simplifying the writing of generic functionality that acts on many types of data * Offering portability of data between APIs -The ``bulk data'' may be, for example: +The "`bulk data`" may be, for example: * Pixel/texel data * Vertex data @@ -120,7 +102,7 @@ specification, but the large number of ways to describe colors, vertices and other repeated data makes standardization useful. The widest variety of standard representations and the most common expected use of this API is to describe pixels or texels; as such the -terms ``texel'' and ``pixel'' are used interchangeably in this +terms "`texel`" and "`pixel`" are used interchangeably in this specification when referring to elements of data, without intending to imply a restriction in use. @@ -134,7 +116,7 @@ descriptor as defined in this specification, but may have different sizes, line or plane strides, tiling or dimensionality; in common parlance, two images that describe (for example) color data in the same way but which are of different shapes or sizes are still described as having the same -``format''. +"`format`". An example pixel representation is described in <>: a single 5:6:5-bit pixel composed of a blue channel in the low 5 bits, a @@ -144,7 +126,7 @@ green channel in the next 6 bits, and red channel in the top 5 bits of a [[SimpleTexelBlock]] .A simple one-texel texel block -image::images/565pixels.{svgpdf}[width="{svgpdf@pdf:400pt:800}",align="center"] +image::{images}/565pixels.svg[width="{svgpdf@pdf:400pt:800}",align="center"] === 1-D texel addressing @@ -157,7 +139,8 @@ Taking the simplest case of an array in the C programming language as an example, a developer might define the following structure to represent a color texel: ------ +[source] +---- typedef struct _MyRGB { unsigned char red; unsigned char green; @@ -165,7 +148,7 @@ typedef struct _MyRGB { } MyRGB; MyRGB *myRGBarray = (MyRGB *) malloc(100 * sizeof(MyRGB)); ------ +---- To determine the location of, for example, the tenth element of ++myRGBarray++, the compiler needs to know the base address of @@ -179,22 +162,23 @@ of ++red++, ++green++ and ++blue++ due to padding; the difference in address between one ++MyRGB++ and the next can be described as the _pixel stride_ in bytes. -[[1DBytes]] +[[im-1DBytes]] .(Trivial) 1D address offsets for 1-byte elements, start of buffer -image::images/1DByteOffset.{svgpdf}[width="{svgpdf@pdf:290pt:450}",align="center"] +image::{images}/1DByteOffset.svg[width="{svgpdf@pdf:290pt:450}",align="center"] -[[1DWords]] +[[im-1DWords]] .1D address offsets for 2-byte elements, start of buffer -image::images/1DWordOffset.{svgpdf}[width="{svgpdf@pdf:290pt:450}",align="center"] +image::{images}/1DWordOffset.svg[width="{svgpdf@pdf:290pt:450}",align="center"] -[[1DRGB]] +[[im-1DRGB]] .1D address offsets for _R_,_G_,_B_ elements (padding in gray), start of buffer -image::images/1DRGBOffset.{svgpdf}[width="{svgpdf@pdf:460pt:720}",align="center"] +image::{images}/1DRGBOffset.svg[width="{svgpdf@pdf:460pt:720}",align="center"] -An alternative representation is a ``structure of arrays'', -distinct from the ``array of structures'' ++myRGBarray++: +An alternative representation is a "`structure of arrays`", +distinct from the "`array of structures`" ++myRGBarray++: ------ +[source] +---- typedef struct _MyRGBSoA { unsigned char *red; unsigned char *green; @@ -205,14 +189,14 @@ MyRGBSoA myRGBSoA; myRGBSoA.red = (unsigned char *) malloc(100); myRGBSoA.green = (unsigned char *) malloc(100); myRGBSoA.blue = (unsigned char *) malloc(100); ------ +---- In this case, accessing a value requires the ++sizeof++ each channel element. The best approach depends on the operations performed: calculations on one whole ++MyRGB++ a time likely favor ++MyRGB++, those processing multiple values from a single channel may prefer ++MyRGBSoA++. -A ``pixel'' need not fill an entire byte -- nor need _pixel stride_ +A "`pixel`" need not fill an entire byte -- nor need _pixel stride_ be a whole number of bytes. For example, a C{plus}{plus} ++std::vector++ can be considered to be a 1-D bulk data structure of individual bits. @@ -235,35 +219,35 @@ In a simple 2-D representation, the row stride and the offset from the start of the storage can be described as follows: [latexmath] -++++++ +++++ \begin{align*} \textit{row stride}_\textit{pixels} &= \textit{width}_\textit{pixels} + \textit{padding}_\textit{pixels} \\ \textit{row stride}_\textit{bytes} &= \textit{width}_\textit{pixels} \times \textit{pixel stride}_\textit{bytes} + \textit{padding}_\textit{bytes} \\ \textit{offset}_\textit{pixels} &= x + (y \times \textit{rowstride}_\textit{pixels}) \\ \textit{address}_\textit{bytes} &= \textit{base} + (x \times \textit{pixel stride}_\textit{bytes}) + (y \times \textit{row stride}_\textit{bytes}) \end{align*} -++++++ +++++ -<<2DLinear>> shows example coordinate byte offsets for a 13{times}4 +<> shows example coordinate byte offsets for a 13{times}4 buffer, padding row stride to a multiple of four elements. -[[2DLinear]] +[[im-2DLinear]] .2D linear texel offsets from coordinates -image::images/2DLinearOffsets.{svgpdf}[width="{svgpdf@pdf:350pt:540}",align="center"] +image::{images}/2DLinearOffsets.svg[width="{svgpdf@pdf:350pt:540}",align="center"] -[[2DLinearMemoryOrder]] +[[im-2DLinearMemoryOrder]] .Order of byte storage in memory for coordinates in a linear 5{times}3 buffer, padded (italics) to 8{times}3 [cols="3,24*^",width="100%"] -|============================== +|==== ^| Byte | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 ^| Coords | *0,0* | *1,0* | *2,0* | *3,0* | *4,0* | _5,0_ | _6,0_ | _7,0_ | *0,1* | *1,1* | *2,1* | *3,1* | *4,1* | _5,1_ | _6,1_ | _7,1_ | *0,2* | *1,2* | *2,2* | *3,2* | *4,2* | _5,2_ | _6,2_ | _7,2_ -|============================== +|==== -[[2DLinearRGB]] +[[im-2DLinearRGB]] .2D _R_,_G_,_B_ byte offsets (padding in gray) from coordinates for a 4{times}4 image -image::images/2DRGBOffsets.{svgpdf}[width="{svgpdf@pdf:350pt:540}",align="center"] +image::{images}/2DRGBOffsets.svg[width="{svgpdf@pdf:350pt:540}",align="center"] -By convention, this ``linear'' layout is in _y_-major order (with the +By convention, this "`linear`" layout is in _y_-major order (with the _x_ axis changing most quickly). This does not necessarily imply that an API which accesses the 2D data will do so in this orientation, and there are image layouts which have @@ -276,9 +260,9 @@ _plane_ of data. In the same way that 1-D data can be described in structure-of-arrays form, two-dimensional data can also be implemented as multiple _planes_. -[[2DRGBplanes]] +[[im-2DRGBplanes]] .2D _R_,_G_,_B_ plane offsets from coordinates for 8{times}4 texels -image::images/2DRGBplanes.{svgpdf}[width="{svgpdf@pdf:250pt:400}",align="center"] +image::{images}/2DRGBplanes.svg[width="{svgpdf@pdf:250pt:400}",align="center"] In early graphics, planes often contributed individual bits to the pixel. This allowed pixels of less than a byte, reducing bandwidth and storage; @@ -310,7 +294,7 @@ to addressing the data. <<< === More complex 2-D texel addressing -In many applications, the simple ``linear'' layout of memory has +In many applications, the simple "`linear`" layout of memory has disadvantages. The primary concern is that data which is vertically adjacent in two-dimensional space may be widely separated in memory address. @@ -336,7 +320,7 @@ were an independent, smaller image, and the order of tiles in memory may be as in the linear layout: [latexmath] -++++++ +++++ \begin{align*} \textit{If}\ a\ \%\ b &= a - \left(b\times\left\lfloor{a\over b}\right\rfloor\right), & \textit{texel offset} &= \left(x\ \%\ \textit{tw}\right) @@ -344,35 +328,38 @@ may be as in the linear layout: + \left\lfloor{x\over\textit{tw}}\right\rfloor\times\textit{th}\times\textit{tw} + \left\lfloor{y\over\textit{th}}\right\rfloor\times\textit{th}\times\textit{line stride} \end{align*} -++++++ +++++ This approach can be implemented efficiently in hardware, so long as the tile dimensions are powers of two, by interleaving some bits from the y-coordinate with the bits contributed by the x-coordinate. If ++twb++ = log~2~(_tw_) and ++thb++ = log~2~(_th_): ------ +[source] +---- pixelOffset = (x & ((1 << twb) - 1)) | ((y & ((1 << thb) - 1)) << twb) | ((x & ~((1 << twb) - 1)) << thb) | ((y & ~((1 << thb)-1)) * lineStride); ------ +---- For example, if a linear 16{times}12 image calculates a pixel offset relative to the start of the buffer as: ------ +[source] +---- pixelOffset = x | (y * 16); ------ +---- a 16{times}12 image comprised of 4{times}4 tiles may calculate the pixel offset relative to the start of the buffer as: ------ +[source] +---- pixelOffset = (x & 3) | ((y & 3) << 2) | ((x & ~3) << 2) | ((y & ~3) * 16); ------ +---- -[[2DTile4x4]] +[[im-2DTile4x4]] .4×4 tiled order texel offsets from coordinates (consecutive values linked in red to show the pattern) -image::images/2DTile4x4.{svgpdf}[width="{svgpdf@pdf:350pt:575}",align="center"] +image::{images}/2DTile4x4.svg[width="{svgpdf@pdf:350pt:575}",align="center"] Textures which have dimensions that are not a multiple of the tile size require padding. @@ -380,7 +367,7 @@ size require padding. <<< For so long as the size of a tile fits into an on-chip cache and can be filled efficiently by the memory subsystem, this approach has the -benefit that only one in latexmath:[$1\over n$] transitions between +benefit that only one in latexmath:[1\over n] transitions between vertically-adjacent lines requires accessing outside a tile of height _n_. The larger the tile, the greater the probability that vertically-adjacent @@ -390,16 +377,17 @@ more distant in memory the larger the tile size, and tile sizes which do not conveniently fit the cache and bus sizes of the memory subsystem have inefficiencies; thus the tile size is an architectural trade-off. -While any non-linear representation is typically referred to as ``tiling'', +While any non-linear representation is typically referred to as "`tiling`", some hardware implementations actually use a more complex layout in order to provide further locality of reference. One such scheme is Morton order: -[[2DMorton]] +[[im-2DMorton]] .Morton order texel offsets from coordinates (consecutive values linked in red) -image::images/2DMortonOffsets.{svgpdf}[width="{svgpdf@pdf:350pt:575}",align="center"] +image::{images}/2DMortonOffsets.svg[width="{svgpdf@pdf:350pt:575}",align="center"] ------ +[source] +---- uint32_t mortonOffset(uint32_t x, uint32_t y, uint32_t width, uint32_t height) { @@ -424,7 +412,7 @@ uint32_t mortonOffset(uint32_t x, uint32_t y, offset |= ((x | y) >> shift) << (shift * 2); return offset; } ------ +---- Note that this particular implementation assumes that the smaller of ++width++ and ++height++ is a power of two, and the larger is @@ -436,11 +424,12 @@ more efficient than this C code would imply. Another approach, with even more correlation between locality in _x_,_y_ space and memory offset, is Hilbert curve order: -[[2DHilbert]] +[[im-2DHilbert]] .Hilbert curve order texel offsets from coordinates (consecutive values linked in red) -image::images/2DHilbertOffsets.{svgpdf}[width="{svgpdf@pdf:350pt:575}",align="center"] +image::{images}/2DHilbertOffsets.svg[width="{svgpdf@pdf:350pt:575}",align="center"] ------ +[source] +---- uint32_t h(uint32_t size, uint32_t x, uint32_t y) { const uint32_t z = x ^ y; uint32_t offset = 0; @@ -469,7 +458,7 @@ uint32_t hilbertOffset(uint32_t x, uint32_t y, uint32_t width, uint32_t height) if (width < height) return (width * width) * (y / width) + h(width, y % width, x); else return (height * height) * (x / height) + h(height, x % height, y); } ------ +---- This code assumes that the smaller of ++width++ and ++height++ is a power of two, with the larger a multiple of the smaller. @@ -484,7 +473,7 @@ edges of the shorter dimension. In all these cases, the relationship between coordinates and the memory storage location of the buffer depends on the image size and, other than needing to know the amount of memory occupied by a single texel, is -orthogonal to the ``format''. +orthogonal to the "`format`". Tiling schemes tend to be complemented by proprietary hardware that performs the coordinate-to-address mapping and depends on cache details, so many APIs expose only a linear layout to end-users, keeping @@ -496,17 +485,17 @@ mandates leaving the calculation to the application. === 3-dimensional texel addressing These storage approaches can be extended to additional dimensions, -for example treating a 3-D image as being made up of 2-D ``planes'', +for example treating a 3-D image as being made up of 2-D "`planes`", which are distinct from the concept of storing channels or bits of data in separate planes. In a linear layout, 3-dimensional textures can be accessed as: [latexmath] -++++++ +++++ \begin{align*} \textit{address}_\textit{bytes} &= \textit{base} + (x \times \textit{pixel stride}_\textit{bytes}) + (y \times \textit{row stride}_\textit{bytes}) + (z \times \textit{plane stride}_\textit{bytes}) \end{align*} -++++++ +++++ Here, the _plane stride_ is the offset between the start of one contiguous 2-D plane of data and the next. @@ -516,7 +505,8 @@ any additional padding. Again, non-linear approaches can be used to increase the correlation between storage address and coordinates. ------ +[source] +---- uint32_t tileOffset3D(uint32_t x, uint32_t y, uint32_t z, uint32_t twb, uint32_t thb, uint32_t tdb, uint32_t lineStride, uint32_t planeStride) { @@ -530,9 +520,10 @@ uint32_t tileOffset3D(uint32_t x, uint32_t y, uint32_t z, ((y & ~((1 << thb) - 1)) << tdb) * lineStride | ((z & ~((1 << tdb) - 1)) * planeStride); } ------ +---- ------ +[source] +---- uint32_t mortonOffset3D(uint32_t x, uint32_t y, uint32_t z, uint32_t width, uint32_t height, uint32_t depth) { const uint32_t max = width | height | depth; @@ -545,11 +536,12 @@ uint32_t mortonOffset3D(uint32_t x, uint32_t y, uint32_t z, } return offset; } ------ +---- There are multiple 3D variations on the Hilbert curve; one such is this: ------ +[source] +---- uint32_t hilbertOffset3D(uint32_t x, uint32_t y, uint32_t z, uint32_t size) { // "Harmonious" 3D Hilbert curve for cube of power-of-two edge "size": // http://herman.haverkort.net/recursive_tilings_and_space-filling_curves @@ -570,7 +562,7 @@ uint32_t hilbertOffset3D(uint32_t x, uint32_t y, uint32_t z, uint32_t size) { } return offset; } ------ +---- <<< === Downsampled channels @@ -580,33 +572,33 @@ color channel is present at each access coordinate. However, some common representations break this assumption. One reason for this variation comes from representing the image in the -_Y′C~B~C~R~_ color model, described in <>; in this -description, the _Y′_ channel represents the intensity of light, +_Y{prime}C~B~C~R~_ color model, described in <>; in this +description, the _Y{prime}_ channel represents the intensity of light, with _C~B~_ and _C~R~_ channels describing how the color differs from a gray value of the same intensity in the blue and red axes. Since the human eye is more sensitive to high spatial frequencies in brightness than in the hue of a color, the _C~B~_ and _C~R~_ channels can be recorded at lower spatial resolution than the -_Y′_ channel with little loss in visual quality, saving storage +_Y{prime}_ channel with little loss in visual quality, saving storage space and bandwidth. In one common representation known colloquially as _YUV_ 4:2:2, -each horizontal pair of _Y′_ values has a single _C~B~_ and +each horizontal pair of _Y{prime}_ values has a single _C~B~_ and _C~R~_ value shared for the pair. -For example, <<1DYCBCR_Y>> shows a 6-element 1-D buffer with one -_Y′_ value for each element, but as shown in <<1DYCBCR_CBCR>> +For example, <> shows a 6-element 1-D buffer with one +_Y{prime}_ value for each element, but as shown in <> the _C~B~_ and _C~R~_ values are shared across pairs of elements. -[[1DYCBCR_Y]] -.1-D _Y′C~B~C~R~_ 4:2:2 buffer, texels associated with _Y′_ values -image::images/1DYCbCr_Y.{svgpdf}[width="{svgpdf@pdf:320pt:520}",align="center"] +[[im-1DYCBCR_Y]] +.1-D _Y{prime}C~B~C~R~_ 4:2:2 buffer, texels associated with _Y{prime}_ values +image::{images}/1DYCbCr_Y.svg[width="{svgpdf@pdf:320pt:520}",align="center"] -[[1DYCBCR_CBCR]] -.1-D _Y′C~B~C~R~_ 4:2:2 buffer, texels associated with _C~B~_ and _C~R~_ values -image::images/1DYCbCr_CbCr.{svgpdf}[width="{svgpdf@pdf:320pt:520}",align="center"] +[[im-1DYCBCR_CBCR]] +.1-D _Y{prime}C~B~C~R~_ 4:2:2 buffer, texels associated with _C~B~_ and _C~R~_ values +image::{images}/1DYCbCr_CbCr.svg[width="{svgpdf@pdf:320pt:520}",align="center"] In this case, we can say that the 2{times}1 coordinate region forms -a _texel block_ which contains two _Y′_ values, one _C~B~_ value +a _texel block_ which contains two _Y{prime}_ values, one _C~B~_ value and one _C~R~_ value; our bulk-data buffer or image is composed of a repeating pattern of these texel blocks. @@ -614,7 +606,7 @@ repeating pattern of these texel blocks. Note that this representation raises a question: while we have assumed so far that accessing a value at texel coordinates will provide the value contained in the texel, how should the shared _C~B~_ and _C~R~_ -values relate to the coordinates of the _Y′_ channel? +values relate to the coordinates of the _Y{prime}_ channel? Each texel coordinate represents a value in the coordinate space of the image or buffer, which can be considered as a _sample_ of the value of a continuous surface at that location. @@ -630,26 +622,26 @@ However, to interpret the data correctly, any application still needs to know the theoretical location associated with the samples, so that information is within the remit of this specification. -Our _Y′_ samples should fall naturally on our native coordinates. +Our _Y{prime}_ samples should fall naturally on our native coordinates. However, the _C~B~_ and _C~R~_ sample locations (which are typically at the same location as each other) could be considered as located -coincident with one or other of the _Y′_ values as shown in -<<1DYCbCr_cosited>>, or could be defined as falling at the mid-point -between them as in <<1DYCbCr_midpoint>>. +coincident with one or other of the _Y{prime}_ values as shown in +<>, or could be defined as falling at the mid-point +between them as in <>. Different representations have chosen either of these alternatives -- in some cases, choosing a different option for each coordinate axis. The application can choose how to treat these sample locations: in some cases it may suffice to duplicate _C~B~_ and _C~R~_ across the -pair of _Y′_ values, in others bilinear or bicubic filtering +pair of _Y{prime}_ values, in others bilinear or bicubic filtering may be more appropriate. -[[1DYCbCr_cosited]] -.1-D _Y′C~B~C~R~_ 4:2:2 buffer, _C~B~_ and _C~R~_ cosited with even _Y′_ values -image::images/1DYCbCr_cosited.{svgpdf}[width="{svgpdf@pdf:220pt:340}",align="center"] +[[im-1DYCbCr_cosited]] +.1-D _Y{prime}C~B~C~R~_ 4:2:2 buffer, _C~B~_ and _C~R~_ cosited with even _Y{prime}_ values +image::{images}/1DYCbCr_cosited.svg[width="{svgpdf@pdf:220pt:340}",align="center"] -[[1DYCbCr_midpoint]] -.1-D _Y′C~B~C~R~_ 4:2:2 buffer, _C~B~_ and _C~R~_ midpoint between _Y′_ values -image::images/1DYCbCr_midpoint.{svgpdf}[width="{svgpdf@pdf:220pt:340}",align="center"] +[[im-1DYCbCr_midpoint]] +.1-D _Y{prime}C~B~C~R~_ 4:2:2 buffer, _C~B~_ and _C~R~_ midpoint between _Y{prime}_ values +image::{images}/1DYCbCr_midpoint.svg[width="{svgpdf@pdf:220pt:340}",align="center"] Traditional APIs have described the _C~B~_ and _C~R~_ as having 2{times}1 _downsampling_ in this format (there are half as many samples available @@ -657,41 +649,41 @@ in the horizontal axis for these channels). <<< This concept can be extended to more dimensions. -Commonly, a two-dimensional image stored in _Y′C~B~C~R~_ format +Commonly, a two-dimensional image stored in _Y{prime}C~B~C~R~_ format may store the _C~B~_ and _C~R~_ channels downsampled by a factor of two -in each dimension (``2{times}2 downsampling'', also known for historical -reasons as ``4:2:0''). +in each dimension ("`2{times}2 downsampling`", also known for historical +reasons as "`4:2:0`"). This approach is used in, for example, many JPEG images and MPEG video streams. -Because there are twice as many rows of _Y′_ data as there are +Because there are twice as many rows of _Y{prime}_ data as there are _C~B~_ and _C~R~_ data, it is convenient to record the channels as -separate planes as shown in <<2DYCbCr420_traditional>> (with 2{times}2 +separate planes as shown in <> (with 2{times}2 texel blocks outlined in red); in addition, image compression schemes often work with the channels independently, which is amenable to planar storage. -[[2DYCbCr420_traditional]] -.2-D _Y′C~B~C~R~_ 4:2:0 planes, downsampled _C~B~_ and _C~R~_ at midpoint between _Y′_ values -image::images/2DYCbCr420_traditional.{svgpdf}[width="{svgpdf@pdf:310pt:480}",align="center"] +[[im-2DYCbCr420_traditional]] +.2-D _Y{prime}C~B~C~R~_ 4:2:0 planes, downsampled _C~B~_ and _C~R~_ at midpoint between _Y{prime}_ values +image::{images}/2DYCbCr420_traditional.svg[width="{svgpdf@pdf:310pt:480}",align="center"] In this case, the _C~B~_ and _C~R~_ planes are half the width and half -the height of the _Y′_ plane, and also have half the line stride. +the height of the _Y{prime}_ plane, and also have half the line stride. Therefore if we store one byte per channel, the offsets for each plane in a linear representation can be calculated as: [latexmath] -++++++ +++++ \begin{align*} \textit{Y}'_\textit{address} &= \textit{Y}'_\textit{base} + x + (y \times \textit{row stride}_\textit{bytes}) \\ \textit{C}_\textit{B address} &= \textit{C}_\textit{B base} + \left\lfloor{x\over 2}\right\rfloor + \left(\left\lfloor{y\over 2}\right\rfloor\times {{\textit{row stride}_\textit{bytes}}\over 2}\right) \\ \textit{C}_\textit{R address} &= \textit{C}_\textit{R base} + \left\lfloor{x\over 2}\right\rfloor + \left(\left\lfloor{y\over 2}\right\rfloor\times {{\textit{row stride}_\textit{bytes}}\over 2}\right) \end{align*} -++++++ +++++ <<< A description based on downsampling factors is sufficient in the case of -common _Y′C~B~C~R~_ layouts, but does not extend conveniently to all +common _Y{prime}C~B~C~R~_ layouts, but does not extend conveniently to all representations. For example, one common representation used in camera sensors is a _Bayer pattern_, in which there is only one of the red, green and blue channels @@ -700,27 +692,27 @@ block, and two green values offset diagonally, as in <>. [[BayerOffsets]] .An 18{times}12 _^RG^_/_~GB~_ Bayer filter pattern (repeating pattern outlined in yellow) -image::images/Bayer18x12.{svgpdf}[width="{svgpdf@pdf:400pt:640}",align="center"] +image::{images}/Bayer18x12.svg[width="{svgpdf@pdf:400pt:640}",align="center"] A Bayer pattern can then be used to sample an image, as shown in <>, and this sampled version can later be used to reconstruct the original image by relying on heuristic correlations between the channels. Technology for image processing continues to develop, so in many cases -it is valuable to record the ``raw'' sensor data for later processing, and +it is valuable to record the "`raw`" sensor data for later processing, and to pass the raw data unmodified to a range of algorithms; the choice of algorithm for reconstructing an image from samples is beyond the remit of this specification. [[SimpleBayerBlock]] .A Bayer-sampled image with a repeating 2{times}2 _^RG^_/_~GB~_ texel block (outlined in yellow) -image::images/Bayer.{svgpdf}[width="{svgpdf@pdf:95pt:170}",align="center"] +image::{images}/Bayer.svg[width="{svgpdf@pdf:95pt:170}",align="center"] In the Bayer representation, the red and blue channels can be considered to be downsampled by a factor of two in each dimension. The two green channels per 2{times}2 repeating block mean that the -``downsampling factor'' for the green channel is effectively -latexmath:[$\sqrt{2}$] in each direction. +"`downsampling factor`" for the green channel is effectively +latexmath:[\sqrt{2}] in each direction. <<< More complex layouts are not uncommon. @@ -728,12 +720,12 @@ For example, the X-Trans sample arrangement developed by Fujifilm for their digital camera range, shown in <>, consists of 6{times}6 texel blocks, with each sample, as in Bayer, corresponding to a single channel. In X-Trans, each block contains eight red, eight blue and twenty green -samples; red and blue are ``downsampled'' by latexmath:[$\sqrt{3\over 2}$] -and green is ``downsampled'' by latexmath:[$3\over\sqrt{5}$]. +samples; red and blue are "`downsampled`" by latexmath:[\sqrt{3\over 2}] +and green is "`downsampled`" by latexmath:[3\over\sqrt{5}]. [[XTrans]] .An 18{times}12 X-Trans image (repeating 6{times}6 pattern outlined in yellow) -image::images/X-Trans18x12.{svgpdf}[width="{svgpdf@pdf:400pt:640}",align="center"] +image::{images}/X-Trans18x12.svg[width="{svgpdf@pdf:400pt:640}",align="center"] Allowing for possible alternative orientations of the samples (such as whether the Bayer pattern starts with a row containing red or blue @@ -763,15 +755,15 @@ descriptor blocks. [[DescriptorAndDescriptorBlocks]] .Data format descriptor and descriptor blocks [width="75%",cols="1a"] -|============= +|==== ^|_Data format descriptor_ [width="100%",cols="1"] !============= -! _ Descriptor block 1_ -! _ Descriptor block 2_ -!  : +! _{nbsp}Descriptor block 1_ +! _{nbsp}Descriptor block 2_ +! {nbsp}: !============= -|============= +|==== The diversity of possible data makes a concise description that can support every possible format impractical. @@ -827,11 +819,11 @@ which contain 4{times}4 samples. In general, this is not a useful approach: it is very verbose to list each sample individually, it does not extend well to larger block sizes (or to infinite ranges in approaches such as Morton order), -it does not handle special cases well (such as the ``tail'' of a +it does not handle special cases well (such as the "`tail`" of a mip chain), and encodings such as Hilbert order do not have a repeating mapping. In most contexts where these concepts exist, tiling is not considered -to be part of a ``format''. +to be part of a "`format`". <<< [[plane]] @@ -846,43 +838,43 @@ For the purposes of this specification, a _plane_ is defined to be texel block*. This interpretation contradicts the traditional interpretation of -downsampled channels: if two rows of _Y′_ data correspond to a +downsampled channels: if two rows of _Y{prime}_ data correspond to a single row of _C~B~_ and _C~R~_ (in a linear, non-tiled memory layout), -the _Y′_ channel contribution to the texel block is _not_ -``a contiguous region of bytes''. -Instead, each row of _Y′_ contributing to a texel block can be -treated as a separate ``plane''. +the _Y{prime}_ channel contribution to the texel block is _not_ +"`a contiguous region of bytes`". +Instead, each row of _Y{prime}_ contributing to a texel block can be +treated as a separate "`plane`". In linear layout, this can be represented by offsetting rows of -_Y′_ data with odd _y_ coordinates by the row stride of the -original _Y′_ plane; each new _Y′_ plane's stride is then -double that of the original _Y′_ plane, as in <<2DYCbCr420_KDFS>> -(c.f. <<2DYCbCr420_traditional>>). -If the planes of a 6{times}4 _Y′C~B~C~R~_ 4:2:0 texture are stored +_Y{prime}_ data with odd _y_ coordinates by the row stride of the +original _Y{prime}_ plane; each new _Y{prime}_ plane's stride is then +double that of the original _Y{prime}_ plane, as in <> +(c.f. <>). +If the planes of a 6{times}4 _Y{prime}C~B~C~R~_ 4:2:0 texture are stored consecutively in memory with no padding, which might be described in a traditional API as <>, the representation used by this specification would be that shown in <>. [[yuv420conventional]] -.Plane descriptors of a 6{times}4 _Y′C~B~C~R~_-format buffer in a conventional API +.Plane descriptors of a 6{times}4 _Y{prime}C~B~C~R~_-format buffer in a conventional API [cols="2,2,3,3",width="70%",options="header"] -|============================== +|==== ^| Plane ^| Byte offset ^| Byte stride ^| Downsample factor -^| _Y′_ ^| 0 ^| 6 ^| 1{times}1 +^| _Y{prime}_ ^| 0 ^| 6 ^| 1{times}1 ^| _C~B~_ ^| 24 ^| 3 ^| 2{times}2 ^| _C~R~_ ^| 30 ^| 3 ^| 2{times}2 -|============================== +|==== [[yuv420thisapi]] -.Plane descriptors of a 6{times}4 _Y′C~B~C~R~_-format buffer using this standard +.Plane descriptors of a 6{times}4 _Y{prime}C~B~C~R~_-format buffer using this standard [cols="4",width="60%",options="header"] -|============================== +|==== ^| Plane ^| Byte offset ^| Byte stride ^| Bytes per plane -^|_Y′_ plane 1 ^| 0 ^| 12 ^| 2 -^|_Y′_ plane 2 ^| 6 ^| 12 ^| 2 +^|_Y{prime}_ plane 1 ^| 0 ^| 12 ^| 2 +^|_Y{prime}_ plane 2 ^| 6 ^| 12 ^| 2 ^|_C~B~_ ^| 24 ^| 3 ^| 1 ^|_C~R~_ ^| 30 ^| 3 ^| 1 -|============================== +|==== NOTE: There is no expectation that an API must actually use this representation in accessing the data: it is simple for an API with @@ -900,11 +892,11 @@ Eight planes are enough to encode, for example: * 8-bit data stored as individual bit planes * Stereo planar _R_, _G_, _B_, _A_ data -* 4{times} vertically-downsampled _Y′C~B~C~R~_ data, as might +* 4{times} vertically-downsampled _Y{prime}C~B~C~R~_ data, as might be produced by rotating a (relatively common) 4{times} -horizontally-downsampled _Y′C~B~C~R~_ (4:1:1) video frame +horizontally-downsampled _Y{prime}C~B~C~R~_ (4:1:1) video frame * A 2{times}2{times}2{times}2 4-D texel block in a linear layout -* Interlaced _Y′C~B~C~R~_ 4:2:0 data with each field stored +* Interlaced _Y{prime}C~B~C~R~_ 4:2:0 data with each field stored separately If a plane contributes less than a byte to a texel (or a non-integer @@ -913,8 +905,8 @@ more texels until a whole number of bytes are covered -- q.v. <>. <<< -NOTE: Interlaced _Y′C~B~C~R~_ data may associate chroma channels -with _Y′_ samples only from the same field, not the frame as a +NOTE: Interlaced _Y{prime}C~B~C~R~_ data may associate chroma channels +with _Y{prime}_ samples only from the same field, not the frame as a whole. This distinction is not made explicit, in part because a number of interlacing schemes exist. @@ -924,11 +916,11 @@ as *_samplePosition3_* = 0, the second field as *_samplePosition3_* = 1, etc.) This interpretation is not mandated to allow other reasons for encoding four-dimensional texels, although it is consistent with -the fourth dimension representing ``time''. +the fourth dimension representing "`time`". -[[2DYCbCr420_KDFS]] -.2-D _Y′C~B~C~R~_ 4:2:0 planes, with separate even and odd _Y′_ planes -image::images/2DYCbCr420_KDFS.{svgpdf}[width="{svgpdf@pdf:310pt:480}",align="center"] +[[im-2DYCbCr420_KDFS]] +.2-D _Y{prime}C~B~C~R~_ 4:2:0 planes, with separate even and odd _Y{prime}_ planes +image::{images}/2DYCbCr420_KDFS.svg[width="{svgpdf@pdf:310pt:480}",align="center"] <<< === Bit pattern interpretation and _samples_ @@ -936,7 +928,7 @@ image::images/2DYCbCr420_KDFS.{svgpdf}[width="{svgpdf@pdf:310pt:480}",align="cen For the purposes of description, the bytes contributed by each plane are considered to be concatenated into a single contiguous _logical bit stream_. -This ``concatenation'' of bits is purely conceptual for the purposes of +This "`concatenation`" of bits is purely conceptual for the purposes of determining the interpretation of the bits that contribute to the texel block, and is not expected to be the way that actual decoders would process the data. @@ -955,9 +947,9 @@ channel and four-dimensional coordinate offset within the texel block; in formats for which only a single texel is being described, this coordinate offset will always be 0,0,0,0. -The descriptor block for a _Y′C~B~C~R~_ 4:2:0 layout is shown in +The descriptor block for a _Y{prime}C~B~C~R~_ 4:2:0 layout is shown in <>. -<<2DYCbCr420Encoding>> shows this representation graphically: +<> shows this representation graphically: the three disjoint regions for each channels and the texel block covering them are shown on the left, represented in this specification as four planes of contiguous bytes. @@ -966,9 +958,9 @@ in top-to-bottom order); these _samples_ then describe the contributions from these logical bits, with geometric location of the sample at the right. -[[2DYCbCr420Encoding]] -._Y′C~B~C~R~_ 4:2:0 described in six samples -image::images/2DYCbCrKDFSEncoding.{svgpdf}[width="{svgpdf@pdf:475pt:800}",align="center"] +[[im-2DYCbCr420Encoding]] +._Y{prime}C~B~C~R~_ 4:2:0 described in six samples +image::{images}/2DYCbCrKDFSEncoding.svg[width="{svgpdf@pdf:475pt:800}",align="center"] <<< Consecutive samples with the same channel, location and flags may describe @@ -998,7 +990,7 @@ The descriptor block for this format is shown in [[RGB565BEEncoding]] ._RGB_ 565 big-endian encoding -image::images/RGB565BEKDFSEncoding.{svgpdf}[width="{svgpdf@pdf:490pt:850}",align="center"] +image::{images}/RGB565BEKDFSEncoding.svg[width="{svgpdf@pdf:490pt:850}",align="center"] In <>, bit 0 of the logical bit stream corresponds to bit 3 of the virtual sample that describes the green channel; therefore @@ -1021,35 +1013,35 @@ The precision to which sample coordinates are specified depends on the size of the texel block: coordinates in a 256{times}256 texel block can be specified only to integer-coordinate granularity, but offsets within a texel block that is only a single coordinate wide -are specified to the precision of latexmath:[$1\over 256$] of a +are specified to the precision of latexmath:[1\over 256] of a coordinate; this approach allows large texel blocks, half-texel offsets -for representations such as _Y′C~B~C~R~_ 4:2:0, and precise +for representations such as _Y{prime}C~B~C~R~_ 4:2:0, and precise fractional offsets for recording multisampled pattern locations. The sequence of bits in the (virtual) sample defines a numerical range which may be interpreted as a fixed-point or floating-point value and signed or unsigned. Many common representations specify this range. -For example, 8-bit _RGB_ data may be interpreted in ``unsigned -normalized'' form as meaning ``0.0'' (zero color contribution) when -the channel bits are 0 and ``1.0'' (maximum color contribution) when +For example, 8-bit _RGB_ data may be interpreted in "`unsigned +normalized`" form as meaning "`0.0`" (zero color contribution) when +the channel bits are 0 and "`1.0`" (maximum color contribution) when the channel is 255. -In _Y′C~B~C~R~_ ``narrow-range'' encoding, there is head-room -and foot-room to the encoding: ``black'' is encoded in the _Y′_ -channel as the value 16, and ``white'' is encoded as 235, as shown +In _Y{prime}C~B~C~R~_ "`narrow-range`" encoding, there is head-room +and foot-room to the encoding: "`black`" is encoded in the _Y{prime}_ +channel as the value 16, and "`white`" is encoded as 235, as shown in <>. To allow the bit pattern of simply-encoded numerical encodings to be mapped to the desired values, each sample has an _upper_ and _lower_ value associated with it, usually representing 1.0 and either 0.0 or -1.0 depending on whether the sample is signed. -Note that it is typically part of the ``format'' to indicate the +Note that it is typically part of the "`format`" to indicate the numbers which are being encoded; how the application chooses to -process these numbers is not part of the ``format''. -For example, some APIs may have two separate ``formats'', in which +process these numbers is not part of the "`format`". +For example, some APIs may have two separate "`formats`", in which the 8-bit pattern 0x01 may be interpreted as either the float value 1.0 or the integer value 1; for the purposes of this -specification, these formats are identical -- ``1'' means ``1''. +specification, these formats are identical -- "`1`" means "`1`". A sample has an associated color channel in the color model of the descriptor block -- for example, if the descriptor block indicates an @@ -1072,11 +1064,11 @@ with which they are associated, then in increasing raster order of coordinates, then in increasing bit order (in a little-endian interpretation). For example: - - In the _Y′C~B~C~R~_ 4:2:0 format described above, the - _Y′_ planes should come before the _C~B~_ and _C~R~_ + - In the _Y{prime}C~B~C~R~_ 4:2:0 format described above, the + _Y{prime}_ planes should come before the _C~B~_ and _C~R~_ planes in that order, because of the channel order. - - The _Y′_ plane corresponding to even _y_ addresses - should come before the _Y′_ plane corresponding to + - The _Y{prime}_ plane corresponding to even _y_ addresses + should come before the _Y{prime}_ plane corresponding to odd _y_ coordinates, because row 0 is even. - Planes should be ordered such that sample values that are split across multiple planes should be ordered in increasing order -- @@ -1157,10 +1149,10 @@ Finally: transfer function is needed. <<< -=== Related concepts outside the ``format'' +=== Related concepts outside the "`format`" The data format descriptor describes only concepts which are -conventionally part of the ``format''. +conventionally part of the "`format`". Additional information is required to access the image data: * A formula for mapping accessed coordinates to byte data for @@ -1172,11 +1164,12 @@ Additional information is required to access the image data: of bytes contributed by each plane. * (Optionally) for each dimension, a maximum (and arguably minimum) range. - * Note that padding is independent of the ``format''. + * Note that padding is independent of the "`format`". For example, if texels are laid out in memory in linear order: ------ +[source] +---- int numPlanes; char *planeBaseAddresses[8]; unsigned int strides[8][4]; @@ -1205,7 +1198,7 @@ decodeTexelGivenCoords(uint32_t *descriptor, float coords[4]) { // decodes the concatenated data according to the descriptor processTexel(descriptor, addresses, coords); } ------ +---- The ++processTexel++ function would typically operate on the coordinates having taken the remainder of dividing them by the texel block size. @@ -1261,13 +1254,13 @@ trivially defines a little-endian native data type size. Big-endian data types can be identified by observing that in a big-endian format, a sequence of bits in the top bits of byte _n_ may continue in the low bits of byte _n_ - 1. -Finally, ``packed'' formats consist of consecutive bit sequences per +Finally, "`packed`" formats consist of consecutive bit sequences per channel in either little- or big-endian order; little-endian sequences are a single stand-alone sample, and a big-endian sequence consists of a number of samples adjacent to byte boundaries in decreasing byte order (see <>); the packed field size can typically be deduced from the *_bytesPlane0_* value. -There is no way to distinguish a logically ``packed'', byte-aligned +There is no way to distinguish a logically "`packed`", byte-aligned samples from distinct but consecutively-stored channels that have the same in-memory representation. @@ -1342,10 +1335,11 @@ the same coordinate. A texel block from a Bayer sensor might have a different location for different channels, and may have multiple samples representing the same channel at multiple locations. -A _Y′C~B~C~R~_ buffer with downsampled chroma may have more luma +A _Y{prime}C~B~C~R~_ buffer with downsampled chroma may have more luma samples than chroma, each at different locations. -== [[dataformatdescriptor]]Khronos Data Format Descriptor == +[[dataformatdescriptor]] +== Khronos Data Format Descriptor The data format descriptor consists of a contiguous area of memory, as shown in <>, divided into one or more @@ -1356,11 +1350,11 @@ The size of the data format descriptor varies according to its content. [[DataFormatDescriptorOverview]] .Data Format Descriptor layout [width="60%",cols="1,2"] -|===================================== ->| *++uint32_t++*   ^|   *_totalSize_* ->| _Descriptor block_   ^|   _First descriptor_ ->| _Descriptor block_   ^|   _Second descriptor (optional) etc._ -|===================================== +|==== +>| *++uint32_t++* {nbsp} ^| {nbsp} *_totalSize_* +>| _Descriptor block_ {nbsp} ^| {nbsp} _First descriptor_ +>| _Descriptor block_ {nbsp} ^| {nbsp} _Second descriptor (optional) etc._ +|==== The *_totalSize_* field, measured in bytes, allows the full format descriptor to be copied without need for details of the descriptor to be interpreted. @@ -1398,26 +1392,27 @@ of most descriptors can be deduced by which half of the *++uint32_t++* *_totalSize_* field is non-zero. NOTE: To avoid expanding the size of the data structure, there is no -``magic identifier'' for a data format descriptor: applications are +"`magic identifier`" for a data format descriptor: applications are expected to know the type of the data structure being accessed, and to provide their own means of identifying a data format descriptor if one is embedded in a multi-purpose byte stream. <<< -=== [[descriptorblock]]Descriptor block +[[descriptorblock]] +=== Descriptor block Each _descriptor block_ has the same prefix, shown in <>. [[DescriptorPrefix]] .Descriptor Block layout [cols="1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1",width="97%"] -|==================== +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 15+^| *_descriptorType_* 17+^| *_vendorId_* 16+^| *_descriptorBlockSize_* 16+^| *_versionNumber_* 32+^| _Format-specific data_ -|==================== +|==== The *_vendorId_* is a 17-bit value uniquely assigned to organizations. If the organization has a 16-bit identifier assigned by the PCI SIG, @@ -1481,7 +1476,7 @@ format descriptor. [[DataFormatDescriptorHeaderExample]] .Data format descriptor header and descriptor block headers for two descriptor blocks [cols="1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1",width="97%"] -|==================== +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize_* @@ -1493,9 +1488,10 @@ format descriptor. 15+^| *_descriptorType_* 17+^| *_vendorId_* 16+^| *_descriptorBlockSize_* 16+^| *_versionNumber_* 32+^| _Descriptor body_ -|==================== +|==== -== [[basicdescriptor]]Khronos Basic Data Format Descriptor Block == +[[basicdescriptor]] +== Khronos Basic Data Format Descriptor Block A _basic descriptor block_ (<>) is designed to encode common metadata associated with bulk data -- especially image or @@ -1512,13 +1508,13 @@ interpretation of the texel block as a whole, supplemented by a description of a number of samples taken from one or more _planes_ of contiguous memory. For example, a 24-bit red/green/blue format may be described as a 1×1 pixel region, in one plane of three samples, one describing each channel. -A _Y′C~B~C~R~_ 4:2:0 format may consist of a repeating 2×2 region: -four _Y′_ samples and one sample each of _C~B~_ and _C~R~_. +A _Y{prime}C~B~C~R~_ 4:2:0 format may consist of a repeating 2×2 region: +four _Y{prime}_ samples and one sample each of _C~B~_ and _C~R~_. [[BasicDescriptorBlock]] .Basic Data Format Descriptor layout [cols="1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1",width="97%"] -|==================== +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 15+^| *_descriptorType_* = 0 17+^| *_vendorId_* = 0 @@ -1529,7 +1525,7 @@ four _Y′_ samples and one sample each of _C~B~_ and _C~R~_. 8+^| *_bytesPlane7_* 8+^| *_bytesPlane6_* 8+^| *_bytesPlane5_* 8+^| *_bytesPlane4_* 32+^| _Sample information for the first sample_ 32+^| _Sample information for the second sample (optional), etc._ -|==================== +|==== The Basic Data Format Descriptor Block should be the first descriptor block in any data format descriptor of which it is a component. @@ -1544,12 +1540,12 @@ block fields: .Field location information for field *_xxx_* [cols="7,10,2"] -|================== +|==== ^| Word offset into basic descriptor block ^| *++KHR_DF_WORD_xxx++* ^| ... ^| Word offset into descriptor ^| *++KHR_DF_WORD_xxx++* {plus} 1 ^| ... ^| Start bit within word ^| *++KHR_DF_SHIFT_xxx++* ^| ... ^| Bit mask of value ^| *++KHR_DF_MASK_xxx++* ^| ... -|================== +|==== If the basic descriptor block is treated as a *++uint32_t++* array ++bdb[]++, field *_xxx_* can be accessed as follows: @@ -1563,24 +1559,24 @@ For example, *++KHR_DFDVAL++*(++bdb++, *++MODEL++*) returns the value: *++KHR_DF_MASK_MODEL++* & (++bdb++[*++KHR_DF_WORD_MODEL++*] >> *++KHR_DF_SHIFT_MODEL++*) <<< -=== *_vendorId_* === +=== *_vendorId_* The *_vendorId_* for the Basic Data Format Descriptor Block is 0, defined as *++KHR_DF_VENDORID_KHRONOS++* in the enum *++khr_df_vendorid_e++*. .Field location information for *_vendorId_* [cols="7,10,3"] -|================== +|==== ^| Word offset into basic descriptor block ^| *++KHR_DF_WORD_VENDORID++* ^| 0 ^| Word offset into descriptor ^| *++KHR_DF_WORD_VENDORID++* {plus} 1 ^| 1 ^| Start bit within word ^| *++KHR_DF_SHIFT_VENDORID++* ^| 0 ^| Bit mask of value ^| *++KHR_DF_MASK_VENDORID++* ^| 0x1FFFFU -|================== +|==== *++khr_df_vendorid_e++* *_vendorId_* = *++KHR_DF_MASK_VENDORID++* & + (++bdb++[*++KHR_DF_WORD_VENDORID++*] >> *++KHR_DF_SHIFT_VENDORID++*); -=== *_descriptorType_* === +=== *_descriptorType_* The *_descriptorType_* for the Basic Data Format Descriptor Block is 0, a value reserved in the enum of Khronos-specific descriptor types, @@ -1588,18 +1584,18 @@ a value reserved in the enum of Khronos-specific descriptor types, .Field location information for *_descriptorType_* [cols="7,10,3"] -|================== +|==== ^| Word offset into basic descriptor block ^| *++KHR_DF_WORD_DESCRIPTORTYPE++* ^| 0 ^| Word offset into descriptor ^| *++KHR_DF_WORD_DESCRIPTORTYPE++* {plus} 1 ^| 1 ^| Start bit within word ^| *++KHR_DF_SHIFT_DESCRIPTORTYPE++* ^| 17 ^| Bit mask of value ^| *++KHR_DF_MASK_DESCRIPTORTYPE++* ^| 0x7FFFU -|================== +|==== *++khr_df_descriptortype_e++* *_descriptorType_* = *++KHR_DF_MASK_DESCRIPTORTYPE++* & + (++bdb++[*++KHR_DF_WORD_DESCRIPTORTYPE++*] >> *++KHR_DF_SHIFT_DESCRIPTORTYPE++*); <<< -=== *_versionNumber_* === +=== *_versionNumber_* The *_versionNumber_* relating to the Basic Data Format Descriptor Block as described in this specification is 2. @@ -1607,23 +1603,23 @@ as described in this specification is 2. NOTE: The *_versionNumber_* is incremented to indicate an incompatible change in the descriptor. The addition of enumerant values, for example to represent more compressed -texel formats, does not constitute an ``incompatible change'', and +texel formats, does not constitute an "`incompatible change`", and implementations should be resilient against enumerants that have been added in later minor updates. .Field location information for *_versionNumber_* [cols="7,10,3"] -|================== +|==== ^| Word offset into basic descriptor block ^| *++KHR_DF_WORD_VERSIONNUMBER++* ^| 1 ^| Word offset into descriptor ^| *++KHR_DF_WORD_VERSIONNUMBER++* {plus} 1 ^| 2 ^| Start bit within word ^| *++KHR_DF_SHIFT_VERSIONNUMBER++* ^| 0 ^| Bit mask of value ^| *++KHR_DF_MASK_VERSIONNUMBER++* ^| 0xFFFFU -|================== +|==== *++uint32_t++* *_versionNumber_* = *++KHR_DF_MASK_VERSIONNUMBER++* & + (++bdb++[*++KHR_DF_WORD_VERSIONNUMBER++*] >> *++KHR_DF_SHIFT_VERSIONNUMBER++*); -=== *_descriptorBlockSize_* === +=== *_descriptorBlockSize_* The memory size of the Basic Data Format Descriptor Block depends on the number of samples contained within it. The memory requirements for this format @@ -1632,19 +1628,19 @@ is measured in bytes. .Field location information for *_descriptorBlockSize_* [cols="7,10,3"] -|================== +|==== ^| Word offset into basic descriptor block ^| *++KHR_DF_WORD_DESCRIPTORBLOCKSIZE++* ^| 1 ^| Word offset into descriptor ^| *++KHR_DF_WORD_DESCRIPTORBLOCKSIZE++* {plus} 1 ^| 2 ^| Start bit within word ^| *++KHR_DF_SHIFT_DESCRIPTORBLOCKSIZE++* ^| 16 ^| Bit mask of value ^| *++KHR_DF_MASK_DESCRIPTORBLOCKSIZE++* ^| 0xFFFFU -|================== +|==== *++uint32_t++* *_descriptorBlockSize_* = *++KHR_DF_MASK_DESCRIPTORBLOCKSIZE++* & + (++bdb++[*++KHR_DF_WORD_DESCRIPTORBLOCKSIZE++*] >> *++KHR_DF_SHIFT_DESCRIPTORBLOCKSIZE++*); <<< [[COLORMODEL]] -=== *_colorModel_* === +=== *_colorModel_* The *_colorModel_* determines the set of color (or other data) channels which may be encoded within the data, though there is no requirement that all @@ -1659,12 +1655,12 @@ and are represented as an unsigned 8-bit value. .Field location information for *_colorModel_* [cols="7,10,2"] -|================== +|==== ^| Word offset into basic descriptor block ^| *++KHR_DF_WORD_MODEL++* ^| 2 ^| Word offset into descriptor ^| *++KHR_DF_WORD_MODEL++* {plus} 1 ^| 3 ^| Start bit within word ^| *++KHR_DF_SHIFT_MODEL++* ^| 0 ^| Bit mask of value ^| *++KHR_DF_MASK_MODEL++* ^| 0xFF -|================== +|==== *++khr_df_model_e++* *_colorModel_* = *++KHR_DF_MASK_MODEL++* & + (++bdb++[*++KHR_DF_WORD_MODEL++*] >> *++KHR_DF_SHIFT_MODEL++*); @@ -1683,7 +1679,7 @@ obligated to represent alpha in any way in channel number 15. The value of each enumerant is shown in parentheses following the enumerant name. -==== *++KHR_DF_MODEL_UNSPECIFIED++* (= 0) ==== +==== *++KHR_DF_MODEL_UNSPECIFIED++* (= 0) When the data format is unknown or does not fall into a predefined category, utilities which perform automatic conversion based on an @@ -1701,14 +1697,14 @@ be able to perform operations that depend only on channel location, not channel interpretation (such as image cropping). For example, a camera may store a raw format taken with a modified Bayer sensor, with _RGBW_ (red, green, blue and white) sensor sites, or _RGBE_ -(red, green, blue and ``emerald''). Rather than trying to encode the +(red, green, blue and "`emerald`"). Rather than trying to encode the exact color coordinates of each sample in the basic descriptor, these formats could be represented by a four-channel *++UNSPECIFIED++* model, with an extension block describing the interpretation of each channel. <<< -==== *++KHR_DF_MODEL_RGBSDA++* (= 1) ==== +==== *++KHR_DF_MODEL_RGBSDA++* (= 1) This color model represents additive colors of three channels, nominally red, green and blue, supplemented by channels for @@ -1721,31 +1717,31 @@ data makes sense. [[RGBSDAChannels]] .Basic Data Format _RGBSDA_ channels [width="100%",options="header"] -|================================ -^| Channel number 2+|   Name |   Description -^| 0 2+|   *++KHR_DF_CHANNEL_RGBSDA_RED++* |   Red -^| 1 2+|   *++KHR_DF_CHANNEL_RGBSDA_GREEN++* |   Green -^| 2 2+|   *++KHR_DF_CHANNEL_RGBSDA_BLUE++* |   Blue -^| 13 2+|   *++KHR_DF_CHANNEL_RGBSDA_STENCIL++* |   Stencil -^| 14 2+|   *++KHR_DF_CHANNEL_RGBSDA_DEPTH++* |   Depth -^| 15 2+|   *++KHR_DF_CHANNEL_RGBSDA_ALPHA++* |   Alpha (opacity) -|================================ +|==== +^| Channel number 2+| {nbsp} Name | {nbsp} Description +^| 0 2+| {nbsp} *++KHR_DF_CHANNEL_RGBSDA_RED++* | {nbsp} Red +^| 1 2+| {nbsp} *++KHR_DF_CHANNEL_RGBSDA_GREEN++* | {nbsp} Green +^| 2 2+| {nbsp} *++KHR_DF_CHANNEL_RGBSDA_BLUE++* | {nbsp} Blue +^| 13 2+| {nbsp} *++KHR_DF_CHANNEL_RGBSDA_STENCIL++* | {nbsp} Stencil +^| 14 2+| {nbsp} *++KHR_DF_CHANNEL_RGBSDA_DEPTH++* | {nbsp} Depth +^| 15 2+| {nbsp} *++KHR_DF_CHANNEL_RGBSDA_ALPHA++* | {nbsp} Alpha (opacity) +|==== Portable representation of additive colors with more than three primaries requires an extension to describe the full color space of the channels present. There is no practical way to do this portably without taking significantly more space. -==== *++KHR_DF_MODEL_YUVSDA++* (= 2) ==== +==== *++KHR_DF_MODEL_YUVSDA++* (= 2) This color model represents color differences with three channels, -nominally luma (_Y′_) and two color-difference chroma channels, +nominally luma (_Y{prime}_) and two color-difference chroma channels, _U_ (_C~B~_) and _V_ (_C~R~_), supplemented by channels for alpha, depth and stencil, as shown in <>. These formats are distinguished by _C~B~_ and _C~R~_ being a delta between -the _Y′_ channel and the blue and red channels respectively, rather +the _Y{prime}_ channel and the blue and red channels respectively, rather than requiring a full color matrix. -The conversion between _Y′C~B~C~R~_ and _RGB_ color spaces is defined +The conversion between _Y{prime}C~B~C~R~_ and _RGB_ color spaces is defined in this case by the choice of value in the *_colorPrimaries_* field as described in <>. @@ -1756,17 +1752,17 @@ a reason to do otherwise. [[YUVSDAChannels]] .Basic Data Format _YUVSDA_ channels [width="100%",options="header"] -|================================ -^| Channel number 2+|   Name |   Description -^| 0 2+|   *++KHR_DF_CHANNEL_YUVSDA_Y++* |   _Y_/_Y′_ (luma/luminance) -^| 1 2+|   *++KHR_DF_CHANNEL_YUVSDA_CB++* |   _C~B~_ (alias for _U_) -^| 1 2+|   *++KHR_DF_CHANNEL_YUVSDA_U++* |   _U_ (alias for _C~B~_) -^| 2 2+|   *++KHR_DF_CHANNEL_YUVSDA_CR++* |   _C~R~_ (alias for _V_) -^| 2 2+|   *++KHR_DF_CHANNEL_YUVSDA_V++* |   _V_ (alias for _C~R~_) -^| 13 2+|   *++KHR_DF_CHANNEL_YUVSDA_STENCIL++* |   Stencil -^| 14 2+|   *++KHR_DF_CHANNEL_YUVSDA_DEPTH++* |   Depth -^| 15 2+|   *++KHR_DF_CHANNEL_YUVSDA_ALPHA++* |   Alpha (opacity) -|================================ +|==== +^| Channel number 2+| {nbsp} Name | {nbsp} Description +^| 0 2+| {nbsp} *++KHR_DF_CHANNEL_YUVSDA_Y++* | {nbsp} _Y_/_Y{prime}_ (luma/luminance) +^| 1 2+| {nbsp} *++KHR_DF_CHANNEL_YUVSDA_CB++* | {nbsp} _C~B~_ (alias for _U_) +^| 1 2+| {nbsp} *++KHR_DF_CHANNEL_YUVSDA_U++* | {nbsp} _U_ (alias for _C~B~_) +^| 2 2+| {nbsp} *++KHR_DF_CHANNEL_YUVSDA_CR++* | {nbsp} _C~R~_ (alias for _V_) +^| 2 2+| {nbsp} *++KHR_DF_CHANNEL_YUVSDA_V++* | {nbsp} _V_ (alias for _C~R~_) +^| 13 2+| {nbsp} *++KHR_DF_CHANNEL_YUVSDA_STENCIL++* | {nbsp} Stencil +^| 14 2+| {nbsp} *++KHR_DF_CHANNEL_YUVSDA_DEPTH++* | {nbsp} Depth +^| 15 2+| {nbsp} *++KHR_DF_CHANNEL_YUVSDA_ALPHA++* | {nbsp} Alpha (opacity) +|==== NOTE: Terminology for this color model is often abused. This model is based on the idea of creating a representation of monochrome light intensity as a @@ -1774,11 +1770,11 @@ weighted average of color channels, then calculating color differences by subtracting two of the color channels from this monochrome value. Proper names vary for each variant of the ensuing numbers, but _YUV_ is colloquially used for all of them. In the television standards from which this terminology is -derived, _Y′C~B~C~R~_ is more formally used to describe the representation +derived, _Y{prime}C~B~C~R~_ is more formally used to describe the representation of these color differences. See <> for more detail. <<< -==== *++KHR_DF_MODEL_YIQSDA++* (= 3) ==== +==== *++KHR_DF_MODEL_YIQSDA++* (= 3) This color model represents color differences with three channels, nominally luma (_Y_) and two color-difference chroma channels, _I_ and _Q_, @@ -1790,17 +1786,17 @@ _I_ and _Q_ are derived from _C~B~_ and _C~R~_ by a 33-degree rotation. [[YIQSDAChannels]] .Basic Data Format _YIQSDA_ channels [width="100%",options="header"] -|================================ -^| Channel number 2+|   Name |   Description -^| 0 2+|   *++KHR_DF_CHANNEL_YIQSDA_Y++* |   _Y_ (luma) -^| 1 2+|   *++KHR_DF_CHANNEL_YIQSDA_I++* |   _I_ (in-phase) -^| 2 2+|   *++KHR_DF_CHANNEL_YIQSDA_Q++* |   _Q_ (quadrature) -^| 13 2+|   *++KHR_DF_CHANNEL_YIQSDA_STENCIL++* |   Stencil -^| 14 2+|   *++KHR_DF_CHANNEL_YIQSDA_DEPTH++* |   Depth -^| 15 2+|   *++KHR_DF_CHANNEL_YIQSDA_ALPHA++* |   Alpha (opacity) -|================================ - -==== *++KHR_DF_MODEL_LABSDA++* (= 4) ==== +|==== +^| Channel number 2+| {nbsp} Name | {nbsp} Description +^| 0 2+| {nbsp} *++KHR_DF_CHANNEL_YIQSDA_Y++* | {nbsp} _Y_ (luma) +^| 1 2+| {nbsp} *++KHR_DF_CHANNEL_YIQSDA_I++* | {nbsp} _I_ (in-phase) +^| 2 2+| {nbsp} *++KHR_DF_CHANNEL_YIQSDA_Q++* | {nbsp} _Q_ (quadrature) +^| 13 2+| {nbsp} *++KHR_DF_CHANNEL_YIQSDA_STENCIL++* | {nbsp} Stencil +^| 14 2+| {nbsp} *++KHR_DF_CHANNEL_YIQSDA_DEPTH++* | {nbsp} Depth +^| 15 2+| {nbsp} *++KHR_DF_CHANNEL_YIQSDA_ALPHA++* | {nbsp} Alpha (opacity) +|==== + +==== *++KHR_DF_MODEL_LABSDA++* (= 4) This color model represents the ICC perceptually-uniform _L*a*b*_ color space, combined with the option of an alpha channel, as @@ -1809,17 +1805,17 @@ shown in <>. [[LABSDAChannels]] .Basic Data Format _LABSDA_ channels [width="100%",options="header"] -|================================ -^| Channel number 2+|   Name |   Description -^| 0 2+|   *++KHR_DF_CHANNEL_LABSDA_L++* |   _L_* (luma) -^| 1 2+|   *++KHR_DF_CHANNEL_LABSDA_A++* |   _a_* -^| 2 2+|   *++KHR_DF_CHANNEL_LABSDA_B++* |   _b_* -^| 13 2+|   *++KHR_DF_CHANNEL_LABSDA_STENCIL++* |   Stencil -^| 14 2+|   *++KHR_DF_CHANNEL_LABSDA_DEPTH++* |   Depth -^| 15 2+|   *++KHR_DF_CHANNEL_LABSDA_ALPHA++* |   Alpha (opacity) -|================================ - -==== *++KHR_DF_MODEL_CMYKA++* (= 5) ==== +|==== +^| Channel number 2+| {nbsp} Name | {nbsp} Description +^| 0 2+| {nbsp} *++KHR_DF_CHANNEL_LABSDA_L++* | {nbsp} _L_* (luma) +^| 1 2+| {nbsp} *++KHR_DF_CHANNEL_LABSDA_A++* | {nbsp} _a_* +^| 2 2+| {nbsp} *++KHR_DF_CHANNEL_LABSDA_B++* | {nbsp} _b_* +^| 13 2+| {nbsp} *++KHR_DF_CHANNEL_LABSDA_STENCIL++* | {nbsp} Stencil +^| 14 2+| {nbsp} *++KHR_DF_CHANNEL_LABSDA_DEPTH++* | {nbsp} Depth +^| 15 2+| {nbsp} *++KHR_DF_CHANNEL_LABSDA_ALPHA++* | {nbsp} Alpha (opacity) +|==== + +==== *++KHR_DF_MODEL_CMYKA++* (= 5) This color model represents secondary (subtractive) colors and the combined key (black) channel, along with alpha, as shown in @@ -1828,19 +1824,19 @@ the combined key (black) channel, along with alpha, as shown in [[CMYKAChannels]] .Basic Data Format _CMYKA_ channels [width="100%",options="header"] -|================================ -^| Channel number 2+|   Name |   Description -^| 0 2+|   *++KHR_DF_CHANNEL_CMYKA_CYAN++* |   Cyan -^| 1 2+|   *++KHR_DF_CHANNEL_CMYKA_MAGENTA++* |   Magenta -^| 2 2+|   *++KHR_DF_CHANNEL_CMYKA_YELLOW++* |   Yellow -^| 3 2+|   *++KHR_DF_CHANNEL_CMYKA_KEY++* |   Key/Black -^| 15 2+|   *++KHR_DF_CHANNEL_CMYKA_ALPHA++* |   Alpha (opacity) -|================================ +|==== +^| Channel number 2+| {nbsp} Name | {nbsp} Description +^| 0 2+| {nbsp} *++KHR_DF_CHANNEL_CMYKA_CYAN++* | {nbsp} Cyan +^| 1 2+| {nbsp} *++KHR_DF_CHANNEL_CMYKA_MAGENTA++* | {nbsp} Magenta +^| 2 2+| {nbsp} *++KHR_DF_CHANNEL_CMYKA_YELLOW++* | {nbsp} Yellow +^| 3 2+| {nbsp} *++KHR_DF_CHANNEL_CMYKA_KEY++* | {nbsp} Key/Black +^| 15 2+| {nbsp} *++KHR_DF_CHANNEL_CMYKA_ALPHA++* | {nbsp} Alpha (opacity) +|==== <<< -==== *++KHR_DF_MODEL_XYZW++* (= 6) ==== +==== *++KHR_DF_MODEL_XYZW++* (= 6) -This ``color model'' represents channel data used for +This "`color model`" represents channel data used for coordinate values, as shown in <> -- for example, as a representation of the surface normal in a bump map. @@ -1851,15 +1847,15 @@ of the *_channelType_* field. [[XYZWChannels]] .Basic Data Format _XYZW_ channels [width="100%",options="header"] -|================================ -^| Channel number 2+|   Name |   Description -^| 0 2+|   *++KHR_DF_CHANNEL_XYZW_X++* |   _X_ -^| 1 2+|   *++KHR_DF_CHANNEL_XYZW_Y++* |   _Y_ -^| 2 2+|   *++KHR_DF_CHANNEL_XYZW_Z++* |   _Z_ -^| 3 2+|   *++KHR_DF_CHANNEL_XYZW_W++* |   _W_ -|================================ +|==== +^| Channel number 2+| {nbsp} Name | {nbsp} Description +^| 0 2+| {nbsp} *++KHR_DF_CHANNEL_XYZW_X++* | {nbsp} _X_ +^| 1 2+| {nbsp} *++KHR_DF_CHANNEL_XYZW_Y++* | {nbsp} _Y_ +^| 2 2+| {nbsp} *++KHR_DF_CHANNEL_XYZW_Z++* | {nbsp} _Z_ +^| 3 2+| {nbsp} *++KHR_DF_CHANNEL_XYZW_W++* | {nbsp} _W_ +|==== -==== *++KHR_DF_MODEL_HSVA_ANG++* (= 7) ==== +==== *++KHR_DF_MODEL_HSVA_ANG++* (= 7) This color model represents color differences with three channels, _value_ (luminance or luma), _saturation_ (distance from monochrome) @@ -1871,15 +1867,15 @@ wheel. [[HSVAAngChannels]] .Basic Data Format angular _HSVA_ channels [width="100%",options="header"] -|================================ -^| Channel number 2+|   Name |   Description -^| 0 2+|   *++KHR_DF_CHANNEL_HSVA_ANG_VALUE++* |   _V_ (value) -^| 1 2+|   *++KHR_DF_CHANNEL_HSVA_ANG_SATURATION++* |   _S_ (saturation) -^| 2 2+|   *++KHR_DF_CHANNEL_HSVA_ANG_HUE++* |   _H_ (hue) -^| 15 2+|   *++KHR_DF_CHANNEL_HSVA_ANG_ALPHA++* |   Alpha (opacity) -|================================ +|==== +^| Channel number 2+| {nbsp} Name | {nbsp} Description +^| 0 2+| {nbsp} *++KHR_DF_CHANNEL_HSVA_ANG_VALUE++* | {nbsp} _V_ (value) +^| 1 2+| {nbsp} *++KHR_DF_CHANNEL_HSVA_ANG_SATURATION++* | {nbsp} _S_ (saturation) +^| 2 2+| {nbsp} *++KHR_DF_CHANNEL_HSVA_ANG_HUE++* | {nbsp} _H_ (hue) +^| 15 2+| {nbsp} *++KHR_DF_CHANNEL_HSVA_ANG_ALPHA++* | {nbsp} Alpha (opacity) +|==== -==== *++KHR_DF_MODEL_HSLA_ANG++* (= 8) ==== +==== *++KHR_DF_MODEL_HSLA_ANG++* (= 8) This color model represents color differences with three channels, _lightness_ (maximum intensity), _saturation_ (distance from monochrome) @@ -1891,16 +1887,16 @@ wheel. [[HSLAAngChannels]] .Basic Data Format angular _HSLA_ channels [width="100%",options="header"] -|================================ -^| Channel number 2+|   Name |   Description -^| 0 2+|   *++KHR_DF_CHANNEL_HSLA_ANG_LIGHTNESS++* |   _L_ (lightness) -^| 1 2+|   *++KHR_DF_CHANNEL_HSLA_ANG_SATURATION++* |   _S_ (saturation) -^| 2 2+|   *++KHR_DF_CHANNEL_HSLA_ANG_HUE++* |   _H_ (hue) -^| 15 2+|   *++KHR_DF_CHANNEL_HSLA_ANG_ALPHA++* |   Alpha (opacity) -|================================ +|==== +^| Channel number 2+| {nbsp} Name | {nbsp} Description +^| 0 2+| {nbsp} *++KHR_DF_CHANNEL_HSLA_ANG_LIGHTNESS++* | {nbsp} _L_ (lightness) +^| 1 2+| {nbsp} *++KHR_DF_CHANNEL_HSLA_ANG_SATURATION++* | {nbsp} _S_ (saturation) +^| 2 2+| {nbsp} *++KHR_DF_CHANNEL_HSLA_ANG_HUE++* | {nbsp} _H_ (hue) +^| 15 2+| {nbsp} *++KHR_DF_CHANNEL_HSLA_ANG_ALPHA++* | {nbsp} Alpha (opacity) +|==== <<< -==== *++KHR_DF_MODEL_HSVA_HEX++* (= 9) ==== +==== *++KHR_DF_MODEL_HSVA_HEX++* (= 9) This color model represents color differences with three channels, _value_ (luminance or luma), _saturation_ (distance from monochrome) @@ -1912,15 +1908,15 @@ extremes on a color hexagon. [[HSVAHexChannels]] .Basic Data Format hexagonal _HSVA_ channels [width="100%",options="header"] -|================================ -^| Channel number 2+|   Name |   Description -^| 0 2+|   *++KHR_DF_CHANNEL_HSVA_HEX_VALUE++* |   _V_ (value) -^| 1 2+|   *++KHR_DF_CHANNEL_HSVA_HEX_SATURATION++* |   _S_ (saturation) -^| 2 2+|   *++KHR_DF_CHANNEL_HSVA_HEX_HUE++* |   _H_ (hue) -^| 15 2+|   *++KHR_DF_CHANNEL_HSVA_HEX_ALPHA++* |   Alpha (opacity) -|================================ +|==== +^| Channel number 2+| {nbsp} Name | {nbsp} Description +^| 0 2+| {nbsp} *++KHR_DF_CHANNEL_HSVA_HEX_VALUE++* | {nbsp} _V_ (value) +^| 1 2+| {nbsp} *++KHR_DF_CHANNEL_HSVA_HEX_SATURATION++* | {nbsp} _S_ (saturation) +^| 2 2+| {nbsp} *++KHR_DF_CHANNEL_HSVA_HEX_HUE++* | {nbsp} _H_ (hue) +^| 15 2+| {nbsp} *++KHR_DF_CHANNEL_HSVA_HEX_ALPHA++* | {nbsp} Alpha (opacity) +|==== -==== *++KHR_DF_MODEL_HSLA_HEX++* (= 10) ==== +==== *++KHR_DF_MODEL_HSLA_HEX++* (= 10) This color model represents color differences with three channels, _lightness_ (maximum intensity), _saturation_ (distance from monochrome) @@ -1932,15 +1928,15 @@ extremes on a color hexagon. [[HSLAHexChannels]] .Basic Data Format hexagonal _HSLA_ channels [width="100%",options="header"] -|================================ -^| Channel number 2+|   Name |   Description -^| 0 2+|   *++KHR_DF_CHANNEL_HSLA_HEX_LIGHTNESS++* |   _L_ (lightness) -^| 1 2+|   *++KHR_DF_CHANNEL_HSLA_HEX_SATURATION++* |   _S_ (saturation) -^| 2 2+|   *++KHR_DF_CHANNEL_HSLA_HEX_HUE++* |   _H_ (hue) -^| 15 2+|   *++KHR_DF_CHANNEL_HSLA_HEX_ALPHA++* |   Alpha (opacity) -|================================ +|==== +^| Channel number 2+| {nbsp} Name | {nbsp} Description +^| 0 2+| {nbsp} *++KHR_DF_CHANNEL_HSLA_HEX_LIGHTNESS++* | {nbsp} _L_ (lightness) +^| 1 2+| {nbsp} *++KHR_DF_CHANNEL_HSLA_HEX_SATURATION++* | {nbsp} _S_ (saturation) +^| 2 2+| {nbsp} *++KHR_DF_CHANNEL_HSLA_HEX_HUE++* | {nbsp} _H_ (hue) +^| 15 2+| {nbsp} *++KHR_DF_CHANNEL_HSLA_HEX_ALPHA++* | {nbsp} Alpha (opacity) +|==== -==== *++KHR_DF_MODEL_YCGCOA++* (= 11) ==== +==== *++KHR_DF_MODEL_YCGCOA++* (= 11) This color model represents low-cost approximate color differences with three channels, nominally luma (_Y_) and two color-difference chroma channels, @@ -1950,55 +1946,55 @@ supplemented by a channel for alpha, as shown in <>. [[YCoCgAChannels]] .Basic Data Format _YCoCgA_ channels [width="100%",options="header"] -|================================ -^| Channel number 2+|   Name |   Description -^| 0 2+|   *++KHR_DF_CHANNEL_YCGCOA_Y++* |   _Y_ -^| 1 2+|   *++KHR_DF_CHANNEL_YCGCOA_CG++* |   _Cg_ -^| 2 2+|   *++KHR_DF_CHANNEL_YCGCOA_CO++* |   _Co_ -^| 15 2+|   *++KHR_DF_CHANNEL_YCGCOA_ALPHA++* |   Alpha (opacity) -|================================ +|==== +^| Channel number 2+| {nbsp} Name | {nbsp} Description +^| 0 2+| {nbsp} *++KHR_DF_CHANNEL_YCGCOA_Y++* | {nbsp} _Y_ +^| 1 2+| {nbsp} *++KHR_DF_CHANNEL_YCGCOA_CG++* | {nbsp} _Cg_ +^| 2 2+| {nbsp} *++KHR_DF_CHANNEL_YCGCOA_CO++* | {nbsp} _Co_ +^| 15 2+| {nbsp} *++KHR_DF_CHANNEL_YCGCOA_ALPHA++* | {nbsp} Alpha (opacity) +|==== <<< -==== *++KHR_DF_MODEL_YCCBCCRC++* (= 12) ==== +==== *++KHR_DF_MODEL_YCCBCCRC++* (= 12) -This color model represents the ``Constant luminance'' -latexmath:[$Y'_CC'_\mathit{BC}C'_\mathit{RC}$] color model defined as an +This color model represents the "`Constant luminance`" +latexmath:[Y'_CC'_\mathit{BC}C'_\mathit{RC}] color model defined as an optional representation in ITU-T BT.2020 and described in <>. [[YCBCCRCChannels]] -.Basic Data Format _Y′~C~C′~BC~C′~RC~_ channels +.Basic Data Format _Y{prime}~C~C{prime}~BC~C{prime}~RC~_ channels [width="100%",options="header"] -|================================ -^| Channel number 2+|   Name |   Description -^| 0 2+|   *++KHR_DF_CHANNEL_YCCBCCRC_YC++* |   latexmath:[$Y'_C$] (luminance) -^| 1 2+|   *++KHR_DF_CHANNEL_YCCBCCRC_CBC++* |   latexmath:[$C'_\mathit{BC}$] -^| 2 2+|   *++KHR_DF_CHANNEL_YCCBCCRC_CRC++* |   latexmath:[$C'_\mathit{RC}$] -^| 13 2+|   *++KHR_DF_CHANNEL_YCCBCCRC_STENCIL++* |   Stencil -^| 14 2+|   *++KHR_DF_CHANNEL_YCCBCCRC_DEPTH++* |   Depth -^| 15 2+|   *++KHR_DF_CHANNEL_YCCBCCRC_ALPHA++* |   Alpha (opacity) -|================================ - -==== *++KHR_DF_MODEL_ICTCP++* (= 13) ==== - -This color model represents the ``Constant intensity -_IC~T~C~P~_ color model'' defined as an optional +|==== +^| Channel number 2+| {nbsp} Name | {nbsp} Description +^| 0 2+| {nbsp} *++KHR_DF_CHANNEL_YCCBCCRC_YC++* | {nbsp} latexmath:[Y'_C] (luminance) +^| 1 2+| {nbsp} *++KHR_DF_CHANNEL_YCCBCCRC_CBC++* | {nbsp} latexmath:[C'_\mathit{BC}] +^| 2 2+| {nbsp} *++KHR_DF_CHANNEL_YCCBCCRC_CRC++* | {nbsp} latexmath:[C'_\mathit{RC}] +^| 13 2+| {nbsp} *++KHR_DF_CHANNEL_YCCBCCRC_STENCIL++* | {nbsp} Stencil +^| 14 2+| {nbsp} *++KHR_DF_CHANNEL_YCCBCCRC_DEPTH++* | {nbsp} Depth +^| 15 2+| {nbsp} *++KHR_DF_CHANNEL_YCCBCCRC_ALPHA++* | {nbsp} Alpha (opacity) +|==== + +==== *++KHR_DF_MODEL_ICTCP++* (= 13) + +This color model represents the "`Constant intensity +_IC~T~C~P~_ color model`" defined as an optional representation in ITU-T BT.2100 and described in <>. [[ICTCPChannels]] .Basic Data Format _IC~T~C~P~_ channels [width="100%",options="header"] -|================================ -^| Channel number 2+|   Name |   Description -^| 0 2+|   *++KHR_DF_CHANNEL_ICTCP_I++* |   _I_ (intensity) -^| 1 2+|   *++KHR_DF_CHANNEL_ICTCP_CT++* |   _C~T~_ -^| 2 2+|   *++KHR_DF_CHANNEL_ICTCP_CP++* |   _C~P~_ -^| 13 2+|   *++KHR_DF_CHANNEL_ICTCP_STENCIL++* |   Stencil -^| 14 2+|   *++KHR_DF_CHANNEL_ICTCP_DEPTH++* |   Depth -^| 15 2+|   *++KHR_DF_CHANNEL_ICTCP_ALPHA++* |   Alpha (opacity) -|================================ +|==== +^| Channel number 2+| {nbsp} Name | {nbsp} Description +^| 0 2+| {nbsp} *++KHR_DF_CHANNEL_ICTCP_I++* | {nbsp} _I_ (intensity) +^| 1 2+| {nbsp} *++KHR_DF_CHANNEL_ICTCP_CT++* | {nbsp} _C~T~_ +^| 2 2+| {nbsp} *++KHR_DF_CHANNEL_ICTCP_CP++* | {nbsp} _C~P~_ +^| 13 2+| {nbsp} *++KHR_DF_CHANNEL_ICTCP_STENCIL++* | {nbsp} Stencil +^| 14 2+| {nbsp} *++KHR_DF_CHANNEL_ICTCP_DEPTH++* | {nbsp} Depth +^| 15 2+| {nbsp} *++KHR_DF_CHANNEL_ICTCP_ALPHA++* | {nbsp} Alpha (opacity) +|==== <<< -==== *++KHR_DF_MODEL_CIEXYZ++* (= 14) ==== +==== *++KHR_DF_MODEL_CIEXYZ++* (= 14) This color model represents channel data used to describe color coordinates in the <> coordinate @@ -2007,14 +2003,14 @@ space, as shown in <>. [[CIEXYZChannels]] .Basic Data Format CIE _XYZ_ channels [width="100%",options="header"] -|================================ -^| Channel number 2+|   Name |   Description -^| 0 2+|   *++KHR_DF_CHANNEL_CIEXYZ_X++* |   _X_ -^| 1 2+|   *++KHR_DF_CHANNEL_CIEXYZ_Y++* |   _Y_ -^| 2 2+|   *++KHR_DF_CHANNEL_CIEXYZ_Z++* |   _Z_ -|================================ +|==== +^| Channel number 2+| {nbsp} Name | {nbsp} Description +^| 0 2+| {nbsp} *++KHR_DF_CHANNEL_CIEXYZ_X++* | {nbsp} _X_ +^| 1 2+| {nbsp} *++KHR_DF_CHANNEL_CIEXYZ_Y++* | {nbsp} _Y_ +^| 2 2+| {nbsp} *++KHR_DF_CHANNEL_CIEXYZ_Z++* | {nbsp} _Z_ +|==== -==== *++KHR_DF_MODEL_CIEXYY++* (= 15) ==== +==== *++KHR_DF_MODEL_CIEXYY++* (= 15) This color model represents channel data used to describe chromaticity coordinates in the <> coordinate @@ -2023,16 +2019,16 @@ space, as shown in <>. [[CIEXYYChannels]] .Basic Data Format CIE _xyY_ channels [width="100%",options="header"] -|================================ -^| Channel number 2+|   Name |   Description -^| 0 2+|   *++KHR_DF_CHANNEL_CIEXYZ_X++* |   _x_ -^| 1 2+|   *++KHR_DF_CHANNEL_CIEXYZ_YCHROMA++* |   _y_ -^| 2 2+|   *++KHR_DF_CHANNEL_CIEXYZ_YLUMA++* |   _Y_ -|================================ +|==== +^| Channel number 2+| {nbsp} Name | {nbsp} Description +^| 0 2+| {nbsp} *++KHR_DF_CHANNEL_CIEXYZ_X++* | {nbsp} _x_ +^| 1 2+| {nbsp} *++KHR_DF_CHANNEL_CIEXYZ_YCHROMA++* | {nbsp} _y_ +^| 2 2+| {nbsp} *++KHR_DF_CHANNEL_CIEXYZ_YLUMA++* | {nbsp} _Y_ +|==== <<< [[CompressedFormatModels]] -=== *_colorModel_* for compressed formats === +=== *_colorModel_* for compressed formats A number of compressed formats are supported as part of *++khr_df_model_e++*. In general, these formats will have the texel block dimensions of the @@ -2068,17 +2064,17 @@ Example descriptors for compressed formats are provided after each model in this section. <<< -==== *++KHR_DF_MODEL_DXT1A++*/*++KHR_DF_MODEL_BC1A++* (= 128) ==== +==== *++KHR_DF_MODEL_DXT1A++*/*++KHR_DF_MODEL_BC1A++* (= 128) This model represents the DXT1 or BC1 format, described in <>. Each compressed texel block consists of 4{times}4 texels in 8 bytes. -A single sample with channel ID 0 indicates that the ``special value'' +A single sample with channel ID 0 indicates that the "`special value`" should be interpreted as black, as described in <> -- a descriptor block representing this is shown in <>. -A single sample with channel ID 1 indicates that the ``special value'' +A single sample with channel ID 1 indicates that the "`special value`" should represent transparency, as described in <> -- a descriptor block representing this is shown in <>. @@ -2088,7 +2084,7 @@ Enumerant names for these channel ids are listed in <>. [[bc1_channels]] .BC1A channel names [options="header"] -|==================== +|==== ^| Enumerant ^| Value ^| *++KHR_DF_CHANNEL_DXT1A_COLOR++* 1.2+^.^| 0 ^| *++KHR_DF_CHANNEL_BC1A_COLOR++* @@ -2096,13 +2092,13 @@ Enumerant names for these channel ids are listed in <>. ^| *++KHR_DF_CHANNEL_DXT1A_ALPHA++* ^| *++KHR_DF_CHANNEL_BC1A_ALPHAPRESENT++* ^| *++KHR_DF_CHANNEL_BC1A_ALPHA++* -|==================== +|==== <<< [[dxt1a_example_noalpha]] .Example DXT1A descriptor with no punch-through alpha [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 44 @@ -2110,21 +2106,21 @@ Enumerant names for these channel ids are listed in <>. 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 1) = 40 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++DXT1A++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 8 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* -|================================ +|==== [[dxt1a_example_alpha]] .Example DXT1A descriptor with punch-through alpha [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 44 @@ -2132,19 +2128,19 @@ Enumerant names for these channel ids are listed in <>. 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 1) = 40 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++DXT1A++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 8 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++ALPHA++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++ALPHA++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* -|================================ +|==== <<< -==== *++KHR_DF_MODEL_DXT2++*/*++3++*/*++KHR_DF_MODEL_BC2++* (= 129) ==== +==== *++KHR_DF_MODEL_DXT2++*/*++3++*/*++KHR_DF_MODEL_BC2++* (= 129) This model represents the DXT2/3 format, also known as BC2, and described in <>. @@ -2161,7 +2157,7 @@ Enumerant names for these channel ids are listed in <>. [[bc2_channels]] .BC2 channel names [options="header"] -|==================== +|==== ^| Enumerant ^| Value ^| *++KHR_DF_CHANNEL_DXT2_COLOR++* 1.3+^.^| 0 ^| *++KHR_DF_CHANNEL_DXT3_COLOR++* @@ -2169,7 +2165,7 @@ Enumerant names for these channel ids are listed in <>. ^| *++KHR_DF_CHANNEL_DXT2_ALPHA++* 1.3+^.^| 15 ^| *++KHR_DF_CHANNEL_DXT3_ALPHA++* ^| *++KHR_DF_CHANNEL_BC2_ALPHA++* -|==================== +|==== The alpha channel is 64 bits and at offset 0; the color channel is 64 bits and at offset 64. @@ -2179,7 +2175,7 @@ requires the whole texel block. .Example DXT2 descriptor (premultiplied alpha) [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 60 @@ -2187,27 +2183,27 @@ requires the whole texel block. 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 2) = 56 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++PREMULTIPLIED++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++DXT2++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 16 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Alpha sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++ALPHA++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++ALPHA++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Color sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 64 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 64 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* -|================================ +|==== <<< .Example DXT3 descriptor [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 60 @@ -2215,25 +2211,25 @@ requires the whole texel block. 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 2) = 56 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++DXT3++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 16 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Alpha sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++ALPHA++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++ALPHA++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Color sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 64 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 64 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* -|================================ +|==== <<< -==== *++KHR_DF_MODEL_DXT4++*/*++5++*/*++KHR_DF_MODEL_BC3++* (= 130) ==== +==== *++KHR_DF_MODEL_DXT4++*/*++5++*/*++KHR_DF_MODEL_BC3++* (= 130) This model represents the DXT4/5 format, also known as BC3, and described in <>. @@ -2250,7 +2246,7 @@ Enumerant names for these channel ids are listed in <>. [[bc3_channels]] .BC3 channel names [options="header"] -|==================== +|==== ^| Enumerant ^| Value ^| *++KHR_DF_CHANNEL_DXT4_COLOR++* 1.3+^.^| 0 ^| *++KHR_DF_CHANNEL_DXT5_COLOR++* @@ -2258,7 +2254,7 @@ Enumerant names for these channel ids are listed in <>. ^| *++KHR_DF_CHANNEL_DXT4_ALPHA++* 1.3+^.^| 15 ^| *++KHR_DF_CHANNEL_DXT5_ALPHA++* ^| *++KHR_DF_CHANNEL_BC3_ALPHA++* -|==================== +|==== The alpha channel is 64 bits and at offset 0; the color channel is 64 bits and at offset 64. @@ -2268,7 +2264,7 @@ requires the whole texel block. .Example DXT4 descriptor (premultiplied alpha) [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 60 @@ -2276,27 +2272,27 @@ requires the whole texel block. 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 2) = 56 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++PREMULTIPLIED++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++DXT4++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 16 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Alpha sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++ALPHA++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++ALPHA++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Color sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 64 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 64 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* -|================================ +|==== <<< .Example DXT5 descriptor [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 60 @@ -2304,25 +2300,25 @@ requires the whole texel block. 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 2) = 56 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++DXT5++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 16 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Alpha sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++ALPHA++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++ALPHA++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Color sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 64 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 64 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* -|================================ +|==== <<< -==== *++KHR_DF_MODEL_BC4++* (= 131) ==== +==== *++KHR_DF_MODEL_BC4++* (= 131) This model represents the Direct3D BC4 format for single-channel interpolated 8-bit data, as described in <>. @@ -2336,14 +2332,14 @@ The enumerant name for this channel id is listed in <>. [[bc4_channel]] .BC4 channel name [options="header"] -|==================== +|==== ^| Enumerant ^| Value ^| *++KHR_DF_CHANNEL_BC4_DATA++* ^| 0 -|==================== +|==== .Example BC4 unsigned descriptor [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 44 @@ -2351,20 +2347,20 @@ The enumerant name for this channel id is listed in <>. 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 1) = 40 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++BC4++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 8 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++DATA++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++DATA++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* -|================================ +|==== .Example BC4 signed descriptor [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 44 @@ -2372,19 +2368,19 @@ The enumerant name for this channel id is listed in <>. 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 1) = 40 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++BC4++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 8 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information~ -^| 0 ^| 1 ^| 0 ^| 0 4+^| *++DATA++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 1 ^| 0 ^| 0 4+^| *++DATA++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* *++INT32_MIN++* 32+^| *_sampleUpper:_* *++INT32_MAX++* -|================================ +|==== <<< -==== *++KHR_DF_MODEL_BC5++* (= 132) ==== +==== *++KHR_DF_MODEL_BC5++* (= 132) This model represents the Direct3D BC5 format for dual-channel interpolated 8-bit data, as described in <>. @@ -2401,17 +2397,17 @@ Enumerant names for these channel ids are listed in <>. [[bc5_channels]] .BC5 channel names [options="header"] -|==================== +|==== ^| Enumerant ^| Value ^| *++KHR_DF_CHANNEL_BC5_RED++* 1.2+^.^| 0 ^| *++KHR_DF_CHANNEL_BC5_R++* ^| *++KHR_DF_CHANNEL_BC5_GREEN++* 1.2+^.^| 1 ^| *++KHR_DF_CHANNEL_BC5_G++* -|==================== +|==== .Example BC5 unsigned descriptor [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 60 @@ -2419,27 +2415,27 @@ Enumerant names for these channel ids are listed in <>. 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 2) = 56 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++BC5++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 16 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Red sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Green sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 64 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 64 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* -|================================ +|==== <<< .Example BC5 signed descriptor [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 60 @@ -2447,30 +2443,30 @@ Enumerant names for these channel ids are listed in <>. 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 2) = 56 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++BC5++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 16 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Red sample information~ -^| 0 ^| 1 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 1 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* *++INT32_MIN++* 32+^| *_sampleUpper:_* *++INT32_MAX++* ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Green sample information~ -^| 0 ^| 1 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 64 +^| 0 ^| 1 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 64 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* *++INT32_MIN++* 32+^| *_sampleUpper:_* *++INT32_MAX++* -|================================ +|==== <<< -A legacy variant of this format known as ``ATI2n'' or ``3Dc'' swaps +A legacy variant of this format known as "`ATI2n`" or "`3Dc`" swaps the location of the two channels, and can be encoded as follows: .Example ATI2n unsigned descriptor [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 60 @@ -2478,25 +2474,25 @@ the location of the two channels, and can be encoded as follows: 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 2) = 56 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++BC5++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 16 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Red sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Green sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 64 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 64 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* -|================================ +|==== <<< -==== *++KHR_DF_MODEL_BC6H++* (= 133) ==== +==== *++KHR_DF_MODEL_BC6H++* (= 133) This model represents the Direct3D BC6H format for _RGB_ floating-point data, as described in <>. @@ -2511,16 +2507,16 @@ The enumerant names for this channel id are listed in <>. [[bc6h_channel]] .BC6H channel names [options="header"] -|==================== +|==== ^| Enumerant ^| Value ^| *++KHR_DF_CHANNEL_BC6H_COLOR++* 1.2+^.^| 0 ^| *++KHR_DF_CHANNEL_BC6H_DATA++* -|==================== +|==== [[example_bc6h]] .Example BC6H signed descriptor [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 44 @@ -2528,22 +2524,22 @@ The enumerant names for this channel id are listed in <>. 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 1) = 40 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++BC6H++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 16 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information~ -^| 1 ^| 1 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 127 (= ``128'') 16+^| *_bitOffset:_* 0 +^| 1 ^| 1 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 127 (= "`128`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0xBF800000U -- -1.0f 32+^| *_sampleUpper:_* 0x7F800000U -- 1.0f -|================================ +|==== <<< [[example_bc6hu]] .Example BC6H unsigned descriptor [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 44 @@ -2551,19 +2547,19 @@ The enumerant names for this channel id are listed in <>. 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 1) = 40 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++BC6H++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 16 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information~ -^| 1 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 127 (= ``128'') 16+^| *_bitOffset:_* 0 +^| 1 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 127 (= "`128`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0xBF800000U -- -1.0f 32+^| *_sampleUpper:_* 0x7F800000U -- 1.0f -|================================ +|==== <<< -==== *++KHR_DF_MODEL_BC7++* (= 134) ==== +==== *++KHR_DF_MODEL_BC7++* (= 134) This model represents the Direct3D BC7 format for _RGBA_ data, as described in <>. @@ -2578,16 +2574,16 @@ The enumerant names for this channel id are listed in <>. [[bc7_channel]] .BC7 channel names [options="header"] -|==================== +|==== ^| Enumerant ^| Value ^| *++KHR_DF_CHANNEL_BC7_COLOR++* 1.2+^.^| 0 ^| *++KHR_DF_CHANNEL_BC7_DATA++* -|==================== +|==== [[example_bc7]] .Example BC7 descriptor [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 44 @@ -2595,19 +2591,19 @@ The enumerant names for this channel id are listed in <>. 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 1) = 40 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++BC7++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 16 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 127 (= ``128'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 127 (= "`128`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* -|================================ +|==== <<< -==== *++KHR_DF_MODEL_ETC1++* (= 160) ==== +==== *++KHR_DF_MODEL_ETC1++* (= 160) This model represents the original Ericsson Texture Compression format, described in <>, with a guarantee that the format does not rely @@ -2623,16 +2619,16 @@ The enumerant names for this channel id are listed in <>. [[etc1_channel]] .ETC1 channel names [options="header"] -|==================== +|==== ^| Enumerant ^| Value ^| *++KHR_DF_CHANNEL_ETC1_COLOR++* 1.2+^.^| 0 ^| *++KHR_DF_CHANNEL_ETC1_DATA++* -|==================== +|==== [[example_etc1]] .Example ETC1 descriptor [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 44 @@ -2640,19 +2636,19 @@ The enumerant names for this channel id are listed in <>. 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 1) = 40 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++ETC1++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 8 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* -|================================ +|==== <<< -==== *++KHR_DF_MODEL_ETC2++* (= 161) ==== +==== *++KHR_DF_MODEL_ETC2++* (= 161) This model represents the updated Ericsson Texture Compression format, ETC2, and also the related R11 EAC and RG11 EAC formats. @@ -2663,7 +2659,7 @@ The enumerant names for these channel ids are listed in <>. [[etc2_channels]] .ETC2 channel names [options="header"] -|==================== +|==== ^| Enumerant ^| Value ^| *++KHR_DF_CHANNEL_ETC2_RED++* 1.2+^.^| 0 ^| *++KHR_DF_CHANNEL_ETC2_R++* @@ -2672,7 +2668,7 @@ The enumerant names for these channel ids are listed in <>. ^| *++KHR_DF_CHANNEL_ETC2_COLOR++* ^| 2 ^| *++KHR_DF_CHANNEL_ETC2_ALPHA++* 1.2+^.^| 15 ^| *++KHR_DF_CHANNEL_ETC2_A++* -|==================== +|==== Channel ID 0 represents red, and is used for the R11 EAC format, as described in <>; the texel block size in this format @@ -2681,7 +2677,7 @@ is 8 bytes, represented as a single 64-bit sample. [[example_r11]] .Example R11 unsigned descriptor [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 44 @@ -2689,20 +2685,20 @@ is 8 bytes, represented as a single 64-bit sample. 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 1) = 40 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++ETC2++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 8 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* -|================================ +|==== .Example R11 signed descriptor [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 44 @@ -2710,16 +2706,16 @@ is 8 bytes, represented as a single 64-bit sample. 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 1) = 40 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++ETC2++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 8 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information~ -^| 0 ^| 1 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 1 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* *++INT32_MIN++* 32+^| *_sampleUpper:_* *++INT32_MAX++* -|================================ +|==== <<< Channel ID 1 represents green; the presence of samples for both red @@ -2729,7 +2725,7 @@ and green, in that order, indicates the RG11 EAC format as described in [[example_rg11]] .Example RG11 unsigned descriptor [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 60 @@ -2737,26 +2733,26 @@ and green, in that order, indicates the RG11 EAC format as described in 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 2) = 56 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++ETC2++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 16 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Red sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Green sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 64 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 64 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* -|================================ +|==== .Example RG11 signed descriptor [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 60 @@ -2764,22 +2760,22 @@ and green, in that order, indicates the RG11 EAC format as described in 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 2) = 56 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++ETC2++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 16 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Red sample information~ -^| 0 ^| 1 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 1 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* *++INT32_MIN++* 32+^| *_sampleUpper:_* *++INT32_MAX++* ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Green sample information~ -^| 0 ^| 1 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 64 +^| 0 ^| 1 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 64 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* *++INT32_MIN++* 32+^| *_sampleUpper:_* *++INT32_MAX++* -|================================ +|==== <<< Channel ID 2 represents _RGB_ combined content, for the ETC2 format as described in @@ -2789,7 +2785,7 @@ A single sample of ID 2 indicates RGB2 with no alpha, occupying 8 bytes. [[example_etc2]] .Example ETC2 descriptor (with no alpha) [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 44 @@ -2797,27 +2793,27 @@ A single sample of ID 2 indicates RGB2 with no alpha, occupying 8 bytes. 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 1) = 40 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++ETC2++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 8 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* -|================================ +|==== <<< Channel ID 15 indicates the presence of alpha. If the texel block size is 8 bytes and the _RGB_ and alpha channels are -co-sited, ``punch through'' alpha is supported as described in +co-sited, "`punch through`" alpha is supported as described in <>. [[example_etc2_punchthrough]] .Example ETC2 descriptor with punchthrough alpha [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 60 @@ -2825,22 +2821,22 @@ co-sited, ``punch through'' alpha is supported as described in 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 1) = 56 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++ETC2++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 8 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Color sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Alpha sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++ALPHA++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++ALPHA++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* -|================================ +|==== <<< Finally, if the texel block size is 16 bytes and the alpha channel appears in the @@ -2850,7 +2846,7 @@ alpha is supported, as described in <>. [[example_etc2_alpha]] .Example ETC2 descriptor with separate alpha [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 60 @@ -2858,25 +2854,25 @@ alpha is supported, as described in <>. 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 1) = 56 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++ETC2++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 16 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Alpha sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++ALPHA++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++ALPHA++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Color sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 64 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 64 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* -|================================ +|==== <<< -==== *++KHR_DF_MODEL_ASTC++* (= 162) ==== +==== *++KHR_DF_MODEL_ASTC++* (= 162) This model represents Adaptive Scalable Texture Compression as a single channel in a texel block of 16 bytes. ASTC HDR (high dynamic range) and @@ -2899,17 +2895,17 @@ The enumerant name for this channel id is listed in <>. [[astc_channels]] .ASTC channel name [options="header"] -|==================== +|==== ^| Enumerant ^| Value ^| *++KHR_DF_CHANNEL_ASTC_DATA++* ^| 0 -|==================== +|==== <<< [[example_astc_ldr]] .Example 4{times}4 ASTC LDR descriptor [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 44 @@ -2917,21 +2913,21 @@ The enumerant name for this channel id is listed in <>. 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 1) = 40 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++ASTC++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 16 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++DATA++* 8+^| *_bitLength:_* 127 (= ``128'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++DATA++* 8+^| *_bitLength:_* 127 (= "`128`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* -|================================ +|==== [[example_astc_hdr]] .Example 8{times}5 ASTC HDR descriptor [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 44 @@ -2939,19 +2935,19 @@ The enumerant name for this channel id is listed in <>. 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 1) = 40 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++ASTC++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 4 (= ``5'') 8+^| 7 (= ``8'') +8+^| 0 8+^| 0 8+^| 4 (= "`5`") 8+^| 7 (= "`8`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 16 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information~ -^| 1 ^| 1 ^| 0 ^| 0 4+^| *++DATA++* 8+^| *_bitLength:_* 127 (= ``128'') 16+^| *_bitOffset:_* 0 +^| 1 ^| 1 ^| 0 ^| 0 4+^| *++DATA++* 8+^| *_bitLength:_* 127 (= "`128`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0xBF800000U -- -1.0f 32+^| *_sampleUpper:_* 0x7F800000U -- 1.0f -|================================ +|==== <<< -==== *++KHR_DF_MODEL_ETC1S++* (= 163) ==== +==== *++KHR_DF_MODEL_ETC1S++* (= 163) This model represents a subset of the original Ericsson Texture Compression format, described in <>, which is restricted @@ -2967,16 +2963,16 @@ The enumerant names for this channel id are listed in <>. [[etc1s_channel]] .ETC1S channel names [options="header"] -|==================== +|==== ^| Enumerant ^| Value ^| *++KHR_DF_CHANNEL_ETC1S_COLOR++* 1.2+^.^| 0 ^| *++KHR_DF_CHANNEL_ETC1S_DATA++* -|==================== +|==== [[example_etc1s]] .Example ETC1S descriptor [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 44 @@ -2984,19 +2980,19 @@ The enumerant names for this channel id are listed in <>. 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 1) = 40 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++ETC1S++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 8 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* -|================================ +|==== <<< -==== *++KHR_DF_MODEL_PVRTC++* (= 164) ==== +==== *++KHR_DF_MODEL_PVRTC++* (= 164) This model represents the first generation of PowerVR Texture Compression as a single channel in a texel block of 8 bytes. 4-bit-per-pixel mode @@ -3010,17 +3006,17 @@ The enumerant names for this channel id are listed in <>. [[pvrtc_channel]] .PVRTC channel names [options="header"] -|==================== +|==== ^| Enumerant ^| Value ^| *++KHR_DF_CHANNEL_PVRTC_COLOR++* 1.2+^.^| 0 ^| *++KHR_DF_CHANNEL_PVRTC_DATA++* -|==================== +|==== <<< [[example_pvrtc4bpp]] .Example PVRTC 4bpp descriptor [options="header"] -|================================ +|==== 32+^| ~++uint32_t++ bit~ ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 44 @@ -3028,21 +3024,21 @@ The enumerant names for this channel id are listed in <>. 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 1) = 40 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++PVRTC++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 8 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* -|================================ +|==== [[example_pvrtc2bpp]] .Example PVRTC 2bpp descriptor [options="header"] -|================================ +|==== 32+^| ~++uint32_t++ bit~ ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 44 @@ -3050,19 +3046,19 @@ The enumerant names for this channel id are listed in <>. 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 1) = 40 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++PVRTC++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 7 (= ``8'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 7 (= "`8`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 8 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* -|================================ +|==== <<< -==== *++KHR_DF_MODEL_PVRTC2++* (= 165) ==== +==== *++KHR_DF_MODEL_PVRTC2++* (= 165) This model represents the second generation of PowerVR Texture Compression as a single channel in a texel block of 8 bytes. 4-bit-per-pixel mode @@ -3076,17 +3072,17 @@ The enumerant names for this channel id are listed in <>. [[pvrtc2_channel]] .PVRTC2 channel names [options="header"] -|==================== +|==== ^| Enumerant ^| Value ^| *++KHR_DF_CHANNEL_PVRTC2_COLOR++* 1.2+^.^| 0 ^| *++KHR_DF_CHANNEL_PVRTC2_DATA++* -|==================== +|==== <<< [[example_pvrtc24bpp]] .Example PVRTC2 4bpp descriptor [options="header"] -|================================ +|==== 32+^| ~++uint32_t++ bit~ ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 44 @@ -3094,21 +3090,21 @@ The enumerant names for this channel id are listed in <>. 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 1) = 40 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++PVRTC2++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 3 (= ``4'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 3 (= "`4`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 8 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* -|================================ +|==== [[example_pvrtc22bpp]] .Example PVRTC2 2bpp descriptor [options="header"] -|================================ +|==== 32+^| ~++uint32_t++ bit~ ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 44 @@ -3116,23 +3112,23 @@ The enumerant names for this channel id are listed in <>. 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 1) = 40 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++PVRTC2++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 3 (= ``4'') 8+^| 7 (= ``8'') +8+^| 0 8+^| 0 8+^| 3 (= "`4`") 8+^| 7 (= "`8`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 8 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= ``64'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++COLOR++* 8+^| *_bitLength:_* 63 (= "`64`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* *++UINT32_MAX++* -|================================ +|==== <<< -=== *_colorPrimaries_* === +=== *_colorPrimaries_* It is not sufficient to define a buffer as containing, for example, additive primaries. Additional information is required to define -what ``red'' is provided by the ``red'' channel. A full definition of +what "`red`" is provided by the "`red`" channel. A full definition of primaries requires an extension which provides the full color space of the data, but a subset of common primary spaces can be identified by the *++khr_df_primaries_e++* enumeration, represented as an unsigned 8-bit @@ -3142,41 +3138,41 @@ More information about color primaries is provided in <>. .Field location information for *_colorPrimaries_* [cols="7,10,2"] -|================== +|==== ^| Word offset into basic descriptor block ^| *++KHR_DF_WORD_PRIMARIES++* ^| 2 ^| Word offset into descriptor ^| *++KHR_DF_WORD_PRIMARIES++* {plus} 1 ^| 3 ^| Start bit within word ^| *++KHR_DF_SHIFT_PRIMARIES++* ^| 8 ^| Bit mask of value ^| *++KHR_DF_MASK_PRIMARIES++* ^| 0xFF -|================== +|==== *++khr_df_primaries_e++* *_colorPrimaries_* = *++KHR_DF_MASK_PRIMARIES++* & + (++bdb++[*++KHR_DF_WORD_PRIMARIES++*] >> *++KHR_DF_SHIFT_PRIMARIES++*); -==== *++KHR_DF_PRIMARIES_UNSPECIFIED++* (= 0) ==== +==== *++KHR_DF_PRIMARIES_UNSPECIFIED++* (= 0) -This ``set of primaries'' identifies a data representation whose color +This "`set of primaries`" identifies a data representation whose color representation is unknown or which does not fit into this list of -common primaries. Having an ``unspecified'' value here precludes users +common primaries. Having an "`unspecified`" value here precludes users of this data format from being able to perform automatic color conversion unless the primaries are defined in another way. Formats which require a proprietary color space -- for example, raw data from a Bayer sensor that records the direct response of each filtered sample -- can still -indicate that samples represent ``red'', ``green'' and ``blue'', but should -mark the primaries here as ``unspecified'' and provide a detailed +indicate that samples represent "`red`", "`green`" and "`blue`", but should +mark the primaries here as "`unspecified`" and provide a detailed description in an extension block. -==== *++KHR_DF_PRIMARIES_BT709++* (= 1) ==== +==== *++KHR_DF_PRIMARIES_BT709++* (= 1) This value represents the Color Primaries defined by the <> and described in <>, which are also shared by sRGB. _RGB_ data is distinguished between BT.709 and sRGB by the Transfer Function. -Conversion to and from BT.709 _Y′C~B~C~R~_ (_YUV_) representation uses the +Conversion to and from BT.709 _Y{prime}C~B~C~R~_ (_YUV_) representation uses the color conversion matrix defined in the <> specification, and described in <>, except in the case of sYCC (which can be distinguished by the use of the sRGB transfer function), in which case conversion to and -from BT.709 _Y′C~B~C~R~_ representation uses the color conversion +from BT.709 _Y{prime}C~B~C~R~_ representation uses the color conversion matrix defined in the <> specification, and described in <>. This is the preferred set of color primaries used by HDTV and sRGB, and likely @@ -3184,71 +3180,71 @@ a sensible default set of color primaries for common rendering operations. *++KHR_DF_PRIMARIES_SRGB++* is provided as a synonym for *++KHR_DF_PRIMARIES_BT709++*. -==== *++KHR_DF_PRIMARIES_BT601_EBU++* (= 2) ==== +==== *++KHR_DF_PRIMARIES_BT601_EBU++* (= 2) This value represents the Color Primaries defined in the <> for standard-definition television, particularly for 625-line signals, and described in <>. -Conversion to and from BT.601 _Y′C~B~C~R~_ (_YUV_) typically uses the color conversion +Conversion to and from BT.601 _Y{prime}C~B~C~R~_ (_YUV_) typically uses the color conversion matrix defined in the BT.601 specification and described in <>. -==== *++KHR_DF_PRIMARIES_BT601_SMPTE++* (= 3) ==== +==== *++KHR_DF_PRIMARIES_BT601_SMPTE++* (= 3) This value represents the Color Primaries defined in the <> for standard-definition television, particularly for 525-line signals, and described in <>. -Conversion to and from BT.601 _Y′C~B~C~R~_ (_YUV_) typically uses the color conversion +Conversion to and from BT.601 _Y{prime}C~B~C~R~_ (_YUV_) typically uses the color conversion matrix defined in the BT.601 specification and described in <>. -==== *++KHR_DF_PRIMARIES_BT2020++* (= 4) ==== +==== *++KHR_DF_PRIMARIES_BT2020++* (= 4) This value represents the Color Primaries defined in the <> for ultra-high-definition television -and described in <>. Conversion to and from BT.2020 _Y′C~B~C~R~_ +and described in <>. Conversion to and from BT.2020 _Y{prime}C~B~C~R~_ (_YUV_ uses the color conversion matrix defined in the BT.2020 specification and described in <>. -==== *++KHR_DF_PRIMARIES_CIEXYZ++* (= 5) ==== +==== *++KHR_DF_PRIMARIES_CIEXYZ++* (= 5) This value represents the theoretical Color Primaries defined by the International Color Consortium for the <> linear color space. -==== *++KHR_DF_PRIMARIES_ACES++* (= 6) ==== +==== *++KHR_DF_PRIMARIES_ACES++* (= 6) This value represents the Color Primaries defined for the <> and described in <>. -==== *++KHR_DF_PRIMARIES_ACESCC++* (= 7) ==== +==== *++KHR_DF_PRIMARIES_ACESCC++* (= 7) This value represents the Color Primaries defined for the <> compositor and described in <>. -==== *++KHR_DF_PRIMARIES_NTSC1953++* (= 8) ==== +==== *++KHR_DF_PRIMARIES_NTSC1953++* (= 8) This value represents the Color Primaries defined for the NTSC 1953 color television transmission standard and described in <>. -==== *++KHR_DF_PRIMARIES_PAL525++* (= 9) ==== +==== *++KHR_DF_PRIMARIES_PAL525++* (= 9) This value represents the Color Primaries defined for 525-line PAL signals, described in <>. -==== *++KHR_DF_PRIMARIES_DISPLAYP3++* (= 10) ==== +==== *++KHR_DF_PRIMARIES_DISPLAYP3++* (= 10) This value represents the Color Primaries defined for the Display P3 color space, described in <>. -==== *++KHR_DF_PRIMARIES_ADOBERGB++* (= 11) ==== +==== *++KHR_DF_PRIMARIES_ADOBERGB++* (= 11) This value represents the Color Primaries defined in <>, described in <>. <<< -=== *_transferFunction_* === +=== *_transferFunction_* Many color representations contain a non-linear _transfer function_ which maps between a linear (intensity-based) representation and @@ -3259,7 +3255,7 @@ and encoded in the enumeration *++khr_df_transfer_e++*. A fully-flexible transfer function requires an extension with a full color space definition. Where the transfer function can be described as a simple power curve, -applying the function is commonly known as ``gamma correction''. +applying the function is commonly known as "`gamma correction`". The transfer function is applied to a sample only when the sample's *++KHR_DF_SAMPLE_DATATYPE_LINEAR++* bit is 0; if this bit is 1, the sample is represented linearly irrespective of the *_transferFunction_*. @@ -3271,7 +3267,7 @@ the transfer function. For example, ASTC stores both alpha and _RGB_ data but is represented by a single sample; in ASTC, any sRGB transfer function is not applied to the alpha channel of the ASTC texture. In this case, the *++KHR_DF_SAMPLE_DATATYPE_LINEAR++* bit being zero means -that the transfer function is ``applied'' to the ASTC sample in a way that +that the transfer function is "`applied`" to the ASTC sample in a way that only affects the _RGB_ channels. This is not a concern for most color models, which explicitly store different channels in each sample. @@ -3284,12 +3280,12 @@ intermediate values to which the transfer function should apply. .Field location information for *_transferFunction_* [cols="4,5,2"] -|================== +|==== ^| Word offset into basic descriptor block ^| *++KHR_DF_WORD_TRANSFER++* ^| 2 ^| Word offset into descriptor ^| *++KHR_DF_WORD_TRANSFER++* {plus} 1 ^| 3 ^| Start bit within word ^| *++KHR_DF_SHIFT_TRANSFER++* ^| 16 ^| Bit mask of value ^| *++KHR_DF_MASK_TRANSFER++* ^| 0xFF -|================== +|==== *++khr_df_transfer_e++* *_transferFunction_* = *++KHR_DF_MASK_TRANSFER++* & + (++bdb++[*++KHR_DF_WORD_TRANSFER++*] >> *++KHR_DF_SHIFT_TRANSFER++*); @@ -3297,14 +3293,14 @@ intermediate values to which the transfer function should apply. The enumerant value for each of the following transfer functions is shown in parentheses alongside the title. -==== *++KHR_DF_TRANSFER_UNSPECIFIED++* (= 0) ==== +==== *++KHR_DF_TRANSFER_UNSPECIFIED++* (= 0) This value should be used when the transfer function is unknown, or specified only in an extension block, precluding conversion of color spaces and correct filtering of the data values using only the information in the basic descriptor block. -==== *++KHR_DF_TRANSFER_LINEAR++* (= 1) ==== +==== *++KHR_DF_TRANSFER_LINEAR++* (= 1) This value represents a linear transfer function: for color data, there is a linear relationship between numerical pixel values and @@ -3312,22 +3308,22 @@ the intensity of additive colors. This transfer function allows for blending and filtering operations to be applied directly to the data values. -==== *++KHR_DF_TRANSFER_SRGB++* (= 2) ==== +==== *++KHR_DF_TRANSFER_SRGB++* (= 2) This value represents the non-linear transfer function defined in the <> for mapping between numerical pixel values and displayed light intensity, as described in <>. [width="60%",cols="^8,^2,^3"] -|========== -| Mapping from linear intensity to encoding | EOTF^ -1^ | <> +|==== +| Mapping from linear intensity to encoding | EOTF^{nbsp}-1^ | <> | Mapping from encoding to linear intensity | EOTF | <> -|========== +|==== Encoded values outside the range 0..1 use the extended formulae for EOTF and EOTF^-1^ described in <>. -==== *++KHR_DF_TRANSFER_ITU++* (= 3) ==== +==== *++KHR_DF_TRANSFER_ITU++* (= 3) This value represents the non-linear transfer function defined by the ITU and used in the BT.601, BT.709 and BT.2020 specifications @@ -3335,12 +3331,12 @@ for mapping between represented scene light intensity and numerical pixel values, as described in <>. [width="60%",cols="^8,^2,^3"] -|========== +|==== | Mapping from linear intensity to encoding | OETF | <> -| Mapping from encoding to linear intensity | OETF^ -1^ | <> -|========== +| Mapping from encoding to linear intensity | OETF^{nbsp}-1^ | <> +|==== -==== *++KHR_DF_TRANSFER_NTSC++* (= 4) ==== +==== *++KHR_DF_TRANSFER_NTSC++* (= 4) This value represents the non-linear transfer function defined by the original NTSC television broadcast specification for mapping @@ -3348,15 +3344,15 @@ between represented scene light intensity or display light intensity and numerical pixel values, as described in <>. [width="60%",cols="^8,^4"] -|========== -| Mapping from linear intensity to encoding | EOTF^ -1^ / OETF -| Mapping from encoding to linear intensity | EOTF / OETF^ -1^ -|========== +|==== +| Mapping from linear intensity to encoding | EOTF^{nbsp}-1^ / OETF +| Mapping from encoding to linear intensity | EOTF / OETF^{nbsp}-1^ +|==== NOTE: More recent formulations of this transfer functions, such as that -defined in SMPTE 170M-2004, use the ``ITU'' formulation described above. +defined in SMPTE 170M-2004, use the "`ITU`" formulation described above. -==== *++KHR_DF_TRANSFER_SLOG++* (= 5) ==== +==== *++KHR_DF_TRANSFER_SLOG++* (= 5) This value represents a nonlinear Transfer Function between linear scene light intensity and nonlinear pixel values, used by some @@ -3364,12 +3360,12 @@ Sony video cameras to represent an increased dynamic range, and is described in <>. [width="60%",cols="^8,^2"] -|========== +|==== | Mapping from linear intensity to encoding | OETF -| Mapping from encoding to linear intensity | OETF^ -1^ -|========== +| Mapping from encoding to linear intensity | OETF^{nbsp}-1^ +|==== -==== *++KHR_DF_TRANSFER_SLOG2++* (= 6) ==== +==== *++KHR_DF_TRANSFER_SLOG2++* (= 6) This value represents a nonlinear Transfer Function between linear scene light intensity and nonlinear pixel values, used by some @@ -3377,25 +3373,25 @@ Sony video cameras to represent a further increased dynamic range, and is described in <>. [width="60%",cols="^8,^2"] -|========== +|==== | Mapping from linear intensity to encoding | OETF -| Mapping from encoding to linear intensity | OETF^ -1^ -|========== +| Mapping from encoding to linear intensity | OETF^{nbsp}-1^ +|==== -==== *++KHR_DF_TRANSFER_BT1886++* (= 7) ==== +==== *++KHR_DF_TRANSFER_BT1886++* (= 7) -This value represents the nonlinear latexmath:[$\gamma = 2.4$] +This value represents the nonlinear latexmath:[\gamma = 2.4] EOTF between encoded pixel values and linear image intensity defined in <> and described in <>. [width="70%",cols="^8,^2,^5"] -|========== -| Mapping from linear intensity to encoding | EOTF^ -1^ | latexmath:[$\{R',G',B'\} = \{R,G,B\}^{2.4}$] -| Mapping from encoding to linear intensity | EOTF | latexmath:[$\{R,G,B\} = \{R',G',B'\}^{1\over{2.4}}$] -|========== +|==== +| Mapping from linear intensity to encoding | EOTF^{nbsp}-1^ | latexmath:[\{R',G',B'\} = \{R,G,B\}^{2.4}] +| Mapping from encoding to linear intensity | EOTF | latexmath:[\{R,G,B\} = \{R',G',B'\}^{1\over{2.4}}] +|==== <<< -==== *++KHR_DF_TRANSFER_HLG_OETF++* (= 8) ==== +==== *++KHR_DF_TRANSFER_HLG_OETF++* (= 8) This value represents the Hybrid Log Gamma OETF between linear scene light intensity and nonlinear pixel values, defined by the @@ -3403,12 +3399,12 @@ ITU in BT.2100 for high dynamic range television, and described in <>. [width="60%",cols="^8,^2,^3"] -|========== +|==== | Mapping from linear intensity to encoding | OETF | <> -| Mapping from encoding to linear intensity | OETF^ -1^ | <> -|========== +| Mapping from encoding to linear intensity | OETF^{nbsp}-1^ | <> +|==== -==== *++KHR_DF_TRANSFER_HLG_EOTF++* (= 9) ==== +==== *++KHR_DF_TRANSFER_HLG_EOTF++* (= 9) This value represents the Hybrid Log Gamma EOTF between nonlinear pixel values and linear image light intensity, defined by the ITU @@ -3416,12 +3412,12 @@ in BT.2100 for high dynamic range television, and described in <>. [width="60%",cols="^8,^2,^3"] -|========== -| Mapping from linear intensity to encoding | EOTF^ -1^ | <> +|==== +| Mapping from linear intensity to encoding | EOTF^{nbsp}-1^ | <> | Mapping from encoding to linear intensity | EOTF | <> -|========== +|==== -==== *++KHR_DF_TRANSFER_PQ_EOTF++* (= 10) ==== +==== *++KHR_DF_TRANSFER_PQ_EOTF++* (= 10) This value represents the Perceptual Quantization EOTF between nonlinear pixel values and linear image light intensity, defined @@ -3429,12 +3425,12 @@ by the ITU in BT.2100 for high dynamic range television, and described in <>. [width="60%",cols="^8,^2,^3"] -|========== -| Mapping from linear intensity to encoding | EOTF^ -1^ | <> +|==== +| Mapping from linear intensity to encoding | EOTF^{nbsp}-1^ | <> | Mapping from encoding to linear intensity | EOTF | <> -|========== +|==== -==== *++KHR_DF_TRANSFER_PQ_OETF++* (= 11) ==== +==== *++KHR_DF_TRANSFER_PQ_OETF++* (= 11) This value represents the Perceptual Quantization OETF between linear scene light intensity and nonlinear pixel values, defined @@ -3442,61 +3438,61 @@ by the ITU in BT.2100 for high dynamic range television, and described in <>. [width="60%",cols="^8,^2,^3"] -|========== +|==== | Mapping from linear intensity to encoding | OETF | <> -| Mapping from encoding to linear intensity | OETF^ -1^ | <> -|========== +| Mapping from encoding to linear intensity | OETF^{nbsp}-1^ | <> +|==== -==== *++KHR_DF_TRANSFER_DCIP3++* (= 12) ==== +==== *++KHR_DF_TRANSFER_DCIP3++* (= 12) This value represents the transfer function between nonlinear pixel values and linear image light intensity defined in DCI P3 and described in <>. [width="60%",cols="^8,^2"] -|========== -| Mapping from linear intensity to encoding | EOTF^ -1^ +|==== +| Mapping from linear intensity to encoding | EOTF^{nbsp}-1^ | Mapping from encoding to linear intensity | EOTF -|========== +|==== <<< -==== *++KHR_DF_TRANSFER_PAL_OETF++* (= 13) ==== +==== *++KHR_DF_TRANSFER_PAL_OETF++* (= 13) This value represents the OETF between linear scene light intensity and nonlinear pixel values for legacy PAL systems described in <>. [width="60%",cols="^8,^2"] -|========== +|==== | Mapping from linear intensity to encoding | OETF -| Mapping from encoding to linear intensity | OETF^ -1^ -|========== +| Mapping from encoding to linear intensity | OETF^{nbsp}-1^ +|==== -==== *++KHR_DF_TRANSFER_PAL625_EOTF++* (= 14) ==== +==== *++KHR_DF_TRANSFER_PAL625_EOTF++* (= 14) This value represents the EOTF between nonlinear pixel values and linear image light intensity for legacy 625-line PAL systems described in <>. [width="60%",cols="^8,^2"] -|========== -| Mapping from linear intensity to encoding | EOTF^ -1^ +|==== +| Mapping from linear intensity to encoding | EOTF^{nbsp}-1^ | Mapping from encoding to linear intensity | EOTF -|========== +|==== -==== *++KHR_DF_TRANSFER_ST240++* (= 15) ==== +==== *++KHR_DF_TRANSFER_ST240++* (= 15) This value represents the transfer function between linear scene light intensity and nonlinear pixel values associated with the legacy ST-240 (SMPTE240M) standard, described in <>. [width="60%",cols="^8,^4"] -|========== -| Mapping from linear intensity to encoding | EOTF^ -1^ / OETF -| Mapping from encoding to linear intensity | EOTF / OETF^ -1^ -|========== +|==== +| Mapping from linear intensity to encoding | EOTF^{nbsp}-1^ / OETF +| Mapping from encoding to linear intensity | EOTF / OETF^{nbsp}-1^ +|==== -==== *++KHR_DF_TRANSFER_ACESCC++* (= 16) ==== +==== *++KHR_DF_TRANSFER_ACESCC++* (= 16) This value represents the nonlinear transfer function between linear scene light intensity and nonlinear pixel values used in @@ -3505,12 +3501,12 @@ for use within Color Grading Systems, S-2014-003, defined in <>. This is described in <>. [width="60%",cols="^8,^2"] -|========== +|==== | Mapping from linear intensity to encoding | OETF -| Mapping from encoding to linear intensity | OETF^ -1^ -|========== +| Mapping from encoding to linear intensity | OETF^{nbsp}-1^ +|==== -==== *++KHR_DF_TRANSFER_ACESCCT++* (= 17) ==== +==== *++KHR_DF_TRANSFER_ACESCCT++* (= 17) This value represents the nonlinear transfer function between linear scene light intensity and nonlinear pixel values used in @@ -3519,18 +3515,18 @@ system for use within Color Grading Systems, S-2016-001, defined in <>. This is described in <>. [width="60%",cols="^8,^2"] -|========== +|==== | Mapping from linear intensity to encoding | OETF -| Mapping from encoding to linear intensity | OETF^ -1^ -|========== +| Mapping from encoding to linear intensity | OETF^{nbsp}-1^ +|==== -==== *++KHR_DF_TRANSFER_ADOBERGB++* (= 18) ==== +==== *++KHR_DF_TRANSFER_ADOBERGB++* (= 18) This value represents the transfer function defined in the Adobe RGB (1998) specification and described in <>. <<< -=== *_flags_* === +=== *_flags_* The format supports some configuration options in the form of boolean flags; these are described in the enumeration @@ -3538,17 +3534,17 @@ boolean flags; these are described in the enumeration .Field location information for *_flags_* [cols="7,10,2"] -|================== +|==== ^| Word offset into basic descriptor block ^| *++KHR_DF_WORD_FLAGS++* ^| 2 ^| Word offset into descriptor ^| *++KHR_DF_WORD_FLAGS++* {plus} 1 ^| 3 ^| Start bit within word ^| *++KHR_DF_SHIFT_FLAGS++* ^| 24 ^| Bit mask of value ^| *++KHR_DF_MASK_FLAGS++* ^| 0xFF -|================== +|==== *++khr_df_flags_e++* *_flags_* = *++KHR_DF_MASK_FLAGS++* & (++bdb++[*++KHR_DF_WORD_FLAGS++*] >> *++KHR_DF_SHIFT_FLAGS++*); -==== *++KHR_DF_FLAG_ALPHA_PREMULTIPLIED++* (= 1) ==== +==== *++KHR_DF_FLAG_ALPHA_PREMULTIPLIED++* (= 1) If the *++KHR_DF_FLAG_ALPHA_PREMULTIPLIED++* bit is set, any color information in the data should be interpreted as having been @@ -3563,7 +3559,7 @@ This flag has no effect if there is no alpha channel in the format. <<< -=== *_texelBlockDimension[0..3]_* === +=== *_texelBlockDimension[0..3]_* The *_texelBlockDimension_* fields define an integer bound on the range of coordinates covered by the repeating block described by the samples; @@ -3586,23 +3582,23 @@ should have a size of 1 in each dimension that it lacks, and therefore the corresponding fields in the representation should be 0. -For example, a _Y′C~B~C~R~_ 4:2:0 representation may use a Texel Block +For example, a _Y{prime}C~B~C~R~_ 4:2:0 representation may use a Texel Block of 2×2 pixels in the nominal coordinate space, corresponding to -the four _Y′_ samples, as shown in <>. +the four _Y{prime}_ samples, as shown in <>. The texel block dimensions in this case would be 2×2×1×1 (in the X, Y, Z and T dimensions, if the fourth dimension is interpreted as T). The *_texelBlockDimension[0..3]_* values would therefore be: [[YUV420Basic]] -.Example Basic Data Format *_texelBlockDimension_* values for _Y′C~B~C~R~_ 4:2:0 +.Example Basic Data Format *_texelBlockDimension_* values for _Y{prime}C~B~C~R~_ 4:2:0 [width="40%",cols="5,1"] -|================================ +|==== ^| *_texelBlockDimension0_* ^| 1 ^| *_texelBlockDimension1_* ^| 1 ^| *_texelBlockDimension2_* ^| 0 ^| *_texelBlockDimension3_* ^| 0 -|================================ +|==== In the descriptor block examples in this specification, block dimensions larger than 1 (encoded as 0) are shown as the value to be stored in the @@ -3611,7 +3607,7 @@ for clarity. .Field location information for *_texelBlockDimension[0..3]_* [cols="7,10,2"] -|================== +|==== ^| Word offset into basic descriptor block ^| *++KHR_DF_WORD_TEXELBLOCKDIMENSION[0..3]++* ^| 3 ^| Word offset into descriptor ^| *++KHR_DF_WORD_TEXELBLOCKDIMENSION[0..3]++* {plus} 1 ^| 4 1.4+^.^| Start bit within word ^| *++KHR_DF_SHIFT_TEXELBLOCKDIMENSION0++* ^| 0 @@ -3619,7 +3615,7 @@ for clarity. ^| *++KHR_DF_SHIFT_TEXELBLOCKDIMENSION2++* ^| 16 ^| *++KHR_DF_SHIFT_TEXELBLOCKDIMENSION3++* ^| 24 ^| Bit mask of value ^| *++KHR_DF_MASK_TEXELBLOCKDIMENSION[0..3]++* ^| 0xFF -|================== +|==== *++uint32_t++* *_texelBlockDimension0_* = *++KHR_DF_MASK_TEXELBLOCKDIMENSION0++* & + (++bdb++[*++KHR_DF_WORD_TEXELBLOCKDIMENSION0++*] >> *++KHR_DF_SHIFT_TEXELBLOCKDIMENSION0++*); @@ -3634,15 +3630,15 @@ for clarity. (++bdb++[*++KHR_DF_WORD_TEXELBLOCKDIMENSION3++*] >> *++KHR_DF_SHIFT_TEXELBLOCKDIMENSION3++*); <<< -=== *_bytesPlane[0..7]_* === +=== *_bytesPlane[0..7]_* The Basic Data Format Descriptor divides the image into a number of planes, each consisting of an integer number of consecutive bytes. The requirement that planes consist of consecutive data means that -formats with distinct subsampled channels -- such as _Y′C~B~C~R~_ +formats with distinct subsampled channels -- such as _Y{prime}C~B~C~R~_ 4:2:0 -- may require multiple planes to describe a channel. -A typical _Y′C~B~C~R~_ 4:2:0 image has _two_ planes for the -_Y′_ channel in this representation, offset by one line vertically. +A typical _Y{prime}C~B~C~R~_ 4:2:0 image has _two_ planes for the +_Y{prime}_ channel in this representation, offset by one line vertically. The use of byte granularity to define planes is a choice to allow large texel blocks. @@ -3666,8 +3662,8 @@ the first plane holds 0x40 {plus} 128 {times} 0x02 = 0x140 bytes; *_bytesPlane2_* then describes the number of bytes in the second plane.. Since only sixteen bits are used to encode a bit offset for each sample, 14 bits (two bytes excluding the top bits) are sufficient to encode any -useful number of bytes -- there is no need to ``extend'' the higher byte. -Few formats are expected to require this ``extension bit'', so for +useful number of bytes -- there is no need to "`extend`" the higher byte. +Few formats are expected to require this "`extension bit`", so for most of this specification, the number of bytes in a plane is considered to be synonymous with the *_bytesPlane_* value. @@ -3679,7 +3675,7 @@ no *_bytesPlane_* value is zero, 8 planes are considered to exist. .Field location information for *_bytesPlane[0..7]_* [cols="7,10,2"] -|================== +|==== 1.2+^.^| Word offset into basic descriptor block ^| *++KHR_DF_WORD_BYTESPLANE[0..3]++* ^| 4 ^| *++KHR_DF_WORD_BYTESPLANE[4..7]++* ^| 5 1.2+^.^| Word offset into descriptor ^| *++KHR_DF_WORD_BYTESPLANE[0..3]++* {plus} 1 ^| 5 @@ -3693,19 +3689,20 @@ no *_bytesPlane_* value is zero, 8 planes are considered to exist. ^| *++KHR_DF_SHIFT_BYTESPLANE6++* ^| 16 ^| *++KHR_DF_SHIFT_BYTESPLANE7++* ^| 24 ^| Bit mask of value ^| *++KHR_DF_MASK_BYTESPLANE[0..7]++* ^| 0xFF -|================== +|==== *++uint32_t++* *_bytesPlane[0..7]_* = *++KHR_DF_MASK_BYTESPLANE[0..7]++* & + (++bdb++[*++KHR_DF_WORD_BYTESPLANE[0..7]++*] >> *++KHR_DF_SHIFT_BYTESPLANE[0..7]++*); NOTE: In versions of this specification prior to 1.3, there was no -facility for the ``extension bit'', and a *_bytesPlane0_* value of +facility for the "`extension bit`", and a *_bytesPlane0_* value of 0 indicated a paletted format. The scheme for encoding paletted formats as of version 1.3 is described in <>. <<< -=== [[sample]]Sample information === +[[sample]] +=== Sample information The layout and position of the information within each plane is determined by a number of _samples_, each consisting of a single @@ -3715,25 +3712,25 @@ the texel block, as shown in <>. [[SampleOverview]] .Basic Data Format Descriptor Sample Information [width="98%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ ^| *_F_* ^| *_S_* ^| *_E_* ^| *_L_* 4+^| *_channelType_* 8+^| *_bitLength_* 16+^| *_bitOffset_* 8+^| *_samplePosition3_* 8+^| *_samplePosition2_* 8+^| *_samplePosition1_* 8+^| *_samplePosition0_* 32+^| *_sampleLower_* 32+^| *_sampleUpper_* -|================================ +|==== Bits *_F_*, *_S_*, *_E_* and *_L_* are abbreviations for the following qualifier flags: [cols="1,5,1",width="65%"] -|================================ +|==== ^| *_F_* ^| *++KHR_DF_SAMPLE_DATATYPE_FLOAT++* ^| 0x80 ^| *_S_* ^| *++KHR_DF_SAMPLE_DATATYPE_SIGNED++* ^| 0x40 ^| *_E_* ^| *++KHR_DF_SAMPLE_DATATYPE_EXPONENT++* ^| 0x20 ^| *_L_* ^| *++KHR_DF_SAMPLE_DATATYPE_LINEAR++* ^| 0x10 -|================================ +|==== The sample information begins at word *++KHR_DF_WORD_SAMPLESTART++* = 6, offset from the start of the basic descriptor block. @@ -3794,11 +3791,11 @@ sample fields: .Field location information for sample field *_xxx_* [cols="7,10,2"] -|================== +|==== ^| Word offset relative to start of sample ^| *++KHR_DF_SAMPLEWORD_xxx++* {plus} 1 ^| ... ^| Start bit within word ^| *++KHR_DF_SAMPLESHIFT_xxx++* ^| ... ^| Bit mask of value ^| *++KHR_DF_SAMPLEMASK_xxx++* ^| ... -|================== +|==== If the basic descriptor block is treated as a *++uint32_t++* array ++bdb[]++, sample field *_xxx_* can be accessed as follows: @@ -3817,7 +3814,7 @@ For example, *++KHR_DFDSVAL++*(++bdb++, 2, *++CHANNELID++*) returns the value: {plus} *++KHR_DF_SAMPLEWORD_CHANNELID++*] >> *++KHR_DF_SAMPLESHIFT_CHANNELID++*) <<< -=== Sample *_bitOffset_* === +=== Sample *_bitOffset_* The *_bitOffset_* field describes the offset of the least significant bit of this sample from the least significant bit of the least @@ -3834,17 +3831,17 @@ This mechanism notably supports values that are zero-extended. .Field location information for sample *_bitOffset_* [cols="7,10,2"] -|================== +|==== ^| Word offset relative to start of sample ^| *++KHR_DF_SAMPLEWORD_BITOFFSET++* ^| 0 ^| Start bit within word ^| *++KHR_DF_SAMPLESHIFT_BITOFFSET++* ^| 0 ^| Bit mask of value ^| *++KHR_DF_SAMPLEMASK_BITOFFSET++* ^| 0xFFFFU -|================== +|==== *++uint32_t++* *_bitoffset_* = *++KHR_DF_SAMPLEMASK_BITOFFSET++* & + ((++bdb++[*++KHR_DF_WORD_SAMPLESTART++* {plus} (_sample_ {times} *++KHR_DF_WORD_SAMPLEWORDS++*) + {plus} *++KHR_DF_SAMPLEWORD_BITOFFSET++*]) >> *++KHR_DF_SAMPLESHIFT_BITOFFSET++*); -=== Sample *_bitLength_* === +=== Sample *_bitLength_* The *_bitLength_* field describes the number of consecutive bits from the concatenated bit stream that contribute to the sample. This field @@ -3877,18 +3874,18 @@ represented number (without the -1 offset) in parentheses for clarity. .Field location information for sample *_bitLength_* [cols="7,10,2"] -|================== +|==== ^| Word offset relative to start of sample ^| *++KHR_DF_SAMPLEWORD_BITLENGTH++* ^| 0 ^| Start bit within word ^| *++KHR_DF_SAMPLESHIFT_BITLENGTH++* ^| 16 ^| Bit mask of value ^| *++KHR_DF_SAMPLEMASK_BITLENGTH++* ^| 0xFF -|================== +|==== *++uint32_t++* *_bitLength_* = *++KHR_DF_SAMPLEMASK_BITLENGTH++* & + ((++bdb++[*++KHR_DF_WORD_SAMPLESTART++* {plus} (_sample_ {times} *++KHR_DF_WORD_SAMPLEWORDS++*) + {plus} *++KHR_DF_SAMPLEWORD_BITLENGTH++*]) >> *++KHR_DF_SAMPLESHIFT_BITLENGTH++*); <<< -=== Sample *_channelType_* and qualifiers === +=== Sample *_channelType_* and qualifiers The *_channelType_* field is an unsigned 8-bit quantity. @@ -3901,11 +3898,11 @@ for each model. .Field location information for sample *_channelType_* [cols="7,10,2"] -|================== +|==== ^| Word offset relative to start of sample ^| *++KHR_DF_SAMPLEWORD_CHANNELID++* ^| 0 ^| Start bit within word ^| *++KHR_DF_SAMPLESHIFT_CHANNELID++* ^| 24 ^| Bit mask of value ^| *++KHR_DF_SAMPLEMASK_CHANNELID++* ^| 0xF -|================== +|==== *++khr_df_model_channels_e++* *_channelType_* = *++KHR_DF_SAMPLEMASK_CHANNELID++* & + ((++bdb++[*++KHR_DF_WORD_SAMPLESTART++* {plus} (_sample_ {times} *++KHR_DF_WORD_SAMPLEWORDS++*) + @@ -3916,11 +3913,11 @@ The top four bits of the *_channelType_* are described by the .Field location information for sample *_qualifiers_* [cols="7,10,2"] -|================== +|==== ^| Word offset relative to start of sample ^| *++KHR_DF_SAMPLEWORD_QUALIFIERS++* ^| 0 ^| Start bit within word ^| *++KHR_DF_SAMPLESHIFT_QUALIFIERS++* ^| 24 ^| Bit mask of value ^| *++KHR_DF_SAMPLEMASK_QUALIFIERS++* ^| 0xF0 -|================== +|==== *++khr_df_sample_datatype_qualifiers_e++* *_qualifiers_* = *++KHR_DF_SAMPLEMASK_QUALIFIERS++* & + ((++bdb++[*++KHR_DF_WORD_SAMPLESTART++* {plus} (_sample_ {times} *++KHR_DF_WORD_SAMPLEWORDS++*) + @@ -3955,7 +3952,7 @@ For samples in which the *++KHR_DF_SAMPLE_DATATYPE_EXPONENT++* bit is not set: * If the *++KHR_DF_SAMPLE_DATATYPE_FLOAT++* bit, shown as *_F_* in <>, is set, the sample holds floating point data in a conventional format of 10, 11 or 16 bits, as described in <>, - or of 32, or 64 bits as described in <>. + or of 32, or 64 bits as described in <>. Unless a genuine unsigned format is intended, *++KHR_DF_SAMPLE_DATATYPE_SIGNED++* (bit *_S_*) should also be set. Less common floating point representations can be generated with @@ -3989,13 +3986,13 @@ channel, as shown in <>. [[exponentqualifiers]] .Qualifier interpretation when *++KHR_DF_SAMPLE_DATATYPE_EXPONENT++* = 1 [cols="^1,^1,^1,4,^5", width="50%"] -|=========== -| *_E_* | *_L_* | *_F_* |  *Interpretation* | *Formula* -| 1 | 0 | 0 |  Exponent | latexmath:[$\mathit{base\ value}\times 2^\mathit{modifier}$] -| 1 | 0 | 1 |  Multiplier | latexmath:[$\mathit{base\ value}\times\mathit{modifier}$] -| 1 | 1 | 0 |  Divisor | latexmath:[$\mathit{base\ value}\over\mathit{modifier}$] -| 1 | 1 | 1 |  Power | latexmath:[$\mathit{base\ value}^\mathit{modifier}$] -|=========== +|==== +| *_E_* | *_L_* | *_F_* |{nbsp} *Interpretation* | *Formula* +| 1 | 0 | 0 |{nbsp} Exponent | latexmath:[\mathit{base\ value}\times 2^\mathit{modifier}] +| 1 | 0 | 1 |{nbsp} Multiplier | latexmath:[\mathit{base\ value}\times\mathit{modifier}] +| 1 | 1 | 0 |{nbsp} Divisor | latexmath:[\mathit{base\ value}\over\mathit{modifier}] +| 1 | 1 | 1 |{nbsp} Power | latexmath:[\mathit{base\ value}^\mathit{modifier}] +|==== For samples in which the *++KHR_DF_SAMPLE_DATATYPE_EXPONENT++* bit is set: @@ -4048,7 +4045,7 @@ to be represented in fixed-point terms, and the values may be signed depending on whether the *_S_* bit is set. <<< -=== *_samplePosition[0..3]_* === +=== *_samplePosition[0..3]_* The sample has an associated location within the 4-dimensional space of the texel block. @@ -4057,14 +4054,14 @@ of the texel block, represented as an 8-bit unsigned integer quantity. .Field location information for sample *_samplePosition[0..3]_* [cols="7,10,2"] -|================== +|==== ^| Word offset relative to start of sample ^| *++KHR_DF_SAMPLEWORD_SAMPLEPOSITION[0..3]++* ^| 1 1.4+^.^| Start bit within word ^| *++KHR_DF_SAMPLESHIFT_SAMPLEPOSITION0++* ^| 0 ^| *++KHR_DF_SAMPLESHIFT_SAMPLEPOSITION1++* ^| 8 ^| *++KHR_DF_SAMPLESHIFT_SAMPLEPOSITION2++* ^| 16 ^| *++KHR_DF_SAMPLESHIFT_SAMPLEPOSITION3++* ^| 24 ^| Bit mask of value ^| *++KHR_DF_SAMPLEMASK_SAMPLEPOSITION[0..3]++* ^| 0xF -|================== +|==== *++khr_df_model_channels_e++* *_samplePosition0_* = *++KHR_DF_SAMPLEMASK_SAMPLEPOSITION0++* & + ((++bdb++[*++KHR_DF_WORD_SAMPLESTART++* {plus} (_sample_ {times} *++KHR_DF_WORD_SAMPLEWORDS++*) + @@ -4085,36 +4082,24 @@ of the texel block, represented as an 8-bit unsigned integer quantity. The interpretation of each *_samplePosition_* field depends on the corresponding *_texelBlockDimension_* value as follows: -ifdef::a2xhtml[] -// N.B. HTML math output doesn't support bold italics -[latexmath] -++++++ -\begin{align*} -n &= \left\lceil\textrm{log}_2(\textbf{texelBlockDimension} + 1)\right\rceil \\ -\textit{coordinateOffset} &= \textbf{samplePosition} \times 2^{n - 8} -\end{align*} -++++++ -endif::[] -ifndef::a2xhtml[] [latexmath] -++++++ +++++ \begin{align*} n &= \left\lceil\textrm{log}_2(\textbf{\textit{texelBlockDimension}} + 1)\right\rceil \\ \textit{coordinateOffset} &= \textbf{\textit{samplePosition}} \times 2^{n - 8} \end{align*} -++++++ -endif::[] +++++ For example, if *_texelBlockDimension0_* is 1 (indicating a texel block width of two units) *_samplePosition0_* is described in units of -latexmath:[${2\over 256} = {1\over 128}$]. -That is, a *_samplePosition0_* of 128 would encode an offset of ``1.0'' -and a *_samplePosition0_* of 64 would encode an offset of ``0.5''. +latexmath:[{2\over 256} = {1\over 128}]. +That is, a *_samplePosition0_* of 128 would encode an offset of "`1.0`" +and a *_samplePosition0_* of 64 would encode an offset of "`0.5`". If *_texelBlockDimension0_* is 5 (indicating a texel block width of six units), *_samplePosition0_* is described in units of -latexmath:[${8\over 256} = {1\over 32}$]. -That is, a *_samplePosition0_* of 64 would encode an offset of ``2.0'' -and a *_samplePosition0_* of 24 would encode an offset of ``0.75''. +latexmath:[{8\over 256} = {1\over 32}]. +That is, a *_samplePosition0_* of 64 would encode an offset of "`2.0`" +and a *_samplePosition0_* of 24 would encode an offset of "`0.75`". The adjusted _coordinateOffset_ must be less than the corresponding texel block dimension. @@ -4138,10 +4123,10 @@ NOTE: Versions of this specification prior to 1.3 always recorded the sample position in a 7.1 fixed-point format (with half-coordinate granularity). This change does not affect the representation of single-coordinate texel -blocks; that is, a *_samplePosition_* of ``0'' still represents ``0.0''. +blocks; that is, a *_samplePosition_* of "`0`" still represents "`0.0`". <<< -=== *_sampleLower_* and *_sampleUpper_* === +=== *_sampleLower_* and *_sampleUpper_* The *_sampleLower_* and *_sampleUpper_* fields are used to define the mapping between the numerical value stored in the format and the @@ -4149,43 +4134,30 @@ conceptual numerical interpretation. For unsigned formats, *_sampleLower_* typically represents the value which should be interpreted as zero (the black point). -For signed formats, *_sampleLower_* typically represents ``-1''. -For color difference models such as _Y′C~B~C~R~_, *_sampleLower_* +For signed formats, *_sampleLower_* typically represents "`-1`". +For color difference models such as _Y{prime}C~B~C~R~_, *_sampleLower_* for chroma channels represents the lower extent of the color difference range (which corresponds to an encoding of -0.5 in numerical terms). *_sampleUpper_* typically represents the value which should be interpreted -as ``1.0'' (the ``white point''). -For color difference models such as _Y′C~B~C~R~_, *_sampleUpper_* +as "`1.0`" (the "`white point`"). +For color difference models such as _Y{prime}C~B~C~R~_, *_sampleUpper_* for chroma channels represents the upper extent of the color difference range (which corresponds to an encoding of 0.5 in numerical terms). [[sampleRangeConversion]] .Sample range conversion rules -ifdef::a2xhtml[] -// N.B. HTML math output doesn't support bold italics -[latexmath] -++++++ -\begin{align*} -\textit{out}_\textit{unsigned} &= \left({{\textit{value} - \textbf{sampleLower}}\over{\textbf{sampleUpper} - \textbf{sampleLower}}}\right) \\ -\textit{out}_\textit{signed} &= \left({{\textit{value} - \textbf{sampleLower}}\over{\textbf{sampleUpper} - \textbf{sampleLower}}} - 0.5\right) \times 2 \\ -\textit{out}_\textit{color difference} &= \left({{\textit{value} - \textbf{sampleLower}}\over{\textbf{sampleUpper} - \textbf{sampleLower}}} - 0.5\right) -\end{align*} -++++++ -endif::[] -ifndef::a2xhtml[] [latexmath] -++++++ +++++ \begin{align*} \textit{out}_\textit{unsigned} &= \left({{\textit{value} - \textbf{\textit{sampleLower}}}\over{\textbf{\textit{sampleUpper}} - \textbf{\textit{sampleLower}}}}\right) \\ \textit{out}_\textit{signed} &= \left({{\textit{value} - \textbf{\textit{sampleLower}}}\over{\textbf{\textit{sampleUpper}} - \textbf{\textit{sampleLower}}}} - 0.5\right) \times 2 \\ \textit{out}_\textit{color difference} &= \left({{\textit{value} - \textbf{\textit{sampleLower}}}\over{\textbf{\textit{sampleUpper}} - \textbf{\textit{sampleLower}}}} - 0.5\right) \end{align*} -++++++ -endif::[] +++++ For example, the BT.709 television broadcast standard dictates that -the _Y′_ value stored in an 8-bit encoding should fall between +the _Y{prime}_ value stored in an 8-bit encoding should fall between the range 16 and 235, as described in <>. In this case, *_sampleLower_* should contain the value 16 and *_sampleUpper_* 235. @@ -4199,12 +4171,12 @@ of the captured image. There is no guarantee or expectation that image data be guaranteed to fall between *_sampleLower_* and *_sampleUpper_* unless the users of a format agree that convention. -For example, high dynamic range video formats may define ``1.0'' as a +For example, high dynamic range video formats may define "`1.0`" as a nominal brightness level substantially lower than the maximum, and coordinates may encode an arbitrary range. In some formats, the integer value should be interpreted directly as a number, in which case *_sampleUpper_* and *_sampleLower_* should -hold ``1'' and either ``0'' or ``-1'' depending on whether the format +hold "`1`" and either "`0`" or "`-1`" depending on whether the format is signed, respectively. If the channel encoding is an integer format, the *_sampleLower_* and @@ -4269,29 +4241,29 @@ See <> for more detail on this. If the channel encoding is the mantissa of a custom floating point format (that is, the encoding is integer but the same sample location and channel is shared by a sample that encodes an exponent), the -presence of an implicit ``1'' digit can be represented by setting the +presence of an implicit "`1`" digit can be represented by setting the *_sampleUpper_* value to a value one larger than can be encoded in the available bits for the mantissa, as described in <>. -In OpenGL terminology, a ``normalized'' channel contains an integer value +In OpenGL terminology, a "`normalized`" channel contains an integer value which is mapped to the range 0..1.0; a channel which is not normalized contains an integer value which is mapped to a floating point equivalent of the integer value. -Similarly an ``snorm'' channel is a signed normalized value mapping from +Similarly an "`snorm`" channel is a signed normalized value mapping from -1.0 to 1.0. Setting *_sampleLower_* to the minimum signed integer value representable in the channel (which is often the negative version of the maximum signed integer, for example -127 rather than -128 for an 8-bit value in order to allow the value 0.0 to be represented exactly) is equivalent to defining -an ``snorm'' texture. +an "`snorm`" texture. Setting *_sampleUpper_* to the maximum signed integer value representable in the channel for a signed channel type is equivalent to defining an -``snorm'' texture. +"`snorm`" texture. Setting *_sampleUpper_* to the maximum unsigned value representable in the channel for an unsigned channel type is equivalent to defining a -``normalized'' texture. -Setting *_sampleUpper_* to ``1'' is equivalent to defining an -``unnormalized'' texture. +"`normalized`" texture. +Setting *_sampleUpper_* to "`1`" is equivalent to defining an +"`unnormalized`" texture. In the special case that the sample *_bitOffset_* field is 0xFFFF, only the bottom 16 bits of the *_sampleLower_* field indicate a contribution to @@ -4303,10 +4275,10 @@ to eight bits before conversion may have four bits with the value 0 stored in bits 19..16 of *_sampleLower_*, indicated by a *_bitOffset_* of 0xFFFF. -These ``virtual bits'' may be needed to encode some numerical +These "`virtual bits`" may be needed to encode some numerical representations. -For example, if an 8-bit integer encodes the value ``-0.5'' as 0 -and ``0.5'' as 255 (in the manner of the color difference channel +For example, if an 8-bit integer encodes the value "`-0.5`" as 0 +and "`0.5`" as 255 (in the manner of the color difference channel in <>, but if we wish to apply this mapping to a channel other than color difference), <> suggests that *_sampleLower_* should hold -127.5 and *_sampleUpper_* @@ -4331,7 +4303,7 @@ map to the -0.5..0.5 range are treated specially. === Paletted formats The storage of the palette is considered to be outside the remit of this -specification; however, the ``format'' describes both the encoding of +specification; however, the "`format`" describes both the encoding of the bits which index into the palette and the format of the entries in the palette itself. @@ -4416,7 +4388,8 @@ In the interests of portability, the following summary (which assumes that bitfields are encoded starting at bit 0) is therefore provided for information, but is not canonical: ------ +[source] +---- typedef struct _DFDSampleType { uint32_t bitOffset: 16; uint32_t bitLength: 8; @@ -4450,9 +4423,9 @@ typedef struct _BasicDataFormatDescriptor { uint32_t bytesPlane7: 8; DFDSampleType samples[]; } BasicDataFormatDescriptor; ------ +---- -== Extension for more complex formats == +== Extension for more complex formats Some formats will require more channels than can be described in the Basic Format Descriptor, or may have more specific color requirements. For example, @@ -4486,7 +4459,7 @@ If bit 14, *++KHR_DF_KHR_DESCRIPTORTYPE_NEEDED_FOR_DECODE_BIT++*, of the understand the extension in order to decode the contents of the texel coherently. If this bit is clear, the data held in the extension can be considered to be -``informative'' and that ignoring the extension will still result in correct +"`informative`" and that ignoring the extension will still result in correct values to the extent specified by the basic descriptor block. For example, an extension may associate an absolute brightness level with a format, but software which does not have need of this concept can continue @@ -4495,7 +4468,7 @@ processing the texel contents correctly. <<< As an example of the description of an extension, consider a single-channel 32-bit depth buffer, as shown in <>. -A tiled renderer may wish to indicate that this buffer is ``virtual'': it +A tiled renderer may wish to indicate that this buffer is "`virtual`": it will be allocated real memory only if needed, and will otherwise exist only a subset at a time in an on-chip representation. Someone developing such a renderer may choose to add a vendor-specific @@ -4524,7 +4497,7 @@ form of allocation while reading texel values. [[DepthExtensionExample]] .Example of a depth buffer with an extension to indicate a virtual allocation [width="97%"] -|============= +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 56 -- total size of the two blocks plus one 32-bit value @@ -4538,7 +4511,7 @@ form of allocation while reading texel values. 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 4 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for depth~ -^| 1 ^| 1 ^| 0 ^| 0 4+^| *++DEPTH++* 8+^| *_bitLength:_* 31 (= ``32'') 16+^| *_bitOffset:_* 0 +^| 1 ^| 1 ^| 0 ^| 0 4+^| *++DEPTH++* 8+^| *_bitLength:_* 31 (= "`32`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0xBF800000U -- -1.0f @@ -4547,18 +4520,18 @@ form of allocation while reading texel values. 15+^| *_descriptorType:_* 0 17+^| *_vendorId:_* 0x1FFFF 16+^| *_descriptorBlockSize:_* 8 + (4 {times} 1) = 12 16+^| *_versionNumber:_* 0 32+^| ~Data specific to the extension follows~ -32+^| 1 -- buffer is ``virtual'' -|============= +32+^| 1 -- buffer is "`virtual`" +|==== It is possible for a vendor to use the extension block to store peripheral information required to access the image -- plane base addresses, stride, etc. Since different implementations have different kinds of non-linear ordering and proprietary alignment requirements, this is not described as part of the standard. By many conventional definitions, this information is not part of -the ``format'', and particularly it ensures that an identical copy of the image +the "`format`", and particularly it ensures that an identical copy of the image will have a different descriptor block (because the addresses will have changed) and so a simple bitwise comparison of two descriptor blocks will disagree even -though the ``format'' matches. Additionally, many APIs will use the format +though the "`format`" matches. Additionally, many APIs will use the format descriptor only for external communication, and have an internal representation that is more concise and less flexible. In this case, it is likely that address information will need to be represented separately from the format anyway. For @@ -4581,7 +4554,7 @@ describes additional planes. [[AdditionalPlanes]] .Additional planes descriptor block [width="97%"] -|============= +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 15+^| *_descriptorType:_* 0x6001 17+^| *_vendorId:_* 0 @@ -4589,7 +4562,7 @@ describes additional planes. 32+^| *_bytesPlane0_* 32+^| *_bytesPlane1_* _(optional)_ 32+^| _(etc.)_ -|============= +|==== If this descriptor block is present, the *_bytesPlane[0..7]_* fields of the basic descriptor block are ignored, and the number of bytes for plane @@ -4618,7 +4591,7 @@ cannot represent the format without extension. The basic descriptor block allows texel blocks of up to four non-trivial dimensions, and with a texel block size of up to 256 coordinate units, -with sample positions described in precision up to latexmath:[$1\over 256$] +with sample positions described in precision up to latexmath:[1\over 256] of a coordinate. Under rare circumstances, this may provide insufficient flexibility. An extension descriptor block, with *_vendorId_* = *++KHR_DF_VENDORID_KHRONOS++* @@ -4634,7 +4607,7 @@ users of the layout being described. [[AdditionalDimensions]] .Additional dimensions descriptor block [width="97%"] -|============= +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 15+^| *_descriptorType:_* 0x6002 17+^| *_vendorId:_* 0 @@ -4645,18 +4618,18 @@ users of the layout being described. 16+^| *++uint16_t++* *_sample0Pos0_* 16+^| *++uint16_t++* *_sample0Pos0Divisor_* 16+^| *++uint16_t++* *_sample0Pos1_* 16+^| *++uint16_t++* *_sample0Pos1Divisor_* 32+^| _(etc.)_ -|============= +|==== The fields *_texelBlockDimension[0..n]_* describe the size in coordinate units of the texel block in the corresponding dimension; as with the basic descriptor block, the value stored is the corresponding dimension -minus 1 (so a stored value of ``0'' corresponds to a dimension of 1). +minus 1 (so a stored value of "`0`" corresponds to a dimension of 1). The *_texelBlockDimension[0..7]_* fields of the basic descriptor block are ignored. For each sample, the *_samplePos_* and *_samplePosDivisor_* fields store a numerator and denominator pair for the coordinate -latexmath:[$\textit{offset} = {\textit{numerator}\over\textit{denominator}}$] +latexmath:[\textit{offset} = {\textit{numerator}\over\textit{denominator}}] for each dimension, with all dimensions for a sample described before describing the next sample. *_samplePos_* and *_samplePosDivisor_* should be minimized, leaving an @@ -4681,9 +4654,9 @@ This descriptor block should be used only if the Khronos Basic Descriptor Block is the first descriptor block in the data format descriptor, and cannot represent the format without extension. -== Frequently Asked Questions == +== Frequently Asked Questions -=== Why have a binary format rather than a human-readable one? === +=== Why have a binary format rather than a human-readable one? While it is not expected that every new container will have a unique data descriptor or that analysis of the data format descriptor will be @@ -4694,12 +4667,12 @@ a large number of format descriptors to be stored, and to be amenable to hardware interpretation or processing in shaders. These goals preclude a text-based representation such as an XML schema. -=== Why not use an existing representation such as those on FourCC.org? === +=== Why not use an existing representation such as those on FourCC.org? Formats in FourCC.org do not describe in detail sufficient information for many APIs, and are sometimes inconsistent. -=== Why have a descriptive format? === +=== Why have a descriptive format? Enumerations are fast and easy to process, but are limited in that any software can only be aware of the enumeration values in place when it @@ -4710,7 +4683,7 @@ for more flexible software which can support a wide range of formats without needing each to be listed, and simplifies the programming of conditional behavior based on format properties. -=== Why describe this standard within Khronos? === +=== Why describe this standard within Khronos? Khronos supports multiple standards that have a range of internal data representations. There is no requirement that this standard be used @@ -4719,7 +4692,7 @@ Khronos standards may use this specification as part of a consistent approach to inter-standard operation. <<< -=== Why should I use this descriptor if I don't need most of the fields? === +=== Why should I use this descriptor if I don't need most of the fields? While a library may not use all the data provided in the data format descriptor that is described within this standard, it is common for @@ -4727,7 +4700,7 @@ users of data -- particularly pixel-like data -- to have additional requirements. Capturing these requirements portably reduces the need for additional metadata to be associated with a proprietary descriptor. It is also common for additional functionality to be added retrospectively -to existing libraries -- for example, _Y′C~B~C~R~_ support is often an +to existing libraries -- for example, _Y{prime}C~B~C~R~_ support is often an afterthought in rendering APIs. Having a consistent and flexible representation in place from the start can reduce the pain of retrofitting this functionality. @@ -4740,7 +4713,7 @@ software outside the proprietary library and for reducing the effort needed to provide a complete, unambiguous and accurate description of a format in human-readable terms. -=== Why not expand each field out to be integer for ease of decoding? === +=== Why not expand each field out to be integer for ease of decoding? There is a trade-off between size and decoding effort. It is assumed that data which occupies the same 32-bit word may need to be tested @@ -4750,7 +4723,7 @@ it is intended that most data can be extracted with low-cost operations, typically being byte-aligned (other than sample flags) and with the natural alignment applied to multi-byte quantities. -=== Can this descriptor be used for text content? === +=== Can this descriptor be used for text content? For simple ASCII content, there is no reason that plain text could not be described in some way, and this may be useful for image formats that contain @@ -4764,13 +4737,13 @@ for this standard. :valign: center [[fpformats]] -== Floating-point formats == +== Floating-point formats Some common floating-point numeric representations are defined in -<>. Additional floating point formats are defined in this +<>. Additional floating point formats are defined in this section. -[[16bitfp]] +[[im-16bitfp]] === 16-bit floating-point numbers A 16-bit floating-point number has a 1-bit sign (_S_), a 5-bit @@ -4779,8 +4752,8 @@ The value _V_ of a 16-bit floating-point number is determined by the following: [latexmath] -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -\[ +++++ +\begin{aligned} V = \begin{cases} (-1)^S \times 0.0, & E = 0, M = 0 \\ @@ -4791,20 +4764,22 @@ V = (-1)^S \times \mathit{Inf}, & E = 31, M = 0 \\ \mathit{NaN}, & E = 31, M \neq 0 \end{cases} -\] -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +\end{aligned} +++++ If the floating-point number is interpreted as an unsigned 16-bit integer _N_, then [latexmath] -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - $$S = \left\lfloor { { N \bmod 65536 } \over 32768 } \right\rfloor$$ - $$E = \left\lfloor { { N \bmod 32768 } \over 1024 } \right\rfloor$$ - $$M = N \bmod 1024.$$ -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++ +\begin{align*} + S = \left\lfloor { { N \bmod 65536 } \over 32768 } \right\rfloor \\ + E = \left\lfloor { { N \bmod 32768 } \over 1024 } \right\rfloor \\ + M = N \bmod 1024. +\end{align*} +++++ -[[11bitfp]] +[[im-11bitfp]] === Unsigned 11-bit floating-point numbers An unsigned 11-bit floating-point number has no sign bit, a 5-bit exponent @@ -4813,8 +4788,8 @@ The value _V_ of an unsigned 11-bit floating-point number is determined by the following: [latexmath] -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -\[ +++++ +\begin{aligned} V = \begin{cases} 0.0, & E = 0, M = 0 \\ @@ -4824,19 +4799,21 @@ V = \mathit{Inf}, & E = 31, M = 0 \\ \mathit{NaN}, & E = 31, M \neq 0 \end{cases} -\] -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +\end{aligned} +++++ If the floating-point number is interpreted as an unsigned 11-bit integer _N_, then [latexmath] -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - $$E = \left\lfloor { N \over 64 } \right\rfloor$$ - $$M = N \bmod 64.$$ -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++ +\begin{align*} + E = \left\lfloor { N \over 64 } \right\rfloor \\ + M = N \bmod 64. +\end{align*} +++++ -[[10bitfp]] +[[im-10bitfp]] === Unsigned 10-bit floating-point numbers An unsigned 10-bit floating-point number has no sign bit, a 5-bit @@ -4845,8 +4822,8 @@ The value _V_ of an unsigned 10-bit floating-point number is determined by the following: [latexmath] -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -\[ +++++ +\begin{aligned} V = \begin{cases} 0.0, & E = 0, M = 0 \\ @@ -4856,17 +4833,19 @@ V = \mathit{Inf}, & E = 31, M = 0 \\ \mathit{NaN}, & E = 31, M \neq 0 \end{cases} -\] -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +\end{aligned} +++++ If the floating-point number is interpreted as an unsigned 10-bit integer _N_, then [latexmath] -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - $$E = \left\lfloor { N \over 32 } \right\rfloor$$ - $$M = N \bmod 32.$$ -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++ +\begin{align*} + E = \left\lfloor { N \over 32 } \right\rfloor \\ + M = N \bmod 32. +\end{align*} +++++ [[customfp]] === Non-standard floating point formats @@ -4878,7 +4857,7 @@ data, as follows. Note that non-standard floating point formats do not use the *++KHR_DF_SAMPLE_DATATYPE_FLOAT++* bit. An example of use of the 16-bit floating point format described in -<<16bitfp>> but described in terms of a custom floating point format +<> but described in terms of a custom floating point format is provided in <>. Note that this is provided for example only, and this particular format would be better described using the standard 16-bit floating @@ -4901,16 +4880,16 @@ The *_sampleUpper_* and *_sampleLower_* values for the mantissa should be set to indicate the representation of 1.0 and 0.0 (for unsigned formats) or -1.0 (for signed formats) respectively when the exponent is in a 0 position after any bias has been corrected. If there is an implicit -``1'' bit, these values for the mantissa will exceed what can be +"`1`" bit, these values for the mantissa will exceed what can be represented in the number of available mantissa bits. For example, the shared exponent formats shown in -<> does not have an implicit ``1'' bit, and +<> does not have an implicit "`1`" bit, and therefore the *_sampleUpper_* values for the 9-bit mantissas are 256 -- this being the mantissa value for 1.0 when the exponent is set to 0. -For the 16-bit signed floating point format described in <<16bitfp>>, -*_sampleUpper_* should be set to 1024, indicating the implicit ``1'' bit +For the 16-bit signed floating point format described in <>, +*_sampleUpper_* should be set to 1024, indicating the implicit "`1`" bit which is above the 10 bits representable in the mantissa. *_sampleLower_* should be 0 in this case, since the mantissa uses a sign-magnitude representation. @@ -4940,8 +4919,8 @@ sign bit can distinguish between +0 and -0. Floating point values encoded with an exponent of 0 (before bias) and a non-zero mantissa are assumed to indicate a denormalized -number, if the format has an implicit ``1'' bit. That is, when -the exponent is 0, the ``1'' bit becomes explicit and the exponent +number, if the format has an implicit "`1`" bit. That is, when +the exponent is 0, the "`1`" bit becomes explicit and the exponent is considered to be the negative sample bias minus one. Floating point values encoded with an exponent larger than the @@ -4956,17 +4935,17 @@ exponent's *_sampleUpper_* value and with a mantissa of non-0 are interpreted as representing not-a-number (_NaN_). Note that these interpretations are compatible with the -corresponding numerical representations in <>. +corresponding numerical representations in <>. ==== Conversion formulae Given an optional sign bit _S_, a mantissa value of _M_ and an -exponent value of _E_, a format with an implicit ``1'' bit can +exponent value of _E_, a format with an implicit "`1`" bit can be converted from its representation to a real value as follows: [latexmath] -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -\[ +++++ +\begin{aligned} V = \begin{cases} (-1)^S \times 0.0, & E = 0, M = 0 \\ @@ -4976,16 +4955,16 @@ V = (-1)^S \times \mathit{Inf}, & E > E_\mathit{sampleUpper}, M = 0 \\ \mathit{NaN}, & E > E_\mathit{sampleUpper}, M \neq 0. \end{cases} -\] -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +\end{aligned} +++++ -If there is no implicit ``1'' bit (that is, the *_sampleUpper_* value +If there is no implicit "`1`" bit (that is, the *_sampleUpper_* value of the mantissa is representable in the number of bits assigned to the mantissa), the value can be converted to a real value as follows: [latexmath] -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -\[ +++++ +\begin{aligned} V = \begin{cases} (-1)^S \times 2^{E-E_{\mathit{sampleUower}}} \times { \left( { M \over M_\mathit{sampleUpper} } \right) }, @@ -4993,36 +4972,40 @@ V = (-1)^S \times \mathit{Inf}, & E > E_\mathit{sampleUpper}, M = 0 \\ \mathit{NaN}, & E > E_\mathit{sampleUpper}, M \neq 0. \end{cases} -\] -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +\end{aligned} +++++ -A descriptor block for a format without an implicit ``1'' (and with the +A descriptor block for a format without an implicit "`1`" (and with the added complication of having the same exponent bits shared across multiple -channels, which is why an implicit ``1'' bit does not make sense) is shown +channels, which is why an implicit "`1`" bit does not make sense) is shown in <>. In the case of this particular example, the above equations simplify to: [latexmath] -+++++++++++++++++++ - $$red = \mathit{red}_\mathrm{shared}\times 2^{(\mathit{exp}_\mathrm{shared}-B-N)}$$ - $$green = \mathit{green}_\mathrm{shared}\times 2^{(\mathit{exp}_\mathrm{shared}-B-N)}$$ - $$blue = \mathit{blue}_\mathrm{shared}\times 2^{(\mathit{exp}_\mathrm{shared}-B-N)}$$ -+++++++++++++++++++ +++++ +\begin{align*} +red = \mathit{red}_\mathrm{shared}\times 2^{(\mathit{exp}_\mathrm{shared}-B-N)} \\ +green = \mathit{green}_\mathrm{shared}\times 2^{(\mathit{exp}_\mathrm{shared}-B-N)} \\ +blue = \mathit{blue}_\mathrm{shared}\times 2^{(\mathit{exp}_\mathrm{shared}-B-N)} +\end{align*} +++++ Where: [latexmath] -+++++++++++++++++++ - $$N = 9 \textrm{ (= number of mantissa bits per component)}$$ - $$B = 15 \textrm{ (= exponent bias)}$$ -+++++++++++++++++++ +++++ +\begin{align*} +N = 9 \textrm{ (= number of mantissa bits per component)} \\ +B = 15 \textrm{ (= exponent bias)} +\end{align*} +++++ Note that in general conversion from a real number _to_ any representation may require rounding, truncation and special value management rules which are beyond the scope of a data format specification and may be documented in APIs which generate these formats. -== Example format descriptors == +== Example format descriptors NOTE: Example data format descriptors for compressed formats can be found under the *_colorModel_* field in <>. @@ -5030,7 +5013,7 @@ be found under the *_colorModel_* field in <>. [[exampledescriptor_565]] .565 _RGB_ packed 16-bit format as written to memory by a little-endian architecture [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 76 @@ -5042,31 +5025,31 @@ be found under the *_colorModel_* field in <>. 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 2 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~First sample: low five bits blue~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++BLUE++* 8+^| *_bitLength:_* 4 (= ``5'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++BLUE++* 8+^| *_bitLength:_* 4 (= "`5`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 31 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Second sample: middle six bits green~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 5 = (``6'') 16+^| *_bitOffset:_* 6 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 5 = ("`6`") 16+^| *_bitOffset:_* 6 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 63 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Third sample: top five bits red~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 4 (= ``5'') 16+^| *_bitOffset:_* 11 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 4 (= "`5`") 16+^| *_bitOffset:_* 11 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 31 -|================================ +|==== <<< [[exampledescriptor_cosited]] .Four co-sited 8-bit sRGB channels, assuming premultiplied alpha [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 92 @@ -5078,37 +5061,37 @@ be found under the *_colorModel_* field in <>. 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 4 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the first sample~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 7 (= ``8'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 7 (= "`8`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 255 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the second sample~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 7 (= ``8'') 16+^| *_bitOffset:_* 8 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 7 (= "`8`") 16+^| *_bitOffset:_* 8 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 255 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the third sample~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++BLUE++* 8+^| *_bitLength:_* 7 (= ``8'') 16+^| *_bitOffset:_* 16 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++BLUE++* 8+^| *_bitLength:_* 7 (= "`8`") 16+^| *_bitOffset:_* 16 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 255 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the fourth sample~ -^| 0 ^| 0 ^| 0 ^| 1 4+^| *++ALPHA++* 8+^| *_bitLength:_* 7 (= ``8'') 16+^| *_bitOffset:_* 24 +^| 0 ^| 0 ^| 0 ^| 1 4+^| *++ALPHA++* 8+^| *_bitLength:_* 7 (= "`8`") 16+^| *_bitOffset:_* 24 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 255 -|================================ +|==== <<< [[exampledescriptor_mono8bit]] .A single 8-bit monochrome channel [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 44 @@ -5125,16 +5108,12 @@ be found under the *_colorModel_* field in <>. 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 255 -|================================ +|==== + [[exampledescriptor_1bpp]] -ifdef::a2xhtml[] -.A single 1-bit monochrome channel, as an 8×1 texel block to allow byte-alignment -endif::[] -ifndef::a2xhtml[] .A single 1-bit monochrome channel, as an 8×1 texel block to allow byte-alignment, part 1 of 2 -endif::[] [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 156 @@ -5142,76 +5121,74 @@ endif::[] 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 8) = 142 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++LINEAR++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++YUVSDA++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 0 8+^| 7 (= ``8'') +8+^| 0 8+^| 0 8+^| 0 8+^| 7 (= "`8`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 1 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the first sample~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 0 (= ``1'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 0 (= "`1`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 1 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the second sample~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 0 (= ``1'') 16+^| *_bitOffset:_* 1 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 0 (= "`1`") 16+^| *_bitOffset:_* 1 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0x20 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 1 -ifndef::a2xhtml[] -|================================ +|==== <<< .A single 1-bit monochrome channel, as an 8×1 texel block to allow byte-alignment, part 2 of 2 [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ -endif::[] ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the third sample~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 0 (= ``1'') 16+^| *_bitOffset:_* 2 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 0 (= "`1`") 16+^| *_bitOffset:_* 2 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0x40 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 1 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| _~Sample information for the fourth sample~_ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 0 (= ``1'') 16+^| *_bitOffset:_* 3 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 0 (= "`1`") 16+^| *_bitOffset:_* 3 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0x60 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 1 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| _~Sample information for the fifth sample~_ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 0 (= ``1'') 16+^| *_bitOffset:_* 4 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 0 (= "`1`") 16+^| *_bitOffset:_* 4 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0x80 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 1 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| _~Sample information for the sixth sample~_ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 0 (= ``1'') 16+^| *_bitOffset:_* 5 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 0 (= "`1`") 16+^| *_bitOffset:_* 5 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0xA0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 1 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| _~Sample information for the seventh sample~_ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 0 (= ``1'') 16+^| *_bitOffset:_* 6 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 0 (= "`1`") 16+^| *_bitOffset:_* 6 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0xC0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 1 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| _~Sample information for the eighth sample~_ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 0 (= ``1'') 16+^| *_bitOffset:_* 7 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 0 (= "`1`") 16+^| *_bitOffset:_* 7 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0xE0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 1 -|================================ +|==== <<< [[exampledescriptor_bayer]] .2×2 Bayer pattern: four 8-bit distributed sRGB channels, spread across two lines (as two planes) [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 92 @@ -5219,41 +5196,41 @@ endif::[] 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 4) = 88 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++SRGB++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++RGBSDA++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 1 (height = ``2'') 8+^| 1 (width = ``2'') +8+^| 0 8+^| 0 8+^| 1 (height = "`2`") 8+^| 1 (width = "`2`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 2 8+^| *_bytesPlane0:_* 2 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the first sample~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 7 (= ``8'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 7 (= "`8`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* -8+^| 0 8+^| 0 8+^| 0x00 (_y_ = ``0'') 8+^| 0x00 (_x_ = ``0'') +8+^| 0 8+^| 0 8+^| 0x00 (_y_ = "`0`") 8+^| 0x00 (_x_ = "`0`") 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 255 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the second sample~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 7 (= ``8'') 16+^| *_bitOffset:_* 8 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 7 (= "`8`") 16+^| *_bitOffset:_* 8 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* -8+^| 0 8+^| 0 8+^| 0x00 (_y_ = ``0'') 8+^| 0x80 (_x_ = ``1'') +8+^| 0 8+^| 0 8+^| 0x00 (_y_ = "`0`") 8+^| 0x80 (_x_ = "`1`") 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 255 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the third sample~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 7 (= ``8'') 16+^| *_bitOffset:_* 16 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 7 (= "`8`") 16+^| *_bitOffset:_* 16 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* -8+^| 0 8+^| 0 8+^| 0x80 (_y_ = ``1'') 8+^| 0x00 (_x_ = ``0'') +8+^| 0 8+^| 0 8+^| 0x80 (_y_ = "`1`") 8+^| 0x00 (_x_ = "`0`") 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 255 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the fourth sample~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++BLUE++* 8+^| *_bitLength:_* 7 (= ``8'') 16+^| *_bitOffset:_* 24 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++BLUE++* 8+^| *_bitLength:_* 7 (= "`8`") 16+^| *_bitOffset:_* 24 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* -8+^| 0 8+^| 0 8+^| 0x80 (_y_ = ``1'') 8+^| 0x80 (_x_ = ``1'') +8+^| 0 8+^| 0 8+^| 0x80 (_y_ = "`1`") 8+^| 0x80 (_x_ = "`1`") 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 255 -|================================ +|==== <<< [[exampledescriptor_simplepalette]] .Simple paletted format: 8-bit index to 240 entries of 4-bit _R_, _G_, _B_ channels [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 92 @@ -5265,35 +5242,35 @@ endif::[] 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 1 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the 8-bit index~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| 0 8+^| *_bitLength:_* 7 (= ``8'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| 0 8+^| *_bitLength:_* 7 (= "`8`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 239 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Red channel of the palette entries~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 3 (= ``4'') 16+^| *_bitOffset:_* 8 (palette entry) +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 3 (= "`4`") 16+^| *_bitOffset:_* 8 (palette entry) 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 (palette id) 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 15 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Green channel of the palette entries~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 3 (= ``4'') 16+^| *_bitOffset:_* 8 (palette entry) +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 3 (= "`4`") 16+^| *_bitOffset:_* 8 (palette entry) 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 (palette id) 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 15 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Blue channel of the palette entries~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++BLUE++* 8+^| *_bitLength:_* 3 (= ``4'') 16+^| *_bitOffset:_* 8 (palette entry) +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++BLUE++* 8+^| *_bitLength:_* 3 (= "`4`") 16+^| *_bitOffset:_* 8 (palette entry) 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 (palette id) 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 15 -|================================ +|==== [[exampledescriptor_LUT]] .Paletted color look-up table format: three 8-bit indices into separate 256-entry 10-bit channels [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 124 @@ -5305,47 +5282,47 @@ endif::[] 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 4 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Red channel palette index~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 7 (= ``8'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 7 (= "`8`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 255 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Green channel palette index~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 7 (= ``8'') 16+^| *_bitOffset:_* 8 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 7 (= "`8`") 16+^| *_bitOffset:_* 8 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 255 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Blue channel palette index~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++BLUE++* 8+^| *_bitLength:_* 7 (= ``8'') 16+^| *_bitOffset:_* 16 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++BLUE++* 8+^| *_bitLength:_* 7 (= "`8`") 16+^| *_bitOffset:_* 16 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 255 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Red palette entry~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 9 (= ``10'') 16+^| *_bitOffset:_* 32 (palette entry) +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 9 (= "`10`") 16+^| *_bitOffset:_* 32 (palette entry) 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 (*++RED++* palette) 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 1023 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Green palette entry~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 9 (= ``10'') 16+^| *_bitOffset:_* 32 (palette entry) +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 9 (= "`10`") 16+^| *_bitOffset:_* 32 (palette entry) 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 1 (*++GREEN++* palette) 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 1023 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Blue palette entry~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 9 (= ``10'') 16+^| *_bitOffset:_* 32 (palette entry) +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 9 (= "`10`") 16+^| *_bitOffset:_* 32 (palette entry) 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 2 (*++BLUE++* palette) 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 1023 -|================================ +|==== [[exampledescriptor_ycbcr]] -._Y′C~B~C~R~_ 4:2:0: BT.709 reduced-range data, with _C~B~_ and _C~R~_ aligned to the midpoint of the _Y′_ samples +._Y{prime}C~B~C~R~_ 4:2:0: BT.709 reduced-range data, with _C~B~_ and _C~R~_ aligned to the midpoint of the _Y{prime}_ samples [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 124 @@ -5353,51 +5330,51 @@ endif::[] 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 6) = 120 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++ITU++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++YUVSDA++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 1 (height = ``2'') 8+^| 1 (width = ``2'') +8+^| 0 8+^| 0 8+^| 1 (height = "`2`") 8+^| 1 (width = "`2`") 8+^| *_bytesPlane3:_* 1 8+^| *_bytesPlane2:_* 1 8+^| *_bytesPlane1:_* 2 8+^| *_bytesPlane0:_* 2 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 -^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the first _Y′_ sample~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 7 (= ``8'') 16+^| *_bitOffset:_* 0 +^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the first _Y{prime}_ sample~ +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 7 (= "`8`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* -8+^| 0 8+^| 0 8+^| 0x00 (_y_ = ``0.0'') 8+^| 0x00 (_x_ = ``0.0'') +8+^| 0 8+^| 0 8+^| 0x00 (_y_ = "`0.0`") 8+^| 0x00 (_x_ = "`0.0`") 32+^| *_sampleLower:_* 16 32+^| *_sampleUpper:_* 235 -^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the second _Y′_ sample~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 7 (= ``8'') 16+^| *_bitOffset:_* 8 +^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the second _Y{prime}_ sample~ +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 7 (= "`8`") 16+^| *_bitOffset:_* 8 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* -8+^| 0 8+^| 0 8+^| 0x00 (_y_ = ``0.0'') 8+^| 0x80 (_x_ = ``1.0'') +8+^| 0 8+^| 0 8+^| 0x00 (_y_ = "`0.0`") 8+^| 0x80 (_x_ = "`1.0`") 32+^| *_sampleLower:_* 16 32+^| *_sampleUpper:_* 235 -^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the third _Y′_ sample~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 7 (= ``8'') 16+^| *_bitOffset:_* 16 +^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the third _Y{prime}_ sample~ +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 7 (= "`8`") 16+^| *_bitOffset:_* 16 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* -8+^| 0 8+^| 0 8+^| 0x80 (_y_ = ``1.0'') 8+^| 0x00 (_x_ = ``0.0'') +8+^| 0 8+^| 0 8+^| 0x80 (_y_ = "`1.0`") 8+^| 0x00 (_x_ = "`0.0`") 32+^| *_sampleLower:_* 16 32+^| *_sampleUpper:_* 235 -^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the fourth _Y′_ sample~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 7 (= ``8'') 16+^| *_bitOffset:_* 24 +^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the fourth _Y{prime}_ sample~ +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 7 (= "`8`") 16+^| *_bitOffset:_* 24 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* -8+^| 0 8+^| 0 8+^| 0x80 (_y_ = ``1.0'') 8+^| 0x80 (_x_ = ``1.0'') +8+^| 0 8+^| 0 8+^| 0x80 (_y_ = "`1.0`") 8+^| 0x80 (_x_ = "`1.0`") 32+^| *_sampleLower:_* 16 32+^| *_sampleUpper:_* 235 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the _U_ sample~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++U++* 8+^| *_bitLength:_* 7 (= ``8'') 16+^| *_bitOffset:_* 32 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++U++* 8+^| *_bitLength:_* 7 (= "`8`") 16+^| *_bitOffset:_* 32 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* -8+^| 0 8+^| 0 8+^| 0x40 (_y_ = ``0.5'') 8+^| 0x40 (_x_ = ``0.5'') +8+^| 0 8+^| 0 8+^| 0x40 (_y_ = "`0.5`") 8+^| 0x40 (_x_ = "`0.5`") 32+^| *_sampleLower:_* 16 32+^| *_sampleUpper:_* 240 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the _V_ sample~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++V++* 8+^| *_bitLength:_* 7 (= ``8'') 16+^| *_bitOffset:_* 40 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++V++* 8+^| *_bitLength:_* 7 (= "`8`") 16+^| *_bitOffset:_* 40 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* -8+^| 0 8+^| 0 8+^| 0x40 (_y_ = ``0.5'') 8+^| 0x40 (_x_ = ``0.5'') +8+^| 0 8+^| 0 8+^| 0x40 (_y_ = "`0.5`") 8+^| 0x40 (_x_ = "`0.5`") 32+^| *_sampleLower:_* 16 32+^| *_sampleUpper:_* 240 -|================================ +|==== [[exampledescriptor_bigendian]] .565 _RGB_ packed 16-bit format as written to memory by a big-endian architecture [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 92 @@ -5409,35 +5386,35 @@ endif::[] 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 2 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Bit 0 is green, green bits 0..2 in bits 5..7 of the higher byte address (less-significant half of the big-endian word)~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 2 (= ``3'') 16+^| *_bitOffset:_* 13 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 2 (= "`3`") 16+^| *_bitOffset:_* 13 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 -- lower 3 bits of 6-bit value 0 32+^| *_sampleUpper:_* 7 -- lower 3 bits of 6-bit value 63 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Continuation: green bits 3..5 in bits 0..2 of the lower byte address (more-significant half of the big-endian word)~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 2 (= ``3'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 2 (= "`3`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 -- upper 3 bits of 6-bit value 0 32+^| *_sampleUpper:_* 7 -- upper 3 bits of 6-bit value 63 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Next undescribed bit: red in bits 3..7 of the lower byte address (more-significant half of the big-endian word)~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 4 (= ``5'') 16+^| *_bitOffset:_* 3 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 4 (= "`5`") 16+^| *_bitOffset:_* 3 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 31 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Remaining bits: blue in bits 0..4 of the higher byte address (less-significant half of the big-endian word)~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++BLUE++* 8+^| *_bitLength:_* 4 (= ``5'') 16+^| *_bitOffset:_* 8 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++BLUE++* 8+^| *_bitLength:_* 4 (= "`5`") 16+^| *_bitOffset:_* 8 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 31 -|================================ +|==== [[exampledescriptor_r9g9b9e5]] .R9G9B9E5 shared-exponent format [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 124 @@ -5449,47 +5426,47 @@ endif::[] 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 4 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the _R_ mantissa~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 8 (= ``9'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 8 (= "`9`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 256 -- mantissa at 1.0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the _R_ exponent~ -^| 0 ^| 0 ^| 1 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 4 (= ``5'') 16+^| *_bitOffset:_* 27 +^| 0 ^| 0 ^| 1 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 4 (= "`5`") 16+^| *_bitOffset:_* 27 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 15 -- exponent bias ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the _G_ mantissa~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 8 (= ``9'') 16+^| *_bitOffset:_* 9 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 8 (= "`9`") 16+^| *_bitOffset:_* 9 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 256 -- mantissa at 1.0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the _G_ exponent~ -^| 0 ^| 0 ^| 1 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 4 (= ``5'') 16+^| *_bitOffset:_* 27 +^| 0 ^| 0 ^| 1 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 4 (= "`5`") 16+^| *_bitOffset:_* 27 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 15 -- exponent bias ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the _B_ mantissa~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++BLUE++* 8+^| *_bitLength:_* 8 (= ``9'') 16+^| *_bitOffset:_* 18 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++BLUE++* 8+^| *_bitLength:_* 8 (= "`9`") 16+^| *_bitOffset:_* 18 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 256 -- mantissa at 1.0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information for the _B_ exponent~ -^| 0 ^| 0 ^| 1 ^| 0 4+^| *++BLUE++* 8+^| *_bitLength:_* 4 (= ``5'') 16+^| *_bitOffset:_* 27 +^| 0 ^| 0 ^| 1 ^| 0 4+^| *++BLUE++* 8+^| *_bitLength:_* 4 (= "`5`") 16+^| *_bitOffset:_* 27 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 15 -- exponent bias -|================================ +|==== [[exampledescriptor_AcornTint]] .Acorn 256-color format (2 bits each independent _RGB_, 2 bits shared tint) [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 108 @@ -5501,46 +5478,40 @@ endif::[] 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 1 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| _~First sample: four bits of red starting at bit 0, including two shared bits 0..1~_ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 3 (= ``4'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 3 (= "`4`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 15 -^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Second sample: two bits of green ``tint'' shared with red~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 1 (= ``2'') 16+^| *_bitOffset:_* 0 +^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Second sample: two bits of green "`tint`" shared with red~ +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 1 (= "`2`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 3 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Third sample: two bits unique to green~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 1 (= ``2'') 16+^| *_bitOffset:_* 4 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 1 (= "`2`") 16+^| *_bitOffset:_* 4 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 3 -^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Fourth sample: two bits of blue ``tint'' shared with red~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++BLUE++* 8+^| *_bitLength:_* 1 (= ``2'') 16+^| *_bitOffset:_* 0 +^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Fourth sample: two bits of blue "`tint`" shared with red~ +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++BLUE++* 8+^| *_bitLength:_* 1 (= "`2`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 3 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Fifth sample: two bits unique to blue~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++BLUE++* 8+^| *_bitLength:_* 1 (= ``2'') 16+^| *_bitOffset:_* 6 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++BLUE++* 8+^| *_bitLength:_* 1 (= "`2`") 16+^| *_bitOffset:_* 6 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 3 -|================================ - -ifdef::a2xhtml[] -.V210 format (full-range _Y′C~B~C~R~_) -endif::[] -ifndef::a2xhtml[] +|==== -.V210 format (full-range _Y′C~B~C~R~_) part 1 of 2 -endif::[] +.V210 format (full-range _Y{prime}C~B~C~R~_) part 1 of 2 [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 220 @@ -5548,96 +5519,94 @@ endif::[] 16+^| *_descriptorBlockSize:_* 24 + (16 {times} 12) = 216 16+^| *_versionNumber:_* 2 8+^| *_flags:_* *++ALPHA_STRAIGHT++* 8+^| *_transferFunction:_* *++ITU++* 8+^| *_colorPrimaries:_* *++BT709++* 8+^| *_colorModel:_* *++YUVSDA++* 8+^| *_~texelBlockDimension3~_* 8+^| *_~texelBlockDimension2~_* 8+^| *_~texelBlockDimension1~_* 8+^| *_~texelBlockDimension0~_* -8+^| 0 8+^| 0 8+^| 0 8+^| 5 (width = ``6'') +8+^| 0 8+^| 0 8+^| 0 8+^| 5 (width = "`6`") 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 16 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~First sample: shared mid-sited _U0/U1_~ ^| 0 ^| 0 ^| 0 ^| 0 4+^| *++U++* 8+^| *_bitLength:_* 10 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* -8+^| 0 8+^| 0 8+^| 0 8+^| 0x10 (_x_ = ``0.5'') +8+^| 0 8+^| 0 8+^| 0 8+^| 0x10 (_x_ = "`0.5`") 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 1023 -^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Second sample: _Y′0_~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 9 (= ``10'') 16+^| *_bitOffset:_* 10 +^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Second sample: _Y{prime}0_~ +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 9 (= "`10`") 16+^| *_bitOffset:_* 10 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* -8+^| 0 8+^| 0 8+^| 0 8+^| 0x00 (_x_ = ``0.0'') +8+^| 0 8+^| 0 8+^| 0 8+^| 0x00 (_x_ = "`0.0`") 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 1023 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Third sample: shared mid-sited _V0/V1_~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++V++* 8+^| *_bitLength:_* 9 (= ``10'') 16+^| *_bitOffset:_* 20 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++V++* 8+^| *_bitLength:_* 9 (= "`10`") 16+^| *_bitOffset:_* 20 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* -8+^| 0 8+^| 0 8+^| 0 8+^| 0x10 (_x_ = ``0.5'') +8+^| 0 8+^| 0 8+^| 0 8+^| 0x10 (_x_ = "`0.5`") 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 1023 -^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Fourth sample: _Y′1_~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 9 (= ``10'') 16+^| *_bitOffset:_* 32 +^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Fourth sample: _Y{prime}1_~ +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 9 (= "`10`") 16+^| *_bitOffset:_* 32 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* -8+^| 0 8+^| 0 8+^| 0 8+^| 0x20 (_x_ = ``1.0'') +8+^| 0 8+^| 0 8+^| 0 8+^| 0x20 (_x_ = "`1.0`") 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 1023 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Fifth sample: shared mid-sited _U2/U3_~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++U++* 8+^| *_bitLength:_* 9 (= ``10'') 16+^| *_bitOffset:_* 42 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++U++* 8+^| *_bitLength:_* 9 (= "`10`") 16+^| *_bitOffset:_* 42 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* -8+^| 0 8+^| 0 8+^| 0 8+^| 0x50 (_x_ = ``2.5'') +8+^| 0 8+^| 0 8+^| 0 8+^| 0x50 (_x_ = "`2.5`") 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 1023 -ifndef::a2xhtml[] -|================================ +|==== -.V210 format (full-range _Y′C~B~C~R~_) part 2 of 2 +.V210 format (full-range _Y{prime}C~B~C~R~_) part 2 of 2 [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ -endif::[] -^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sixth sample: _Y′2_~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 9 (= ``10'') 16+^| *_bitOffset:_* 52 +^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sixth sample: _Y{prime}2_~ +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 9 (= "`10`") 16+^| *_bitOffset:_* 52 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* -8+^| 0 8+^| 0 8+^| 0 8+^| 0x40 (_x_ = ``2.0'') +8+^| 0 8+^| 0 8+^| 0 8+^| 0x40 (_x_ = "`2.0`") 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 1023 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Seventh sample: shared mid-sited _V2/V3_~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++V++* 8+^| *_bitLength:_* 9 (= ``10'') 16+^| *_bitOffset:_* 64 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++V++* 8+^| *_bitLength:_* 9 (= "`10`") 16+^| *_bitOffset:_* 64 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* -8+^| 0 8+^| 0 8+^| 0 8+^| 0x50 (_x_ = ``2.5'') +8+^| 0 8+^| 0 8+^| 0 8+^| 0x50 (_x_ = "`2.5`") 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 1023 -^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Eighth sample: _Y′3_~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 9 (= ``10'') 16+^| *_bitOffset:_* 74 +^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Eighth sample: _Y{prime}3_~ +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 9 (= "`10`") 16+^| *_bitOffset:_* 74 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* -8+^| 0 8+^| 0 8+^| 0 8+^| 0x60 (_x_ = ``3.0'') +8+^| 0 8+^| 0 8+^| 0 8+^| 0x60 (_x_ = "`3.0`") 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 1023 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Ninth sample: shared mid-sited _U4/U5_~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++U++* 8+^| *_bitLength:_* 9 (= ``10'') 16+^| *_bitOffset:_* 84 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++U++* 8+^| *_bitLength:_* 9 (= "`10`") 16+^| *_bitOffset:_* 84 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* -8+^| 0 8+^| 0 8+^| 0 8+^| 0x90 (_x_ = ``4.5'') +8+^| 0 8+^| 0 8+^| 0 8+^| 0x90 (_x_ = "`4.5`") 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 1023 -^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Tenth sample: _Y′4_~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 9 (= ``10'') 16+^| *_bitOffset:_* 96 +^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Tenth sample: _Y{prime}4_~ +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 9 (= "`10`") 16+^| *_bitOffset:_* 96 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* -8+^| 0 8+^| 0 8+^| 0 8+^| 0x80 (_x_ = ``4.0'') +8+^| 0 8+^| 0 8+^| 0 8+^| 0x80 (_x_ = "`4.0`") 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 1023 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Eleventh sample: shared mid-sited _V4/V5_~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++V++* 8+^| *_bitLength:_* 9 (= ``10'') 16+^| *_bitOffset:_* 106 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++V++* 8+^| *_bitLength:_* 9 (= "`10`") 16+^| *_bitOffset:_* 106 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* -8+^| 0 8+^| 0 8+^| 0 8+^| 0x90 (_x_ = ``4.5'') +8+^| 0 8+^| 0 8+^| 0 8+^| 0x90 (_x_ = "`4.5`") 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 1023 -^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Twelfth sample: _Y′5_~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 9 (= ``10'') 16+^| *_bitOffset:_* 116 +^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Twelfth sample: _Y{prime}5_~ +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++Y++* 8+^| *_bitLength:_* 9 (= "`10`") 16+^| *_bitOffset:_* 116 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* -8+^| 0 8+^| 0 8+^| 0 8+^| 0xA0 (_x_ = ``5.0'') +8+^| 0 8+^| 0 8+^| 0 8+^| 0xA0 (_x_ = "`5.0`") 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 1023 -|================================ +|==== [[exampledescriptor_intensity]] .Intensity-alpha format showing aliased samples [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 92 @@ -5649,35 +5618,35 @@ endif::[] 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 1 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~First sample: red~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 7 (= ``8'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 7 (= "`8`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 255 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Second sample: green~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 7 (= ``8'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++GREEN++* 8+^| *_bitLength:_* 7 (= "`8`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 255 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Third sample: blue~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++BLUE++* 8+^| *_bitLength:_* 7 (= ``8'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++BLUE++* 8+^| *_bitLength:_* 7 (= "`8`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 255 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Fourth sample: alpha~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++ALPHA++* 8+^| *_bitLength:_* 7 (= ``8'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++ALPHA++* 8+^| *_bitLength:_* 7 (= "`8`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 255 -|================================ +|==== [[exampledescriptor_48bit]] .A 48-bit signed middle-endian red channel: three co-sited 16-bit little-endian words, high word first [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 76 @@ -5689,29 +5658,29 @@ endif::[] 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 6 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~First sample: bits 0..15 of the 48-bit value, in memory bytes 4..5~ -^| 0 ^| 1 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 15 (= ``16'') 16+^| *_bitOffset:_* 32 +^| 0 ^| 1 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 15 (= "`16`") 16+^| *_bitOffset:_* 32 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0xFFFF0000U -- bottom 16 bits of 0x800000000000, sign-extended 32+^| *_sampleUpper:_* 0x0000FFFFU -- bottom 16 bits of 0x7FFFFFFFFFFF ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Second sample: bits 16..31 of the 48-bit value, in memory bytes 2..3~ -^| 0 ^| 1 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 15 (= ``16'') 16+^| *_bitOffset:_* 16 +^| 0 ^| 1 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 15 (= "`16`") 16+^| *_bitOffset:_* 16 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0xFFFF0000U -- middle 16 bits of 0x800000000000, sign-extended 32+^| *_sampleUpper:_* 0x0000FFFFU -- middle 16 bits of 0x7FFFFFFFFFFF ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Third sample: bits 32..47 of the 48-bit value, in memory bytes 0..1~ -^| 0 ^| 1 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 15 (= ``16'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 1 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 15 (= "`16`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0xFFFF8000U -- top 16 bits of 0x800000000000, sign-extended 32+^| *_sampleUpper:_* 0x00007FFFU -- top 16 bits of 0x7FFFFFFFFFFF -|================================ +|==== [[exampledescriptor_float16explicit]] .A single 16-bit floating-point red value, described explicitly (example only!) [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 76 @@ -5723,29 +5692,29 @@ endif::[] 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 2 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~First sample: mantissa~ -^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 9 (= ``10'') 16+^| *_bitOffset:_* 0 +^| 0 ^| 0 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 9 (= "`10`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0 32+^| *_sampleUpper:_* 1024 -- implicit 1.0 bit since 1024 > 2^*_bitLength_*^ - 1 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Second sample: sign of mantissa~ -^| 0 ^| 1 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 0 (= ``1'') 16+^| *_bitOffset:_* 15 +^| 0 ^| 1 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 0 (= "`1`") 16+^| *_bitOffset:_* 15 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 -32+^| *_sampleLower:_* 1 -- 1-bit ``-1'' -32+^| *_sampleUpper:_* 0 -- 1-bit ``0'' +32+^| *_sampleLower:_* 1 -- 1-bit "`-1`" +32+^| *_sampleUpper:_* 0 -- 1-bit "`0`" ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Third sample: exponent~ -^| 0 ^| 0 ^| 1 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 4 (= ``5'') 16+^| *_bitOffset:_* 10 +^| 0 ^| 0 ^| 1 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 4 (= "`5`") 16+^| *_bitOffset:_* 10 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 15 -- bias 32+^| *_sampleUpper:_* 30 -- support for infinities because 30 < 2^*bitLength*^ - 1 -|================================ +|==== [[exampledescriptor_float16implicit]] .A single 16-bit floating-point red value, described normally [width="97%"] -|================================ +|==== 32+^| *~++uint32_t++ bit~* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 32+^| *_totalSize:_* 44 @@ -5757,32 +5726,32 @@ endif::[] 8+^| *_bytesPlane3:_* 0 8+^| *_bytesPlane2:_* 0 8+^| *_bytesPlane1:_* 0 8+^| *_bytesPlane0:_* 2 8+^| *_bytesPlane7:_* 0 8+^| *_bytesPlane6:_* 0 8+^| *_bytesPlane5:_* 0 8+^| *_bytesPlane4:_* 0 ^| *_~F~_* ^| *_~S~_* ^| *_~E~_* ^| *_~L~_* 4+^| *_~channelType~_* 24+^| ~Sample information~ -^| 1 ^| 1 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 15 (= ``16'') 16+^| *_bitOffset:_* 0 +^| 1 ^| 1 ^| 0 ^| 0 4+^| *++RED++* 8+^| *_bitLength:_* 15 (= "`16`") 16+^| *_bitOffset:_* 0 8+^| *_~samplePosition3~_* 8+^| *_~samplePosition2~_* 8+^| *_~samplePosition1~_* 8+^| *_~samplePosition0~_* 8+^| 0 8+^| 0 8+^| 0 8+^| 0 32+^| *_sampleLower:_* 0xBF800000U -- IEEE 754 floating-point representation for -1.0f 32+^| *_sampleUpper:_* 0x3F800000U -- IEEE 754 floating-point representation for 1.0f -|================================ +|==== -ifndef::a2xhtml[] +ifndef::backend-html5[] = Color conversions endif::[] -include::conversions.txt[] +include::{chapters}/conversions.adoc[] -ifndef::a2xhtml[] +ifndef::backend-html5[] = Compressed Texture Formats endif::[] -include::compformats.txt[] +include::{chapters}/compformats.adoc[] -ifndef::a2xhtml[] +ifndef::backend-html5[] = References and contributors endif::[] -include::references.txt[] +include::{chapters}/references.adoc[] -== Contributors == +== Contributors Frank Brill @@ -5845,4 +5814,3 @@ Eric Werness David Wilkinson // vim: filetype=asciidoc ai expandtab tw=72 ts=4 sts=2 sw=2 - diff --git a/etc1.txt b/chapters/etc1.adoc similarity index 78% rename from etc1.txt rename to chapters/etc1.adoc index 5503a18..cb6fd0e 100644 --- a/etc1.txt +++ b/chapters/etc1.adoc @@ -1,5 +1,6 @@ -// Copyright (c) 2014-2019 The Khronos Group Inc. -// Copyright notice at https://www.khronos.org/registry/speccopyright.html +// Copyright 2014-2026 The Khronos Group Inc. +// SPDX-License-Identifier: CC-BY-4.0 + [[ETC1]] == ETC1 Compressed Texture Image Formats @@ -36,7 +37,7 @@ _d_~3~ _h_~3~ _l_~3~ _p_~3~ _d_~4~ _h_~4~ _l_~4~ _p_~4~. [[ETC18x8]] .Pixel layout for an 8×8 texture using four ETC1 compressed blocks -image::images/ETCletter8x8.{svgpdf}[width="{svgpdf@pdf:218pt:327}",align="center"] +image::{images}/ETCletter8x8.svg[width="{svgpdf@pdf:218pt:327}",align="center"] Note how pixel _a_~2~ in the second block is adjacent to pixel _m_~1~ in the first block. @@ -51,18 +52,18 @@ _q_~7~ at the highest. The 64 bits specifying the block are then represented by the following 64 bit integer: [latexmath] -++++++ +++++ \begin{align*} \mathit{int64bit} & = 256\times (256\times (256\times (256\times (256\times (256\times (256\times q_0+q_1)+q_2)+q_3)+q_4)+q_5)+q_6)+q_7 \end{align*} -++++++ +++++ Each 64-bit word contains information about a 4{times}4 pixel block as shown in <>. [[ETC1layout]] .Pixel layout for an ETC1 compressed block -image::images/ETCletterdirections.{svgpdf}[width="{svgpdf@pdf:115pt:173}",align="center"] +image::{images}/ETCletterdirections.svg[width="{svgpdf@pdf:115pt:173}",align="center"] There are two modes in ETC1: the `individual' mode and the `differential' mode. Which mode is @@ -76,13 +77,13 @@ in <> <> and <>. [[ETC1format]] .Texel Data format for ETC1 compressed textures -ifdef::a2xhtml[] +ifdef::backend-html5[] [cols="16*1"] endif::[] -ifndef::a2xhtml[] +ifndef::backend-html5[] [width="55%",cols="16*1"] endif::[] -|==================== +|==== 16+^| [[ETC1individual]]*a) Bit layout in bits 63 through 32 if _diff bit_ = 0* ^| ~63~ ^| ~62~ ^| ~61~ ^| ~60~ ^| ~59~ ^| ~58~ ^| ~57~ ^| ~56~ ^| ~55~ ^| ~54~ ^| ~53~ ^| ~52~ ^| ~51~ ^| ~50~ ^| ~49~ ^| ~48~ 4+^| Base color 1 @@ -156,7 +157,7 @@ _bit_ 16+^| *Less significant pixel index bits* ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ ^| _p_^0^ ^| _o_^0^ ^| _n_^0^ ^| _m_^0^ ^| _l_^0^ ^| _k_^0^ ^| _j_^0^ ^| _i_^0^ ^| _h_^0^ ^| _g_^0^ ^| _f_^0^ ^| _e_^0^ ^| _d_^0^ ^| _c_^0^ ^| _b_^0^ ^| _a_^0^ -|==================== +|==== <<< In both modes, the 4{times}4 block is divided into @@ -170,11 +171,11 @@ of each other, as shown in <>. [[ETC12x4]] .Two 2{times}4-pixel ETC1 subblocks side-by-side -image::images/ETC2x4.{svgpdf}[width="{svgpdf@pdf:142pt:213}",align="center"] +image::{images}/ETC2x4.svg[width="{svgpdf@pdf:142pt:213}",align="center"] [[ETC14x2]] .Two 4{times}2-pixel ETC1 subblocks on top of each other -image::images/ETC4x2.{svgpdf}[width="{svgpdf@pdf:142pt:213}",align="center"] +image::{images}/ETC4x2.svg[width="{svgpdf@pdf:142pt:213}",align="center"] In both individual and differential mode, a _base color_ for each subblock is stored, but the way they are stored is different in @@ -186,11 +187,11 @@ subblock 1 is derived from the codewords _R_ (bits 63..60), _G_ of <>. These four bit values are extended to _RGB_:888 by replicating the four higher order bits in the four lower order bits. -For instance, if _R_ = 14 = 1110b, -_G_ = 3 = 0011b and _B_ = 8 = 1000b, +For instance, if _R_{nbsp}={nbsp}14{nbsp}={nbsp}1110b, +_G_{nbsp}={nbsp}3{nbsp}={nbsp}0011b and _B_{nbsp}={nbsp}8{nbsp}={nbsp}1000b, then the red component of the _base color_ of subblock 1 becomes -11101110b = 238, and the green and blue components become -00110011b = 51 and 10001000b = 136. +11101110b{nbsp}={nbsp}238, and the green and blue components become +00110011b{nbsp}={nbsp}51 and 10001000b{nbsp}={nbsp}136. The _base color_ for subblock 2 is decoded the same way, but using the 4-bit codewords _R_~2~ (bits 59..56), _G_~2~ (bits 51..48) and _B_~2~ (bits 43..40) instead. @@ -198,12 +199,12 @@ In summary, the _base colors_ for the subblocks in the individual mode are: [latexmath] -++++++ +++++ \begin{align*} \mathit{base\ color_{subblock1}} & = \mathit{extend\_4to8bits}(\mathit{R}, \mathit{G}, \mathit{B}) \\ \mathit{base\ color_{subblock2}} & = \mathit{extend\_4to8bits}(\mathit{R}_2, \mathit{G}_2, \mathit{B}_2) \end{align*} -++++++ +++++ In the `differential' mode (_diff bit_ = 1), the _base color_ for subblock 1 is derived from the five-bit codewords _R_, @@ -211,34 +212,34 @@ _G_ and _B_. These five-bit codewords are extended to eight bits by replicating the top three highest-order bits to the three lowest order bits. -For instance, if _R _= 28 = 11100b, the resulting -eight-bit red color component becomes 11100111b = 231. -Likewise, if _G _= 4 = 00100b and -_B _= 3 = 00011b, the green and blue components become -00100001b = 33 and 00011000b = 24 respectively. +For instance, if _R{nbsp}_={nbsp}28{nbsp}={nbsp}11100b, the resulting +eight-bit red color component becomes 11100111b{nbsp}={nbsp}231. +Likewise, if _G{nbsp}_={nbsp}4{nbsp}={nbsp}00100b and +_B{nbsp}_={nbsp}3{nbsp}={nbsp}00011b, the green and blue components become +00100001b{nbsp}={nbsp}33 and 00011000b{nbsp}={nbsp}24 respectively. Thus, in this example, the _base color_ for subblock 1 -is (231, 33, 24). The five-bit representation for the _base color_ +is (231,{nbsp}33,{nbsp}24). The five-bit representation for the _base color_ of subblock 2 is obtained by modifying the five-bit codewords _R_, _G_ and _B_ by the codewords _R_~d~, _G_~d~ and _B_~d~. Each of _R_~d~, _G_~d~ and _B_~d~ is a three-bit two's-complement number that can hold values between -4 and {plus}3. -For instance, if _R_= 28 as above, an -_R_~d~ = 100b = -4, then the five-bit representation for -the red color component is 28{plus}(-4) = 24 = 11000b, -which is then extended to eight bits, to 11000110b = 198. -Likewise, if _G _= 4, _G_~d~ = 2, -_B_ = 3 and _B_~d~ = 0, the _base color_ of -subblock 2 will be _RGB _= (198, 49, 24). +For instance, if _R_={nbsp}28 as above, an +_R_~d~{nbsp}={nbsp}100b{nbsp}={nbsp}-4, then the five-bit representation for +the red color component is 28{plus}(-4){nbsp}={nbsp}24{nbsp}={nbsp}11000b, +which is then extended to eight bits, to 11000110b{nbsp}={nbsp}198. +Likewise, if _G{nbsp}_={nbsp}4, _G_~d~{nbsp}={nbsp}2, +_B_{nbsp}={nbsp}3 and _B_~d~{nbsp}={nbsp}0, the _base color_ of +subblock 2 will be _RGB{nbsp}_={nbsp}(198,{nbsp}49,{nbsp}24). In summary, the _base colors_ for the subblocks in the differential mode are: [latexmath] -++++++ +++++ \begin{align*} \mathit{base\ color_{subblock1}} & = \mathit{extend\_5to8bits}(\mathit{R}, \mathit{G}, \mathit{B}) \\ \mathit{base\ color_{subblock2}} & = \mathit{extend\_5to8bits}(\mathit{R}+\mathit{R}_\mathrm{d}, \mathit{G}+\mathit{G}_\mathrm{d}, \mathit{B}+\mathit{B}_\mathrm{d}) \end{align*} -++++++ +++++ Note that these additions are not allowed to under- or overflow (go below zero or above 31). (The compression scheme can easily @@ -254,7 +255,7 @@ is used (bits 39..37), and for subblock 2, table codeword 2 is used (bits 36..34), see <>. The table codeword is used to select one of eight modifier tables, see <>. For instance, if the table code word is 010b = 2, then the modifier -table [-29,{nbsp}-9, 9, 29] is selected. +table [-29,{nbsp}-9,{nbsp}9,{nbsp}29] is selected. Note that the values in <> are valid for all textures and can therefore be hardcoded into the decompression unit. @@ -268,48 +269,48 @@ that the pixel index for a particular texel is always stored in the same bit position, irrespectively of bits _diff bit_ and _flip bit_. The pixel index bits are decoded using <>. If, for instance, the pixel index bits are 01b = 1, and -the modifier table [-29, -9, 9, 29] is used, then the modifier +the modifier table [-29,{nbsp}-9,{nbsp}9,{nbsp}29] is used, then the modifier value selected for that pixel is 29 (see <>). This modifier value is now used to additively modify the base -color. For example, if we have the base color (231, 8, 16), we +color. For example, if we have the base color (231,{nbsp}8,{nbsp}16), we should add the modifier value 29 to all three components: -(231{plus}29, 8{plus}29, 16{plus}29) resulting in -(260, 37, 45). These values are then +(231{plus}29,{nbsp}8{plus}29,{nbsp}16{plus}29) resulting in +(260,{nbsp}37,{nbsp}45). These values are then clamped to [0..255], resulting in the color -(255, 37, 45), and we are finished decoding the texel. +(255,{nbsp}37,{nbsp}45), and we are finished decoding the texel. [[ETC1modifiersets]] .Intensity modifier sets for ETC1 compressed textures [cols="2,1,1,1,1",width="48%"] -|============== +|==== ^| *_Table codeword_* 4+^.^| *Modifier table* -^| 0 >| -8   >| -2   >| 2   >| 8   -^| 1 >| -17   >| -5   >| 5   >| 17   -^| 2 >| -29   >| -9   >| 9   >| 29   -^| 3 >| -42   >| -13   >| 13   >| 42   -^| 4 >| -60   >| -18   >| 18   >| 60   -^| 5 >| -80   >| -24   >| 24   >| 80   -^| 6 >| -106   >| -33   >| 33   >| 106   -^| 7 >| -183   >| -47   >| 47   >| 183   -|============== +^| 0 >| -8 {nbsp} >| -2 {nbsp} >| 2 {nbsp} >| 8 {nbsp} +^| 1 >| -17 {nbsp} >| -5 {nbsp} >| 5 {nbsp} >| 17 {nbsp} +^| 2 >| -29 {nbsp} >| -9 {nbsp} >| 9 {nbsp} >| 29 {nbsp} +^| 3 >| -42 {nbsp} >| -13 {nbsp} >| 13 {nbsp} >| 42 {nbsp} +^| 4 >| -60 {nbsp} >| -18 {nbsp} >| 18 {nbsp} >| 60 {nbsp} +^| 5 >| -80 {nbsp} >| -24 {nbsp} >| 24 {nbsp} >| 80 {nbsp} +^| 6 >| -106 {nbsp} >| -33 {nbsp} >| 33 {nbsp} >| 106 {nbsp} +^| 7 >| -183 {nbsp} >| -47 {nbsp} >| 47 {nbsp} >| 183 {nbsp} +|==== [[ETC1modifiermapping]] .Mapping from pixel index values to modifier values for ETC1 compressed textures [cols="1,1,3",width="50%"] -|============ +|==== 2+^| *_Pixel index_ value* .2+^.^| *Resulting modifier value* ^| *MSB* ^| *LSB* -^| 1 ^| 1 |   -b (large negative value) -^| 1 ^| 0 |   -a (small negative value) -^| 0 ^| 0 |   {plus}a (small positive value) -^| 0 ^| 1 |   {plus}b (large positive value) -|============ +^| 1 ^| 1 | {nbsp} -b (large negative value) +^| 1 ^| 0 | {nbsp} -a (small negative value) +^| 0 ^| 0 | {nbsp} {plus}a (small positive value) +^| 0 ^| 1 | {nbsp} {plus}b (large positive value) +|==== [NOTE] ==== ETC1 is a proper subset of ETC2. -There are examples of ``<>'' and -``<>'' decoding in <>. +There are examples of "`<>`" and +"`<>`" decoding in <>. ==== [[ETC1S]] diff --git a/etc2.txt b/chapters/etc2.adoc similarity index 78% rename from etc2.txt rename to chapters/etc2.adoc index 711ed96..d796489 100644 --- a/etc2.txt +++ b/chapters/etc2.adoc @@ -1,9 +1,10 @@ -// Copyright (c) 2014-2019 The Khronos Group Inc. -// Copyright notice at https://www.khronos.org/registry/speccopyright.html +// Copyright 2014-2026 The Khronos Group Inc. +// SPDX-License-Identifier: CC-BY-4.0 + [[ETC2]] == ETC2 Compressed Texture Image Formats -_This description is derived from the ``ETC Compressed Texture Image Formats'' +_This description is derived from the "`ETC Compressed Texture Image Formats`" section of the OpenGL 4.4 specification._ The ETC formats form a family of related compressed texture image formats. @@ -55,9 +56,9 @@ _Signed RG11 EAC_ is a two-channel signed format. Each channel is decoded exactly as signed R11 EAC. -_RGB ETC2 with ``punchthrough'' alpha_ is very similar to +_RGB ETC2 with "`punchthrough`" alpha_ is very similar to RGB ETC2, but has the ability to represent -``punchthrough'' alpha (completely opaque or transparent). Each block +"`punchthrough`" alpha (completely opaque or transparent). Each block can select to be completely opaque using one bit. To fit this bit, there is no individual mode in RGB ETC2 with punchthrough alpha. In other respects, @@ -76,7 +77,7 @@ described as a number of 4{times}4 pixel blocks. <<< Pixel _a_~1~ (see <>) of the first block in -memory will represent the texture coordinate (_u_=0,_ v_=0). Pixel +memory will represent the texture coordinate (_u_=0,_{nbsp}v_=0). Pixel _a_~2~ in the second block in memory will be adjacent to pixel _m_~1~ in the first block, etc. until the width of the texture. Then pixel _a_~3~ in the following block (third block in memory for an 8{times}8 @@ -98,7 +99,7 @@ _d_~3~ _h_~3~ _l_~3~ _p_~3~ _d_~4~ _h_~4~ _l_~4~ _p_~4~. [[ETC28x8]] .Pixel layout for an 8×8 texture using four ETC2 compressed blocks -image::images/ETCletter8x8.{svgpdf}[width="{svgpdf@pdf:218pt:327}",align="center"] +image::{images}/ETCletter8x8.svg[width="{svgpdf@pdf:218pt:327}",align="center"] Note how pixel _a_~3~ in the third block is adjacent to pixel _d_~1~ in the first block. @@ -107,7 +108,7 @@ not a multiple of four, then padding is added to ensure that the texture contains a whole number of 4{times}4 blocks in each dimension. The padding does not affect the texel coordinates. For example, the texel shown as _a_~1~ in <> -always has coordinates (_i_=0,_ j_=0). The values of padding texels +always has coordinates (_i_=0,_{nbsp}j_=0). The values of padding texels are irrelevant, e.g., in a 3{times}3 texture, the texels marked as _m_~1~, _n_~1~, _o_~1~, _d_~1~, _h_~1~, _l_~1~ and _p_~1~ form padding and have no effect on the final texture image. @@ -122,11 +123,11 @@ _q_~0~ is located at the lowest memory address and _q_~7~ at the highest. The 64 bits specifying the block are then represented by the following 64 bit integer: [latexmath] -++++++ +++++ \begin{align*} \mathit{int64bit} & = 256\times (256\times (256\times (256\times (256\times (256\times (256\times q_0+q_1)+q_2)+q_3)+q_4)+q_5)+q_6)+q_7 \end{align*} -++++++ +++++ The number of bits that represent a 4{times}4 texel block is 128 bits if the format is RGBA ETC2 with a linear or sRGB transfer function. In @@ -140,12 +141,12 @@ This is split into two 64-bit integers, one used for color channel decompression and one for alpha channel decompression: [latexmath] -++++++ +++++ \begin{align*} \mathit{int64bit_{Alpha}} & = 256\times (256\times (256\times (256\times (256\times (256\times (256\times q_0+q_1)+q_2)+q_3)+q_4)+q_5)+q_6)+q_7 \\ \mathit{int64bit_{Color}} & = 256\times (256\times (256\times (256\times (256\times (256\times (256\times q_8+q_9)+q_{10})+q_{11})+q_{12})+q_{13})+q_{14})+q_{15} \end{align*} -++++++ +++++ <<< @@ -158,36 +159,36 @@ a three-channel 4{times}4 pixel block as shown in [[Figure-etc2-pixellayout]] .Pixel layout for an ETC2 compressed block -image::images/ETCletterdirections.{svgpdf}[width="{svgpdf@pdf:115pt:173}",align="center"] +image::{images}/ETCletterdirections.svg[width="{svgpdf@pdf:115pt:173}",align="center"] [[Table-etc2-dataformat]] .Texel Data format for ETC2 compressed texture formats [cols="1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1",width="97%"] -|==================== -32+| [[ETC2ModeSelection]]  *a) Location of bits for mode selection* +|==== +32+| [[ETC2ModeSelection]]{nbsp} *a) Location of bits for mode selection* ^| ~63~ ^| ~62~ ^| ~61~ ^| ~60~ ^| ~59~ ^| ~58~ ^| ~57~ ^| ~56~ ^| ~55~ ^| ~54~ ^| ~53~ ^| ~52~ ^| ~51~ ^| ~50~ ^| ~49~ ^| ~48~ ^| ~47~ ^| ~46~ ^| ~45~ ^| ~44~ ^| ~43~ ^| ~42~ ^| ~41~ ^| ~40~ ^| ~39~ ^| ~38~ ^| ~37~ ^| ~36~ ^| ~35~ ^| ~34~ ^| ~33~ ^| ~32~ 5+^| _R_ 3+^| _R_~d~ 5+^| _G_ 3+^| _G_~d~ 5+^| _B_ 3+^| _B_~d~ 6+^| ...... ^| _D_ ^| . -32+| [[ETC2IndividualLayout]]  *b) Bit layout for bits 63 through 32 for `individual' mode* +32+| [[ETC2IndividualLayout]]{nbsp} *b) Bit layout for bits 63 through 32 for `individual' mode* ^| ~63~ ^| ~62~ ^| ~61~ ^| ~60~ ^| ~59~ ^| ~58~ ^| ~57~ ^| ~56~ ^| ~55~ ^| ~54~ ^| ~53~ ^| ~52~ ^| ~51~ ^| ~50~ ^| ~49~ ^| ~48~ ^| ~47~ ^| ~46~ ^| ~45~ ^| ~44~ ^| ~43~ ^| ~42~ ^| ~41~ ^| ~40~ ^| ~39~ ^| ~38~ ^| ~37~ ^| ~36~ ^| ~35~ ^| ~34~ ^| ~33~ ^| ~32~ 4+^| _R_ 4+^| _R_~2~ 4+^| _G_ 4+^| _G_~2~ 4+^| _B_ 4+^| _B_~2~ 3+^| _table_~1~ 3+^| _table_~2~ ^| 0 ^| _F~B~_ -32+| [[ETC2DifferentialLayout]]  *c) Bit layout for bits 63 through 32 for `differential' mode* +32+| [[ETC2DifferentialLayout]]{nbsp} *c) Bit layout for bits 63 through 32 for `differential' mode* ^| ~63~ ^| ~62~ ^| ~61~ ^| ~60~ ^| ~59~ ^| ~58~ ^| ~57~ ^| ~56~ ^| ~55~ ^| ~54~ ^| ~53~ ^| ~52~ ^| ~51~ ^| ~50~ ^| ~49~ ^| ~48~ ^| ~47~ ^| ~46~ ^| ~45~ ^| ~44~ ^| ~43~ ^| ~42~ ^| ~41~ ^| ~40~ ^| ~39~ ^| ~38~ ^| ~37~ ^| ~36~ ^| ~35~ ^| ~34~ ^| ~33~ ^| ~32~ 5+^| _R_ 3+^| _R_~d~ 5+^| _G_ 3+^| _G_~d~ 5+^| _B_ 3+^| _B_~d~ 3+^| _table_~1~ 3+^| _table_~2~ ^| 1 ^| _F~B~_ -32+| [[ETC2TLayout]]  *d) Bit layout for bits 63 through 32 for `T' mode* +32+| [[ETC2TLayout]]{nbsp} *d) Bit layout for bits 63 through 32 for `T' mode* ^| ~63~ ^| ~62~ ^| ~61~ ^| ~60~ ^| ~59~ ^| ~58~ ^| ~57~ ^| ~56~ ^| ~55~ ^| ~54~ ^| ~53~ ^| ~52~ ^| ~51~ ^| ~50~ ^| ~49~ ^| ~48~ ^| ~47~ ^| ~46~ ^| ~45~ ^| ~44~ ^| ~43~ ^| ~42~ ^| ~41~ ^| ~40~ ^| ~39~ ^| ~38~ ^| ~37~ ^| ~36~ ^| ~35~ ^| ~34~ ^| ~33~ ^| ~32~ 3+^| ... 2+^| _R_^3..2^ ^| . 2+^| _R_^1..0^ 4+^| _G_ 4+^| _B_ 4+^| _R_~2~ 4+^| _G_~2~ 4+^| _B_~2~ 2+^| _d_~a~ ^| 1 ^| _d_~b~ -32+| [[ETC2HLayout]]  *e) Bit layout for bits 63 through 32 for `H' mode* +32+| [[ETC2HLayout]]{nbsp} *e) Bit layout for bits 63 through 32 for `H' mode* ^| ~63~ ^| ~62~ ^| ~61~ ^| ~60~ ^| ~59~ ^| ~58~ ^| ~57~ ^| ~56~ ^| ~55~ ^| ~54~ ^| ~53~ ^| ~52~ ^| ~51~ ^| ~50~ ^| ~49~ ^| ~48~ ^| ~47~ ^| ~46~ ^| ~45~ ^| ~44~ ^| ~43~ ^| ~42~ ^| ~41~ ^| ~40~ ^| ~39~ ^| ~38~ ^| ~37~ ^| ~36~ ^| ~35~ ^| ~34~ ^| ~33~ ^| ~32~ ^| . 4+^| _R_ 3+^| _G_^3..1^ 3+^| ... ^| _G_^0^ ^| _B_^3^ ^| . 3+^| _B_^2..0^ 4+^| _R_~2~ 4+^| _G_~2~ 4+^| _B_~2~ ^| _d~a~_ ^| 1 ^| _d~b~_ -32+| [[ETC2LowBits]]  *f) Bit layout for bits 31 through 0 for `individual', `differential', `T' and `H' modes* +32+| [[ETC2LowBits]]{nbsp} *f) Bit layout for bits 31 through 0 for `individual', `differential', `T' and `H' modes* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ ^| _p_^1^ ^| _o_^1^ ^| _n_^1^ ^| _m_^1^ ^| _l_^1^ ^| _k_^1^ ^| _j_^1^ ^| _i_^1^ ^| _h_^1^ ^| _g_^1^ ^| _f_^1^ ^| _e_^1^ ^| _d_^1^ ^| _c_^1^ ^| _b_^1^ ^| _a_^1^ ^| _p_^0^ ^| _o_^0^ ^| _n_^0^ ^| _m_^0^ ^| _l_^0^ ^| _k_^0^ ^| _j_^0^ ^| _i_^0^ ^| _h_^0^ ^| _g_^0^ ^| _f_^0^ ^| _e_^0^ ^| _d_^0^ ^| _c_^0^ ^| _b_^0^ ^| _a_^0^ -32+| [[ETC2Planar]]  *g) Bit layout for bits 63 through 0 for `planar' mode* +32+| [[ETC2Planar]]{nbsp} *g) Bit layout for bits 63 through 0 for `planar' mode* ^| ~63~ ^| ~62~ ^| ~61~ ^| ~60~ ^| ~59~ ^| ~58~ ^| ~57~ ^| ~56~ ^| ~55~ ^| ~54~ ^| ~53~ ^| ~52~ ^| ~51~ ^| ~50~ ^| ~49~ ^| ~48~ ^| ~47~ ^| ~46~ ^| ~45~ ^| ~44~ ^| ~43~ ^| ~42~ ^| ~41~ ^| ~40~ ^| ~39~ ^| ~38~ ^| ~37~ ^| ~36~ ^| ~35~ ^| ~34~ ^| ~33~ ^| ~32~ ^| . 6+^| _R_ ^| _G_^6^ ^| . 6+^| _G_^5..0^ ^| _B_^5^ 3+^| ... 2+^| _B_^4..3^ ^| . 3+^| _B_^2..0^ 5+^| _R_~h~^5..1^ ^| 1 ^| _R~h~_^0^ ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 7+^| _G_~h~ 6+^| _B_~h~ 6+^| _R_~v~ 7+^| _G_~v~ 6+^| _B_~v~ -|==================== +|==== <<< @@ -226,11 +227,11 @@ they are stored is different in the two modes: [[Table-etc2-sidebyside]] .Two 2{times}4-pixel ETC2 subblocks side-by-side -image::images/ETC2x4.{svgpdf}[width="{svgpdf@pdf:142pt:213}",align="center"] +image::{images}/ETC2x4.svg[width="{svgpdf@pdf:142pt:213}",align="center"] [[Table-etc2-ontop]] .Two 4{times}2-pixel ETC2 subblocks on top of each other -image::images/ETC4x2.{svgpdf}[width="{svgpdf@pdf:142pt:213}",align="center"] +image::{images}/ETC4x2.svg[width="{svgpdf@pdf:142pt:213}",align="center"] In the `individual' mode, following the layout shown in <> of <>, the @@ -248,12 +249,12 @@ instead. In summary, the _base colors_ for the subblocks in the individual mode are: [latexmath] -++++++ +++++ \begin{align*} \mathit{base\ color_{subblock1}} & = \mathit{extend4to8bits}(\mathit{R}, \mathit{G}, \mathit{B}) \\ \mathit{base\ color_{subblock2}} & = \mathit{extend4to8bits}(\mathit{R}_2, \mathit{G}_2, \mathit{B}_2) \end{align*} -++++++ +++++ <<< @@ -262,36 +263,36 @@ In the `differential' mode, following the layout shown in _base color_ for subblock 1 is derived from the five-bit codewords _R_, _G_ and _B_. These five-bit codewords are extended to eight bits by replicating the top three highest-order bits to the three lowest-order bits. -For instance, if _R_ = 28 = 11100b, the resulting eight-bit -red color component becomes 11100111b = 231. -Likewise, if _G_ = 4 = 00100b and -_B_ = 3 = 00011b, the green and blue components become +For instance, if _R_{nbsp}={nbsp}28{nbsp}={nbsp}11100b, the resulting eight-bit +red color component becomes 11100111b{nbsp}={nbsp}231. +Likewise, if _G_{nbsp}={nbsp}4{nbsp}={nbsp}00100b and +_B_{nbsp}={nbsp}3{nbsp}={nbsp}00011b, the green and blue components become 00100001b = 33 and 00011000b = 24 respectively. Thus, in this example, the _base color_ for subblock 1 is -(231, 33, 24). +(231,{nbsp}33,{nbsp}24). The five-bit representation for the _base color_ of subblock 2 is obtained by modifying the five-bit codewords _R_, _G_ and _B_ by the codewords _R_~d~, _G_~d~ and _B_~d~. Each of _R_~d~, _G_~d~ and _B_~d~ is a 3-bit two's-complement number that can hold values between -4 and {plus}3. -For instance, if _R_ = 28 as above, and -_R_~d~ = 100b = y - 4, +For instance, if _R_{nbsp}={nbsp}28 as above, and +_R_~d~{nbsp}={nbsp}100b{nbsp}={nbsp}y{nbsp}-{nbsp}4, then the five bit representation for the red color component is -28{plus}(-4) = 24 = 11000b, which is then extended to -eight bits to 11000110b = 198. -Likewise, if _G_ = 4, _G_~d~ = 2, _B_ = 3 and -_B_~d~ = 0, the _base color_ of subblock 2 will be -_RGB _= 198, 49, 24. +28{plus}(-4){nbsp}={nbsp}24{nbsp}={nbsp}11000b, which is then extended to +eight bits to 11000110b{nbsp}={nbsp}198. +Likewise, if _G_{nbsp}={nbsp}4, _G_~d~{nbsp}={nbsp}2, _B_{nbsp}={nbsp}3 and +_B_~d~{nbsp}={nbsp}0, the _base color_ of subblock 2 will be +_RGB{nbsp}_={nbsp}198,{nbsp}49,{nbsp}24. In summary, the _base colors_ for the subblocks in the `differential' mode are: [latexmath] -++++++ +++++ \begin{align*} \mathit{base\ color_{subblock1}} & = \mathit{extend5to8bits}(\mathit{R}, \mathit{G}, \mathit{B}) \\ \mathit{base\ color_{subblock2}} & = \mathit{extend5to8bits}(\mathit{R}+\mathit{R}_\mathrm{d}, \mathit{G}+\mathit{G}_\mathrm{d}, \mathit{B}+\mathit{B}_\mathrm{d}) \end{align*} -++++++ +++++ Note that these additions will not under- or overflow, or one of the alternative decompression modes would have been chosen instead of the @@ -304,37 +305,37 @@ using the _table codewords_: For subblock 1, _table codeword 1_ is used 36..34), see <> or <> of <>. The _table codeword_ is used to select one of eight modifier tables, see <>. For -instance, if the _table codeword_ is 010 binary = 2, then the modifier -table [-29, -9, 9, 29] is selected for the corresponding sub-block. +instance, if the _table codeword_ is 010{nbsp}binary{nbsp}={nbsp}2, then the modifier +table [-29,{nbsp}-9,{nbsp}9,{nbsp}29] is selected for the corresponding sub-block. Note that the values in <> are valid for all textures and can therefore be hardcoded into the decompression unit. [[Table-etc2-modifiers]] .ETC2 intensity modifier sets for `individual' and `differential' modes [cols="2,1,1,1,1",width="45%"] -|============== +|==== ^| *_Table codeword_* 4+^.^| Modifier table -^| 0 >| -8   >| -2   >| 2   >| 8   -^| 1 >| -17   >| -5   >| 5   >| 17   -^| 2 >| -29   >| -9   >| 9   >| 29   -^| 3 >| -42   >| -13   >| 13   >| 42   -^| 4 >| -60   >| -18   >| 18   >| 60   -^| 5 >| -80   >| -24   >| 24   >| 80   -^| 6 >| -106   >| -33   >| 33   >| 106   -^| 7 >| -183   >| -47   >| 47   >| 183   -|============== +^| 0 >| -8 {nbsp} >| -2 {nbsp} >| 2 {nbsp} >| 8 {nbsp} +^| 1 >| -17 {nbsp} >| -5 {nbsp} >| 5 {nbsp} >| 17 {nbsp} +^| 2 >| -29 {nbsp} >| -9 {nbsp} >| 9 {nbsp} >| 29 {nbsp} +^| 3 >| -42 {nbsp} >| -13 {nbsp} >| 13 {nbsp} >| 42 {nbsp} +^| 4 >| -60 {nbsp} >| -18 {nbsp} >| 18 {nbsp} >| 60 {nbsp} +^| 5 >| -80 {nbsp} >| -24 {nbsp} >| 24 {nbsp} >| 80 {nbsp} +^| 6 >| -106 {nbsp} >| -33 {nbsp} >| 33 {nbsp} >| 106 {nbsp} +^| 7 >| -183 {nbsp} >| -47 {nbsp} >| 47 {nbsp} >| 183 {nbsp} +|==== [[Table-etc2-pixelindices]] .Mapping from pixel index values to modifier values for RGB ETC2 compressed textures [cols="1,1,3",width="50%"] -|============ +|==== 2+^.^| *_Pixel index_ value* .2+^.^| *Resulting _modifier_ value* ^| *MSB* ^| *LSB* -^| 1 ^| 1 |   -b (large negative value) -^| 1 ^| 0 |   -a (small negative value) -^| 0 ^| 0 |   {plus}a (small positive value) -^| 0 ^| 1 |   {plus}b (large positive value) -|============ +^| 1 ^| 1 | {nbsp} -b (large negative value) +^| 1 ^| 0 | {nbsp} -a (small negative value) +^| 0 ^| 0 | {nbsp} {plus}a (small positive value) +^| 0 ^| 1 | {nbsp} {plus}b (large positive value) +|==== Next, we identify which _modifier_ value to use from the modifier table using the two _pixel index_ bits. The _pixel index_ bits are unique for @@ -347,14 +348,14 @@ the same bit position, irrespectively of bits _diff bit_ and _flip bit_. The _pixel index_ bits are decoded using <>. If, for instance, the _pixel index_ bits are 01 binary = 1, and the -modifier table [-29, -9, 9, 29] is used, then the _modifier_ +modifier table [-29,{nbsp}-9,{nbsp}9,{nbsp}29] is used, then the _modifier_ value selected for that pixel is 29 (see <>). This _modifier_ value is now used to additively modify the _base color_. -For example, if we have the _base color_ (231, 8, 16), we should add -the _modifier_ value 29 to all three components: (231+29, 8+29, 16+29) -resulting in (260, 37, 45). +For example, if we have the _base color_ (231,{nbsp}8,{nbsp}16), we should add +the _modifier_ value 29 to all three components: (231+29,{nbsp}8+29,{nbsp}16+29) +resulting in (260,{nbsp}37,{nbsp}45). These values are then clamped to [0..255], resulting in the color -(255, 37, 45), and we are finished decoding the texel. +(255,{nbsp}37,{nbsp}45), and we are finished decoding the texel. [NOTE] ==== @@ -365,42 +366,42 @@ to each channel to give the `paint colors' selectable by each _pixel index_, shown as small diamonds. Since the same _modifier_ is applied to each channel, each _paint color_ for a subblock falls on a line (shown dashed) parallel to the grayscale -(0, 0, 0) to (255, 255, 255) axis, unless the +(0,{nbsp}0,{nbsp}0) to (255,{nbsp}255,{nbsp}255) axis, unless the channels are modified by clamping to the range [0..255]. [[Figure-etc2-individual]] .ETC2 `individual' mode -image::images/ETC1Ind.{svgpdf}[width="{svgpdf@pdf:190.5pt:382.5}",align="center"] +image::{images}/ETC1Ind.svg[width="{svgpdf@pdf:190.5pt:382.5}",align="center"] In this example, one _base color_ is encoded as the 4-bit triple -(4, 11, 9), which is expanded by _extend4to8bits_ to -(68, 187, 153). -Modifier table 4 [-60, -18, 18, 60] is selected for this subblock, +(4,{nbsp}11,{nbsp}9), which is expanded by _extend4to8bits_ to +(68,{nbsp}187,{nbsp}153). +Modifier table 4 [-60,{nbsp}-18,{nbsp}18,{nbsp}60] is selected for this subblock, giving the following _paint colors_: [options="header",width="25%",cols="2,1,1,1"] -|===== +|==== ^| Modifier ^| _R_ ^| _G_ ^| _B_ -^| -60   >| 8   >| 127   >| 93   -^| -18   >| 58   >| 169   >| 135   -^| 18   >| 86   >| 205   >| 171   -^| 60   >| 128   >| 247   >| 213   -|===== +^| -60 {nbsp} >| 8 {nbsp} >| 127 {nbsp} >| 93 {nbsp} +^| -18 {nbsp} >| 58 {nbsp} >| 169 {nbsp} >| 135 {nbsp} +^| 18 {nbsp} >| 86 {nbsp} >| 205 {nbsp} >| 171 {nbsp} +^| 60 {nbsp} >| 128 {nbsp} >| 247 {nbsp} >| 213 {nbsp} +|==== The other _base color_ is encoded as the 4-bit triple -(14, 3, 8), which is expanded by _extend4to8bits_ to -(238, 51, 136). -Modifier table 0 [-8, -2, 2, 8] is selected for this +(14,{nbsp}3,{nbsp}8), which is expanded by _extend4to8bits_ to +(238,{nbsp}51,{nbsp}136). +Modifier table 0 [-8,{nbsp}-2,{nbsp}2,{nbsp}8] is selected for this subblock, giving the following _paint colors_ for the subblock: [options="header",width="25%",cols="2,1,1,1"] -|===== +|==== ^| Modifier ^| _R_ ^| _G_ ^| _B_ -^| -8 >| 230   >| 43   >| 128   -^| -2 >| 236   >| 49   >| 134   -^| 2 >| 240   >| 53   >| 138   -^| 8 >| 246   >| 59   >| 144   -|===== +^| -8 >| 230 {nbsp} >| 43 {nbsp} >| 128 {nbsp} +^| -2 >| 236 {nbsp} >| 49 {nbsp} >| 134 {nbsp} +^| 2 >| 240 {nbsp} >| 53 {nbsp} >| 138 {nbsp} +^| 8 >| 246 {nbsp} >| 59 {nbsp} >| 144 {nbsp} +|==== In this example, none of the _paint colors_ are modified by the process of clipping the channels to the range [0..255]. @@ -421,26 +422,26 @@ _Modifiers_ to the _base colors_ give `paint colors' selectable by each _pixel index_, shown as small diamonds. Since the same _modifier_ is applied to each channel, each _paint color_ for a subblock falls on a line (shown dashed) parallel to the grayscale -(0, 0, 0) to (255, 255, 255) axis, unless channels are +(0,{nbsp}0,{nbsp}0) to (255,{nbsp}255,{nbsp}255) axis, unless channels are modified by clamping to [0..255]. [[Figure-etc2-differential]] .ETC2 `differential' mode -image::images/ETC1Diff.{svgpdf}[width="{svgpdf@pdf:190.5pt:382.5}",align="center"] +image::{images}/ETC1Diff.svg[width="{svgpdf@pdf:190.5pt:382.5}",align="center"] Here the first subblock's _base color_ is encoded as the 5-bit triple -(29, 26, 8), and expanded by _extend5to8bits_ to -(239, 214, 66). +(29,{nbsp}26,{nbsp}8), and expanded by _extend5to8bits_ to +(239,{nbsp}214,{nbsp}66). Note that not every color representable in `individual mode', exists in `differential mode', or vice-versa. -  +{nbsp} The _base color_ of subblock 2 is the five-bit representation of the -_base color_ of subblock 1 (29, 26, 8) plus a -(_R_~d~,_ G_~d~,_ B_~d~) offset of (-4, -3, {plus}3), -for a new _base color_ of (25, 23, 11) - expanded by -_extend5to8bits_ to (206, 189, 90). +_base color_ of subblock 1 (29,{nbsp}26,{nbsp}8) plus a +(_R_~d~,_{nbsp}G_~d~,_{nbsp}B_~d~) offset of (-4,{nbsp}-3,{nbsp}{plus}3), +for a new _base color_ of (25,{nbsp}23,{nbsp}11) - expanded by +_extend5to8bits_ to (206,{nbsp}189,{nbsp}90). The offset cannot exceed the range [0..31] (expanded to [0..255]): this would select the `T', `H' or `planar' modes. For `differential mode', the _base colors_ must be similar in each @@ -448,34 +449,34 @@ channel. The two's complement offset gives an asymmetry: we could not swap the subblocks of this example, since a _R_~d~ offset of {plus}4 is unrepresentable. -  +{nbsp} -In this example, modifier table 2 [-29, -9, 9, 29] is -applied to subblock 1's _base color_ of (239, 214, 66): +In this example, modifier table 2 [-29,{nbsp}-9,{nbsp}9,{nbsp}29] is +applied to subblock 1's _base color_ of (239,{nbsp}214,{nbsp}66): [options="header",width="25%",cols="2,1,1,1"] -|===== +|==== ^| Modifier ^| _R_ ^| _G_ ^| _B_ -^| -29 >| 210   >| 185   >| 37   -^| -9 >| 230   >| 205   >| 57   -^| 9 >| 248   >| 223   >| 75   -^| 29 >| 268   >| 243   >| 95   -|===== +^| -29 >| 210 {nbsp} >| 185 {nbsp} >| 37 {nbsp} +^| -9 >| 230 {nbsp} >| 205 {nbsp} >| 57 {nbsp} +^| 9 >| 248 {nbsp} >| 223 {nbsp} >| 75 {nbsp} +^| 29 >| 268 {nbsp} >| 243 {nbsp} >| 95 {nbsp} +|==== -The last row is clamped to (255, 243, 95), so subblock 1's +The last row is clamped to (255,{nbsp}243,{nbsp}95), so subblock 1's _paint colors_ are not colinear in this example. With _modifiers_, all grays [0..255] are representable. -Similarly, modifier table 3 [-42, -13, 13, 42] is applied to -the _base color_ of subblock 2, (206, 189, 90): +Similarly, modifier table 3 [-42,{nbsp}-13,{nbsp}13,{nbsp}42] is applied to +the _base color_ of subblock 2, (206,{nbsp}189,{nbsp}90): [options="header",width="25%",cols="2,1,1,1"] -|===== +|==== ^| Modifier ^| _R_ ^| _G_ ^| _B_ -^| -42 >| 164   >| 147   >| 48   -^| -13 >| 193   >| 176   >| 77   -^| 13 >| 219   >| 202   >| 103   -^| 42 >| 248   >| 231   >| 132   -|===== +^| -42 >| 164 {nbsp} >| 147 {nbsp} >| 48 {nbsp} +^| -13 >| 193 {nbsp} >| 176 {nbsp} >| 77 {nbsp} +^| 13 >| 219 {nbsp} >| 202 {nbsp} >| 103 {nbsp} +^| 42 >| 248 {nbsp} >| 231 {nbsp} >| 132 {nbsp} +|==== ==== @@ -490,24 +491,24 @@ are not stored sequentially, but in the layout shown in colors are constructed as follows: [latexmath] -++++++ +++++ \begin{align*} \mathit{base\ color\ 1} & = \mathit{extend4to8bits}(\: (\mathit{R}^{3..2} \ll 2)\: | \: \mathit{R}^{1..0}, \: \mathit{G}, \: \mathit{B}) \\ \mathit{base\ color\ 2} & = \mathit{extend4to8bits}(\mathit{R}_2, \: \mathit{G}_2, \: \mathit{B}_2) \end{align*} -++++++ +++++ -Here, latexmath:[$\ll$] denotes bit-wise left shift and latexmath:[$|$] +Here, latexmath:[\ll] denotes bit-wise left shift and latexmath:[|] denotes bit-wise OR. In the `H' mode, the two colors are constructed as follows: [latexmath] -++++++ +++++ \begin{align*} \mathit{base\ color\ 1} & = \mathit{extend4to8bits}(\mathit{R}, \: (\mathit{G}^{3..1} \ll 1) \: | \: \mathit{G}^0, \: (\mathit{B}^3 \ll 3) \: | \: \mathit{B}^{2..0}) \\ \mathit{base\ color\ 2} & = \mathit{extend4to8bits}(\mathit{R}_2, \: \mathit{G}_2, \: \mathit{B}_2) \end{align*} -++++++ +++++ Both the `T' and `H' modes have four _paint colors_ which are the colors that will be used in the decompressed block, but they are @@ -519,7 +520,7 @@ determined, which will be used to modify the luminance of one of the _base colors_. This is done by combining the values _d~a~_ and _d~b~_ shown in <> of <> by -(_d~a~_ latexmath:[$\ll$] 1) | _d~b~_, +(_d~a~_ latexmath:[\ll] 1) | _d~b~_, and then using this value as an index into the small look-up table shown in <>. For example, if _d~a~_ is 10 binary and _d~b~_ is 1 binary, the _distance index_ @@ -531,7 +532,7 @@ the `distance' _d_ subtracted. [[Table-etc2-distancetable]] .Distance table for ETC2 `T' and `H' modes [options="header",width="25%"] -|================ +|==== ^.^| Distance index ^.^| Distance _d_ ^| 0 ^| 3 ^| 1 ^| 6 @@ -541,19 +542,19 @@ the `distance' _d_ subtracted. ^| 5 ^| 32 ^| 6 ^| 41 ^| 7 ^| 64 -|================ +|==== In summary, to determine the four _paint colors_ for a `T' block: [latexmath] -+++++++++++ +++++ \begin{align*} \mathit{paint\ color\ 0} & = \mathit{base\ color\ 1} \\ \mathit{paint\ color\ 1} & = \mathit{base\ color\ 2 + (d, d, d)} \\ \mathit{paint\ color\ 2} & = \mathit{base\ color\ 2} \\ \mathit{paint\ color\ 3} & = \mathit{base\ color\ 2 - (d, d, d)} \end{align*} -+++++++++++ +++++ In both cases, the value of each channel is clamped to within [0..255]. @@ -566,29 +567,29 @@ to _base color 2_ to give the other two `paint colors', shown as small diamonds. Since the same _modifier_ is applied to each channel, _base color 2_ and the two _paint colors_ derived from it fall on a line (shown dashed) parallel -to the grayscale (0, 0, 0) to (255, 255, 255) axis, unless +to the grayscale (0,{nbsp}0,{nbsp}0) to (255,{nbsp}255,{nbsp}255) axis, unless channels are modified by clamping to [0..255]. [[Figure-etc2-T]] .ETC2 `T' mode -image::images/ETC2T.{svgpdf}[width="{svgpdf@pdf:190.5pt:382.5}",align="center"] +image::{images}/ETC2T.svg[width="{svgpdf@pdf:190.5pt:382.5}",align="center"] In this example, the first _base color_ is defined as the triple of 4-bit -_RGB_ values (13, 1, 8), which is expanded by _extend4to8bits_ to -(221, 17, 136). +_RGB_ values (13,{nbsp}1,{nbsp}8), which is expanded by _extend4to8bits_ to +(221,{nbsp}17,{nbsp}136). This becomes _paint color 0_. -  +{nbsp} The second _base color_ is encoded as the triple of 4-bit _RGB_ values -(4, 12, 13), which is expanded by _extend4to8bits_ to -(68, 204, 221). +(4,{nbsp}12,{nbsp}13), which is expanded by _extend4to8bits_ to +(68,{nbsp}204,{nbsp}221). -  +{nbsp} _Distance index_ 5 is used to select a distance value _d_ of 32, which is added to and subtracted from the second base color, giving -(100, 236, 253) as _paint color 1_ and (36, 172, 189) +(100,{nbsp}236,{nbsp}253) as _paint color 1_ and (36,{nbsp}172,{nbsp}189) as _paint color 3_. On this occasion, the channels of these _paint colors_ are not modified by the process of clamping them to [0..255]. @@ -600,21 +601,21 @@ is slightly more complex. In order to construct the three-bit index into the distance table shown in <>, _d~a~_ and _d~b~_ shown in <> of <> are used as the most significant bit and middle bit, respectively, but the least -significant bit is computed as (_base color 1_ value latexmath:[$\geq$] _base color 2_ +significant bit is computed as (_base color 1_ value latexmath:[\geq] _base color 2_ value), the `value' of a color for the comparison being equal to -(_R_ latexmath:[$\ll$] 16) {plus} (_G_ latexmath:[$\ll$] 8) +_ B_. +(_R_{nbsp}latexmath:[\ll]{nbsp}16){nbsp}{plus}{nbsp}(_G_{nbsp}latexmath:[\ll]{nbsp}8){nbsp}+_{nbsp}B_. Once the `distance' _d_ has been determined for an `H' block, the four _paint colors_ will be: [latexmath] -+++++++++++ +++++ \begin{align*} \mathit{paint\ color\ 0} & = \mathit{base\ color\ 1 + (d, d, d)} \\ \mathit{paint\ color\ 1} & = \mathit{base\ color\ 1 - (d, d, d)} \\ \mathit{paint\ color\ 2} & = \mathit{base\ color\ 2 + (d, d, d)} \\ \mathit{paint\ color\ 3} & = \mathit{base\ color\ 2 - (d, d, d)} \end{align*} -+++++++++++ +++++ Again, all color components are clamped to within [0..255]. @@ -626,41 +627,41 @@ to each channel to give the `paint colors' selectable by each _pixel index_, shown as small diamonds. Since the same _modifier_ is applied to each channel, each _paint color_ falls on a line through the _base color_ from which it is derived (shown -dashed) parallel to the grayscale (0, 0, 0) to -(255, 255, 255) axis, unless the channels are modified by clamping +dashed) parallel to the grayscale (0,{nbsp}0,{nbsp}0) to +(255,{nbsp}255,{nbsp}255) axis, unless the channels are modified by clamping to the range [0..255]. [[Figure-etc2-H]] .ETC2 `H' mode -image::images/ETC2H.{svgpdf}[width="{svgpdf@pdf:190.5pt:382.5}",align="center"] +image::{images}/ETC2H.svg[width="{svgpdf@pdf:190.5pt:382.5}",align="center"] In this example, the first _base color_ is defined as the triple of 4-bit -_RGB_ values (13, 1, 8), as in the `T mode' case above. -This is expanded by _extend4to8bits_ to (221, 17, 136). +_RGB_ values (13,{nbsp}1,{nbsp}8), as in the `T mode' case above. +This is expanded by _extend4to8bits_ to (221,{nbsp}17,{nbsp}136). -  +{nbsp} -The second _base color_ is defined as the 4-bit triple (4, 12, 13), -which expands to (68, 204, 221). +The second _base color_ is defined as the 4-bit triple (4,{nbsp}12,{nbsp}13), +which expands to (68,{nbsp}204,{nbsp}221). -  +{nbsp} The block encodes a _distance index_ of 5 (this means that _base color 1_ must be greater than _base color 2_), corresponding to a distance _d_ of 32. This leads to the following _paint colors_: [width="50%",cols="2,1,1,1,2,1,1,1"] -|===== +|==== .2+^.^| *_Paint color_ id* 3+^| *_Base color_* ^| *Distance* 3+^| *_Paint color_* ^| *_R_* ^| *_G_* ^| *_B_* ^| *_d_* ^| *_R_* ^| *_G_* ^| *_B_* -^| 0 .2+>.^| 221 .2+>.^| 17 .2+>.^| 136 ^| {plus}32 >| 253   >| 49   >| 168   -^| 1 ^| -32 >| 189   >| -15   >| 104   -^| 2 .2+>.^| 68 .2+>.^| 204 .2+>.^| 221 ^| {plus}32 >| 100   >| 236   >| 253   -^| 3 ^| -32 >| 36   >| 172   >| 189   -|===== +^| 0 .2+>.^| 221 .2+>.^| 17 .2+>.^| 136 ^| {plus}32 >| 253 {nbsp} >| 49 {nbsp} >| 168 {nbsp} +^| 1 ^| -32 >| 189 {nbsp} >| -15 {nbsp} >| 104 {nbsp} +^| 2 .2+>.^| 68 .2+>.^| 204 .2+>.^| 221 ^| {plus}32 >| 100 {nbsp} >| 236 {nbsp} >| 253 {nbsp} +^| 3 ^| -32 >| 36 {nbsp} >| 172 {nbsp} >| 189 {nbsp} +|==== The _G_ channel of _paint color 1_ is clamped to 0, giving -(189, 0, 104). This stops _paint color_ 1 being +(189,{nbsp}0,{nbsp}104). This stops _paint color_ 1 being colinear with _paint color 0_ and _base color 1_. ==== @@ -698,35 +699,35 @@ With three _base colors_ in _RGB_:888 format, the color of each pixel can then be determined as: [latexmath] -++++++++++++ +++++ \begin{align*} \mathit{R}(x,y) & = {x\times (\mathit{R}_\mathrm{h}-\mathit{R})\over 4.0} + {y\times (\mathit{R}_\mathrm{v}-\mathit{R})\over 4.0} + \mathit{R} \\ \mathit{G}(x,y) & = {x\times (\mathit{G}_\mathrm{h}-\mathit{G})\over 4.0} + {y\times (\mathit{G}_\mathrm{v}-\mathit{G})\over 4.0} + \mathit{G} \\ \mathit{B}(x,y) & = {x\times (\mathit{B}_\mathrm{h}-\mathit{B})\over 4.0} + {y\times (\mathit{B}_\mathrm{v}-\mathit{B})\over 4.0} + \mathit{B} \end{align*} -++++++++++++ +++++ where _x_ and _y_ are values from 0 to 3 corresponding to the pixels coordinates within the block, _x_ being in the _u_ direction and _y_ in the _v_ direction. For example, the pixel _g_ in <> would have -_x _= 1 and _y _= 2. +_x{nbsp}_={nbsp}1 and _y{nbsp}_={nbsp}2. These values are then rounded to the nearest integer (to the larger integer if there is a tie) and then clamped to a value between 0 and 255. Note that this is equivalent to [latexmath] -++++++++++++++ +++++ \begin{align*} \mathit{R}(x,y) & = \mathit{clamp255}((x\times (\mathit{R}_\mathrm{h}-\mathit{R}) + y\times (\mathit{R}_\mathrm{v}-\mathit{R}) + 4\times \mathit{R} + 2) \gg 2) \\ \mathit{G}(x,y) & = \mathit{clamp255}((x\times (\mathit{G}_\mathrm{h}-\mathit{G}) + y\times (\mathit{G}_\mathrm{v}-\mathit{G}) + 4\times \mathit{G} + 2) \gg 2) \\ \mathit{B}(x,y) & = \mathit{clamp255}((x\times (\mathit{B}_\mathrm{h}-\mathit{B}) + y\times (\mathit{B}_\mathrm{v}-\mathit{B}) + 4\times \mathit{B} + 2) \gg 2) \end{align*} -++++++++++++++ +++++ where _clamp255_({cdot}) clamps the value to a number in the range -[0..255] and where latexmath:[$\gg$] performs bit-wise right shift. +[0..255] and where latexmath:[\gg] performs bit-wise right shift. This specification gives the output for each compression mode in 8-bit integer colors between 0 and 255, and these values all need to be @@ -740,40 +741,40 @@ values are shown as small diamonds. [[Figure-etc2-planar]] .ETC2 `planar' mode -image::images/ETC2P.{svgpdf}[width="{svgpdf@pdf:190.5pt:382.5}",align="center"] +image::{images}/ETC2P.svg[width="{svgpdf@pdf:190.5pt:382.5}",align="center"] -In this example, the origin (_R_,_ G_,_ B_) is encoded as the 6-7-6-bit -value (12, 64, 62), which is expanded to (48, 129, 251). +In this example, the origin (_R_,_{nbsp}G_,_{nbsp}B_) is encoded as the 6-7-6-bit +value (12,{nbsp}64,{nbsp}62), which is expanded to (48,{nbsp}129,{nbsp}251). The `horizontal' (interpolated by _x_) _base color_ -(_R_~h~,_ G_~h~,_ B_~h~) = (50, 5, 37) and `vertical' -(interpolated by _y_) _base color_ (_R_~v~,_ G_~v~,_ B_~v~) = -(40, 112, 45) expand to (203, 10, 150) and -(162, 225, 182) respectively. +(_R_~h~,_{nbsp}G_~h~,_{nbsp}B_~h~) = (50,{nbsp}5,{nbsp}37) and `vertical' +(interpolated by _y_) _base color_ (_R_~v~,_{nbsp}G_~v~,_{nbsp}B_~v~) = +(40,{nbsp}112,{nbsp}45) expand to (203,{nbsp}10,{nbsp}150) and +(162,{nbsp}225,{nbsp}182) respectively. -  +{nbsp} The resulting texel colors are then: [options="header",width="25%",cols="1,1,1,1,1"] -|===== +|==== ^| _x_ ^| _y_ ^| _R_ ^| _G_ ^| _B_ -^| 0 ^| 0 >| 48   >| 129   >| 251   -^| 1 ^| 0 >| 87   >| 99   >| 226   -^| 2 ^| 0 >| 126   >| 70   >| 201   -^| 3 ^| 0 >| 164   >| 40   >| 175   -^| 0 ^| 1 >| 77   >| 153   >| 234   -^| 1 ^| 1 >| 115   >| 123   >| 209   -^| 2 ^| 1 >| 154   >| 94   >| 183   -^| 3 ^| 1 >| 193   >| 64   >| 158   -^| 0 ^| 2 >| 105   >| 177   >| 217   -^| 1 ^| 2 >| 144   >| 147   >| 191   -^| 2 ^| 2 >| 183   >| 118   >| 166   -^| 3 ^| 2 >| 221   >| 88   >| 141   -^| 0 ^| 3 >| 134   >| 201   >| 199   -^| 1 ^| 3 >| 172   >| 171   >| 174   -^| 2 ^| 3 >| 211   >| 142   >| 149   -^| 3 ^| 3 >| 250   >| 112   >| 124   -|===== +^| 0 ^| 0 >| 48 {nbsp} >| 129 {nbsp} >| 251 {nbsp} +^| 1 ^| 0 >| 87 {nbsp} >| 99 {nbsp} >| 226 {nbsp} +^| 2 ^| 0 >| 126 {nbsp} >| 70 {nbsp} >| 201 {nbsp} +^| 3 ^| 0 >| 164 {nbsp} >| 40 {nbsp} >| 175 {nbsp} +^| 0 ^| 1 >| 77 {nbsp} >| 153 {nbsp} >| 234 {nbsp} +^| 1 ^| 1 >| 115 {nbsp} >| 123 {nbsp} >| 209 {nbsp} +^| 2 ^| 1 >| 154 {nbsp} >| 94 {nbsp} >| 183 {nbsp} +^| 3 ^| 1 >| 193 {nbsp} >| 64 {nbsp} >| 158 {nbsp} +^| 0 ^| 2 >| 105 {nbsp} >| 177 {nbsp} >| 217 {nbsp} +^| 1 ^| 2 >| 144 {nbsp} >| 147 {nbsp} >| 191 {nbsp} +^| 2 ^| 2 >| 183 {nbsp} >| 118 {nbsp} >| 166 {nbsp} +^| 3 ^| 2 >| 221 {nbsp} >| 88 {nbsp} >| 141 {nbsp} +^| 0 ^| 3 >| 134 {nbsp} >| 201 {nbsp} >| 199 {nbsp} +^| 1 ^| 3 >| 172 {nbsp} >| 171 {nbsp} >| 174 {nbsp} +^| 2 ^| 3 >| 211 {nbsp} >| 142 {nbsp} >| 149 {nbsp} +^| 3 ^| 3 >| 250 {nbsp} >| 112 {nbsp} >| 124 {nbsp} +|==== ==== @@ -785,7 +786,7 @@ The result is sRGB-encoded values between 0.0 and 1.0. The further conversion from an sRGB encoded component _cs_ to a linear component _cl_ is done according to the formulae in <>. -Assume _cs_ is the sRGB component in the range [0, 1]. +Assume _cs_ is the sRGB component in the range [0,{nbsp}1]. <<< [[RGBAETC2]] @@ -801,26 +802,21 @@ The _RGB_ component is then decoded the same way as for RGB ETC2 [[Table-etc2eac-dataformat]] .Texel Data format for alpha part of RGBA ETC2 compressed textures -ifdef::a2xhtml[] -[width="60%"] -endif::[] -ifndef::a2xhtml[] [width="60%"] -endif::[] -|============= -16+|   *a) Bit layout in bits 63 through 48* +|==== +16+| {nbsp} *a) Bit layout in bits 63 through 48* ^| ~63~ ^| ~62~ ^| ~61~ ^| ~60~ ^| ~59~ ^| ~58~ ^| ~57~ ^| ~56~ ^| ~55~ ^| ~54~ ^| ~53~ ^| ~52~ ^| ~51~ ^| ~50~ ^| ~49~ ^| ~48~ 8+^| _base codeword_ 4+^| _multiplier_ 4+^| _table index_ -16+|   *b) Bit layout in bits 47 through 0, with pixels as name in <>,* +16+| {nbsp} *b) Bit layout in bits 47 through 0, with pixels as name in <>,* -  *bits labeled from 0 being the LSB to 47 being the MSB* +{nbsp} *bits labeled from 0 being the LSB to 47 being the MSB* ^| ~47~ ^| ~46~ ^| ~45~ ^| ~44~ ^| ~43~ ^| ~42~ ^| ~41~ ^| ~40~ ^| ~39~ ^| ~38~ ^| ~37~ ^| ~36~ ^| ~35~ ^| ~34~ ^| ~33~ ^| ~32~ ^| _a_~{alpha}~^2^ ^| _a_~{alpha}~^1^ ^| _a_~{alpha}~^0^ ^| _b_~{alpha}~^2^ ^| _b_~{alpha}~^1^ ^| _b_~{alpha}~^0^ ^| _c_~{alpha}~^2^ ^| _c_~{alpha}~^1^ ^| _c_~{alpha}~^0^ ^| _d_~{alpha}~^2^ ^| _d_~{alpha}~^1^ ^| _d_~{alpha}~^0^ ^| _e_~{alpha}~^2^ ^| _e_~{alpha}~^1^ ^| _e_~{alpha}~^0^ ^| _f_~{alpha}~^2^ ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| _f_~{alpha}~^1^ ^| _f_~{alpha}~^0^ ^| _g_~{alpha}~^2^ ^| _g_~{alpha}~^1^ ^| _g_~{alpha}~^0^ ^| _h_~{alpha}~^2^ ^| _h_~{alpha}~^1^ ^| _h_~{alpha}~^0^ ^| _i_~{alpha}~^2^ ^| _i_~{alpha}~^1^ ^| _i_~{alpha}~^0^ ^| _j_~{alpha}~^2^ ^| _j_~{alpha}~^1^ ^| _j_~{alpha}~^0^ ^| _k_~{alpha}~^2^ ^| _k_~{alpha}~^1^ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ ^| _k_~{alpha}~^0^ ^| _l_~{alpha}~^2^ ^| _l_~{alpha}~^1^ ^| _l_~{alpha}~^0^ ^| _m_~{alpha}~^2^ ^| _m_~{alpha}~^1^ ^| _m_~{alpha}~^0^ ^| _n_~{alpha}~^2^ ^| _n_~{alpha}~^1^ ^| _n_~{alpha}~^0^ ^| _o_~{alpha}~^2^ ^| _o_~{alpha}~^1^ ^| _o_~{alpha}~^0^ ^| _p_~{alpha}~^2^ ^| _p_~{alpha}~^1^ ^| _p_~{alpha}~^0^ -|============= +|==== The 64-bits in _int64bit~Alpha~_ used to decompress the alpha channel are laid out as shown in <>. The information @@ -846,11 +842,11 @@ calculated the following way: [[Equation-etc2eac-eqn-base]] .ETC2 base [latexmath] -++++++ +++++ \begin{align*} \mathit{clamp255}(\mathit{base\ codeword} + \mathit{modifier}\times \mathit{multiplier}) \end{align*} -++++++ +++++ where _clamp255_({cdot}) maps values outside the range [0..255] to 0.0 or 255.0. @@ -868,28 +864,28 @@ one of 16 pre-determined `modifier tables', shown in [[Table-etc2eac-modifiers]] .Intensity modifier sets for RGBA ETC2 alpha component [cols="20%,10%,10%,10%,10%,10%,10%,10%,10%",width="60%",options="header"] -|================= +|==== ^| _Table index_ 8+^| Modifier table ->| 0   >| -3   >| -6   >| -9   >| -15   >| 2   >| 5   >| 8   >| 14   ->| 1   >| -3   >| -7   >| -10   >| -13   >| 2   >| 6   >| 9   >| 12   ->| 2   >| -2   >| -5   >| -8   >| -13   >| 1   >| 4   >| 7   >| 12   ->| 3   >| -2   >| -4   >| -6   >| -13   >| 1   >| 3   >| 5   >| 12   ->| 4   >| -3   >| -6   >| -8   >| -12   >| 2   >| 5   >| 7   >| 11   ->| 5   >| -3   >| -7   >| -9   >| -11   >| 2   >| 6   >| 8   >| 10   ->| 6   >| -4   >| -7   >| -8   >| -11   >| 3   >| 6   >| 7   >| 10   ->| 7   >| -3   >| -5   >| -8   >| -11   >| 2   >| 4   >| 7   >| 10   ->| 8   >| -2   >| -6   >| -8   >| -10   >| 1   >| 5   >| 7   >| 9   ->| 9   >| -2   >| -5   >| -8   >| -10   >| 1   >| 4   >| 7   >| 9   ->| 10   >| -2   >| -4   >| -8   >| -10   >| 1   >| 3   >| 7   >| 9   ->| 11   >| -2   >| -5   >| -7   >| -10   >| 1   >| 4   >| 6   >| 9   ->| 12   >| -3   >| -4   >| -7   >| -10   >| 2   >| 3   >| 6   >| 9   ->| 13   >| -1   >| -2   >| -3   >| -10   >| 0   >| 1   >| 2   >| 9   ->| 14   >| -4   >| -6   >| -8   >| -9   >| 3   >| 5   >| 7   >| 8   ->| 15   >| -3   >| -5   >| -7   >| -9   >| 2   >| 4   >| 6   >| 8   -|================= +>| 0 {nbsp} >| -3 {nbsp} >| -6 {nbsp} >| -9 {nbsp} >| -15 {nbsp} >| 2 {nbsp} >| 5 {nbsp} >| 8 {nbsp} >| 14 {nbsp} +>| 1 {nbsp} >| -3 {nbsp} >| -7 {nbsp} >| -10 {nbsp} >| -13 {nbsp} >| 2 {nbsp} >| 6 {nbsp} >| 9 {nbsp} >| 12 {nbsp} +>| 2 {nbsp} >| -2 {nbsp} >| -5 {nbsp} >| -8 {nbsp} >| -13 {nbsp} >| 1 {nbsp} >| 4 {nbsp} >| 7 {nbsp} >| 12 {nbsp} +>| 3 {nbsp} >| -2 {nbsp} >| -4 {nbsp} >| -6 {nbsp} >| -13 {nbsp} >| 1 {nbsp} >| 3 {nbsp} >| 5 {nbsp} >| 12 {nbsp} +>| 4 {nbsp} >| -3 {nbsp} >| -6 {nbsp} >| -8 {nbsp} >| -12 {nbsp} >| 2 {nbsp} >| 5 {nbsp} >| 7 {nbsp} >| 11 {nbsp} +>| 5 {nbsp} >| -3 {nbsp} >| -7 {nbsp} >| -9 {nbsp} >| -11 {nbsp} >| 2 {nbsp} >| 6 {nbsp} >| 8 {nbsp} >| 10 {nbsp} +>| 6 {nbsp} >| -4 {nbsp} >| -7 {nbsp} >| -8 {nbsp} >| -11 {nbsp} >| 3 {nbsp} >| 6 {nbsp} >| 7 {nbsp} >| 10 {nbsp} +>| 7 {nbsp} >| -3 {nbsp} >| -5 {nbsp} >| -8 {nbsp} >| -11 {nbsp} >| 2 {nbsp} >| 4 {nbsp} >| 7 {nbsp} >| 10 {nbsp} +>| 8 {nbsp} >| -2 {nbsp} >| -6 {nbsp} >| -8 {nbsp} >| -10 {nbsp} >| 1 {nbsp} >| 5 {nbsp} >| 7 {nbsp} >| 9 {nbsp} +>| 9 {nbsp} >| -2 {nbsp} >| -5 {nbsp} >| -8 {nbsp} >| -10 {nbsp} >| 1 {nbsp} >| 4 {nbsp} >| 7 {nbsp} >| 9 {nbsp} +>| 10 {nbsp} >| -2 {nbsp} >| -4 {nbsp} >| -8 {nbsp} >| -10 {nbsp} >| 1 {nbsp} >| 3 {nbsp} >| 7 {nbsp} >| 9 {nbsp} +>| 11 {nbsp} >| -2 {nbsp} >| -5 {nbsp} >| -7 {nbsp} >| -10 {nbsp} >| 1 {nbsp} >| 4 {nbsp} >| 6 {nbsp} >| 9 {nbsp} +>| 12 {nbsp} >| -3 {nbsp} >| -4 {nbsp} >| -7 {nbsp} >| -10 {nbsp} >| 2 {nbsp} >| 3 {nbsp} >| 6 {nbsp} >| 9 {nbsp} +>| 13 {nbsp} >| -1 {nbsp} >| -2 {nbsp} >| -3 {nbsp} >| -10 {nbsp} >| 0 {nbsp} >| 1 {nbsp} >| 2 {nbsp} >| 9 {nbsp} +>| 14 {nbsp} >| -4 {nbsp} >| -6 {nbsp} >| -8 {nbsp} >| -9 {nbsp} >| 3 {nbsp} >| 5 {nbsp} >| 7 {nbsp} >| 8 {nbsp} +>| 15 {nbsp} >| -3 {nbsp} >| -5 {nbsp} >| -7 {nbsp} >| -9 {nbsp} >| 2 {nbsp} >| 4 {nbsp} >| 6 {nbsp} >| 8 {nbsp} +|==== For example, a _table index_ of 13 (1101 binary) means that we should -use table [-1, -2 -3, -10, 0, 1, 2, 9]. +use table [-1,{nbsp}-2{nbsp}-3,{nbsp}-10,{nbsp}0,{nbsp}1,{nbsp}2,{nbsp}9]. To select which of these values we should use, we consult the _pixel index_ of the pixel we want to decode. As shown in <> part (b), bits 47..0 are used to store @@ -906,7 +902,7 @@ In the next step we obtain the _multiplier_ value; bits 55..52 form a four-bit _multiplier_ between 0 and 15. This value should be multiplied with the _modifier_. An encoder is not allowed to produce a _multiplier_ of zero, but the decoder should -still be able to handle this case (and produce 0 {times} _modifier_ = 0 in that case). +still be able to handle this case (and produce 0{nbsp}{times} _modifier_ ={nbsp}0 in that case). The _modifier_ times the _multiplier_ now provides the third and final term in the sum in <>. The sum is @@ -917,11 +913,11 @@ For example, assume a _base codeword_ of 103, a _table index_ of 13, a _pixel index_ of 3 and a _multiplier_ of 2. We will then start with the _base codeword_ 103 (01100111 binary). Next, a _table index_ of 13 selects table -[-1, -2, -3, -10, 0, 1, 2, 9], +[-1,{nbsp}-2,{nbsp}-3,{nbsp}-10,{nbsp}0,{nbsp}1,{nbsp}2,{nbsp}9], and using a _pixel index_ of 3 will result in a _modifier_ of -10. -The _multiplier_ is 2, forming -10 {times} 2 = -20. -We now add this to the base value and get 103 - 20 = 83. -After clamping we still get 83 = 01010011 binary. +The _multiplier_ is 2, forming -10{nbsp}{times}{nbsp}2{nbsp}={nbsp}-20. +We now add this to the base value and get 103{nbsp}-{nbsp}20{nbsp}={nbsp}83. +After clamping we still get 83{nbsp}={nbsp}01010011 binary. This is our 8-bit output value. This specification gives the output for each channel in 8-bit integer @@ -939,7 +935,7 @@ follows that of floating point _RGB_ values of linear RGBA ETC2. The result is sRGB values between 0.0 and 1.0. The further conversion from an sRGB encoded component _cs_ to a linear component _cl_ is according to the formula in <>. Assume -_cs_ is the sRGB component in the range [0, 1]. +_cs_ is the sRGB component in the range [0,{nbsp}1]. The alpha component of RGBA ETC2 with sRGB encoding is done in the same way as for linear RGBA ETC2. @@ -958,11 +954,11 @@ the highest. The red component of the 4{times}4 block is then represented by the following 64-bit integer: [latexmath] -++++++ +++++ \begin{align*} \mathit{int64bit} & = 256\times (256\times (256\times (256\times (256\times (256\times (256\times q_0+q_1)+q_2)+q_3)+q_4)+q_5)+q_6)+q_7 \end{align*} -++++++ +++++ This 64-bit word contains information about a single-channel 4{times}4 pixel block as shown in <>. The 64-bit word @@ -978,11 +974,11 @@ The decoded value is calculated as: [[Equation-r11eac-eqn-start]] .Unsigned R11 EAC start [latexmath] -++++++ +++++ \begin{align*} \mathit{clamp1}\left((\mathit{base\ codeword}+0.5)\times \frac{1}{255.875} + \mathit{modifier}\times\mathit{multiplier}\times\frac{1}{255.875}\right) \end{align*} -+++++++ +++++ where _clamp1_({cdot}) maps values outside the range [0.0, 1.0] to 0.0 or 1.0. @@ -997,24 +993,24 @@ To get a value between 0 and 2047 we must multiply <> by 2047.0: [latexmath] -+++++++ +++++ \begin{align*} \mathit{clamp2}\left((\mathit{base\ codeword}+0.5)\times \frac{2047.0}{255.875} + \mathit{modifier}\times\mathit{multiplier}\times\frac{2047.0}{255.875}\right) \end{align*} -+++++++ +++++ -where _clamp2_({cdot}) clamps to the range [0.0, 2047.0]. +where _clamp2_({cdot}) clamps to the range [0.0,{nbsp}2047.0]. -Since latexmath:[$2047.0 \over 255.875$] is exactly 8.0, the above equation can be written as +Since latexmath:[2047.0 \over 255.875] is exactly 8.0, the above equation can be written as [[Equation-r11eac-eqn-simple]] .Unsigned R11 EAC simple [latexmath] -+++++++ +++++ \begin{align*} \mathit{clamp2}(\mathit{base\ codeword}\times 8 + 4 + \mathit{modifier} \times \mathit{multiplier} \times 8) \end{align*} -+++++++ +++++ The _base codeword_ is stored in the first 8 bits as shown in <> part (a). Bits 63..56 in each block @@ -1025,15 +1021,15 @@ bits after the shift. For example, if _base codeword_ is 129 = 10000001 binary (or 10000001b for short), the shifted value is 10000001000b and the shifted value including the {plus}4 term is -10000001100b = 1036 = 129{times}8{plus}4. +10000001100b{nbsp}={nbsp}1036{nbsp}={nbsp}129{times}8{plus}4. Hence we have summed together the first two terms of the sum in <>. Next, we want to obtain the _modifier_. Bits 51..48 form a 4-bit index used to select one of 16 pre-determined `modifier tables', shown in <>. -For example, a _table index_ of 13 (1101 binary) means that we should use table -[-1, -2, -3, -10, 0, 1, 2, 9]. +For example, a _table index_ of 13{nbsp}(1101{nbsp}binary) means that we should use table +[-1,{nbsp}-2,{nbsp}-3,{nbsp}-10,{nbsp}0,{nbsp}1,{nbsp}2,{nbsp}9]. To select which of these values we should use, we consult the _pixel index_ of the pixel we want to decode. Bits 47..0 are used to store a 3-bit index for each pixel in the block, selecting one of the @@ -1041,7 +1037,7 @@ store a 3-bit index for each pixel in the block, selecting one of the Assume we are interested in pixel _b_. Its pixel indices are stored in bit 44..42, with the most significant bit stored in 44 and the least significant bit stored in 42. -If the _pixel index_ is 011 binary = 3, this means we should take the value +If the _pixel index_ is 011{nbsp}binary{nbsp}={nbsp}3, this means we should take the value 3 from the left in the table, which is -10. This is now our _modifier_, which is the starting point of our second term in the sum. @@ -1058,51 +1054,51 @@ The resulting value is the 11-bit output value. For example, assume a _base codeword_ of 103, a _table index_ of 13, a _pixel index_ of 3 and a _multiplier_ of 2. -We will then first multiply the _base codeword_ 103 (01100111b) by +We will then first multiply the _base codeword_ 103{nbsp}(01100111b) by 8 by left-shifting it (0110111000b) and then add 4 resulting in -0110111100b = 828 = 103 {times} 8 + 4. +0110111100b{nbsp}={nbsp}828{nbsp}={nbsp}103{nbsp}{times}{nbsp}8{nbsp}+{nbsp}4. Next, a _table index_ of 13 selects table -[-1, -2, -3, -10, 0, 1, 2, 9], +[-1,{nbsp}-2,{nbsp}-3,{nbsp}-10,{nbsp}0,{nbsp}1,{nbsp}2,{nbsp}9], and using a _pixel index_ of 3 will result in a _modifier_ of -10. The _multiplier_ is nonzero, which means that we should multiply it with the _modifier_, -forming -10 {times} 2 = -20 = 111111101100b. +forming -10{nbsp}{times}{nbsp}2{nbsp}={nbsp}-20{nbsp}={nbsp}111111101100b. This value should in turn be multiplied by 8 by left-shifting it three steps: -111101100000b = -160. -We now add this to the base value and get 828 - 160 = 668. -After clamping we still get 668 = 01010011100b. +111101100000b{nbsp}={nbsp}-160. +We now add this to the base value and get 828{nbsp}-{nbsp}160{nbsp}={nbsp}668. +After clamping we still get 668{nbsp}={nbsp}01010011100b. This is our 11-bit output value, which represents the -value latexmath:[${668 \over 2047} = 0.32633121 \ldots$] +value latexmath:[{668 \over 2047} = 0.32633121 \ldots] If the _multiplier_ value is zero (i.e., the _multiplier_ bits 55..52 are -all zero), we should set the _multiplier_ to latexmath:[$1.0\over 8.0$]. +all zero), we should set the _multiplier_ to latexmath:[1.0\over 8.0]. <> can then be simplified to [[Equation-r11eac-eqn-simpler]] .Unsigned R11 EAC simpler [latexmath] -++++++ +++++ \begin{align*} \mathit{clamp2}(\mathit{base\ codeword}\times 8 + 4 + \mathit{modifier}) \end{align*} -+++++++ +++++ As an example, assume a _base codeword_ of 103, a _table index_ of 13, a _pixel index_ of 3 and a _multiplier_ value of 0. We treat the -_base codeword_ the same way, getting 828 = 103{times}8{plus}4. The +_base codeword_ the same way, getting 828{nbsp}={nbsp}103{times}8{plus}4. The _modifier_ is still -10. -But the _multiplier_ should now be latexmath:[$1 \over 8$], which +But the _multiplier_ should now be latexmath:[1 \over 8], which means that third term becomes -latexmath:[$-10\times \left({1\over 8}\right)\times 8 = -10$]. +latexmath:[-10\times \left({1\over 8}\right)\times 8 = -10]. The sum therefore becomes 828-10 = 818. After clamping we still get -818 = 01100110010b, and this is our 11-bit output value, and it represents -latexmath:[${818 \over 2047} = 0.39960918 \ldots$] +818{nbsp}={nbsp}01100110010b, and this is our 11-bit output value, and it represents +latexmath:[{818 \over 2047} = 0.39960918 \ldots] Some OpenGL ES implementations may find it convenient to use 16-bit values for further processing. In this case, the 11-bit value should be extended using bit replication. An 11-bit value _x_ is extended to 16 -bits through latexmath:[$(x\ll 5) + (x \gg 6)$]. For example, the value -668 = 01010011100b should be extended to -0101001110001010b = 21386. +bits through latexmath:[(x\ll 5) + (x \gg 6)]. For example, the value +668{nbsp}={nbsp}01010011100b should be extended to +0101001110001010b{nbsp}={nbsp}21386. In general, the implementation may extend the value to any number of bits that is convenient for further processing, e.g., 32 bits. In @@ -1113,20 +1109,20 @@ than 11 bits. Note that the method does not have the same reconstruction levels as the alpha part in the RGBA ETC2 format. For instance, for a _base codeword_ of 255 and a _table value_ of 0, the alpha part of the -RGBA ETC2 format will represent a value of latexmath:[${(255+0)\over 255.0} = 1.0$] +RGBA ETC2 format will represent a value of latexmath:[{(255+0)\over 255.0} = 1.0] exactly. In R11 EAC the same _base codeword_ and _table value_ will -instead represent latexmath:[${(255.5+0)\over 255.875} = 0.99853444 \ldots$] +instead represent latexmath:[{(255.5+0)\over 255.875} = 0.99853444 \ldots] That said, it is still possible to decode the alpha part of the RGBA ETC2-format using R11 EAC hardware. This is done by truncating the 11-bit number to 8 bits. -As an example, if _base codeword_ = 255 and _table value_ = 0, we get the 11-bit value -(255{times}8{plus}4{plus}0) = 2044 = 1111111100b, which after truncation -becomes the 8-bit value 11111111b = 255 which is exactly the correct +As an example, if _base codeword_{nbsp}={nbsp}255 and _table value_{nbsp}={nbsp}0, we get the 11-bit value +(255{times}8{plus}4{plus}0){nbsp}={nbsp}2044{nbsp}={nbsp}1111111100b, which after truncation +becomes the 8-bit value 11111111b{nbsp}={nbsp}255 which is exactly the correct value according to RGBA ETC2. -Clamping has to be done to [0, 255] after truncation for RGBA ETC2 decoding. +Clamping has to be done to [0,{nbsp}255] after truncation for RGBA ETC2 decoding. Care must also be taken to handle the case when the _multiplier_ value is -zero. In the 11-bit version, this means multiplying by latexmath:[$1 \over 8$], but in +zero. In the 11-bit version, this means multiplying by latexmath:[1 \over 8], but in the 8-bit version, it really means multiplication by 0. Thus, the decoder will have to know if it is an RGBA ETC2 texture or an R11 EAC texture to decode @@ -1134,48 +1130,48 @@ correctly, but the hardware can be 100% shared. <<< As stated above, a _base codeword_ of 255 and a _table value_ of 0 will -represent a value of latexmath:[${(255.5+0) \over 255.875} = 0.99853444 \ldots$], and this +represent a value of latexmath:[{(255.5+0) \over 255.875} = 0.99853444 \ldots], and this does not reach 1.0 even though 255 is the highest possible _base codeword_. However, it is still possible to reach a pixel value of 1.0 since a _modifier_ other than 0 can be used. Indeed, half of the _modifiers_ will often produce a value of 1.0. As an example, assume we choose the _base codeword_ 255, a _multiplier_ of 1 and the modifier table -[-3, -5, -7, -9, 2, 4, 6, 8]. Starting with +[-3,{nbsp}-5,{nbsp}-7,{nbsp}-9,{nbsp}2,{nbsp}4,{nbsp}6,{nbsp}8]. Starting with <>, [latexmath] -++++++ +++++ \begin{align*} \mathit{clamp1}\left((\mathit{base\ codeword}+0.5)\times \frac{1}{255.875} + \mathit{table\ value} \times \mathit{multiplier} \times \frac{1}{255.875}\right) \end{align*} -++++++ +++++ we get [latexmath] -++++++ +++++ \begin{align*} \mathit{clamp1}\left((255+0.5)\times \frac{1}{255.875} + \left[ \begin{array}{cccccccc} -3 & -5 & -7 &-9 & 2 & 4 & 6 & 8 \end{array}\right] \times \frac{1}{255.875}\right) \end{align*} -++++++ +++++ which equals [latexmath] -++++++ +++++ \begin{align*} \mathit{clamp1}\left(\left[ \begin{array}{cccccccc} 0.987 & 0.979 & 0.971 & 0.963 & 1.00 & 1.01 & 1.02 & 1.03 \end{array}\right]\right) \end{align*} -++++++ +++++ or after clamping [latexmath] -++++++ +++++ \begin{align*} \left[ \begin{array}{cccccccc} 0.987 & 0.979 & 0.971 & 0.963 & 1.00 & 1.00 & 1.00 & 1.00\end{array}\right] \end{align*} -++++++ +++++ which shows that several values can be 1.0, even though the base value does not reach 1.0. The same reasoning goes for 0.0. @@ -1193,12 +1189,12 @@ The 128 bits specifying the block are then represented by the following two 64 bit integers: [latexmath] -++++++ +++++ \begin{align*} \mathit{int64bit}_0 & = 256\times (256\times (256\times (256\times (256\times (256\times (256\times q_0+q_1)+q_2)+q_3)+q_4)+q_5)+q_6)+q_7 \\ \mathit{int64bit}_1 & = 256\times (256\times (256\times (256\times (256\times (256\times (256\times p_0+p_1)+p_2)+p_3)+p_4)+p_5)+p_6)+p_7 \end{align*} -++++++ +++++ The 64-bit word _int64bit_~0~ contains information about the red component of a two-channel 4{times}4 pixel block as shown in @@ -1218,11 +1214,11 @@ The red component of the 4{times}4 block is then represented by the following 64 bit integer: [latexmath] -+++++ +++++ \begin{align*} \mathit{int64bit} & = 256\times(256\times(256\times(256\times(256\times(256\times(256\times q_0+q_1)+q_2)+q_3)+q_4)+q_5)+q_6)+q_7 \end{align*} -+++++ +++++ This 64-bit word contains information about a single-channel 4{times}4 pixel block as shown in <>. @@ -1238,13 +1234,13 @@ The decoded value is calculated as [[Equation-signedr11eac-eqn-start]] .Signed R11 EAC start [latexmath] -+++++ +++++ \begin{align*} \mathit{clamp1}\left(\mathit{base\ codeword}\times \frac{1}{127.875} + \mathit{modifier}\times \mathit{multiplier}\times \frac{1}{127.875}\right) \end{align*} -+++++ +++++ -where _clamp1_({cdot}) maps values outside the range [-1.0, 1.0] to +where _clamp1_({cdot}) maps values outside the range [-1.0,{nbsp}1.0] to -1.0 or 1.0. We will now go into detail how the decoding is done. The result will be an 11-bit two's-complement fixed point number where -1023 represents @@ -1257,44 +1253,44 @@ To get a value between -1023 and 1023 we must multiply <> by 1023.0: [latexmath] -+++++ +++++ \begin{align*} \mathit{clamp2}\left(\mathit{base\ codeword}\times \frac{1023.0}{127.875} + \mathit{modifier}\times \mathit{multiplier}\times \frac{1023.0}{127.875}\right) \end{align*} -+++++ +++++ -where _clamp2_({cdot}) clamps to the range [-1023.0, 1023.0]. Since -latexmath:[$1023.0\over 127.875$] is exactly 8, the above formula can be written as: +where _clamp2_({cdot}) clamps to the range [-1023.0,{nbsp}1023.0]. Since +latexmath:[1023.0\over 127.875] is exactly 8, the above formula can be written as: [[Equation-signedr11eac-eqn-simple]] .Signed R11 EAC simple [latexmath] -+++++ +++++ \begin{align*} \mathit{clamp2}(\mathit{base\ codeword}\times 8 + \mathit{modifier}\times \mathit{multiplier} \times 8) \end{align*} -+++++ +++++ The _base codeword_ is stored in the first 8 bits as shown in <> part (a). It is a two's-complement value -in the range [-127, 127], and where the value -128 is not allowed; +in the range [-127,{nbsp}127], and where the value -128 is not allowed; however, if it should occur anyway it must be treated as -127. The _base codeword_ is then multiplied by 8 by shifting it left three steps. -For example the value 65 = 01000001 binary (or 01000001b for -short) is shifted to 01000001000b = 520 = 65{times}8. +For example the value 65{nbsp}={nbsp}01000001 binary (or 01000001b for +short) is shifted to 01000001000b{nbsp}={nbsp}520{nbsp}={nbsp}65{times}8. Next, we want to obtain the _modifier_. Bits 51..48 form a 4-bit index used to select one of 16 pre-determined `modifier tables', shown in <>. For example, a _table index_ of 13 (1101 binary) means that -we should use table [-1, -2, -3, -10, 0, 1, 2, 9]. +we should use table [-1,{nbsp}-2,{nbsp}-3,{nbsp}-10,{nbsp}0,{nbsp}1,{nbsp}2,{nbsp}9]. To select which of these values we should use, we consult the _pixel index_ of the pixel we want to decode. Bits 47..0 are used to store a 3-bit index for each pixel in the block, selecting one of the 8 possible values. Assume we are interested in pixel _b_. Its pixel indices are stored in bit 44..42, with the most significant bit stored in 44 and the least significant bit stored in 42. If the _pixel index_ -is 011 binary = 3, this means we should take the value 3 from the left +is 011{nbsp}binary{nbsp}={nbsp}3, this means we should take the value 3 from the left in the table, which is -10. This is now our _modifier_, which is the starting point of our second term in the sum. @@ -1311,56 +1307,57 @@ calculated and the result is clamped to a value in the interval For example, assume a a _base codeword_ of 60, a _table index_ of 13, a _pixel index_ of 3 and a _multiplier_ of 2. We start by multiplying the _base codeword_ (00111100b) by 8 using bit shift, -resulting in (00111100000b) = 480 = 60 {times} 8. +resulting in (00111100000b){nbsp}={nbsp}480{nbsp}={nbsp}60{nbsp}{times}{nbsp}8. Next, a _table index_ of 13 selects table -[-1, -2, -3, -10, 0, 1, 2, 9], and using a +[-1,{nbsp}-2,{nbsp}-3,{nbsp}-10,{nbsp}0,{nbsp}1,{nbsp}2,{nbsp}9], and using a _pixel index_ of 3 will result in a _modifier_ of -10. The _multiplier_ is nonzero, which means that we should multiply it with the -_modifier_, forming -10{times}2 = -20 = 111111101100b. +_modifier_, forming -10{times}2{nbsp}={nbsp}-20{nbsp}={nbsp}111111101100b. This value should in turn be multiplied by 8 by left-shifting it three steps: -111101100000b = -160. -We now add this to the base value and get 480-160 = 320. -After clamping we still get 320 = 00101000000b. +111101100000b{nbsp}={nbsp}-160. +We now add this to the base value and get 480-160{nbsp}={nbsp}320. +After clamping we still get 320{nbsp}={nbsp}00101000000b. This is our 11-bit output value, which represents the value -latexmath:[${320\over 1023} = 0.31280547\ldots$]. +latexmath:[{320\over 1023} = 0.31280547\ldots]. If the _multiplier_ value is zero (i.e., the _multiplier_ bits 55..52 are -all zero), we should set the _multiplier_ to latexmath:[$1.0 \over 8.0$]. +all zero), we should set the _multiplier_ to latexmath:[1.0 \over 8.0]. <> can then be simplified to: [[Equation-signedr11eac-eqn-simpler]] .Signed R11 EAC simpler [latexmath] -+++++ +++++ \begin{align*} \mathit{clamp2}(\mathit{base\ codeword} \times 8 + \mathit{modifier}) \end{align*} -+++++ +++++ As an example, assume a _base codeword_ of 65, a _table index_ of 13, a _pixel index_ of 3 and a _multiplier_ value of 0. -We treat the _base codeword_ the same way, getting 480 = 60{times}8. +We treat the _base codeword_ the same way, getting 480{nbsp}={nbsp}60{times}8. The _modifier_ is still -10. -But the _multiplier_ should now be latexmath:[$1 \over 8$], which means -that third term becomes latexmath:[$-10\times\left({1 \over 8}\right)\times 8 = -10$]. -The sum therefore becomes 480-10 = 470. -Clamping does not affect the value since it is already in the range [-1023, 1023], -and the 11-bit output value is therefore 470 = 00111010110b. -This represents latexmath:[${470\over 1023} = 0.45943304 \dots$] +But the _multiplier_ should now be latexmath:[1 \over 8], which means +that third term becomes latexmath:[-10\times\left({1 \over 8}\right)\times 8 = -10]. +The sum therefore becomes 480-10{nbsp}={nbsp}470. +Clamping does not affect the value since it is already in the range [-1023,{nbsp}1023], +and the 11-bit output value is therefore 470{nbsp}={nbsp}00111010110b. +This represents latexmath:[{470\over 1023} = 0.45943304 \dots] Some OpenGL ES implementations may find it convenient to use two's-complement 16-bit values for further processing. In this case, a positive 11-bit value should be extended using bit replication on all the bits except the sign bit. An 11-bit value x is extended to 16 bits through -(_x_ latexmath:[$\ll$] 5) {plus} (_x_ latexmath:[$\gg$] 5). +(_x_{nbsp}latexmath:[\ll]{nbsp}5){nbsp}{plus}{nbsp}(_x_{nbsp}latexmath:[\gg]{nbsp}5). Since the sign bit is zero for a positive value, no addition logic is needed for the bit replication in this case. -For example, the value 470 = 00111010110b in the above example should be -expanded to 0011101011001110b = 15054. +For example, the value 470{nbsp}={nbsp}00111010110b in the above example should be +expanded to 0011101011001110b{nbsp}={nbsp}15054. A negative 11-bit value must first be made positive before bit replication, and then made negative again: ------ +[source] +---- if (result11bit >= 0) { result16bit = (result11bit << 5) + (result11bit >> 5); } else { @@ -1368,7 +1365,7 @@ if (result11bit >= 0) { result16bit = (result11bit << 5) + (result11bit >> 5); result16bit = -result16bit; } ------ +---- Simply bit replicating a negative number without first making it positive will not give a correct result. @@ -1381,48 +1378,48 @@ the other hand, an implementation is not allowed to truncate the Note that it is not possible to specify a base value of 1.0 or -1.0. The largest possible _base codeword_ is {plus}127, which represents -latexmath:[${127 \over 127.875} = 0.993\ldots$]. +latexmath:[{127 \over 127.875} = 0.993\ldots]. However, it is still possible to reach a pixel value of 1.0 or -1.0, since the base value is modified by the table before the pixel value is calculated. Indeed, half of the _modifiers_ will often produce a value of 1.0. As an example, assume the _base codeword_ is {plus}127, the modifier table is -[-3, -5, -7, -9, 2, 4, 6, 8] and +[-3,{nbsp}-5,{nbsp}-7,{nbsp}-9,{nbsp}2,{nbsp}4,{nbsp}6,{nbsp}8] and the _multiplier_ is one. Starting with <>, [latexmath] -++++++ +++++ \begin{align*} \mathit{base\ codeword}\times \frac{1}{127.875} + \mathit{modifier}\times \mathit{multiplier}\times \frac{1}{127.875} \end{align*} -++++++ +++++ we get [latexmath] -++++++ +++++ \begin{align*} \frac{127}{127.875} + \left[\begin{array}{cccccccc} -3 & -5 & -7 & -9 & 2 & 4 & 6 & 8 \end{array}\right] \times \frac{1}{127.875} \end{align*} -++++++ +++++ which equals [latexmath] -++++++ +++++ \begin{align*} \left[ \begin{array}{cccccccc} 0.970 & 0.954 & 0.938 & 0.923 & 1.01 & 1.02 & 1.04 &1.06\end{array}\right] \end{align*} -++++++ +++++ or after clamping [latexmath] -++++++ +++++ \begin{align*} \left[ \begin{array}{cccccccc} 0.970 & 0.954 & 0.938 & 0.923 & 1.00 & 1.00 & 1.00 & 1.00 \end{array}\right] \end{align*} -++++++ +++++ This shows that it is indeed possible to arrive at the value 1.0. The same reasoning goes for -1.0. @@ -1447,12 +1444,12 @@ where byte _q_~0~ is located at the lowest memory address and _p_~7~ at the high two 64 bit integers: [latexmath] -++++++ +++++ \begin{align*} \mathit{int64bit}_0 & = 256\times (256\times (256\times (256\times (256\times (256\times (256\times q_0+q_1)+q_2)+q_3)+q_4)+q_5)+q_6)+q_7 \\ \mathit{int64bit}_1 & = 256\times (256\times (256\times (256\times (256\times (256\times (256\times p_0+p_1)+p_2)+p_3)+p_4)+p_5)+p_6)+p_7 \end{align*} -++++++ +++++ The 64-bit word _int64bit_~0~ contains information about the red component of a two-channel 4{times}4 pixel block as shown in @@ -1476,28 +1473,28 @@ determining the mode used in a given block. [[Table-etc2punch-dataformat]] .Texel Data format for punchthrough alpha ETC2 compressed texture formats [cols="1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1",width="97%"] -|==================== -32+|   *a) Location of bits for mode selection* +|==== +32+| {nbsp} *a) Location of bits for mode selection* ^| ~63~ ^| ~62~ ^| ~61~ ^| ~60~ ^| ~59~ ^| ~58~ ^| ~57~ ^| ~56~ ^| ~55~ ^| ~54~ ^| ~53~ ^| ~52~ ^| ~51~ ^| ~50~ ^| ~49~ ^| ~48~ ^| ~47~ ^| ~46~ ^| ~45~ ^| ~44~ ^| ~43~ ^| ~42~ ^| ~41~ ^| ~40~ ^| ~39~ ^| ~38~ ^| ~37~ ^| ~36~ ^| ~35~ ^| ~34~ ^| ~33~ ^| ~32~ 5+^| _R_ 3+^| _R_~d~ 5+^| _G_ 3+^| _G_~d~ 5+^| _B_ 3+^| _B_~d~ 6+^| ...... ^| _Op_ ^| . -32+|   *b) Bit layout for bits 63 through 32 for `differential' mode* +32+| {nbsp} *b) Bit layout for bits 63 through 32 for `differential' mode* ^| ~63~ ^| ~62~ ^| ~61~ ^| ~60~ ^| ~59~ ^| ~58~ ^| ~57~ ^| ~56~ ^| ~55~ ^| ~54~ ^| ~53~ ^| ~52~ ^| ~51~ ^| ~50~ ^| ~49~ ^| ~48~ ^| ~47~ ^| ~46~ ^| ~45~ ^| ~44~ ^| ~43~ ^| ~42~ ^| ~41~ ^| ~40~ ^| ~39~ ^| ~38~ ^| ~37~ ^| ~36~ ^| ~35~ ^| ~34~ ^| ~33~ ^| ~32~ 5+^| _R_ 3+^| _R_~d~ 5+^| _G_ 3+^| _G_~d~ 5+^| _B_ 3+^| _B_~d~ 3+^| _table_~1~ 3+^| _table_~2~ ^| _Op_ ^| _F~B~_ -32+|   *c) Bit layout for bits 63 through 32 for `T' mode* +32+| {nbsp} *c) Bit layout for bits 63 through 32 for `T' mode* ^| ~63~ ^| ~62~ ^| ~61~ ^| ~60~ ^| ~59~ ^| ~58~ ^| ~57~ ^| ~56~ ^| ~55~ ^| ~54~ ^| ~53~ ^| ~52~ ^| ~51~ ^| ~50~ ^| ~49~ ^| ~48~ ^| ~47~ ^| ~46~ ^| ~45~ ^| ~44~ ^| ~43~ ^| ~42~ ^| ~41~ ^| ~40~ ^| ~39~ ^| ~38~ ^| ~37~ ^| ~36~ ^| ~35~ ^| ~34~ ^| ~33~ ^| ~32~ 3+^| ... 2+^| _R_^3..2^ ^| . 2+^| _R_^1..0^ 4+^| _G_ 4+^| _B_ 4+^| _R_~2~ 4+^| _G_~2~ 4+^| _B_~2~ 2+^| _d~a~_ ^| _Op_ ^| _d~b~_ -32+|   *d) Bit layout for bits 63 through 32 for `H' mode* +32+| {nbsp} *d) Bit layout for bits 63 through 32 for `H' mode* ^| ~63~ ^| ~62~ ^| ~61~ ^| ~60~ ^| ~59~ ^| ~58~ ^| ~57~ ^| ~56~ ^| ~55~ ^| ~54~ ^| ~53~ ^| ~52~ ^| ~51~ ^| ~50~ ^| ~49~ ^| ~48~ ^| ~47~ ^| ~46~ ^| ~45~ ^| ~44~ ^| ~43~ ^| ~42~ ^| ~41~ ^| ~40~ ^| ~39~ ^| ~38~ ^| ~37~ ^| ~36~ ^| ~35~ ^| ~34~ ^| ~33~ ^| ~32~ ^| . 4+^| _R_ 3+^| _G_^3..1^ 3+^| ... ^| _G_^0^ ^| _B_^3^ ^| . 3+^| _B_^2..0^ 4+^| _R_~2~ 4+^| _G_~2~ 4+^| _B_~2~ ^| _d~a~_ ^| _Op_ ^| _d~b~_ -32+|   *e) Bit layout for bits 31 through 0 for `differential', `T' and `H' modes* +32+| {nbsp} *e) Bit layout for bits 31 through 0 for `differential', `T' and `H' modes* ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ ^| _p_^1^ ^| _o_^1^ ^| _n_^1^ ^| _m_^1^ ^| _l_^1^ ^| _k_^1^ ^| _j_^1^ ^| _i_^1^ ^| _h_^1^ ^| _g_^1^ ^| _f_^1^ ^| _e_^1^ ^| _d_^1^ ^| _c_^1^ ^| _b_^1^ ^| _a_^1^ ^| _p_^0^ ^| _o_^0^ ^| _n_^0^ ^| _m_^0^ ^| _l_^0^ ^| _k_^0^ ^| _j_^0^ ^| _i_^0^ ^| _h_^0^ ^| _g_^0^ ^| _f_^0^ ^| _e_^0^ ^| _d_^0^ ^| _c_^0^ ^| _b_^0^ ^| _a_^0^ -32+|   *f) Bit layout for bits 63 through 0 for `planar' mode* +32+| {nbsp} *f) Bit layout for bits 63 through 0 for `planar' mode* ^| ~63~ ^| ~62~ ^| ~61~ ^| ~60~ ^| ~59~ ^| ~58~ ^| ~57~ ^| ~56~ ^| ~55~ ^| ~54~ ^| ~53~ ^| ~52~ ^| ~51~ ^| ~50~ ^| ~49~ ^| ~48~ ^| ~47~ ^| ~46~ ^| ~45~ ^| ~44~ ^| ~43~ ^| ~42~ ^| ~41~ ^| ~40~ ^| ~39~ ^| ~38~ ^| ~37~ ^| ~36~ ^| ~35~ ^| ~34~ ^| ~33~ ^| ~32~ ^| . 6+^| _R_ ^| _G_^6^ ^| . 6+^| _G_^5..0^ ^| _B_^5^ 3+^| ... 2+^| _B_^4..3^ ^| . 3+^| _B_^2..0^ 5+^| _R_~h~^5..1^ ^| 1 ^| _R_~h~^0^ ^| ~31~ ^| ~30~ ^| ~29~ ^| ~28~ ^| ~27~ ^| ~26~ ^| ~25~ ^| ~24~ ^| ~23~ ^| ~22~ ^| ~21~ ^| ~20~ ^| ~19~ ^| ~18~ ^| ~17~ ^| ~16~ ^| ~15~ ^| ~14~ ^| ~13~ ^| ~12~ ^| ~11~ ^| ~10~ ^| ~9~ ^| ~8~ ^| ~7~ ^| ~6~ ^| ~5~ ^| ~4~ ^| ~3~ ^| ~2~ ^| ~1~ ^| ~0~ 7+^| _G_~h~ 6+^| _B_~h~ 6+^| _R_~v~ 7+^| _G_~v~ 6+^| _B_~v~ -|==================== +|==== To determine the mode, the three 5-bit values _R_, _G_ and _B_, and the three 3-bit values _R_~d~, _G_~d~ and _B_~d~ are examined. @@ -1528,35 +1525,35 @@ In the `differential' mode, following the layout shown in 1 is derived from the five-bit codewords _R_, _G_ and _B_. These five-bit codewords are extended to eight bits by replicating the top three highest-order bits to the three lowest-order bits. -For instance, if _R_ = 28 = 11100 binary (11100b +For instance, if _R_{nbsp}={nbsp}28{nbsp}={nbsp}11100{nbsp}binary (11100b for short), the resulting eight-bit red color component becomes -11100111b = 231. -Likewise, if _G_ = 4 = 00100b and -_B_ = 3 = 00011b, the green and blue components become -00100001b = 33 and 00011000b = 24 respectively. +11100111b{nbsp}={nbsp}231. +Likewise, if _G_{nbsp}={nbsp}4{nbsp}={nbsp}00100b and +_B_{nbsp}={nbsp}3{nbsp}={nbsp}00011b, the green and blue components become +00100001b{nbsp}={nbsp}33 and 00011000b{nbsp}={nbsp}24 respectively. Thus, in this example, the _base color_ for subblock 1 is -(231, 33, 24). +(231,{nbsp}33,{nbsp}24). The five bit representation for the _base color_ of subblock 2 is obtained by modifying the 5-bit codewords _R_, _G_ and _B_ by the codewords _R_~d~, _G_~d~ and _B_~d~. Each of _R_~d~, _G_~d~ and _B_~d~ is a 3-bit two's-complement number that can hold values between -4 and {plus}3. -For instance, if _R_ = 28 as above, and -_R_~d~ = 100b = -4, then the five bit representation for -the red color component is 28{plus}(-4)=24 = 11000b, which is then -extended to eight bits to 11000110b = 198. -Likewise, if _G_ = 4, _G_~d~ = 2, _B_ = 3 and -_B_~d~ = 0, the _base color_ of subblock 2 will be -_RGB _= (198, 49, 24). +For instance, if _R_{nbsp}={nbsp}28 as above, and +_R_~d~{nbsp}={nbsp}100b{nbsp}={nbsp}-4, then the five bit representation for +the red color component is 28{plus}(-4)=24{nbsp}={nbsp}11000b, which is then +extended to eight bits to 11000110b{nbsp}={nbsp}198. +Likewise, if _G_{nbsp}={nbsp}4, _G_~d~{nbsp}={nbsp}2, _B_{nbsp}={nbsp}3 and +_B_~d~{nbsp}={nbsp}0, the _base color_ of subblock 2 will be +_RGB{nbsp}_={nbsp}(198,{nbsp}49,{nbsp}24). In summary, the _base colors_ for the subblocks in the differential mode are: [latexmath] -++++++ +++++ \begin{align*} \mathit{base\ color_{subblock1}} & = \mathit{extend5to8bits}(\mathit{R}, \mathit{G}, \mathit{B}) \\ \mathit{base\ color_{subblock2}} & = \mathit{extend5to8bits}(\mathit{R}+\mathit{R}_\mathrm{d}, \mathit{G}+\mathit{G}_\mathrm{d}, \mathit{B}+\mathit{B}_\mathrm{d}) \end{align*} -++++++ +++++ Note that these additions will not under- or overflow, or one of the alternative decompression modes would have been chosen instead of the @@ -1565,32 +1562,32 @@ alternative decompression modes would have been chosen instead of the [[Table-etc2punch-modifiers-a]] .ETC2 intensity modifier sets for the `differential' if `opaque' (_Op_) is set [cols="3,1,1,1,1",options="header",width="40%"] -|======== +|==== ^| _Table codeword_ 4+^| Modifier table -^| 0 >| -8   >| -2   >| 2   >| 8   -^| 1 >| -17   >| -5   >| 5   >| 17   -^| 2 >| -29   >| -9   >| 9   >| 29   -^| 3 >| -42   >|-13   >| 13   >| 42   -^| 4 >| -60   >|-18   >| 18   >| 60   -^| 5 >| -80   >|-24   >| 24   >| 80   -^| 6 >| -106   >|-33   >| 33   >|106   -^| 7 >| -183   >|-47   >| 47   >|183   -|======== +^| 0 >| -8 {nbsp} >| -2 {nbsp} >| 2 {nbsp} >| 8 {nbsp} +^| 1 >| -17 {nbsp} >| -5 {nbsp} >| 5 {nbsp} >| 17 {nbsp} +^| 2 >| -29 {nbsp} >| -9 {nbsp} >| 9 {nbsp} >| 29 {nbsp} +^| 3 >| -42 {nbsp} >|-13 {nbsp} >| 13 {nbsp} >| 42 {nbsp} +^| 4 >| -60 {nbsp} >|-18 {nbsp} >| 18 {nbsp} >| 60 {nbsp} +^| 5 >| -80 {nbsp} >|-24 {nbsp} >| 24 {nbsp} >| 80 {nbsp} +^| 6 >| -106 {nbsp} >|-33 {nbsp} >| 33 {nbsp} >|106 {nbsp} +^| 7 >| -183 {nbsp} >|-47 {nbsp} >| 47 {nbsp} >|183 {nbsp} +|==== [[Table-etc2punch-modifiers-b]] .ETC2 intensity modifier sets for the `differential' if `opaque' (_Op_) is unset [cols="3,1,1,1,1",options="header",width="40%"] -|======== +|==== ^| _Table codeword_ 4+^| Modifier table -^| 0 >| -8   >| 0   >| 0   >| 8   -^| 1 >| -17   >| 0   >| 0   >| 17   -^| 2 >| -29   >| 0   >| 0   >| 29   -^| 3 >| -42   >| 0   >| 0   >| 42   -^| 4 >| -60   >| 0   >| 0   >| 60   -^| 5 >| -80   >| 0   >| 0   >| 80   -^| 6 >| -106   >| 0   >| 0   >| 106   -^| 7 >| -183   >| 0   >| 0   >| 183   -|======== +^| 0 >| -8 {nbsp} >| 0 {nbsp} >| 0 {nbsp} >| 8 {nbsp} +^| 1 >| -17 {nbsp} >| 0 {nbsp} >| 0 {nbsp} >| 17 {nbsp} +^| 2 >| -29 {nbsp} >| 0 {nbsp} >| 0 {nbsp} >| 29 {nbsp} +^| 3 >| -42 {nbsp} >| 0 {nbsp} >| 0 {nbsp} >| 42 {nbsp} +^| 4 >| -60 {nbsp} >| 0 {nbsp} >| 0 {nbsp} >| 60 {nbsp} +^| 5 >| -80 {nbsp} >| 0 {nbsp} >| 0 {nbsp} >| 80 {nbsp} +^| 6 >| -106 {nbsp} >| 0 {nbsp} >| 0 {nbsp} >| 106 {nbsp} +^| 7 >| -183 {nbsp} >| 0 {nbsp} >| 0 {nbsp} >| 183 {nbsp} +|==== After obtaining the _base color_, a table is chosen using the _table codewords_: For subblock 1, _table codeword 1_ is used (bits 39..37), and @@ -1600,7 +1597,7 @@ The _table codeword_ is used to select one of eight modifier tables. If the `opaque'-bit (bit 33) is set, <> is used. If it is unset, <> is used. For instance, if the `opaque'-bit is 1 and the _table codeword_ is 010 -binary = 2, then the modifier table [-29, -9, 9, 29] is selected for +binary = 2, then the modifier table [-29,{nbsp}-9,{nbsp}9,{nbsp}29] is selected for the corresponding sub-block. Note that the values in <> and <> are valid for all textures and can @@ -1621,40 +1618,40 @@ If the `opaque'-bit (bit 33) is set, the _pixel index_ bits are decoded using <>. If the `opaque'-bit is unset, <> will be used instead. If, for instance, the `opaque'-bit is 1, and the -_pixel index_ bits are 01 binary = 1, and the modifier table -[-29, -9, 9, 29] is used, then the _modifier_ value +_pixel index_ bits are 01 binary{nbsp}={nbsp}1, and the modifier table +[-29,{nbsp}-9,{nbsp}9,{nbsp}29] is used, then the _modifier_ value selected for that pixel is 29 (see <>). This _modifier_ value is now used to additively modify the _base color_. -For example, if we have the _base color_ (231, 8, 16), we should +For example, if we have the _base color_ (231,{nbsp}8,{nbsp}16), we should add the _modifier_ value 29 to all three components: -(231{plus}29, 8{plus}29, 16{plus}29) resulting in -(260, 37, 45). +(231{plus}29,{nbsp}8{plus}29,{nbsp}16{plus}29) resulting in +(260,{nbsp}37,{nbsp}45). These values are then clamped to [0..255], resulting in the -color (255, 37, 45). +color (255,{nbsp}37,{nbsp}45). [[Table-etc2punch-pixelindices-a]] .ETC2 mapping from pixel index values to modifier values when `opaque' bit is set [cols="1,1,3",width="50%"] -|============ +|==== 2+^| *_Pixel index_ value* .2+^.^| *Resulting _modifier_ value* ^| *msb* ^| *lsb* -^| 1 ^| 1 |   -b (large negative value) -^| 1 ^| 0 |   -a (small negative value) -^| 0 ^| 0 |   {plus}a (small positive value) -^| 0 ^| 1 |   {plus}b (large positive value) -|============ +^| 1 ^| 1 | {nbsp} -b (large negative value) +^| 1 ^| 0 | {nbsp} -a (small negative value) +^| 0 ^| 0 | {nbsp} {plus}a (small positive value) +^| 0 ^| 1 | {nbsp} {plus}b (large positive value) +|==== [[Table-etc2punch-pixelindices-b]] .ETC2 mapping from pixel index values to modifier values when `opaque' bit is unset [cols="1,1,3",width="50%"] -|============ +|==== 2+^| *_Pixel index_ value* .2+^.^| *Resulting _modifier_ value* ^| *msb* ^| *lsb* -^| 1 ^| 1 |   -b (large negative value) -^| 1 ^| 0 |   0 (zero) -^| 0 ^| 0 |   0 (zero) -^| 0 ^| 1 |   {plus}b (large positive value) -|============ +^| 1 ^| 1 | {nbsp} -b (large negative value) +^| 1 ^| 0 | {nbsp} 0 (zero) +^| 0 ^| 0 | {nbsp} 0 (zero) +^| 0 ^| 1 | {nbsp} {plus}b (large positive value) +|==== The alpha component is decoded using the `opaque'-bit, which is positioned in bit 33 (see @@ -1665,7 +1662,8 @@ if MSB==1 and LSB==0, the alpha value will be zero, otherwise it will be 255. Finally, if the alpha value equals 0, the red, green and blue components will also be zero. ------ +[source] +---- if (opaque == 0 && MSB == 1 && LSB == 0) { red = 0; green = 0; @@ -1674,13 +1672,13 @@ if (opaque == 0 && MSB == 1 && LSB == 0) { } else { alpha = 255; } ------ +---- -Hence _paint color 2_ will equal _RGBA_ = (0, 0, 0, 0) if opaque = 0. +Hence _paint color 2_ will equal _RGBA_ = (0,{nbsp}0,{nbsp}0,{nbsp}0) if opaque = 0. In the example above, assume that the `opaque'-bit was instead 0. Then, since the MSB = 0 and LSB 1, alpha will be 255, and the final -decoded _RGBA_-tuple will be (255, 37, 45, 255). +decoded _RGBA_-tuple will be (255,{nbsp}37,{nbsp}45,{nbsp}255). The `T' and `H' compression modes share some characteristics: both use two _base colors_ stored using 4 bits per channel. These bits are not @@ -1690,26 +1688,26 @@ stored sequentially, but in the layout shown in To clarify, in the `T' mode, the two colors are constructed as follows: [latexmath] -++++++ +++++ \begin{align*} \mathit{base\ color\ 1} & = \mathit{extend4to8bits}(\: (\mathit{R}^{3..2} \ll 2)\: | \: \mathit{R}^{1..0}, \: \mathit{G}, \: \mathit{B}) \\ \mathit{base\ color\ 2} & = \mathit{extend4to8bits}(\mathit{R}_2, \: \mathit{G}_2, \: \mathit{B}_2) \end{align*} -++++++ +++++ In the `H' mode, the two colors are constructed as follows: [latexmath] -++++++ +++++ \begin{align*} \mathit{base\ color\ 1} & = \mathit{extend4to8bits}(\mathit{R}, \: (\mathit{G}^{3..1} \ll 1) \: | \: \mathit{G}^0, \: (\mathit{B}^3 \ll 3) \: | \: \mathit{B}^{2..0}) \\ \mathit{base\ color\ 2} & = \mathit{extend4to8bits}(\mathit{R}_2, \: \mathit{G}_2, \: \mathit{B}_2) \end{align*} -++++++ +++++ The function _extend4to8bits_({cdot}) just replicates the four bits twice. This is equivalent to multiplying by 17. As an example, -_extend4to8bits_(1101b) equals 11011101b = 221. +_extend4to8bits_(1101b) equals 11011101b{nbsp}={nbsp}221. Both the `T' and `H' modes have four _paint colors_ which are the colors that will be used in the decompressed block, but they are @@ -1719,7 +1717,7 @@ color_. To obtain the other _paint colors_, a `distance' is first determined, which will be used to modify the luminance of one of the _base colors_. This is done by combining the values _d~a~_ and _d~b~_ shown in <> part (c) by -(_d~a~_ latexmath:[$\ll$] 1) | _d~b~_, and +(_d~a~_ latexmath:[\ll] 1) | _d~b~_, and then using this value as an index into the small look-up table shown in <>. For example, if _d~a~_ is 10 binary and _d~b~_ is 1 binary, the index is 101 binary and the selected distance _d_ @@ -1729,21 +1727,22 @@ second _base color_ with the `distance' _d_ subtracted. In summary, to determine the four _paint colors_ for a `T' block: [latexmath] -++++++ +++++ \begin{align*} \mathit{paint\ color\ 0} & = \mathit{base\ color\ 1} \\ \mathit{paint\ color\ 1} & = \mathit{base\ color\ 2 + (d, d, d)} \\ \mathit{paint\ color\ 2} & = \mathit{base\ color\ 2} \\ \mathit{paint\ color\ 3} & = \mathit{base\ color\ 2 - (d, d, d)} \end{align*} -++++++ +++++ In both cases, the value of each channel is clamped to within [0..255]. Just as for the differential mode, the _RGB_ channels are set to zero if alpha is zero, and the alpha component is calculated the same way: ------ +[source] +---- if (opaque == 0 && MSB == 1 && LSB == 0) { red = 0; green = 0; @@ -1752,33 +1751,34 @@ if (opaque == 0 && MSB == 1 && LSB == 0) { } else { alpha = 255; } ------ +---- A `distance' value is computed for the `H' mode as well, but doing so is slightly more complex. In order to construct the three-bit index into the distance table shown in <>, _d~a~_ and _d~b~_ shown in <> part (d) are used as the most significant bit and middle bit, respectively, but the -least significant bit is computed as (_base color 1_ value latexmath:[$\geq$] +least significant bit is computed as (_base color 1_ value latexmath:[\geq] _base color 2_ value), the `value' of a color for the comparison being equal to -(_R_ latexmath:[$\ll$] 16) {plus} (_G_ latexmath:[$\ll$] 8)_ {plus} B_. +(_R_{nbsp}latexmath:[\ll]{nbsp}16){nbsp}{plus}{nbsp}(_G_{nbsp}latexmath:[\ll]{nbsp}8)_{nbsp}{plus}{nbsp}B_. Once the `distance' _d_ has been determined for an `H' block, the four _paint colors_ will be: [latexmath] -++++++ +++++ \begin{align*} \mathit{paint\ color\ 0} & = \mathit{base\ color\ 1 + (d, d, d)} \\ \mathit{paint\ color\ 1} & = \mathit{base\ color\ 1 - (d, d, d)} \\ \mathit{paint\ color\ 2} & = \mathit{base\ color\ 2 + (d, d, d)} \\ \mathit{paint\ color\ 3} & = \mathit{base\ color\ 2 - (d, d, d)} \end{align*} -++++++ +++++ Yet again, _RGB_ is zeroed if alpha is 0 and the alpha component is determined the same way: ------ +[source] +---- if (opaque == 0 && MSB == 1 && LSB == 0) { red = 0; green = 0; @@ -1787,9 +1787,9 @@ if (opaque == 0 && MSB == 1 && LSB == 0) { } else { alpha = 255; } ------ +---- -Hence _paint color 2_ will have _R_ =_ G _=_ B _= alpha = 0 +Hence _paint color 2_ will have _R_{nbsp}=_{nbsp}G{nbsp}_=_{nbsp}B{nbsp}_={nbsp}alpha{nbsp}={nbsp}0 if opaque = 0. Again, all color components are clamped to within [0..255]. Finally, in @@ -1827,33 +1827,33 @@ With three _base colors_ in _RGB_:888 format, the color of each pixel can then be determined as: [latexmath] -++++++ +++++ \begin{align*} \mathit{R}(x,y) & = {x\times (\mathit{R}_\mathrm{h}-\mathit{R})\over 4.0} + {y\times (\mathit{R}_\mathrm{v}-\mathit{R})\over 4.0} + \mathit{R} \\ \mathit{G}(x,y) & = {x\times (\mathit{G}_\mathrm{h}-\mathit{G})\over 4.0} + {y\times (\mathit{G}_\mathrm{v}-\mathit{G})\over 4.0} + \mathit{G} \\ \mathit{B}(x,y) & = {x\times (\mathit{B}_\mathrm{h}-\mathit{B})\over 4.0} + {y\times (\mathit{B}_\mathrm{v}-\mathit{B})\over 4.0} + \mathit{B} \\ A(x,y) & = 255 \end{align*} -++++++ +++++ where _x_ and _y_ are values from 0 to 3 corresponding to the pixels coordinates within the block, _x_ being in the _u_ direction and _y_ in the _v_ direction. For example, the pixel _g_ in <> -would have _x _= 1 and _y _= 2. +would have _x{nbsp}_={nbsp}1 and _y{nbsp}_={nbsp}2. These values are then rounded to the nearest integer (to the larger integer if there is a tie) and then clamped to a value between 0 and 255. Note that this is equivalent to [latexmath] -+++++++++++++++ +++++ \begin{align*} \mathit{R}(x,y) & = \mathit{clamp255}((x\times (\mathit{R}_\mathrm{h}-\mathit{R}) + y\times (\mathit{R}_\mathrm{v}-\mathit{R}) + 4\times \mathit{R} + 2) \gg 2) \\ \mathit{G}(x,y) & = \mathit{clamp255}((x\times (\mathit{G}_\mathrm{h}-\mathit{G}) + y\times (\mathit{G}_\mathrm{v}-\mathit{G}) + 4\times \mathit{G} + 2) \gg 2) \\ \mathit{B}(x,y) & = \mathit{clamp255}((x\times (\mathit{B}_\mathrm{h}-\mathit{B}) + y\times (\mathit{B}_\mathrm{v}-\mathit{B}) + 4\times \mathit{B} + 2) \gg 2) \\ A(x,y) & = 255 \end{align*} -+++++++++++++++ +++++ where _clamp255_({cdot}) clamps the value to a number in the range [0..255]. @@ -1871,5 +1871,5 @@ _RGB_ values of RGB ETC2 with punchthrough alpha. The result is sRGB values between 0.0 and 1.0. The further conversion from an sRGB encoded component, _cs_, to a linear component, _cl_, is according to the formula in <>. Assume _cs_ is the sRGB component in the range -[0, 1]. Note that the alpha component is not gamma corrected, +[0,{nbsp}1]. Note that the alpha component is not gamma corrected, and hence does not use this formula. diff --git a/primaries.txt b/chapters/primaries.adoc similarity index 82% rename from primaries.txt rename to chapters/primaries.adoc index baf0145..dfa4139 100644 --- a/primaries.txt +++ b/chapters/primaries.adoc @@ -1,5 +1,5 @@ -// Copyright (c) 2017 The Khronos Group Inc. -// Copyright notice at https://www.khronos.org/registry/speccopyright.html +// Copyright 2017-2026 The Khronos Group Inc. +// SPDX-License-Identifier: CC-BY-4.0 [[PRIMARY_CONVERSION]] == Color primaries @@ -24,12 +24,12 @@ linear luminance. _xyY_ is related to _XYZ_ via the following formulae: [latexmath] -++++++ +++++ \begin{align*} x & = {X\over{X + Y + Z}} &&&y & = {Y\over{X + Y + Z}} &&&z & = {Z\over{X + Y + Z}} = 1 - x - y\\ &&X & = {Y\over{y}}x &&&Z & = {Y\over{y}}(1-x-y) \end{align*} -++++++ +++++ This is relevant because, although the brightness of the display in a color space definition is typically undefined, the *white point* is known: @@ -41,8 +41,8 @@ primaries. NOTE: Many color standards use the CIE D65 standard illuminant as a white point. D65 is intended to represent average daylight, and has a color temperature of approximately 6500K. In <> terms, this -white point is defined in ITU standards as latexmath:[$x=0.3127,\ y=0.3290$], -but elsewhere given as latexmath:[$x=0.312713,\ y=0.329016$]. +white point is defined in ITU standards as latexmath:[x=0.3127,\ y=0.3290], +but elsewhere given as latexmath:[x=0.312713,\ y=0.329016]. Different coordinates will affect the conversion matrices given below. The definition of the D65 white point is complicated by the constants in Planck's Law (which is a component in calculating the white point from @@ -50,25 +50,25 @@ the color temperature) having been revised since D65 was standardized, such that the standard formula for calculating CIE coordinates from the color temperature do not agree with the D65 standard. The actual color temperature of D65 is nearer to -latexmath:[$6500\times {1.4388\over 1.438} \approx 6503.6\textrm{K}$]. +latexmath:[6500\times {1.4388\over 1.438} \approx 6503.6\textrm{K}]. Assuming an arbitrary white luminance (_Y_ value) of 1.0, it is possible to express the following identity for the _X_, _Y_ and _Z_ coordinates of each color channel _R_, _G_ and _B_, and of the white point _W_: [latexmath] -++++++ +++++ \begin{align*} W_X &= R_X + G_X + B_X &W_Y &= R_Y + G_Y + B_Y = 1.0 &W_Z &= R_Z + G_Z + B_Z \end{align*} -++++++ +++++ -The identities latexmath:[$X = Y{x\over{y}}$] and -latexmath:[$Z = Y{{(1-x-y)}\over{y}}$] can be used to +The identities latexmath:[X = Y{x\over{y}}] and +latexmath:[Z = Y{{(1-x-y)}\over{y}}] can be used to re-express the above terms in the _xyY_ space: [latexmath] -++++++ +++++ \begin{align*} R_Y\left({R_x\over{R_y}}\right) + G_Y\left({G_x\over{G_y}}\right) + @@ -82,12 +82,12 @@ B_Y\left({1-B_x-B_y\over{B_y}}\right) & = W_Y\left({1-W_x-W_y\over{W_y}}\right) = {1-W_x-W_y\over{W_y}} \end{align*} -++++++ +++++ This equation for _W~Z~_ can be simplified to: [latexmath] -++++++ +++++ \begin{align*} R_Y\left({1-R_x\over{R_y}}-1\right) + G_Y\left({1-G_x\over{G_y}}-1\right) + @@ -95,87 +95,87 @@ B_Y\left({1-B_x\over{B_y}}-1\right) & = W_Y\left({1-W_x\over{W_y}}-1\right) = {1-W_x\over{W_y}}-1 \end{align*} -++++++ +++++ -Since latexmath:[$R_Y + G_Y + B_Y = W_Y = 1$], this further +Since latexmath:[R_Y + G_Y + B_Y = W_Y = 1], this further simplifies to: [latexmath] -++++++ +++++ \begin{align*} R_Y\left({1-R_x\over{R_y}}\right) + G_Y\left({1-G_x\over{G_y}}\right) + B_Y\left({1-B_x\over{B_y}}\right) & = {1-W_x\over{W_y}} \end{align*} -++++++ +++++ -The latexmath:[$R_Y+G_Y+B_Y$] term for _W~Y~_ can be multiplied by -latexmath:[$R_x\over{R_y}$] and subtracted from the equation for _W~X~_: +The latexmath:[R_Y+G_Y+B_Y] term for _W~Y~_ can be multiplied by +latexmath:[R_x\over{R_y}] and subtracted from the equation for _W~X~_: [latexmath] -++++++ -$$ G_Y\left({G_x\over{G_y}}-{R_x\over{R_y}}\right) + - B_Y\left({B_x\over{B_y}}-{R_x\over{R_y}}\right) = - {W_x\over{W_y}}-{R_x\over{R_y}}$$ -++++++ +++++ +G_Y\left({G_x\over{G_y}}-{R_x\over{R_y}}\right) + +B_Y\left({B_x\over{B_y}}-{R_x\over{R_y}}\right) = +{W_x\over{W_y}}-{R_x\over{R_y}} +++++ -Similarly, the latexmath:[$R_Y+G_Y+B_Y$] term can be multiplied by -latexmath:[$1-R_x\over{R_y}$] and subtracted from the simplified +Similarly, the latexmath:[R_Y+G_Y+B_Y] term can be multiplied by +latexmath:[1-R_x\over{R_y}] and subtracted from the simplified _W~Z~_ line: [latexmath] -++++++ -$$ G_Y\left({1-G_x\over{G_y}}-{1-R_x\over{R_y}}\right) + - B_Y\left({1-B_x\over{B_y}}-{1-R_x\over{R_y}}\right) = - {1-W_x\over{W_y}}-{1-R_x\over{R_y}}$$ -++++++ +++++ +G_Y\left({1-G_x\over{G_y}}-{1-R_x\over{R_y}}\right) + +B_Y\left({1-B_x\over{B_y}}-{1-R_x\over{R_y}}\right) = +{1-W_x\over{W_y}}-{1-R_x\over{R_y}} +++++ Finally, the _G~Y~_ term can be eliminated by multiplying the former of these -two equations by latexmath:[${1-G_x\over{G_y}}-{1-R_x\over{R_y}}$] and subtracting it -from the latter multiplied by latexmath:[${G_x\over{G_y}}-{R_x\over{R_y}}$], giving: +two equations by latexmath:[{1-G_x\over{G_y}}-{1-R_x\over{R_y}}] and subtracting it +from the latter multiplied by latexmath:[{G_x\over{G_y}}-{R_x\over{R_y}}], giving: [latexmath] -++++++ -$$ B_Y\left(\left({1-B_x\over{B_y}}-{1-R_x\over{R_y}}\right) - \left({G_x\over{G_y}}-{R_x\over{R_y}}\right) - - \left({B_x\over{B_y}}-{R_x\over{R_y}}\right) - \left({1-G_x\over{G_y}}-{1-R_x\over{R_y}}\right)\right)$$ -$$ = \left({1-W_x\over{W_y}}-{1-R_x\over{R_y}}\right) - \left({G_x\over{G_y}}-{R_x\over{R_y}}\right) - - \left({W_x\over{W_y}}-{R_x\over{R_y}}\right) - \left({1-G_x\over{G_y}}-{1-R_x\over{R_y}}\right)$$ -++++++ +++++ +B_Y\left(\left({1-B_x\over{B_y}}-{1-R_x\over{R_y}}\right) +\left({G_x\over{G_y}}-{R_x\over{R_y}}\right) - +\left({B_x\over{B_y}}-{R_x\over{R_y}}\right) +\left({1-G_x\over{G_y}}-{1-R_x\over{R_y}}\right)\right) \\ += \left({1-W_x\over{W_y}}-{1-R_x\over{R_y}}\right) +\left({G_x\over{G_y}}-{R_x\over{R_y}}\right) - +\left({W_x\over{W_y}}-{R_x\over{R_y}}\right) +\left({1-G_x\over{G_y}}-{1-R_x\over{R_y}}\right) +++++ Thus: [latexmath] -++++++ -$$ B_Y = {{\left({1-W_x\over{W_y}}-{1-R_x\over{R_y}}\right) - \left({G_x\over{G_y}}-{R_x\over{R_y}}\right) - - \left({W_x\over{W_y}}-{R_x\over{R_y}}\right) - \left({1-G_x\over{G_y}}-{1-R_x\over{R_y}}\right)} - \over{\left({1-B_x\over{B_y}}-{1-R_x\over{R_y}}\right) - \left({G_x\over{G_y}}-{R_x\over{R_y}}\right) - - \left({B_x\over{B_y}}-{R_x\over{R_y}}\right) - \left({1-G_x\over{G_y}}-{1-R_x\over{R_y}}\right)}}$$ -++++++ +++++ +B_Y = {{\left({1-W_x\over{W_y}}-{1-R_x\over{R_y}}\right) +\left({G_x\over{G_y}}-{R_x\over{R_y}}\right) - +\left({W_x\over{W_y}}-{R_x\over{R_y}}\right) +\left({1-G_x\over{G_y}}-{1-R_x\over{R_y}}\right)} +\over{\left({1-B_x\over{B_y}}-{1-R_x\over{R_y}}\right) +\left({G_x\over{G_y}}-{R_x\over{R_y}}\right) - +\left({B_x\over{B_y}}-{R_x\over{R_y}}\right) +\left({1-G_x\over{G_y}}-{1-R_x\over{R_y}}\right)}} +++++ This allows _G~Y~_ to be calculated by rearranging an earlier equation: [latexmath] -++++++ -$$ G_Y = - {{W_x\over{W_y}}-{R_x\over{R_y}} - -B_Y\left({B_x\over{B_y}}-{R_x\over{R_y}}\right) - \over{{G_x\over{G_y}}-{R_x\over{R_y}}}}$$ -++++++ +++++ +G_Y = +{{W_x\over{W_y}}-{R_x\over{R_y}} +-B_Y\left({B_x\over{B_y}}-{R_x\over{R_y}}\right) +\over{{G_x\over{G_y}}-{R_x\over{R_y}}}} +++++ And finally: [latexmath] -++++++ -$$ R_Y = 1 - G_Y - B_Y $$ -++++++ +++++ +R_Y = 1 - G_Y - B_Y +++++ These relative magnitudes allow the definition of vectors representing the color primaries in the _XYZ_ space, which in turn @@ -187,8 +187,8 @@ but sufficient to allow transformation to another set of color primaries. The transform from the defined color primaries to _XYZ_ space is: [latexmath] -++++++ -$$ \left(\begin{array}{c}X\\ +++++ +\left(\begin{array}{c}X \\ Y\\ Z\end{array}\right) = \left(\begin{array}{ccc}R_X, & G_X, & B_X \\ @@ -200,16 +200,16 @@ B\end{array}\right) = \left(\begin{array}{ccc}{R_Y\over{R_y}}R_x, & {G_Y\over{G_y}}G_x, & {B_Y\over{B_y}}B_x \\ R_Y, & G_Y, & B_Y \\ {R_Y\over{R_y}}(1-R_x-R_y), & {G_Y\over{G_y}}(1-G_x-G_y), & {B_Y\over{B_y}}(1-B_x-B_y) -\end{array}\right)\left(\begin{array}{c}R\\ -G\\ -B\end{array}\right)$$ -++++++ +\end{array}\right)\left(\begin{array}{c}R \\ +G \\ +B\end{array}\right) +++++ The transform from _XYZ_ space to the defined color primaries is therefore: [latexmath] -++++++ -$$ \left(\begin{array}{c}R\\ +++++ +\left(\begin{array}{c}R \\ G\\ B\end{array}\right) = \left(\begin{array}{ccc}R_X, & G_X, & B_X \\ @@ -221,16 +221,16 @@ Z\end{array}\right) = \left(\begin{array}{ccc}{R_Y\over{R_y}}R_x, & {G_Y\over{G_y}}G_x, & {B_Y\over{B_y}}B_x \\ R_Y, & G_Y, & B_Y \\ {R_Y\over{R_y}}(1-R_x-R_y), & {G_Y\over{G_y}}(1-G_x-G_y), & {B_Y\over{B_y}}(1-B_x-B_y) -\end{array}\right)^{-1}\left(\begin{array}{c}X\\ -Y\\ -Z\end{array}\right)$$ -++++++ +\end{array}\right)^{-1}\left(\begin{array}{c}X \\ +Y \\ +Z\end{array}\right) +++++ NOTE: These transforms assume that the black point for the color space -is at latexmath:[$(X, Y, Z) = (0, 0, 0)$]. If the black point is non-zero, +is at latexmath:[(X, Y, Z) = (0, 0, 0)]. If the black point is non-zero, these transforms require a translational component. In some color spaces the black point has the same color as the white point, in which case it is also -possible to adjust the latexmath:[$(R, G, B)$] values outside the matrix. +possible to adjust the latexmath:[(R, G, B)] values outside the matrix. [NOTE] ==== @@ -239,25 +239,25 @@ of wavelengths in varying intensities. Describing the color of an object in terms of three wavelengths is necessarily an approximation, and effective only because the human eye typically sees the world mostly in terms of combinations of three color -cone cell responses -- ``tristimulus values''. -The typical response of these ``long'', ``medium'' and ``short'' +cone cell responses -- "`tristimulus values`". +The typical response of these "`long`", "`medium`" and "`short`" wavelength-sensitive cones is the basis of the CIE XYZ color space, so a linear combination of primaries described in this color space can be mapped to a linear combination of other primaries. Two colors with a different spectrum but an identical appearance are known as _metamers_, and the tristimulus model of color relies -on ``metameric matching'': picking a linear combination of some set +on "`metameric matching`": picking a linear combination of some set of primaries that will elicit the same cone cell response as the desired color. -  +{nbsp} Each of the cone cells can appear in mutated form which results in a change to its response to different frequencies of light. Since the genes for cone cells are encoded on the X chromosome, some women have more than one variant of the same cone cell, being -``tetrachromats'' -- and there is evidence that such people can -distinguish more colors than the general ``trichromat'' population, +"`tetrachromats`" -- and there is evidence that such people can +distinguish more colors than the general "`trichromat`" population, with only a subset of these colors describable with three color primaries. There is some evidence for people with two variants of more than one @@ -272,7 +272,7 @@ Note that rod cells, which dominate the human visual system in low light conditions, are typically ignored at higher illumination levels for the purposes of color matching. -  +{nbsp} The difference between a primary color representation and the full spectrum emitted by a real-world object is particularly @@ -281,7 +281,7 @@ Printing colors are typically described assuming that they will reflect the spectrum of a theoretical illuminant; changing this light source may change the appearance of the printed object in a more complex manner than scaling the primary values. -This can lead to ``metameric failure'', where two colors may +This can lead to "`metameric failure`", where two colors may appear identical under some lighting conditions and different under others. This effect is present in nature, notably in the mineral @@ -294,15 +294,15 @@ spectra) to appear different. Inkjet printing often uses many more than three inks in order to maximize the representable gamut and control metamerism. -  +{nbsp} Adaptation to a different white point is often performed by a -linear scaling of primaries, known as the ``von Kries transform''. +linear scaling of primaries, known as the "`von Kries transform`". The link:https://onlinelibrary.wiley.com/doi/pdf/10.1002/9781119021780.app3[Bradford color adaptation transform] incorporates a slight nonlinear term to the blue component of colors to more accurately reflect visual behavior. -  +{nbsp} It is common for production rendering systems to represent each pixel with more than three channels. @@ -310,7 +310,7 @@ For example, the contributions from different lights may be recorded separately in order to allow later adjustment to color and relative intensity, specular and diffuse reflectance from a surface may be recorded separately (which is valuable, for example, in denoising -algorithms), and virtual ``channels'' may be used to control shader +algorithms), and virtual "`channels`" may be used to control shader effects. A larger number of wavelengths may also be used when rendering effects such as chromatic dispersion, which is important for rendering @@ -326,14 +326,14 @@ descriptor for such a pixel. <> (HDTV) defines the following chromaticity coordinates: [latexmath] -++++++ +++++ \begin{align*} R_x &= 0.640 & R_y &= 0.330 \\ G_x &= 0.300 & G_y &= 0.600 \\ B_x &= 0.150 & B_y &= 0.060 \\ W_x &= 0.3127 & W_y &= 0.3290\ (\textrm{D}65) \end{align*} -++++++ +++++ These chromaticity coordinates are also shared by <> and <>. @@ -341,8 +341,8 @@ Therefore to convert from linear color values defined in terms of BT.709 color primaries to _XYZ_ space the formulae in <> result in the following matrix: [latexmath] -++++++ -$$\left(\begin{array}{c}X \\ +++++ +\left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) \approx \left(\begin{array}{ccc} @@ -351,15 +351,15 @@ Z\end{array}\right) \approx 0.019331, & 0.119195, & 0.950532\end{array}\right) \left(\begin{array}{c} R_{709} \\ G_{709} \\ -B_{709}\end{array}\right)$$ -++++++ +B_{709}\end{array}\right) +++++ The inverse transformation, from the _XYZ_ space to a color defined in terms of BT.709 color primaries, is: ifeval::["{svgpdf}"=="pdf"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{709} \\ +++++ +\left(\begin{array}{c} R_{709} \\ G_{709} \\ B_{709}\end{array}\right) \approx \left(\begin{array}{r@{}lr@{}lr@{}l} @@ -369,13 +369,12 @@ B_{709}\end{array}\right) \approx \left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) -$$ -++++++ +++++ endif::[] ifeval::["{svgpdf}"=="svg"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{709} \\ +++++ +\left(\begin{array}{c} R_{709} \\ G_{709} \\ B_{709}\end{array}\right) \approx \left(\begin{array}{ccc} @@ -385,8 +384,7 @@ B_{709}\end{array}\right) \approx \left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) -$$ -++++++ +++++ endif::[] NOTE: <> lists a slightly different version of this matrix, @@ -399,26 +397,26 @@ possibly due to rounding errors. (as used in most PAL systems) and for 525-line systems (as used in the <> standard for NTSC). -The following chromaticity coordinates are defined for 625-line ``EBU'' systems: +The following chromaticity coordinates are defined for 625-line "`EBU`" systems: [latexmath] -++++++ +++++ \begin{align*} R_x &= 0.640 & R_y &= 0.330 \\ G_x &= 0.290 & G_y &= 0.600 \\ B_x &= 0.150 & B_y &= 0.060 \\ W_x &= 0.3127 & W_y &= 0.3290 \end{align*} -++++++ +++++ NOTE: <>, which also describes these constants in a legacy -context, approximates D65 as latexmath:[$x = 0.313,\ y = 0.329$]. +context, approximates D65 as latexmath:[x = 0.313,\ y = 0.329]. Therefore to convert from linear color values defined in terms of BT.601 color primaries for 625-line systems to _XYZ_ space the formulae in <> result in the following matrix: [latexmath] -++++++ -$$\left(\begin{array}{c}X \\ +++++ +\left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) \approx \left(\begin{array}{ccc} @@ -427,15 +425,15 @@ Z\end{array}\right) \approx 0.020182, & 0.129553, & 0.939322\end{array}\right) \left(\begin{array}{c} R_{601\textrm{EBU}} \\ G_{601\textrm{EBU}} \\ -B_{601\textrm{EBU}}\end{array}\right)$$ -++++++ +B_{601\textrm{EBU}}\end{array}\right) +++++ The inverse transformation, from the _XYZ_ space to a color defined -in terms of BT.601 ``EBU'' 625-line color primaries, is: +in terms of BT.601 "`EBU`" 625-line color primaries, is: ifeval::["{svgpdf}"=="pdf"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{601\textrm{EBU}} \\ +++++ +\left(\begin{array}{c} R_{601\textrm{EBU}} \\ G_{601\textrm{EBU}} \\ B_{601\textrm{EBU}}\end{array}\right) \approx \left(\begin{array}{r@{}lr@{}lr@{}l} @@ -445,13 +443,12 @@ B_{601\textrm{EBU}}\end{array}\right) \approx \left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) -$$ -++++++ +++++ endif::[] ifeval::["{svgpdf}"=="svg"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{601\textrm{EBU}} \\ +++++ +\left(\begin{array}{c} R_{601\textrm{EBU}} \\ G_{601\textrm{EBU}} \\ B_{601\textrm{EBU}}\end{array}\right) \approx \left(\begin{array}{ccc} @@ -461,8 +458,7 @@ B_{601\textrm{EBU}}\end{array}\right) \approx \left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) -$$ -++++++ +++++ endif::[] [[PRIMARIES_BT601_SMPTE]] @@ -475,22 +471,22 @@ the <> standard for NTSC). The following chromaticity coordinates are defined in BT.601 for 525-line digital systems and in SMPTE-170M: [latexmath] -++++++ +++++ \begin{align*} R_x &= 0.630 & R_y &= 0.340 \\ G_x &= 0.310 & G_y &= 0.595 \\ B_x &= 0.155 & B_y &= 0.070 \\ W_x &= 0.3127 & W_y &= 0.3290 \end{align*} -++++++ +++++ Therefore to convert from linear color values defined in terms of BT.601 color primaries for 525-line systems to _XYZ_ space the formulae in <> result in the following matrix: ifeval::["{svgpdf}"=="pdf"] [latexmath] -++++++ -$$\left(\begin{array}{c}X \\ +++++ +\left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) \approx \left(\begin{array}{ccc} @@ -499,13 +495,13 @@ Z\end{array}\right) \approx 0.018739, & 0.111934, & 0.958385\end{array}\right) \left(\begin{array}{c} R_{601\textrm{SMPTE}} \\ G_{601\textrm{SMPTE}} \\ -B_{601\textrm{SMPTE}}\end{array}\right)$$ -++++++ +B_{601\textrm{SMPTE}}\end{array}\right) +++++ endif::[] ifeval::["{svgpdf}"=="svg"] [latexmath] -++++++ -$$\left(\begin{array}{c}X \\ +++++ +\left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) \approx \left(\begin{array}{ccc} @@ -514,16 +510,16 @@ Z\end{array}\right) \approx 0.018739, & 0.111934, & 0.958385\end{array}\right) \left(\begin{array}{c} R_{601\textrm{SMPTE}} \\ G_{601\textrm{SMPTE}} \\ -B_{601\textrm{SMPTE}}\end{array}\right)$$ -++++++ +B_{601\textrm{SMPTE}}\end{array}\right) +++++ endif::[] The inverse transformation, from the _XYZ_ space to a color defined in terms of BT.601 525-line color primaries, is: ifeval::["{svgpdf}"=="pdf"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{601\textrm{SMPTE}} \\ +++++ +\left(\begin{array}{c} R_{601\textrm{SMPTE}} \\ G_{601\textrm{SMPTE}} \\ B_{601\textrm{SMPTE}}\end{array}\right) \approx \left(\begin{array}{r@{}lr@{}lr@{}l} @@ -533,13 +529,12 @@ B_{601\textrm{SMPTE}}\end{array}\right) \approx \left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) -$$ -++++++ +++++ endif::[] ifeval::["{svgpdf}"=="svg"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{601\textrm{SMPTE}} \\ +++++ +\left(\begin{array}{c} R_{601\textrm{SMPTE}} \\ G_{601\textrm{SMPTE}} \\ B_{601\textrm{SMPTE}}\end{array}\right) \approx \left(\begin{array}{ccc} @@ -549,8 +544,7 @@ B_{601\textrm{SMPTE}}\end{array}\right) \approx \left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) -$$ -++++++ +++++ endif::[] NOTE: <> used a different white point, @@ -562,14 +556,14 @@ and therefore have a <> conversion matrix. The following chromaticity coordinates are defined in <> for ultra-high-definition television: [latexmath] -++++++ +++++ \begin{align*} R_x &= 0.708 & R_y &= 0.292 \\ G_x &= 0.170 & G_y &= 0.797 \\ B_x &= 0.131 & B_y &= 0.046 \\ W_x &= 0.3127 & W_y &= 0.3290 \end{align*} -++++++ +++++ The same primaries are used for <> for HDR TV. @@ -578,8 +572,8 @@ primaries to _XYZ_ space the formulae in <> result in the following matrix: ifeval::["{svgpdf}"=="pdf"] [latexmath] -++++++ -$$\left(\begin{array}{c}X \\ +++++ +\left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) \approx \left(\begin{array}{r@{}lr@{}lr@{}l} @@ -588,13 +582,13 @@ Z\end{array}\right) \approx 0.&000000, & 0.&028073, & 1.&060985\end{array}\right) \left(\begin{array}{c} R_{2020} \\ G_{2020} \\ -B_{2020}\end{array}\right)$$ -++++++ +B_{2020}\end{array}\right) +++++ endif::[] ifeval::["{svgpdf}"=="svg"] [latexmath] -++++++ -$$\left(\begin{array}{c}X \\ +++++ +\left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) \approx \left(\begin{array}{ccc} @@ -603,16 +597,16 @@ Z\end{array}\right) \approx 0.000000, & 0.028073, & 1.060985\end{array}\right) \left(\begin{array}{c} R_{2020} \\ G_{2020} \\ -B_{2020}\end{array}\right)$$ -++++++ +B_{2020}\end{array}\right) +++++ endif::[] The inverse transformation, from the _XYZ_ space to a color defined in terms of BT.2020 color primaries, is: ifeval::["{svgpdf}"=="pdf"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{2020} \\ +++++ +\left(\begin{array}{c} R_{2020} \\ G_{2020} \\ B_{2020}\end{array}\right) \approx \left(\begin{array}{r@{}lr@{}lr@{}l} @@ -622,13 +616,12 @@ B_{2020}\end{array}\right) \approx \left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) -$$ -++++++ +++++ endif::[] ifeval::["{svgpdf}"=="svg"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{2020} \\ +++++ +\left(\begin{array}{c} R_{2020} \\ G_{2020} \\ B_{2020}\end{array}\right) \approx \left(\begin{array}{ccc} @@ -638,8 +631,7 @@ B_{2020}\end{array}\right) \approx \left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) -$$ -++++++ +++++ endif::[] <<< @@ -650,14 +642,14 @@ The following chromaticity coordinates are defined in <> and <> as a reference to the legacy NTSC standard: [latexmath] -++++++ +++++ \begin{align*} R_x &= 0.67 & R_y &= 0.33 \\ G_x &= 0.21 & G_y &= 0.71 \\ B_x &= 0.14 & B_y &= 0.08 \\ W_x &= 0.310 & W_y &= 0.316\ (\textrm{Illuminant C}) \end{align*} -++++++ +++++ NOTE: These primaries apply to the 1953 revision of the NTSC standard. Modern NTSC systems, which reflect displays that are optimized for @@ -676,8 +668,8 @@ primaries to _XYZ_ space the formulae in <> result in the following matrix: ifeval::["{svgpdf}"=="pdf"] [latexmath] -++++++ -$$\left(\begin{array}{c}X \\ +++++ +\left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) \approx \left(\begin{array}{r@{}lr@{}lr@{}l} @@ -686,13 +678,13 @@ Z\end{array}\right) \approx 0.&000000, & 0.&066076, & 1.&117469\end{array}\right) \left(\begin{array}{c} R_{\textrm{NTSC}} \\ G_{\textrm{NTSC}} \\ -B_{\textrm{NTSC}}\end{array}\right)$$ -++++++ +B_{\textrm{NTSC}}\end{array}\right) +++++ endif::[] ifeval::["{svgpdf}"=="svg"] [latexmath] -++++++ -$$\left(\begin{array}{c}X \\ +++++ +\left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) \approx \left(\begin{array}{ccc} @@ -701,16 +693,16 @@ Z\end{array}\right) \approx 0.000000, & 0.066076, & 1.117469\end{array}\right) \left(\begin{array}{c} R_{\textrm{NTSC}} \\ G_{\textrm{NTSC}} \\ -B_{\textrm{NTSC}}\end{array}\right)$$ -++++++ +B_{\textrm{NTSC}}\end{array}\right) +++++ endif::[] The inverse transformation, from the _XYZ_ space to a color defined in terms of NTSC 1953 color primaries, is: ifeval::["{svgpdf}"=="pdf"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{\textrm{NTSC}} \\ +++++ +\left(\begin{array}{c} R_{\textrm{NTSC}} \\ G_{\textrm{NTSC}} \\ B_{\textrm{NTSC}}\end{array}\right) \approx \left(\begin{array}{r@{}lr@{}lr@{}l} @@ -720,13 +712,12 @@ B_{\textrm{NTSC}}\end{array}\right) \approx \left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) -$$ -++++++ +++++ endif::[] ifeval::["{svgpdf}"=="svg"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{\textrm{NTSC}} \\ +++++ +\left(\begin{array}{c} R_{\textrm{NTSC}} \\ G_{\textrm{NTSC}} \\ B_{\textrm{NTSC}}\end{array}\right) \approx \left(\begin{array}{ccc} @@ -736,8 +727,7 @@ B_{\textrm{NTSC}}\end{array}\right) \approx \left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) -$$ -++++++ +++++ endif::[] [[PRIMARIES_PAL525]] @@ -746,14 +736,14 @@ endif::[] <> defines the following chromaticity coordinates for legacy 525-line PAL systems: [latexmath] -++++++ +++++ \begin{align*} R_x &= 0.630 & R_y &= 0.340 \\ G_x &= 0.310 & G_y &= 0.595 \\ B_x &= 0.155 & B_y &= 0.070 \\ W_x &= 0.3101 & W_y &= 0.3162\ (\textrm{Illuminant C}) \end{align*} -++++++ +++++ NOTE: This matches the color primaries from <> analog NTSC and <> 525-line encoding, but the white point used is CIE Standard @@ -765,8 +755,8 @@ primaries to _XYZ_ space the formulae in <> result in the following matrix: ifeval::["{svgpdf}"=="pdf"] [latexmath] -++++++ -$$\left(\begin{array}{c}X \\ +++++ +\left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) \approx \left(\begin{array}{r@{}lr@{}lr@{}l} @@ -775,13 +765,13 @@ Z\end{array}\right) \approx 0.&019781, & 0.&108679, & 1.&053387\end{array}\right) \left(\begin{array}{c} R_{\textrm{PAL525}} \\ G_{\textrm{PAL525}} \\ -B_{\textrm{PAL525}}\end{array}\right)$$ -++++++ +B_{\textrm{PAL525}}\end{array}\right) +++++ endif::[] ifeval::["{svgpdf}"=="svg"] [latexmath] -++++++ -$$\left(\begin{array}{c}X \\ +++++ +\left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) \approx \left(\begin{array}{ccc} @@ -790,16 +780,16 @@ Z\end{array}\right) \approx 0.019781, & 0.108679, & 1.053387\end{array}\right) \left(\begin{array}{c} R_{\textrm{PAL525}} \\ G_{\textrm{PAL525}} \\ -B_{\textrm{PAL525}}\end{array}\right)$$ -++++++ +B_{\textrm{PAL525}}\end{array}\right) +++++ endif::[] The inverse transformation, from the _XYZ_ space to a color defined in terms of PAL 525-line 1953 color primaries, is: ifeval::["{svgpdf}"=="pdf"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{\textrm{PAL525}} \\ +++++ +\left(\begin{array}{c} R_{\textrm{PAL525}} \\ G_{\textrm{PAL525}} \\ B_{\textrm{PAL525}}\end{array}\right) \approx \left(\begin{array}{r@{}lr@{}lr@{}l} @@ -809,13 +799,12 @@ B_{\textrm{PAL525}}\end{array}\right) \approx \left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) -$$ -++++++ +++++ endif::[] ifeval::["{svgpdf}"=="svg"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{\textrm{PAL525}} \\ +++++ +\left(\begin{array}{c} R_{\textrm{PAL525}} \\ G_{\textrm{PAL525}} \\ B_{\textrm{PAL525}}\end{array}\right) \approx \left(\begin{array}{ccc} @@ -825,8 +814,7 @@ B_{\textrm{PAL525}}\end{array}\right) \approx \left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) -$$ -++++++ +++++ endif::[] [[PRIMARIES_ACES]] @@ -834,22 +822,22 @@ endif::[] The following chromaticity coordinates are defined in <> [latexmath] -++++++ +++++ \begin{align*} R_x &= 0.73470 & R_y &= 0.26530 \\ G_x &= 0.0 & G_y &= 1.0 \\ B_x &= 0.00010 & B_y &= -0.0770 \\ W_x &= 0.32168 & W_y &= 0.33767 \end{align*} -++++++ +++++ Therefore to convert from linear color values defined in terms of ACES color primaries to _XYZ_ space the formulae in <> result in the following matrix: ifeval::["{svgpdf}"=="pdf"] [latexmath] -++++++ -$$\left(\begin{array}{c}X \\ +++++ +\left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) \approx \left(\begin{array}{r@{}lr@{}lr@{}l} @@ -858,13 +846,13 @@ Z\end{array}\right) \approx 0.&0, & 0.&0, & 1.&0088251844\end{array}\right) \left(\begin{array}{c} R_{\textrm{ACES}} \\ G_{\textrm{ACES}} \\ -B_{\textrm{ACES}}\end{array}\right)$$ -++++++ +B_{\textrm{ACES}}\end{array}\right) +++++ endif::[] ifeval::["{svgpdf}"=="svg"] [latexmath] -++++++ -$$\left(\begin{array}{c}X \\ +++++ +\left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) \approx \left(\begin{array}{ccc} @@ -873,15 +861,15 @@ Z\end{array}\right) \approx 0.0, & 0.0, & 1.0088251844\end{array}\right) \left(\begin{array}{c} R_{\textrm{ACES}} \\ G_{\textrm{ACES}} \\ -B_{\textrm{ACES}}\end{array}\right)$$ -++++++ +B_{\textrm{ACES}}\end{array}\right) +++++ endif::[] The inverse transformation, from the _XYZ_ space to a color defined in terms of ACES color primaries, is: ifeval::["{svgpdf}"=="pdf"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{\textrm{ACES}} \\ +++++ +\left(\begin{array}{c} R_{\textrm{ACES}} \\ G_{\textrm{ACES}} \\ B_{\textrm{ACES}}\end{array}\right) \approx \left(\begin{array}{r@{}lr@{}lr@{}l} @@ -891,13 +879,12 @@ B_{\textrm{ACES}}\end{array}\right) \approx \left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) -$$ -++++++ +++++ endif::[] ifeval::["{svgpdf}"=="svg"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{\textrm{ACES}} \\ +++++ +\left(\begin{array}{c} R_{\textrm{ACES}} \\ G_{\textrm{ACES}} \\ B_{\textrm{ACES}}\end{array}\right) \approx \left(\begin{array}{ccc} @@ -907,8 +894,7 @@ B_{\textrm{ACES}}\end{array}\right) \approx \left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) -$$ -++++++ +++++ endif::[] [[PRIMARIES_ACESCC]] @@ -917,22 +903,22 @@ endif::[] The following chromaticity coordinates are defined in <> (ACEScct) and S-2014-003 (ACEScc), which share the same primaries: [latexmath] -++++++ +++++ \begin{align*} R_x &= 0.713 & R_y &= 0.293 \\ G_x &= 0.165 & G_y &= 0.830 \\ B_x &= 0.128 & B_y &= 0.044 \\ W_x &= 0.32168 & W_y &= 0.33767 \end{align*} -++++++ +++++ Therefore to convert from linear color values defined in terms of ACEScc/ACEScct color primaries to _XYZ_ space the formulae in <> result in the following matrix: ifeval::["{svgpdf}"=="pdf"] [latexmath] -++++++ -$$\left(\begin{array}{c}X \\ +++++ +\left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) \approx \left(\begin{array}{r@{}lr@{}lr@{}l} @@ -941,13 +927,13 @@ Z\end{array}\right) \approx -0.&0055746495, & 0.&0040607335, & 1.&0103391003\end{array}\right) \left(\begin{array}{c} R_{\textrm{ACEScct}} \\ G_{\textrm{ACEScct}} \\ -B_{\textrm{ACEScct}}\end{array}\right)$$ -++++++ +B_{\textrm{ACEScct}}\end{array}\right) +++++ endif::[] ifeval::["{svgpdf}"=="svg"] [latexmath] -++++++ -$$\left(\begin{array}{c}X \\ +++++ +\left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) \approx \left(\begin{array}{ccc} @@ -956,15 +942,15 @@ Z\end{array}\right) \approx -0.0055746495, & 0.0040607335, & 1.0103391003\end{array}\right) \left(\begin{array}{c} R_{\textrm{ACEScct}} \\ G_{\textrm{ACEScct}} \\ -B_{\textrm{ACEScct}}\end{array}\right)$$ -++++++ +B_{\textrm{ACEScct}}\end{array}\right) +++++ endif::[] The inverse transformation, from the _XYZ_ space to a color defined in terms of ACEScc/ACEScct color primaries, is: ifeval::["{svgpdf}"=="pdf"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{\textrm{ACEScc}} \\ +++++ +\left(\begin{array}{c} R_{\textrm{ACEScc}} \\ G_{\textrm{ACEScc}} \\ B_{\textrm{ACEScc}}\end{array}\right) \approx \left(\begin{array}{r@{}lr@{}lr@{}l} @@ -974,13 +960,12 @@ B_{\textrm{ACEScc}}\end{array}\right) \approx \left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) -$$ -++++++ +++++ endif::[] ifeval::["{svgpdf}"=="svg"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{\textrm{ACEScc}} \\ +++++ +\left(\begin{array}{c} R_{\textrm{ACEScc}} \\ G_{\textrm{ACEScc}} \\ B_{\textrm{ACEScc}}\end{array}\right) \approx \left(\begin{array}{ccc} @@ -990,8 +975,7 @@ B_{\textrm{ACEScc}}\end{array}\right) \approx \left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) -$$ -++++++ +++++ endif::[] <<< @@ -1000,14 +984,14 @@ endif::[] The following chromaticity coordinates are defined in <>: [latexmath] -++++++ +++++ \begin{align*} R_x &= 0.6800 & R_y &= 0.3200 \\ G_x &= 0.2650 & G_y &= 0.6900 \\ B_x &= 0.1500 & B_y &= 0.0600 \\ W_x &= 0.3127 & W_y &= 0.3290 \end{align*} -++++++ +++++ NOTE: The DCI P3 color space defines the bounds of its gamut using these primaries, but actual color data in DCI P3 is encoded using @@ -1020,8 +1004,8 @@ color primaries to _XYZ_ space the formulae in <> result in the following matrix: ifeval::["{svgpdf}"=="pdf"] [latexmath] -++++++ -$$\left(\begin{array}{c}X \\ +++++ +\left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) \approx \left(\begin{array}{r@{}lr@{}lr@{}l} @@ -1030,13 +1014,13 @@ Z\end{array}\right) \approx 0.&0000000000, & 0.&0451133819, & 1.&0439443689\end{array}\right) = \left(\begin{array}{c} R_{\textrm{DisplayP3}} \\ G_{\textrm{DisplayP3}} \\ -B_{\textrm{DisplayP3}}\end{array}\right)$$ -++++++ +B_{\textrm{DisplayP3}}\end{array}\right) +++++ endif::[] ifeval::["{svgpdf}"=="svg"] [latexmath] -++++++ -$$\left(\begin{array}{c}X \\ +++++ +\left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) \approx \left(\begin{array}{ccc} @@ -1045,15 +1029,15 @@ Z\end{array}\right) \approx 0.0000000000, & 0.0451133819, & 1.0439443689\end{array}\right) = \left(\begin{array}{c} R_{\textrm{DisplayP3}} \\ G_{\textrm{DisplayP3}} \\ -B_{\textrm{DisplayP3}}\end{array}\right)$$ -++++++ +B_{\textrm{DisplayP3}}\end{array}\right) +++++ endif::[] The inverse transformation, from the _XYZ_ space to a color defined in terms of DisplayP3 color primaries, is: ifeval::["{svgpdf}"=="pdf"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{\textrm{DisplayP3}} \\ +++++ +\left(\begin{array}{c} R_{\textrm{DisplayP3}} \\ G_{\textrm{DisplayP3}} \\ B_{\textrm{DisplayP3}}\end{array}\right) \approx \left(\begin{array}{r@{}lr@{}lr@{}l} @@ -1063,12 +1047,11 @@ B_{\textrm{DisplayP3}}\end{array}\right) \approx \left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) -$$ -++++++ +++++ endif::[] ifeval::["{svgpdf}"=="svg"] -++++++ -$$\left(\begin{array}{c} R_{\textrm{DisplayP3}} \\ +++++ +\left(\begin{array}{c} R_{\textrm{DisplayP3}} \\ G_{\textrm{DisplayP3}} \\ B_{\textrm{DisplayP3}}\end{array}\right) \approx \left(\begin{array}{ccc} @@ -1078,14 +1061,13 @@ B_{\textrm{DisplayP3}}\end{array}\right) \approx \left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) -$$ -++++++ +++++ endif::[] NOTE: These matrices differ from those given in <> due to the choice of a D65 white point in Display P3. The matrices in 432-1 can be reproduced by applying a white point -of latexmath:[$W_x = 0.314,\ W_y = 0.351$] to the above primaries. +of latexmath:[W_x = 0.314,\ W_y = 0.351] to the above primaries. <<< [[PRIMARIES_ADOBERGB]] @@ -1094,21 +1076,21 @@ of latexmath:[$W_x = 0.314,\ W_y = 0.351$] to the above primaries. The following chromaticity coordinates are defined in <>: [latexmath] -++++++ +++++ \begin{align*} R_x &= 0.6400 & R_y &= 0.3300 \\ G_x &= 0.2100 & G_y &= 0.7100 \\ B_x &= 0.1500 & B_y &= 0.0600 \\ W_x &= 0.3127 & W_y &= 0.3290 \end{align*} -++++++ +++++ Therefore to convert from linear color values defined in terms of Adobe RGB (1998) color primaries to _XYZ_ space the formulae in <> result in the following matrix: [latexmath] -++++++ -$$\left(\begin{array}{c}X \\ +++++ +\left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) \approx \left(\begin{array}{ccc} @@ -1117,14 +1099,14 @@ Z\end{array}\right) \approx 0.0270313614, & 0.0706888525, & 0.9913375368\end{array}\right) = \left(\begin{array}{c} R_{\textrm{AdobeRGB}} \\ G_{\textrm{AdobeRGB}} \\ -B_{\textrm{AdobeRGB}}\end{array}\right)$$ -++++++ +B_{\textrm{AdobeRGB}}\end{array}\right) +++++ The inverse transformation, from the _XYZ_ space to a color defined in terms of Adobe RGB (1998) color primaries, is: ifeval::["{svgpdf}"=="pdf"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{\textrm{AdobeRGB}} \\ +++++ +\left(\begin{array}{c} R_{\textrm{AdobeRGB}} \\ G_{\textrm{AdobeRGB}} \\ B_{\textrm{AdobeRGB}}\end{array}\right) \approx \left(\begin{array}{r@{}lr@{}lr@{}l} @@ -1134,13 +1116,12 @@ B_{\textrm{AdobeRGB}}\end{array}\right) \approx \left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) -$$ -++++++ +++++ endif::[] ifeval::["{svgpdf}"=="svg"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{\textrm{AdobeRGB}} \\ +++++ +\left(\begin{array}{c} R_{\textrm{AdobeRGB}} \\ G_{\textrm{AdobeRGB}} \\ B_{\textrm{AdobeRGB}}\end{array}\right) \approx \left(\begin{array}{ccc} @@ -1150,8 +1131,7 @@ B_{\textrm{AdobeRGB}}\end{array}\right) \approx \left(\begin{array}{c}X \\ Y \\ Z\end{array}\right) -$$ -++++++ +++++ endif::[] Adobe RGB (1998) defines a reference display white brightness of 160cd/m^2^ and @@ -1169,8 +1149,8 @@ as follows: ifeval::["{svgpdf}"=="pdf"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{601\textrm{EBU}} \\ +++++ +\left(\begin{array}{c} R_{601\textrm{EBU}} \\ G_{601\textrm{EBU}} \\ B_{601\textrm{EBU}}\end{array}\right) \approx \left(\begin{array}{r@{}lr@{}lr@{}l} @@ -1183,13 +1163,13 @@ B_{601\textrm{EBU}}\end{array}\right) \approx 0.019331, & 0.119195, & 0.950532\end{array}\right) \left(\begin{array}{c} R_{709} \\ G_{709} \\ -B_{709}\end{array}\right)$$ -++++++ +B_{709}\end{array}\right) +++++ endif::[] ifeval::["{svgpdf}"=="svg"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{601\textrm{EBU}} \\ +++++ +\left(\begin{array}{c} R_{601\textrm{EBU}} \\ G_{601\textrm{EBU}} \\ B_{601\textrm{EBU}}\end{array}\right) \approx \left(\begin{array}{ccc} @@ -1202,14 +1182,14 @@ B_{601\textrm{EBU}}\end{array}\right) \approx 0.019331, & 0.119195, & 0.950532\end{array}\right) \left(\begin{array}{c} R_{709} \\ G_{709} \\ -B_{709}\end{array}\right)$$ -++++++ +B_{709}\end{array}\right) +++++ endif::[] ifeval::["{svgpdf}"=="pdf"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{601\textrm{EBU}} \\ +++++ +\left(\begin{array}{c} R_{601\textrm{EBU}} \\ G_{601\textrm{EBU}} \\ B_{601\textrm{EBU}}\end{array}\right) \approx \left(\begin{array}{r@{}lr@{}lr@{}l} @@ -1218,13 +1198,13 @@ B_{601\textrm{EBU}}\end{array}\right) \approx 0.&0, & -0.&011934, & 1.&011934\end{array}\right) \left(\begin{array}{c} R_{709} \\ G_{709} \\ -B_{709}\end{array}\right)$$ -++++++ +B_{709}\end{array}\right) +++++ endif::[] ifeval::["{svgpdf}"=="svg"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{601\textrm{EBU}} \\ +++++ +\left(\begin{array}{c} R_{601\textrm{EBU}} \\ G_{601\textrm{EBU}} \\ B_{601\textrm{EBU}}\end{array}\right) \approx \left(\begin{array}{ccc} @@ -1233,8 +1213,8 @@ B_{601\textrm{EBU}}\end{array}\right) \approx 0.0, & -0.011934, & 1.011934\end{array}\right) \left(\begin{array}{c} R_{709} \\ G_{709} \\ -B_{709}\end{array}\right)$$ -++++++ +B_{709}\end{array}\right) +++++ endif::[] Conversion from BT.601 625-line to BT.709 primaries can be performed @@ -1242,8 +1222,8 @@ using these matrices: ifeval::["{svgpdf}"=="pdf"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{709} \\ +++++ +\left(\begin{array}{c} R_{709} \\ G_{709} \\ B_{709}\end{array}\right) \approx \left(\begin{array}{r@{}lr@{}lr@{}l} @@ -1256,13 +1236,13 @@ B_{709}\end{array}\right) \approx 0.020182, & 0.129553, & 0.939322\end{array}\right) \left(\begin{array}{c} R_{601\textrm{EBU}} \\ G_{601\textrm{EBU}} \\ -B_{601\textrm{EBU}}\end{array}\right)$$ -++++++ +B_{601\textrm{EBU}}\end{array}\right) +++++ endif::[] ifeval::["{svgpdf}"=="svg"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{709} \\ +++++ +\left(\begin{array}{c} R_{709} \\ G_{709} \\ B_{709}\end{array}\right) \approx \left(\begin{array}{ccc} @@ -1275,14 +1255,14 @@ B_{709}\end{array}\right) \approx 0.020182, & 0.129553, & 0.939322\end{array}\right) \left(\begin{array}{c} R_{601\textrm{EBU}} \\ G_{601\textrm{EBU}} \\ -B_{601\textrm{EBU}}\end{array}\right)$$ -++++++ +B_{601\textrm{EBU}}\end{array}\right) +++++ endif::[] ifeval::["{svgpdf}"=="pdf"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{709} \\ +++++ +\left(\begin{array}{c} R_{709} \\ G_{709} \\ B_{709}\end{array}\right) \approx \left(\begin{array}{r@{}lr@{}lr@{}l} @@ -1291,13 +1271,13 @@ B_{709}\end{array}\right) \approx 0.&0, & 0.&011793, & 0.&988207\end{array}\right) \left(\begin{array}{c} R_{601\textrm{EBU}} \\ G_{601\textrm{EBU}} \\ -B_{601\textrm{EBU}}\end{array}\right)$$ -++++++ +B_{601\textrm{EBU}}\end{array}\right) +++++ endif::[] ifeval::["{svgpdf}"=="svg"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{709} \\ +++++ +\left(\begin{array}{c} R_{709} \\ G_{709} \\ B_{709}\end{array}\right) \approx \left(\begin{array}{ccc} @@ -1306,8 +1286,8 @@ B_{709}\end{array}\right) \approx 0.0, & 0.011793, & 0.988207\end{array}\right) \left(\begin{array}{c} R_{601\textrm{EBU}} \\ G_{601\textrm{EBU}} \\ -B_{601\textrm{EBU}}\end{array}\right)$$ -++++++ +B_{601\textrm{EBU}}\end{array}\right) +++++ endif::[] === BT.709/BT.2020 primary conversion example @@ -1318,8 +1298,8 @@ as follows: ifeval::["{svgpdf}"=="pdf"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{2020} \\ +++++ +\left(\begin{array}{c} R_{2020} \\ G_{2020} \\ B_{2020}\end{array}\right) \approx \left(\begin{array}{r@{}lr@{}lr@{}l} @@ -1332,13 +1312,13 @@ B_{2020}\end{array}\right) \approx 0.019331, & 0.119195, & 0.950532\end{array}\right) \left(\begin{array}{c} R_{709} \\ G_{709} \\ -B_{709}\end{array}\right)$$ -++++++ +B_{709}\end{array}\right) +++++ endif::[] ifeval::["{svgpdf}"=="svg"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{2020} \\ +++++ +\left(\begin{array}{c} R_{2020} \\ G_{2020} \\ B_{2020}\end{array}\right) \approx \left(\begin{array}{ccc} @@ -1351,13 +1331,13 @@ B_{2020}\end{array}\right) \approx 0.019331, & 0.119195, & 0.950532\end{array}\right) \left(\begin{array}{c} R_{709} \\ G_{709} \\ -B_{709}\end{array}\right)$$ -++++++ +B_{709}\end{array}\right) +++++ endif::[] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{2020} \\ +++++ +\left(\begin{array}{c} R_{2020} \\ G_{2020} \\ B_{2020}\end{array}\right) \approx \left(\begin{array}{ccc} @@ -1366,16 +1346,16 @@ B_{2020}\end{array}\right) \approx 0.016392, & 0.088013, & 0.895595\end{array}\right) \left(\begin{array}{c} R_{709} \\ G_{709} \\ -B_{709}\end{array}\right)$$ -++++++ +B_{709}\end{array}\right) +++++ Conversion from BT.2020 primaries to BT.709 primaries can be performed with the following matrices: ifeval::["{svgpdf}"=="pdf"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{709} \\ +++++ +\left(\begin{array}{c} R_{709} \\ G_{709} \\ B_{709}\end{array}\right) \approx \left(\begin{array}{r@{}lr@{}lr@{}l} @@ -1388,13 +1368,13 @@ B_{709}\end{array}\right) \approx 0.&000000, & 0.&028073, & 1.&060985\end{array}\right) \left(\begin{array}{c} R_{2020} \\ G_{2020} \\ -B_{2020}\end{array}\right)$$ -++++++ +B_{2020}\end{array}\right) +++++ endif::[] ifeval::["{svgpdf}"=="svg"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{709} \\ +++++ +\left(\begin{array}{c} R_{709} \\ G_{709} \\ B_{709}\end{array}\right) \approx \left(\begin{array}{ccc} @@ -1407,14 +1387,14 @@ B_{709}\end{array}\right) \approx 0.000000, & 0.028073, & 1.060985\end{array}\right) \left(\begin{array}{c} R_{2020} \\ G_{2020} \\ -B_{2020}\end{array}\right)$$ -++++++ +B_{2020}\end{array}\right) +++++ endif::[] ifeval::["{svgpdf}"=="pdf"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{709} \\ +++++ +\left(\begin{array}{c} R_{709} \\ G_{709} \\ B_{709}\end{array}\right) \approx \left(\begin{array}{r@{}lr@{}lr@{}l} @@ -1424,13 +1404,13 @@ B_{709}\end{array}\right) \approx \end{array}\right) \left(\begin{array}{c} R_{2020} \\ G_{2020} \\ -B_{2020}\end{array}\right)$$ -++++++ +B_{2020}\end{array}\right) +++++ endif::[] ifeval::["{svgpdf}"=="svg"] [latexmath] -++++++ -$$\left(\begin{array}{c} R_{709} \\ +++++ +\left(\begin{array}{c} R_{709} \\ G_{709} \\ B_{709}\end{array}\right) \approx \left(\begin{array}{ccc} @@ -1440,6 +1420,6 @@ B_{709}\end{array}\right) \approx \end{array}\right) \left(\begin{array}{c} R_{2020} \\ G_{2020} \\ -B_{2020}\end{array}\right)$$ -++++++ +B_{2020}\end{array}\right) +++++ endif::[] diff --git a/pvrtc.txt b/chapters/pvrtc.adoc similarity index 68% rename from pvrtc.txt rename to chapters/pvrtc.adoc index 57c513c..ff25212 100644 --- a/pvrtc.txt +++ b/chapters/pvrtc.adoc @@ -1,5 +1,6 @@ -// Copyright (c) 2014-2019 The Khronos Group Inc. -// Copyright notice at https://www.khronos.org/registry/speccopyright.html +// Copyright 2014-2026 The Khronos Group Inc. +// SPDX-License-Identifier: CC-BY-4.0 + [[PVRTC]] == PVRTC Compressed Texture Image Formats @@ -20,7 +21,7 @@ data wherein texel values are encoded as two low-resolution images, modulation signal, **M~Sig~**, to combine those images. More information on the specifics of the PVRTC1 compression technique can be -found in the ``Graphics Hardware 2003'' paper +found in the "`Graphics Hardware 2003`" paper link:http://cdn.imgtec.com/sdk-documentation/PVR+Texture+Compression.Whitepaper.pdf[Texture Compression using Low-Frequency Signal Modulation]. In PVRTC, images are described in terms of 64-bit little-endian words, @@ -31,9 +32,9 @@ Unlike traditional block-based formats, PVRTC uses adjacent data-words to reconstruct the original image. If combined with this encoding scheme, the <> -is applied to the unquantized version of the _R′_, _G′_ and -_B′_ channels (that is, -latexmath:[$\textit{R}_\textit{out} = \textit{EOTF}_{\textit{sRGB}}\left({\textit{R}'\over 255}\right)$], +is applied to the unquantized version of the _R{prime}_, _G{prime}_ and +_B{prime}_ channels (that is, +latexmath:[\textit{R}_\textit{out} = \textit{EOTF}_{\textit{sRGB}}\left({\textit{R}'\over 255}\right)], etc.) at the end of the texel decode process, but the _A_ channel is interpreted linearly. @@ -43,10 +44,10 @@ interpreted linearly. For PVRTC1 4bpp, each 64-bit word _W_~_X_,_Y_~ at block coordinates (_X_,_Y_) contains the modulation information for a 4{times}4 block of texels beginning -at image pixels latexmath:[$(4\times\mathit{X}, 4\times\mathit{Y})$], and a +at image pixels latexmath:[(4\times\mathit{X}, 4\times\mathit{Y})], and a color sample for each low-resolution image which influences an overlapping 7{times}7 texel region of the final output, with each sample centered on -output pixel latexmath:[$((4\times\mathit{X})+2, (4\times\mathit{Y})+2)$]. +output pixel latexmath:[((4\times\mathit{X})+2, (4\times\mathit{Y})+2)]. Nearly every texel location requires data from a set of 2{times}2 data words in order to be decoded: the low-resolution encoded images are bilinearly interpolated to, in effect, generate a pair of full-resolution images prior to modulation, and this @@ -68,14 +69,14 @@ color contains a bit to describe whether it contains alpha data. .Texel Data format for PVRTC1 4bpp compressed texture formats [width="97%",cols="32*^"] -|======= +|==== 32+| *~Bits 64..32: Color data and flags~* | ~63~ | ~62~ | ~61~ | ~60~ | ~59~ | ~58~ | ~57~ | ~56~ | ~55~ | ~54~ | ~53~ | ~52~ | ~51~ | ~50~ | ~49~ | ~48~ | ~47~ | ~46~ | ~45~ | ~44~ | ~43~ | ~42~ | ~41~ | ~40~ | ~39~ | ~38~ | ~37~ | ~36~ | ~35~ | ~34~ | ~33~ | ~32~ 16+| *Color B* 15+| *Color A* | _M_ 32+| *~Bits 31..0: Modulation data bits [1..0] for pixel offset (_x_, _y_)~* | ~31~ | ~30~ | ~29~ | ~28~ | ~27~ | ~26~ | ~25~ | ~24~ | ~23~ | ~22~ | ~21~ | ~20~ | ~19~ | ~18~ | ~17~ | ~16~ | ~15~ | ~14~ | ~13~ | ~12~ | ~11~ | ~10~ | ~9~ | ~8~ | ~7~ | ~6~ | ~5~ | ~4~ | ~3~ | ~2~ | ~1~ | ~0~ 2+| 3,3 2+| 2,3 2+| 1,3 2+| 0,3 2+| 3,2 2+| 2,2 2+| 1,2 2+| 0,2 2+| 3,1 2+| 2,1 2+| 1,1 2+| 0,1 2+| 3,0 2+| 2,0 2+| 1,0 2+| 0,0 -|======= +|==== ==== PVRTC1 4bpp word offset calculation @@ -85,27 +86,27 @@ word _W~X,Y~_: [[Morton]] .Reflected Morton order 16×4-block image -image::images/Morton.{svgpdf}[title="Reflected Morton Order 16×4-block image",width="{svgpdf@pdf:321pt:426}",align="center"] +image::{images}/Morton.svg[title="Reflected Morton Order 16×4-block image",width="{svgpdf@pdf:321pt:426}",align="center"] Expressing each of the _X_ and _Y_ indices as an array of bits, the index of a particular PVRTC word can be found by interleaving the bits of the _X_ and _Y_ indices as follows: -Let _Xb_ be the number of bits used to express _X_ -- i.e. latexmath:[$\mathit{Xb} = \mathrm{log}_2\left(\left\lceil{\mathit{width}\over 4}\right\rceil\right)$]. +Let _Xb_ be the number of bits used to express _X_ -- i.e. latexmath:[\mathit{Xb} = \mathrm{log}_2\left(\left\lceil{\mathit{width}\over 4}\right\rceil\right)]. -Let _Yb_ be the number of bits used to express _Y_ -- i.e. latexmath:[$\mathit{Yb} = \mathrm{log}_2\left(\left\lceil{\mathit{height}\over 4}\right\rceil\right)$]. +Let _Yb_ be the number of bits used to express _Y_ -- i.e. latexmath:[\mathit{Yb} = \mathrm{log}_2\left(\left\lceil{\mathit{height}\over 4}\right\rceil\right)]. Then: [latexmath] -++++++ +++++ \begin{align*} \textit{Reflected Morton order offset W}_\textit{X,Y} &= \begin{cases} \mathit{X}^{\textit{Xb}}\ldots\mathit{X}^\textrm{n}\ldots\mathit{X}^{\textit{Yb}+1}\mathit{X}^{\textit{Yb}}\mathit{Y}^{\textit{Yb}}\ldots\mathit{X}^\textrm{m}\mathit{Y}^\textrm{m}\ldots\mathit{X}^0\mathit{Y}^0, & \textrm{width} \geq \textrm{height} \\ \mathit{Y}^{\textit{Yb}}\ldots\mathit{Y}^\textrm{n}\ldots\mathit{Y}^{\textit{Xb}+1}\mathit{X}^{\textit{Xb}}\mathit{Y}^{\textit{Xb}}\ldots\mathit{X}^\textrm{m}\mathit{Y}^\textrm{m}\ldots\mathit{X}^0\mathit{Y}^0, & \textrm{width} < \textrm{height} \end{cases} \\ \end{align*} -++++++ +++++ That is, to form the word offset, bits of _X_ and _Y_ are interleaved, with bits from _Y_ in the lower of each interleaved pair. @@ -118,8 +119,8 @@ larger, are appended to the offset bit pattern. For example, <> represents a 64{times}16-texel image represented by 16{times}4 = 64 words of 64 bits. The largest possible _X_ value in this example is -latexmath:[${64\over 4} - 1$] = 15; the largest possible -_Y_ value in this example is latexmath:[${16\over 4} - 1$] = 3. +latexmath:[{64\over 4} - 1] = 15; the largest possible +_Y_ value in this example is latexmath:[{16\over 4} - 1] = 3. The bottom four bits of the word offset are composed by interleaving the bottom two bits of _Y_ and the bottom two bits of _X_ (with _Y_ in the lowest bit). @@ -131,29 +132,30 @@ is constructed as follows: .Calculation of reflected Morton word offset for 13,2 [width="35%"] -|======= +|==== 2+^| _X_ ^| *1* ^| *1* 2+^| *0* 2+^| *1* 2+^| = 13 2+^| _W~13,2~_ ^| *1* ^| *1* ^| *0* ^| _1_ ^| *1* ^| _0_ 2+^| = 54 2+^| _Y_ 2+^| 2+^| _1_ 2+^| _0_ 2+^| = 2 -|======= +|==== Where _wordWidth_ and _wordHeight_ are the image width and height in units of 4{times}4 areas encoded by words: [latexmath] -++++++ +++++ \begin{align*} \textit{wordWidth} =& \left\lceil{\textit{width}\over 4}\right\rceil \\ \textit{wordHeight} =& \left\lceil{\textit{height}\over 4}\right\rceil \end{align*} -++++++ +++++ the word offset for -latexmath:[$\mathit{X} = \left\lfloor{\mathit{x}\over 4}\right\rfloor$] and -latexmath:[$\mathit{Y} = \left\lfloor{\mathit{y}\over 4}\right\rfloor$] can +latexmath:[\mathit{X} = \left\lfloor{\mathit{x}\over 4}\right\rfloor] and +latexmath:[\mathit{Y} = \left\lfloor{\mathit{y}\over 4}\right\rfloor] can be calculated iteratively as follows: ------ +[source] +---- uint32_t reflectedMortonOffset(const uint32_t X, const uint32_t Y, const uint32_t wordWidth, @@ -180,7 +182,7 @@ uint32_t reflectedMortonOffset(const uint32_t X, return offset; } ------ +---- <<< @@ -192,80 +194,80 @@ corresponding to the (_X~Low~_, _Y~Low~_) location of the colors in the low-resolution images. The image colors for a given pixel location (_x_, _y_) are reconstructed using the words containing the four nearest color samples: -latexmath:[$W_{X_\textit{Low},Y_\textit{Low}}$], -latexmath:[$W_{X_\textit{Low}+1,Y_\textit{Low}}$], -latexmath:[$W_{X_\textit{Low},Y_\textit{Low}+1}$] and -latexmath:[$W_{X_\textit{Low}+1,Y_\textit{Low}+1}$], +latexmath:[W_{X_\textit{Low},Y_\textit{Low}}], +latexmath:[W_{X_\textit{Low}+1,Y_\textit{Low}}], +latexmath:[W_{X_\textit{Low},Y_\textit{Low}+1}] and +latexmath:[W_{X_\textit{Low}+1,Y_\textit{Low}+1}], where _X~Low~_ and _Y~Low~_ are derived as follows: [latexmath] -++++++ +++++ \begin{align*} X_\textit{Low}=&\left\lfloor{{x - 2}\over 4}\right\rfloor & Y_\textit{Low}=&\left\lfloor{{y - 2}\over 4}\right\rfloor \end{align*} -++++++ +++++ [NOTE] -===== +==== <> shows a grid of pixels with (_x_ = 0, _y_ = 0) at top left. -Each word latexmath:[$W_{X_\mathit{Mod},Y_\mathit{Mod}}$] holds modulation +Each word latexmath:[W_{X_\mathit{Mod},Y_\mathit{Mod}}] holds modulation values for a 4{times}4 texel region -latexmath:[$\mathbf{M}_{\mathbf{X}_\mathbf{Mod},\mathbf{Y}_\mathbf{Mod}}$], +latexmath:[\mathbf{M}_{\mathbf{X}_\mathbf{Mod},\mathbf{Y}_\mathbf{Mod}}], as described in <>, where -latexmath:[$X_\mathit{Mod} = \left\lfloor{x\over 4}\right\rfloor$] -and latexmath:[$Y_\mathit{Mod} = \left\lfloor{y\over 4}\right\rfloor$]. +latexmath:[X_\mathit{Mod} = \left\lfloor{x\over 4}\right\rfloor] +and latexmath:[Y_\mathit{Mod} = \left\lfloor{y\over 4}\right\rfloor]. -For latexmath:[$X_\mathit{Low} = \left\lfloor{{x - 2}\over 4}\right\rfloor$] -and latexmath:[$Y_\mathit{Low} = \left\lfloor{{y - 2}\over 4}\right\rfloor$], +For latexmath:[X_\mathit{Low} = \left\lfloor{{x - 2}\over 4}\right\rfloor] +and latexmath:[Y_\mathit{Low} = \left\lfloor{{y - 2}\over 4}\right\rfloor], color reconstruction for the pixels shaded in <> requires data -from the words latexmath:[$W_{X_\mathit{Low},Y_\mathit{Low}}$] through -latexmath:[$W_{X_\mathit{Low}+1,Y_\mathit{Low}+1}$]; the pixels for +from the words latexmath:[W_{X_\mathit{Low},Y_\mathit{Low}}] through +latexmath:[W_{X_\mathit{Low}+1,Y_\mathit{Low}+1}]; the pixels for which these these words hold modulation values are shown as -latexmath:[$\mathbf{M}_{\mathbf{X}_\mathbf{Mod},\mathbf{Y}_\mathbf{Mod}}$] +latexmath:[\mathbf{M}_{\mathbf{X}_\mathbf{Mod},\mathbf{Y}_\mathbf{Mod}}] through -latexmath:[$\mathbf{M}_{\mathbf{X}_\mathbf{Mod}+1,\mathbf{Y}_\mathbf{Mod}+1}$], +latexmath:[\mathbf{M}_{\mathbf{X}_\mathbf{Mod}+1,\mathbf{Y}_\mathbf{Mod}+1}], outlined in red. All pixels within the region contained by the dashed outline have the same -values for latexmath:[$X_\mathit{Low}$] and latexmath:[$Y_\mathit{Low}$]. +values for latexmath:[X_\mathit{Low}] and latexmath:[Y_\mathit{Low}]. The remaining shaded pixels have different calculated -latexmath:[$X_\mathit{Low}$] and/or latexmath:[$Y_\mathit{Low}$] values, but +latexmath:[X_\mathit{Low}] and/or latexmath:[Y_\mathit{Low}] values, but due to <>, no contribution is required from additional words. [[PVRTCrecon]] .PVRTC1 image reconstruction -image::images/PVRTC1_image_reconstruction_simple.{svgpdf}[width="{svgpdf@pdf:350pt:550}",align="center"] -===== +image::{images}/PVRTC1_image_reconstruction_simple.svg[width="{svgpdf@pdf:350pt:550}",align="center"] +==== <<< -The texture data words are wrapped toroidally, such that the ``nearest'' +The texture data words are wrapped toroidally, such that the "`nearest`" sample may exist on the opposite side of the image. [NOTE] -===== +==== For example, sampling a pixel in any corner of the image results in the words in all four corners being examined -- or sampling a pixel at the bottom of the image will result in words from the top of the image being examined, as shown in <>. -In this example, the nearest samples ``below'' the shaded pixels in regions -latexmath:[$\mathbf{M}_{\mathbf{X}_\mathbf{Mod},\mathbf{Y}_\mathbf{Mod}}$] +In this example, the nearest samples "`below`" the shaded pixels in regions +latexmath:[\mathbf{M}_{\mathbf{X}_\mathbf{Mod},\mathbf{Y}_\mathbf{Mod}}] and -latexmath:[$\mathbf{M}_{\mathbf{X}_\mathbf{Mod}+1,\mathbf{Y}_\mathbf{Mod}}$] +latexmath:[\mathbf{M}_{\mathbf{X}_\mathbf{Mod}+1,\mathbf{Y}_\mathbf{Mod}}] the row of words at the top of the image, and the nearest samples -``above'' the shaded pixels in regions -latexmath:[$\mathbf{M}_{\mathbf{X}_\mathbf{Mod},\mathbf{Y}_\mathbf{Mod}+1}$] +"`above`" the shaded pixels in regions +latexmath:[\mathbf{M}_{\mathbf{X}_\mathbf{Mod},\mathbf{Y}_\mathbf{Mod}+1}] and -latexmath:[$\mathbf{M}_{\mathbf{X}_\mathbf{Mod}+1,\mathbf{Y}_\mathbf{Mod}+1}$] -are in words latexmath:[$W_{X_\mathit{Low},Y_\mathit{Low}}$] and -latexmath:[$W_{X_\mathit{Low}+1,Y_\mathit{Low}}$] at the bottom of the image. +latexmath:[\mathbf{M}_{\mathbf{X}_\mathbf{Mod}+1,\mathbf{Y}_\mathbf{Mod}+1}] +are in words latexmath:[W_{X_\mathit{Low},Y_\mathit{Low}}] and +latexmath:[W_{X_\mathit{Low}+1,Y_\mathit{Low}}] at the bottom of the image. [[PVRTCwraprecon]] .PVRTC1 image reconstruction (wrapping) -image::images/PVRTC1_image_reconstruction_wrap.{svgpdf}[width="{svgpdf@pdf:300pt:466}",align="center"] -===== +image::{images}/PVRTC1_image_reconstruction_wrap.svg[width="{svgpdf@pdf:300pt:466}",align="center"] +==== <<< @@ -279,7 +281,7 @@ The exact data layout of each color is described below: .Data layout of color segments in a PVRTC1 word [cols="^,^1,^1,^1,^1,^1,^1,^1,^1,^1,^1,^1,^1,^1,^1,^1",width="55%"] -|==================================================================== +|==== 16+s| ~*Color B* -- opaque color mode (opacity flag _Op_ = 1)~ | ~63~ | ~62~ | ~61~ | ~60~ | ~59~ | ~58~ | ~57~ | ~56~ | ~55~ | ~54~ | ~53~ | ~52~ | ~51~ | ~50~ | ~49~ | ~48~ | 1 5+| Red 5+| Green 5+| Blue @@ -292,7 +294,7 @@ The exact data layout of each color is described below: 16+s| ~*Color A* -- translucent color mode (opacity flag _Op_ = 0)~ | ~47~ | ~46~ | ~45~ | ~44~ | ~43~ | ~42~ | ~41~ | ~40~ | ~39~ | ~38~ | ~37~ | ~36~ | ~35~ | ~34~ | ~33~ | ~32~ | 0 3+| Alpha 4+| Red 4+| Green 3+| Blue | _M_ -|==================================================================== +|==== <<< @@ -317,27 +319,27 @@ For each channel _C_ of each color (*Color A* and *Color B*), the interpolation proceeds as follows: * For low-resolution image color channel -latexmath:[$\textbf{C}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$] +latexmath:[\textbf{C}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}] stored in word -latexmath:[$\textit{W}_{\textit{X}_\textit{Low},\textit{Y}_\textit{Low}}$]: -** _X~Low~_ = latexmath:[$\left\lfloor{{x-2}\over 4}\right\rfloor$], +latexmath:[\textit{W}_{\textit{X}_\textit{Low},\textit{Y}_\textit{Low}}]: +** _X~Low~_ = latexmath:[\left\lfloor{{x-2}\over 4}\right\rfloor], as described above. -** _Y~Low~_ = latexmath:[$\left\lfloor{{y-2}\over 4}\right\rfloor$], +** _Y~Low~_ = latexmath:[\left\lfloor{{y-2}\over 4}\right\rfloor], as described above. * Using relative coordinates: -** latexmath:[$x_r +** latexmath:[x_r = (x - 2) - \left(4\times\left\lfloor{{x - 2}\over 4}\right\rfloor\right) -= (x - 2) - (4 \times X_\textit{Low})$] -** latexmath:[$y_r += (x - 2) - (4 \times X_\textit{Low})] +** latexmath:[y_r = (y - 2) - \left(4\times\left\lfloor{{y - 2}\over 4}\right\rfloor\right) -= (y - 2) - (4 \times Y_\textit{Low})$] += (y - 2) - (4 \times Y_\textit{Low})] * Coordinates wrap at the edges of the image. * An interpolation is performed which is mathematically equivalent to <>. [[PVRTC1_4bpp_interpolation]] .PVRTC1 4bpp color channel interpolation [latexmath] -++++++ +++++ \begin{align*} \textit{C}_\textit{x,y} = & \left(\textbf{C}_{\textbf{X}_\textbf{Low}, \textbf{Y}_\textbf{Low}} @@ -350,29 +352,29 @@ as described above. \left(\textbf{C}_{\textbf{X}_\textbf{Low}+1, \textbf{Y}_\textbf{Low}+1} \times x_r \times y_r\right) \end{align*} -++++++ +++++ [NOTE] ==== The colors of **Image A** and **Image B** at -(latexmath:[$x = (4 \times X_\mathit{Low} + 2)$], -latexmath:[$y = (4 \times Y_\mathit{Low} + 2)$]) are exactly the +(latexmath:[x = (4 \times X_\mathit{Low} + 2)], +latexmath:[y = (4 \times Y_\mathit{Low} + 2)]) are exactly the corresponding colors that word -latexmath:[$W_{X_\mathit{Low}, Y_\mathit{Low}}$] encodes. -Texels in the same column as a texel block such that latexmath:[$x_r = 0$] +latexmath:[W_{X_\mathit{Low}, Y_\mathit{Low}}] encodes. +Texels in the same column as a texel block such that latexmath:[x_r = 0] are not influenced by the color samples from words -latexmath:[$W_{X_\mathit{Low}+1, Y_\mathit{Low}}$] and -latexmath:[$W_{X_\mathit{Low}+1, Y_\mathit{Low}+1}$]. -Texels in the same row as a texel block such that latexmath:[$y_r = 0$] +latexmath:[W_{X_\mathit{Low}+1, Y_\mathit{Low}}] and +latexmath:[W_{X_\mathit{Low}+1, Y_\mathit{Low}+1}]. +Texels in the same row as a texel block such that latexmath:[y_r = 0] are not influenced by the color samples from words -latexmath:[$W_{X_\mathit{Low}, Y_\mathit{Low}+1}$] and -latexmath:[$W_{X_\mathit{Low}+1, Y_\mathit{Low}+1}$]. -Therefore a single color sample at latexmath:[$C_{x,y}$] influences the +latexmath:[W_{X_\mathit{Low}, Y_\mathit{Low}+1}] and +latexmath:[W_{X_\mathit{Low}+1, Y_\mathit{Low}+1}]. +Therefore a single color sample at latexmath:[C_{x,y}] influences the interpolated color of all texels in the 7{times}7 region -from latexmath:[$C_{x-3,y-3}$] to latexmath:[$C_{x+3,y+3}$] centered on +from latexmath:[C_{x-3,y-3}] to latexmath:[C_{x+3,y+3}] centered on the color sample. -  +{nbsp} Any 2{times}2 quad of texel values can be evaluated from a single set of four adjacent texel blocks. @@ -385,11 +387,11 @@ self-contained texel blocks of other schemes. For the red, green and blue channels, _C~x,y~_ is a 5.4-bit fixed-point value whose bit pattern can be converted to an 8-bit normalized value, i.e. UNORM, as -latexmath:[$\textbf{Image \{A,B\}}\{\textit{R,G,B}\}_{x,y} = \left\lfloor{{C_{x,y}}\over 2}\right\rfloor+\left\lfloor{{C_{x,y}}\over 64}\right\rfloor$]. +latexmath:[\textbf{Image \{A,B\}}\{\textit{R,G,B}\}_{x,y} = \left\lfloor{{C_{x,y}}\over 2}\right\rfloor+\left\lfloor{{C_{x,y}}\over 64}\right\rfloor]. For the alpha channel, _C~x,y~_ is a 4.4-bit fixed-point value whose bit pattern can be converted to an 8-bit normalized value as -latexmath:[$\textbf{Image \{A,B\}}\{\textit{A}\}_{x,y} = C_{x,y}+\left\lfloor{{C_{x,y}}\over 16}\right\rfloor$]. +latexmath:[\textbf{Image \{A,B\}}\{\textit{A}\}_{x,y} = C_{x,y}+\left\lfloor{{C_{x,y}}\over 16}\right\rfloor]. <<< @@ -400,9 +402,9 @@ The final image is created by linearly interpolating between the *Image A* and *Image B* texels, using the modulation data for each pixel to determine the weighting. The modulation information is retrieved from word -latexmath:[$W_{X_\textit{Mod},Y_\textit{Mod}}$] -where latexmath:[$X_\textit{Mod} = \left\lfloor{x\over 4}\right\rfloor$] -and latexmath:[$Y_\textit{Mod} = \left\lfloor{y\over 4}\right\rfloor$]. +latexmath:[W_{X_\textit{Mod},Y_\textit{Mod}}] +where latexmath:[X_\textit{Mod} = \left\lfloor{x\over 4}\right\rfloor] +and latexmath:[Y_\textit{Mod} = \left\lfloor{y\over 4}\right\rfloor]. The weight for the interpolation is derived from the 2 bits of the modulation data corresponding to the relevant pixel offset (_x~offset~_ = _x_ - (4 {times} _X~Mod~_), @@ -412,23 +414,23 @@ depending on the value of modulation flag _M_. [[PVRTC1ModulationWeights]] .Modulation weights for PVRTC1 4bpp [cols="10,10,1,10,10,10"] -|======= +|==== 2+^| *Standard bilinear* (_M_ = 0) .6+| 3+^| *Punch-through* (_M_ = 1) ^| *Modulation bits* ^| *Weight* ^| *Modulation bits* ^| *Weight* ^| *Alpha* -^| 00 ^| 0 ^| 00 ^| 0 .2+^.^| Normal -^| 01 ^| 3 ^| 01 .2+^.^| 4 -^| 10 ^| 5 ^| 10 ^| ``Punch-through'' +^| 00 ^| 0 ^| 00 ^| 0 .2+^.^|{nbsp}Normal +^| 01 ^| 3 ^| 01 .2+^.^|{nbsp}4 +^| 10 ^| 5 ^| 10 ^| "`Punch-through`" ^| 11 ^| 8 | 11 ^| 8 ^| Normal -|======= +|==== [[PVRTCmodulate]] .PVRTC image modulation [latexmath] -++++++ +++++ \begin{align*} \textit{Final color}_\textit{x,y} = & \left\lfloor{{(\textbf{Image A}_\textit{x,y} \times (8 - \textit{weight})) + (\textbf{Image B}_\textit{x,y} \times \textit{weight})}\over 8}\right\rfloor \end{align*} -++++++ +++++ If punch-through mode is selected, and the modulation bits for a given pixel have a value of 0b10, the alpha value of the resulting color is 0x00. @@ -442,7 +444,7 @@ corresponding pixels in the upscaled images. For this reason, with PVRTC1 4bpp, it is advised to not use pre-multiplied alpha textures, and to change the color of fully transparent areas to the average of the local neighborhood. -PVRTexTool provides ``alpha bleed'' functionality to modify +PVRTexTool provides "`alpha bleed`" functionality to modify fully-transparent areas appropriately. ==== @@ -457,9 +459,9 @@ uses an 8{times}4 bilinear upscale. The inputs to the Morton order encoding for 2bpp mode are: -Let _Xb_ be the number of bits used to express _X_ -- i.e. latexmath:[$\mathit{Xb} = \mathrm{log}_2\left(\left\lceil{\mathit{width}\over 8}\right\rceil\right)$]. +Let _Xb_ be the number of bits used to express _X_ -- i.e. latexmath:[\mathit{Xb} = \mathrm{log}_2\left(\left\lceil{\mathit{width}\over 8}\right\rceil\right)]. -Let _Yb_ be the number of bits used to express _Y_ -- i.e. latexmath:[$\mathit{Yb} = \mathrm{log}_2\left(\left\lceil{\mathit{height}\over 4}\right\rceil\right)$]. +Let _Yb_ be the number of bits used to express _Y_ -- i.e. latexmath:[\mathit{Yb} = \mathrm{log}_2\left(\left\lceil{\mathit{height}\over 4}\right\rceil\right)]. ==== PVRTC1 2bpp image reconstruction @@ -468,25 +470,25 @@ For each channel _C_ of each color (*Color A* and *Color B*), the interpolation proceeds as follows: * For low-resolution image color channel -latexmath:[$\textbf{C}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$] +latexmath:[\textbf{C}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}] stored in word -latexmath:[$\textit{W}_{\textit{X}_\textit{Low},\textit{Y}_\textit{Low}}$]: -** _X~Low~_ = latexmath:[$\left\lfloor{{x-4}\over 8}\right\rfloor$] -** _Y~Low~_ = latexmath:[$\left\lfloor{{y-2}\over 4}\right\rfloor$] +latexmath:[\textit{W}_{\textit{X}_\textit{Low},\textit{Y}_\textit{Low}}]: +** _X~Low~_ = latexmath:[\left\lfloor{{x-4}\over 8}\right\rfloor] +** _Y~Low~_ = latexmath:[\left\lfloor{{y-2}\over 4}\right\rfloor] * Using relative coordinates: -** latexmath:[$x_r +** latexmath:[x_r = (x - 4) - \left(8\times\left\lfloor{{x - 4}\over 8}\right\rfloor\right) -= (x - 4) - (8 \times X_\textit{Low})$] -** latexmath:[$y_r += (x - 4) - (8 \times X_\textit{Low})] +** latexmath:[y_r = (y - 2) - \left(4\times\left\lfloor{{y - 2}\over 4}\right\rfloor\right) -= (y - 2) - (4 \times Y_\textit{Low})$] += (y - 2) - (4 \times Y_\textit{Low})] * Coordinates wrap at the edges of the image. * An interpolation is performed which is mathematically equivalent to <>. [[PVRTC1_2bpp_interpolation]] .PVRTC1 2bpp color channel interpolation [latexmath] -++++++ +++++ \begin{align*} \textit{C}_\textit{x,y} = & \left(\textbf{C}_{\textbf{X}_\textbf{Low}, \textbf{Y}_\textbf{Low}} @@ -499,23 +501,23 @@ latexmath:[$\textit{W}_{\textit{X}_\textit{Low},\textit{Y}_\textit{Low}}$]: \left(\textbf{C}_{\textbf{X}_\textbf{Low}+1, \textbf{Y}_\textbf{Low}+1} \times x_r \times y_r\right) \end{align*} -++++++ +++++ For the red, green and blue channels, _C~x,y~_ is a 5.5-bit fixed-point value whose bit pattern can be converted to an 8-bit normalized value as -latexmath:[$\textbf{Image \{A,B\}}\{\textit{R,G,B}\}_{x,y} = \left\lfloor{{C_{x,y}}\over 4}\right\rfloor+\left\lfloor{{C_{x,y}}\over 128}\right\rfloor$]. +latexmath:[\textbf{Image \{A,B\}}\{\textit{R,G,B}\}_{x,y} = \left\lfloor{{C_{x,y}}\over 4}\right\rfloor+\left\lfloor{{C_{x,y}}\over 128}\right\rfloor]. For the alpha channel, _C~x,y~_ is a 4.5-bit fixed-point value whose bit pattern can be converted to an 8-bit normalized value as -latexmath:[$\textbf{Image \{A,B\}}\{\textit{A}\}_{x,y} = \left\lfloor{{C_{x,y}}\over 2}\right\rfloor+\left\lfloor{{C_{x,y}}\over 32}\right\rfloor$]. +latexmath:[\textbf{Image \{A,B\}}\{\textit{A}\}_{x,y} = \left\lfloor{{C_{x,y}}\over 2}\right\rfloor+\left\lfloor{{C_{x,y}}\over 32}\right\rfloor]. <<< ==== PVRTC1 2bpp color modulation The modulation data, retrieved from word _W~X,Y~_ where -latexmath:[$X_\mathit{Mod} = \left\lfloor{x\over 8}\right\rfloor$] and -latexmath:[$Y_\mathit{Mod} = \left\lfloor{y\over 4}\right\rfloor$], are +latexmath:[X_\mathit{Mod} = \left\lfloor{x\over 8}\right\rfloor] and +latexmath:[Y_\mathit{Mod} = \left\lfloor{y\over 4}\right\rfloor], are interpreted differently in order to accommodate the additional pixels. Each word holds the modulation data which corresponds to pixels that have offsets (_x~offset~_ = _x_ - 8 {times} _X~Mod~_, @@ -529,7 +531,7 @@ affect the layout: .Texel Data format for PVRTC1 2bpp compressed texture formats [width="97%",cols="32*^"] -|======= +|==== 32+| *~Bits 64..32: Color data and flags~* 32+| _Identical to PVRTC1 4bpp_ 32+| *~Bits 31..0: Modulation data: direct encoding, 1 bit per pixel (modulation flag~* ~_M_~ *~= 0) for pixel offset (_x_, _y_)~* @@ -541,7 +543,7 @@ affect the layout: 32+| *~Bits 31..0: Modulation data, horizontally- or vertically-interpolated encoding, samples for pixel offset (_x_, _y_) (modulation flag~* ~_M_~ *~= 1, bit 0 flag = 1)~* | ~31~ | ~30~ | ~29~ | ~28~ | ~27~ | ~26~ | ~25~ | ~24~ | ~23~ | ~22~ | ~21~ | ~20~ | ~19~ | ~18~ | ~17~ | ~16~ | ~15~ | ~14~ | ~13~ | ~12~ | ~11~ | ~10~ | ~9~ | ~8~ | ~7~ | ~6~ | ~5~ | ~4~ | ~3~ | ~2~ | ~1~ | ~0~ 2+| 7,3 2+| 5,3 2+| 3,3 2+| 1,3 2+| 6,2 | 4,2 | _F_ 2+| 2,2 2+| 0,2 2+| 7,1 2+| 5,1 2+| 3,1 2+| 1,1 2+| 6,0 2+| 4,0 2+| 2,0 | 0,0 | 1 -|======= +|==== If the modulation flag _M_ is set to 0, each pixel only has a single bit of modulation data. @@ -550,11 +552,11 @@ and *Image B* for modulation data bit = 1. .Modulation modes for PVRTC1 2bpp [cols="2,2",width="75%"] -|======= +|==== ^| *Modulation flag value* _M_ ^| *Mode* ^| 0 ^| Standard Bilinear, 1bpp modulation ^| 1 ^| Punch-through, interpolated modulation -|======= +|==== If the modulation flag _M_ is set to 1, the pixels with 2-bit stored values have modulation weights equal to those of PVRTC1 4bpp for modulation mode 1, @@ -571,17 +573,17 @@ in bit 20 determine how they are reconstructed: * If bit~0~ is 0, the value is the mean of the weights of the four horizontally- and vertically-adjacent pixels, rounded to the nearest integer: -latexmath:[$\textit{weight}_{x,y} = \left\lfloor{{w(\textit{md}(x-1,y))+w(\textit{md}(x,y-1))+w(\textit{md}(x+1,y))+w(\textit{md}(x,y+1))+2}\over 4}\right\rfloor$]. +latexmath:[\textit{weight}_{x,y} = \left\lfloor{{w(\textit{md}(x-1,y))+w(\textit{md}(x,y-1))+w(\textit{md}(x+1,y))+w(\textit{md}(x,y+1))+2}\over 4}\right\rfloor]. * If bit~0~ is 1, and flag _F_ is 1, the value is the mean of the weights of the two vertically-adjacent pixels, rounded to the nearest integer: -latexmath:[$\textit{weight}_{x,y} = \left\lfloor{{w(\textit{md}(x,y-1))+w(\textit{md}(x,y+1))+1}\over 2}\right\rfloor$]. +latexmath:[\textit{weight}_{x,y} = \left\lfloor{{w(\textit{md}(x,y-1))+w(\textit{md}(x,y+1))+1}\over 2}\right\rfloor]. * If bit~0~ is 1, and flag _F_ is 0, the value is the mean of the weights from the horizontally-adjacent pixels, rounded to the nearest integer: -latexmath:[$\textit{weight}_{x,y} = \left\lfloor{{w(\textit{md}(x-1,y))+w(\textit{md}(x+1,y))+1}\over 2}\right\rfloor$]. +latexmath:[\textit{weight}_{x,y} = \left\lfloor{{w(\textit{md}(x-1,y))+w(\textit{md}(x+1,y))+1}\over 2}\right\rfloor]. where _md(x,y)_ is the modulation data for texel offset (_x_, _y_) and _w_() is the weighting described in <> @@ -619,18 +621,18 @@ discontinuities, or diverse color distributions. .Texel Data format for PVRTC2 4bpp compressed texture formats [width="97%",cols="32*^"] -|======= +|==== 32+| *~Bits 64..32: Color data and flags~* | ~63~ | ~62~ | ~61~ | ~60~ | ~59~ | ~58~ | ~57~ | ~56~ | ~55~ | ~54~ | ~53~ | ~52~ | ~51~ | ~50~ | ~49~ | ~48~ | ~47~ | ~46~ | ~45~ | ~44~ | ~43~ | ~42~ | ~41~ | ~40~ | ~39~ | ~38~ | ~37~ | ~36~ | ~35~ | ~34~ | ~33~ | ~32~ | _Op_ 15+| *Color B* | _H_ 14+| *Color A* | _M_ 32+| *~Bits 31..0: Modulation data bits [1..0] for pixel offset (_x_, _y_) -- identical to PVRTC1 4bpp~* | ~31~ | ~30~ | ~29~ | ~28~ | ~27~ | ~26~ | ~25~ | ~24~ | ~23~ | ~22~ | ~21~ | ~20~ | ~19~ | ~18~ | ~17~ | ~16~ | ~15~ | ~14~ | ~13~ | ~12~ | ~11~ | ~10~ | ~9~ | ~8~ | ~7~ | ~6~ | ~5~ | ~4~ | ~3~ | ~2~ | ~1~ | ~0~ 2+| 3,3 2+| 2,3 2+| 1,3 2+| 0,3 2+| 3,2 2+| 2,2 2+| 1,2 2+| 0,2 2+| 3,1 2+| 2,1 2+| 1,1 2+| 0,1 2+| 3,0 2+| 2,0 2+| 1,0 2+| 0,0 -|======= +|==== .Data layout of color segments in a PVRTC2 word [cols="^,^1,^1,^1,^1,^1,^1,^1,^1,^1,^1,^1,^1,^1,^1,^1",width="55%"] -|==================================================================== +|==== 16+s| ~*Color B* -- opaque color mode (opacity flag _Op_ = 1)~ | ~63~ | ~62~ | ~61~ | ~60~ | ~59~ | ~58~ | ~57~ | ~56~ | ~55~ | ~54~ | ~53~ | ~52~ | ~51~ | ~50~ | ~49~ | ~48~ | 1 5+| Red 5+| Green 5+| Blue @@ -643,7 +645,7 @@ discontinuities, or diverse color distributions. 16+s| ~*Color A* -- translucent color mode (opacity flag _Op_ = 0)~ | ~47~ | ~46~ | ~45~ | ~44~ | ~43~ | ~42~ | ~41~ | ~40~ | ~39~ | ~38~ | ~37~ | ~36~ | ~35~ | ~34~ | ~33~ | ~32~ | _H_ 3+| Alpha 4+| Red 4+| Green 3+| Blue | _M_ -|==================================================================== +|==== There is one change to the interpretation of the color data relative to PVRTC1: as there is only one opacity flag for each PVRTC2 data word, to @@ -667,38 +669,38 @@ centered on boundaries of multiples of 4{times}4 texel regions, the hard transition flag _H_ changes the behavior of the entire red-dotted region shown in <>. This is a subset of the logical 4{times}4 pixel regions -latexmath:[$\textbf{M}_{\textbf{X}_\textbf{Mod},\textbf{Y}_\textbf{Mod}}$] +latexmath:[\textbf{M}_{\textbf{X}_\textbf{Mod},\textbf{Y}_\textbf{Mod}}] through -latexmath:[$\textbf{M}_{\textbf{X}_\textbf{Mod}+1,\textbf{Y}_\textbf{Mod}+1}$] +latexmath:[\textbf{M}_{\textbf{X}_\textbf{Mod}+1,\textbf{Y}_\textbf{Mod}+1}] that correspond to the modulation data stored in 64-bit data words -latexmath:[$W_{X_\mathit{Mod},Y_\mathit{Mod}}$] through -latexmath:[$W_{X_\mathit{Mod}+1,Y_\mathit{Mod}+1}$]. +latexmath:[W_{X_\mathit{Mod},Y_\mathit{Mod}}] through +latexmath:[W_{X_\mathit{Mod}+1,Y_\mathit{Mod}+1}]. The flag _H_ for this hard transition region is stored in -latexmath:[$W_{X_\mathit{Mod},Y_\mathit{Mod}}^{47}$]. +latexmath:[W_{X_\mathit{Mod},Y_\mathit{Mod}}^{47}]. [[PVRTC2HardTransition]] .PVRTC2 hard transition subsets -image::images/PVRTC2_hard_transition.{svgpdf}[title="PVRTC2 hard transition subsets",width="{svgpdf@pdf:130pt:200}",align="center"] +image::{images}/PVRTC2_hard_transition.svg[title="PVRTC2 hard transition subsets",width="{svgpdf@pdf:130pt:200}",align="center"] The hard transition region is further subdivided into four smaller subregions, shown with the dotted 2{times}2 texel outlines in <>, where it intersects the pixel regions -latexmath:[$\textbf{M}_{\textbf{X}_\textbf{Mod},\textbf{Y}_\textbf{Mod}}$] +latexmath:[\textbf{M}_{\textbf{X}_\textbf{Mod},\textbf{Y}_\textbf{Mod}}] through -latexmath:[$\textbf{M}_{\textbf{X}_\textbf{Mod}+1,\textbf{Y}_\textbf{Mod}+1}$]. +latexmath:[\textbf{M}_{\textbf{X}_\textbf{Mod}+1,\textbf{Y}_\textbf{Mod}+1}]. The hard transition flag _H_, coupled with the relevant modulation flag _M_ for the texel subregion, determines how the colors for each reconstructed pixel in the subregion are evaluated, as summarized in the table below. .Modulation modes for PVRTC2 4bpp [cols="1^,1^,2^"] -|======= +|==== ^| *Modulation flag* _M_ ^| *Hard transition flag* _H_ ^| *Mode* | 0 | 0 | Standard bilinear | 1 | 0 | Punch-through alpha | 0 | 1 | Non-interpolated | 1 | 1 | Local palette -|======= +|==== In `standard bilinear' the modulation behaves as described for PVRTC1 4bpp. @@ -719,7 +721,7 @@ used directly, in the sense that the stored colors are expanded, where necessary, via bit replication to an _ARGB_:4555 format and then, again, by bit replication to _ARGB_:8888. The modulation encodings are interpreted in the same manner as for the -``standard bilinear'' weights, and the colors blended, as before, with +"`standard bilinear`" weights, and the colors blended, as before, with <>. <<< @@ -732,131 +734,131 @@ Instead, the eight distinct colors from each surrounding word make up a local palette from which colors are selected. Denoting *Color B* and *Color A* from words -latexmath:[$W_{X_\textit{Low},Y_\textit{Low}}$] through -latexmath:[$W_{X_\textit{Low}+1,Y_\textit{Low}+1}$] as described +latexmath:[W_{X_\textit{Low},Y_\textit{Low}}] through +latexmath:[W_{X_\textit{Low}+1,Y_\textit{Low}+1}] as described above, the following colors are available: -latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$], -latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$], -latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}$], -latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}$], -latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}$], -latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}$], -latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}+1}$] +latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}], +latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}], +latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}], +latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}], +latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}], +latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}], +latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}+1}] and -latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}+1}$]. +latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}+1}]. Whilst 8 distinct colors exist in each of those four words, only two bits of modulation data are available for each pixel. Subsequently, each pixel at offset -latexmath:[$(x_r = (x - 2) - (4 \times X_\textit{Low}), -y_r = (y - 2) - (4 \times Y_\textit{Low}))$] relative to +latexmath:[(x_r = (x - 2) - (4 \times X_\textit{Low}), +y_r = (y - 2) - (4 \times Y_\textit{Low}))] relative to start of the hard transition region has access to a subset of the palette as follows: .Color mappings in local palette mode for PVRTC2 4bpp [cols="2^,5^,3^,3^,3^"] -|================================================================== +|==== | *~Modulation bits~* | *~0,0~* | *~1,0~* | *~2,0~* | *~3,0~* | 0 -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}] | 1 -| latexmath:[$\left\lfloor{{5\times \textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}+3\times \textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}}\over 8}\right\rfloor$] -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$] +| latexmath:[\left\lfloor{{5\times \textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}+3\times \textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}}\over 8}\right\rfloor] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}] | 2 -| latexmath:[$\left\lfloor{{3\times \textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}+5\times \textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}}\over 8}\right\rfloor$] -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}$] +| latexmath:[\left\lfloor{{3\times \textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}+5\times \textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}}\over 8}\right\rfloor] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}] | 3 -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}$] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}] | *~Modulation bits~* | *~0,1~* | *~1,1~* | *~2,1~* | *~3,1~* | 0 -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}+1}$] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}+1}] | 1 -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}] | 2 -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}$] -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}$] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}] | 3 -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}$] -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}$] -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}$] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}] | *~Modulation bits~* |*~0,2~* | *~1,2~* | *~2,2~* | *~3,2~* | 0 -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}+1}$] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}+1}] | 1 -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}+1}$] -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}+1}$] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}+1}] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}+1}] | 2 -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}$] -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}$] -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}$] -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}$] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}] | 3 -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}$] -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}$] -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}$] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}] | *~Modulation bits~* | *~0,3~* | *~1,3~* | *~2,3~* | *~3,3~* | 0 -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}+1}$] -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}+1}$] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}+1}] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}+1}] | 1 -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}$] -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}+1}$] -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}+1}$] -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}+1}$] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}}] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}+1}] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}+1}] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}+1}] | 2 -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}$] -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}$] -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}$] -| latexmath:[$\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}$] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}] +| latexmath:[\textbf{A}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}] | 3 -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}$] -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}$] -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}$] -| latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}$] -|================================================================== +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low},\textbf{Y}_\textbf{Low}+1}] +| latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}] +|==== [NOTE] ==== The entry for offset 0,0 is interpolated as per PVRTC's standard bilinear filtering mode. It will thus only use colors from word -latexmath:[$W_{X_\textit{Low},Y_\textit{Low}}$]. +latexmath:[W_{X_\textit{Low},Y_\textit{Low}}]. -  +{nbsp} The local palette mode shares with the other modes of PVRTC2 the property -that the column latexmath:[$x_r = 0$] has no contribution from words -latexmath:[$W_{X_\mathit{Low}+1, Y_\mathit{Low}}$] and -latexmath:[$W_{X_\mathit{Low}+1, Y_\mathit{Low}+1}$], -and that row latexmath:[$y_r = 0$] has no contribution from words -latexmath:[$W_{X_\mathit{Low}, Y_\mathit{Low}+1}$] and -latexmath:[$W_{X_\mathit{Low}+1, Y_\mathit{Low}+1}$]. +that the column latexmath:[x_r = 0] has no contribution from words +latexmath:[W_{X_\mathit{Low}+1, Y_\mathit{Low}}] and +latexmath:[W_{X_\mathit{Low}+1, Y_\mathit{Low}+1}], +and that row latexmath:[y_r = 0] has no contribution from words +latexmath:[W_{X_\mathit{Low}, Y_\mathit{Low}+1}] and +latexmath:[W_{X_\mathit{Low}+1, Y_\mathit{Low}+1}]. Therefore any 2{times}2 quad of texel values, required for example by bilinear filtering, can be evaluated from a single set of four adjacent texel blocks. @@ -866,7 +868,7 @@ texel blocks. pixel above. For instance, a modulation value of 3 (bit pattern 11) for pixel location 0,1 (which is offset 2,3 relative to the top left of block P) would - correspond to color latexmath:[$\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}$] being selected. + correspond to color latexmath:[\textbf{B}_{\textbf{X}_\textbf{Low}+1,\textbf{Y}_\textbf{Low}}] being selected. * The stored color values are first expanded, _where necessary_, to _ARGB_:4555 (via bit replication for _R_, _G_, or _B_ and via padding @@ -892,12 +894,12 @@ the single opacity flag _Op_, as specified in the PVRTC2 4bpp format. .Texel Data format for PVRTC2 2bpp compressed texture formats [width="50%"] -|======= +|==== ^s| Bits 63-32: Color data and flags ^| Identical to PVRTC2 4bpp ^s| Bits 31-0: Modulation data ^| Identical to PVRTC1 2bpp -|======= +|==== Color values are interpreted in the same manner as for the PVRTC2 4bpp format. @@ -906,13 +908,13 @@ uses the non-interpolated mode -- no local palette mode exists. .Modulation modes for PVRTC2 2bpp [cols="1^,1^,2^"] -|======= +|==== ^| *Modulation flag* _M_ ^| *Hard transition* _H_ ^| Mode | 0 | 0 | Standard bilinear, 1bpp modulation | 1 | 0 | Standard bilinear, interpolated modulation | 0 | 1 | Non-interpolated, 1bpp modulation | 1 | 1 | Non-interpolated, interpolated modulation -|======= +|==== If the hard transition flag _H_ for PVRTC2 2bpp is equal to 0, the format is interpreted in the same manner as the PVRTC1 2bpp format. diff --git a/quantization.txt b/chapters/quantization.adoc similarity index 80% rename from quantization.txt rename to chapters/quantization.adoc index af0be91..ec33cd8 100644 --- a/quantization.txt +++ b/chapters/quantization.adoc @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2019 The Khronos Group Inc. -// Copyright notice at https://www.khronos.org/registry/speccopyright.html +// Copyright 2017-2026 The Khronos Group Inc. +// SPDX-License-Identifier: CC-BY-4.0 [[CONVERSION_QUANTIZATION]] == Quantization schemes @@ -11,16 +11,16 @@ encodings for representing some color models within a given bit depth range. [[QUANTIZATION_NARROW]] -=== ``Narrow range'' encoding +=== "`Narrow range`" encoding ITU broadcast standards typically reserve values at the ends of the representable integer range for rounding errors and for signal control data. The nominal range of representable values between these limits is represented by the following encodings, -for bit depth _n_ = {8, 10, 12}: +for bit depth _n_ = {8,{nbsp}10,{nbsp}12}: [latexmath] -++++++ +++++ \begin{align*} \mathit{DG}' & = \lfloor 0.5 + (219\times G' + 16)\times 2^{n-8}\rfloor &\mathit{DB}' & = \lfloor 0.5 + (219\times B' + 16)\times 2^{n-8}\rfloor \\ @@ -35,11 +35,11 @@ for bit depth _n_ = {8, 10, 12}: &\mathit{DC}'_T & = \lfloor 0.5 + (224\times C'_T + 128)\times 2^{n-8}\rfloor \\ &&\mathit{DC}'_P & = \lfloor 0.5 + (224\times C'_P + 128)\times 2^{n-8}\rfloor \end{align*} -++++++ +++++ The dequantization formulae are therefore: [latexmath] -++++++ +++++ \begin{align*} G' & = {{{\mathit{DG}'\over{2^{n-8}}} - 16}\over{219}} & Y' & = {{{\mathit{DY}'\over{2^{n-8}}} - 16}\over{219}} & @@ -54,102 +54,102 @@ C'_R & = {{{\mathit{DC}'_R\over{2^{n-8}}} - 128}\over{224}} & C'_\mathit{CR} & = {{{\mathit{DC}'_\mathit{CR}\over{2^{n-8}}} - 128}\over{224}} & C'_P & = {{{\mathit{DC}'_P\over{2^{n-8}}} - 128}\over{224}} \end{align*} -++++++ +++++ -For consistency with latexmath:[$Y'_CC'_\mathit{BC}C'_\mathit{RC}$], these +For consistency with latexmath:[Y'_CC'_\mathit{BC}C'_\mathit{RC}], these formulae use the <> and <> terminology of prefixing a _D_ to represent the digital quantized encoding of a numerical value. <<< -That is, in ``narrow range'' encoding: +That is, in "`narrow range`" encoding: [options="header",cols="18%,34%,48%"] -|====== +|==== | Value | Continuous encoding value | Quantized encoding | Black | -{_R′_, -_G′_, -_B′_, -_Y′_, -latexmath:[$Y'_C$], +{_R{prime}_, +_G{prime}_, +_B{prime}_, +_Y{prime}_, +latexmath:[Y'_C], _I_} = 0.0 | -{_DR′_, -_DG′_, -_DB′_, -_DY′_, -latexmath:[$\mathit{DY}'_C$], +{_DR{prime}_, +_DG{prime}_, +_DB{prime}_, +_DY{prime}_, +latexmath:[\mathit{DY}'_C], _DI_} = -latexmath:[$16 \times 2^{n-8}$] +latexmath:[16 \times 2^{n-8}] | Peak brightness | -{_R′_, -_G′_, -_B′_, -_Y′_, -latexmath:[$Y'_C$], +{_R{prime}_, +_G{prime}_, +_B{prime}_, +_Y{prime}_, +latexmath:[Y'_C], _I_} = 1.0 | -{_DR′_, -_DG′_, -_DB′_, -_DY′_, -latexmath:[$\mathit{DY}'_C$], +{_DR{prime}_, +_DG{prime}_, +_DB{prime}_, +_DY{prime}_, +latexmath:[\mathit{DY}'_C], _DI_} = -latexmath:[$235 \times 2^{n-8}$] +latexmath:[235 \times 2^{n-8}] | Minimum color difference value | -{latexmath:[$C'_B$], -latexmath:[$C'_R$], -latexmath:[$C'_\mathit{BC}$], -latexmath:[$C'_\mathit{RC}$], +{latexmath:[C'_B], +latexmath:[C'_R], +latexmath:[C'_\mathit{BC}], +latexmath:[C'_\mathit{RC}], _C~T~_, _C~P~_} = -0.5 | -{latexmath:[$\mathit{DC}'_B$], -latexmath:[$\mathit{DC}'_R$], -latexmath:[$\mathit{DC}'_\mathit{BC}$], -latexmath:[$\mathit{DC}'_\mathit{CR}$], +{latexmath:[\mathit{DC}'_B], +latexmath:[\mathit{DC}'_R], +latexmath:[\mathit{DC}'_\mathit{BC}], +latexmath:[\mathit{DC}'_\mathit{CR}], _DC~T~_, _DC~P~_} = -latexmath:[$16 \times 2^{n-8}$] +latexmath:[16 \times 2^{n-8}] | Maximum color difference value | -{latexmath:[$C'_B$], -latexmath:[$C'_R$], -latexmath:[$C'_\mathit{BC}$], -latexmath:[$C'_\mathit{RC}$], +{latexmath:[C'_B], +latexmath:[C'_R], +latexmath:[C'_\mathit{BC}], +latexmath:[C'_\mathit{RC}], _C~T~_, _C~P~_} = 0.5 | -{latexmath:[$\mathit{DC}'_B$], -latexmath:[$\mathit{DC}'_R$], -latexmath:[$\mathit{DC}'_\mathit{BC}$], -latexmath:[$\mathit{DC}'_\mathit{CR}$], +{latexmath:[\mathit{DC}'_B], +latexmath:[\mathit{DC}'_R], +latexmath:[\mathit{DC}'_\mathit{BC}], +latexmath:[\mathit{DC}'_\mathit{CR}], _DC~T~_, _DC~P~_} = -latexmath:[$240 \times 2^{n-8}$] +latexmath:[240 \times 2^{n-8}] | Achromatic colors | -_R′_ = _G′_ = _B′_ +_R{prime}_ = _G{prime}_ = _B{prime}_ -{latexmath:[$C'_B$], -latexmath:[$C'_R$], -latexmath:[$C'_\mathit{BC}$], -latexmath:[$C'_\mathit{RC}$], +{latexmath:[C'_B], +latexmath:[C'_R], +latexmath:[C'_\mathit{BC}], +latexmath:[C'_\mathit{RC}], _C~T~_, _C~P~_} = 0.0 | -{latexmath:[$\mathit{DC}'_B$], -latexmath:[$\mathit{DC}'_R$], -latexmath:[$\mathit{DC}'_\mathit{BC}$], -latexmath:[$\mathit{DC}'_\mathit{CR}$], +{latexmath:[\mathit{DC}'_B], +latexmath:[\mathit{DC}'_R], +latexmath:[\mathit{DC}'_\mathit{BC}], +latexmath:[\mathit{DC}'_\mathit{CR}], _DC~T~_, _DC~P~_} = -latexmath:[$128 \times 2^{n-8}$] -|====== +latexmath:[128 \times 2^{n-8}] +|==== If, instead of the quantized values, the input is interpreted as fixed-point values in the range 0.0..1.0, as might be the case if the values were treated @@ -157,7 +157,7 @@ as unsigned normalized quantities in a computer graphics API, the following conversions can be applied instead: [latexmath] -++++++ +++++ \begin{align*} G' & = {{{G'_{\mathit{norm}}\times{2^{n-1}}} - 16\times{2^{n-8}}}\over{219\times 2^{n-8}}} & B' & = {{{B'_{\mathit{norm}}\times{2^{n-1}}} - 16\times{2^{n-8}}}\over{219\times 2^{n-8}}} \\ @@ -184,16 +184,16 @@ I_\mathit{norm} & = {{{I\times{219\times 2^{n-8}}} + 16\times{2^{n-8}}}\over C'_\mathit{Tnorm} & = {{{\mathit{DC}'_{T}\times{224\times ^{n-8}}} + 128\times 2^{n-8}}\over{2^{n-1}}} \\ &&C'_\mathit{Pnorm} & = {{{\mathit{DC}'_{P}\times{224\times ^{n-8}}} + 128\times 2^{n-8}}\over{2^{n-1}}} \end{align*} -++++++ +++++ [[QUANTIZATION_FULL]] -=== ``Full range'' encoding +=== "`Full range`" encoding <>-1 and the current <> JFIF specification define the following quantization scheme that does not incorporate any reserved head-room or foot-room, which is optional -and described as ``full range'' in BT.2100, and integral to Rec. T.871. +and described as "`full range`" in BT.2100, and integral to Rec. T.871. NOTE: Both these specifications modify a definition used in previous versions of their specifications, which is described <>. @@ -201,7 +201,7 @@ of their specifications, which is described <>. For bit depth _n_ = {8 (JFIF),10,12 (Rec.2100)}: [latexmath] -++++++ +++++ \begin{align*} \mathit{DG}' & = \textrm{Round}\left(G'\times (2^n-1)\right) & \mathit{DB}' & = \textrm{Round}\left(B'\times (2^n-1)\right) \\ @@ -216,12 +216,12 @@ For bit depth _n_ = {8 (JFIF),10,12 (Rec.2100)}: \mathit{DC}'_T & = \textrm{Round}\left(C'_T\times (2^n-1) + 2^{n-1}\right) \\ &&\mathit{DC}'_P & = \textrm{Round}\left(C'_P\times (2^n-1) + 2^{n-1}\right) \end{align*} -++++++ +++++ <>-1 defines Round() as: [latexmath] -++++++ +++++ \begin{align*} \textrm{Round}(x) &= \textrm{Sign}(x)\times\lfloor|x| + 0.5\rfloor \\ \textrm{Sign}(x) &= \begin{cases} @@ -230,11 +230,11 @@ For bit depth _n_ = {8 (JFIF),10,12 (Rec.2100)}: -1, & x < 0 \end{cases} \end{align*} -++++++ +++++ Note that a chroma channel value of exactly 0.5 corresponds to a quantized -encoding of latexmath:[$2^n$], and must therefore be clamped to the nominal -peak value of latexmath:[$2^n-1$]. +encoding of latexmath:[2^n], and must therefore be clamped to the nominal +peak value of latexmath:[2^n-1]. <> does not have this problem. A chroma channel value of -0.5 corresponds to a quantized encoding of 1, which is the nominal minimum peak value. @@ -243,7 +243,7 @@ In <> (which defines only n = 8), the corresponding formula is: [latexmath] -++++++ +++++ \begin{align*} \textrm{Round}(x) &= \textrm{Clamp}(\lfloor|x| + 0.5\rfloor) \\ \textrm{clamp}(x) &= \begin{cases} @@ -252,7 +252,7 @@ formula is: x, & \textrm{otherwise} \end{cases} \end{align*} -++++++ +++++ Allowing for the clamping at a chroma value of 0.5, these formulae are equivalent across the expected -0.5..0.5 range for chroma and 0.0..1.0 @@ -261,7 +261,7 @@ range for luma values. The dequantization formulae are therefore: [latexmath] -++++++ +++++ \begin{align*} G' & = {\mathit{DG}'\over{2^n - 1}} & Y' & = {\mathit{DY}'\over{2^n - 1}} & @@ -276,99 +276,99 @@ C'_R & = {\mathit{DC}'_R - 2^{n-1}\over{2^n - 1}} & C'_\mathit{CR} & = {\mathit{DC}'_\mathit{CR} - 2^{n-1}\over{2^n - 1}} & C'_P & = {\mathit{DC}'_P - 2^{n-1}\over{2^n - 1}} \end{align*} -++++++ +++++ <<< -That is, in ``full range'' encoding: +That is, in "`full range`" encoding: [options="header",cols="18%,34%,48%"] -|====== +|==== | Value | Continuous encoding value | Quantized encoding | Black | -{_R′_, -_G′_, -_B′_, -_Y′_, -latexmath:[$Y'_C$], +{_R{prime}_, +_G{prime}_, +_B{prime}_, +_Y{prime}_, +latexmath:[Y'_C], _I_} = 0.0 | -{_DR′_, -_DG′_, -_DB′_, -_DY′_, -latexmath:[$\mathit{DY}'_C$], +{_DR{prime}_, +_DG{prime}_, +_DB{prime}_, +_DY{prime}_, +latexmath:[\mathit{DY}'_C], _DI_} = 0 | Peak brightness | -{_R′_, -_G′_, -_B′_, -_Y′_, -latexmath:[$Y'_C$], +{_R{prime}_, +_G{prime}_, +_B{prime}_, +_Y{prime}_, +latexmath:[Y'_C], _I_} = 1.0 | -{_DR′_, -_DG′_, -_DB′_, -_DY′_, -latexmath:[$\mathit{DY}'_C$], +{_DR{prime}_, +_DG{prime}_, +_DB{prime}_, +_DY{prime}_, +latexmath:[\mathit{DY}'_C], _DI_} = 2^_n_^ - 1 | Minimum color difference value | -{latexmath:[$C'_B$], -latexmath:[$C'_R$], -latexmath:[$C'_\mathit{BC}$], -latexmath:[$C'_\mathit{RC}$], +{latexmath:[C'_B], +latexmath:[C'_R], +latexmath:[C'_\mathit{BC}], +latexmath:[C'_\mathit{RC}], _C~T~_, _C~P~_} = -0.5 | -{latexmath:[$\mathit{DC}'_B$], -latexmath:[$\mathit{DC}'_R$], -latexmath:[$\mathit{DC}'_\mathit{BC}$], -latexmath:[$\mathit{DC}'_\mathit{CR}$], +{latexmath:[\mathit{DC}'_B], +latexmath:[\mathit{DC}'_R], +latexmath:[\mathit{DC}'_\mathit{BC}], +latexmath:[\mathit{DC}'_\mathit{CR}], _DC~T~_, _DC~P~_} = 1 | Maximum color difference value | -{latexmath:[$C'_B$], -latexmath:[$C'_R$], -latexmath:[$C'_\mathit{BC}$], -latexmath:[$C'_\mathit{RC}$], +{latexmath:[C'_B], +latexmath:[C'_R], +latexmath:[C'_\mathit{BC}], +latexmath:[C'_\mathit{RC}], _C~T~_, _C~P~_} = 0.5 | -{latexmath:[$\mathit{DC}'_B$], -latexmath:[$\mathit{DC}'_R$], -latexmath:[$\mathit{DC}'_\mathit{BC}$], -latexmath:[$\mathit{DC}'_\mathit{CR}$], +{latexmath:[\mathit{DC}'_B], +latexmath:[\mathit{DC}'_R], +latexmath:[\mathit{DC}'_\mathit{BC}], +latexmath:[\mathit{DC}'_\mathit{CR}], _DC~T~_, _DC~P~_} = -latexmath:[$2^n - 1$] +latexmath:[2^n - 1] (clamped) | Achromatic colors | -_R′_ = _G′_ = _B′_ +_R{prime}_ = _G{prime}_ = _B{prime}_ -{latexmath:[$C'_B$], -latexmath:[$C'_R$], -latexmath:[$C'_\mathit{BC}$], -latexmath:[$C'_\mathit{RC}$], +{latexmath:[C'_B], +latexmath:[C'_R], +latexmath:[C'_\mathit{BC}], +latexmath:[C'_\mathit{RC}], _C~T~_, _C~P~_} = 0.0 | -{latexmath:[$\mathit{DC}'_B$], -latexmath:[$\mathit{DC}'_R$], -latexmath:[$\mathit{DC}'_\mathit{BC}$], -latexmath:[$\mathit{DC}'_\mathit{CR}$], +{latexmath:[\mathit{DC}'_B], +latexmath:[\mathit{DC}'_R], +latexmath:[\mathit{DC}'_\mathit{BC}], +latexmath:[\mathit{DC}'_\mathit{CR}], _DC~T~_, _DC~P~_} = 2^_n_-1^ -|====== +|==== If, instead of the quantized values, the input is interpreted as fixed-point values in the range 0.0..1.0, as might be the case if the values were treated @@ -376,7 +376,7 @@ as unsigned normalized quantities in a computer graphics API, the following conversions can be applied instead: [latexmath] -++++++ +++++ \begin{align*} G' & = G'_{\mathit{norm}} & B' & = B'_{\mathit{norm}} \\ @@ -403,20 +403,20 @@ I_{\mathit{norm}} & = I & C'_{\mathit{Tnorm}} & = \mathit{DC}'_{T} + {2^{n-1}\over{2^n - 1}} \\ &&C'_{\mathit{Pnorm}} & = \mathit{DC}'_{P} + {2^{n-1}\over{2^n - 1}} \end{align*} -++++++ +++++ <<< [[QUANTIZATION_LEGACY_FULL]] -=== Legacy ``full range'' encoding. +=== Legacy "`full range`" encoding. <>-0 formalized an optional encoding scheme that does not incorporate any reserved head-room or foot-room. The legacy <> similarly used the full range of 8-bit -channels to represent latexmath:[$Y'C_BC_R$] color. +channels to represent latexmath:[Y'C_BC_R] color. For bit depth _n_ = {8 (JFIF),10,12 (Rec.2100)}: [latexmath] -++++++ +++++ \begin{align*} \mathit{DG}' & = \lfloor 0.5 + G'\times 2^n\rfloor & \mathit{DB}' & = \lfloor 0.5 + B'\times 2^n\rfloor \\ @@ -431,12 +431,12 @@ For bit depth _n_ = {8 (JFIF),10,12 (Rec.2100)}: \mathit{DC}'_T & = \lfloor 0.5 + (C'_T + 0.5)\times 2^n\rfloor \\ &&\mathit{DC}'_P & = \lfloor 0.5 + (C'_P + 0.5)\times 2^n\rfloor \end{align*} -++++++ +++++ The dequantization formulae are therefore: [latexmath] -++++++ +++++ \begin{align*} G' & = \mathit{DG}'\times 2^{-n} & Y' & = \mathit{DY}'\times 2^{-n} & @@ -451,17 +451,17 @@ C'_R & = \mathit{DC}'_R\times 2^{-n}-0.5 & C'_\mathit{CR} & = \mathit{DC}'_\mathit{CR}\times 2^{-n}-0.5 & C'_P & = \mathit{DC}'_P\times 2^{-n}-0.5 \end{align*} -++++++ +++++ NOTE: These formulae map luma values of 1.0 and chroma values of 0.5 -to latexmath:[$2^n$], for bit depth latexmath:[$n$]. +to latexmath:[2^n], for bit depth latexmath:[n]. This has the effect that the maximum value (e.g. pure white) cannot be represented directly. Out-of-bounds values must be clamped to the largest representable value. NOTE: ITU-R BT.2100-0 dictates that in 12-bit coding, the largest -values encoded should be 4092 (``for consistency'' with 10-bit +values encoded should be 4092 ("`for consistency`" with 10-bit encoding, with a maximum value of 1023). This slightly reduces the maximum intensity which can be expressed, and slightly reduces the saturation range. @@ -477,7 +477,7 @@ as unsigned normalized quantities in a computer graphics API, the following conversions can be applied instead: [latexmath] -++++++ +++++ \begin{align*} G' & = {{G'_{\mathit{norm}}\times (2^n-1)}\over{2^n}} & B' & = {{B'_{\mathit{norm}}\times (2^n-1)}\over{2^n}} & @@ -492,10 +492,10 @@ I & = {{I'_{\mathit{norm}}\times (2^n-1)}\over{2^n}} & C'_T & = {{C'_{\mathit{Tnorm}}\times (2^n-1)}\over{2^n}} - 0.5 & C'_P & = {{C'_{\mathit{Pnorm}}\times (2^n-1)}\over{2^n}} - 0.5 \end{align*} -++++++ +++++ [latexmath] -++++++ +++++ \begin{align*} G_{norm}' & = {{G'\times 2^n}\over{2^n-1}} & B_{norm}' & = {{B'\times 2^n}\over{2^n-1}} & @@ -510,23 +510,23 @@ I_{\mathit{norm}} & = {{I'\times 2^n}\over{2^n-1}} & C'_{\mathit{Tnorm}} & = {{(C'_{T} + 0.5)\times 2^n}\over{2^n-1}} & C'_{\mathit{Pnorm}} & = {{(C'_{P} + 0.5)\times 2^n}\over{2^n-1}} \end{align*} -++++++ +++++ That is, to match the behavior described in these specifications, the inputs to color model conversion should be expanded such that the maximum representable value is that defined by the quantization of these encodings -latexmath:[$\left({255\over 256},\ {1023\over 1024}\ \textrm{or}\ {4095\over 4096}\right)$], +latexmath:[\left({255\over 256},\ {1023\over 1024}\ \textrm{or}\ {4095\over 4096}\right)], and the inverse operation should be applied to the result of the model conversion. For example, a legacy shader-based JPEG decoder may read values in a normalized 0..1 range, where the in-memory value 0 represents 0.0 and the in-memory value 1 represents 1.0. -The decoder should scale the _Y′_ value by a factor of -latexmath:[$255\over 256$] to match the encoding in the <> -document, and latexmath:[$C'_B$] and _C~R~_ should be scaled by -latexmath:[$255\over 256$] and offset by 0.5. -After the model conversion matrix has been applied, the _R′_, -_G′_ and _B′_ values should be scaled by -latexmath:[$256\over 255$], restoring the ability to represent pure white. +The decoder should scale the _Y{prime}_ value by a factor of +latexmath:[255\over 256] to match the encoding in the <> +document, and latexmath:[C'_B] and _C~R~_ should be scaled by +latexmath:[255\over 256] and offset by 0.5. +After the model conversion matrix has been applied, the _R{prime}_, +_G{prime}_ and _B{prime}_ values should be scaled by +latexmath:[256\over 255], restoring the ability to represent pure white. diff --git a/references.txt b/chapters/references.adoc similarity index 97% rename from references.txt rename to chapters/references.adoc index 6d758ad..2b9acc0 100644 --- a/references.txt +++ b/chapters/references.adoc @@ -1,9 +1,9 @@ -// Copyright (c) 2019 The Khronos Group Inc. -// Copyright notice at https://www.khronos.org/registry/speccopyright.html +// Copyright 2019-2026 The Khronos Group Inc. +// SPDX-License-Identifier: CC-BY-4.0 -== External references == +== External references -*[[IEEE 754]]IEEE754-2008 - IEEE standard for floating-point arithmetic* +*[[IEEE-754]]IEEE754-2008 - IEEE standard for floating-point arithmetic* IEEE Std 754-2008 http://dx.doi.org/10.1109/IEEESTD.2008.4610935, @@ -120,7 +120,7 @@ link:https://webstore.iec.ch/preview/info_iec61966-2-2%7Bed1.0%7Den.pdf[https:// A working draft is freely available at link:https://web.archive.org/web/20110725185444/http://www.colour.org/tc8-05/Docs/colorspace/61966-2-2NPa.pdf[https://web.archive.org/web/20110725185444/http://www.colour.org/tc8-05/Docs/colorspace/61966-2-2NPa.pdf]. -link:http://www.color.org/sycc.pdf[http://www.color.org/sycc.pdf] - sYCC (the latexmath:[$Y'C_BC_R$] variant of sRGB) +link:http://www.color.org/sycc.pdf[http://www.color.org/sycc.pdf] - sYCC (the latexmath:[Y'C_BC_R] variant of sRGB) link:https://webstore.iec.ch/corrigenda/iec61966-2-2-cor1%7Bed1.0%7Den.pdf[https://webstore.iec.ch/corrigenda/iec61966-2-2-cor1%7Bed1.0%7Den.pdf] - Annex B: Non-linear encoding for scRGB : scRGB-nl and its YCC Transformation: scYCC-nl + diff --git a/rgtc.txt b/chapters/rgtc.adoc similarity index 74% rename from rgtc.txt rename to chapters/rgtc.adoc index d208bb7..b7df232 100644 --- a/rgtc.txt +++ b/chapters/rgtc.adoc @@ -1,9 +1,10 @@ -// Copyright (C) 2008-2019 The Khronos Group Inc. All Rights Reserved. -// Copyright notice at https://www.khronos.org/registry/speccopyright.html +// Copyright 2008-2026 The Khronos Group Inc. +// SPDX-License-Identifier: CC-BY-4.0 + [[RGTC]] == RGTC Compressed Texture Image Formats -_This description is derived from the ``RGTC Compressed Texture Image Formats'' +_This description is derived from the "`RGTC Compressed Texture Image Formats`" section of the OpenGL 4.4 specification._ Compressed texture images stored using the RGTC compressed image encodings @@ -19,36 +20,36 @@ size of _blocksize_ (8 or 16 bytes) is decoded, the corresponding image size (in bytes) is: [latexmath] -++++++++++++++++++++++ +++++ \begin{align*} \left\lceil { w \over 4 } \right\rceil \times \left\lceil { h \over 4 } \right\rceil \times \mathit{blocksize} \end{align*} -++++++++++++++++++++++ +++++ When decoding an RGTC image, the block containing the texel at offset -latexmath:[$(x,y)$] begins at an offset (in bytes) relative to the base of the image of: +latexmath:[(x,y)] begins at an offset (in bytes) relative to the base of the image of: [latexmath] -++++++++++++++++++++++ +++++ \begin{align*} \mathit{blocksize} \times \left( { \left\lceil { w \over 4 } \right\rceil \times \left\lfloor { y \over 4 } \right\rfloor + \left\lfloor { x \over 4 } \right\rfloor } \right) \end{align*} -++++++++++++++++++++++ +++++ The data corresponding to a specific texel (_x_, _y_) are extracted from a 4{times}4 texel block using a relative (_x_, _y_) value of [latexmath] -++++++++++++++++++++++ +++++ \begin{align*} (x \bmod 4,y \bmod 4) \end{align*} -++++++++++++++++++++++ +++++ There are four distinct RGTC image formats described in the following sections. @@ -64,16 +65,16 @@ Each red image data block is encoded as a sequence of 8 bytes, called (in order of increasing address): [latexmath] -++++++ +++++ \begin{align*} \mathit{red}_0, \mathit{red}_1, \mathit{bits}_0, \mathit{bits}_1, \mathit{bits}_2, \mathit{bits}_3, \mathit{bits}_4, \mathit{bits}_5 \end{align*} -++++++ +++++ The 6 _bits_~{0..5}~ bytes of the block are decoded into a 48-bit bit vector: [latexmath] -++++++++++++++++++++++ +++++ \begin{align*} \mathit{bits} & = \mathit{bits}_0 + @@ -87,23 +88,23 @@ The 6 _bits_~{0..5}~ bytes of the block are decoded into a 48-bit bit vector: \right) } \right) \end{align*} -++++++++++++++++++++++ +++++ _red_~0~ and _red_~1~ are 8-bit unsigned integers that are unpacked to red -values _RED_~0~ and _RED_~1~ by multiplying by latexmath:[$1\over 255$]. +values _RED_~0~ and _RED_~1~ by multiplying by latexmath:[1\over 255]. _bits_ is a 48-bit unsigned integer, from which a three-bit control code is extracted for a texel at location (_x_, _y_) in the block using: [latexmath] -++++++++++++++++++++++ +++++ \begin{align*} \mathit{code}(x,y) & = \mathit{bits} \left[ 3 \times (4 \times y + x) + 2 \dots 3 \times (4 \times y + x) + 0 \right] \end{align*} -++++++++++++++++++++++ +++++ where _bits_[47] is the most-significant and _bits_[0] is the least-significant bit. @@ -113,30 +114,30 @@ the block is given by <>. [[BC4blocks]] .Block decoding for BC4 [options="header",width="43%",cols="1,2"] -|========== +|==== ^| _R_ value ^| Condition ^| _RED_~0~ ^.^| _red_~0~ > _red_~1~, _code_(_x_, _y_) = 0 ^| _RED_~1~ ^.^| _red_~0~ > _red_~1~, _code_(_x_, _y_) = 1 -^| latexmath:[${ 6 \times \mathit{RED}_0 + \mathit{RED}_1 } \over 7$] ^.^| _red_~0~ > _red_~1~, _code_(_x_, _y_) = 2 -^| latexmath:[${ 5 \times \mathit{RED}_0 + 2 \times \mathit{RED}_1 } \over 7$] ^.^| _red_~0~ > _red_~1~, _code_(_x_, _y_) = 3 -^| latexmath:[${ 4 \times \mathit{RED}_0 + 3 \times \mathit{RED}_1 } \over 7$] ^.^| _red_~0~ > _red_~1~, _code_(_x_, _y_) = 4 -^| latexmath:[${ 3 \times \mathit{RED}_0 + 4 \times \mathit{RED}_1 } \over 7$] ^.^| _red_~0~ > _red_~1~, _code_(_x_, _y_) = 5 -^| latexmath:[${ 2 \times \mathit{RED}_0 + 5 \times \mathit{RED}_1 } \over 7$] ^.^| _red_~0~ > _red_~1~, _code_(_x_, _y_) = 6 -^| latexmath:[${ \mathit{RED}_0 + 6 \times \mathit{RED}_1 } \over 7$] ^.^| _red_~0~ > _red_~1~, _code_(_x_, _y_) = 7 +^| latexmath:[{ 6 \times \mathit{RED}_0 + \mathit{RED}_1 } \over 7] ^.^| _red_~0~ > _red_~1~, _code_(_x_, _y_) = 2 +^| latexmath:[{ 5 \times \mathit{RED}_0 + 2 \times \mathit{RED}_1 } \over 7] ^.^| _red_~0~ > _red_~1~, _code_(_x_, _y_) = 3 +^| latexmath:[{ 4 \times \mathit{RED}_0 + 3 \times \mathit{RED}_1 } \over 7] ^.^| _red_~0~ > _red_~1~, _code_(_x_, _y_) = 4 +^| latexmath:[{ 3 \times \mathit{RED}_0 + 4 \times \mathit{RED}_1 } \over 7] ^.^| _red_~0~ > _red_~1~, _code_(_x_, _y_) = 5 +^| latexmath:[{ 2 \times \mathit{RED}_0 + 5 \times \mathit{RED}_1 } \over 7] ^.^| _red_~0~ > _red_~1~, _code_(_x_, _y_) = 6 +^| latexmath:[{ \mathit{RED}_0 + 6 \times \mathit{RED}_1 } \over 7] ^.^| _red_~0~ > _red_~1~, _code_(_x_, _y_) = 7 ^| _RED_~0~ ^.^| _red_~0~ {leq} _red_~1~, _code_(_x_, _y_) = 0 ^| _RED_~1~ ^.^| _red_~0~ {leq} _red_~1~, _code_(_x_, _y_) = 1 -^| latexmath:[${ 4 \times \mathit{RED}_0 + \mathit{RED}_1 } \over 5$] ^.^| _red_~0~ {leq} _red_~1~, _code_(_x_, _y_) = 2 -^| latexmath:[${ 3 \times \mathit{RED}_0 + 2 \times \mathit{RED}_1 } \over 5$] ^.^| _red_~0~ {leq} _red_~1~, _code_(_x_, _y_) = 3 -^| latexmath:[${ 2 \times \mathit{RED}_0 + 3 \times \mathit{RED}_1 } \over 5$] ^.^| _red_~0~ {leq} _red_~1~, _code_(_x_, _y_) = 4 -^| latexmath:[${ \mathit{RED}_0 + 4 \times \mathit{RED}_1 } \over 5$] ^.^| _red_~0~ {leq} _red_~1~, _code_(_x_, _y_) = 5 +^| latexmath:[{ 4 \times \mathit{RED}_0 + \mathit{RED}_1 } \over 5] ^.^| _red_~0~ {leq} _red_~1~, _code_(_x_, _y_) = 2 +^| latexmath:[{ 3 \times \mathit{RED}_0 + 2 \times \mathit{RED}_1 } \over 5] ^.^| _red_~0~ {leq} _red_~1~, _code_(_x_, _y_) = 3 +^| latexmath:[{ 2 \times \mathit{RED}_0 + 3 \times \mathit{RED}_1 } \over 5] ^.^| _red_~0~ {leq} _red_~1~, _code_(_x_, _y_) = 4 +^| latexmath:[{ \mathit{RED}_0 + 4 \times \mathit{RED}_1 } \over 5] ^.^| _red_~0~ {leq} _red_~1~, _code_(_x_, _y_) = 5 ^| _RED~min~_ ^.^| _red_~0~ {leq} _red_~1~, _code_(_x_, _y_) = 6 ^| _RED~max~_ ^.^| _red_~0~ {leq} _red_~1~, _code_(_x_, _y_) = 7 -|========== +|==== _RED_~min~ and _RED_~max~ are 0.0 and 1.0 respectively. Since the decoded texel has a red format, the resulting _RGBA_ value for the -texel is (_R_, 0, 0, 1). +texel is (_R_,{nbsp}0,{nbsp}0,{nbsp}1). === BC4 signed @@ -146,7 +147,7 @@ BC4 unsigned except _red_~0~, _red_~1~, _RED_~0~, _RED_~1~, _RED_~min~, and _RED_~max~ are signed values defined as follows: [latexmath] -++++++ +++++ \begin{align*} \mathit{RED}_0 & = \begin{cases} {\mathit{red}_0 \over 127.0}, & \mathit{red}_0 > -128 \\ @@ -159,7 +160,7 @@ _RED_~min~, and _RED_~max~ are signed values defined as follows: \mathit{RED}_{\mathit{min}} & = -1.0 \\ \mathit{RED}_{\mathit{max}} & = 1.0 \end{align*} -+++++++++++ +++++ _red_~0~ and _red_~1~ are 8-bit signed (two's complement) integers. @@ -186,7 +187,7 @@ BC4 unsigned above except the decoded value _R_ for this second block is considered the resulting green value _G_. Since the decoded texel has a red-green format, the resulting _RGBA_ -value for the texel is (_R_,_ G_, 0, 1). +value for the texel is (_R_,_{nbsp}G_,{nbsp}0,{nbsp}1). === BC5 signed @@ -200,4 +201,4 @@ BC4 signed above except the decoded value _R_ for this second block is considered the resulting green value _G_. Since this image has a red-green format, the resulting _RGBA_ value is -(_R_,_ G_, 0, 1). +(_R_,_{nbsp}G_,{nbsp}0,{nbsp}1). diff --git a/s3tc.txt b/chapters/s3tc.adoc similarity index 77% rename from s3tc.txt rename to chapters/s3tc.adoc index b06acfb..73d4388 100644 --- a/s3tc.txt +++ b/chapters/s3tc.adoc @@ -1,5 +1,6 @@ -// Copyright (C) 2008-2019 The Khronos Group Inc. All Rights Reserved. -// Copyright notice at https://www.khronos.org/registry/speccopyright.html +// Copyright 2008-2026 The Khronos Group Inc. +// SPDX-License-Identifier: CC-BY-4.0 + [[S3TC]] == S3TC Compressed Texture Image Formats @@ -23,37 +24,37 @@ _blocksize_ (8 or 16 bytes) is decoded, the corresponding image size (in bytes) is: [latexmath] -++++++++++++++++ +++++ \begin{align*} \left\lceil { w \over 4 } \right\rceil \times \left\lceil { h \over 4 } \right\rceil \times blocksize \end{align*} -++++++++++++++++ +++++ When decoding an S3TC image, the block containing the texel at offset (_x_, _y_) begins at an offset (in bytes) relative to the base of the image of: [latexmath] -++++++++++++++ +++++ \begin{align*} blocksize \times \left( { \left\lceil { w \over 4 } \right\rceil \times \left\lfloor { y \over 4 } \right\rfloor + \left\lfloor { x \over 4 } \right\rfloor } \right) \end{align*} -++++++++++++++ +++++ The data corresponding to a specific texel (_x_, _y_) are extracted from a 4{times}4 texel block using a relative (_x_, _y_) value of [latexmath] -++++++++++++++ +++++ \begin{align*} (x \bmod 4,y \bmod 4) \end{align*} -++++++++++++++ +++++ There are four distinct S3TC image formats: @@ -67,22 +68,22 @@ Each _RGB_ image data block is encoded as a sequence of 8 bytes, called (in order of increasing address): [latexmath] -++++++ +++++ \begin{align*} c0_{\mathit{lo}}, c0_{\mathit{hi}}, c1_{\mathit{lo}}, c1_{\mathit{hi}}, \mathit{bits}_0, \mathit{bits}_1, \mathit{bits}_2, \mathit{bits}_3 \end{align*} -++++++ +++++ The 8 bytes of the block are decoded into three quantities: [latexmath] -++++++ +++++ \begin{align*} \mathit{color}_0 & = c0_{\mathit{lo}} + c0_{\mathit{hi}} \times 256 \\ \mathit{color}_1 & = c1_{\mathit{lo}} + c1_{\mathit{hi}} \times 256 \\ \mathit{bits} & = \mathit{bits}_0 + 256 \times (\mathit{bits}_1 + 256 \times (\mathit{bits}_2 + 256 \times \mathit{bits}_3)) \end{align*} -++++++ +++++ _color_~0~ and _color_~1~ are 16-bit unsigned integers that are unpacked to _RGB_ colors _RGB_~0~ and _RGB_~1~ as though they were 16-bit @@ -90,23 +91,23 @@ unsigned packed pixels with the _R_ channel in the high 5 bits, _G_ in the next 6 bits and _B_ in the low 5 bits: [latexmath] -++++++ +++++ \begin{align*} \mathit{R}_n & = {{\mathit{color}_n^{15..11}}\over 31} \\ \mathit{G}_n & = {{\mathit{color}_n^{10..5}}\over 63} \\ \mathit{B}_n & = {{\mathit{color}_n^{4..0}}\over 31} \end{align*} -++++++ +++++ _bits_ is a 32-bit unsigned integer, from which a two-bit control code is extracted for a texel at location (_x_, _y_) in the block using: [latexmath] -++++++ +++++ \begin{align*} \mathit{code}(x,y) & = \mathit{bits}[2\times (4\times y+x)+1\ \dots\ 2\times(4\times y+x)+0] \end{align*} -++++++ +++++ where _bits_[31] is the most significant and _bits_[0] is the least significant bit. @@ -117,17 +118,17 @@ in <>. [[BC1blocks]] .Block decoding for BC1 [options="header",cols="1,2",width="60%"] -|========== +|==== ^| Texel value ^| Condition ^.^| _RGB_~0~ ^.^| _color_~0~ > _color_~1~ and _code_(_x_, _y_) = 0 ^.^| _RGB_~1~ ^.^| _color_~0~ > _color_~1~ and _code_(_x_, _y_) = 1 -^| latexmath:[$(2\times \mathit{RGB}_0 + \mathit{RGB}_1)\over 3$] ^.^| _color_~0~ > _color_~1~ and _code_(_x_, _y_) = 2 -^| latexmath:[$(\mathit{RGB}_0 + 2\times RGB_1)\over 3$] ^.^| _color_~0~ > _color_~1~ and _code_(_x_, _y_) = 3 +^| latexmath:[(2\times \mathit{RGB}_0 + \mathit{RGB}_1)\over 3] ^.^| _color_~0~ > _color_~1~ and _code_(_x_, _y_) = 2 +^| latexmath:[(\mathit{RGB}_0 + 2\times RGB_1)\over 3] ^.^| _color_~0~ > _color_~1~ and _code_(_x_, _y_) = 3 ^.^| _RGB_~0~ ^.^| _color_~0~ {leq} _color_~1~ and _code_(_x_, _y_) = 0 ^.^| _RGB_~1~ ^.^| _color_~0~ {leq} _color_~1~ and _code_(_x_, _y_) = 1 -^| latexmath:[$(\mathit{RGB}_0+\mathit{RGB}_1)\over 2$] ^.^| _color_~0~ {leq} _color_~1~ and _code_(_x_, _y_) = 2 +^| latexmath:[(\mathit{RGB}_0+\mathit{RGB}_1)\over 2] ^.^| _color_~0~ {leq} _color_~1~ and _code_(_x_, _y_) = 2 ^.^| BLACK ^.^| _color_~0~ {leq} _color_~1~ and _code_(_x_, _y_) = 3 -|========== +|==== Arithmetic operations are done per component, and BLACK refers to an _RGB_ color where red, green, and blue are all zero. @@ -149,11 +150,11 @@ given by <>. [[BC1alpha]] .BC1 with alpha [options="header",cols="1,2",width="60%"] -|========== +|==== ^| Alpha value ^| Condition ^| 0.0 ^| _color_~0~ {leq} _color_~1~ and _code_(_x_, _y_) = 3 ^| 1.0 ^| otherwise -|========== +|==== // This is a discussion of the behavior of the encoder, not of the // format itself. @@ -176,30 +177,30 @@ of 0 should be encoded as zero (black). [NOTE] ==== <> shows an example BC1 texel block: -_color_~0~, encoded as latexmath:[$\left({{29}\over{31}}, {{60}\over{63}}, {{1}\over{31}}\right)$], -and _color_~1~, encoded as latexmath:[$\left({{20}\over{31}}, {{2}\over{63}}, {{30}\over{31}}\right)$], +_color_~0~, encoded as latexmath:[\left({{29}\over{31}}, {{60}\over{63}}, {{1}\over{31}}\right)], +and _color_~1~, encoded as latexmath:[\left({{20}\over{31}}, {{2}\over{63}}, {{30}\over{31}}\right)], are shown as circles. The interpolated values are shown as small diamonds. Since 29 > 20, there are two interpolated values, accessed when _code_(_x_, _y_) = 2 and _code_(_x_, _y_) = 3. [[Figure-bc1]] .BC1 two interpolated colors -image::images/bc1.{svgpdf}[width="{svgpdf@pdf:190.5pt:382.5}",align="center"] +image::{images}/bc1.svg[width="{svgpdf@pdf:190.5pt:382.5}",align="center"] <> shows the example BC1 texel block with the colors swapped: -_color_~0~, encoded as latexmath:[$\left({{20}\over{31}}, {{2}\over{63}}, {{30}\over{31}}\right)$], -and _color_~1~, encoded as latexmath:[$\left({{29}\over{31}}, {{60}\over{63}}, {{1}\over{31}}\right)$], +_color_~0~, encoded as latexmath:[\left({{20}\over{31}}, {{2}\over{63}}, {{30}\over{31}}\right)], +and _color_~1~, encoded as latexmath:[\left({{29}\over{31}}, {{60}\over{63}}, {{1}\over{31}}\right)], are shown as circles. The interpolated value is shown as a small diamonds. Since 20 {leq} 29, there is one interpolated value for _code_(_x_, _y_) = 2, and _code_(_x_, _y_) = 3 represents -(_R_,_ G_,_ B_) = (0, 0, 0). +(_R_,_{nbsp}G_,_{nbsp}B_) = (0,{nbsp}0,{nbsp}0). [[Figure-bc1a]] .BC1 one interpolated color {plus} black -image::images/bc1a.{svgpdf}[width="{svgpdf@pdf:190.5pt:382.5}",align="center"] +image::{images}/bc1a.svg[width="{svgpdf@pdf:190.5pt:382.5}",align="center"] If the format is BC1 with alpha, _code_(_x_, _y_) = 3 is transparent -(alpha = 0). +(alpha{nbsp}={nbsp}0). If the format is BC1 with no alpha, _code_(_x_, _y_) = 3 represents opaque black. @@ -223,37 +224,37 @@ Each alpha image data block is encoded as a sequence of 8 bytes, called (in order of increasing address): [latexmath] -++++++ +++++ \begin{align*} a_0, a_1, a_2, a_3, a_4, a_5, a_6, a_7 \end{align*} -++++++ +++++ The 8 bytes of the block are decoded into one 64-bit integer: [latexmath] -++++++ +++++ \begin{align*} \mathit{alpha} & = a_0 + 256 \times (a_1 + 256 \times (a_2 + 256 \times (a_3 + 256 \times (a_4 + 256 \times (a_5 + 256 \times (a_6 + 256 \times a_7)))))) \end{align*} -++++++ +++++ _alpha_ is a 64-bit unsigned integer, from which a four-bit alpha value is extracted for a texel at location (_x_, _y_) in the block using: [latexmath] -++++++ +++++ \begin{align*} \mathit{alpha}(x,y) & = \mathit{bits}[4\times(4\times y+x)+3 \dots 4\times(4\times y+x)+0] \end{align*} -++++++ +++++ where _bits_[63] is the most significant and _bits_[0] is the least significant bit. The alpha component for a texel at location (_x_, _y_) in the block is -given by latexmath:[$\mathit{alpha}(x,y)\over 15$]. +given by latexmath:[\mathit{alpha}(x,y)\over 15]. [[s3tc_bc3]] === BC3 @@ -271,34 +272,34 @@ Each alpha image data block is encoded as a sequence of 8 bytes, called (in order of increasing address): [latexmath] -++++++ +++++ \begin{align*} \mathit{alpha}_0, \mathit{alpha}_1, \mathit{bits}_0, \mathit{bits}_1, \mathit{bits}_2, \mathit{bits}_3, \mathit{bits}_4, \mathit{bits}_5 \end{align*} -++++++ +++++ The _alpha_~0~ and _alpha_~1~ are 8-bit unsigned bytes converted to alpha -components by multiplying by latexmath:[$1\over 255$]. +components by multiplying by latexmath:[1\over 255]. The 6 _bits_ bytes of the block are decoded into one 48-bit integer: [latexmath] -++++++ +++++ \begin{align*} \mathit{bits} & = \mathit{bits}_0 + 256 \times (\mathit{bits}_1 + 256 \times (\mathit{bits}_2 + 256 \times (\mathit{bits}_3 + 256 \times (\mathit{bits}_4 + 256 \times \mathit{bits}_5)))) \end{align*} -++++++ +++++ _bits_ is a 48-bit unsigned integer, from which a three-bit control code is extracted for a texel at location (_x_, _y_) in the block using: [latexmath] -++++++ +++++ \begin{align*} \mathit{code}(x,y) & = \mathit{bits}[3\times(4\times y+x)+2 \dots 3\times(4\times y+x)+0] \end{align*} -++++++ +++++ where _bits_[47] is the most-significant and _bits_[0] is the least-significant bit. @@ -310,20 +311,20 @@ given by <>. [[BC3alpha]] .Alpha encoding for BC3 blocks [options="header",cols="2,3",width="70%"] -|================= +|==== ^| Alpha value ^| Condition ^.^| _alpha_~0~ ^.^| _code_(_x_, _y_) = 0 ^.^| _alpha_~1~ ^.^| _code_(_x_, _y_) = 1 -^| latexmath:[$(6\times\mathit{alpha}_0 + 1\times\mathit{alpha}_1)\over 7$] ^.^| _alpha_~0~ > _alpha_~1~ and _code_(_x_, _y_) = 2 -^| latexmath:[$(5\times\mathit{alpha}_0 + 2\times\mathit{alpha}_1)\over 7$] ^.^| _alpha_~0~ > _alpha_~1~ and _code_(_x_, _y_) = 3 -^| latexmath:[$(4\times\mathit{alpha}_0 + 3\times\mathit{alpha}_1)\over 7$] ^.^| _alpha_~0~ > _alpha_~1~ and _code_(_x_, _y_) = 4 -^| latexmath:[$(3\times\mathit{alpha}_0 + 4\times\mathit{alpha}_1)\over 7$] ^.^| _alpha_~0~ > _alpha_~1~ and _code_(_x_, _y_) = 5 -^| latexmath:[$(2\times\mathit{alpha}_0 + 5\times\mathit{alpha}_1)\over 7$] ^.^| _alpha_~0~ > _alpha_~1~ and _code_(_x_, _y_) = 6 -^| latexmath:[$(1\times\mathit{alpha}_0 + 6\times\mathit{alpha}_1)\over 7$] ^.^| _alpha_~0~ > _alpha_~1~ and _code_(_x_, _y_) = 7 -^| latexmath:[$(4\times\mathit{alpha}_0 + 1\times\mathit{alpha}_1)\over 5$] ^.^| _alpha_~0~ {leq} _alpha_~1~ and _code_(_x_, _y_) = 2 -^| latexmath:[$(3\times\mathit{alpha}_0 + 2\times\mathit{alpha}_1)\over 5$] ^.^| _alpha_~0~ {leq} _alpha_~1~ and _code_(_x_, _y_) = 3 -^| latexmath:[$(2\times\mathit{alpha}_0 + 3\times\mathit{alpha}_1)\over 5$] ^.^| _alpha_~0~ {leq} _alpha_~1~ and _code_(_x_, _y_) = 4 -^| latexmath:[$(1\times\mathit{alpha}_0 + 4\times\mathit{alpha}_1)\over 5$] ^.^| _alpha_~0~ {leq} _alpha_~1~ and _code_(_x_, _y_) = 5 +^| latexmath:[(6\times\mathit{alpha}_0 + 1\times\mathit{alpha}_1)\over 7] ^.^| _alpha_~0~ > _alpha_~1~ and _code_(_x_, _y_) = 2 +^| latexmath:[(5\times\mathit{alpha}_0 + 2\times\mathit{alpha}_1)\over 7] ^.^| _alpha_~0~ > _alpha_~1~ and _code_(_x_, _y_) = 3 +^| latexmath:[(4\times\mathit{alpha}_0 + 3\times\mathit{alpha}_1)\over 7] ^.^| _alpha_~0~ > _alpha_~1~ and _code_(_x_, _y_) = 4 +^| latexmath:[(3\times\mathit{alpha}_0 + 4\times\mathit{alpha}_1)\over 7] ^.^| _alpha_~0~ > _alpha_~1~ and _code_(_x_, _y_) = 5 +^| latexmath:[(2\times\mathit{alpha}_0 + 5\times\mathit{alpha}_1)\over 7] ^.^| _alpha_~0~ > _alpha_~1~ and _code_(_x_, _y_) = 6 +^| latexmath:[(1\times\mathit{alpha}_0 + 6\times\mathit{alpha}_1)\over 7] ^.^| _alpha_~0~ > _alpha_~1~ and _code_(_x_, _y_) = 7 +^| latexmath:[(4\times\mathit{alpha}_0 + 1\times\mathit{alpha}_1)\over 5] ^.^| _alpha_~0~ {leq} _alpha_~1~ and _code_(_x_, _y_) = 2 +^| latexmath:[(3\times\mathit{alpha}_0 + 2\times\mathit{alpha}_1)\over 5] ^.^| _alpha_~0~ {leq} _alpha_~1~ and _code_(_x_, _y_) = 3 +^| latexmath:[(2\times\mathit{alpha}_0 + 3\times\mathit{alpha}_1)\over 5] ^.^| _alpha_~0~ {leq} _alpha_~1~ and _code_(_x_, _y_) = 4 +^| latexmath:[(1\times\mathit{alpha}_0 + 4\times\mathit{alpha}_1)\over 5] ^.^| _alpha_~0~ {leq} _alpha_~1~ and _code_(_x_, _y_) = 5 ^.^| 0.0 ^.^| _alpha_~0~ {leq} _alpha_~1~ and _code_(_x_, _y_) = 6 ^.^| 1.0 ^.^| _alpha_~0~ {leq} _alpha_~1~ and _code_(_x_, _y_) = 7 -|================= +|==== diff --git a/transferfunctions.txt b/chapters/transferfunctions.adoc similarity index 70% rename from transferfunctions.txt rename to chapters/transferfunctions.adoc index 47a81e5..94a1506 100644 --- a/transferfunctions.txt +++ b/chapters/transferfunctions.adoc @@ -1,5 +1,5 @@ -// Copyright (c) 2017-2019 The Khronos Group Inc. -// Copyright notice at https://www.khronos.org/registry/speccopyright.html +// Copyright 2017-2026 The Khronos Group Inc. +// SPDX-License-Identifier: CC-BY-4.0 [[TRANSFER_CONVERSION]] == Transfer functions @@ -25,11 +25,11 @@ represent darker intensities than their fraction of the representation of white would suggest. .Conversion curves between linear light and encoded values (sRGB example) -image::images/tf_curves.{svgpdf}[width="{svgpdf@pdf:350pt:576}",align="center"] +image::{images}/tf_curves.svg[width="{svgpdf@pdf:350pt:576}",align="center"] The behavior has historically been approximated by a power function -with an exponent conventionally called latexmath:[$\gamma$]: + -{_R_,_G_,_B_}~non-linear~ = {_R_,_G_,_B_}~linear~^latexmath:[$\gamma$]^. +with an exponent conventionally called latexmath:[\gamma]: + +{_R_,_G_,_B_}~non-linear~ = {_R_,_G_,_B_}~linear~^latexmath:[\gamma]^. Hence this conversion is colloquially known as _gamma correction_. NOTE: Many practical transfer functions incorporate a small linear @@ -63,7 +63,7 @@ approximating the behavior of a CRT with uncorrected signals. The background represents 50% gray. .Averaging checker values with different transfer functions -image::images/tf_sampling.{svgpdf}[width="{svgpdf@pdf:210pt:576}",align="center"] +image::{images}/tf_sampling.svg[width="{svgpdf@pdf:210pt:576}",align="center"] * *In row 1* black (0.0) and white (1.0) texels are averaged to calculate a 0.5 value in the frame buffer. @@ -71,7 +71,7 @@ image::images/tf_sampling.{svgpdf}[width="{svgpdf@pdf:210pt:576}",align="center" than the average value of the black and white texels, so the gray box appears darker than the average intensity of the checker pattern. * *In row 2* the 0.5 average of the frame buffer is corrected using the - sRGB (electro-optical) EOTF^ -1^ to ∼0.74. + sRGB (electro-optical) EOTF^{nbsp}-1^ to {sim}0.74. The gray box accordingly appears a good match for the average intensity of the black and white squares on most media. * *In row 3* the checker pattern instead represents values of 25% and @@ -80,11 +80,11 @@ image::images/tf_sampling.{svgpdf}[width="{svgpdf@pdf:210pt:576}",align="center" rows). These checker values have been converted to their non-linear representations, as might be the case for a texture in this format: - the darker squares are represented by ∼0.54, and - the lighter squares are represented by ∼0.88. + the darker squares are represented by {sim}0.54, and + the lighter squares are represented by {sim}0.88. Averaging these two values to get a value of 0.71 results in the right-most square: this appears slightly too dark compared with the - correct representation of mid-gray (∼0.74) because, + correct representation of mid-gray ({sim}0.74) because, due to the non-linear encoding, the calculated value should not lie exactly half way between the two end points. Since the end points of the interpolation are less distant than the @@ -95,7 +95,7 @@ image::images/tf_sampling.{svgpdf}[width="{svgpdf@pdf:210pt:576}",align="center" but the resulting output represents linear light, which is therefore interpreted as too dark by the non-linear display. * *In row 5* the results of row 4 have been converted back to the - non-linear representation using the EOTF^ -1^. + non-linear representation using the EOTF^{nbsp}-1^. The checker colors are restored to their correct values, and the interpolated value is now the correct average intensity of the two colors. @@ -104,18 +104,18 @@ Incorrectly-applied transfer functions can also introduce color shifts, as demonstrated by the saturation change in the following examples: ._R_, _G_, _B_ channels and combined color gradient with linear light intensity in each channel -image::images/tf_colorshift_intensitylinearvalues.png[width="{svgpdf@pdf:150pt:256}",align="center"] +image::{images}/tf_colorshift_intensitylinearvalues.png[width="{svgpdf@pdf:150pt:256}",align="center"] -._R′_, _G′_, _B′_ channels and combined color gradient with non-linear sRGB encoding in each channel -image::images/tf_colorshift_srgblinearvalues.png[width="{svgpdf@pdf:150pt:256}",align="center"] +._R{prime}_, _G{prime}_, _B{prime}_ channels and combined color gradient with non-linear sRGB encoding in each channel +image::{images}/tf_colorshift_srgblinearvalues.png[width="{svgpdf@pdf:150pt:256}",align="center"] <<< A standard for image representation typically defines one or both of two types of transfer functions: .Opto-electronics and electro-optical transfer functions -image::images/tf_scene_store_display.{svgpdf}[width="{svgpdf@pdf:450pt:800}",align="center"] +image::{images}/tf_scene_store_display.svg[width="{svgpdf@pdf:450pt:800}",align="center"] * An opto-electronic transfer function (OETF) defines the conversion between a normalized linear light intensity as recorded in the scene, @@ -132,13 +132,13 @@ image::images/tf_scene_store_display.{svgpdf}[width="{svgpdf@pdf:450pt:800}",ali accordingly. The inverse of the OETF (the conversion from the non-linear electronic representation to linear scene light) is written - OETF^ -1^(_n_). + OETF^{nbsp}-1^(_n_). * An electro-optical transfer function (EOTF) converts between a non-linear electronic representation and a linear light normalized intensity as produced by the output display. The inverse of the EOTF (the conversion from linear display light to the non-linear electronic representation) is written - EOTF^ -1^(_n_). + EOTF^{nbsp}-1^(_n_). Typical CRT technology has implicitly applied a non-linear EOTF which coincidentally offered an approximately perceptually linear gradient when supplied with a linear voltage; other display @@ -183,7 +183,7 @@ Adaptation to the surround means that the top left and lower right images look similar. .Simultaneous contrast -image::images/tf_surround_luminance.{svgpdf}[width="{svgpdf@pdf:450pt:800}",align="center"] +image::{images}/tf_surround_luminance.svg[width="{svgpdf@pdf:450pt:800}",align="center"] In the context of a non-linear OOTF, an application should be aware of whether operations on the image are intended to reflect the representation of colors in @@ -209,14 +209,14 @@ The effect of a non-linear OOTF is usually secondary to the benefits of using non-linear encoding to reduce quantization. By convention, non-linearly-encoded values are distinguished from -linearly-encoded values by the addition of a prime (′) +linearly-encoded values by the addition of a prime ({prime}) symbol. For example, (_R_,_G_,_B_) may represent a linear set of -red, green and blue components; (_R_′,_G_′,_B_′) +red, green and blue components; (_R_{prime},_G_{prime},_B_{prime}) would represent the non-linear encoding of each value. Typically the non-linear encoding is applied to additive primary colors; derived color differences may or may not retain the prime symbol. -Charles Poynton provides a further discussion on ``Gamma'' in +Charles Poynton provides a further discussion on "`Gamma`" in link:http://www.poynton.com/PDFs/TIDV/Gamma.pdf[ http://www.poynton.com/PDFs/TIDV/Gamma.pdf]. @@ -224,7 +224,7 @@ http://www.poynton.com/PDFs/TIDV/Gamma.pdf]. [[TRANSFER_ITU]] === ITU transfer functions -NOTE: ``ITU'' is used in this context as a shorthand for the +NOTE: "`ITU`" is used in this context as a shorthand for the OETF shared by the current <>, <> and <> family of standard dynamic range digital television production standards. @@ -242,10 +242,10 @@ specifications (for standard definition television, HDTV and UHDTV respectively), and <>, which defines NTSC broadcasts, define an opto-electrical transfer function. The (OETF) conversion from linear (_R_,_G_,_B_) encoding -to non-linear (_R′_,_G′_,_B′_) encoding is: +to non-linear (_R{prime}_,_G{prime}_,_B{prime}_) encoding is: [latexmath] -++++++ +++++ \begin{align*} \textit{R}' &= \begin{cases} \textit{R} \times 4.500, & \textit{R} < \beta \\ @@ -260,19 +260,19 @@ to non-linear (_R′_,_G′_,_B′_) encoding is: \alpha \times \textit{B}^{0.45} - (\alpha - 1), & \textit{B} \geq \beta \end{cases} \end{align*} -++++++ +++++ -Where _α_ = 1.0993 and _β_ = 0.0181 +Where _{alpha}_ = 1.0993 and _{beta}_ = 0.0181 for 12-bit encoding in the BT.2020 specification, and -latexmath:[$\alpha = 1.099$] and latexmath:[$\beta = 0.018$] otherwise. +latexmath:[\alpha = 1.099] and latexmath:[\beta = 0.018] otherwise. [[TRANSFER_ITU_INVOETF]] -==== ITU OETF^ -1^ +==== ITU OETF^{nbsp}-1^ -From this the inverse (OETF^ -1^) transformation can be deduced: +From this the inverse (OETF^{nbsp}-1^) transformation can be deduced: [latexmath] -++++++ +++++ \begin{align*} \textit{R} &= \begin{cases} {{\textit{R}'}\over{4.500}}, & \textit{R}' < \delta \\ @@ -287,19 +287,19 @@ B &= \begin{cases} {\left({\textit{B}' + (\alpha - 1)}\over{\alpha}\right)}^{1\over{0.45}}, & \textit{B}' \geq \delta \end{cases} \end{align*} -++++++ +++++ -_δ_ can be deduced from _α_ {times} _β_^0.45^ -- (_α_ - 1) ≈ 0.0812. Note that this is subtly different from -4.5 {times} _β_ due to rounding. See the following section +_{delta}_ can be deduced from _{alpha}_ {times} _{beta}_^0.45^ +- (_{alpha}_ - 1) {approx} 0.0812. Note that this is subtly different from +4.5 {times} _{beta}_ due to rounding. See the following section for the derivation of these values. <>, which defines the behavior of NTSC -televisions, defines the EOTF of the ``reference reproducer'' as the -OETF^ -1^ function above, with _δ_ explicitly +televisions, defines the EOTF of the "`reference reproducer`" as the +OETF^{nbsp}-1^ function above, with _{delta}_ explicitly written as 0.0812. -Therefore the SMPTE 170M-2004 EOTF^ -1^ equals the OETF given above. -The ``reference camera'' of SMTPE 170M-2004 has an OETF function matching +Therefore the SMPTE 170M-2004 EOTF^{nbsp}-1^ equals the OETF given above. +The "`reference camera`" of SMTPE 170M-2004 has an OETF function matching that of the ITU specifications. That is, the OOTF of the system described in SMPTE 170M-2004 provides a linear mapping of captured scene intensity to display intensity: the SMPTE @@ -307,14 +307,14 @@ linear mapping of captured scene intensity to display intensity: the SMPTE on a typical display. This is distinct from the current ITU specifications, which assume a non-linear OOTF. -SMPTE 170M-2004 also represents a change from the ``assumed gamma'' of +SMPTE 170M-2004 also represents a change from the "`assumed gamma`" of 2.2 associated with most NTSC display devices as described in <> and <>, although these standards also define a linear OOTF. <<< -This ``ITU'' OETF is closely approximated by a simple power function with -an exponent of 0.5 (and therefore the OETF^ -1^ is quite closely +This "`ITU`" OETF is closely approximated by a simple power function with +an exponent of 0.5 (and therefore the OETF^{nbsp}-1^ is quite closely approximated by a simple power function with an exponent of 2.0); the linear segment and offset mean that the best match is _not_ the exponent of 0.45 that forms part of the exact equation. @@ -322,106 +322,106 @@ ITU standards deliberately chose a different transfer curve from that of a typical CRT in order to introduce a non-linear OOTF, as a means to compensate for the typically dim conditions in which a television is viewed. <> refers to the approximation of the OETF with a -square root latexmath:[$\left(\gamma = {1\over{2}}\right)$] function. +square root latexmath:[\left(\gamma = {1\over{2}}\right)] function. The following graph shows the close relationship between the ITU OETF (shown in red) and a pure power function with -latexmath:[$\gamma={1\over{2}}$] (in blue). +latexmath:[\gamma={1\over{2}}] (in blue). The difference between the curves is shown in black. The largest difference between the curve values at the same point when quantized to 8 bits is 15, mostly due to the sharp vertical gradient near 0. .ITU OETF vs pure gamma ^1^/~2~ -image::images/tf_ituvsgamma2_0.png[width="{svgpdf@pdf:160pt:257}",align="center"] +image::{images}/tf_ituvsgamma2_0.png[width="{svgpdf@pdf:160pt:257}",align="center"] [NOTE] ==== -<> contains a note that the OETF is a more ``technically -correct'' definition of the transfer function, and compares it to a ``transfer -gradient (gamma exponent) of 2.2'' in previous specifications, and that the -OETF in older documents is described as ``1/2.2 (0.455...)''. +<> contains a note that the OETF is a more "`technically +correct`" definition of the transfer function, and compares it to a "`transfer +gradient (gamma exponent) of 2.2`" in previous specifications, and that the +OETF in older documents is described as "`1/2.2 (0.455...)`". While both versions define a linear OOTF, there is no explicit mention that curve has substantially changed; this might be due to conflation of the 0.455 exponent in older specifications with the 0.45 exponent in the new formulae. The ITU OETF is actually a closer match to a gamma exponent of -latexmath:[$1\over{2.0}$], as shown above; it is a relatively poor match to a -gamma exponent of latexmath:[$1\over{2.2}$]; the following graph shows the +latexmath:[1\over{2.0}], as shown above; it is a relatively poor match to a +gamma exponent of latexmath:[1\over{2.2}]; the following graph shows the difference between the ITU OETF (shown in red) and a pure power function -with latexmath:[$\gamma={1\over{2.2}}$] (in blue). +with latexmath:[\gamma={1\over{2.2}}] (in blue). The difference between the curves is shown in black. .ITU OETF vs pure gamma ^1^/~2.2~ -image::images/tf_ituvsgamma2_2.png[width="{svgpdf@pdf:160pt:257}",align="center"] +image::{images}/tf_ituvsgamma2_2.png[width="{svgpdf@pdf:160pt:257}",align="center"] ==== ==== Derivation of the ITU alpha and beta constants (informative) -Using the 12-bit encoding values for _α_ and _β_ +Using the 12-bit encoding values for _{alpha}_ and _{beta}_ from <>, there is an overlap around a non-linear value of 0.08145. In other cases, the conversion from linear to non-linear representation with encoding introduces a discontinuity between -(0.018 {times} 4.500) = 0.081 and -(1.099 {times} 0.018^0.45^ - 0.099) ≈ 0.0812, +(0.018{nbsp}{times}{nbsp}4.500){nbsp}={nbsp}0.081 and +(1.099{nbsp}{times}{nbsp}0.018^0.45^{nbsp}-{nbsp}0.099){nbsp}{approx}{nbsp}0.0812, corresponding to roughly a single level in a 12-bit range. <> provides formulae for both transformations and uses 0.0812 as a case selector for the non-linear-to-linear transformation. -The values of _α_ and _β_ in the ITU function +The values of _{alpha}_ and _{beta}_ in the ITU function were apparently chosen such that the linear segment and power segment meet at the same value and with the same derivative (that is, the linear segment meets the power segment at a tangent). -The _α_ and _β_ values can be derived as follows: +The _{alpha}_ and _{beta}_ values can be derived as follows: -At {_R_,_G_,_B_} = _β_, the linear and non-linear segments of the curve +At {_R_,_G_,_B_}{nbsp}= _{beta}_, the linear and non-linear segments of the curve must calculate the same value: [latexmath] -++++++ -$$4.5 \times \beta = \alpha \times \beta^{0.45} - (\alpha - 1)$$ -++++++ +++++ +4.5 \times \beta = \alpha \times \beta^{0.45} - (\alpha - 1) +++++ Additionally, the derivatives of the linear and non-linear segments of the curve must match: [latexmath] -++++++ -$$4.5 = 0.45 \times \alpha \times \beta^{-0.55}$$ -++++++ +++++ +4.5 = 0.45 \times \alpha \times \beta^{-0.55} +++++ The derivative can be rearranged to give the equation: [latexmath] -++++++ -$$\alpha = 10 \times \beta^{0.55}$$ -++++++ +++++ +\alpha = 10 \times \beta^{0.55} +++++ Substituting this into the original equation results in the following: [latexmath] -++++++ -$$4.5 \times \beta = 10 \times \beta^{0.55} \times \beta^{0.45} - (10 \times \beta^{0.55} - 1)$$ -++++++ +++++ +4.5 \times \beta = 10 \times \beta^{0.55} \times \beta^{0.45} - (10 \times \beta^{0.55} - 1) +++++ This simplifies to: [latexmath] -++++++ -$$5.5 \times \beta - 10 \times \beta^{0.55} + 1 = 0$$ -++++++ +++++ +5.5 \times \beta - 10 \times \beta^{0.55} + 1 = 0 +++++ This can be solved numerically (for example by Newton-Raphson iteration), and results in values of: [latexmath] -++++++ +++++ \begin{align*} \beta &\approx 0.018053968510808\\ \alpha &\approx 1.099296826809443\\ \delta &= \alpha\times\beta^{0.45} - (\alpha-1) = 4.5\times\beta\\ &\approx 0.081242858298635\\ \end{align*} -++++++ +++++ <<< @@ -432,12 +432,12 @@ and results in values of: ==== sRGB EOTF The <> defines an electro-optical transfer function. -The EOTF conversion from non-linear latexmath:[$(R', G', B')$] encoding -to linear latexmath:[$(R, G, B)$] encoding is: +The EOTF conversion from non-linear latexmath:[(R', G', B')] encoding +to linear latexmath:[(R, G, B)] encoding is: [[srgbgamma]] [latexmath] -++++++ +++++ \begin{align*} R &= \begin{cases} {R' \over 12.92}, & R' \leq 0.04045 \\ @@ -452,17 +452,17 @@ to linear latexmath:[$(R, G, B)$] encoding is: \left({B' + 0.055} \over 1.055\right)^{2.4}, & B' > 0.04045 \end{cases} \end{align*} -++++++ +++++ [[TRANSFER_SRGB_INVEOTF]] ==== sRGB EOTF^-1^ -The corresponding sRGB EOTF^ -1^ conversion from linear -latexmath:[$(R, G, B)$] encoding to non-linear latexmath:[$(R', G', B')$] +The corresponding sRGB EOTF^{nbsp}-1^ conversion from linear +latexmath:[(R, G, B)] encoding to non-linear latexmath:[(R', G', B')] encoding is: [latexmath] -++++++ +++++ \begin{align*} R' &= \begin{cases} R \times 12.92, & R \leq 0.0031308 \\ @@ -477,7 +477,7 @@ encoding is: 1.055 \times B^{1\over 2.4} - 0.055, & B > 0.0031308 \end{cases} \end{align*} -++++++ +++++ [[TRANSFER_SRGB_EOTFVSGAMMA]] ==== sRGB EOTF vs gamma 2.2 @@ -497,32 +497,32 @@ its EOTF as the inverse of its (and BT.709's) OETF. <<< The following graph compares the sRGB EOTF (in red) and a pure power -function with latexmath:[$\gamma=2.2$] (in blue); the area between the +function with latexmath:[\gamma=2.2] (in blue); the area between the two curves is shown in black. The largest non-linear difference at the same linear value when quantized to 8 bits is 3. .sRGB EOTF vs pure gamma 2.2 -image::images/tf_srgbvsgamma.png[width="{svgpdf@pdf:192pt:257}",align="center"] +image::{images}/tf_srgbvsgamma.png[width="{svgpdf@pdf:192pt:257}",align="center"] NOTE: The sRGB standard assumes a quantization scheme in which 0.0 is represented by the value 0 and 1.0 is represented by 255. Despite the goal of complementing <>, -this is different from the ITU ``full-range'' encoding scheme +this is different from the ITU "`full-range`" encoding scheme defined in <>, which represents 1.0 as -a power of two (not latexmath:[$2^n-1$]) and therefore cannot exactly +a power of two (not latexmath:[2^n-1]) and therefore cannot exactly represent 1.0. The following graph shows the relationship between the sRGB EOTF (shown in red) and the <> (shown in blue). The result of applying the two functions in turn, resulting in the OOTF of a combined ITU-sRGB system, is shown in black. Since the sRGB EOTF approximates a power function -with latexmath:[$\gamma=2.2$] and the ITU OETF approximates a power function with -latexmath:[$\gamma=2.0$], also shown in green is the resulting OOTF corresponding to a -power function with latexmath:[$\gamma={2.2\over{2.0}}=1.1$]. +with latexmath:[\gamma=2.2] and the ITU OETF approximates a power function with +latexmath:[\gamma=2.0], also shown in green is the resulting OOTF corresponding to a +power function with latexmath:[\gamma={2.2\over{2.0}}=1.1]. .sRGB EOTF and ITU OETF -image::images/tf_ituvssrgb256.png[width="{svgpdf@pdf:192pt:257}",align="center"] +image::{images}/tf_ituvssrgb256.png[width="{svgpdf@pdf:192pt:257}",align="center"] <<< [[TRANSFER_SCRGB_EOTF]] @@ -539,7 +539,7 @@ the absolute value of the input. That is: [latexmath] -++++++ +++++ \begin{align*} R' &= \begin{cases} -1.055 \times (-R)^{1\over 2.4} + 0.055, & R \leq -0.0031308 \\ @@ -557,18 +557,18 @@ That is: 1.055 \times B^{1\over 2.4} - 0.055, & B \geq 0.0031308 \end{cases} \end{align*} -++++++ +++++ NOTE: <> annex B changes the behavior of the -latexmath:[$\{R,G,B\} = 0.0031308$] case compared with the +latexmath:[\{R,G,B\} = 0.0031308] case compared with the <> specification. Since both calculations agree to seven decimal places, this is unlikely to be significant in most applications. -scRGB annex B does not define the EOTF^ -1^, so the +scRGB annex B does not define the EOTF^{nbsp}-1^, so the formulae below are derived by extending the sRGB formulae. [latexmath] -++++++ +++++ \begin{align*} R &= \begin{cases} -\left({0.055 - R'} \over 1.055\right)^{2.4}, & R' < -0.04045 \\ @@ -586,18 +586,18 @@ formulae below are derived by extending the sRGB formulae. \left({B' + 0.055} \over 1.055\right)^{2.4}, & B' > 0.04045 \end{cases} \end{align*} -++++++ +++++ [NOTE] ==== <> includes a hint that a 1cd/m^2^ level of flare should be assumed for the reference 80cd/m^2^ output, and that the black level -should therefore be assumed to be latexmath:[${1\over 80} = 0.0125$]. -It notes that the non-linear sRGB \{latexmath:[$R',G',B'$]\} values can +should therefore be assumed to be latexmath:[{1\over 80} = 0.0125]. +It notes that the non-linear sRGB \{latexmath:[R',G',B']\} values can be corrected as follows: [latexmath] -++++++ +++++ \begin{align*} E_{sYCC} &= \begin{cases} 0.0125 - \left({1-0.0125\over 1.055^{2.4}}\right) @@ -613,12 +613,12 @@ E_{sYCC} &= \begin{cases} E_{sYCC} &= (\textrm{linear}) \{R_{sYCC},G_{sYCC},B_{sYCC}\} \\ E'_{sRGB} &= (\textrm{non-linear}) \{R'_{sRGB},G'_{sRGB},B'_{sRGB}\} \end{align*} -++++++ +++++ This is equivalent to applying -latexmath:[$E_{sYCC} = 0.0125 + {1\over 1-0.0125} \times E_{sRGB}$] -to linear latexmath:[$\{R,G,B\}$] values. -The resulting linear latexmath:[$E_{sYCC}$] values then need to be +latexmath:[E_{sYCC} = 0.0125 + {1\over 1-0.0125} \times E_{sRGB}] +to linear latexmath:[\{R,G,B\}] values. +The resulting linear latexmath:[E_{sYCC}] values then need to be non-linearly encoded with the EOTF. ==== @@ -627,88 +627,88 @@ non-linearly encoded with the EOTF. [[TRANSFER_SRGB_DERIVED]] ==== Derivation of the sRGB constants (informative) -Similar to the ITU transfer function, the EOTF^ -1^ of the sRGB function +Similar to the ITU transfer function, the EOTF^{nbsp}-1^ of the sRGB function can be written as: [latexmath] -++++++ +++++ \begin{align*} \{R,G,B\} &= \begin{cases} \{R',G',B'\} \times 12.92, & \{R',G',B'\} \leq \beta \\ \alpha \times \{R',G',B'\}^{1\over{2.4}} - (\alpha - 1), & \{R',G',B'\} < \beta \end{cases} \end{align*} -++++++ +++++ -Like the ITU transfer function above, the values of latexmath:[$\alpha$] -and latexmath:[$\beta$] in the sRGB function appear to have been chosen +Like the ITU transfer function above, the values of latexmath:[\alpha] +and latexmath:[\beta] in the sRGB function appear to have been chosen such that the linear segment and power segment meet at the same value and with the same derivative (that is, the linear segment meets the power segment at a tangent). -The latexmath:[$\alpha$] and latexmath:[$\beta$] values can be derived as +The latexmath:[\alpha] and latexmath:[\beta] values can be derived as follows: -At latexmath:[$\{R',G',B'\} = \beta$], the linear and non-linear segments +At latexmath:[\{R',G',B'\} = \beta], the linear and non-linear segments of the function must calculate the same value: [latexmath] -++++++ -$$12.92 \times \beta = \alpha \times \beta^{1\over{2.4}} - (\alpha - 1)$$ -++++++ +++++ +12.92 \times \beta = \alpha \times \beta^{1\over{2.4}} - (\alpha - 1) +++++ Additionally, the derivatives of the linear and non-linear segments of the function must match: [latexmath] -++++++ -$$12.92 = {{\alpha \times \beta^{{1\over{2.4}}-1}}\over{2.4}}$$ -++++++ +++++ +12.92 = {{\alpha \times \beta^{{1\over{2.4}}-1}}\over{2.4}} +++++ -This formula can be rearranged to give latexmath:[$\alpha$] in terms of -latexmath:[$\beta$]: +This formula can be rearranged to give latexmath:[\alpha] in terms of +latexmath:[\beta]: [latexmath] -++++++ -$$\alpha = 12.92\times 2.4\times \beta^{1-{1\over{2.4}}}$$ -++++++ +++++ +\alpha = 12.92\times 2.4\times \beta^{1-{1\over{2.4}}} +++++ -Substituting this into the formula for latexmath:[$\{R,G,B\}$]: +Substituting this into the formula for latexmath:[\{R,G,B\}]: [latexmath] -++++++ -$$12.92 \times \beta = 12.92\times 2.4\times \beta^{1-{1\over{2.4}}} \times \beta^{1\over{2.4}} - (12.92\times 2.4\times \beta^{1-{1\over{2.4}}} - 1)$$ -++++++ +++++ +12.92 \times \beta = 12.92\times 2.4\times \beta^{1-{1\over{2.4}}} \times \beta^{1\over{2.4}} - (12.92\times 2.4\times \beta^{1-{1\over{2.4}}} - 1) +++++ This equation simplifies to: [latexmath] -++++++ -$$1.4 \times 12.92 \times \beta - 2.4 \times 12.92 \times \beta^{1 - {1\over{2.4}}} + 1 = 0$$ -+++++ +++++ +1.4 \times 12.92 \times \beta - 2.4 \times 12.92 \times \beta^{1 - {1\over{2.4}}} + 1 = 0 +++++ This can be further simplified to: [latexmath] -++++++ -$$1.4 \times \beta - 2.4 \times \beta^{1 - {1\over{2.4}}} + {1\over{12.92}} = 0$$ -+++++ +++++ +1.4 \times \beta - 2.4 \times \beta^{1 - {1\over{2.4}}} + {1\over{12.92}} = 0 +++++ -The value of latexmath:[$\beta$] can be found numerically (for example by +The value of latexmath:[\beta] can be found numerically (for example by Newton-Raphson iteration, with a derivative of -latexmath:[$1.4-1.4\beta^{-{1\over{2.4}}}$]), and results in values of: +latexmath:[1.4-1.4\beta^{-{1\over{2.4}}}]), and results in values of: [latexmath] -++++++ +++++ \begin{align*} \beta &\approx 0.003041282560128\\ \alpha &\approx 1.055010718947587\\ \delta &= 12.92\times\beta = \alpha\times\beta^{1\over{2.4}}-(\alpha-1.0)\\ &\approx 0.039293370676848 \end{align*} -++++++ +++++ -Where latexmath:[$\delta$] is the value of the EOTF^ -1^ at -latexmath:[$\{R',G',B'\} = \beta$]. +Where latexmath:[\delta] is the value of the EOTF^{nbsp}-1^ at +latexmath:[\{R',G',B'\} = \beta]. [NOTE] ==== @@ -728,12 +728,12 @@ practice. The EOTF can be written with these derived values as: [latexmath] -++++++ - $$\{R,G,B\} = \begin{cases} - {{\{R',G',B'\}}\over{12.92}}, & \{R',G',B'\} \leq \delta \\ - \left({{\{R',G',B'\}}\over{\alpha}} + {{\alpha-1}\over\alpha}\right)^{2.4}, & \{R',G',B'\} > \delta - \end{cases}$$ -++++++ +++++ +\{R,G,B\} = \begin{cases} + {{\{R',G',B'\}}\over{12.92}}, & \{R',G',B'\} \leq \delta \\ + \left({{\{R',G',B'\}}\over{\alpha}} + {{\alpha-1}\over\alpha}\right)^{2.4}, & \{R',G',B'\} > \delta +\end{cases} +++++ [NOTE] ==== @@ -743,47 +743,47 @@ The profile viewer in Apple's ColorSync utility reports that the EOTF is of the following form: [latexmath] -++++++ - $$f(x) = \begin{cases} +++++ +f(x) = \begin{cases} cx, & x < d \\ (ax+b)^\gamma, & x \geq d - \end{cases}$$ -++++++ +\end{cases} +++++ -The reported figures for latexmath:[$\gamma=2.4,\ a=0.948,\ b=0.52$] -and latexmath:[$c=0.077$] correspond to the equivalent values in +The reported figures for latexmath:[\gamma=2.4,\ a=0.948,\ b=0.52] +and latexmath:[c=0.077] correspond to the equivalent values in the sRGB specification: [latexmath] -++++++ +++++ \begin{align*} {1\over{\alpha}} &\approx 0.948 = a\\ {{\alpha-1}\over\alpha} &\approx 0.52 = b\\ {1\over{12.92}} &\approx 0.077 = c \end{align*} -++++++ +++++ These values are correct to the reported precision both for the value -latexmath:[$\alpha = 1.055$] in the sRGB specification and for the more -precise latexmath:[$\alpha \approx 1.055010718947587$] derived above. +latexmath:[\alpha = 1.055] in the sRGB specification and for the more +precise latexmath:[\alpha \approx 1.055010718947587] derived above. -  +{nbsp} However, where the sRGB specification states that -latexmath:[$\delta = 0.04045$], the profile viewer reports -a corresponding d = 0.039. +latexmath:[\delta = 0.04045], the profile viewer reports +a corresponding d{nbsp}={nbsp}0.039. The disparity can be explained if the profile values have been derived as described in this section: [latexmath] -++++++ -$$\delta \approx 0.039293370676848\approx 0.039 = d$$ -++++++ +++++ +\delta \approx 0.039293370676848\approx 0.039 = d +++++ Note that this value assumes a correspondingly corrected version -of latexmath:[$\alpha$] rather than latexmath:[$a = 1.055$]. +of latexmath:[\alpha] rather than latexmath:[a = 1.055]. -  +{nbsp} The extra precision may be needed over the constants in the sRGB specification due to the use of additional bits of accuracy in the @@ -791,35 +791,35 @@ Display P3 representation, which may expose a discontinuity due to rounding with the original numbers, particularly in the gradient of the curve. However, this distinction is subtle: when calculated over a [0..1] -range, the derived EOTF and EOTF^ -1^ agree with the official +range, the derived EOTF and EOTF^{nbsp}-1^ agree with the official sRGB formulae to greater than 16-bit precision. ==== -Without allowing for adjusting the latexmath:[$\alpha = 1.055$] +Without allowing for adjusting the latexmath:[\alpha = 1.055] constant in the sRGB formula, the power function cannot be made to intersect perfectly at a tangent to the linear segment with gradient of 12.92. -However, the intersection point latexmath:[$\beta$] can be +However, the intersection point latexmath:[\beta] can be found by solving: [latexmath] -++++++ -$$1.055\times\beta^{1\over{2.4}}-12.92\times\beta-0.055 = 0$$ -++++++ +++++ +1.055\times\beta^{1\over{2.4}}-12.92\times\beta-0.055 = 0 +++++ This equation can give us a slightly more precise pair of values for the original sRGB equation: [latexmath] -++++++ +++++ \begin{align*} \beta &\approx 0.003130668 \\ \delta &\approx 0.040448236 \end{align*} -++++++ +++++ In practice this makes no measurable difference, but does suggest -that the values of latexmath:[$\beta = 0.0031308$] in the sRGB +that the values of latexmath:[\beta = 0.0031308] in the sRGB specification may have been incorrectly rounded. <<< @@ -827,40 +827,40 @@ specification may have been incorrectly rounded. [[TRANSFER_BT1886]] === BT.1886 transfer functions -The <> standard for the ``Reference electro-optical transfer -function for flat panel displays used in HDTV studio production'' is intended to +The <> standard for the "`Reference electro-optical transfer +function for flat panel displays used in HDTV studio production`" is intended to represent a typical EOTF for CRTs and to document this to ensure consistency between other display technologies: [latexmath] -++++++ -$$L = a(\textrm{max}(V+b,0))^\gamma$$ -++++++ +++++ +L = a(\textrm{max}(V+b,0))^\gamma +++++ [width="40%",grid="none",frame="none"] -|============ +|==== <|_L_ = screen luminance in cd/m^2^ <|_V_ = input signal normalized to [0..1] -<|_a_ = user gain (legacy ``contrast'') -<|_b_ = black level lift (legacy ``brightness'') -<|latexmath:[$\gamma$] = 2.4 -|============ +<|_a_ = user gain (legacy "`contrast`") +<|_b_ = black level lift (legacy "`brightness`") +<|latexmath:[\gamma] = 2.4 +|==== If _L~W~_ is the screen luminance of maximum white and _L~B~_ is the screen luminance of minimum black: [latexmath] -++++++ +++++ \begin{align*} L_B &= a \times b^\gamma \\ L_W &= a \times (1 + b)^\gamma \\ a &= (L_W^{1\over\gamma} - L_B^{1\over\gamma})^\gamma \\ b &= {{L_B^{1\over\gamma}}\over{L_W^{1\over\gamma} - L_B^{1\over\gamma}}} \end{align*} -++++++ +++++ <> proposes the use of a simple power function with a -latexmath:[$\gamma = 2.4$] as an approximation to this EOTF for the purposes +latexmath:[\gamma = 2.4] as an approximation to this EOTF for the purposes of color conversion, effectively assuming _b_ = 0 and _L~B~_ is pure black. The reference display described in BT.1886 has a maximum luminance level of 100cd/m^2^ (brighter than the equivalent <> reference @@ -870,11 +870,11 @@ The following graph shows the relationship between the BT.1886 EOTF (shown in re and the <> such as used for <> (shown in blue). The result of applying the two functions in turn, resulting in the OOTF of a combined BT.709-BT.1886 system, is shown in black. Since the ITU OETF approximates a power -function with latexmath:[$\gamma=2.0$], also shown in green is the resulting OOTF -corresponding to a power function with latexmath:[$\gamma={2.4\over{2.0}}=1.2$]. +function with latexmath:[\gamma=2.0], also shown in green is the resulting OOTF +corresponding to a power function with latexmath:[\gamma={2.4\over{2.0}}=1.2]. .BT.1886 EOTF and BT.709 OETF -image::images/tf_ituvsgamma256.png[width="{svgpdf@pdf:192pt:257}",align="center"] +image::{images}/tf_ituvsgamma256.png[width="{svgpdf@pdf:192pt:257}",align="center"] [NOTE] ==== @@ -882,24 +882,24 @@ image::images/tf_ituvsgamma256.png[width="{svgpdf@pdf:192pt:257}",align="center" match to CRT measured luminance than the standard formula listed above: [latexmath] -++++++ +++++ \begin{align*} L &= \begin{cases} k(V_C+b)^{(\alpha_1-\alpha_2)}(V+b)^{\alpha_2}, & V < V_C \\ k(V+b)^{\alpha_1}, & V_C \leq V \end{cases} \end{align*} -++++++ +++++ [width="60%",grid="none",frame="none"] -|============ +|==== <|_V~C~_ = 0.35 -<|latexmath:[$\alpha_1$] = 2.6 -<|latexmath:[$\alpha_2$] = 3.0 +<|latexmath:[\alpha_1] = 2.6 +<|latexmath:[\alpha_2] = 3.0 <|_k_ = coefficient of normalization (so that _V_ = 1 gives white), -<|latexmath:[$k=L_W(1+b)^{-\alpha_1}$] -<|_b_ = black level lift (legacy ``brightness'') -|============ +<|latexmath:[k=L_W(1+b)^{-\alpha_1}] +<|_b_ = black level lift (legacy "`brightness`") +|==== ==== @@ -919,21 +919,21 @@ The <> Hybrid Log Gamma description defines the following OETF for linear scene light: [latexmath] -++++++ - $$E'_\mathit{norm} = \textrm{OETF}(E) = \begin{cases} +++++ +E'_\mathit{norm} = \textrm{OETF}(E) = \begin{cases} \sqrt{3E}, & 0 \leq E \leq {1\over{12}} \\ a \times \textrm{ln}((12\times E) - b) + c, & {1\over{12}} < E \leq 1 - \end{cases}$$ -++++++ +\end{cases} +++++ [width="80%",grid="none",frame="none"] -|============ -<|latexmath:[$E$] = the latexmath:[$R_S$], latexmath:[$G_S$] or latexmath:[$B_S$] color component of linear scene light, normalized to [0..1] -<|latexmath:[$E'$] = the resulting non-linear latexmath:[$R_S'$], latexmath:[$G_S'$] or latexmath:[$B_S'$] non-linear scene light value in in the range [0..1] +|==== +<|latexmath:[E] = the latexmath:[R_S], latexmath:[G_S] or latexmath:[B_S] color component of linear scene light, normalized to [0..1] +<|latexmath:[E'] = the resulting non-linear latexmath:[R_S'], latexmath:[G_S'] or latexmath:[B_S'] non-linear scene light value in in the range [0..1] <|_a_ = 0.17883277 -<|_b_ = latexmath:[$1 - 4\times a = 0.28466892$] -<|_c_ = latexmath:[$0.5 - a\times ln(4\times a) \approx 0.55991073$] -|============ +<|_b_ = latexmath:[1 - 4\times a = 0.28466892] +<|_c_ = latexmath:[0.5 - a\times ln(4\times a) \approx 0.55991073] +|==== [NOTE] ==== @@ -941,104 +941,104 @@ BT.2100-0, in note 5b, defines these formulae equivalently, but slightly differently: [latexmath] -++++++ - $$E'_\mathit{norm} = \textrm{OETF}(E) = \begin{cases} +++++ +E'_\mathit{norm} = \textrm{OETF}(E) = \begin{cases} \sqrt{3E}, & 0 \leq E \leq {1\over{12}} \\ a \times \textrm{ln}(E - b_0) + c_0, & {1\over{12}} < E \leq 1 - \end{cases}$$ -++++++ +\end{cases} +++++ This formulation in BT.2100-0 uses different constants for _b_ and _c_ (_a_ is unmodified), as follows: [width="50%",options="header",cols="1,5,5"] -|============ +|==== | | BT.2100-2, BT.2100-1 | BT.2100-0 | _b_ | _b_~1~ = 0.28466892 | _b_~0~ = 0.02372241 | _c_ | _c_~1~ = 0.55991073 | _c_~0~ = 1.00429347 -|============ +|==== The BT.2100-0 variations can be derived from the BT.2100-2 numbers as: [latexmath] -++++++ +++++ \begin{align*} a \times \textrm{ln}((12 \times E) - b_1)+ c_1 & = a \times \textrm{ln}\left(12\times\left(E - {b_1\over{12}}\right)\right) + c_1\\ & = a \times \textrm{ln}\left(E - {{b_1}\over{12}}\right) + a\times\textrm{ln}(12) + c_1 \\ {{b_1}\over{12}} = {{0.28466892}\over{12}} &= 0.023772241 = b_0 \\ a\times\textrm{ln}(12) + c_1 = 0.17883277\times\textrm{ln}(12) + 0.55991073 &= 1.00429347 = c_0 \end{align*} -++++++ +++++ ==== <<< [[TRANSFER_HLG_IOETF_NORM]] -==== HLG OETF^ -1^ (normalized) +==== HLG OETF^{nbsp}-1^ (normalized) -The OETF^ -1^ of normalized HLG is: +The OETF^{nbsp}-1^ of normalized HLG is: [latexmath] -++++++ - $$E = \textrm{OETF}^{-1}(E') = \begin{cases} +++++ +E = \textrm{OETF}^{-1}(E') = \begin{cases} {{E'^2}\over 3}, & 0 \leq E' \leq {1\over 2} \\ {1\over 12} \times \left({b + e^{(E'-c)/a}}\right), & {1\over 2} < E' \leq 1 - \end{cases}$$ -++++++ +\end{cases} +++++ _a_, _b_ and _c_ are defined as for the normalized HLG OETF. BT.2100-0 again defines an equivalent formula without the -latexmath:[$1\over{12}$] scale factor in the -latexmath:[${1\over 2}$] < latexmath:[$E' \leq 1$] term, +latexmath:[1\over{12}] scale factor in the +latexmath:[{1\over 2} < E' \leq 1] term, using the modified _b_~0~ and _c_~0~ constants described in the note in the <> above. [[TRANSFER_HLG_OETF_UNNORM]] ==== Unnormalized HLG OETF -BT.2100-0 describes the HLG OETF formulae with _E_ ``normalized'' to the +BT.2100-0 describes the HLG OETF formulae with _E_ "`normalized`" to the range [0..12], with the <> as an alternative. Only the variant normalized to the range [0..1] is described in the updated versions of the specification, BT.2100-1 and BT.2100-2. [latexmath] -++++++ - $$E' = \textrm{OETF}(E) = \begin{cases} +++++ +E' = \textrm{OETF}(E) = \begin{cases} {{\sqrt{E}}\over{2}}, & 0 \leq E \leq 1 \\ a \times \textrm{ln}(E-b) + c, & 1 < E - \end{cases}$$ -++++++ +\end{cases} +++++ [width="80%",grid="none",frame="none"] -|============ -<|latexmath:[$E'$] = the latexmath:[$R_S$], latexmath:[$G_S$] or latexmath:[$B_S$] color component of linear scene light, normalized to [0..12] -<|latexmath:[$E_S'$] = the resulting non-linear latexmath:[$R_S'$], latexmath:[$G_S'$] or latexmath:[$B_S'$] value in in the range [0..1] +|==== +<|latexmath:[E'] = the latexmath:[R_S], latexmath:[G_S] or latexmath:[B_S] color component of linear scene light, normalized to [0..12] +<|latexmath:[E_S'] = the resulting non-linear latexmath:[R_S'], latexmath:[G_S'] or latexmath:[B_S'] value in in the range [0..1] <|_a_ = 0.17883277 <|_b_ = 0.28466892 <|_c_ = 0.55991073 -|============ +|==== Note that these constants are the same as those used in the BT.2100-1 version of the <>. [[TRANSFER_HLG_IOETF_UNNORM]] -==== Unnormalized HLG OETF^ -1^ +==== Unnormalized HLG OETF^{nbsp}-1^ -The OETF^ -1^ of ``unnormalized'' HLG (producing _E_ in the range [0..12]) is: +The OETF^{nbsp}-1^ of "`unnormalized`" HLG (producing _E_ in the range [0..12]) is: [latexmath] -++++++ - $$E = \textrm{OETF}^{-1}(E') = \begin{cases} +++++ +E = \textrm{OETF}^{-1}(E') = \begin{cases} 4\times E'^2, & 0 \leq E' \leq {1\over 2} \\ b + e^{(E'-c)/a}, & {1\over 2} < E' - \end{cases}$$ -++++++ +\end{cases} +++++ _a_, _b_ and _c_ are defined as for the <>. -BT.2100-0 describes this ``unnormalized'' version of the formulae, with the +BT.2100-0 describes this "`unnormalized`" version of the formulae, with the variant with the E normalized to [0..1] as an alternative. Only the variant with E normalized to [0..1] is described in the updated versions, BT.2100-1 and BT.2100-2. @@ -1048,15 +1048,15 @@ versions, BT.2100-1 and BT.2100-2. HLG constants appear to have chosen _a_, _b_ and _c_ to meet the following constraints, which are easiest to express in terms of the unnormalized -OETF^ -1^: +OETF^{nbsp}-1^: - * The derivative of the latexmath:[$0 \leq E' \leq {1\over 2}$] term of - the unnormalized OETF^ -1^ has the same value as the derivative of - the latexmath:[${1\over 2}$] < latexmath:[$E' \leq 1$] term - of the unnormalized OETF^ -1^ at latexmath:[$E' = {1\over 2}$]: + * The derivative of the latexmath:[0 \leq E' \leq {1\over 2}] term of + the unnormalized OETF^{nbsp}-1^ has the same value as the derivative of + the latexmath:[{1\over 2} < E' \leq 1] term + of the unnormalized OETF^{nbsp}-1^ at latexmath:[E' = {1\over 2}]: + [latexmath] -++++++ +++++ \begin{align*} {{d(4\times E'^2)}\over{dE'}} = 8\times E' &= 8 \times {1\over 2} = 4 \textrm{ (derivative of the } 0 \leq E' \leq {1\over 2} \textrm{ case)}\\ @@ -1071,14 +1071,14 @@ OETF^ -1^: \implies c &= -\textrm{ln}\left({{(4\times a)^a}\over{e^{0.5}}}\right)\\ &= 0.5 - a\times\textrm{ln}(4\times a) \end{align*} -++++++ - * The latexmath:[$0 \leq E' \leq {1\over 2}$] term of the unnormalized - OETF^ -1^ has the same value as the - latexmath:[${1\over 2}$] < latexmath:[$E'\leq 1$] - term of the unnormalized OETF^ -1^ at latexmath:[$E' = {1\over 2}$]: +++++ + * The latexmath:[0 \leq E' \leq {1\over 2}] term of the unnormalized + OETF^{nbsp}-1^ has the same value as the + latexmath:[{1\over 2} < E'\leq 1] + term of the unnormalized OETF^{nbsp}-1^ at latexmath:[E' = {1\over 2}]: + [latexmath] -++++++ +++++ \begin{align*} 4\times{E'}^2 &= e^{{E' - c}\over a} + b \textrm{ (from the }0 \leq E' \leq {1\over 2}\textrm{ and }{1\over 2} < E' \textrm{ cases})\\ @@ -1087,12 +1087,12 @@ OETF^ -1^: &= e^{\textrm{ln}(4\times a)} + b\\ b &= 1 - 4\times a \end{align*} -++++++ - * At _E'_ = 1, the latexmath:[${1\over 2}$] < latexmath:[$E'$] - term of the unnormalized OETF^ -1^ = 12: +++++ + * At _E'_ = 1, the latexmath:[{1\over 2} < E'] + term of the unnormalized OETF^{nbsp}-1^ = 12: + [latexmath] -++++++ +++++ \begin{align*} 12 &= e^{{E'-c}\over a} + b\\ &= {e^{{1 - 0.5 + a\times\textrm{ln}(4\times a)}\over a} + 1 - 4\times a} \\ @@ -1102,36 +1102,36 @@ b &= 1 - 4\times a {121\over{16\times a^2}} + {11\over{2\times a}} + 1 &= e^{1\over a}\\ {121\over{16}} + {a\times 11\over 2} + a^2 \times (1 - e^{1\over a}) = 0 \end{align*} -++++++ +++++ This last equation can be solved numerically to find: [latexmath] -++++++ +++++ \begin{align*} a \approx 0.1788327726569497656312771 \end{align*} -++++++ +++++ With this precision, more accurate values of the other constants are: [latexmath] -++++++ +++++ \begin{align*} b &= 0.28466890937 \\ c &= 0.55991072776 \end{align*} -++++++ +++++ The _b_ = 0.28466892 official figure assumes the rounded -_a_ = 0.17883277 value as an input to the _b_ = latexmath:[$1 - 4\times a$] +_a_ = 0.17883277 value as an input to the _b_ = latexmath:[1 - 4\times a] relation. [NOTE] ==== No explanation for the choice of [0..12] range in the official version of the formula is explicitly offered in BT.2100-0 (it does _not_, for example, -appear to relate to the <> OOTF latexmath:[$\gamma = 1.2$] -combined with the latexmath:[$10\times$] ratio between the +appear to relate to the <> OOTF latexmath:[\gamma = 1.2] +combined with the latexmath:[10\times] ratio between the <>cd/m^2^ of a standard HLG HDR TV and the <>cd/m^2^ of a standard dynamic range set). However, allowing for the difference in the maximum display brightness of @@ -1147,16 +1147,16 @@ content, an SDR display may represent darker tones accurately and simply under-represent highlights. The origins of both HLG and PQ are discussed in <>. -  +{nbsp} -As graphed in <>, the ``unnormalized'' HLG OETF (red) +As graphed in <>, the "`unnormalized`" HLG OETF (red) is a good approximation to the standard dynamic range ITU transfer function -(blue, output scaled by 0.5) up to latexmath:[$E \approx 1$] and -latexmath:[$\textrm{OETF}(E) = E' \approx 0.5$], with a smooth -curve up to the maximum HLG representable scene light value of ``12'': +(blue, output scaled by 0.5) up to latexmath:[E \approx 1] and +latexmath:[\textrm{OETF}(E) = E' \approx 0.5], with a smooth +curve up to the maximum HLG representable scene light value of "`12`": .HLG OETF (red) vs ITU OETF/2 (blue) -image::images/tf_hlg.{svgpdf}[width="{svgpdf@pdf:200pt:300}",align="center"] +image::{images}/tf_hlg.svg[width="{svgpdf@pdf:200pt:300}",align="center"] ==== <<< @@ -1165,13 +1165,13 @@ image::images/tf_hlg.{svgpdf}[width="{svgpdf@pdf:200pt:300}",align="center"] The OOTF of HLG is described as: [latexmath] -+++++ +++++ \begin{align*} R_D &= \alpha\times Y_S^{\gamma-1}\times R_S \\ G_D &= \alpha\times Y_S^{\gamma-1}\times G_S \\ B_D &= \alpha\times Y_S^{\gamma-1}\times B_S \\ \end{align*} -+++++ +++++ where _R~D~_, _G~D~_ and _B~D~_ describe the luminance of the displayed linear component in cd/m^2^ and _R~S~_, _G~S~_ and _B~S~_ describe each @@ -1179,89 +1179,89 @@ color component in scene linear light, scaled by camera exposure and normalized to the representable range. NOTE: BT.2100 notes that some legacy displays apply the -latexmath:[$\gamma$] function to each channel separately, rather than +latexmath:[\gamma] function to each channel separately, rather than to the luminance component. That is, -latexmath:[$\{R_D,G_D,B_D\}=\alpha\times\{R_S,G_S,B_S\}^\gamma+\beta$]. +latexmath:[\{R_D,G_D,B_D\}=\alpha\times\{R_S,G_S,B_S\}^\gamma+\beta]. This is an approximation to the official OOTF. _Y~S~_ is the normalized scene luminance, defined as: [latexmath] -+++++ -$$Y_S = 0.2627\times R_S + 0.6780\times G_S + 0.0593\times B_S$$ -+++++ +++++ +Y_S = 0.2627\times R_S + 0.6780\times G_S + 0.0593\times B_S +++++ -latexmath:[$\alpha$] represents adjustable user gain (display ``contrast'') +latexmath:[\alpha] represents adjustable user gain (display "`contrast`") representing _L~W~_, the nominal peak luminance of achromatic pixels. [NOTE] -====== -Versions of BT.2100 prior to BT.2100-2 incorporated a latexmath:[$\beta$] -black level offset (display ``brightness'') representing the display +==== +Versions of BT.2100 prior to BT.2100-2 incorporated a latexmath:[\beta] +black level offset (display "`brightness`") representing the display luminance of black in cd/m^2^: [latexmath] -+++++ +++++ \begin{align*} R_D &= \alpha\times Y_S^{\gamma-1}\times R_S + \beta \\ G_D &= \alpha\times Y_S^{\gamma-1}\times G_S + \beta \\ B_D &= \alpha\times Y_S^{\gamma-1}\times B_S + \beta \\ \end{align*} -+++++ +++++ -latexmath:[$\alpha$] then represented the relative display ``contrast'': +latexmath:[\alpha] then represented the relative display "`contrast`": [width="70%",options="header",cols="1,5,5"] -|============ +|==== | | Scene light normalized to [0..1] | Scene light normalized to [0..12] -| latexmath:[$\alpha$] | latexmath:[${L_W - L_B}$] | latexmath:[${{L_W - L_B}\over{\left(12\right)^\gamma}}$] -|============ +| latexmath:[\alpha] | latexmath:[{L_W - L_B}] | latexmath:[{{L_W - L_B}\over{\left(12\right)^\gamma}}] +|==== where _L~W~_ is the nominal peak luminance of the display in cd/m^2^, and _L~B~_ is the display luminance of black in cd/m^2^. -That is, in older versions of BT.2100, latexmath:[$\alpha$] represented +That is, in older versions of BT.2100, latexmath:[\alpha] represented the difference between minimum and maximum brightness, whereas in BT.2100-2 -latexmath:[$\alpha$] is independent of black level. -===== +latexmath:[\alpha] is independent of black level. +==== -latexmath:[$\gamma = 1.2$] for a nominal peak display luminance of 1000cd/m^2^. +latexmath:[\gamma = 1.2] for a nominal peak display luminance of 1000cd/m^2^. For displays with higher peak luminance or if peak luminance is reduced through a contrast control, -latexmath:[$\gamma = 1.2 + 0.42\times \textrm{log}_{10}\left({L_W\over 1000}\right)$]. +latexmath:[\gamma = 1.2 + 0.42\times \textrm{log}_{10}\left({L_W\over 1000}\right)]. For the purposes of general conversion, _L~W~_ can be assumed to be 1000cd/m^2^, and _L~B~_ can be approximated as 0, removing the constant -offset from the above equations and meaning latexmath:[$\gamma=1.2$]. +offset from the above equations and meaning latexmath:[\gamma=1.2]. <<< -==== HLG OOTF^ -1^ +==== HLG OOTF^{nbsp}-1^ The inverse OOTF for HLG can be defined as: [latexmath] -+++++ +++++ \begin{align*} R_S&=\left({{Y_D}\over\alpha}\right)^{(1/\gamma)-1}\times \left({{R_D}\over\alpha}\right) \\ G_S&=\left({{Y_D}\over\alpha}\right)^{(1/\gamma)-1}\times \left({{G_D}\over\alpha}\right) \\ B_S&=\left({{Y_D}\over\alpha}\right)^{(1/\gamma)-1}\times \left({{B_D}\over\alpha}\right) \\ Y_D&= 0.2627\times R_D + 0.6780\times G_D + 0.0593\times B_D \end{align*} -+++++ +++++ -For processing without reference to a specific display, latexmath:[$\alpha$] can be assumed +For processing without reference to a specific display, latexmath:[\alpha] can be assumed to be 1.0cd/m^2^. [NOTE] -===== -Versions of BT.2100 prior to BT.2100-2 incorporated a latexmath:[$\beta$] +==== +Versions of BT.2100 prior to BT.2100-2 incorporated a latexmath:[\beta] term into the OOTF. Using this formula from the OOTF leads to the following relationship between _Y~D~_ and _Y~S~_: [latexmath] -+++++ +++++ \begin{align*} Y_D &= 0.2627\times R_D + 0.6780\times G_D + 0.0593\times B_D \\ &= 0.2627\times(\alpha\times Y_S^{\gamma-1}\times R_S + \beta) + @@ -1273,11 +1273,11 @@ Y_D &= 0.2627\times R_D + 0.6780\times G_D + 0.0593\times B_D \\ \therefore Y_S =& \left({{Y_D-\beta}\over\alpha}\right)^{1\over\gamma}\\ Y_S^{1-\gamma} =& \left({{Y_D-\beta}\over\alpha}\right)^{(1-\gamma)/\gamma} \end{align*} -+++++ +++++ From this, the following relations can be derived: [latexmath] -+++++ +++++ \begin{align*} R_S &= {(R_D - \beta)\over{\alpha\times Y_S^{\gamma-1}}} = Y_S^{1-\gamma}\times{{(R_D-\beta)}\over\alpha} @@ -1292,15 +1292,15 @@ B_S &= {(B_D - \beta)\over{\alpha\times Y_S^{\gamma-1}}} = \left({{Y_D - \beta}\over\alpha}\right)^{(1-\gamma)/\gamma} \times \left({{B_D - \beta}\over{\alpha}}\right) \end{align*} -+++++ +++++ -For processing without knowledge of the display, latexmath:[$\alpha$] -can be treated as 1.0cd/m^2^ and latexmath:[$\beta$] can be considered +For processing without knowledge of the display, latexmath:[\alpha] +can be treated as 1.0cd/m^2^ and latexmath:[\beta] can be considered to be 0.0cd/m^2^. This simplifies the equations as follows: [latexmath] -+++++ +++++ \begin{align*} Y_S &= Y_D^{1/\gamma} \\ Y_S^{1-\gamma} &= Y_D^{(1/\gamma)-1} \\ @@ -1308,8 +1308,8 @@ R_S&=Y_D^{(1/\gamma)-1}\times R_D \\ G_S&=Y_D^{(1/\gamma)-1}\times G_D \\ B_S&=Y_D^{(1/\gamma)-1}\times B_D \end{align*} -+++++ -===== +++++ +==== <<< [[TRANSFER_HLG_EOTF_NORM]] @@ -1319,56 +1319,56 @@ The EOTF of BT.2100 HLG is defined in terms of the OETF and OOTF defined above: [latexmath] -+++++ +++++ \begin{align*} R_D &= \textrm{OOTF}\left(\textrm{OETF}^{-1}\left(\textrm{max}(0, (1-\beta)R_S' + \beta)\right)\right) \\ G_D &= \textrm{OOTF}\left(\textrm{OETF}^{-1}\left(\textrm{max}(0, (1-\beta)G_S' + \beta)\right)\right) \\ B_D &= \textrm{OOTF}\left(\textrm{OETF}^{-1}\left(\textrm{max}(0, (1-\beta)B_S' + \beta)\right)\right) \\ \beta &= \sqrt{3\times \left({{L_B}\over{L_W}}\right)^{1/\gamma}} \end{align*} -+++++ +++++ where _L~W~_ is the nominal peak luminance of the display in cd/m^2^, and _L~B~_ is the display luminance of black in cd/m^2^. [NOTE] -====== +==== Versions of BT.2100 prior to BT.2100-2 incorporated the black level -offset (display ``brightness'') latexmath:[$\beta$] into the definition +offset (display "`brightness`") latexmath:[\beta] into the definition of the OOTF, such that: [latexmath] -+++++ -$$\{R_D,G_D,B_D\}=\textrm{OOTF}(\textrm{OETF}^{-1}(\{R_S',G_S',B_S'\}))$$ -+++++ -====== +++++ +\{R_D,G_D,B_D\}=\textrm{OOTF}(\textrm{OETF}^{-1}(\{R_S',G_S',B_S'\})) +++++ +==== [[TRANSFER_HLG_IEOTF_NORM]] -==== HLG EOTF^ -1^ +==== HLG EOTF^{nbsp}-1^ -The EOTF^ -1^ can be derived as: +The EOTF^{nbsp}-1^ can be derived as: [latexmath] -+++++ +++++ \begin{align*} R_S' &= {{\textrm{OETF}\left(\textrm{OOTF}^{-1}\left(R_D'\right)\right) - \beta}\over{1-\beta}} \\ G_S' &= {{\textrm{OETF}\left(\textrm{OOTF}^{-1}\left(G_D'\right)\right) - \beta}\over{1-\beta}} \\ B_S' &= {{\textrm{OETF}\left(\textrm{OOTF}^{-1}\left(B_D'\right)\right) - \beta}\over{1-\beta}} \\ \beta &= \sqrt{3\times \left({{L_B}\over{L_W}}\right)^{1/\gamma}} \end{align*} -+++++ +++++ [NOTE] -====== +==== Versions of BT.2100 prior to BT.2100-2 incorporated the black level -offset (display ``brightness'') latexmath:[$\beta$] into the definition +offset (display "`brightness`") latexmath:[\beta] into the definition of the OOTF, such that: [latexmath] -+++++ -$$\{R_S',G_S',B_S'\} = \textrm{OETF}(\textrm{OOTF}^{-1}(\{R_D,G_D,B_D\}))$$ -+++++ -===== +++++ +\{R_S',G_S',B_S'\} = \textrm{OETF}(\textrm{OOTF}^{-1}(\{R_D,G_D,B_D\})) +++++ +==== <<< [[TRANSFER_PQ]] @@ -1386,24 +1386,24 @@ The <> Perceptual Quantization description defines the following EOTF: [latexmath] -+++++ +++++ \begin{align*} F_D &= \textrm{EOTF}(E') = 10000\times Y \\ Y &= \left(\textrm{max}(({E'}^{1\over{m_2}} - c_1),0)\over{c_2 - c_3\times {E'}^{1\over{m_2}}}\right)^{1\over{m_1}} \end{align*} -+++++ +++++ -latexmath:[$E'$] is a non-linear color channel latexmath:[$\{R',G',B'\}$] or -latexmath:[$\{L',M',S'\}$] encoded as PQ in the range [0..1]. + -latexmath:[$F_D$] is the luminance of the displayed component in cd/m^2^ -(where the luminance of an latexmath:[$\{R_D,G_D,B_D\}$] or latexmath:[$Y_D$] -or latexmath:[$I_D$] component is considered to be the luminance of the +latexmath:[E'] is a non-linear color channel latexmath:[\{R',G',B'\}] or +latexmath:[\{L',M',S'\}] encoded as PQ in the range [0..1]. + +latexmath:[F_D] is the luminance of the displayed component in cd/m^2^ +(where the luminance of an latexmath:[\{R_D,G_D,B_D\}] or latexmath:[Y_D] +or latexmath:[I_D] component is considered to be the luminance of the color with all channels set to the same value as the component). + -When latexmath:[$R'=G'=B'$] the displayed pixel is monochromatic. + -latexmath:[$Y$] is a linear color value normalized to [0..1]. +When latexmath:[R'=G'=B'] the displayed pixel is monochromatic. + +latexmath:[Y] is a linear color value normalized to [0..1]. [latexmath] -+++++ +++++ \begin{align*} m_1 &= {2610\over 16384} = 0.1593017578125 \\ m_2 &= {2523\over 4096} \times 128 = 78.84375 \\ @@ -1411,20 +1411,20 @@ c_1 &= {3424\over 4096} = 0.8359375 = c_3 - c_2 + 1 \\ c_2 &= {2413\over 4096} \times 32 = 18.8515625 \\ c_3 &= {2392\over 4096} \times 32 = 18.6875 \end{align*} -+++++ +++++ [[TRANSFER_PQ_IEOTF]] -==== PQ EOTF^ -1^ +==== PQ EOTF^{nbsp}-1^ -The corresponding EOTF^ -1^ is: +The corresponding EOTF^{nbsp}-1^ is: [latexmath] -+++++ +++++ \begin{align*} Y &= {F_D\over 10000} \\ \textrm{EOTF}^{-1}(F_D) &= \left({c_1 + c_2\times Y^{m_1}\over 1 + c_3\times Y^{m_1}}\right)^{m_2} \end{align*} -+++++ +++++ <<< ==== PQ OOTF @@ -1433,18 +1433,18 @@ The OOTF of PQ matches that of <>'s EOTF combined with <>'s OETF: [latexmath] -+++++ -$$F_D = \textrm{OOTF}(E) = \textrm{G}_{1886}(\textrm{G}_{709}(E))$$ -+++++ +++++ +F_D = \textrm{OOTF}(E) = \textrm{G}_{1886}(\textrm{G}_{709}(E)) +++++ -where _E_ is one of latexmath:[$\{R_S,G_S,B_S,Y_S,I_S\}$], the linear +where _E_ is one of latexmath:[\{R_S,G_S,B_S,Y_S,I_S\}], the linear representation of scene light scaled by camera exposure and in the range [0..1], G~1886~ is the EOTF described in <>, and G~709~ is the OETF described in <> with a scale factor of 59.5208 applied to _E_: [latexmath] -+++++ +++++ \begin{align*} F_D &= \textrm{G}_{1886}(\textrm{G}_{709}(E)) &=\ &\textrm{G}_{1886}(E') = 100\times E'^{2.4} \\ E' &= \textrm{G}_{709}(E) &= &\begin{cases} @@ -1452,19 +1452,19 @@ E' &= \textrm{G}_{709}(E) &= &\begin{cases} 267.84\times E, & 0.0003024 \geq E \geq 0 \end{cases} \end{align*} -+++++ +++++ [NOTE] ==== <> explains the derivation of the scale factor: -  +{nbsp} PQ can encode 100 times the display brightness of a standard dynamic -range (``SDR'') encoding (10000cd/m^2^ compared with the 100cd/m^2^ +range ("`SDR`") encoding (10000cd/m^2^ compared with the 100cd/m^2^ SDR reference display described in <>). High dynamic range (HDR) displays are intended to represent the -majority of scene content within a ``standard'' dynamic range, and +majority of scene content within a "`standard`" dynamic range, and exposure of a normalized SDR signal is chosen to provide suitable exposure. HDR displays offer extra capability for representation of small @@ -1476,39 +1476,39 @@ Therefore the behavior of HDR displays is intended to approximate a conventional standard dynamic range display for most of the image, while retaining the ability to encode extreme values. -  +{nbsp} As described in BT.2390, the OOTF of SDR is roughly -latexmath:[$\gamma = 1.2$] (deviating from this curve more near a 0 value), +latexmath:[\gamma = 1.2] (deviating from this curve more near a 0 value), so the maximum _scene_ light intensity that can be represented is roughly -latexmath:[$100^{1\over 1.2} \approx 46.42$] times that of a SDR encoding. +latexmath:[100^{1\over 1.2} \approx 46.42] times that of a SDR encoding. -  +{nbsp} Using exact equations from <> and <> -to create the OOTF, rather than the latexmath:[$\gamma = 1.2$] +to create the OOTF, rather than the latexmath:[\gamma = 1.2] approximation, the maximum representable scene brightness, if 1.0 is the maximum normalized SDR brightness is: [latexmath] -+++++ +++++ \begin{align*} \left({100^{1\over 2.4} + 0.099\over 1.099}\right)^{1\over 0.45} &\approx 59.5208 \end{align*} -+++++ +++++ The other constants in the G~709~ formula are derived as follows: [latexmath] -+++++ +++++ \begin{align*} {0.018\over 59.5208} &\approx 0.0003024 \\ 4.5\times 59.5208 &\approx 267.84 \end{align*} -+++++ +++++ Note that these constants differ slightly if the more accurate -latexmath:[$\alpha = 1.0993$] figure from <> is used +latexmath:[\alpha = 1.0993] figure from <> is used instead of 1.099. ==== @@ -1518,26 +1518,26 @@ instead of 1.099. The OETF of PQ is described in terms of the above OOTF: [latexmath] -+++++ -$$E' = \textrm{OETF}(E) = \textrm{EOTF}^{-1}(\textrm{OOTF}(E)) = \textrm{EOTF}^{-1}(F_D)$$ -+++++ +++++ +E' = \textrm{OETF}(E) = \textrm{EOTF}^{-1}(\textrm{OOTF}(E)) = \textrm{EOTF}^{-1}(F_D) +++++ <<< -==== PQ OOTF^ -1^ +==== PQ OOTF^{nbsp}-1^ -The PQ OOTF^ -1^ is: +The PQ OOTF^{nbsp}-1^ is: [latexmath] -+++++ -$$E=\textrm{OOTF}^{-1}(F_D)=\textrm{G}_{709}^{-1}(\textrm{G}_{1886}^{-1}(F_D))$$ -+++++ +++++ +E=\textrm{OOTF}^{-1}(F_D)=\textrm{G}_{709}^{-1}(\textrm{G}_{1886}^{-1}(F_D)) +++++ where _F~D~_, display intensity, is one of -latexmath:[$\{R_D,G_D,B_D,Y_D,I_D\}$], and +latexmath:[\{R_D,G_D,B_D,Y_D,I_D\}], and E is the corresponding normalized scene intensity. [latexmath] -+++++ +++++ \begin{align*} E' &= \textrm{G}_{1886}^{-1}(F_D) &= &\left({F_D\over 100}\right)^{1\over 2.4} \\ E &= \textrm{G}_{709}^{-1}(E') &= &\begin{cases} @@ -1545,17 +1545,17 @@ E &= \textrm{G}_{709}^{-1}(E') &= &\begin{cases} {E'\over{267.84}}, & 0.081\geq E'\geq 0 \implies {8.1}^{2.4}\geq F_D\geq 0 \end{cases} \end{align*} -+++++ +++++ [[TRANSFER_PQ_IOETF]] -==== PQ OETF^ -1^ +==== PQ OETF^{nbsp}-1^ -The PQ OETF^ -1^ is described in terms of the OOTF^ -1^: +The PQ OETF^{nbsp}-1^ is described in terms of the OOTF^{nbsp}-1^: [latexmath] -+++++ -$$E = \textrm{OETF}^{-1}(E') = \textrm{OOTF}^{-1}(\textrm{EOTF}(E')) = \textrm{OOTF}^{-1}(F_D)$$ -+++++ +++++ +E = \textrm{OETF}^{-1}(E') = \textrm{OOTF}^{-1}(\textrm{EOTF}(E')) = \textrm{OOTF}^{-1}(F_D) +++++ <<< [[TRANSFER_DCIP3]] @@ -1565,27 +1565,27 @@ $$E = \textrm{OETF}^{-1}(E') = \textrm{OOTF}^{-1}(\textrm{EOTF}(E')) = \textrm{O (applied to scaled CIE _XYZ_ values): [options="header",cols="^1,^1"] -|====== -| EOTF^ -1^ | EOTF -| latexmath:[$X' = \left({X\over{52.37}}\right)^{1\over{2.6}}$] +|==== +| EOTF^{nbsp}-1^ | EOTF +| latexmath:[X' = \left({X\over{52.37}}\right)^{1\over{2.6}}] -latexmath:[$Y' = \left({Y\over{52.37}}\right)^{1\over{2.6}}$] +latexmath:[Y' = \left({Y\over{52.37}}\right)^{1\over{2.6}}] -latexmath:[$Z' = \left({Z\over{52.37}}\right)^{1\over{2.6}}$] -| latexmath:[$X = X'^{2.6}\times 52.37$] +latexmath:[Z' = \left({Z\over{52.37}}\right)^{1\over{2.6}}] +| latexmath:[X = X'^{2.6}\times 52.37] -latexmath:[$Y = Y'^{2.6}\times 52.37$] +latexmath:[Y = Y'^{2.6}\times 52.37] -latexmath:[$Z = Z'^{2.6}\times 52.37$] -|====== +latexmath:[Z = Z'^{2.6}\times 52.37] +|==== This power function is applied directly to scaled CIE _XYZ_ color -coordinates: the ``primaries'' in DCI define the bounds of the gamut, +coordinates: the "`primaries`" in DCI define the bounds of the gamut, but the actual color encoding uses _XYZ_ coordinates. DCI scales the resulting non-linear values to the range [0..4095] prior to quantization, rounding to nearest. -NOTE: ``Display P3'' uses the <>, +NOTE: "`Display P3`" uses the <>, modified in some implementations to have more accurate constants (see the section on the derivation of the sRGB constants). @@ -1596,39 +1596,39 @@ section on the derivation of the sRGB constants). regional TV standard variants; an updated list of variant codes used by country is defined in <>. This standard, along with <>, documents a -simple EOTF power function with latexmath:[$\gamma = 2.2$] for NTSC display +simple EOTF power function with latexmath:[\gamma = 2.2] for NTSC display devices. [options="header",cols="^1,^1"] -|====== -| EOTF^ -1^ | EOTF -| latexmath:[$R' = R^{1\over{2.2}}$] +|==== +| EOTF^{nbsp}-1^ | EOTF +| latexmath:[R' = R^{1\over{2.2}}] -latexmath:[$G' = G^{1\over{2.2}}$] +latexmath:[G' = G^{1\over{2.2}}] -latexmath:[$B' = B^{1\over{2.2}}$] -| latexmath:[$R = R'^{2.2}$] +latexmath:[B' = B^{1\over{2.2}}] +| latexmath:[R = R'^{2.2}] -latexmath:[$G = G'^{2.2}$] +latexmath:[G = G'^{2.2}] -latexmath:[$B = B'^{2.2}$] -|====== +latexmath:[B = B'^{2.2}] +|==== -This value of latexmath:[$\gamma$] is also used for N/PAL signals in the +This value of latexmath:[\gamma] is also used for N/PAL signals in the Eastern Republic of Uruguay, and was also adopted by <>. Combined with the reference in <> to a -latexmath:[$\gamma = 2.2$] being used in ``older documents'', this +latexmath:[\gamma = 2.2] being used in "`older documents`", this suggests a linear design OOTF for NTSC systems. <>, which partly replaced BT.470, also describes an -``assumed gamma of display device'' of 2.2 for PAL and SECAM systems; -this is distinct from the latexmath:[$\gamma = 2.8$] value listed in +"`assumed gamma of display device`" of 2.2 for PAL and SECAM systems; +this is distinct from the latexmath:[\gamma = 2.8] value listed in <>. Combined with the <> which approximates -latexmath:[$\gamma = {1\over{2.0}}$], the PAL OOTF retains a -latexmath:[$\gamma \approx 1.1$] when this value of -latexmath:[$\gamma = 2.2$] is used for the EOTF, similar to the figure +latexmath:[\gamma = {1\over{2.0}}], the PAL OOTF retains a +latexmath:[\gamma \approx 1.1] when this value of +latexmath:[\gamma = 2.2] is used for the EOTF, similar to the figure described under <>. In contrast, <> also includes @@ -1640,29 +1640,29 @@ Hence the new NTSC formulation also assumes a linear OOTF. [[TRANSFER_LEGACY_PAL_OETF]] === Legacy PAL OETF -<>, ``Video-frequency characteristics of a television +<>, "`Video-frequency characteristics of a television system to be used for the international exchange of programmes between -countries that have adopted 625-line colour or monochrome systems'', defines -that the ``gamma of the picture signal'' should be ``approximately 0.4''. +countries that have adopted 625-line colour or monochrome systems`", defines +that the "`gamma of the picture signal`" should be "`approximately 0.4`". The reciprocal of this value is 2.5. -That is, this standard defines an approximate OETF and OETF^ -1^ for +That is, this standard defines an approximate OETF and OETF^{nbsp}-1^ for PAL content: [options="header",cols="^1,^1"] -|====== -| OETF | OETF^ -1^ -| latexmath:[$R' \approx R^{0.4}$] +|==== +| OETF | OETF^{nbsp}-1^ +| latexmath:[R' \approx R^{0.4}] -latexmath:[$G' \approx G^{0.4}$] +latexmath:[G' \approx G^{0.4}] -latexmath:[$B' \approx B^{0.4}$] -| latexmath:[$R \approx R'^{2.5}$] +latexmath:[B' \approx B^{0.4}] +| latexmath:[R \approx R'^{2.5}] -latexmath:[$G \approx G'^{2.5}$] +latexmath:[G \approx G'^{2.5}] -latexmath:[$B \approx B'^{2.5}$] -|====== +latexmath:[B \approx B'^{2.5}] +|==== [[TRANSFER_LEGACY_PAL_EOTF]] === Legacy PAL 625-line EOTF @@ -1672,56 +1672,56 @@ lists a number of regional TV standard variants; an updated list of variant codes used by country is defined in <>. This specification describes a simple EOTF power function with -latexmath:[$\gamma_{\textrm{EOTF}} = 2.8$] for most PAL and SECAM display devices: +latexmath:[\gamma_{\textrm{EOTF}} = 2.8] for most PAL and SECAM display devices: [options="header",cols="^1,^1"] -|====== -| EOTF^ -1^ | EOTF -| latexmath:[$R' = R^{1\over{2.8}}$] +|==== +| EOTF^{nbsp}-1^ | EOTF +| latexmath:[R' = R^{1\over{2.8}}] -latexmath:[$G' = G^{1\over{2.8}}$] +latexmath:[G' = G^{1\over{2.8}}] -latexmath:[$B' = B^{1\over{2.8}}$] -| latexmath:[$R = R'^{2.8}$] +latexmath:[B' = B^{1\over{2.8}}] +| latexmath:[R = R'^{2.8}] -latexmath:[$G = G'^{2.8}$] +latexmath:[G = G'^{2.8}] -latexmath:[$B = B'^{2.8}$] -|====== +latexmath:[B = B'^{2.8}] +|==== -NOTE: Poynton describes a latexmath:[$\gamma$] of 2.8 as being ``unrealistically -high'' for actual CRT devices. +NOTE: Poynton describes a latexmath:[\gamma] of 2.8 as being "`unrealistically +high`" for actual CRT devices. Combined with the <> with -latexmath:[$\gamma_{\textrm{EOTF}} = 0.4$], the described system OOTF is: +latexmath:[\gamma_{\textrm{EOTF}} = 0.4], the described system OOTF is: [latexmath] -+++++ +++++ \begin{align*} R_{display} &\approx R_{scene}^{2.8\over{2.5}}\\ G_{display} &\approx G_{scene}^{2.8\over{2.5}}\\ B_{display} &\approx B_{scene}^{2.8\over{2.5}} \end{align*} -+++++ +++++ -Or latexmath:[$\gamma_{\textrm{OOTF}} \approx 1.12$]. +Or latexmath:[\gamma_{\textrm{OOTF}} \approx 1.12]. -The value of latexmath:[$\gamma_{\textrm{EOTF}} = 2.8$] is described in BT.470-6 as being -chosen for ``an overall system gamma'' (OOTF power function exponent) of -``approximately 1.2''; this suggests that the ``approximately 0.4'' exponent in -<> should be interpreted as nearer to latexmath:[${1.2\over{2.8}} -\approx 0.43$], or at least that there was enough variation in early devices for +The value of latexmath:[\gamma_{\textrm{EOTF}} = 2.8] is described in BT.470-6 as being +chosen for "`an overall system gamma`" (OOTF power function exponent) of +"`approximately 1.2`"; this suggests that the "`approximately 0.4`" exponent in +<> should be interpreted as nearer to latexmath:[{1.2\over{2.8}} +\approx 0.43], or at least that there was enough variation in early devices for precise formulae to be considered irrelevant. [NOTE] ==== -The EOTF power function of latexmath:[$\gamma_{\textrm{EOTF}} = 2.2$] described in +The EOTF power function of latexmath:[\gamma_{\textrm{EOTF}} = 2.2] described in <> combines with the <> described in -<> (which approximates latexmath:[$\gamma_{\textrm{OETF}} \approx 0.5$]) -to give a similar system latexmath:[$\gamma_{\textrm{OOTF}} \approx 1.1$]. +<> (which approximates latexmath:[\gamma_{\textrm{OETF}} \approx 0.5]) +to give a similar system latexmath:[\gamma_{\textrm{OOTF}} \approx 1.1]. As described <>, the <> combined with the <> EOTF results in a more strongly non-linear -latexmath:[$\gamma_{\textrm{OOTF}} \approx {2.4\over{2.0}} = 1.2$]. +latexmath:[\gamma_{\textrm{OOTF}} \approx {2.4\over{2.0}} = 1.2]. ==== <<< @@ -1732,41 +1732,45 @@ The <>, formerly SMPTE240M, interim standard for HDTV defines the following OETF: [latexmath] -++++++ - $$R' = \begin{cases} - R \times 4, & 0 \leq R < 0.0228 \\ - 1.1115 \times R^{0.45} - 0.1115, & 1 \geq R \geq 0.0228 - \end{cases}$$ - $$G' = \begin{cases} - G \times 4, & 0 \leq G < 0.0228 \\ - 1.1115 \times G^{0.45} - 0.1115, & 1 \geq G \geq 0.0228 - \end{cases}$$ - $$B' = \begin{cases} - B \times 4, & 0 \leq B < 0.0228 \\ - 1.1115 \times B^{0.45} - 0.1115, & 1 \geq B \geq 0.0228 - \end{cases}$$ -++++++ +++++ +\begin{align*} + R' &= \begin{cases} + R \times 4, & 0 \leq R < 0.0228 \\ + 1.1115 \times R^{0.45} - 0.1115, & 1 \geq R \geq 0.0228 + \end{cases} \\ + G' &= \begin{cases} + G \times 4, & 0 \leq G < 0.0228 \\ + 1.1115 \times G^{0.45} - 0.1115, & 1 \geq G \geq 0.0228 + \end{cases} \\ + B' &= \begin{cases} + B \times 4, & 0 \leq B < 0.0228 \\ + 1.1115 \times B^{0.45} - 0.1115, & 1 \geq B \geq 0.0228 + \end{cases} +\end{align*} +++++ Like <>, ST-240 defines a linear OOTF. -Therefore the above relationship also holds for the EOTF^ -1^. - -The EOTF, and also OETF^ -1^, is: - -[latexmath] -++++++ - $$R = \begin{cases} - {R' \over 4}, & 0 \leq R < 0.0913 \\ - \left({R' + 0.1115\over 1.1115}\right)^{1\over 0.45} - 0.1115, & 1 \geq R' \geq 0.0228 - \end{cases}$$ - $$G = \begin{cases} - {G' \over 4}, & 0 \leq R < 0.0913 \\ - \left({G' + 0.1115\over 1.1115}\right)^{1\over 0.45} - 0.1115, & 1 \geq G' \geq 0.0228 - \end{cases}$$ - $$B = \begin{cases} - {B' \over 4}, & 0 \leq R < 0.0913 \\ - \left({B' + 0.1115\over 1.1115}\right)^{1\over 0.45} - 0.1115, & 1 \geq B' \geq 0.0228 - \end{cases}$$ -++++++ +Therefore the above relationship also holds for the EOTF^{nbsp}-1^. + +The EOTF, and also OETF^{nbsp}-1^, is: + +[latexmath] +++++ +\begin{align*} + R &= \begin{cases} + {R' \over 4}, & 0 \leq R < 0.0913 \\ + \left({R' + 0.1115\over 1.1115}\right)^{1\over 0.45} - 0.1115, & 1 \geq R' \geq 0.0228 + \end{cases} \\ + G &= \begin{cases} + {G' \over 4}, & 0 \leq R < 0.0913 \\ + \left({G' + 0.1115\over 1.1115}\right)^{1\over 0.45} - 0.1115, & 1 \geq G' \geq 0.0228 + \end{cases} \\ + B &= \begin{cases} + {B' \over 4}, & 0 \leq R < 0.0913 \\ + \left({B' + 0.1115\over 1.1115}\right)^{1\over 0.45} - 0.1115, & 1 \geq B' \geq 0.0228 + \end{cases} +\end{align*} +++++ [[TRANSFER_ADOBERGB]] === Adobe RGB (1998) transfer functions @@ -1776,26 +1780,26 @@ function between nonlinear encoding and linear light intensity (notable for not including a linear component): [latexmath] -+++++ +++++ \begin{align*} R &= R'^{2.19921875} \\ G &= G'^{2.19921875} \\ B &= B'^{2.19921875} \end{align*} -+++++ +++++ -2.19921875 is obtained from latexmath:[$2{51\over{256}}$] or hexadecimal 2.33. +2.19921875 is obtained from latexmath:[2{51\over{256}}] or hexadecimal 2.33. Therefore the inverse transfer function between linear light intensity and nonlinear encoding is: [latexmath] -+++++ +++++ \begin{align*} R' &= R^{256\over{563}} \\ G' &= G^{256\over{563}} \\ B' &= B^{256\over{563}} \end{align*} -+++++ +++++ <<< [[TRANSFER_SLOG]] @@ -1804,19 +1808,19 @@ B' &= B^{256\over{563}} The Sony <> OETF is defined for each color channel as: [latexmath] -+++++ -$$y = (0.432699 \times \textrm{log}_{10}(t + 0.037584) + 0.616596) + 0.03$$ -+++++ +++++ +y = (0.432699 \times \textrm{log}_{10}(t + 0.037584) + 0.616596) + 0.03 +++++ Linear camera input scaled by exposure _t_ ranges from 0 to 10.0; _y_ is the non-linear encoded value. -The OETF^ -1^ is: +The OETF^{nbsp}-1^ is: [latexmath] -+++++ -$$Y = 10.0^{t - 0.616596 - 0.03\over 0.432699} - 0.037584$$ -+++++ +++++ +Y = 10.0^{t - 0.616596 - 0.03\over 0.432699} - 0.037584 +++++ The encoded non-linear value _t_ ranges from 0 to 1.09; _Y_ is the linear scene light. @@ -1827,29 +1831,29 @@ linear scene light. <> defines the following OETF: [latexmath] -+++++ +++++ \begin{align*} y &= \begin{cases} (0.432699\times\textrm{log}_{10}\left({155.0\times x\over 219.0} + 0.037584\right) + 0.616596 + 0.03, &x \geq 0 \\ x \times 3.53881278538813 + 0.030001222851889303, &x < 0 \end{cases} \end{align*} -+++++ +++++ _x_ is the IRE in scene-linear space. + _y_ is the IRE in S-Log2 space. -The OETF^ -1^ is: +The OETF^{nbsp}-1^ is: [latexmath] -+++++ +++++ \begin{align*} y &= \begin{cases} {219.0 \times 10.0^{x - 0.616596 - 0.03\over 0.432699}\over 155.0}, &x \geq 0.030001222851889303 \\ {x - 0.030001222851889303\over 3.53881278538813}, &x < 0.030001222851889303 \end{cases} \end{align*} -+++++ +++++ _x_ is the IRE in S-Log2 space. + _y_ is the IRE in scene-linear space. @@ -1865,13 +1869,13 @@ For each linear color channel _lin~AP1~_ transformed to the ACEScc primaries, the _ACEScc_ non-linear encoding is: [latexmath] -+++++ - $$ACEScc = \begin{cases} - {{\textrm{log}_\textrm{2}(2^{-16})+9.72}\over{17.52}}, & lin_{AP1} \leq 0 \\ - {{\textrm{log}_\textrm{2}(2^{-16} + lin_{AP1}\times 0.5) + 9.72}\over{17.52}}, & lin_{AP1} < 2^{-15} \\ - {{\textrm{log}_\textrm{2}(lin_{AP1})+9.72}\over{17.52}}, & lin_{AP1} \geq 2^{-15} - \end{cases}$$ -+++++ +++++ +ACEScc = \begin{cases} + {{\textrm{log}_\textrm{2}(2^{-16})+9.72}\over{17.52}}, & lin_{AP1} \leq 0 \\ + {{\textrm{log}_\textrm{2}(2^{-16} + lin_{AP1}\times 0.5) + 9.72}\over{17.52}}, & lin_{AP1} < 2^{-15} \\ + {{\textrm{log}_\textrm{2}(lin_{AP1})+9.72}\over{17.52}}, & lin_{AP1} \geq 2^{-15} +\end{cases} +++++ [[TRANSFER_ACESCCT]] === ACEScct transfer function @@ -1882,9 +1886,9 @@ For each linear color channel _lin~AP1~_ transformed to the ACEScc primaries, the _ACEScct_ non-linear encoding is: [latexmath] -+++++ - $$ACEScct = \begin{cases} - {10.5402377416545 \times lin_{AP1} + 0.0729055341958355}, & lin_{AP1} \leq 0.0078125 \\ - {{\textrm{log}_2(lin_{AP1})+9.72}\over{17.52}}, & lin_{AP1} > 0.0078125 - \end{cases}$$ -+++++ +++++ +ACEScct = \begin{cases} + {10.5402377416545 \times lin_{AP1} + 0.0729055341958355}, & lin_{AP1} \leq 0.0078125 \\ + {{\textrm{log}_2(lin_{AP1})+9.72}\over{17.52}}, & lin_{AP1} > 0.0078125 +\end{cases} +++++ diff --git a/compformats.txt b/compformats.txt deleted file mode 100644 index 8bfe66a..0000000 --- a/compformats.txt +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2014-2019 The Khronos Group Inc. -// Copyright notice at https://www.khronos.org/registry/speccopyright.html - -include::compintro.txt[] - -include::s3tc.txt[] - -include::rgtc.txt[] - -include::bptc.txt[] - -include::etc1.txt[] - -include::etc2.txt[] - -include::astc.txt[] - -include::pvrtc.txt[] diff --git a/config/README.adoc b/config/README.adoc new file mode 100644 index 0000000..db44354 --- /dev/null +++ b/config/README.adoc @@ -0,0 +1,39 @@ +// Copyright 2015-2024 The Khronos Group Inc. +// SPDX-License-Identifier: CC-BY-4.0 + += Data Format Asciidoc Configuration Files + +== Support for Math + +Asciidoctor is customized to insert KaTeX ` - - - diff --git a/config/docbook-xsl/common.xsl b/config/docbook-xsl/common.xsl deleted file mode 100644 index eccd619..0000000 --- a/config/docbook-xsl/common.xsl +++ /dev/null @@ -1,112 +0,0 @@ - - - - - - - - - - 1 - 0 - - - - - - -images/icons/ -0 - - - - 0 - #E0E0E0 - - - -images/icons/ - - - margin-left: 0; margin-right: 10%; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -article toc,title -book toc,title,figure,table,example,equation - - -chapter toc,title -part toc,title -preface toc,title -qandadiv toc -qandaset toc -reference toc,title -sect1 toc -sect2 toc -sect3 toc -sect4 toc -sect5 toc -section toc -set toc,title - - - -article nop -book nop - - - - - diff --git a/config/docbook-xsl/pdf.xsl b/config/docbook-xsl/pdf.xsl deleted file mode 100644 index 3df11e7..0000000 --- a/config/docbook-xsl/pdf.xsl +++ /dev/null @@ -1,29 +0,0 @@ - - - - \begin{alltt} - \normalfont{} - - \end{alltt} - - - - - \pagebreak[4] - - - - - - \newline - - - - - \begin{center} - \line(1,0){444} - \end{center} - - - - diff --git a/config/docbook-xsl/xhtml.xsl b/config/docbook-xsl/xhtml.xsl deleted file mode 100644 index 4990d13..0000000 --- a/config/docbook-xsl/xhtml.xsl +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - diff --git a/config/fonts/mplus1p-regular-fallback.ttf b/config/fonts/mplus1p-regular-fallback.ttf new file mode 100644 index 0000000..d9d2e3d Binary files /dev/null and b/config/fonts/mplus1p-regular-fallback.ttf differ diff --git a/config/katex_replace.rb b/config/katex_replace.rb new file mode 100644 index 0000000..d15a2c4 --- /dev/null +++ b/config/katex_replace.rb @@ -0,0 +1,11 @@ +# Copyright 2016-2024 The Khronos Group Inc. +# +# SPDX-License-Identifier: Apache-2.0 + +#require 'asciidoctor/extensions' unless RUBY_ENGINE == 'opal' +RUBY_ENGINE == 'opal' ? (require 'katex_replace/extension') : (require_relative 'katex_replace/extension') + +# All the inline macros we need +Asciidoctor::Extensions.register do + postprocessor ReplaceMathjaxWithKatex +end diff --git a/config/katex_replace/extension.rb b/config/katex_replace/extension.rb new file mode 100644 index 0000000..f5a63de --- /dev/null +++ b/config/katex_replace/extension.rb @@ -0,0 +1,44 @@ +# Copyright 2016-2024 The Khronos Group Inc. +# +# SPDX-License-Identifier: Apache-2.0 + +require 'asciidoctor/extensions' unless RUBY_ENGINE == 'opal' + +include ::Asciidoctor + +class ReplaceMathjaxWithKatex < Extensions::Postprocessor + + MathJaXScript = / +' + + hide_script = '' + + output.sub! /(?=<\/head>)/, loaded_script + output.sub! /(
)/, '\1' + hide_script + output.sub! /(?=
\n" + end + output + end +end diff --git a/config/makedocinfologo b/config/makedocinfologo new file mode 100755 index 0000000..c166368 --- /dev/null +++ b/config/makedocinfologo @@ -0,0 +1,23 @@ +#!/bin/bash +# Copyright 2014-2024 The Khronos Group Inc. +# SPDX-License-Identifier: Apache-2.0 + +# makedocinfologo - generate HTML docinfo file from an SVG image. +# Usage: makedocinfologo file.svg alt-text > docinfo-header.html +# Example: makedocinfologo ../images/vulkansc-unscaled.svg "Vulkan SC Logo" > vulkansc/docinfo-header.html + +file=$1 +if test ! -r "$file" ; then + echo "Cannot read SVG file: $file" > /dev/stderr + exit 1 +fi +#echo "file: $file" > /dev/stderr +alt=${2-$file} +#echo "alt: $alt" > /dev/stderr + +echo '
' +echo -n ' '$2'' +echo ' ' +echo '
' diff --git a/config/mathjax-asciidoc.conf b/config/mathjax-asciidoc.conf deleted file mode 100644 index 1ba9ce1..0000000 --- a/config/mathjax-asciidoc.conf +++ /dev/null @@ -1,19 +0,0 @@ -# adoc.conf - add some asciidoc-specific (non-a2x) config stuff for html5.conf - -# Override html5.conf definition -[xref-inlinemacro] -xref -[xref-inlinemacro] -{0} -[xref2-inlinemacro] -{1} -[link-inlinemacro] -link{target} - -[latexmath-inlinemacro] -{passtext} - -[docinfo] -ifdef::mathjax[] -include1::mathjax.js[] -endif::[] diff --git a/config/mathjax-docbook.conf b/config/mathjax-docbook.conf deleted file mode 100644 index f8f0edc..0000000 --- a/config/mathjax-docbook.conf +++ /dev/null @@ -1,89 +0,0 @@ -# testdb.conf - override some Docbook-specific config stuff - -# Override docbook45 definition to not encapsulate LaTeX math -# This requires some cleverness in the latexmath macros to include -# the equation source in the alt block for PDF output, and in -# a Docbook block tag otherwise, using the a2x-format variable. - -# a2x-format can be one of: chunked, docbook, dvi, epub, htmlhelp, manpage, -# pdf (default), ps, tex, text, xhtml. - -[blockdef-pass] -ifeval::["{a2x-format}"=="pdf"] -latexmath-style=template="latexmathblock",subs=() -endif::[] -ifeval::["{a2x-format}"!="pdf"] -latexmath-style=template="latexmathblock" -subs=specialcharacters -endif::[] - -[latexmath-inlinemacro] - -ifeval::["{a2x-format}"=="pdf"] - -endif::[] - -ifeval::["{a2x-format}"!="pdf"] -{passtext} -endif::[] - - - -[latexmath-blockmacro] - -ifeval::["{a2x-format}"=="pdf"] - -endif::[] - -ifeval::["{a2x-format}"!="pdf"] -{passtext} -endif::[] - - - -[latexmathblock] -{title#}{title} -{title%} -ifeval::["{a2x-format}"=="pdf"] - -endif::[] - -ifeval::["{a2x-format}"!="pdf"] -| -endif::[] - -{title#} -{title%} - -# Attempt to turn HTML links into just the prefix, like the PDF version. Failure. Retained for reference. -# [link-inlinemacro] -# ifdef::basebackend-docbook[] -# {target} -# endif::basebackend-docbook[] -# ifdef::basebackend-xhtml[] -# {target} -# endif::basebackend-xhtml[] -# -# [xref-inlinemacro] -# ifdef::basebackend-docbook[] -# {0} -# {2%} -# endif::basebackend-docbook[] -# ifdef::basebackend-xhtml[] -# {2%} -# endif::basebackend-xhtml[] -# ifdef::basebackend-html[] -# {2%} -# endif::basebackend-html[] -# -# [xref2-inlinemacro] -# ifdef::basebackend-docbook[] -# {2} -# {2%} -# endif::basebackend-docbook[] -# ifdef::basebackend-xhtml[] -# {2%} -# endif::basebackend-xhtml[] -# ifdef::basebackend-html[] -# {2%} -# endif::basebackend-html[] diff --git a/config/mathjax.js b/config/mathjax.js deleted file mode 100644 index f079ab9..0000000 --- a/config/mathjax.js +++ /dev/null @@ -1,8 +0,0 @@ - - diff --git a/config/open_listing_block.rb b/config/open_listing_block.rb new file mode 100644 index 0000000..e617631 --- /dev/null +++ b/config/open_listing_block.rb @@ -0,0 +1,28 @@ +# Copyright 2023-2024 The Khronos Group Inc. +# SPDX-License-Identifier: Apache-2.0 + +# open_listing_block - allows a listing block to masquerade as an open +# block: +# +# [open] +# ---- +# (block content) +# ---- +# +# This allows nesting arbitrary open blocks inside 'refpage' open blocks. + +require 'asciidoctor/extensions' unless RUBY_ENGINE == 'opal' + +include ::Asciidoctor + +Asciidoctor::Extensions.register do + block do + named :open + on_context :listing + process do |parent, reader, attrs| + wrapper = create_open_block parent, [], {} + parse_content wrapper, reader + wrapper + end + end +end diff --git a/config/quiet-include-failure.rb b/config/quiet-include-failure.rb new file mode 100644 index 0000000..9342f3f --- /dev/null +++ b/config/quiet-include-failure.rb @@ -0,0 +1,30 @@ +# Copyright 2021-2024 The Khronos Group Inc. +# +# SPDX-License-Identifier: Apache-2.0 + +require 'asciidoctor/extensions' unless RUBY_ENGINE == 'opal' + +include Asciidoctor + +class ExistsIncludeProcessor < Extensions::IncludeProcessor + def handles? target + # Only handle files which do not exist + # This relies on the full absolute path to every include file being + # given, since relative directory information exists only in the + # process method. + + not File.exist? target + end + + def process doc, reader, target, attributes + # If we reach this point, we have been asked to include a file which + # does not exist. Do nothing, instead of raising an error. + + reader + end +end + +Extensions.register do + include_processor ExistsIncludeProcessor +end + diff --git a/config/rouge-extend-css.rb b/config/rouge-extend-css.rb new file mode 100644 index 0000000..c19dd74 --- /dev/null +++ b/config/rouge-extend-css.rb @@ -0,0 +1,60 @@ +# Copyright 2021-2024 The Khronos Group Inc. +# +# SPDX-License-Identifier: Apache-2.0 + +# Khronos overrides for Rouge 'github' theme CSS for accessibility. +# See (note that this code is evolving, works as of asciidoctor 2.0.12): +# https://github.com/asciidoctor/asciidoctor/blob/main/lib/asciidoctor/syntax_highlighter/rouge.rb + +include ::Asciidoctor + +class ExtendedRougeSyntaxHighlighter < (Asciidoctor::SyntaxHighlighter.for 'rouge') + register_for 'rouge' + + # Insert rouge stylesheet from super + # Then replace many 'github' theme colors for accessibility compliance + # It would be better to use rouge's stylesheet factory, if it has one + def docinfo location, doc, opts + overrides = %() + + # super can return either