165 Commits
2.1.0 ... 2.1.2

Author SHA1 Message Date
b1a90f3601 Update version number. 2020-08-23 23:27:21 -07:00
72dd3db723 Update changelog. 2020-08-23 23:27:09 -07:00
4754e526ce Target AVX2 in all projects and configurations. 2020-08-23 23:24:25 -07:00
f7e037d1c1 Fix build error. 2020-08-23 23:20:52 -07:00
b4da3c68f0 Update version number. 2020-08-23 23:18:24 -07:00
46d1179b17 Fix version number. 2020-08-23 22:55:58 -07:00
e5cf10de0e Remove specialized fast compressor. 2020-08-23 22:55:49 -07:00
13121bf32e Update README.md
Add badges.
2020-08-23 22:26:58 -07:00
9870cfbf90 Merge pull request #329 from MaddTheSane/patch-1
Update Half.cpp
2020-08-23 22:04:10 -07:00
e4301b3df7 Merge branch 'master' of https://github.com/castano/nvidia-texture-tools 2020-08-23 21:58:56 -07:00
831c8e6667 Upgrade ICBC to 1.05 2020-08-23 21:58:18 -07:00
be5a305081 Update Half.cpp
Replace old(?) usage of NV_CC_GCC with NV_CC_GNUC
2020-08-23 18:03:02 -06:00
5932492d8a Add release build. 2020-08-23 16:02:06 -07:00
09164a5fd3 Cleanup configuration. 2020-08-23 15:59:57 -07:00
2ab73d8cd5 Fix release instructions. 2020-08-23 15:53:09 -07:00
a4712cff20 Remove unused code.
Remove jai-specific workaround.
Various cleanups.
2020-08-23 15:39:54 -07:00
93146ffc73 Update svn:ignore properties. 2020-08-23 15:26:09 -07:00
dd6b750942 Update release instructions. 2020-08-23 15:23:38 -07:00
b06d5aba59 Remove support for some external compressors. 2020-08-23 15:21:54 -07:00
9d93fccb37 Cleanup. 2020-08-23 15:20:42 -07:00
2b3ffac418 Add sublime and vscode projects. 2020-08-23 15:20:01 -07:00
7525d356a0 Update buildpkg script 2020-08-23 15:16:47 -07:00
cb21ee18a1 Remove unused dependencies. 2020-08-23 15:15:45 -07:00
e5be4a615f Remove unused scripts. 2020-08-23 15:14:55 -07:00
c4aefe530c Remove unused scripts. 2020-08-23 15:13:22 -07:00
a77953a306 Update copyright. 2020-08-23 14:47:27 -07:00
6b9a6abccb Fix github action 2020-08-23 14:46:54 -07:00
8dc9df25d7 Create build.yml 2020-08-23 14:17:31 -07:00
614a7a4b82 Update README.md
Update build instructions.
2020-08-23 13:57:17 -07:00
61935ffa08 Update README.md
Provide links for source path.
2020-08-23 13:54:25 -07:00
6f3d02deab Merge pull request #328 from akb825/linux-fix-2
Linux build fixes.
2020-08-19 10:28:31 -07:00
cfa3fc528e Linux build fixes.
* Avoid hacks to get an empty VA list, which doesn't work with all
  compilers.
* Fix for isnan() on some versions of GCC.
2020-08-16 21:26:37 -07:00
b4cf9bc3f6 Merge pull request #324 from tepGithub/master
Add some support for uncompressed textures for ktx
2020-07-28 10:24:19 -07:00
967278d579 Fix tab/whitespace 2 2020-07-28 10:16:25 -07:00
aa8514e65d Fix tab/whitespace 2020-07-28 10:15:34 -07:00
b4eb9c5972 Added some support for uncompressed texture for ktx 2020-07-28 10:07:16 -07:00
eb34681ce8 Merge pull request #308 from voroskoi/musl
Musl build fixes
2020-07-13 16:54:35 -07:00
aeb84b5ffa Merge pull request #322 from leper/fix_va_list_vcpp
Fix build on VC++. Refs #309.
2020-07-13 16:17:19 -07:00
d73335fb82 Fix build on VC++. Refs #309.
This was broken by 831d8e1a91.
2020-07-10 19:01:56 +02:00
1aa1b038e8 Merge pull request #309 from leper/aarch64
Fix build on AArch64. Fixes #298.
2020-07-09 17:14:13 -07:00
26a56414c5 Do not include etcpack & rgetc in the build. 2020-07-07 09:56:04 -07:00
8baac9b111 Fix mac build error. 2020-07-06 13:28:18 -07:00
2bd1ed1ba7 Use AVX2 by default. 2020-07-06 11:13:05 -07:00
8fb22e951e Fix error reported by #312. 2020-07-06 11:04:47 -07:00
ea53e0b1ee Update vs2017 project files. 2020-07-06 10:33:17 -07:00
721cc85da7 Remove old projects. 2020-07-06 10:31:30 -07:00
446e4b4611 Remove unused dependencies. 2020-07-06 10:08:14 -07:00
0be40976a2 Remove unused external dependencies. 2020-07-06 10:07:14 -07:00
bf4799c9ac Fix build errors. 2020-07-06 10:00:04 -07:00
bfd1a38a86 Updates for new icbc interface. 2020-07-05 23:09:46 -07:00
ba3dbe32df KTX output fixes. 2020-07-05 23:09:29 -07:00
7aebf0c251 ETC compression experiments. 2020-07-05 23:08:57 -07:00
c87706f2a4 Remove unused files. 2020-07-05 23:08:22 -07:00
e5b93bbfe8 Upgrade icbc 2020-07-05 23:07:21 -07:00
d09dd24ce9 Remove unused files. 2020-07-05 23:06:48 -07:00
7894e9e6f8 Upgrade rgbcx. 2020-07-05 23:05:50 -07:00
07d9ab7860 Add goofy_tc. 2020-07-05 23:05:17 -07:00
4ff7af50ca Upgrade CMP Core. 2020-07-05 23:05:07 -07:00
1e06539012 Create FUNDING.yml 2020-06-12 23:01:14 -07:00
fdfbfb2552 Update to latest icbc version. 2020-06-07 20:02:14 -07:00
0f98a936f8 Fix rgbe conversion routines thanks to Charles Bloom. http://cbloomrants.blogspot.com/2020/06/widespread-error-in-radiance-hdr-rgbe.html 2020-06-07 19:46:35 -07:00
3e034d2de1 Merge pull request #314 from r-a-sattarov/master
Added compiler check for support of C++11 standard
2020-04-26 09:39:57 -07:00
0297a00ebc Added compiler check for support of C ++ 11 standard 2020-04-26 15:23:47 +03:00
8e64503338 Update vc projects.
Disable RGETC for now.
2020-04-13 18:44:57 -07:00
a671567596 Update nvtt to use icbc library. 2020-04-13 18:01:33 -07:00
daff42781d Work toward packaging dxt1 compressor as a single header library. 2020-04-05 12:22:25 -07:00
1a6e70c9a0 Cleanup. Assume static linking. 2020-04-05 12:20:35 -07:00
860b639492 Remove unused code. 2020-04-04 10:40:58 -07:00
52e065d66a Update benchmark with rgbcx. 2020-04-04 10:21:00 -07:00
0b15c58692 Fix more build errors. 2020-04-04 10:18:58 -07:00
504ecc8e10 Fix build errors. 2020-04-04 10:17:01 -07:00
f68d894b8b Tweak endpoint refinement. 2020-03-30 16:35:17 -07:00
5eac5a4859 Experiment with endpoint refinement. Add Rich's encoder, not functional yet. 2020-03-30 10:13:59 -07:00
ca3871a28c More cleanups! 2020-03-30 10:12:29 -07:00
adce1a00da More cleanups. Assume static linking. 2020-03-30 10:09:31 -07:00
7f9c87713a Minor cleanups in nvmath. 2020-03-30 10:07:15 -07:00
4f0ecc4506 Add defer helper. 2020-03-30 10:06:10 -07:00
e5740ccb32 Add Rich's improved tie breaking change. 2020-03-30 10:04:35 -07:00
9a16bebf8f Add external libs for comparisons and benchmarks. 2020-03-23 10:07:38 -07:00
4a33d1ac75 Add baboon image to waterloo image set. 2020-03-23 10:05:31 -07:00
9009962054 Minor cleanups and some experiments. 2020-03-23 10:03:19 -07:00
97723db794 Rename internal squish library to nvsquish to avoid conflicts. 2020-03-23 10:02:07 -07:00
4d47c0d2fc Comment out debug code. 2020-03-23 10:01:12 -07:00
5d7a761d6b Handle more DDS formats in Surface::load(). 2020-03-23 10:00:40 -07:00
a3ae50b50f Update stb_image. 2020-03-23 09:59:44 -07:00
6dd3687be1 Minor cleanup. 2020-03-23 09:58:56 -07:00
3a99af11d7 Fix initialization of PVR texture header. 2020-03-23 09:58:19 -07:00
e5b763b075 Minor fixes. 2020-03-23 09:54:09 -07:00
c8a6e2c6cc Update SDK version. 2020-03-23 09:50:11 -07:00
9e36d6747b Update stb libraries. 2020-03-23 09:49:15 -07:00
831d8e1a91 Fix build on AArch64. Fixes #298. 2020-03-16 21:08:18 +01:00
99bcaf719c Use isnan() instead of isnanf() on linux
isnanf() is deprecated since C99
2020-02-20 11:05:44 +01:00
6474f25934 Don't include sys/sysctl.h on Linux.
Not only is sysctl() not used on this platform, but musl libc does not have the header.
2020-02-20 10:10:17 +01:00
b45560cfc4 Merge pull request #292 from leper/clang_linking
Fix linking with Clang and clean up some linking directive
2019-11-23 16:10:19 -08:00
d14b4df347 Merge pull request #304 from r-a-sattarov/master
Added support for MCST Elbrus 2000 (e2k) architecture
2019-11-23 16:03:39 -08:00
c621de8d2b E2K: added initial support for MCST Elbrus 2000 2019-11-23 16:40:53 +03:00
b764700527 poshlib: added support for MCST Elbrus 2000 (e2k) 2019-11-23 16:22:56 +03:00
a131e4c6b0 Merge pull request #301 from Starnick/master
Updated C-API to expose some functionality present in the C++ API
2019-09-08 17:25:30 -07:00
187fa60492 Updated C-API to expose some functionality present in the C++ API. Added the following functions and enums:
nvttSetOutputOptionsContainer [and NvttContainer, KTX/DDS10 formats can now be set as the output container]
nvttSetOutputOptionsSrgbFlag
nvttSetOutputOptionsErrorHandler [rearranged NvttError enum to match layout of nvtt::error]
nvttEnableCudaAcceleration
nvttIsCudaAccelerationEnabled
2019-09-06 17:54:40 -04:00
e872fc2850 Merge pull request #300 from edowson/master
Enable CUDA support.
2019-08-30 10:08:13 -07:00
d57ca44902 Enable CUDA support.
This commit also reintroduces nvcore Library.h and Library.cpp files
required by nvtt/cuda/CudaUtils.cpp

Ref:
https://github.com/castano/nvidia-texture-tools/issues/230
81336cc3e9

Signed-off-by: Elvis Dowson <elvis.dowson@gmail.com>
2019-08-19 03:22:00 +04:00
662d223626 Merge pull request #295 from mitko0003/master
Minor fix to ATOC normalization.
2019-02-15 08:31:45 -08:00
d891d044e7 Minor fix to ATOC normalization. 2019-02-15 15:06:29 +02:00
84595a62f2 Add helper methods for jai bindings. 2019-02-07 15:39:32 -08:00
29493d365e Add Visual Studio 2017 projects. 2019-01-31 18:10:14 -08:00
c591c5f8b4 Compute spherical harmonics from cube maps. Work in progress. 2019-01-31 18:06:02 -08:00
2ac75fc932 Remove duplicate link instruction. 2019-01-09 00:55:49 +01:00
542711f862 Link with -fPIC when using Clang.
Remove the need for a few workarounds by handling this in just one place.
2019-01-09 00:55:19 +01:00
7c68e09d77 Fix ATOC overflow error on large textures. Merge fix from The Witness. 2018-10-29 12:52:00 -07:00
a9a6f6968e Fix minor warnings.
Add output directories to ignore list.
2018-10-29 12:37:16 -07:00
8a076c8e8d Merge pull request #289 from Starnick/master
Updated C-API
2018-10-27 10:51:11 -07:00
40f395ef19 spaces->tabs consistency 2018-10-18 20:34:07 -04:00
0f65d60602 Updated C-API to support 2D array textures + added missing enum values from nvtt.h 2018-10-18 20:29:57 -04:00
d2b514a3c1 Comment out hack. 2018-10-10 16:30:25 -07:00
a1c54bc7f7 Add fast sRGB conversion. 2018-10-10 14:04:13 -07:00
bc60e8c154 Use our own parallel for by default to avoid dependencies. 2018-10-09 18:11:21 -07:00
1722b00802 FloatImage does not need a virtual dtor. 2018-10-09 18:10:25 -07:00
95f1f60490 Enable stb libraries for image loading. This was disabled by error. 2018-10-09 18:01:15 -07:00
5c70ffef0b Merge pull request #287 from madscientist159/master
Fix build on OpenPOWER (ppc64le) platforms
2018-08-19 14:04:22 -07:00
005b2518c9 Install nvtt_wrapper.h. Fix issue #288. 2018-08-19 14:02:34 -07:00
95454e9024 Fix build on OpenPOWER (ppc64le) platforms 2018-08-15 21:53:49 -05:00
95bd6193cc Fix bug 281. 2018-05-29 23:28:08 -07:00
6ea078f196 Merge pull request #280 from MonoGame/ignore
Added gitignore to hide stuff that shouldn't be checked in.
2018-02-24 12:04:38 -08:00
e52a2f1a02 Merge pull request #279 from MonoGame/vc12
Fixed some missing files in the vc12 project.
2018-02-24 12:03:51 -08:00
6cb1821bf1 Added gitignore to hide stuff that shouldn't be checked in. 2018-02-23 19:59:21 -06:00
1a78eae8f6 Fixed some missing files in the vc12 project. 2018-02-23 19:56:37 -06:00
2c276f64d7 Merge pull request #276 from StefanBruens/fix_memalign_linux
Fix compilation on Linux - missing include, semicolon
2018-02-06 16:32:27 -08:00
ff3bd55892 Fix compilation on Linux - missing include, semicolon
According to http://man7.org/linux/man-pages/man3/memalign.3.html ,
memalign() is defined in malloc.h.
Also, the line should be terminated with a semicolon.

Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
2018-02-06 08:38:37 +01:00
9489aed825 Merge changes from The Witness. 2018-02-05 18:55:07 -08:00
2075d740c9 Merge pull request #274 from StefanBruens/fix_build_errors
Fix some build errors
2018-02-05 18:30:58 -08:00
00d7e249e2 Add nvimgdiff to TOOLS target, so it is installed by default
Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
2018-02-02 19:46:58 +01:00
389f7582e5 Fix linking of bc7, needs symbols from nvmath
If nvtt is build with -Wl,--as-needed, the linker will not resolve bc7
symbols from any library listed earlier, make sure it (also) appears
after libbc7.a
2018-02-02 19:46:54 +01:00
7b4b7bb42e Build intermediate EtcLib always as STATIC
Depending on the BUILD_SHARED_LIBS variable EtcLib may be built as SHARED
if not set explicitly, like done for the other libraries in extern.

Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
2018-02-02 19:45:18 +01:00
8e8b3b82e1 Merge pull request #273 from wsmind/master
Fix .hdr images being loaded as LDR before compression
2018-01-28 12:06:21 -08:00
b03d5178fc Fix .hdr images being loaded as LDR before compression 2018-01-28 20:18:13 +01:00
befe79d103 Merge changes from thekla-atlas. 2017-12-15 11:39:21 -08:00
182a326e1c Merge pull request #271 from Chainsawkitten/patch-1
Update file paths in readme
2017-11-15 16:45:18 -08:00
133b84d536 Update file paths in readme
There is no src/nvimage/nvtt folder.
2017-11-08 22:49:11 +01:00
6816128f80 Add dataset from lightmap compression article. 2017-09-28 22:32:59 -07:00
e442d6d390 Remove incorrect assert. Fixes issue #261. 2017-09-04 12:34:00 -07:00
ed735ac2cb Fix alpha coverage subsampling. Fixes issue #266. 2017-09-04 12:25:22 -07:00
5f6424778e Update changelog 2017-08-23 11:05:30 -07:00
132cf14623 Bump version number 2017-08-23 11:02:09 -07:00
8d333f2a4f Merge pull request #264 from justinmeiners/master
added noalpha option to assemble and fixed RGB write
2017-06-28 15:06:12 -07:00
d47de35893 added noalpha option to assemble and fixed RGB write 2017-06-28 15:53:50 -06:00
4fb0070b7e Do not use undeclared format. 2017-06-28 11:26:18 -07:00
fa03dfc291 Add option to control prefered swizzle. 2017-06-28 11:19:47 -07:00
923b57db45 Merge pull request #255 from AMDmi3/patch-3
Use libexecinfo on FreeBSD as well
2017-06-06 17:58:17 -07:00
ef30f69c9d Merge pull request #256 from AMDmi3/patch-4
Use HW_NCPU on FreeBSD as well
2017-06-06 17:57:50 -07:00
7849ee9e71 Merge pull request #260 from leper/master
Add virtual destructor to TaskDispatcher.
2017-06-06 17:57:01 -07:00
0608489ec4 Merge pull request #262 from kencooke/master
Fast implementations of toLinear() and toGamma() for default gamma=2.2
2017-06-06 17:56:24 -07:00
01597842fe Update CMakeLists.txt and vc8/9/10 projects 2017-06-04 11:10:15 -07:00
96b73af196 Fast implementations of toLinear() and toGamma() for default gamma=2.2 2017-06-01 13:44:28 -07:00
78054e977b Add virtual destructor to TaskDispatcher.
This removes a GCC warning about that missing while virtual functions exist.
2017-05-04 03:22:19 +02:00
a64cc24169 Use HW_NCPU on FreeBSD as well 2017-02-16 18:21:39 +04:00
6b24b1f45c Use libexecinfo on FreeBSD as well 2017-02-16 18:20:07 +04:00
e85d851cd9 Do not compile etcpack. Only used for reference. 2017-02-15 11:12:27 -08:00
91fe4d37d6 Enable c++1x the official way. 2017-02-15 11:11:44 -08:00
1762334a9f Fix buildpkg for osx. 2017-02-15 11:10:43 -08:00
d7612a3b67 Add some external dependencies. 2017-02-08 11:42:25 -08:00
1004d5d5b5 Merge pull request #252 from lunkhound/fix-normal-maps
fix a bug where created normal maps were not packed prior to compression
2016-12-26 23:19:17 -08:00
0535ab3414 fix a bug where created normal maps were not packed prior to compression 2016-12-26 12:34:06 -08:00
cec8e7159a Merge pull request #247 from Lectem/patch-2
Fix compression for non multiple of 4 texture size
2016-10-19 12:18:36 -07:00
24e63456c6 Fix compression for non multiple of 4 texture size
If the width or the height was not a multiple of 4, we would read data outside of the bitmap array
2016-10-19 17:47:00 +02:00
6fb57d3478 Fix order of kaiser parameters. 2016-10-05 11:14:11 -07:00
573 changed files with 101564 additions and 85140 deletions

3
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,3 @@
# These are supported funding model platforms
github: castano

33
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,33 @@
name: build
on: [push, pull_request]
jobs:
vs2017:
runs-on: windows-2019
steps:
- uses: actions/checkout@v2
- uses: microsoft/setup-msbuild@v1.0.0
- name: Build Debug/x64
run: msbuild .\project\vc2017\nvtt.sln /property:Configuration=Debug /property:Platform=x64
- name: Build Debug/Win32
run: msbuild .\project\vc2017\nvtt.sln /property:Configuration=Debug /property:Platform=Win32
- name: Build Release/x64
run: msbuild .\project\vc2017\nvtt.sln /property:Configuration=Release /property:Platform=x64
- name: Build Release/Win32
run: msbuild .\project\vc2017\nvtt.sln /property:Configuration=Release /property:Platform=Win32
unix:
strategy:
matrix:
os: [ubuntu, macos]
name: ${{matrix.os}}
runs-on: ${{matrix.os}}-latest
steps:
- uses: actions/checkout@v2
- name: make
run: |
./configure --debug
make
./configure --release
make

17
.gitignore vendored Normal file
View File

@ -0,0 +1,17 @@
**/bin/
**/obj/
**/Debug/
**/Release/
**/Debug.x64/
**/Release.x64/
**/Debug.Win32/
**/Release.Win32/
**/Debug-CUDA/
**/Release-CUDA/
*.vcxproj.user
*.opensdf
*.sdf
*.suo
build
.vs
project/nvtt.sublime-workspace

View File

@ -5,41 +5,25 @@ ENABLE_TESTING()
SET(NV_CMAKE_DIR "${NV_SOURCE_DIR}/cmake")
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${NV_CMAKE_DIR}")
# GCC check (needs -std:c++11 flag)
if(CMAKE_COMPILER_IS_GNUCC)
ADD_DEFINITIONS("-std=c++11")
ENDIF(CMAKE_COMPILER_IS_GNUCC)
IF(WIN32)
# gnuwin32 paths:
SET(GNUWIN32_PATH "${NV_SOURCE_DIR}/extern/gnuwin32")
SET(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${GNUWIN32_PATH}/include")
SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "${GNUWIN32_PATH}/lib")
# Set GLUT path:
SET(GLUT_ROOT_DIR "${NV_SOURCE_DIR}/extern/glut")
# Set FreeImage path:
SET(FREEIMAGE_ROOT_DIR "${NV_SOURCE_DIR}/extern/FreeImage")
ENDIF(WIN32)
# Compiler check (needs -std:c++11 flag)
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
else()
message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()
INCLUDE(${NV_CMAKE_DIR}/OptimalOptions.cmake)
MESSAGE(STATUS "Setting optimal options")
MESSAGE(STATUS " Processor: ${NV_SYSTEM_PROCESSOR}")
MESSAGE(STATUS " Compiler Flags: ${CMAKE_CXX_FLAGS}")
IF(CMAKE_BUILD_TYPE MATCHES "debug")
SET(CMAKE_DEBUG_POSTFIX "_d" CACHE STRING "Postfix for debug build libraries.")
ADD_DEFINITIONS(-D_DEBUG=1)
ENDIF()
IF(NVTT_SHARED)
SET(NVCORE_SHARED TRUE)
SET(NVMATH_SHARED TRUE)
SET(NVIMAGE_SHARED TRUE)
ENDIF(NVTT_SHARED)
ADD_SUBDIRECTORY(extern)
ADD_SUBDIRECTORY(src)
@ -60,10 +44,9 @@ ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
SET(CPACK_PACKAGE_NAME "nvidia-texture-tools")
SET(CPACK_PACKAGE_VERSION_MAJOR "2")
SET(CPACK_PACKAGE_VERSION_MINOR "1")
SET(CPACK_PACKAGE_VERSION_PATCH "0")
SET(CPACK_PACKAGE_VERSION "2.1.0")
SET(CPACK_PACKAGE_VERSION_PATCH "2")
SET(CPACK_PACKAGE_VERSION "2.1.2")
SET(CPACK_PACKAGE_CONTACT "Ignacio Casta<74>o <castano@gmail.com>")
#SET(CPACK_PACKAGE_VENDOR "NVIDIA Corporation")
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Texture processing tools with support for Direct3D 10 and 11 formats.")
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${NV_SOURCE_DIR}/README.md")
@ -73,7 +56,7 @@ SET(CPACK_RESOURCE_FILE_LICENSE "${NV_SOURCE_DIR}/LICENSE")
IF(WIN32)
SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_VENDOR}\\\\NVIDIA Texture Tools 2.1")
SET(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_VENDOR}\\\\NVIDIA Texture Tools 2.1")
SET(CPACK_PACKAGE_ICON "${NV_SOURCE_DIR}\\\\project\\\\vc8\\\\nvcompress\\\\nvidia.ico")
SET(CPACK_PACKAGE_ICON "${NV_SOURCE_DIR}\\\\project\\\\vc2017\\\\nvcompress\\\\nvidia.ico")
ENDIF(WIN32)
INCLUDE(CPack)

View File

@ -1,3 +1,10 @@
NVIDIA Texture Tools version 2.1.2
* Use ICBC as the main BC1 compressor.
* Various fixes.
NVIDIA Texture Tools version 2.1.1
* Various fixes.
NVIDIA Texture Tools version 2.1.0
* Too many changes to list here.
* CTX1 CUDA compressor.

View File

@ -1,6 +1,6 @@
NVIDIA Texture Tools is licensed under the MIT license.
Copyright (c) 2009-2016 Ignacio Castano
Copyright (c) 2009-2020 Ignacio Castaño
Copyright (c) 2007-2009 NVIDIA Corporation
Permission is hereby granted, free of charge, to any person

View File

@ -1,19 +1,16 @@
NVIDIA Texture Tools
====================
# NVIDIA Texture Tools [![Actions Status](https://github.com/castano/nvidia-texture-tools/workflows/build/badge.svg)](https://github.com/castano/nvidia-texture-tools/actions) ![MIT](https://img.shields.io/badge/license-MIT-blue.svg) [![GitHub](https://img.shields.io/badge/repo-github-green.svg)](https://github.com/castano/nvidia-texture-tools)
The NVIDIA Texture Tools is a collection of image processing and texture
manipulation tools, designed to be integrated in game tools and asset
processing pipelines.
The primary features of the library are mipmap and normal map generation, format
conversion and DXT compression.
conversion, and DXT compression.
### How to build (Windows)
Open `project/vc12/thekla.sln` using Visual Studio.
Solutions for previous versions are also available, but they may not be up to date.
Use the provided Visual Studio 2017 solution `project/vc2017/thekla.sln`.
### How to build (Linux/OSX)
@ -32,15 +29,15 @@ $ sudo make install
To use the NVIDIA Texture Tools in your own applications you just have to
include the following header file:
src/nvimage/nvtt/nvtt.h
[src/nvtt/nvtt.h](https://github.com/castano/nvidia-texture-tools/blob/master/src/nvtt/nvtt.h)
And include the nvtt library in your projects.
The following file contains a simple example that shows how to use the library:
src/nvimage/nvtt/compress.cpp
[src/nvtt/tools/compress.cpp](https://github.com/castano/nvidia-texture-tools/blob/master/src/nvtt/tools/compress.cpp)
Detailed documentation of the API can be found at:
http://code.google.com/p/nvidia-texture-tools/wiki/ApiDocumentation
https://github.com/castano/nvidia-texture-tools/wiki/ApiDocumentation

View File

@ -1 +1 @@
2.1.0
2.1.2

View File

@ -1,10 +0,0 @@
#!/bin/sh
tar zcvf nvidia-texture-tools-`cat VERSION`.tar.gz \
--exclude '.*' --exclude debian --exclude '*~' --exclude buildpkg \
--exclude 'build-*' --exclude data --exclude tags --exclude Makefile \
--exclude 'doc' --exclude 'nvidia-texture-tools-*.tar.gz' \
--exclude '*.user' -s ',^,nvidia-texture-tools/,' *
# --exclude '*.user' --transform 's,^,nvidia-texture-tools/,' *
# --exclude '*.user' *

View File

@ -1,72 +0,0 @@
# Assume i586 by default.
SET(NV_SYSTEM_PROCESSOR "i586")
IF(UNIX)
FIND_PROGRAM(CMAKE_UNAME uname /bin /usr/bin /usr/local/bin )
IF(CMAKE_UNAME)
#EXEC_PROGRAM(uname ARGS -p OUTPUT_VARIABLE NV_SYSTEM_PROCESSOR RETURN_VALUE val)
#IF("${val}" GREATER 0 OR NV_SYSTEM_PROCESSOR STREQUAL "unknown")
EXEC_PROGRAM(uname ARGS -m OUTPUT_VARIABLE NV_SYSTEM_PROCESSOR RETURN_VALUE val)
#ENDIF("${val}" GREATER 0 OR NV_SYSTEM_PROCESSOR STREQUAL "unknown")
IF(NV_SYSTEM_PROCESSOR STREQUAL "Power Macintosh")
SET(NV_SYSTEM_PROCESSOR "powerpc")
ENDIF(NV_SYSTEM_PROCESSOR STREQUAL "Power Macintosh")
# processor may have double quote in the name, and that needs to be removed
STRING(REGEX REPLACE "\"" "" NV_SYSTEM_PROCESSOR "${NV_SYSTEM_PROCESSOR}")
STRING(REGEX REPLACE "/" "_" NV_SYSTEM_PROCESSOR "${NV_SYSTEM_PROCESSOR}")
ENDIF(CMAKE_UNAME)
#~ # Get extended processor information from /proc/cpuinfo
#~ IF(EXISTS "/proc/cpuinfo")
#~ FILE(READ /proc/cpuinfo PROC_CPUINFO)
#~ SET(VENDOR_ID_RX "vendor_id[ \t]*:[ \t]*([a-zA-Z]+)\n")
#~ STRING(REGEX MATCH "${VENDOR_ID_RX}" VENDOR_ID "${PROC_CPUINFO}")
#~ STRING(REGEX REPLACE "${VENDOR_ID_RX}" "\\1" VENDOR_ID "${VENDOR_ID}")
#~ SET(CPU_FAMILY_RX "cpu family[ \t]*:[ \t]*([0-9]+)")
#~ STRING(REGEX MATCH "${CPU_FAMILY_RX}" CPU_FAMILY "${PROC_CPUINFO}")
#~ STRING(REGEX REPLACE "${CPU_FAMILY_RX}" "\\1" CPU_FAMILY "${CPU_FAMILY}")
#~ SET(MODEL_RX "model[ \t]*:[ \t]*([0-9]+)")
#~ STRING(REGEX MATCH "${MODEL_RX}" MODEL "${PROC_CPUINFO}")
#~ STRING(REGEX REPLACE "${MODEL_RX}" "\\1" MODEL "${MODEL}")
#~ SET(FLAGS_RX "flags[ \t]*:[ \t]*([a-zA-Z0-9 _]+)\n")
#~ STRING(REGEX MATCH "${FLAGS_RX}" FLAGS "${PROC_CPUINFO}")
#~ STRING(REGEX REPLACE "${FLAGS_RX}" "\\1" FLAGS "${FLAGS}")
#~ # Debug output.
#~ IF(LINUX_CPUINFO)
#~ MESSAGE(STATUS "LinuxCPUInfo.cmake:")
#~ MESSAGE(STATUS "VENDOR_ID : ${VENDOR_ID}")
#~ MESSAGE(STATUS "CPU_FAMILY : ${CPU_FAMILY}")
#~ MESSAGE(STATUS "MODEL : ${MODEL}")
#~ MESSAGE(STATUS "FLAGS : ${FLAGS}")
#~ ENDIF(LINUX_CPUINFO)
#~ ENDIF(EXISTS "/proc/cpuinfo")
#~ # Information on how to decode CPU_FAMILY and MODEL:
#~ # http://balusc.xs4all.nl/srv/har-cpu-int-pm.php
ELSE(UNIX)
IF(WIN32)
# It's not OK to trust $ENV{PROCESSOR_ARCHITECTURE}: its value depends on the type of executable being run,
# so a 32-bit cmake (the default binary distribution) will always say "x86" regardless of the actual target.
IF (CMAKE_SIZEOF_VOID_P EQUAL 8)
SET (NV_SYSTEM_PROCESSOR "x86_64")
ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8)
SET (NV_SYSTEM_PROCESSOR "x86")
ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8)
ENDIF(WIN32)
ENDIF(UNIX)

View File

@ -1,172 +0,0 @@
#
# Try to find NVIDIA's Cg compiler, runtime libraries, and include path.
# Once done this will define
#
# CG_FOUND =system has NVIDIA Cg and it can be used.
# CG_INCLUDE_DIR = directory where cg.h resides
# CG_LIBRARY = full path to libCg.so (Cg.DLL on win32)
# CG_GL_LIBRARY = full path to libCgGL.so (CgGL.dll on win32)
# CG_COMPILER = full path to cgc (cgc.exe on win32)
#
# On OSX default to using the framework version of Cg.
IF (APPLE)
INCLUDE(${CMAKE_ROOT}/Modules/CMakeFindFrameworks.cmake)
SET(CG_FRAMEWORK_INCLUDES)
CMAKE_FIND_FRAMEWORKS(Cg)
IF (Cg_FRAMEWORKS)
FOREACH(dir ${Cg_FRAMEWORKS})
SET(CG_FRAMEWORK_INCLUDES ${CG_FRAMEWORK_INCLUDES}
${dir}/Headers ${dir}/PrivateHeaders)
ENDFOREACH(dir)
# Find the include dir
FIND_PATH(CG_INCLUDE_DIR cg.h
${CG_FRAMEWORK_INCLUDES}
)
# Since we are using Cg framework, we must link to it.
# Note, we use weak linking, so that it works even when Cg is not available.
SET(CG_LIBRARY "-weak_framework Cg" CACHE STRING "Cg library")
SET(CG_GL_LIBRARY "-weak_framework Cg" CACHE STRING "Cg GL library")
ENDIF (Cg_FRAMEWORKS)
FIND_PROGRAM(CG_COMPILER cgc
/usr/bin
/usr/local/bin
DOC "The Cg compiler"
)
ELSE (APPLE)
IF (WIN32)
# When compiling 64-bit programs, the binaries and libs are in bin.x64 and lib.x64 directories,
# This will have only effect for 64bit versions of cmake, when running the default 32bit version
# both ProgramFiles and ProgramFiles(x86) point to the same place in Win64
SET(PFx86_VARNAME "ProgramFiles(x86)")
SET(PFx86 $ENV{${PFx86_VARNAME}})
# Let's play safe in case we are cross compiling to 64 bit: for cgc it doesn't really matter
FIND_PROGRAM( CG_COMPILER cgc
$ENV{CG_BIN64_PATH}
$ENV{CG_BIN_PATH}
$ENV{PROGRAMFILES}/NVIDIA\ Corporation/Cg/bin
$ENV{PFx86}/NVIDIA\ Corporation/Cg/bin
$ENV{PROGRAMFILES}/Cg
${PROJECT_SOURCE_DIR}/../Cg
DOC "The Cg Compiler"
)
IF (CG_COMPILER)
GET_FILENAME_COMPONENT(CG_COMPILER_DIR ${CG_COMPILER} PATH)
GET_FILENAME_COMPONENT(CG_COMPILER_SUPER_DIR ${CG_COMPILER_DIR} PATH)
ELSE (CG_COMPILER)
SET (CG_COMPILER_DIR .)
SET (CG_COMPILER_SUPER_DIR ..)
ENDIF (CG_COMPILER)
FIND_PATH( CG_INCLUDE_DIR Cg/cg.h
$ENV{CG_INC_PATH}
$ENV{PROGRAMFILES}/NVIDIA\ Corporation/Cg/include
$ENV{PROGRAMFILES}/Cg
${PROJECT_SOURCE_DIR}/../Cg
${CG_COMPILER_SUPER_DIR}/include
${CG_COMPILER_DIR}
DOC "The directory where Cg/cg.h resides"
)
IF (NV_SYSTEM_PROCESSOR STREQUAL "x86_64")
FIND_LIBRARY( CG_LIBRARY
NAMES Cg
PATHS
$ENV{CG_LIB64_PATH}
$ENV{PROGRAMFILES}/NVIDIA\ Corporation/Cg/lib.x64
$ENV{PFx86}/NVIDIA\ Corporation/Cg/lib.x64
$ENV{PROGRAMFILES}/Cg
$ENV{PFx86}/Cg
${PROJECT_SOURCE_DIR}/../Cg
${CG_COMPILER_SUPER_DIR}/lib.x64
${CG_COMPILER_DIR}
DOC "The Cg runtime library (64-bit)"
)
FIND_LIBRARY( CG_GL_LIBRARY
NAMES CgGL
PATHS
$ENV{CG_LIB64_PATH}
$ENV{PROGRAMFILES}/NVIDIA\ Corporation/Cg/lib.x64
$ENV{PFx86}/NVIDIA\ Corporation/Cg/lib.x64
$ENV{PROGRAMFILES}/Cg
$ENV{PFx86}/Cg
${PROJECT_SOURCE_DIR}/../Cg
${CG_COMPILER_SUPER_DIR}/lib.x64
${CG_COMPILER_DIR}
DOC "The Cg GL runtime library (64-bit)"
)
ELSE(NV_SYSTEM_PROCESSOR STREQUAL "x86_64")
FIND_LIBRARY( CG_LIBRARY
NAMES Cg
PATHS
$ENV{CG_LIB_PATH}
$ENV{PROGRAMFILES}/NVIDIA\ Corporation/Cg/lib
$ENV{PROGRAMFILES}/Cg
${PROJECT_SOURCE_DIR}/../Cg
${CG_COMPILER_SUPER_DIR}/lib
${CG_COMPILER_DIR}
DOC "The Cg runtime library"
)
FIND_LIBRARY( CG_GL_LIBRARY
NAMES CgGL
PATHS
$ENV{CG_LIB_PATH}
$ENV{PROGRAMFILES}/NVIDIA\ Corporation/Cg/lib
$ENV{PROGRAMFILES}/Cg
${PROJECT_SOURCE_DIR}/../Cg
${CG_COMPILER_SUPER_DIR}/lib
${CG_COMPILER_DIR}
DOC "The Cg GL runtime library"
)
ENDIF(NV_SYSTEM_PROCESSOR STREQUAL "x86_64")
ELSE (WIN32)
FIND_PROGRAM( CG_COMPILER cgc
/usr/bin
/usr/local/bin
DOC "The Cg Compiler"
)
GET_FILENAME_COMPONENT(CG_COMPILER_DIR "${CG_COMPILER}" PATH)
GET_FILENAME_COMPONENT(CG_COMPILER_SUPER_DIR "${CG_COMPILER_DIR}" PATH)
FIND_PATH( CG_INCLUDE_DIR Cg/cg.h
/usr/include
/usr/local/include
${CG_COMPILER_SUPER_DIR}/include
DOC "The directory where Cg/cg.h resides"
)
FIND_LIBRARY( CG_LIBRARY Cg
PATHS
/usr/lib64
/usr/lib
/usr/local/lib64
/usr/local/lib
${CG_COMPILER_SUPER_DIR}/lib64
${CG_COMPILER_SUPER_DIR}/lib
DOC "The Cg runtime library"
)
SET(CG_LIBRARY ${CG_LIBRARY} -lpthread)
FIND_LIBRARY( CG_GL_LIBRARY CgGL
PATHS
/usr/lib64
/usr/lib
/usr/local/lib64
/usr/local/lib
${CG_COMPILER_SUPER_DIR}/lib64
${CG_COMPILER_SUPER_DIR}/lib
DOC "The Cg runtime library"
)
ENDIF (WIN32)
ENDIF (APPLE)
IF (CG_INCLUDE_DIR)
SET( CG_FOUND 1 CACHE STRING "Set to 1 if CG is found, 0 otherwise")
ELSE (CG_INCLUDE_DIR)
SET( CG_FOUND 0 CACHE STRING "Set to 1 if CG is found, 0 otherwise")
ENDIF (CG_INCLUDE_DIR)
MARK_AS_ADVANCED( CG_FOUND )

View File

@ -1,38 +0,0 @@
IF (WIN32)
FIND_PATH(DX9_INCLUDE_PATH d3d9.h
PATHS
"$ENV{DXSDK_DIR}/Include"
"$ENV{PROGRAMFILES}/Microsoft DirectX SDK/Include"
DOC "The directory where D3D9.h resides")
FIND_PATH(DX10_INCLUDE_PATH D3D10.h
PATHS
"$ENV{DXSDK_DIR}/Include"
"$ENV{PROGRAMFILES}/Microsoft DirectX SDK/Include"
DOC "The directory where D3D10.h resides")
FIND_LIBRARY(D3D10_LIBRARY d3d10.lib
PATHS
"$ENV{DXSDK_DIR}/Lib/x86"
"$ENV{PROGRAMFILES}/Microsoft DirectX SDK/Lib/x86"
DOC "The directory where d3d10.lib resides")
FIND_LIBRARY(D3DX10_LIBRARY d3dx10.lib
PATHS
"$ENV{DXSDK_DIR}/Lib/x86"
"$ENV{PROGRAMFILES}/Microsoft DirectX SDK/Lib/x86"
DOC "The directory where d3dx10.lib resides")
SET(DX10_LIBRARIES ${D3D10_LIBRARY} ${D3DX10_LIBRARY})
ENDIF (WIN32)
IF (DX10_INCLUDE_PATH)
SET( DX10_FOUND 1 CACHE STRING "Set to 1 if CG is found, 0 otherwise")
ELSE (DX10_INCLUDE_PATH)
SET( DX10_FOUND 0 CACHE STRING "Set to 1 if CG is found, 0 otherwise")
ENDIF (DX10_INCLUDE_PATH)
MARK_AS_ADVANCED( DX10_FOUND )

View File

@ -1,53 +0,0 @@
#
# Try to find the FreeImage library and include path.
# Once done this will define
#
# FREEIMAGE_FOUND
# FREEIMAGE_INCLUDE_PATH
# FREEIMAGE_LIBRARY
#
IF (WIN32)
FIND_PATH( FREEIMAGE_INCLUDE_PATH FreeImage.h
${FREEIMAGE_ROOT_DIR}/include
${FREEIMAGE_ROOT_DIR}
DOC "The directory where FreeImage.h resides")
FIND_LIBRARY( FREEIMAGE_LIBRARY
NAMES FreeImage freeimage
PATHS
${FREEIMAGE_ROOT_DIR}/lib
${FREEIMAGE_ROOT_DIR}
DOC "The FreeImage library")
ELSE (WIN32)
FIND_PATH( FREEIMAGE_INCLUDE_PATH FreeImage.h
/usr/include
/usr/local/include
/sw/include
/opt/local/include
DOC "The directory where FreeImage.h resides")
FIND_LIBRARY( FREEIMAGE_LIBRARY
NAMES FreeImage freeimage
PATHS
/usr/lib64
/usr/lib
/usr/local/lib64
/usr/local/lib
/sw/lib
/opt/local/lib
DOC "The FreeImage library")
ENDIF (WIN32)
SET(FREEIMAGE_LIBRARIES ${FREEIMAGE_LIBRARY})
IF (FREEIMAGE_INCLUDE_PATH AND FREEIMAGE_LIBRARY)
SET( FREEIMAGE_FOUND TRUE CACHE BOOL "Set to TRUE if FreeImage is found, FALSE otherwise")
ELSE (FREEIMAGE_INCLUDE_PATH AND FREEIMAGE_LIBRARY)
SET( FREEIMAGE_FOUND FALSE CACHE BOOL "Set to TRUE if FreeImage is found, FALSE otherwise")
ENDIF (FREEIMAGE_INCLUDE_PATH AND FREEIMAGE_LIBRARY)
MARK_AS_ADVANCED(
FREEIMAGE_FOUND
FREEIMAGE_LIBRARY
FREEIMAGE_LIBRARIES
FREEIMAGE_INCLUDE_PATH)

View File

@ -1,50 +0,0 @@
#
# Try to find GLEW library and include path.
# Once done this will define
#
# GLEW_FOUND
# GLEW_INCLUDE_PATH
# GLEW_LIBRARY
#
IF (WIN32)
FIND_PATH( GLEW_INCLUDE_PATH GL/glew.h
$ENV{PROGRAMFILES}/GLEW/include
${GLEW_ROOT_DIR}/include
DOC "The directory where GL/glew.h resides")
FIND_LIBRARY( GLEW_LIBRARY
NAMES glew GLEW glew32 glew32s
PATHS
$ENV{PROGRAMFILES}/GLEW/lib
${PROJECT_SOURCE_DIR}/src/nvgl/glew/bin
${PROJECT_SOURCE_DIR}/src/nvgl/glew/lib
DOC "The GLEW library")
ELSE (WIN32)
FIND_PATH( GLEW_INCLUDE_PATH GL/glew.h
/usr/include
/usr/local/include
/sw/include
/opt/local/include
${GLEW_ROOT_DIR}/include
DOC "The directory where GL/glew.h resides")
# Prefer the static library.
FIND_LIBRARY( GLEW_LIBRARY
NAMES libGLEW.a GLEW
PATHS
/usr/lib64
/usr/lib
/usr/local/lib64
/usr/local/lib
/sw/lib
/opt/local/lib
${GLEW_ROOT_DIR}/lib
DOC "The GLEW library")
ENDIF (WIN32)
SET(GLEW_FOUND "NO")
IF (GLEW_INCLUDE_PATH AND GLEW_LIBRARY)
SET(GLEW_LIBRARIES ${GLEW_LIBRARY})
SET(GLEW_FOUND "YES")
ENDIF (GLEW_INCLUDE_PATH AND GLEW_LIBRARY)

View File

@ -1,67 +0,0 @@
IF (WIN32)
# Maya plugins can only be compiled with msvc
IF (MSVC)
FIND_PATH(MAYA_INCLUDE_PATH maya/MTypes.h
PATHS
"$ENV{PROGRAMFILES}/Autodesk/Maya8.5/include"
"$ENV{MAYA_LOCATION}/include"
DOC "The directory where MTypes.h resides")
# Find maya version!
FIND_LIBRARY(MAYA_FOUNDATION_LIBRARY Foundation
PATHS
"$ENV{PROGRAMFILES}/Autodesk/Maya8.5/lib"
"$ENV{MAYA_LOCATION}/lib"
DOC "The directory where Foundation.lib resides")
FIND_LIBRARY(MAYA_OPENMAYA_LIBRARY OpenMaya
PATHS
"$ENV{PROGRAMFILES}/Autodesk/Maya8.5/lib"
"$ENV{MAYA_LOCATION}/lib"
DOC "The directory where OpenMaya.lib resides")
FIND_LIBRARY(MAYA_OPENMAYAANIM_LIBRARY OpenMayaAnim
PATHS
"$ENV{PROGRAMFILES}/Autodesk/Maya8.5/lib"
"$ENV{MAYA_LOCATION}/lib"
DOC "The directory where OpenMayaAnim.lib resides")
SET(MAYA_LIBRARIES
${MAYA_FOUNDATION_LIBRARY}
${MAYA_OPENMAYA_LIBRARY}
${MAYA_OPENMAYAANIM_LIBRARY})
SET(MAYA_EXTENSION ".mll")
ENDIF (MSVC)
ELSE (WIN32)
# On linux, check gcc version.
# OSX and Linux
FIND_PATH(MAYA_INCLUDE_PATH maya/MTypes.h
PATHS
/usr/autodesk/maya/include
$ENV{MAYA_LOCATION}/include
DOC "The directory where MTypes.h resides")
# TODO
ENDIF (WIN32)
IF (MAYA_INCLUDE_PATH)
SET( MAYA_FOUND 1 CACHE STRING "Set to 1 if Maya is found, 0 otherwise")
ELSE (MAYA_INCLUDE_PATH)
SET( MAYA_FOUND 0 CACHE STRING "Set to 1 if Maya is found, 0 otherwise")
ENDIF (MAYA_INCLUDE_PATH)
MARK_AS_ADVANCED( MAYA_FOUND )

View File

@ -1,75 +0,0 @@
#
# Try to find OpenEXR's libraries, and include path.
# Once done this will define:
#
# OPENEXR_FOUND = OpenEXR found.
# OPENEXR_INCLUDE_PATHS = OpenEXR include directories.
# OPENEXR_LIBRARIES = libraries that are needed to use OpenEXR.
#
INCLUDE(FindZLIB)
IF(ZLIB_FOUND)
SET(LIBRARY_PATHS
/usr/lib
/usr/local/lib
/sw/lib
/opt/local/lib
$ENV{PROGRAM_FILES}/OpenEXR/lib/static)
FIND_PATH(OPENEXR_INCLUDE_PATH ImfRgbaFile.h
PATH_SUFFIXES OpenEXR
/usr/include
/usr/local/include
/sw/include
/opt/local/include)
FIND_LIBRARY(OPENEXR_HALF_LIBRARY
NAMES Half
PATHS ${LIBRARY_PATHS})
FIND_LIBRARY(OPENEXR_IEX_LIBRARY
NAMES Iex
PATHS ${LIBRARY_PATHS})
FIND_LIBRARY(OPENEXR_IMATH_LIBRARY
NAMES Imath
PATHS ${LIBRARY_PATHS})
FIND_LIBRARY(OPENEXR_ILMIMF_LIBRARY
NAMES IlmImf
PATHS ${LIBRARY_PATHS})
FIND_LIBRARY(OPENEXR_ILMTHREAD_LIBRARY
NAMES IlmThread
PATHS ${LIBRARY_PATHS})
ENDIF(ZLIB_FOUND)
#MESSAGE(STATUS ${OPENEXR_IMATH_LIBRARY} ${OPENEXR_ILMIMF_LIBRARY} ${OPENEXR_IEX_LIBRARY} ${OPENEXR_HALF_LIBRARY} ${OPENEXR_ILMTHREAD_LIBRARY} ${ZLIB_LIBRARY})
IF (OPENEXR_INCLUDE_PATH AND OPENEXR_IMATH_LIBRARY AND OPENEXR_ILMIMF_LIBRARY AND OPENEXR_IEX_LIBRARY AND OPENEXR_HALF_LIBRARY)
SET(OPENEXR_FOUND TRUE)
SET(OPENEXR_INCLUDE_PATHS ${OPENEXR_INCLUDE_PATH} CACHE STRING "The include paths needed to use OpenEXR")
SET(OPENEXR_LIBRARIES ${OPENEXR_IMATH_LIBRARY} ${OPENEXR_ILMIMF_LIBRARY} ${OPENEXR_IEX_LIBRARY} ${OPENEXR_HALF_LIBRARY} ${OPENEXR_ILMTHREAD_LIBRARY} ${ZLIB_LIBRARY} CACHE STRING "The libraries needed to use OpenEXR")
ENDIF (OPENEXR_INCLUDE_PATH AND OPENEXR_IMATH_LIBRARY AND OPENEXR_ILMIMF_LIBRARY AND OPENEXR_IEX_LIBRARY AND OPENEXR_HALF_LIBRARY)
IF(OPENEXR_FOUND)
IF(NOT OPENEXR_FIND_QUIETLY)
MESSAGE(STATUS "Found OpenEXR: ${OPENEXR_ILMIMF_LIBRARY}")
ENDIF(NOT OPENEXR_FIND_QUIETLY)
ELSE(OPENEXR_FOUND)
IF(OPENEXR_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find OpenEXR library")
ENDIF(OPENEXR_FIND_REQUIRED)
ENDIF(OPENEXR_FOUND)
MARK_AS_ADVANCED(
OPENEXR_INCLUDE_PATHS
OPENEXR_LIBRARIES
OPENEXR_ILMIMF_LIBRARY
OPENEXR_IMATH_LIBRARY
OPENEXR_IEX_LIBRARY
OPENEXR_HALF_LIBRARY)

View File

@ -1,54 +1,11 @@
INCLUDE(${NV_CMAKE_DIR}/DetermineProcessor.cmake)
# Set optimal options for gcc:
IF(CMAKE_COMPILER_IS_GNUCXX)
IF(NV_SYSTEM_PROCESSOR STREQUAL "i586")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=i586")
ENDIF(NV_SYSTEM_PROCESSOR STREQUAL "i586")
IF(NV_SYSTEM_PROCESSOR STREQUAL "i686")
#SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=i686")
#SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpmath=sse -mtune=i686 -msse3")
#SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=pentium4")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=prescott")
ENDIF(NV_SYSTEM_PROCESSOR STREQUAL "i686")
IF(NV_SYSTEM_PROCESSOR STREQUAL "x86_64")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=athlon64")
#SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=athlon64 -msse3")
ENDIF(NV_SYSTEM_PROCESSOR STREQUAL "x86_64")
IF(NV_SYSTEM_PROCESSOR STREQUAL "powerpc")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=powerpc -faltivec -maltivec -mabi=altivec -mpowerpc-gfxopt")
# ibook G4:
#SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=7450 -mtune=7450 -faltivec -maltivec -mabi=altivec -mpowerpc-gfxopt")
# G5
#SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=G5 -faltivec -maltivec -mabi=altivec -mpowerpc-gfxopt")
ENDIF(NV_SYSTEM_PROCESSOR STREQUAL "powerpc")
# IF(DARWIN)
# SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=10.5 -isysroot /Developer/SDKs/MacOSX10.5.sdk")
# SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.5 -isysroot /Developer/SDKs/MacOSX10.5.sdk")
# ENDIF(DARWIN)
IF(APPLE)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -arch i586 -arch x86_64 -msse3 -mmacosx-version-min=10.5")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -arch i586 -arch x86_64 -msse3 -mmacosx-version-min=10.5")
ENDIF(APPLE)
IF(CMAKE_BUILD_TYPE STREQUAL "debug")
ADD_DEFINITIONS(-D_DEBUG)
ENDIF(CMAKE_BUILD_TYPE STREQUAL "debug")
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
ENDIF(CMAKE_COMPILER_IS_GNUCXX)
ENDIF()
IF(MSVC)
# @@ Some of these might only be available in VC8.
# Code generation flags.
# SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /arch:SSE2 /fp:fast")
# SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:SSE2 /fp:fast")

Binary file not shown.

After

Width:  |  Height:  |  Size: 622 KiB

BIN
data/witness/archway.dds Normal file

Binary file not shown.

BIN
data/witness/hallway.dds Normal file

Binary file not shown.

BIN
data/witness/hub.dds Normal file

Binary file not shown.

BIN
data/witness/hut.dds Normal file

Binary file not shown.

BIN
data/witness/mine.dds Normal file

Binary file not shown.

41
data/witness/run.sh Normal file
View File

@ -0,0 +1,41 @@
FILES=(hallway windmill tunnel theater tower hub mine archway hut shaft)
EXT=dds
#FILES=(kodim01 kodim02 kodim03 kodim04 kodim05 kodim06 kodim07 kodim08)
#EXT=png
for file in "${FILES[@]}"
do
#echo $file
# Output histogram
#./nvdecompress -histogram $file.$EXT
# R11G11B10_FLOAT
#./nvcompress -silent -alpha -nomips -dds10 -rgb $file.$EXT $file.r11g11b10.dds
#./nvimgdiff -alpha $file.$EXT $file.r11g11b10.dds
# RGBM
#./nvcompress -silent -alpha -nomips -rgb -rgbm $file.$EXT $file.rgbm.dds
#./nvimgdiff -alpha $file.$EXT $file.rgbm.dds
# RGB-DXT1
#./nvcompress -silent -alpha -nomips -bc1 $file.$EXT $file.bc1.dds
#./nvimgdiff -alpha $file.$EXT $file.bc1.dds
# RGBM-DXT5 Naive
#./nvcompress -silent -alpha -nomips -bc3 -rgbm $file.$EXT $file.bc3-rgbm.dds
#./nvimgdiff -alpha $file.$EXT $file.bc3-rgbm.dds
# RGBM-DXT5 Optimized
./nvcompress -silent -alpha -nomips -bc3_rgbm $file.$EXT $file.bc3-rgbm.dds
./nvimgdiff -alpha $file.$EXT $file.bc3-rgbm.dds
# BC6
#./nvcompress -silent -alpha -nomips -bc6 $file.$EXT $file.bc6.dds
#./nvimgdiff -alpha $file.$EXT $file.bc6.dds
# ETC2-EAC
./nvcompress -silent -alpha -nomips -etc_rgbm
done

BIN
data/witness/shaft.dds Normal file

Binary file not shown.

BIN
data/witness/theater.dds Normal file

Binary file not shown.

BIN
data/witness/tower.dds Normal file

Binary file not shown.

BIN
data/witness/tunnel.dds Normal file

Binary file not shown.

BIN
data/witness/windmill.dds Normal file

Binary file not shown.

View File

@ -1,4 +1,5 @@
Update version number in nvtt/nvtt.h
Update version number in nvimage/DirectDrawSurface.cpp
Update version number in CMakeLists.txt
Update version number in VERSION
Update version number in NVIDIA_Texture_Tools_README.txt
Update version number in project/vc2017/nvtt/nvtt.rc

56
extern/CMP_Core/CMP_Core.def vendored Normal file
View File

@ -0,0 +1,56 @@
; Core def : Declares the module parameters for the DLL.
EXPORTS
CreateOptionsBC1
CreateOptionsBC2
CreateOptionsBC3
CreateOptionsBC4
CreateOptionsBC5
CreateOptionsBC6
CreateOptionsBC7
DestroyOptionsBC1
DestroyOptionsBC2
DestroyOptionsBC3
DestroyOptionsBC4
DestroyOptionsBC5
DestroyOptionsBC6
DestroyOptionsBC7
SetDecodeChannelMapping
SetChannelWeightsBC1
SetChannelWeightsBC2
SetChannelWeightsBC3
SetQualityBC1
SetQualityBC2
SetQualityBC3
SetQualityBC4
SetQualityBC5
SetQualityBC6
SetQualityBC7
SetAlphaThresholdBC1
SetMaskBC6
SetMaskBC7
SetErrorThresholdBC7
SetAlphaOptionsBC7
CompressBlockBC1
CompressBlockBC2
CompressBlockBC3
CompressBlockBC4
CompressBlockBC5
CompressBlockBC6
CompressBlockBC7
DecompressBlockBC1
DecompressBlockBC2
DecompressBlockBC3
DecompressBlockBC4
DecompressBlockBC5
DecompressBlockBC6
DecompressBlockBC7

33
extern/CMP_Core/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,33 @@
cmake_minimum_required(VERSION 3.10)
add_library(CMP_Core STATIC "")
target_sources(CMP_Core
PRIVATE
shaders/BC1_Encode_kernel.h
shaders/BC1_Encode_kernel.cpp
shaders/BC2_Encode_kernel.h
shaders/BC2_Encode_kernel.cpp
shaders/BC3_Encode_kernel.h
shaders/BC3_Encode_kernel.cpp
shaders/BC4_Encode_kernel.h
shaders/BC4_Encode_kernel.cpp
shaders/BC5_Encode_kernel.h
shaders/BC5_Encode_kernel.cpp
shaders/BC6_Encode_kernel.h
shaders/BC6_Encode_kernel.cpp
shaders/BC7_Encode_Kernel.h
shaders/BC7_Encode_Kernel.cpp
shaders/BCn_Common_Kernel.h
shaders/Common_Def.h
)
target_include_directories(CMP_Core
PRIVATE
shaders
source)
#add_subdirectory(test)
if (UNIX)
target_compile_definitions(CMP_Core PRIVATE _LINUX ASPM_GPU)
endif()

View File

@ -0,0 +1,305 @@
//==============================================================================
// Copyright (c) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// 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 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.
//
//===============================================================================
// Heat Mapping
// This is code that compares quality of two similar or equal codecs with varying quality settings
// A resulting compressed codec data block is colored according to three colors conditions
// The base codec, lowest quality is colored green and the varying quality code is colored red.
// If the quality of the base matches that of the varying codec then the color is set to blue
// Base codecs can be local to CMP_Core or imported using a external set of files, the base codec
#ifndef TEST_HEATMAP
//#define TEST_HEATMAP // Enable this to run heat map tests on BC1 codec
#endif
#include "BC1_Encode_kernel.h"
#ifdef TEST_HEATMAP
#include "ExternCodec.h" // Use external codec for testing
#endif
//============================================== BC1 INTERFACES =======================================================
#ifndef ASPM_HLSL
void CompressBlockBC1_Internal(
const CMP_Vec4uc srcBlockTemp[16],
CMP_GLOBAL CGU_UINT32 compressedBlock[2],
CMP_GLOBAL CMP_BC15Options *BC15options)
{
CGU_UINT8 srcindex = 0;
CGU_FLOAT BlockA[16];
CGU_Vec3f rgbBlockUV[16];
for ( CGU_INT32 j = 0; j < 4; j++) {
for ( CGU_INT32 i = 0; i < 4; i++) {
rgbBlockUV[srcindex].x = (CGU_FLOAT)(srcBlockTemp[srcindex].x & 0xFF)/ 255.0f; // R
rgbBlockUV[srcindex].y = (CGU_FLOAT)(srcBlockTemp[srcindex].y & 0xFF)/ 255.0f; // G
rgbBlockUV[srcindex].z = (CGU_FLOAT)(srcBlockTemp[srcindex].z & 0xFF)/ 255.0f; // B
srcindex++;
}
}
CMP_BC15Options internalOptions = *BC15options;
internalOptions = CalculateColourWeightings3f(rgbBlockUV,internalOptions);
CGU_Vec3f channelWeights = {internalOptions.m_fChannelWeights[0],internalOptions.m_fChannelWeights[1],internalOptions.m_fChannelWeights[2]};
CGU_BOOL isSRGB = internalOptions.m_bIsSRGB; // feature not supported in this section of code until v4.1
CGU_Vec2ui cmpBlock = 0;
//#define CMP_PRINTRESULTS
#ifdef TEST_HEATMAP
#ifdef CMP_PRINTRESULTS
static int q1= 0,q2= 0,same = 0;
static int testnum = 0;
printf("%4d ",testnum);
#endif
{
// Heatmap test: See BCn_Common_Kernel for details
CGU_Vec2ui red = {0xf800f800,0};
CGU_Vec2ui green = {0x07e007e0,0};
CGU_Vec2ui blue = {0x001f001f,0};
CGU_Vec2ui comp1;
CGU_Vec2ui comp2;
float err ;
comp1 = (BC15options->m_fquality < 0.3)?CompressBC1Block_SRGB(rgbBlockUV):CompressBC1Block(rgbBlockUV);
comp2 = CompressBlockBC1_UNORM(rgbBlockUV, BC15options->m_fquality,BC15options->m_fquality < 0.3?true:false);
if ((comp1.x == comp2.x)&&(comp1.y == comp2.y)) err = 0.0f;
else {
float err1 = CMP_RGBBlockError(rgbBlockUV,comp1,(BC15options->m_fquality < 0.3)?true:false);
float err2 = CMP_RGBBlockError(rgbBlockUV,comp2,(BC15options->m_fquality < 0.3)?true:false);
err = err1-err2;
}
if (err > 0.0f)
{
cmpBlock = red;
}
else if (err < 0.0f) {
cmpBlock = green;
}
else {
cmpBlock = blue;
}
}
#ifdef CMP_PRINTRESULTS
printf("Q1 [%4X:%4X] %.3f, ",cmpBlockQ1.x,cmpBlockQ1.y,err1);
printf("Q2 [%4X:%4X] %.3f, ",cmpBlock.x,cmpBlock.y ,err2);
testnum++;
#endif
#else
// printf("q = %f\n",internalOptions.m_fquality);
cmpBlock = CompressBlockBC1_RGBA_Internal(
rgbBlockUV,
BlockA,
channelWeights,
0, //internalOptions.m_nAlphaThreshold, bug to investigate in debug is ok release has issue!
1,
internalOptions.m_fquality,
isSRGB
);
#endif
compressedBlock[0] = cmpBlock.x;
compressedBlock[1] = cmpBlock.y;
}
#endif
//============================================== CPU USER INTERFACES ========================================================
#ifndef ASPM_GPU
int CMP_CDECL CreateOptionsBC1(void **options)
{
CMP_BC15Options *BC15optionsDefault = new CMP_BC15Options;
if (BC15optionsDefault) {
SetDefaultBC15Options(BC15optionsDefault);
(*options) = BC15optionsDefault;
}
else {
(*options) = NULL;
return CGU_CORE_ERR_NEWMEM;
}
return CGU_CORE_OK;
}
int CMP_CDECL DestroyOptionsBC1(void *options)
{
if (!options) return CGU_CORE_ERR_INVALIDPTR;
CMP_BC15Options *BCOptions = reinterpret_cast <CMP_BC15Options *>(options);
delete BCOptions;
return CGU_CORE_OK;
}
int CMP_CDECL SetQualityBC1(void *options,
CGU_FLOAT fquality)
{
if (!options) return CGU_CORE_ERR_NEWMEM;
CMP_BC15Options *BC15optionsDefault = reinterpret_cast <CMP_BC15Options *>(options);
if (fquality < 0.0f) fquality = 0.0f;
else
if (fquality > 1.0f) fquality = 1.0f;
BC15optionsDefault->m_fquality = fquality;
return CGU_CORE_OK;
}
int CMP_CDECL SetAlphaThresholdBC1(void *options,
CGU_UINT8 alphaThreshold)
{
if (!options) return CGU_CORE_ERR_INVALIDPTR;
CMP_BC15Options *BC15optionsDefault = reinterpret_cast <CMP_BC15Options *>(options);
BC15optionsDefault->m_nAlphaThreshold = alphaThreshold;
return CGU_CORE_OK;
}
int CMP_CDECL SetDecodeChannelMapping(void *options,
CGU_BOOL mapRGBA)
{
if (!options) return CGU_CORE_ERR_INVALIDPTR;
CMP_BC15Options *BC15optionsDefault = reinterpret_cast <CMP_BC15Options *>(options);
BC15optionsDefault->m_mapDecodeRGBA = mapRGBA;
return CGU_CORE_OK;
}
int CMP_CDECL SetChannelWeightsBC1(void *options,
CGU_FLOAT WeightRed,
CGU_FLOAT WeightGreen,
CGU_FLOAT WeightBlue) {
if (!options) return CGU_CORE_ERR_INVALIDPTR;
CMP_BC15Options *BC15optionsDefault = (CMP_BC15Options *)options;
if ((WeightRed < 0.0f) || (WeightRed > 1.0f)) return CGU_CORE_ERR_RANGERED;
if ((WeightGreen < 0.0f) || (WeightGreen > 1.0f)) return CGU_CORE_ERR_RANGEGREEN;
if ((WeightBlue < 0.0f) || (WeightBlue > 1.0f)) return CGU_CORE_ERR_RANGEBLUE;
BC15optionsDefault->m_bUseChannelWeighting = true;
BC15optionsDefault->m_fChannelWeights[0] = WeightRed;
BC15optionsDefault->m_fChannelWeights[1] = WeightGreen;
BC15optionsDefault->m_fChannelWeights[2] = WeightBlue;
return CGU_CORE_OK;
}
int CMP_CDECL CompressBlockBC1(const unsigned char *srcBlock,
unsigned int srcStrideInBytes,
CMP_GLOBAL unsigned char cmpBlock[8],
const void *options = NULL) {
CMP_Vec4uc inBlock[16];
//----------------------------------
// Fill the inBlock with source data
//----------------------------------
CGU_INT srcpos = 0;
CGU_INT dstptr = 0;
for (CGU_UINT8 row=0; row < 4; row++)
{
srcpos = row * srcStrideInBytes;
for (CGU_UINT8 col = 0; col < 4; col++)
{
inBlock[dstptr].x = CGU_UINT8(srcBlock[srcpos++]);
inBlock[dstptr].y = CGU_UINT8(srcBlock[srcpos++]);
inBlock[dstptr].z = CGU_UINT8(srcBlock[srcpos++]);
inBlock[dstptr].w = CGU_UINT8(srcBlock[srcpos++]);
dstptr++;
}
}
CMP_BC15Options *BC15options = (CMP_BC15Options *)options;
CMP_BC15Options BC15optionsDefault;
if (BC15options == NULL)
{
BC15options = &BC15optionsDefault;
SetDefaultBC15Options(BC15options);
}
CompressBlockBC1_Internal(inBlock, (CMP_GLOBAL CGU_UINT32 *)cmpBlock, BC15options);
return CGU_CORE_OK;
}
int CMP_CDECL DecompressBlockBC1(const unsigned char cmpBlock[8],
CMP_GLOBAL unsigned char srcBlock[64],
const void *options = NULL) {
CMP_BC15Options *BC15options = (CMP_BC15Options *)options;
CMP_BC15Options BC15optionsDefault;
if (BC15options == NULL)
{
BC15options = &BC15optionsDefault;
SetDefaultBC15Options(BC15options);
}
CGU_Vec2ui compBlock;
compBlock.x = (CGU_UINT32)cmpBlock[3] << 24 |
(CGU_UINT32)cmpBlock[2] << 16 |
(CGU_UINT32)cmpBlock[1] << 8 |
(CGU_UINT32)cmpBlock[0];
compBlock.y = (CGU_UINT32)cmpBlock[7] << 24 |
(CGU_UINT32)cmpBlock[6] << 16 |
(CGU_UINT32)cmpBlock[5] << 8 |
(CGU_UINT32)cmpBlock[4];
cmp_decompressDXTRGBA_Internal(srcBlock, compBlock, BC15options->m_mapDecodeRGBA);
return CGU_CORE_OK;
}
#endif
//============================================== OpenCL USER INTERFACE ========================================================
#ifdef ASPM_OPENCL
CMP_STATIC CMP_KERNEL void CMP_GPUEncoder(
CMP_GLOBAL const CMP_Vec4uc* ImageSource,
CMP_GLOBAL CGU_UINT8* ImageDestination,
CMP_GLOBAL Source_Info* SourceInfo,
CMP_GLOBAL CMP_BC15Options* BC15options
)
{
CGU_UINT32 xID;
CGU_UINT32 yID;
//printf("SourceInfo: (H:%d,W:%d) Quality %1.2f \n", SourceInfo->m_src_height, SourceInfo->m_src_width, SourceInfo->m_fquality);
xID = get_global_id(0);
yID = get_global_id(1);
if (xID >= (SourceInfo->m_src_width / BlockX)) return;
if (yID >= (SourceInfo->m_src_height / BlockX)) return;
int srcWidth = SourceInfo->m_src_width;
CGU_UINT32 destI = (xID*BC1CompBlockSize) + (yID*(srcWidth / BlockX)*BC1CompBlockSize);
int srcindex = 4 * (yID * srcWidth + xID);
int blkindex = 0;
CMP_Vec4uc srcData[16];
srcWidth = srcWidth - 4;
for ( CGU_INT32 j = 0; j < 4; j++) {
for ( CGU_INT32 i = 0; i < 4; i++) {
srcData[blkindex++] = ImageSource[srcindex++];
}
srcindex += srcWidth;
}
CompressBlockBC1_Internal(srcData, (CMP_GLOBAL CGU_UINT32 *)&ImageDestination[destI], BC15options);
}
#endif

View File

@ -0,0 +1,30 @@
//=====================================================================
// Copyright (c) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// 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 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.
//
//=====================================================================
#ifndef BC1_ENCODE_KERNEL_H
#define BC1_ENCODE_KERNEL_H
#include "Common_Def.h"
#include "BCn_Common_Kernel.h"
#endif

View File

@ -0,0 +1,99 @@
//=====================================================================
// Copyright (c) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// 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 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.
//
// File: BC1_Encode_kernel.hlsl
//--------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//--------------------------------------------------------------------------------------
#ifndef ASPM_HLSL
#define ASPM_HLSL
#endif
cbuffer cbCS : register( b0 )
{
uint g_tex_width;
uint g_num_block_x;
uint g_format;
uint g_mode_id;
uint g_start_block_id;
uint g_num_total_blocks;
float g_alpha_weight;
float g_quality;
};
#include "BCn_Common_Kernel.h"
// Source Data
Texture2D g_Input : register( t0 );
StructuredBuffer<uint4> g_InBuff : register( t1 );
// Compressed Output Data
RWStructuredBuffer<uint2> g_OutBuff : register( u0 );
// Processing multiple blocks at a time
#define MAX_USED_THREAD 16 // pixels in a BC (block compressed) block
#define BLOCK_IN_GROUP 4 // the number of BC blocks a thread group processes = 64 / 16 = 4
#define THREAD_GROUP_SIZE 64 // 4 blocks where a block is (BLOCK_SIZE_X x BLOCK_SIZE_Y)
#define BLOCK_SIZE_Y 4
#define BLOCK_SIZE_X 4
groupshared float4 shared_temp[THREAD_GROUP_SIZE];
[numthreads( THREAD_GROUP_SIZE, 1, 1 )]
void EncodeBlocks(uint GI : SV_GroupIndex, uint3 groupID : SV_GroupID)
{
// we process 4 BC blocks per thread group
uint blockInGroup = GI / MAX_USED_THREAD; // what BC block this thread is on within this thread group
uint blockID = g_start_block_id + groupID.x * BLOCK_IN_GROUP + blockInGroup; // what global BC block this thread is on
uint pixelBase = blockInGroup * MAX_USED_THREAD; // the first id of the pixel in this BC block in this thread group
uint pixelInBlock = GI - pixelBase; // id of the pixel in this BC block
uint block_y = blockID / g_num_block_x;
uint block_x = blockID - block_y * g_num_block_x;
uint base_x = block_x * BLOCK_SIZE_X;
uint base_y = block_y * BLOCK_SIZE_Y;
// Load up the pixels
if (pixelInBlock < 16)
{
// load pixels (0..1)
shared_temp[GI] = float4(g_Input.Load( uint3( base_x + pixelInBlock % 4, base_y + pixelInBlock / 4, 0 ) ));
}
GroupMemoryBarrierWithGroupSync();
// Process and save s
if (pixelInBlock == 0)
{
float3 block[16];
for (int i = 0; i < 16; i++ )
{
block[i].x = shared_temp[pixelBase + i].x;
block[i].y = shared_temp[pixelBase + i].y;
block[i].z = shared_temp[pixelBase + i].z;
}
g_OutBuff[blockID] = CompressBlockBC1_UNORM(block,g_quality,false);
}
}

View File

@ -0,0 +1,250 @@
//=====================================================================
// Copyright (c) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// 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 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.
//
//=====================================================================
#include "BC2_Encode_kernel.h"
//============================================== BC2 INTERFACES =======================================================
void CompressBlockBC2_Internal(const CMP_Vec4uc srcBlockTemp[16],
CMP_GLOBAL CGU_UINT32 compressedBlock[4],
CMP_GLOBAL const CMP_BC15Options *BC15options)
{
CGU_Vec2ui cmpBlock;
CGU_Vec3f rgbBlock[16];
CGU_FLOAT BlockA[16];
for (CGU_INT32 i = 0; i < 16; i++) {
rgbBlock[i].x = (CGU_FLOAT)(srcBlockTemp[i].x & 0xFF)/255.0f; // R
rgbBlock[i].y = (CGU_FLOAT)(srcBlockTemp[i].y & 0xFF)/255.0f; // G
rgbBlock[i].z = (CGU_FLOAT)(srcBlockTemp[i].z & 0xFF)/255.0f; // B
BlockA[i] = (CGU_FLOAT)(srcBlockTemp[i].w & 0xFF)/255.0f; // A
}
cmpBlock = cmp_compressExplicitAlphaBlock(BlockA);
compressedBlock[DXTC_OFFSET_ALPHA ] = cmpBlock.x;
compressedBlock[DXTC_OFFSET_ALPHA+1] = cmpBlock.y;
// Need a copy, as CalculateColourWeightings sets variables in the BC15options
CMP_BC15Options internalOptions = *BC15options;
internalOptions = CalculateColourWeightings3f(rgbBlock, internalOptions);
internalOptions.m_bUseAlpha = false;
CGU_Vec3f channelWeights = {internalOptions.m_fChannelWeights[0],internalOptions.m_fChannelWeights[1],internalOptions.m_fChannelWeights[2]};
CGU_Vec3f MinColor = {0,0,0}, MaxColor={0,0,0};
cmpBlock = CompressBlockBC1_RGBA_Internal(
rgbBlock,
BlockA,
channelWeights,
0,//internalOptions.m_nAlphaThreshold,
1, //internalOptions.m_nRefinementSteps
internalOptions.m_fquality,
FALSE);
compressedBlock[DXTC_OFFSET_RGB] = cmpBlock.x;
compressedBlock[DXTC_OFFSET_RGB+1] = cmpBlock.y;
}
//============================================== USER INTERFACES ========================================================
#ifndef ASPM_GPU
int CMP_CDECL CreateOptionsBC2(void **options)
{
CMP_BC15Options *BC15optionsDefault = new CMP_BC15Options;
if (BC15optionsDefault) {
SetDefaultBC15Options(BC15optionsDefault);
(*options) = BC15optionsDefault;
}
else {
(*options) = NULL;
return CGU_CORE_ERR_NEWMEM;
}
return CGU_CORE_OK;
}
int CMP_CDECL DestroyOptionsBC2(void *options)
{
if (!options) return CGU_CORE_ERR_INVALIDPTR;
CMP_BC15Options *BCOptions = reinterpret_cast <CMP_BC15Options *>(options);
delete BCOptions;
return CGU_CORE_OK;
}
int CMP_CDECL SetQualityBC2(void *options,
CGU_FLOAT fquality)
{
if (!options) return CGU_CORE_ERR_INVALIDPTR;
CMP_BC15Options *BC15optionsDefault = reinterpret_cast <CMP_BC15Options *>(options);
if (fquality < 0.0f) fquality = 0.0f;
else
if (fquality > 1.0f) fquality = 1.0f;
BC15optionsDefault->m_fquality = fquality;
return CGU_CORE_OK;
}
int CMP_CDECL SetChannelWeightsBC2(void *options,
CGU_FLOAT WeightRed,
CGU_FLOAT WeightGreen,
CGU_FLOAT WeightBlue) {
if (!options) return CGU_CORE_ERR_INVALIDPTR;
CMP_BC15Options *BC15optionsDefault = (CMP_BC15Options *)options;
if ((WeightRed < 0.0f) || (WeightRed > 1.0f)) return CGU_CORE_ERR_RANGERED;
if ((WeightGreen < 0.0f) || (WeightGreen > 1.0f)) return CGU_CORE_ERR_RANGEGREEN;
if ((WeightBlue < 0.0f) || (WeightBlue > 1.0f)) return CGU_CORE_ERR_RANGEBLUE;
BC15optionsDefault->m_bUseChannelWeighting = true;
BC15optionsDefault->m_fChannelWeights[0] = WeightRed;
BC15optionsDefault->m_fChannelWeights[1] = WeightGreen;
BC15optionsDefault->m_fChannelWeights[2] = WeightBlue;
return CGU_CORE_OK;
}
#define EXPLICIT_ALPHA_PIXEL_MASK 0xf
#define EXPLICIT_ALPHA_PIXEL_BPP 4
// Decompresses an explicit alpha block (DXT3)
void DecompressExplicitAlphaBlock(CGU_UINT8 alphaBlock[BLOCK_SIZE_4X4],
const CGU_UINT32 compressedBlock[2])
{
for (int i = 0; i < 16; i++)
{
int nBlock = i < 8 ? 0 : 1;
CGU_UINT8 cAlpha = (CGU_UINT8)((compressedBlock[nBlock] >> ((i % 8) * EXPLICIT_ALPHA_PIXEL_BPP)) & EXPLICIT_ALPHA_PIXEL_MASK);
alphaBlock[i] = (CGU_UINT8)((cAlpha << EXPLICIT_ALPHA_PIXEL_BPP) | cAlpha);
}
}
void DecompressBC2_Internal(CMP_GLOBAL CGU_UINT8 rgbaBlock[BLOCK_SIZE_4X4X4],
const CGU_UINT32 compressedBlock[4],
const CMP_BC15Options *BC15options)
{
CGU_UINT8 alphaBlock[BLOCK_SIZE_4X4];
DecompressExplicitAlphaBlock(alphaBlock, &compressedBlock[DXTC_OFFSET_ALPHA]);
CGU_Vec2ui compBlock;
compBlock.x = compressedBlock[DXTC_OFFSET_RGB];
compBlock.y = compressedBlock[DXTC_OFFSET_RGB+1];
cmp_decompressDXTRGBA_Internal(rgbaBlock, compBlock,BC15options->m_mapDecodeRGBA);
for (CGU_UINT32 i = 0; i < 16; i++)
((CMP_GLOBAL CGU_UINT32*)rgbaBlock)[i] = (alphaBlock[i] << RGBA8888_OFFSET_A) | (((CMP_GLOBAL CGU_UINT32*)rgbaBlock)[i] & ~(BYTE_MASK << RGBA8888_OFFSET_A));
}
int CMP_CDECL CompressBlockBC2(const unsigned char *srcBlock,
unsigned int srcStrideInBytes,
CMP_GLOBAL unsigned char cmpBlock[16],
CMP_GLOBAL const void *options = NULL) {
CMP_Vec4uc inBlock[16];
//----------------------------------
// Fill the inBlock with source data
//----------------------------------
CGU_INT srcpos = 0;
CGU_INT dstptr = 0;
for (CGU_UINT8 row = 0; row < 4; row++)
{
srcpos = row * srcStrideInBytes;
for (CGU_UINT8 col = 0; col < 4; col++)
{
inBlock[dstptr].x = CGU_UINT8(srcBlock[srcpos++]);
inBlock[dstptr].y = CGU_UINT8(srcBlock[srcpos++]);
inBlock[dstptr].z = CGU_UINT8(srcBlock[srcpos++]);
inBlock[dstptr].w = CGU_UINT8(srcBlock[srcpos++]);
dstptr++;
}
}
CMP_BC15Options *BC15options = (CMP_BC15Options *)options;
CMP_BC15Options BC15optionsDefault;
if (BC15options == NULL)
{
BC15options = &BC15optionsDefault;
SetDefaultBC15Options(BC15options);
}
CompressBlockBC2_Internal(inBlock, (CMP_GLOBAL CGU_UINT32 *)cmpBlock, BC15options);
return CGU_CORE_OK;
}
int CMP_CDECL DecompressBlockBC2(const unsigned char cmpBlock[16],
CMP_GLOBAL unsigned char srcBlock[64],
const void *options = NULL) {
CMP_BC15Options *BC15options = (CMP_BC15Options *)options;
CMP_BC15Options BC15optionsDefault;
if (BC15options == NULL)
{
BC15options = &BC15optionsDefault;
SetDefaultBC15Options(BC15options);
}
DecompressBC2_Internal(srcBlock, (CGU_UINT32 *)cmpBlock,BC15options);
return CGU_CORE_OK;
}
#endif
//============================================== OpenCL USER INTERFACE ========================================================
#ifdef ASPM_OPENCL
CMP_STATIC CMP_KERNEL void CMP_GPUEncoder(
CMP_GLOBAL const CMP_Vec4uc* ImageSource,
CMP_GLOBAL CGU_UINT8* ImageDestination,
CMP_GLOBAL Source_Info* SourceInfo,
CMP_GLOBAL CMP_BC15Options* BC15options
)
{
CGU_UINT32 xID;
CGU_UINT32 yID;
#ifdef ASPM_GPU
xID = get_global_id(0);
yID = get_global_id(1);
#else
xID = 0;
yID = 0;
#endif
if (xID >= (SourceInfo->m_src_width / BlockX)) return;
if (yID >= (SourceInfo->m_src_height / BlockX)) return;
int srcWidth = SourceInfo->m_src_width;
CGU_UINT32 destI = (xID*BC2CompBlockSize) + (yID*(srcWidth / BlockX)*BC2CompBlockSize);
int srcindex = 4 * (yID * srcWidth + xID);
int blkindex = 0;
CMP_Vec4uc srcData[16];
srcWidth = srcWidth - 4;
for ( CGU_INT32 j = 0; j < 4; j++) {
for ( CGU_INT32 i = 0; i < 4; i++) {
srcData[blkindex++] = ImageSource[srcindex++];
}
srcindex += srcWidth;
}
CompressBlockBC2_Internal(srcData,(CMP_GLOBAL CGU_UINT32 *)&ImageDestination[destI], BC15options);
}
#endif

View File

@ -0,0 +1,34 @@
//=====================================================================
// Copyright (c) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// 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 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.
//
//=====================================================================
#ifndef BC2_ENCODE_KERNEL_H
#define BC2_ENCODE_KERNEL_H
#include "Common_Def.h"
#include "BCn_Common_Kernel.h"
#define BC2CompBlockSize 16
#define NUM_CHANNELS 4
#define NUM_ENDPOINTS 2
#endif

View File

@ -0,0 +1,101 @@
//=====================================================================
// Copyright (c) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// 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 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.
//
// File: BC1Encode.hlsl
//--------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//--------------------------------------------------------------------------------------
#ifndef ASPM_HLSL
#define ASPM_HLSL
#endif
cbuffer cbCS : register( b0 )
{
uint g_tex_width;
uint g_num_block_x;
uint g_format;
uint g_mode_id;
uint g_start_block_id;
uint g_num_total_blocks;
float g_alpha_weight;
float g_quality;
};
#include "BCn_Common_Kernel.h"
// Source Data
Texture2D g_Input : register( t0 );
StructuredBuffer<uint4> g_InBuff : register( t1 );
// Compressed Output Data
RWStructuredBuffer<uint4> g_OutBuff : register( u0 );
// Processing multiple blocks at a time
#define MAX_USED_THREAD 16 // pixels in a BC (block compressed) block
#define BLOCK_IN_GROUP 4 // the number of BC blocks a thread group processes = 64 / 16 = 4
#define THREAD_GROUP_SIZE 64 // 4 blocks where a block is (BLOCK_SIZE_X x BLOCK_SIZE_Y)
#define BLOCK_SIZE_Y 4
#define BLOCK_SIZE_X 4
groupshared float4 shared_temp[THREAD_GROUP_SIZE];
[numthreads( THREAD_GROUP_SIZE, 1, 1 )]
void EncodeBlocks(uint GI : SV_GroupIndex, uint3 groupID : SV_GroupID)
{
// we process 4 BC blocks per thread group
uint blockInGroup = GI / MAX_USED_THREAD; // what BC block this thread is on within this thread group
uint blockID = g_start_block_id + groupID.x * BLOCK_IN_GROUP + blockInGroup; // what global BC block this thread is on
uint pixelBase = blockInGroup * MAX_USED_THREAD; // the first id of the pixel in this BC block in this thread group
uint pixelInBlock = GI - pixelBase; // id of the pixel in this BC block
uint block_y = blockID / g_num_block_x;
uint block_x = blockID - block_y * g_num_block_x;
uint base_x = block_x * BLOCK_SIZE_X;
uint base_y = block_y * BLOCK_SIZE_Y;
// Load up the pixels
if (pixelInBlock < 16)
{
// load pixels (0..1)
shared_temp[GI] = float4(g_Input.Load( uint3( base_x + pixelInBlock % 4, base_y + pixelInBlock / 4, 0 ) ));
}
GroupMemoryBarrierWithGroupSync();
// Process and save s
if (pixelInBlock == 0)
{
float3 blockRGB[16];
float blockA[16];
for (int i = 0; i < 16; i++ )
{
blockRGB[i].x = shared_temp[pixelBase + i].x;
blockRGB[i].y = shared_temp[pixelBase + i].y;
blockRGB[i].z = shared_temp[pixelBase + i].z;
blockA[i] = shared_temp[pixelBase + i].w;
}
g_OutBuff[blockID] = CompressBlockBC2_UNORM(blockRGB,blockA,g_quality,false);
}
}

View File

@ -0,0 +1,235 @@
//=====================================================================
// Copyright (c) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// 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 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.
//
//=====================================================================
#include "BC3_Encode_kernel.h"
//============================================== BC3 INTERFACES =======================================================
#ifndef ASPM_HLSL
void CompressBlockBC3_Internal(const CMP_Vec4uc srcBlockTemp[16],
CMP_GLOBAL CGU_UINT32 compressedBlock[4],
CMP_GLOBAL CMP_BC15Options *BC15options) {
CGU_Vec3f rgbBlock[16];
CGU_FLOAT alphaBlock[BLOCK_SIZE_4X4];
for (CGU_INT32 i = 0; i < 16; i++) {
rgbBlock[i].x = (CGU_FLOAT)(srcBlockTemp[i].x & 0xFF)/255; // R
rgbBlock[i].y = (CGU_FLOAT)(srcBlockTemp[i].y & 0xFF)/255; // G
rgbBlock[i].z = (CGU_FLOAT)(srcBlockTemp[i].z & 0xFF)/255; // B
alphaBlock[i] = (CGU_FLOAT)(srcBlockTemp[i].w) / 255.0f;
}
CMP_BC15Options internalOptions = *BC15options;
CGU_Vec2ui cmpBlock;
cmpBlock = cmp_compressAlphaBlock(alphaBlock,internalOptions.m_fquality);
compressedBlock[0] = cmpBlock.x;
compressedBlock[1] = cmpBlock.y;
for (CGU_INT32 i = 0; i < 16; i++) {
alphaBlock[i] = (CGU_FLOAT)(srcBlockTemp[i].w);
}
internalOptions = CalculateColourWeightings3f(rgbBlock, internalOptions);
CGU_Vec3f channelWeights = {internalOptions.m_fChannelWeights[0],internalOptions.m_fChannelWeights[1],internalOptions.m_fChannelWeights[2]};
cmpBlock = CompressBlockBC1_RGBA_Internal(
rgbBlock,
alphaBlock,
channelWeights,
0, // internalOptions.m_nAlphaThreshold,
1, // internalOptions.m_nRefinementSteps
internalOptions.m_fquality,
FALSE);
compressedBlock[2] = cmpBlock.x;
compressedBlock[3] = cmpBlock.y;
}
#endif
//============================================== USER INTERFACES ========================================================
#ifndef ASPM_GPU
int CMP_CDECL CreateOptionsBC3(void **options)
{
CMP_BC15Options *BC15optionsDefault = new CMP_BC15Options;
if (BC15optionsDefault) {
SetDefaultBC15Options(BC15optionsDefault);
(*options) = BC15optionsDefault;
}
else {
(*options) = NULL;
return CGU_CORE_ERR_NEWMEM;
}
return CGU_CORE_OK;
}
int CMP_CDECL DestroyOptionsBC3(void *options)
{
if (!options) return CGU_CORE_ERR_INVALIDPTR;
CMP_BC15Options *BCOptions = reinterpret_cast <CMP_BC15Options *>(options);
delete BCOptions;
return CGU_CORE_OK;
}
int CMP_CDECL SetQualityBC3(void *options,
CGU_FLOAT fquality)
{
if (!options) return CGU_CORE_ERR_INVALIDPTR;
CMP_BC15Options *BC15optionsDefault = reinterpret_cast <CMP_BC15Options *>(options);
if (fquality < 0.0f) fquality = 0.0f;
else
if (fquality > 1.0f) fquality = 1.0f;
BC15optionsDefault->m_fquality = fquality;
return CGU_CORE_OK;
}
int CMP_CDECL SetChannelWeightsBC3(void *options,
CGU_FLOAT WeightRed,
CGU_FLOAT WeightGreen,
CGU_FLOAT WeightBlue) {
if (!options) return 1;
CMP_BC15Options *BC15optionsDefault = (CMP_BC15Options *)options;
if ((WeightRed < 0.0f) || (WeightRed > 1.0f)) return CGU_CORE_ERR_RANGERED;
if ((WeightGreen < 0.0f) || (WeightGreen > 1.0f)) return CGU_CORE_ERR_RANGEGREEN;
if ((WeightBlue < 0.0f) || (WeightBlue > 1.0f)) return CGU_CORE_ERR_RANGEBLUE;
BC15optionsDefault->m_bUseChannelWeighting = true;
BC15optionsDefault->m_fChannelWeights[0] = WeightRed;
BC15optionsDefault->m_fChannelWeights[1] = WeightGreen;
BC15optionsDefault->m_fChannelWeights[2] = WeightBlue;
return CGU_CORE_OK;
}
void DecompressBC3_Internal(CMP_GLOBAL CGU_UINT8 rgbaBlock[64],
const CGU_UINT32 compressedBlock[4],
const CMP_BC15Options *BC15options) {
CGU_UINT8 alphaBlock[BLOCK_SIZE_4X4];
cmp_decompressAlphaBlock(alphaBlock, &compressedBlock[DXTC_OFFSET_ALPHA]);
CGU_Vec2ui compBlock;
compBlock.x = compressedBlock[DXTC_OFFSET_RGB];
compBlock.y = compressedBlock[DXTC_OFFSET_RGB+1];
cmp_decompressDXTRGBA_Internal(rgbaBlock, compBlock,BC15options->m_mapDecodeRGBA);
for (CGU_UINT32 i = 0; i < 16; i++)
((CMP_GLOBAL CGU_UINT32 *)rgbaBlock)[i] =
(alphaBlock[i] << RGBA8888_OFFSET_A) |
(((CMP_GLOBAL CGU_UINT32 *)rgbaBlock)[i] &
~(BYTE_MASK << RGBA8888_OFFSET_A));
}
int CMP_CDECL CompressBlockBC3( const unsigned char *srcBlock,
unsigned int srcStrideInBytes,
CMP_GLOBAL unsigned char cmpBlock[16],
const void *options = NULL) {
CMP_Vec4uc inBlock[16];
//----------------------------------
// Fill the inBlock with source data
//----------------------------------
CGU_INT srcpos = 0;
CGU_INT dstptr = 0;
for (CGU_UINT8 row = 0; row < 4; row++)
{
srcpos = row * srcStrideInBytes;
for (CGU_UINT8 col = 0; col < 4; col++)
{
inBlock[dstptr].x = CGU_UINT8(srcBlock[srcpos++]);
inBlock[dstptr].y = CGU_UINT8(srcBlock[srcpos++]);
inBlock[dstptr].z = CGU_UINT8(srcBlock[srcpos++]);
inBlock[dstptr].w = CGU_UINT8(srcBlock[srcpos++]);
dstptr++;
}
}
CMP_BC15Options *BC15options = (CMP_BC15Options *)options;
CMP_BC15Options BC15optionsDefault;
if (BC15options == NULL) {
BC15options = &BC15optionsDefault;
SetDefaultBC15Options(BC15options);
}
CompressBlockBC3_Internal(inBlock,(CMP_GLOBAL CGU_UINT32 *)cmpBlock, BC15options);
return CGU_CORE_OK;
}
int CMP_CDECL DecompressBlockBC3(const unsigned char cmpBlock[16],
CMP_GLOBAL unsigned char srcBlock[64],
const void *options = NULL) {
CMP_BC15Options *BC15options = (CMP_BC15Options *)options;
CMP_BC15Options BC15optionsDefault;
if (BC15options == NULL)
{
BC15options = &BC15optionsDefault;
SetDefaultBC15Options(BC15options);
}
DecompressBC3_Internal(srcBlock, (CGU_UINT32 *)cmpBlock,BC15options);
return CGU_CORE_OK;
}
#endif
//============================================== OpenCL USER INTERFACE ====================================================
#ifdef ASPM_OPENCL
CMP_STATIC CMP_KERNEL void CMP_GPUEncoder(
CMP_GLOBAL const CMP_Vec4uc *ImageSource,
CMP_GLOBAL CGU_UINT8 *ImageDestination, CMP_GLOBAL Source_Info *SourceInfo,
CMP_GLOBAL CMP_BC15Options *BC15options) {
CGU_UINT32 xID;
CGU_UINT32 yID;
#ifdef ASPM_GPU
xID = get_global_id(0);
yID = get_global_id(1);
#else
xID = 0;
yID = 0;
#endif
if (xID >= (SourceInfo->m_src_width / BlockX)) return;
if (yID >= (SourceInfo->m_src_height / BlockX)) return;
int srcWidth = SourceInfo->m_src_width;
CGU_UINT32 destI =
(xID * BC3CompBlockSize) + (yID * (srcWidth / BlockX) * BC3CompBlockSize);
int srcindex = 4 * (yID * srcWidth + xID);
int blkindex = 0;
CMP_Vec4uc srcData[16];
srcWidth = srcWidth - 4;
for (CGU_INT32 j = 0; j < 4; j++) {
for (CGU_INT32 i = 0; i < 4; i++) {
srcData[blkindex++] = ImageSource[srcindex++];
}
srcindex += srcWidth;
}
CompressBlockBC3_Internal(
srcData, (CMP_GLOBAL CGU_UINT32 *)&ImageDestination[destI], BC15options);
}
#endif

View File

@ -0,0 +1,31 @@
//=====================================================================
// Copyright (c) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// 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 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.
//
//=====================================================================
#ifndef BC3_ENCODE_KERNEL_H
#define BC3_ENCODE_KERNEL_H
#include "Common_Def.h"
#include "BCn_Common_Kernel.h"
#define BC3CompBlockSize 16
#endif

View File

@ -0,0 +1,101 @@
//=====================================================================
// Copyright (c) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// 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 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.
//
// File: BC1Encode.hlsl
//--------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//--------------------------------------------------------------------------------------
#ifndef ASPM_HLSL
#define ASPM_HLSL
#endif
cbuffer cbCS : register( b0 )
{
uint g_tex_width;
uint g_num_block_x;
uint g_format;
uint g_mode_id;
uint g_start_block_id;
uint g_num_total_blocks;
float g_alpha_weight;
float g_quality;
};
#include "BCn_Common_Kernel.h"
// Source Data
Texture2D g_Input : register( t0 );
StructuredBuffer<uint4> g_InBuff : register( t1 );
// Compressed Output Data
RWStructuredBuffer<uint4> g_OutBuff : register( u0 );
// Processing multiple blocks at a time
#define MAX_USED_THREAD 16 // pixels in a BC (block compressed) block
#define BLOCK_IN_GROUP 4 // the number of BC blocks a thread group processes = 64 / 16 = 4
#define THREAD_GROUP_SIZE 64 // 4 blocks where a block is (BLOCK_SIZE_X x BLOCK_SIZE_Y)
#define BLOCK_SIZE_Y 4
#define BLOCK_SIZE_X 4
groupshared float4 shared_temp[THREAD_GROUP_SIZE];
[numthreads( THREAD_GROUP_SIZE, 1, 1 )]
void EncodeBlocks(uint GI : SV_GroupIndex, uint3 groupID : SV_GroupID)
{
// we process 4 BC blocks per thread group
uint blockInGroup = GI / MAX_USED_THREAD; // what BC block this thread is on within this thread group
uint blockID = g_start_block_id + groupID.x * BLOCK_IN_GROUP + blockInGroup; // what global BC block this thread is on
uint pixelBase = blockInGroup * MAX_USED_THREAD; // the first id of the pixel in this BC block in this thread group
uint pixelInBlock = GI - pixelBase; // id of the pixel in this BC block
uint block_y = blockID / g_num_block_x;
uint block_x = blockID - block_y * g_num_block_x;
uint base_x = block_x * BLOCK_SIZE_X;
uint base_y = block_y * BLOCK_SIZE_Y;
// Load up the pixels
if (pixelInBlock < 16)
{
// load pixels (0..1)
shared_temp[GI] = float4(g_Input.Load( uint3( base_x + pixelInBlock % 4, base_y + pixelInBlock / 4, 0 ) ));
}
GroupMemoryBarrierWithGroupSync();
// Process and save s
if (pixelInBlock == 0)
{
float3 blockRGB[16];
float blockA[16];
for (int i = 0; i < 16; i++ )
{
blockRGB[i].x = shared_temp[pixelBase + i].x;
blockRGB[i].y = shared_temp[pixelBase + i].y;
blockRGB[i].z = shared_temp[pixelBase + i].z;
blockA[i] = shared_temp[pixelBase + i].w;
}
g_OutBuff[blockID] = CompressBlockBC3_UNORM(blockRGB,blockA, g_quality,false);
}
}

View File

@ -0,0 +1,213 @@
//=====================================================================
// Copyright (c) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// 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 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.
//
//=====================================================================
#include "BC4_Encode_kernel.h"
//============================================== BC4 INTERFACES =======================================================
void CompressBlockBC4_Internal(const CMP_Vec4uc srcBlockTemp[16],
CMP_GLOBAL CGU_UINT32 compressedBlock[2],
CMP_GLOBAL const CMP_BC15Options *BC15options) {
if (BC15options->m_fquality) {
// Reserved!
}
CGU_UINT8 blkindex = 0;
CGU_UINT8 srcindex = 0;
CGU_FLOAT alphaBlock[16];
for (CGU_INT32 j = 0; j < 4; j++) {
for (CGU_INT32 i = 0; i < 4; i++) {
alphaBlock[blkindex++] = srcBlockTemp[srcindex].x / 255.0f; // Red channel
srcindex++;
}
}
CGU_Vec2ui cmpBlock;
cmpBlock = cmp_compressAlphaBlock(alphaBlock,BC15options->m_fquality);
compressedBlock[0] = cmpBlock.x;
compressedBlock[1] = cmpBlock.y;
}
void DecompressBC4_Internal(CMP_GLOBAL CGU_UINT8 rgbaBlock[64],
const CGU_UINT32 compressedBlock[2],
const CMP_BC15Options *BC15options) {
if (BC15options) {}
CGU_UINT8 alphaBlock[BLOCK_SIZE_4X4];
cmp_decompressAlphaBlock(alphaBlock, compressedBlock);
CGU_UINT8 blkindex = 0;
CGU_UINT8 srcindex = 0;
for (CGU_INT32 j = 0; j < 4; j++) {
for (CGU_INT32 i = 0; i < 4; i++) {
rgbaBlock[blkindex++] = (CGU_UINT8)alphaBlock[srcindex]; // R
rgbaBlock[blkindex++] = (CGU_UINT8)alphaBlock[srcindex]; // G
rgbaBlock[blkindex++] = (CGU_UINT8)alphaBlock[srcindex]; // B
rgbaBlock[blkindex++] = (CGU_UINT8)alphaBlock[srcindex]; // A
srcindex++;
}
}
}
void CompressBlockBC4_SingleChannel(const CGU_UINT8 srcBlockTemp[BLOCK_SIZE_4X4],
CMP_GLOBAL CGU_UINT32 compressedBlock[2],
CMP_GLOBAL const CMP_BC15Options *BC15options) {
if (BC15options) {}
CGU_FLOAT alphaBlock[BLOCK_SIZE_4X4];
for (CGU_INT32 i = 0; i < BLOCK_SIZE_4X4; i++) alphaBlock[i] = (srcBlockTemp[i] / 255.0f);
CGU_Vec2ui cmpBlock;
cmpBlock = cmp_compressAlphaBlock(alphaBlock,BC15options->m_fquality);
compressedBlock[0] = cmpBlock.x;
compressedBlock[1] = cmpBlock.y;
}
void DecompressBlockBC4_SingleChannel(CGU_UINT8 srcBlockTemp[16],
const CGU_UINT32 compressedBlock[2],
const CMP_BC15Options *BC15options) {
if (BC15options) {}
cmp_decompressAlphaBlock(srcBlockTemp, compressedBlock);
}
//============================================== USER INTERFACES ========================================================
#ifndef ASPM_GPU
int CMP_CDECL CreateOptionsBC4(void **options)
{
CMP_BC15Options *BC15optionsDefault = new CMP_BC15Options;
if (BC15optionsDefault) {
SetDefaultBC15Options(BC15optionsDefault);
(*options) = BC15optionsDefault;
}
else {
(*options) = NULL;
return CGU_CORE_ERR_NEWMEM;
}
return CGU_CORE_OK;
}
int CMP_CDECL DestroyOptionsBC4(void *options)
{
if (!options) return CGU_CORE_ERR_INVALIDPTR;
CMP_BC15Options *BCOptions = reinterpret_cast <CMP_BC15Options *>(options);
delete BCOptions;
return CGU_CORE_OK;
}
int CMP_CDECL SetQualityBC4(void *options,
CGU_FLOAT fquality)
{
if (!options) return CGU_CORE_ERR_INVALIDPTR;
CMP_BC15Options *BC15optionsDefault = reinterpret_cast <CMP_BC15Options *>(options);
if (fquality < 0.0f) fquality = 0.0f;
else
if (fquality > 1.0f) fquality = 1.0f;
BC15optionsDefault->m_fquality = fquality;
return CGU_CORE_OK;
}
int CMP_CDECL CompressBlockBC4(const unsigned char *srcBlock,
unsigned int srcStrideInBytes,
CMP_GLOBAL unsigned char cmpBlock[8],
const void *options = NULL) {
unsigned char inBlock[16];
//----------------------------------
// Fill the inBlock with source data
//----------------------------------
CGU_INT srcpos = 0;
CGU_INT dstptr = 0;
for (CGU_UINT8 row = 0; row < 4; row++)
{
srcpos = row * srcStrideInBytes;
for (CGU_UINT8 col = 0; col < 4; col++)
{
inBlock[dstptr++] = CGU_UINT8(srcBlock[srcpos++]);
}
}
CMP_BC15Options *BC15options = (CMP_BC15Options *)options;
if (BC15options == NULL) {
CMP_BC15Options BC15optionsDefault;
BC15options = &BC15optionsDefault;
SetDefaultBC15Options(BC15options);
}
CompressBlockBC4_SingleChannel(inBlock,(CMP_GLOBAL CGU_UINT32 *)cmpBlock, BC15options);
return CGU_CORE_OK;
}
int CMP_CDECL DecompressBlockBC4(const unsigned char cmpBlock[8],
CMP_GLOBAL unsigned char srcBlock[16],
const void *options = NULL) {
CMP_BC15Options *BC15options = (CMP_BC15Options *)options;
CMP_BC15Options BC15optionsDefault;
if (BC15options == NULL)
{
BC15options = &BC15optionsDefault;
SetDefaultBC15Options(BC15options);
}
DecompressBlockBC4_SingleChannel(srcBlock, (CGU_UINT32 *)cmpBlock,BC15options);
return CGU_CORE_OK;
}
#endif
//============================================== OpenCL USER INTERFACE ====================================================
#ifdef ASPM_OPENCL
CMP_STATIC CMP_KERNEL void CMP_GPUEncoder(
CMP_GLOBAL const CMP_Vec4uc *ImageSource,
CMP_GLOBAL CGU_UINT8 *ImageDestination, CMP_GLOBAL Source_Info *SourceInfo,
CMP_GLOBAL CMP_BC15Options *BC15options) {
CGU_UINT32 xID;
CGU_UINT32 yID;
#ifdef ASPM_GPU
xID = get_global_id(0);
yID = get_global_id(1);
#else
xID = 0;
yID = 0;
#endif
if (xID >= (SourceInfo->m_src_width / BlockX)) return;
if (yID >= (SourceInfo->m_src_height / BlockX)) return;
int srcWidth = SourceInfo->m_src_width;
CGU_UINT32 destI =
(xID * BC4CompBlockSize) + (yID * (srcWidth / BlockX) * BC4CompBlockSize);
int srcindex = 4 * (yID * srcWidth + xID);
int blkindex = 0;
CMP_Vec4uc srcData[16];
srcWidth = srcWidth - 4;
for (CGU_INT32 j = 0; j < 4; j++) {
for (CGU_INT32 i = 0; i < 4; i++) {
srcData[blkindex++] = ImageSource[srcindex++];
}
srcindex += srcWidth;
}
CompressBlockBC4_Internal(srcData, (CMP_GLOBAL CGU_UINT32 *)&ImageDestination[destI], BC15options);
}
#endif

View File

@ -0,0 +1,31 @@
//=====================================================================
// Copyright (c) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// 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 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.
//
//=====================================================================
#ifndef BC4_ENCODE_KERNEL_H
#define BC4_ENCODE_KERNEL_H
#include "Common_Def.h"
#include "BCn_Common_Kernel.h"
#define BC4CompBlockSize 8
#endif

View File

@ -0,0 +1,97 @@
//=====================================================================
// Copyright (c) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// 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 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.
//
// File: BC4Encode.hlsl
//--------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//--------------------------------------------------------------------------------------
#ifndef ASPM_HLSL
#define ASPM_HLSL
#endif
cbuffer cbCS : register( b0 )
{
uint g_tex_width;
uint g_num_block_x;
uint g_format;
uint g_mode_id;
uint g_start_block_id;
uint g_num_total_blocks;
float g_alpha_weight;
float g_quality;
};
#include "BCn_Common_Kernel.h"
// Source Data
Texture2D g_Input : register( t0 );
StructuredBuffer<uint4> g_InBuff : register( t1 );
// Compressed Output Data
RWStructuredBuffer<uint2> g_OutBuff : register( u0 );
// Processing multiple blocks at a time
#define MAX_USED_THREAD 16 // pixels in a BC (block compressed) block
#define BLOCK_IN_GROUP 4 // the number of BC blocks a thread group processes = 64 / 16 = 4
#define THREAD_GROUP_SIZE 64 // 4 blocks where a block is (BLOCK_SIZE_X x BLOCK_SIZE_Y)
#define BLOCK_SIZE_Y 4
#define BLOCK_SIZE_X 4
groupshared float4 shared_temp[THREAD_GROUP_SIZE];
[numthreads( THREAD_GROUP_SIZE, 1, 1 )]
void EncodeBlocks(uint GI : SV_GroupIndex, uint3 groupID : SV_GroupID)
{
// we process 4 BC blocks per thread group
uint blockInGroup = GI / MAX_USED_THREAD; // what BC block this thread is on within this thread group
uint blockID = g_start_block_id + groupID.x * BLOCK_IN_GROUP + blockInGroup; // what global BC block this thread is on
uint pixelBase = blockInGroup * MAX_USED_THREAD; // the first id of the pixel in this BC block in this thread group
uint pixelInBlock = GI - pixelBase; // id of the pixel in this BC block
uint block_y = blockID / g_num_block_x;
uint block_x = blockID - block_y * g_num_block_x;
uint base_x = block_x * BLOCK_SIZE_X;
uint base_y = block_y * BLOCK_SIZE_Y;
// Load up the pixels
if (pixelInBlock < 16)
{
// load pixels (0..1)
shared_temp[GI] = float4(g_Input.Load( uint3( base_x + pixelInBlock % 4, base_y + pixelInBlock / 4, 0 ) ));
}
GroupMemoryBarrierWithGroupSync();
// Process and save s
if (pixelInBlock == 0)
{
float block[16];
// covert back to UV for processing!!
for ( uint i = 0; i < 16; i ++ )
{
block[i].x = shared_temp[pixelBase + i].x;
}
g_OutBuff[blockID] = CompressBlockBC4_UNORM(block, g_quality);
}
}

View File

@ -0,0 +1,287 @@
//=====================================================================
// Copyright (c) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// 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 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.
//
//=====================================================================
#include "BC5_Encode_kernel.h"
//============================================== BC5 INTERFACES =======================================================
CGU_Vec4ui CompressBC5Block_Internal(CMP_IN CGU_FLOAT aBlockU[16], CMP_IN CGU_FLOAT aBlockV[16], CMP_IN CGU_FLOAT fquality)
{
CGU_Vec4ui compBlock;
CGU_Vec2ui cmpBlock;
cmpBlock = cmp_compressAlphaBlock(aBlockU,fquality);
compBlock.x = cmpBlock.x;
compBlock.y = cmpBlock.y;
cmpBlock = cmp_compressAlphaBlock(aBlockV,fquality);
compBlock.z = cmpBlock.x;
compBlock.w = cmpBlock.y;
return compBlock;
}
#ifndef ASPM_HLSL
void CompressBlockBC5_Internal(CMP_Vec4uc srcBlockTemp[16], // range 0 to 255
CMP_GLOBAL CGU_UINT32 compressedBlock[4],
CMP_GLOBAL CMP_BC15Options *BC15options)
{
CGU_Vec4ui cmpBlock;
CGU_FLOAT alphaBlockU[16];
CGU_FLOAT alphaBlockV[16];
CGU_UINT32 i;
for (i = 0; i < 16; i++) {
alphaBlockU[i] = srcBlockTemp[i].x / 255.0f;
alphaBlockV[i] = srcBlockTemp[i].y / 255.0f;
}
cmpBlock = CompressBC5Block_Internal(alphaBlockU, alphaBlockV,BC15options->m_fquality);
compressedBlock[0] = cmpBlock.x;
compressedBlock[1] = cmpBlock.y;
compressedBlock[2] = cmpBlock.z;
compressedBlock[3] = cmpBlock.w;
}
#endif
#ifndef ASPM_GPU
void DecompressBC5_Internal(CMP_GLOBAL CGU_UINT8 rgbaBlock[64],
CGU_UINT32 compressedBlock[4],
CMP_BC15Options *BC15options)
{
CGU_UINT8 alphaBlockR[BLOCK_SIZE_4X4];
CGU_UINT8 alphaBlockG[BLOCK_SIZE_4X4];
cmp_decompressAlphaBlock(alphaBlockR, &compressedBlock[0]);
cmp_decompressAlphaBlock(alphaBlockG, &compressedBlock[2]);
CGU_UINT8 blkindex = 0;
CGU_UINT8 srcindex = 0;
if (BC15options->m_mapDecodeRGBA)
{
for (CGU_INT32 j = 0; j < 4; j++) {
for (CGU_INT32 i = 0; i < 4; i++) {
rgbaBlock[blkindex++] = (CGU_UINT8)alphaBlockR[srcindex];
rgbaBlock[blkindex++] = (CGU_UINT8)alphaBlockG[srcindex];
rgbaBlock[blkindex++] = 0;
rgbaBlock[blkindex++] = 255;
srcindex++;
}
}
}
else
{
for (CGU_INT32 j = 0; j < 4; j++) {
for (CGU_INT32 i = 0; i < 4; i++) {
rgbaBlock[blkindex++] = 0;
rgbaBlock[blkindex++] = (CGU_UINT8)alphaBlockG[srcindex];
rgbaBlock[blkindex++] = (CGU_UINT8)alphaBlockR[srcindex];
rgbaBlock[blkindex++] = 255;
srcindex++;
}
}
}
}
void CompressBlockBC5_DualChannel_Internal(const CGU_UINT8 srcBlockR[16],
const CGU_UINT8 srcBlockG[16],
CMP_GLOBAL CGU_UINT32 compressedBlock[4],
CMP_GLOBAL const CMP_BC15Options *BC15options)
{
if (BC15options) {}
CGU_Vec2ui cmpBlock;
CGU_FLOAT srcAlphaRF[16];
CGU_FLOAT srcAlphaGF[16];
for (CGU_INT i =0; i< 16; i++)
{
srcAlphaRF[i] = srcBlockR[i];
srcAlphaGF[i] = srcBlockG[i];
}
cmpBlock = cmp_compressAlphaBlock(srcAlphaRF,BC15options->m_fquality);
compressedBlock[0] = cmpBlock.x;
compressedBlock[1] = cmpBlock.y;
cmpBlock = cmp_compressAlphaBlock(srcAlphaGF,BC15options->m_fquality);
compressedBlock[2] = cmpBlock.x;
compressedBlock[3] = cmpBlock.y;
}
void DecompressBC5_DualChannel_Internal(CMP_GLOBAL CGU_UINT8 srcBlockR[16],
CMP_GLOBAL CGU_UINT8 srcBlockG[16],
const CGU_UINT32 compressedBlock[4],
const CMP_BC15Options *BC15options)
{
if (BC15options) {}
cmp_decompressAlphaBlock(srcBlockR, &compressedBlock[0]);
cmp_decompressAlphaBlock(srcBlockG, &compressedBlock[2]);
}
#endif
//============================================== USER INTERFACES ========================================================
#ifndef ASPM_GPU
int CMP_CDECL CreateOptionsBC5(void **options)
{
CMP_BC15Options *BC15optionsDefault = new CMP_BC15Options;
if (BC15optionsDefault) {
SetDefaultBC15Options(BC15optionsDefault);
(*options) = BC15optionsDefault;
}
else {
(*options) = NULL;
return CGU_CORE_ERR_NEWMEM;
}
return CGU_CORE_OK;
}
int CMP_CDECL DestroyOptionsBC5(void *options)
{
if (!options) return CGU_CORE_ERR_INVALIDPTR;
CMP_BC15Options *BCOptions = reinterpret_cast <CMP_BC15Options *>(options);
delete BCOptions;
return CGU_CORE_OK;
}
int CMP_CDECL SetQualityBC5(void *options,
CGU_FLOAT fquality)
{
if (!options) return CGU_CORE_ERR_INVALIDPTR;
CMP_BC15Options *BC15optionsDefault = reinterpret_cast <CMP_BC15Options *>(options);
if (fquality < 0.0f) fquality = 0.0f;
else
if (fquality > 1.0f) fquality = 1.0f;
BC15optionsDefault->m_fquality = fquality;
return CGU_CORE_OK;
}
int CMP_CDECL CompressBlockBC5(const CGU_UINT8 *srcBlockR,
unsigned int srcStrideInBytes1,
const CGU_UINT8 *srcBlockG,
unsigned int srcStrideInBytes2,
CMP_GLOBAL CGU_UINT8 cmpBlock[16],
const void *options = NULL) {
CGU_UINT8 inBlockR[16];
//----------------------------------
// Fill the inBlock with source data
//----------------------------------
CGU_INT srcpos = 0;
CGU_INT dstptr = 0;
for (CGU_UINT8 row = 0; row < 4; row++)
{
srcpos = row * srcStrideInBytes1;
for (CGU_UINT8 col = 0; col < 4; col++)
{
inBlockR[dstptr++] = CGU_UINT8(srcBlockR[srcpos++]);
}
}
CGU_UINT8 inBlockG[16];
//----------------------------------
// Fill the inBlock with source data
//----------------------------------
srcpos = 0;
dstptr = 0;
for (CGU_UINT8 row = 0; row < 4; row++)
{
srcpos = row * srcStrideInBytes2;
for (CGU_UINT8 col = 0; col < 4; col++)
{
inBlockG[dstptr++] = CGU_UINT8(srcBlockG[srcpos++]);
}
}
CMP_BC15Options *BC15options = (CMP_BC15Options *)options;
CMP_BC15Options BC15optionsDefault;
if (BC15options == NULL)
{
BC15options = &BC15optionsDefault;
SetDefaultBC15Options(BC15options);
}
CompressBlockBC5_DualChannel_Internal(inBlockR,inBlockG, (CMP_GLOBAL CGU_UINT32 *)cmpBlock, BC15options);
return CGU_CORE_OK;
}
int CMP_CDECL DecompressBlockBC5(const CGU_UINT8 cmpBlock[16],
CMP_GLOBAL CGU_UINT8 srcBlockR[16],
CMP_GLOBAL CGU_UINT8 srcBlockG[16],
const void *options = NULL) {
CMP_BC15Options *BC15options = (CMP_BC15Options *)options;
CMP_BC15Options BC15optionsDefault;
if (BC15options == NULL)
{
BC15options = &BC15optionsDefault;
SetDefaultBC15Options(BC15options);
}
DecompressBC5_DualChannel_Internal(srcBlockR,srcBlockG,(CGU_UINT32 *)cmpBlock,BC15options);
return CGU_CORE_OK;
}
#endif
//============================================== OpenCL USER INTERFACE ====================================================
#ifdef ASPM_OPENCL
CMP_STATIC CMP_KERNEL void CMP_GPUEncoder(CMP_GLOBAL const CMP_Vec4uc* ImageSource,
CMP_GLOBAL CGU_UINT8* ImageDestination,
CMP_GLOBAL Source_Info* SourceInfo,
CMP_GLOBAL CMP_BC15Options* BC15options
)
{
CGU_UINT32 xID;
CGU_UINT32 yID;
#ifdef ASPM_GPU
xID = get_global_id(0);
yID = get_global_id(1);
#else
xID = 0;
yID = 0;
#endif
if (xID >= (SourceInfo->m_src_width / BlockX)) return;
if (yID >= (SourceInfo->m_src_height / BlockX)) return;
int srcWidth = SourceInfo->m_src_width;
CGU_UINT32 destI = (xID*BC5CompBlockSize) + (yID*(srcWidth / BlockX)*BC5CompBlockSize);
int srcindex = 4 * (yID * srcWidth + xID);
int blkindex = 0;
CMP_Vec4uc srcData[16];
srcWidth = srcWidth - 4;
for ( CGU_INT32 j = 0; j < 4; j++) {
for ( CGU_INT32 i = 0; i < 4; i++) {
srcData[blkindex++] = ImageSource[srcindex++];
}
srcindex += srcWidth;
}
CompressBlockBC5_Internal(srcData, (CMP_GLOBAL CGU_UINT32 *)&ImageDestination[destI], BC15options);
}
#endif

View File

@ -0,0 +1,31 @@
//=====================================================================
// Copyright (c) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// 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 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.
//
//=====================================================================
#ifndef BC5_ENCODE_KERNEL_H
#define BC5_ENCODE_KERNEL_H
#include "Common_Def.h"
#include "BCn_Common_Kernel.h"
#define BC5CompBlockSize 16
#endif

View File

@ -0,0 +1,98 @@
//=====================================================================
// Copyright (c) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// 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 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.
//
// File: BC1Encode.hlsl
//--------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
//--------------------------------------------------------------------------------------
#ifndef ASPM_HLSL
#define ASPM_HLSL
#endif
cbuffer cbCS : register( b0 )
{
uint g_tex_width;
uint g_num_block_x;
uint g_format;
uint g_mode_id;
uint g_start_block_id;
uint g_num_total_blocks;
float g_alpha_weight;
float g_quality;
};
#include "BCn_Common_Kernel.h"
// Source Data
Texture2D g_Input : register( t0 );
StructuredBuffer<uint4> g_InBuff : register( t1 );
// Compressed Output Data
RWStructuredBuffer<uint4> g_OutBuff : register( u0 );
// Processing multiple blocks at a time
#define MAX_USED_THREAD 16 // pixels in a BC (block compressed) block
#define BLOCK_IN_GROUP 4 // the number of BC blocks a thread group processes = 64 / 16 = 4
#define THREAD_GROUP_SIZE 64 // 4 blocks where a block is (BLOCK_SIZE_X x BLOCK_SIZE_Y)
#define BLOCK_SIZE_Y 4
#define BLOCK_SIZE_X 4
groupshared float4 shared_temp[THREAD_GROUP_SIZE];
[numthreads( THREAD_GROUP_SIZE, 1, 1 )]
void EncodeBlocks(uint GI : SV_GroupIndex, uint3 groupID : SV_GroupID)
{
// we process 4 BC blocks per thread group
uint blockInGroup = GI / MAX_USED_THREAD; // what BC block this thread is on within this thread group
uint blockID = g_start_block_id + groupID.x * BLOCK_IN_GROUP + blockInGroup; // what global BC block this thread is on
uint pixelBase = blockInGroup * MAX_USED_THREAD; // the first id of the pixel in this BC block in this thread group
uint pixelInBlock = GI - pixelBase; // id of the pixel in this BC block
uint block_y = blockID / g_num_block_x;
uint block_x = blockID - block_y * g_num_block_x;
uint base_x = block_x * BLOCK_SIZE_X;
uint base_y = block_y * BLOCK_SIZE_Y;
// Load up the pixels
if (pixelInBlock < 16)
{
// load pixels (0..1)
shared_temp[GI] = float4(g_Input.Load( uint3( base_x + pixelInBlock % 4, base_y + pixelInBlock / 4, 0 ) ));
}
GroupMemoryBarrierWithGroupSync();
// Process and save s
if (pixelInBlock == 0)
{
float blockU[16];
float blockV[16];
for ( uint i = 0; i < 16; i ++ )
{
blockU[i] = shared_temp[pixelBase + i].x;
blockV[i] = shared_temp[pixelBase + i].y;
}
g_OutBuff[blockID] = CompressBlockBC5_UNORM(blockU,blockV,g_quality);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,482 @@
//=====================================================================
// Copyright (c) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// 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 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.
//
//=====================================================================
#ifndef BC6_ENCODE_KERNEL_H
#define BC6_ENCODE_KERNEL_H
#pragma warning(disable:4505) // disable warnings on unreferenced local function has been removed
#include "Common_Def.h"
#define MAX_TRACE 10
#define MAX_ENTRIES_QUANT_TRACE 16
#define BlockX 4
#define BlockY 4
#define BYTEPP 4
#define COMPRESSED_BLOCK_SIZE 16 // Size of a compressed block in bytes
#define MAX_DIMENSION_BIG 4
#define MAX_SUBSET_SIZE 16 // Largest possible size for an individual subset
#define NUM_BLOCK_TYPES 8 // Number of block types in the format
#define MAX_SUBSETS 3 // Maximum number of possible subsets
#define MAX_PARTITIONS 64 // Maximum number of partition types
#define MAX_ENTRIES 64
#define MAX_TRY 20
#define MAX_PARTITIONS_TABLE (1+64+64)
#define DIMENSION 4
#define MAX_CLUSTERS_BIG 16
#define EPSILON 0.000001
#define MAX_CLUSTERS_QUANT_TRACE 8
//# Image Quality will increase as this number gets larger and end-to-end performance time will reduce
#define MAX_INDEX_BITS 4
#define HIGHQULITY_THRESHOLD 0.7F
#define qFAST_THRESHOLD 0.5F
#define F16NEGPREC_LIMIT_VAL -2048.0f //f16 negative precision limit value
#define LOG_CL_RANGE 5
#define LOG_CL_BASE 2
#define BIT_BASE 5
#define BIT_RANGE 9
#define MAX_CLUSTERS 8
#define BTT(bits) (bits-BIT_BASE)
#define CLT(cl) (cl-LOG_CL_BASE)
#define MASK(n) ((1<<(n))-1)
#define SIGN_EXTEND_TYPELESS(x,nb) ((((x)&(1<<((nb)-1)))?((~0)<<(nb)):0)|(x))
#define CMP_HALF_MAX 65504.0f // positive half max
#ifndef ASPM_GPU
#include <bitset>
#include <assert.h>
//typedef uint8_t byte;
#else
//typedef bitset uint8_t;
//typedef uint8 byte;
#endif
#define BC6CompBlockSize 16
#define BC6BlockX 4
#define BC6BlockY 4
typedef struct
{
CGU_INT k;
CGU_FLOAT d;
} BC6H_TRACE;
#define NCHANNELS 3
#define MAX_END_POINTS 2
#define MAX_BC6H_MODES 14
#define MAX_BC6H_PARTITIONS 32
#define MAX_TWOREGION_MODES 10
#define COMPRESSED_BLOCK_SIZE 16 // Size of a compressed block in bytes
#define ONE_REGION_INDEX_OFFSET 65 // bit location to start saving color index values for single region shape
#define TWO_REGION_INDEX_OFFSET 82 // bit location to start saving color index values for two region shapes
#define MIN_MODE_FOR_ONE_REGION 11 // Two regions shapes use modes 1..9 and single use 11..14
#define R_0(ep) (ep)[0][0][i]
#define R_1(ep) (ep)[0][1][i]
#define R_2(ep) (ep)[1][0][i]
#define R_3(ep) (ep)[1][1][i]
#define FLT16_MAX 0x7bff
#ifndef ASPM_GPU
#define USE_SHAKERHD
#endif
#define USE_NEWRAMP
typedef struct
{
CGU_FLOAT A[NCHANNELS];
CGU_FLOAT B[NCHANNELS];
} END_Points;
typedef struct
{
CGU_FLOAT x, y, z;
} BC6H_Vec3f;
typedef struct
{
CGU_INT nbits; // Number of bits
CGU_INT prec[3]; // precission of the Qunatized RGB endpoints
CGU_INT transformed; // if 0, deltas are unsigned and no transform; otherwise, signed and transformed
CGU_INT modebits; // number of mode bits
CGU_INT IndexPrec; // Index Precision
CGU_INT mode; // Mode value to save
CGU_INT lowestPrec; // Step size of each precesion incriment
} ModePartitions;
__constant ModePartitions ModePartition[MAX_BC6H_MODES + 1] =
{
{0, {0,0,0}, 0, 0, 0, 0, 0}, // Mode = Invaild
// Two region Partition
{ 10, {5,5,5}, 1, 2, 3, 0x00, 31 }, // Mode = 1
{ 7, {6,6,6}, 1, 2, 3, 0x01, 248}, // Mode = 2
{ 11, {5,4,4}, 1, 5, 3, 0x02, 15 }, // Mode = 3
{ 11, {4,5,4}, 1, 5, 3, 0x06, 15 }, // Mode = 4
{ 11, {4,4,5}, 1, 5, 3, 0x0a, 15 }, // Mode = 5
{ 9, {5,5,5}, 1, 5, 3, 0x0e, 62 }, // Mode = 6
{ 8, {6,5,5}, 1, 5, 3, 0x12, 124}, // Mode = 7
{ 8, {5,6,5}, 1, 5, 3, 0x16, 124}, // Mode = 8
{ 8, {5,5,6}, 1, 5, 3, 0x1a, 124}, // Mode = 9
{ 6, {6,6,6}, 0, 5, 3, 0x1e, 496}, // Mode = 10
// One region Partition
{10, {10,10,10}, 0, 5, 4, 0x03, 31}, // Mode = 11
{11, {9,9,9 }, 1, 5, 4, 0x07, 15}, // Mode = 12
{12, {8,8,8 }, 1, 5, 4, 0x0b, 7 }, // Mode = 13
{16, {4,4,4 }, 1, 5, 4, 0x0f, 1 } // Mode = 14
};
//================================================
// Mode Pathern order to try on endpoints
// The order can be rearranged to set which modes gets processed first
// for now it is set in order.
//================================================
__constant CGU_INT8 ModeFitOrder[MAX_BC6H_MODES + 1] =
{
0, //0: N/A
// ---- 2 region lower bits ---
1, // 10 5 5 5
2, // 7 6 6 6
3, // 11 5 4 5
4, // 11 4 5 4
5, // 11 4 4 5
6, // 9 5 5 5
7, // 8 6 5 5
8, // 8 5 6 5
9, // 8 5 5 6
10, // 6 6 6 6
//------ 1 region high bits ---
11, // 10 10 10 10
12, // 11 9 9 9
13, // 12 8 8 8
14 // 16 4 4 4
};
// The Region2FixUps are for our index[subset = 2][16][3] locations
// indexed by shape region 2
__constant CGU_INT g_Region2FixUp[32] =
{
7 , 3 , 11, 7,
3 , 11, 9 , 5,
2 , 12, 7 , 3,
11, 7 , 11, 3,
7 , 1 , 0 , 1,
0 , 1 , 0 , 7,
0 , 1 , 1 , 0,
4 , 4 , 1 , 0,
};
// Indexed by all shape regions
// Partition Set Fixups for region 1 note region 0 is always at 0
// that means normally we use 3 bits to define an index value
// if its at the fix up location then its one bit less
__constant CGU_INT g_indexfixups[32] =
{
15,15,15,15,
15,15,15,15,
15,15,15,15,
15,15,15,15,
15, 2, 8, 2,
2, 8, 8,15,
2, 8, 2, 2,
8, 8, 2, 2,
};
typedef struct
{
CGU_INT8 region; // one or two
CGU_INT8 m_mode; // m
CGU_INT8 d_shape_index; // d
CGU_INT rw; // endpt[0].A[0]
CGU_INT rx; // endpt[0].B[0]
CGU_INT ry; // endpt[1].A[0]
CGU_INT rz; // endpt[1].B[0]
CGU_INT gw; // endpt[0].A[1]
CGU_INT gx; // endpt[0].B[1]
CGU_INT gy; // endpt[1].A[1]
CGU_INT gz; // endpt[1].B[1]
CGU_INT bw; // endpt[0].A[2]
CGU_INT bx; // endpt[0].B[2]
CGU_INT by; // endpt[1].A[2]
CGU_INT bz; // endpt[1].B[2]
union
{
CGU_UINT8 indices[4][4]; // Indices data after header block
CGU_UINT8 indices16[16];
};
union
{
CGU_FLOAT din[MAX_SUBSET_SIZE][MAX_DIMENSION_BIG]; // Original data input as floats
unsigned char cdin[256]; // as uchar to match float
};
END_Points EC[MAX_END_POINTS]; // compressed endpoints expressed as endpt[0].A[] and endpt[1].B[]
END_Points E[MAX_END_POINTS]; // decompressed endpoints
CGU_BOOL issigned; // Format is 16 bit signed floating point
CGU_BOOL istransformed; // region two: all modes = true except mode=10
short wBits; // number of bits for the root endpoint
short tBits[NCHANNELS]; // number of bits used for the transformed endpoints
CGU_INT format; // floating point format are we using for decompression
BC6H_Vec3f Paletef[2][16];
CGU_INT index; // for debugging
CGU_FLOAT fEndPoints[MAX_SUBSETS][MAX_END_POINTS][MAX_DIMENSION_BIG];
CGU_FLOAT cur_best_fEndPoints[MAX_SUBSETS][MAX_END_POINTS][MAX_DIMENSION_BIG];
CGU_INT shape_indices[MAX_SUBSETS][MAX_SUBSET_SIZE];
CGU_INT cur_best_shape_indices[MAX_SUBSETS][MAX_SUBSET_SIZE];
CGU_INT entryCount[MAX_SUBSETS];
CGU_INT cur_best_entryCount[MAX_SUBSETS];
CGU_FLOAT partition[MAX_SUBSETS][MAX_SUBSET_SIZE][MAX_DIMENSION_BIG];
CGU_FLOAT cur_best_partition[MAX_SUBSETS][MAX_SUBSET_SIZE][MAX_DIMENSION_BIG];
CGU_BOOL optimized; // were end points optimized during final encoding
} BC6H_Encode_local;
#ifndef ASPM_GPU
using namespace std;
class BitHeader
{
public:
BitHeader(const CGU_UINT8 in[], CGU_INT sizeinbytes)
{
m_bits.reset();
m_sizeinbytes = sizeinbytes;
if ((in != NULL) && (sizeinbytes <= 16))
{
// Init bits set with given data
CGU_INT bitpos = 0;
for (CGU_INT i = 0; i < sizeinbytes; i++)
{
CGU_INT bit = 1;
for (CGU_INT j = 0; j < 8; j++)
{
m_bits[bitpos] = in[i] & bit ? 1 : 0;
bit = bit << 1;
bitpos++;
}
}
}
}
~BitHeader()
{
}
void transferbits(CGU_UINT8 in[], CGU_INT sizeinbytes)
{
if ((sizeinbytes <= m_sizeinbytes) && (in != NULL))
{
// Init bits set with given data
memset(in, 0, sizeinbytes);
CGU_INT bitpos = 0;
for (CGU_INT i = 0; i < sizeinbytes; i++)
{
CGU_INT bit = 1;
for (CGU_INT j = 0; j < 8; j++)
{
if (m_bits[bitpos]) in[i] |= bit;
bit = bit << 1;
bitpos++;
}
}
}
}
CGU_INT getvalue(CGU_INT start, CGU_INT bitsize)
{
CGU_INT value = 0;
CGU_INT end = start + bitsize - 1;
for (; end >= start; end--)
{
value |= m_bits[end] ? 1 : 0;
if (end > start) value <<= 1;
}
return value;
}
void setvalue(CGU_INT start, CGU_INT bitsize, CGU_INT value, CGU_INT maskshift = 0)
{
CGU_INT end = start + bitsize - 1;
CGU_INT mask = 0x1 << maskshift;
for (; start <= end; start++)
{
m_bits[start] = (value&mask) ? 1 : 0;
mask <<= 1;
}
}
bitset<128> m_bits; // 16 bytes max
CGU_INT m_sizeinbytes;
};
//==================== DECODER CODE ======================
#define MAXENDPOINTS 2
#define U16MAX 0xffff
#define S16MAX 0x7fff
#define SIGN_EXTEND(w,tbits) ((((signed(w))&(1<<((tbits)-1)))?((~0)<<(tbits)):0)|(signed(w)))
enum
{
UNSIGNED_F16 = 1,
SIGNED_F16 = 2
};
enum
{
BC6_ONE = 0,
BC6_TWO
};
enum
{
C_RED = 0,
C_GREEN,
C_BLUE
};
struct BC6H_Vec3
{
int x,y,z;
};
struct AMD_BC6H_Format
{
unsigned short region; // one or two
unsigned short m_mode; // m
int d_shape_index; // d
int rw; // endpt[0].A[0]
int rx; // endpt[0].B[0]
int ry; // endpt[1].A[0]
int rz; // endpt[1].B[0]
int gw; // endpt[0].A[1]
int gx; // endpt[0].B[1]
int gy; // endpt[1].A[1]
int gz; // endpt[1].B[1]
int bw; // endpt[0].A[2]
int bx; // endpt[0].B[2]
int by; // endpt[1].A[2]
int bz; // endpt[1].B[2]
union
{
CGU_UINT8 indices[4][4]; // Indices data after header block
CGU_UINT8 indices16[16];
};
float din[MAX_SUBSET_SIZE][MAX_DIMENSION_BIG]; // Original data input
END_Points EC[MAXENDPOINTS]; // compressed endpoints expressed as endpt[0].A[] and endpt[1].B[]
END_Points E[MAXENDPOINTS]; // decompressed endpoints
bool issigned; // Format is 16 bit signed floating point
bool istransformed; // region two: all modes = true except mode=10
short wBits; // number of bits for the root endpoint
short tBits[NCHANNELS]; // number of bits used for the transformed endpoints
int format; // floating point format are we using for decompression
BC6H_Vec3 Palete[2][16];
BC6H_Vec3f Paletef[2][16];
int index; // for debugging
float fEndPoints[MAX_SUBSETS][MAX_END_POINTS][MAX_DIMENSION_BIG];
float cur_best_fEndPoints[MAX_SUBSETS][MAX_END_POINTS][MAX_DIMENSION_BIG];
int shape_indices[MAX_SUBSETS][MAX_SUBSET_SIZE];
int cur_best_shape_indices[MAX_SUBSETS][MAX_SUBSET_SIZE];
int entryCount[MAX_SUBSETS];
int cur_best_entryCount[MAX_SUBSETS];
float partition[MAX_SUBSETS][MAX_SUBSET_SIZE][MAX_DIMENSION_BIG];
float cur_best_partition[MAX_SUBSETS][MAX_SUBSET_SIZE][MAX_DIMENSION_BIG];
bool optimized; // were end points optimized during final encoding
};
// =================================== END OF DECODER CODE ========================================================
#endif
//-------------------------------------------------
// Set by Host : Read only in kernel
//-------------------------------------------------
typedef struct
{
// Setup at initialization time
CGU_FLOAT m_quality;
CGU_FLOAT m_performance;
CGU_FLOAT m_errorThreshold;
CGU_DWORD m_validModeMask;
CGU_BOOL m_imageNeedsAlpha;
CGU_BOOL m_colourRestrict;
CGU_BOOL m_alphaRestrict;
CGU_BOOL m_isSigned;
} CMP_BC6HOptions;
typedef struct
{
// These are quality parameters used to select when to use the high precision quantizer
// and shaker paths
CGU_FLOAT m_quantizerRangeThreshold;
CGU_FLOAT m_shakerRangeThreshold;
CGU_FLOAT m_partitionSearchSize;
// Setup at initialization time
CGU_FLOAT m_quality;
CGU_FLOAT m_performance;
CGU_FLOAT m_errorThreshold;
CGU_DWORD m_validModeMask;
CGU_BOOL m_imageNeedsAlpha;
CGU_BOOL m_colourRestrict;
CGU_BOOL m_alphaRestrict;
CGU_BOOL m_isSigned;
// Source image info : must be set prior to use in kernel
CGU_UINT32 m_src_width;
CGU_UINT32 m_src_height;
CGU_UINT32 m_src_stride;
} BC6H_Encode;
CMP_STATIC void SetDefaultBC6Options(BC6H_Encode *BC6Encode)
{
if (BC6Encode)
{
BC6Encode->m_quality = 1.0f;
BC6Encode->m_quantizerRangeThreshold = 0.0f;
BC6Encode->m_shakerRangeThreshold = 0.0f;
BC6Encode->m_partitionSearchSize = 0.20f;
BC6Encode->m_performance = 0.0f;
BC6Encode->m_errorThreshold = 0.0f;
BC6Encode->m_validModeMask = 0;
BC6Encode->m_imageNeedsAlpha = 0;
BC6Encode->m_colourRestrict = 0;
BC6Encode->m_alphaRestrict = 0;
BC6Encode->m_isSigned = 0;
BC6Encode->m_src_width = 4;
BC6Encode->m_src_height = 4;
BC6Encode->m_src_stride = 0;
}
}
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

454
extern/CMP_Core/shaders/Common_Def.h vendored Normal file
View File

@ -0,0 +1,454 @@
//===============================================================================
// Copyright (c) 2007-2020 Advanced Micro Devices, Inc. All rights reserved.
// Copyright (c) 2004-2006 ATI Technologies Inc.
//===============================================================================
//
// 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 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.
//
//
// File Name: Common_Def
// Description: common definitions used for CPU/HPC/GPU
//
//////////////////////////////////////////////////////////////////////////////
#ifndef _COMMON_DEFINITIONS_H
#define _COMMON_DEFINITIONS_H
// The shaders for UE4 require extension in the form of .ush in place of standard .h
// this directive is used to make the change without users requiring to modify all of the include extensions
// specific to UE4
#ifdef ASPM_HLSL_UE4
#pragma once
#define INC_cmp_math_vec4 "cmp_math_vec4.ush"
#define INC_cmp_math_func "cmp_math_func.ush"
#else
#define INC_cmp_math_vec4 "cmp_math_vec4.h"
#define INC_cmp_math_func "cmp_math_func.h"
#endif
// Features
#ifdef _WIN32
//#define USE_ASPM_CODE
#endif
// Proxy ISPC compiler (Warning! Not all ASPM features will be available : expect build errors for specialized ASPM code!
#ifdef ISPC
#define ASPM
#endif
// Using OpenCL Compiler
#ifdef __OPENCL_VERSION__
#define ASPM_GPU
#define ASPM_OPENCL
#endif
// Using DirectX fxc Compiler
// Note use the /DASPM_HLSL command line to define this
#ifdef ASPM_HLSL
#define ASPM_GPU
#endif
#ifdef _LINUX
#undef ASPM_GPU
#undef ASPM_OPENCL
#ifndef ASPM_HLSL
#include <cstring>
#include <cmath>
#include <stdio.h>
#include INC_cmp_math_vec4
#endif
#endif
#ifndef CMP_MAX
#define CMP_MAX(x, y) (((x) > (y)) ? (x) : (y))
#endif
#ifndef CMP_MIN
#define CMP_MIN(x, y) (((x) < (y)) ? (x) : (y))
#endif
#ifndef ASPM_GPU
#define CMP_STATIC_CAST(x,y) static_cast<x>(y)
#else
#define CMP_STATIC_CAST(x,y) (x)(y)
#endif
#define CMP_SET_BC13_DECODER_RGBA // Sets mapping BC1, BC2 & BC3 to decode Red,Green,Blue and Alpha
// RGBA to channels [0,1,2,3] else BGRA maps to [0,1,2,3]
// BC4 alpha always maps as AAAA to channels [0,1,2,3]
// BC5 decoded (Red&Green) maps R,G,B=0,A=255 to [0,1,2,3] else maps [B=0,G,R,A=255] to [0,1,2,3]
//#define USE_BLOCK_LINEAR
#define CMP_FLOAT_MAX 3.402823466e+38F // max value used to detect an Error in processing
#define CMP_FLOAT_MAX_EXP 38
#define USE_PROCESS_SEPERATE_ALPHA // Enable this to use higher quality code using CompressDualIndexBlock
#define COMPRESSED_BLOCK_SIZE 16 // Size of a compressed block in bytes
#define MAX_DIMENSION_BIG 4 // Max number of channels (RGBA)
#define MAX_SUBSETS 3 // Maximum number of possible subsets
#define MAX_SUBSET_SIZE 16 // Largest possible size for an individual subset
#define BLOCK_SIZE_4X4X4 64
#define BLOCK_SIZE_4X4 16
#define BlockX 4
#define BlockY 4
//#define USE_BLOCK_LINEAR // Source Data is organized in linear form for each block : Experimental Code not fully developed
//#define USE_DOUBLE // Default is to use float, enable to use double data types only for float definitions
//---------------------------------------------
// Predefinitions for GPU and CPU compiled code
//---------------------------------------------
#ifdef ASPM_HLSL
// ==== Vectors ====
typedef float2 CGU_Vec2f;
typedef float2 CGV_Vec2f;
typedef float3 CGU_Vec3f;
typedef float3 CGV_Vec3f;
typedef float4 CGU_Vec4f;
typedef float4 CGV_Vec4f;
typedef int2 CGU_Vec2i;
typedef int2 CGV_Vec2i;
typedef uint2 CGU_Vec2ui;
typedef uint2 CGV_Vec2ui;
typedef int3 CGU_Vec3i;
typedef int3 CGV_Vec3i;
typedef uint3 CGU_Vec3ui;
typedef uint3 CGV_Vec3ui;
typedef uint4 CGU_Vec4ui;
typedef uint4 CGV_Vec4ui;
// ==== Scalar Types ==== to remove from code
typedef int CGU_INT8;
typedef uint CGU_INT;
typedef int CGV_INT;
typedef uint CGU_UINT8;
typedef uint CGU_UINT;
// ==== Scalar Types ====
typedef int CGU_BOOL;
typedef int CGV_BOOL;
typedef int CGU_INT32;
typedef int CGV_INT32;
typedef uint CGU_UINT32;
typedef uint CGV_UINT32;
typedef float CGV_FLOAT;
typedef float CGU_FLOAT;
typedef min16float CGU_MIN16_FLOAT; // FP16 GPU support defaults to 32 bit if no HW support
#define TRUE 1
#define FALSE 0
#define CMP_CDECL
#define BC7_ENCODECLASS
#define CMP_EXPORT
#define INLINE
#define uniform
#define varying
#define CMP_GLOBAL
#define CMP_KERNEL
#define CMP_CONSTANT
#define CMP_STATIC
#define CMP_REFINOUT
#define CMP_PTRINOUT
#define CMP_INOUT inout
#define CMP_OUT out
#define CMP_IN in
#define CMP_UNUSED(x) (x);
#define CMP_UNROLL [unroll]
#else
typedef enum {
CGU_CORE_OK = 0, // No errors, call was successfull
CGU_CORE_ERR_UNKOWN, // An unknown error occurred
CGU_CORE_ERR_NEWMEM, // New Memory Allocation Failed
CGU_CORE_ERR_INVALIDPTR, // The pointer value used is invalid or null
CGU_CORE_ERR_RANGERED, // values for Red Channel is out of range (too high or too low)
CGU_CORE_ERR_RANGEGREEN, // values for Green Channel is out of range (too high or too low)
CGU_CORE_ERR_RANGEBLUE, // values for Blue Channel is out of range (too high or too low)
} CGU_ERROR_CODES;
#ifdef ASPM_OPENCL // GPU Based code using OpenCL
// ==== Vectors ====
typedef float2 CGU_Vec2f;
typedef float2 CGV_Vec2f;
typedef float3 CMP_Vec3f;
typedef float3 CGU_Vec3f;
typedef float3 CGV_Vec3f;
typedef float4 CGU_Vec4f;
typedef float4 CGV_Vec4f;
typedef uchar3 CGU_Vec3uc;
typedef uchar3 CGV_Vec3uc;
typedef uchar4 CMP_Vec4uc;
typedef uchar4 CGU_Vec4uc;
typedef uchar4 CGV_Vec4uc;
typedef int2 CGU_Vec2i;
typedef int2 CGV_Vec2i;
typedef int3 CGU_Vec3i;
typedef int3 CGV_Vec3i;
typedef int4 CGU_Vec4i;
typedef int4 CGV_Vec4i;
typedef uint2 CGU_Vec2ui;
typedef uint2 CGV_Vec2ui;
typedef uint3 CGU_Vec3ui;
typedef uint3 CGV_Vec3ui;
typedef uint4 CGU_Vec4ui;
typedef uint4 CGV_Vec4ui;
#define USE_BC7_SP_ERR_IDX
#define BC7_ENCODECLASS
#define ASPM_PRINT(args) printf args
#define CMP_EXPORT
#define INLINE
#define uniform
#define varying
#define CMP_GLOBAL __global
#define CMP_KERNEL __kernel
#define CMP_CONSTANT __constant
#define CMP_STATIC
#define CMP_REFINOUT &
#define CMP_PTRINOUT *
#define CMP_INOUT
#define CMP_OUT
#define CMP_IN
#define CMP_UNUSED(x)
#define CMP_UNROLL
typedef unsigned int CGU_DWORD; //32bits
typedef int CGU_INT; //32bits
typedef bool CGU_BOOL;
typedef unsigned short CGU_SHORT; //16bits
typedef float CGU_FLOAT;
typedef half CGU_MIN16_FLOAT; // FP16 GPU support defaults to 32 bit if no HW support
typedef unsigned int uint32; // need to remove this def
typedef int CGV_INT;
typedef unsigned int CGU_UINT;
typedef int CGUV_INT;
typedef int CGV_BOOL;
typedef char CGU_INT8;
typedef unsigned char CGU_UINT8;
typedef short CGU_INT16;
typedef unsigned short CGU_UINT16;
typedef int CGU_INT32;
typedef unsigned int CGU_UINT32;
typedef unsigned long CGU_UINT64;
typedef char CGV_INT8;
typedef unsigned char CGV_UINT8;
typedef short CGV_INT16;
typedef unsigned short CGV_UINT16;
typedef int CGV_INT32;
typedef unsigned int CGV_UINT32;
typedef unsigned long CGV_UINT64;
typedef float CGV_FLOAT;
#define TRUE 1
#define FALSE 0
#define CMP_CDECL
#else
// CPU & ASPM definitions
#define CMP_REFINOUT &
#define CMP_PTRINOUT *
#define CMP_INOUT
#define CMP_OUT
#define CMP_IN
#define CMP_UNUSED(x) (void)(x);
#define CMP_UNROLL
#ifdef ASPM // SPMD ,SIMD CPU code
// using hybrid (CPU/GPU) aspm compiler
#define ASPM_PRINT(args) print args
#define CMP_USE_FOREACH_ASPM
#define __ASPM__
#define BC7_ENCODECLASS
#define USE_BC7_SP_ERR_IDX
//#define USE_BC7_RAMP
#define CMP_EXPORT export
#define TRUE true
#define FALSE false
typedef uniform bool CGU_BOOL;
typedef bool CGV_BOOL;
typedef unsigned int8 uint8;
typedef unsigned int16 uint16;
typedef unsigned int32 uint32;
typedef unsigned int64 uint64;
typedef uniform float CGU_FLOAT;
typedef varying float CGV_FLOAT;
typedef uniform float CGU_MIN16_FLOAT;
typedef uniform uint8 CGU_UINT8;
typedef varying uint8 CGV_UINT8;
typedef CGV_UINT8<4> CGV_Vec4uc;
typedef CGU_UINT8<4> CGU_Vec4uc;
typedef CGU_FLOAT<2> CGU_Vec2f;
typedef CGV_FLOAT<2> CGV_Vec2f;
typedef CGU_FLOAT<3> CGU_Vec3f;
typedef CGV_FLOAT<3> CGV_Vec3f;
typedef CGU_FLOAT<4> CGU_Vec4f;
typedef CGV_FLOAT<4> CGV_Vec4f;
typedef CGU_UINT32<3> CGU_Vec3ui;
typedef CGV_UINT32<3> CGV_Vec3ui;
typedef CGU_UINT32<4> CGU_Vec4ui;
typedef CGV_UINT32<4> CGV_Vec4ui;
#define CMP_CDECL
#else // standard CPU code
#include <stdio.h>
#include <string>
#include INC_cmp_math_vec4
// using CPU compiler
#define ASPM_PRINT(args) printf args
#define USE_BC7_RAMP
#define USE_BC7_SP_ERR_IDX
#define CMP_EXPORT
#define BC7_ENCODECLASS BC7_EncodeClass::
#define TRUE 1
#define FALSE 0
#define uniform
#define varying
typedef char int8;
typedef short int16;
typedef int int32;
typedef long int64;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef unsigned long uint64;
typedef int8 CGV_BOOL;
typedef bool CGU_BOOL;
typedef int16 CGU_WORD;
typedef uint8 CGU_SHORT;
typedef int64 CGU_LONG;
typedef uint64 CGU_ULONG;
typedef uniform float CGU_FLOAT;
typedef varying float CGV_FLOAT;
typedef uniform float CGU_MIN16_FLOAT;
typedef uniform uint8 CGU_UINT8;
typedef varying uint8 CGV_UINT8;
typedef CMP_Vec3ui CGU_Vec3ui;
typedef CMP_Vec3ui CGV_Vec3ui;
typedef CMP_Vec4ui CGU_Vec4ui;
typedef CMP_Vec4ui CGV_Vec4ui;
typedef CMP_Vec4f CGU_Vec4f;
typedef CMP_Vec4f CGV_Vec4f;
#if defined(WIN32) || defined(_WIN64)
#define CMP_CDECL __cdecl
#else
#define CMP_CDECL
#endif
#endif
// Common CPU & ASPM definitions
#define CMP_ASSERT(arg)
#define CMP_GLOBAL
#define CMP_KERNEL
#define __local const
#define __constant const
#define CMP_CONSTANT const
#define INLINE inline
#define CMP_STATIC static
typedef uniform int32 CGU_DWORD;
typedef uniform uint8 CGU_UBYTE;
typedef uniform int CGU_INT;
typedef uniform int8 CGU_INT8;
typedef uniform int16 CGU_INT16;
typedef uniform uint16 CGU_UINT16;
typedef uniform int32 CGU_INT32;
typedef uniform uint32 CGU_UINT32;
typedef uniform uint64 CGU_UINT64;
typedef int CGV_INT;
typedef int8 CGV_INT8;
typedef int16 CGV_INT16;
typedef int32 CGV_INT32;
typedef uint16 CGV_UINT16;
typedef uint32 CGV_UINT32;
typedef uint64 CGV_UINT64;
#endif // else ASPM_GPU
typedef struct
{
CGU_UINT32 m_src_width;
CGU_UINT32 m_src_height;
CGU_UINT32 m_width_in_blocks;
CGU_UINT32 m_height_in_blocks;
CGU_FLOAT m_fquality;
} Source_Info;
typedef unsigned char* CGU_PTR;
// Ref Compute_CPU_HPC
struct texture_surface
{
CGU_PTR ptr;
CGU_INT width,
height,
stride;
CGU_INT channels;
};
#endif // else ASPM_HLSL
#endif // Common_Def.h

69
extern/CMP_Core/shaders/CopyFiles.bat vendored Normal file
View File

@ -0,0 +1,69 @@
REM ====================================
REM Hybrid Codecs: Full support in v4.0
REM ====================================
REM gets the output dir
set BUILD_OUTDIR=%1
REM get the batch files dir
SET mypath=%~dp0
echo %mypath:~0,-1%
IF NOT EXIST "%outpath%"\Plugins mkdir %BUILD_OUTDIR%Plugins
IF NOT EXIST "%outpath%"\Plugins\Compute mkdir %BUILD_OUTDIR%Plugins\Compute
REM ToDo: Build Vulkan based shaders
REM "%VULKAN_SDK%"\bin\glslangvalidator -V %mypath:~0,-1%\BC1... -o %BUILD_OUTDIR%\Plugins\Compute\BC1....spv
REM IF %ERRORLEVEL% GTR 0 exit 123
REM Remove any OpenCL compiled Binaries
REM
del %BUILD_OUTDIR%Plugins\Compute\BC1_Encode_kernel.cpp.cmp
del %BUILD_OUTDIR%Plugins\Compute\BC1_Encode_kernel.hlsl.cmp
del %BUILD_OUTDIR%Plugins\Compute\BC2_Encode_kernel.cpp.cmp
del %BUILD_OUTDIR%Plugins\Compute\BC2_Encode_kernel.hlsl.cmp
del %BUILD_OUTDIR%Plugins\Compute\BC3_Encode_kernel.cpp.cmp
del %BUILD_OUTDIR%Plugins\Compute\BC3_Encode_kernel.hlsl.cmp
del %BUILD_OUTDIR%Plugins\Compute\BC4_Encode_kernel.cpp.cmp
del %BUILD_OUTDIR%Plugins\Compute\BC4_Encode_kernel.hlsl.cmp
del %BUILD_OUTDIR%Plugins\Compute\BC5_Encode_kernel.cpp.cmp
del %BUILD_OUTDIR%Plugins\Compute\BC5_Encode_kernel.hlsl.cmp
del %BUILD_OUTDIR%Plugins\Compute\BC6_Encode_kernel.cpp.cmp
del %BUILD_OUTDIR%Plugins\Compute\BC6_Encode_kernel.hlsl.cmp
del %BUILD_OUTDIR%Plugins\Compute\BC6_Encode_kernel.hlsl.0.cmp
del %BUILD_OUTDIR%Plugins\Compute\BC6_Encode_kernel.hlsl.1.cmp
del %BUILD_OUTDIR%Plugins\Compute\BC7_Encode_Kernel.cpp.cmp
del %BUILD_OUTDIR%Plugins\Compute\BC7_Encode_Kernel.hlsl.cmp
del %BUILD_OUTDIR%Plugins\Compute\BC7_Encode_Kernel.hlsl.0.cmp
del %BUILD_OUTDIR%Plugins\Compute\BC7_Encode_Kernel.hlsl.1.cmp
del %BUILD_OUTDIR%Plugins\Compute\BC7_Encode_Kernel.hlsl.2.cmp
XCopy /r /d /y "%mypath:~0,-1%\Common_Def.h" %BUILD_OUTDIR%Plugins\Compute\
XCopy /r /d /y "%mypath:~0,-1%\BCn_Common_Kernel.h" %BUILD_OUTDIR%Plugins\Compute\
XCopy /r /d /y "%mypath:~0,-1%\BC1_Encode_kernel.h" %BUILD_OUTDIR%Plugins\Compute\
XCopy /r /d /y "%mypath:~0,-1%\BC1_Encode_kernel.hlsl" %BUILD_OUTDIR%Plugins\Compute\
XCopy /r /d /y "%mypath:~0,-1%\BC1_Encode_kernel.cpp" %BUILD_OUTDIR%Plugins\Compute\
XCopy /r /d /y "%mypath:~0,-1%\BC2_Encode_kernel.h" %BUILD_OUTDIR%Plugins\Compute\
XCopy /r /d /y "%mypath:~0,-1%\BC2_Encode_kernel.hlsl" %BUILD_OUTDIR%Plugins\Compute\
XCopy /r /d /y "%mypath:~0,-1%\BC2_Encode_kernel.cpp" %BUILD_OUTDIR%Plugins\Compute\
XCopy /r /d /y "%mypath:~0,-1%\BC3_Encode_kernel.h" %BUILD_OUTDIR%Plugins\Compute\
XCopy /r /d /y "%mypath:~0,-1%\BC3_Encode_kernel.hlsl" %BUILD_OUTDIR%Plugins\Compute\
XCopy /r /d /y "%mypath:~0,-1%\BC3_Encode_kernel.cpp" %BUILD_OUTDIR%Plugins\Compute\
XCopy /r /d /y "%mypath:~0,-1%\BC4_Encode_kernel.h" %BUILD_OUTDIR%Plugins\Compute\
XCopy /r /d /y "%mypath:~0,-1%\BC4_Encode_kernel.hlsl" %BUILD_OUTDIR%Plugins\Compute\
XCopy /r /d /y "%mypath:~0,-1%\BC4_Encode_kernel.cpp" %BUILD_OUTDIR%Plugins\Compute\
XCopy /r /d /y "%mypath:~0,-1%\BC5_Encode_kernel.h" %BUILD_OUTDIR%Plugins\Compute\
XCopy /r /d /y "%mypath:~0,-1%\BC5_Encode_kernel.hlsl" %BUILD_OUTDIR%Plugins\Compute\
XCopy /r /d /y "%mypath:~0,-1%\BC5_Encode_kernel.cpp" %BUILD_OUTDIR%Plugins\Compute\
XCopy /r /d /y "%mypath:~0,-1%\BC6_Encode_kernel.h" %BUILD_OUTDIR%Plugins\Compute\
XCopy /r /d /y "%mypath:~0,-1%\BC6_Encode_kernel.hlsl" %BUILD_OUTDIR%Plugins\Compute\
XCopy /r /d /y "%mypath:~0,-1%\BC6_Encode_kernel.cpp" %BUILD_OUTDIR%Plugins\Compute\
XCopy /r /d /y "%mypath:~0,-1%\BC7_Encode_Kernel.h" %BUILD_OUTDIR%Plugins\Compute\
XCopy /r /d /y "%mypath:~0,-1%\BC7_Encode_Kernel.hlsl" %BUILD_OUTDIR%Plugins\Compute\
XCopy /r /d /y "%mypath:~0,-1%\BC7_Encode_Kernel.cpp" %BUILD_OUTDIR%Plugins\Compute\
echo "Dependencies copied done"

153
extern/CMP_Core/source/CMP_Core.h vendored Normal file
View File

@ -0,0 +1,153 @@
//=====================================================================
// Copyright (c) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// 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 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.
//
/// \file CMP_Core.h CPU User Interface
//
//=====================================================================
#ifndef CMP_CORE_H
#define CMP_CORE_H
#include <stdint.h>
#ifdef _WIN32
#define CMP_CDECL __cdecl
#else
#define CMP_CDECL
#endif
//====================================================================================
// API Definitions for Core API
//------------------------------------------------------------------------------------
// All API return 0 on success else error codes > 0
// See Common_Def.h CGU_CORE_ values for the error codes
//=====================================================================================
//======================================================================================================
// Block level setting option: Create and Destroy Reference Pointers
//======================================================================================================
// Context create and destroy to use for BCn codec settings, where n is the set [1,2,3,4,5,6,7]
// All codecs will use default max quality settings, users can create multiple contexts to
// set quality levels, masks , channel mapping, etc...
int CMP_CDECL CreateOptionsBC1(void **optionsBC1);
int CMP_CDECL CreateOptionsBC2(void **optionsBC2);
int CMP_CDECL CreateOptionsBC3(void **optionsBC3);
int CMP_CDECL CreateOptionsBC4(void **optionsBC4);
int CMP_CDECL CreateOptionsBC5(void **optionsBC5);
int CMP_CDECL CreateOptionsBC6(void **optionsBC6);
int CMP_CDECL CreateOptionsBC7(void **optionsBC7);
int CMP_CDECL DestroyOptionsBC1(void *optionsBC1);
int CMP_CDECL DestroyOptionsBC2(void *optionsBC2);
int CMP_CDECL DestroyOptionsBC3(void *optionsBC3);
int CMP_CDECL DestroyOptionsBC4(void *optionsBC4);
int CMP_CDECL DestroyOptionsBC5(void *optionsBC5);
int CMP_CDECL DestroyOptionsBC6(void *optionsBC6);
int CMP_CDECL DestroyOptionsBC7(void *optionsBC7);
//======================================================================================================
// Block level settings using the options Reference Pointers
//======================================================================================================
// Setting channel Weights : Applies to BC1, BC2 and BC3 valid ranges are [0..1.0f] Default is {1.0f, 1.0f , 1.0f}
// Use channel weightings. With swizzled formats the weighting applies to the data within the specified channel not the channel itself.
int CMP_CDECL SetChannelWeightsBC1(void *options, float WeightRed, float WeightGreen, float WeightBlue);
int CMP_CDECL SetChannelWeightsBC2(void *options, float WeightRed, float WeightGreen, float WeightBlue);
int CMP_CDECL SetChannelWeightsBC3(void *options, float WeightRed, float WeightGreen, float WeightBlue);
// True sets mapping CMP_Core BC1, BC2 & BC3 to decode Red,Green,Blue and Alpha as
// RGBA to channels [0,1,2,3] else BGRA maps to [0,1,2,3]
// Default is set to true.
int CMP_CDECL SetDecodeChannelMapping(void *options, bool mapRGBA);
int CMP_CDECL SetQualityBC1(void *options, float fquality);
int CMP_CDECL SetQualityBC2(void *options, float fquality);
int CMP_CDECL SetQualityBC3(void *options, float fquality);
int CMP_CDECL SetQualityBC4(void *options, float fquality);
int CMP_CDECL SetQualityBC5(void *options, float fquality);
int CMP_CDECL SetQualityBC6(void *options, float fquality);
int CMP_CDECL SetQualityBC7(void *options, float fquality);
int CMP_CDECL SetAlphaThresholdBC1(void *options, unsigned char alphaThreshold);
int CMP_CDECL SetMaskBC6(void *options, unsigned int mask);
int CMP_CDECL SetMaskBC7(void *options, unsigned char mask);
int CMP_CDECL SetAlphaOptionsBC7(void *options, bool imageNeedsAlpha, bool colourRestrict, bool alphaRestrict);
int CMP_CDECL SetErrorThresholdBC7(void *options, float minThreshold, float maxThreshold);
//======================================================================================================
// (4x4) Block level 4 channel source CompressBlock and DecompressBlock API for BCn Codecs
//======================================================================================================
// The options parameter for these API can be set to null in the calls if defaults settings is sufficient
// Example: CompressBlockBC1(srcBlock,16,cmpBlock,NULL); For "C" call
// CompressBlockBC1(srcBlock,16,cmpBlock); For "C++" calls
//
// To use this parameter first create the options context using the CreateOptions call
// then use the Set Options to set various codec settings and pass them to the appropriate
// Compress or Decompress API.
// The source (srcBlock) channel format is expected to be RGBA:8888 by default for LDR Codecs
// for BC6H the format is RGBA Half float (16 bits per channel)
//------------------------------------------------------------------------------------------------------
#ifdef __cplusplus
#define CMP_DEFAULTNULL =NULL
#else
#define CMP_DEFAULTNULL
#endif
//=========================================================================================================
// 4 channel Sources, default format RGBA:8888 is processed as a 4x4 block starting at srcBlock location
// where each row of the block is calculated from srcStride
//=========================================================================================================
int CMP_CDECL CompressBlockBC1(const unsigned char *srcBlock, unsigned int srcStrideInBytes, unsigned char cmpBlock[8 ], const void *options CMP_DEFAULTNULL);
int CMP_CDECL CompressBlockBC2(const unsigned char *srcBlock, unsigned int srcStrideInBytes, unsigned char cmpBlock[16], const void *options CMP_DEFAULTNULL);
int CMP_CDECL CompressBlockBC3(const unsigned char *srcBlock, unsigned int srcStrideInBytes, unsigned char cmpBlock[16], const void *options CMP_DEFAULTNULL);
int CMP_CDECL CompressBlockBC7(const unsigned char *srcBlock, unsigned int srcStrideInBytes, unsigned char cmpBlock[16], const void *options CMP_DEFAULTNULL);
int CMP_CDECL DecompressBlockBC1(const unsigned char cmpBlock[8 ], unsigned char srcBlock[64], const void *options CMP_DEFAULTNULL);
int CMP_CDECL DecompressBlockBC2(const unsigned char cmpBlock[16], unsigned char srcBlock[64], const void *options CMP_DEFAULTNULL);
int CMP_CDECL DecompressBlockBC3(const unsigned char cmpBlock[16], unsigned char srcBlock[64], const void *options CMP_DEFAULTNULL);
int CMP_CDECL DecompressBlockBC7(const unsigned char cmpBlock[16], unsigned char srcBlock[64], const void *options CMP_DEFAULTNULL);
//================================================
// 1 channel Source 4x4 8 bits per block
//================================================
int CMP_CDECL CompressBlockBC4(const unsigned char *srcBlock, unsigned int srcStrideInBytes, unsigned char cmpBlock[8], const void *options CMP_DEFAULTNULL);
int CMP_CDECL DecompressBlockBC4(const unsigned char cmpBlock[8], unsigned char srcBlock[16], const void *options CMP_DEFAULTNULL);
//================================================
// 2 channel Source 2x(4x4 8 bits)
//================================================
int CMP_CDECL CompressBlockBC5(const unsigned char *srcBlock1, unsigned int srcStrideInBytes1,
const unsigned char *srcBlock2, unsigned int srcStrideInBytes2,
unsigned char cmpBlock[16], const void *options CMP_DEFAULTNULL);
int CMP_CDECL DecompressBlockBC5(const unsigned char cmpBlock[16], unsigned char srcBlock1[16], unsigned char srcBlock2[16], const void *options CMP_DEFAULTNULL);
//========================================================================================
// For 3 channel Source RGB_16, Note srcStride is in unsigned short steps (2 bytes each)
//========================================================================================
int CMP_CDECL CompressBlockBC6(const unsigned short *srcBlock, unsigned int srcStrideInShorts, unsigned char cmpBlock[16], const void *options CMP_DEFAULTNULL);
int CMP_CDECL DecompressBlockBC6(const unsigned char cmpBlock[16], unsigned short srcBlock[48], const void *options CMP_DEFAULTNULL);
#endif // CMP_CORE

143
extern/CMP_Core/source/cmp_math_func.h vendored Normal file
View File

@ -0,0 +1,143 @@
//=====================================================================
// Copyright 2020 (c), Advanced Micro Devices, Inc. All rights reserved.
//
// 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 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.
//
//=====================================================================
#ifndef CMP_MATH_FUNC_H
#define CMP_MATH_FUNC_H
#include "Common_Def.h"
#ifndef ASPM_GPU
//============================================================================
// Core API which have have GPU equivalents, defined here for HPC_CPU usage
//============================================================================
#include <algorithm>
using namespace std;
static CGU_INT QSortFCmp(const void *Elem1, const void *Elem2) {
CGU_INT ret = 0;
if (*(CGU_FLOAT *)Elem1 - *(CGU_FLOAT *)Elem2 < 0.)
ret = -1;
else if (*(CGU_FLOAT *)Elem1 - *(CGU_FLOAT *)Elem2 > 0.)
ret = 1;
return ret;
}
static int QSortIntCmp(const void *Elem1, const void *Elem2)
{
return (*(CGU_INT32 *)Elem1 - *(CGU_INT32 *)Elem2);
}
static CGU_FLOAT dot(CMP_IN CGU_Vec3f Color,CMP_IN CGU_Vec3f Color2)
{
CGU_FLOAT ColorDot;
ColorDot = (Color.x * Color2.x) + (Color.y * Color2.y) + (Color.z * Color2.z);
return ColorDot;
}
static CGU_FLOAT dot(CMP_IN CGU_Vec2f Color,CMP_IN CGU_Vec2f Color2)
{
CGU_FLOAT ColorDot;
ColorDot = Color.x * Color2.x + Color.y * Color2.y;
return ColorDot;
}
static CGU_Vec2f abs(CMP_IN CGU_Vec2f Color)
{
CGU_Vec2f ColorAbs;
ColorAbs.x = std::abs(Color.x);
ColorAbs.y = std::abs(Color.y);
return ColorAbs;
}
static CGU_Vec3f fabs(CMP_IN CGU_Vec3f Color)
{
CGU_Vec3f ColorAbs;
ColorAbs.x = std::abs(Color.x);
ColorAbs.y = std::abs(Color.y);
ColorAbs.z = std::abs(Color.z);
return ColorAbs;
}
static CGU_Vec3f round(CMP_IN CGU_Vec3f Color)
{
CGU_Vec3f ColorRound;
ColorRound.x = std::round(Color.x);
ColorRound.y = std::round(Color.y);
ColorRound.z = std::round(Color.z);
return ColorRound;
}
static CGU_Vec2f round(CMP_IN CGU_Vec2f Color)
{
CGU_Vec2f ColorRound;
ColorRound.x = std::round(Color.x);
ColorRound.y = std::round(Color.y);
return ColorRound;
}
static CGU_Vec3f ceil(CMP_IN CGU_Vec3f Color)
{
CGU_Vec3f ColorCeil;
ColorCeil.x = std::ceil(Color.x);
ColorCeil.y = std::ceil(Color.y);
ColorCeil.z = std::ceil(Color.z);
return ColorCeil;
}
static CGU_Vec3f floor(CMP_IN CGU_Vec3f Color)
{
CGU_Vec3f Colorfloor;
Colorfloor.x = std::floor(Color.x);
Colorfloor.y = std::floor(Color.y);
Colorfloor.z = std::floor(Color.z);
return Colorfloor;
}
static CGU_Vec3f saturate(CGU_Vec3f value)
{
if (value.x > 1.0f) value.x = 1.0f;
else
if (value.x < 0.0f) value.x = 0.0f;
if (value.y > 1.0f) value.y = 1.0f;
else
if (value.y < 0.0f) value.y = 0.0f;
if (value.z > 1.0f) value.z = 1.0f;
else
if (value.z < 0.0f) value.z = 0.0f;
return value;
}
#endif
//============================================================================
// Core API which are shared between GPU & CPU
//============================================================================
#endif // Header Guard

435
extern/CMP_Core/source/cmp_math_vec4.h vendored Normal file
View File

@ -0,0 +1,435 @@
//=====================================================================
// Copyright 2019 (c), Advanced Micro Devices, Inc. All rights reserved.
//
// 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 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.
//
//=====================================================================
#ifndef CMP_MATH_VEC4_H
#define CMP_MATH_VEC4_H
//====================================================
// Vector Class definitions for CPU & Intrinsics
//====================================================
#if defined (_LINUX) || defined (_WIN32)
//============================================= VEC2 ==================================================
template <class T> class vec3;
template<class T>
class Vec2
{
public:
T x;
T y;
// *****************************************
// Constructors
// *****************************************
/// Default constructor
Vec2() : x((T)0), y((T)0) {};
/// Value constructor
Vec2(const T& vx, const T& vy) : x(vx), y(vy) {};
/// Copy constructor
Vec2(const Vec2<T>& val) : x(val.x), y(val.y) {};
/// Single value constructor. Sets all components to the given value
Vec2(const T& v) : x(v), y(v) {};
// *****************************************
// Conversions/Assignment/Indexing
// *****************************************
/// cast to T*
operator const T* () const { return (const T*)this; };
/// cast to T*
operator T* () { return (T*)this; };
/// Indexing
const T& operator[](int i) const { return ((const T*)this)[i]; };
T& operator[](int i) { return ((T*)this)[i]; };
/// Assignment
const Vec2<T>& operator=(const Vec2<T>& rhs) { x = rhs.x; y = rhs.y; return *this; };
// *****************************************
// Comparison
// *****************************************
/// Equality comparison
bool operator==(const Vec2<T>& rhs) const { return (x == rhs.x && y == rhs.y); };
/// Inequality comparision
bool operator!=(const Vec2<T>& rhs) const { return (x != rhs.x || y != rhs.y); };
// *****************************************
// Arithmetic
// *****************************************
/// Addition
const Vec2<T> operator+(const Vec2<T>& rhs) const { return Vec2<T>(x + rhs.x, y + rhs.y); };
/// Subtraction
const Vec2<T> operator-(const Vec2<T>& rhs) const { return Vec2<T>(x - rhs.x, y - rhs.y); };
/// Multiply
const Vec2<T> operator*(const Vec2<T>& rhs) const { return Vec2<T>(x * rhs.x, y * rhs.y); };
/// Divide
const Vec2<T> operator/(const Vec2<T>& rhs) const { return Vec2<T>(x / rhs.x, y / rhs.y); };
/// Multiply by scalar
const Vec2<T> operator*(const T& v) const { return Vec2<T>(x * v, y * v); };
/// Divide by scalar
const Vec2<T> operator/(const T& v) const { return Vec2<T>(x / v, y / v); };
/// Addition in-place
Vec2<T>& operator+= (const Vec2<T>& rhs) { x += rhs.x; y += rhs.y; return *this; };
/// Subtract in-place
Vec2<T>& operator-= (const Vec2<T>& rhs) { x -= rhs.x; y -= rhs.y; return *this; };
/// Scalar multiply in-place
Vec2<T>& operator*= (const T& v) { x *= v; y *= v; return *this; };
/// Scalar divide in-place
Vec2<T>& operator/= (const T& v) { x /= v; y /= v; return *this; };
};
typedef Vec2<float> CMP_Vec2f;
typedef Vec2<float> CGU_Vec2f;
typedef Vec2<float> CGV_Vec2f;
typedef Vec2<double> CMP_Vec2d;
typedef Vec2<int> CMP_Vec2i;
typedef Vec2<unsigned int> CGU_Vec2ui;
//}
//============================================= VEC3 ==================================================
template<class T>
class Vec3
{
public:
T x;
T y;
T z;
// *****************************************
// Constructors
// *****************************************
/// Default constructor
Vec3() : x((T)0), y((T)0), z((T)0) {};
/// Value constructor
Vec3(const T& vx, const T& vy, const T& vz) : x(vx), y(vy), z(vz) {};
/// Copy constructor
Vec3(const Vec3<T>& val) : x(val.x), y(val.y), z(val.z) {};
/// Single value constructor. Sets all components to the given value
Vec3(const T& v) : x(v), y(v), z(v) {};
/// Array constructor. Assumes a 3-component array
Vec3(const T* v) : x(v[0]), y(v[1]), z(v[2]) {};
// *****************************************
// Conversions/Assignment/Indexing
// *****************************************
/// cast to T*
operator const T* () const { return (const T*)this; };
/// cast to T*
operator T* () { return (T*)this; };
/// Assignment
const Vec3<T>& operator=(const Vec3<T>& rhs) { x = rhs.x; y = rhs.y; z = rhs.z; return *this; };
// *****************************************
// Comparison
// *****************************************
/// Equality comparison
bool operator==(const Vec3<T>& rhs) const { return (x == rhs.x && y == rhs.y && z == rhs.z); };
/// Inequality comparision
bool operator!=(const Vec3<T>& rhs) const { return (x != rhs.x || y != rhs.y || z != rhs.z); };
// *****************************************
// Arithmetic
// *****************************************
/// Addition by vector
const Vec3<T> operator+(const Vec3<T>& rhs) const { return Vec3<T>(x + rhs.x, y + rhs.y, z + rhs.z); };
/// Subtraction by vector
const Vec3<T> operator-(const Vec3<T>& rhs) const { return Vec3<T>(x - rhs.x, y - rhs.y, z - rhs.z); };
/// Multiply by vector
const Vec3<T> operator*(const Vec3<T>& rhs) const { return Vec3<T>(x * rhs.x, y * rhs.y, z * rhs.z); };
/// Divide by vector
const Vec3<T> operator/(const Vec3<T>& rhs) const { return Vec3<T>(x / rhs.x, y / rhs.y, z / rhs.z); };
/// Multiply by scalar
const Vec3<T> operator*(const T& v) const { return Vec3<T>(x * v, y * v, z * v); };
/// Divide by scalar
const Vec3<T> operator/(const T& v) const { return Vec3<T>(x / v, y / v, z / v); };
/// Addition in-place
Vec3<T>& operator+= (const Vec3<T>& rhs) { x += rhs.x; y += rhs.y; z += rhs.z; return *this; };
/// Subtract in-place
Vec3<T>& operator-= (const Vec3<T>& rhs) { x -= rhs.x; y -= rhs.y; z -= rhs.z; return *this; };
/// Scalar multiply in-place
Vec3<T>& operator*= (const T& v) { x *= v; y *= v; z *= v; return *this; };
/// Scalar divide in-place
Vec3<T>& operator/= (const T& v) { x /= v; y /= v; z /= v; return *this; };
};
typedef Vec3<bool> CGU_Vec3bool;
typedef Vec3<float> CGU_Vec3f;
typedef Vec3<float> CGV_Vec3f;
typedef Vec3<unsigned char> CGU_Vec3uc;
typedef Vec3<unsigned char> CGV_Vec3uc;
typedef Vec3<float> CMP_Vec3f;
typedef Vec3<double> CMP_Vec3d;
typedef Vec3<int> CMP_Vec3i;
typedef Vec3<unsigned char> CMP_Vec3uc;
typedef Vec3<unsigned int> CMP_Vec3ui;
//============================================= VEC4 ==================================================
template<class T>
class Vec4
{
public:
T x;
T y;
T z;
T w;
// *****************************************
// Constructors
// *****************************************
/// Default constructor
Vec4() : x((T)0), y((T)0), z((T)0), w((T)0) {};
/// Value constructor
Vec4(const T& vx, const T& vy, const T& vz, const T& vw) : x(vx), y(vy), z(vz), w(vw) {};
/// Copy constructor
Vec4(const Vec4<T>& val) : x(val.x), y(val.y), z(val.z), w(val.w) {};
/// Single value constructor. Sets all components to the given value
Vec4(const T& v) : x(v), y(v), z(v), w(v) {};
/// Array constructor. Assumes a 4-component array
Vec4(const T* v) : x(v[0]), y(v[1]), z(v[2]), w(v[3]) {};
// *****************************************
// Conversions/Assignment/Indexing
// *****************************************
/// cast to T*
operator const T* () const { return (const T*)this; };
/// cast to T*
operator T* () { return (T*)this; };
/// Assignment
const Vec4<T>& operator=(const Vec4<T>& rhs) { x = rhs.x; y = rhs.y; z = rhs.z; w = rhs.w; return *this; };
// *****************************************
// Comparison
// *****************************************
/// Equality comparison
bool operator==(const Vec4<T>& rhs) const { return (x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w); };
/// Inequality comparision
bool operator!=(const Vec4<T>& rhs) const { return (x != rhs.x || y != rhs.y || z != rhs.z || w != rhs.w); };
// *****************************************
// Arithmetic
// *****************************************
/// Addition by vector
const Vec4<T> operator+(const Vec4<T>& rhs) const { return Vec4<T>(x + rhs.x, y + rhs.y, z + rhs.z, w + rhs.w); };
/// Subtraction by vector
const Vec4<T> operator-(const Vec4<T>& rhs) const { return Vec4<T>(x - rhs.x, y - rhs.y, z - rhs.z, w - rhs.w); };
/// Multiply by vector
const Vec4<T> operator*(const Vec4<T>& rhs) const { return Vec4<T>(x * rhs.x, y * rhs.y, z * rhs.z, w * rhs.w); };
/// Divide by vector
const Vec4<T> operator/(const Vec4<T>& rhs) const { return Vec4<T>(x / rhs.x, y / rhs.y, z / rhs.z, w / rhs.w); };
/// Multiply by scalar
const Vec4<T> operator*(const T& v) const { return Vec4<T>(x * v, y * v, z * v, w * v); };
/// Divide by scalar
const Vec4<T> operator/(const T& v) const { return Vec4<T>(x / v, y / v, z / v, w / v); };
/// Addition in-place
Vec4<T>& operator+= (const Vec4<T>& rhs) { x += rhs.x; y += rhs.y; z += rhs.z; w += rhs.w; return *this; };
/// Subtract in-place
Vec4<T>& operator-= (const Vec4<T>& rhs) { x -= rhs.x; y -= rhs.y; z -= rhs.z; w -= rhs.w; return *this; };
/// Scalar multiply in-place
Vec4<T>& operator*= (const T& v) { x *= v; y *= v; z *= v; w *= v; return *this; };
/// Scalar divide in-place
Vec4<T>& operator/= (const T& v) { x /= v; y /= v; z /= v; w /= v; return *this; };
};
#include <stdio.h>
#include "xmmintrin.h"
#include <math.h>
#include <float.h>
// SSE Vec4
#ifdef _LINUX
class CMP_SSEVec4f
#else
#include "intrin.h"
class __declspec(align(16)) CMP_SSEVec4f
#endif
{
public:
union
{
__m128 vec128; // float Vector 128 bits in total (16 Bytes) = array of 4 floats
#ifdef _LINUX
float f32[4];
#endif
};
// constructors
inline CMP_SSEVec4f() {};
inline CMP_SSEVec4f(float x, float y, float z, float w) : vec128(_mm_setr_ps(x, y, z, w)) {};
inline CMP_SSEVec4f(__m128 vec) : vec128(vec) {}
inline CMP_SSEVec4f(const float* data) : vec128(_mm_load_ps(data)) {};
inline CMP_SSEVec4f(float scalar) : vec128(_mm_load1_ps(&scalar)) {};
// copy and assignment
inline CMP_SSEVec4f(const CMP_SSEVec4f& init) : vec128(init.vec128) {};
inline const CMP_SSEVec4f& operator=(const CMP_SSEVec4f& lhs) { vec128 = lhs.vec128; return *this; };
// conversion to m128 type for direct use in _mm intrinsics
inline operator __m128() { return vec128; };
inline operator const __m128() const { return vec128; };
// indexing
#ifdef _LINUX
inline const float& operator[](int i) const { return f32[i]; };
inline float& operator[](int i) { return f32[i]; };
#else
inline const float& operator[](int i) const { return vec128.m128_f32[i]; };
inline float& operator[](int i) { return vec128.m128_f32[i]; };
#endif
// addition
inline CMP_SSEVec4f operator+(const CMP_SSEVec4f& rhs) const { return CMP_SSEVec4f(_mm_add_ps(vec128, rhs.vec128)); };
inline CMP_SSEVec4f& operator+=(const CMP_SSEVec4f& rhs) { vec128 = _mm_add_ps(vec128, rhs.vec128); return *this; };
// multiplication
inline CMP_SSEVec4f operator*(const CMP_SSEVec4f& rhs) const { return CMP_SSEVec4f(_mm_mul_ps(vec128, rhs.vec128)); };
inline CMP_SSEVec4f& operator*=(const CMP_SSEVec4f& rhs) { vec128 = _mm_mul_ps(vec128, rhs.vec128); return *this; };
// scalar multiplication
//inline CMP_SSEVec4f operator*( float rhs ) const { return CMP_SSEVec4f( _mm_mul_ps(vec128, _mm_load1_ps(&rhs)) ); };
//inline CMP_SSEVec4f& operator*=( float rhs ) { vec128 = _mm_mul_ps(vec128, _mm_load1_ps(&rhs)); return *this; };
// subtraction
inline CMP_SSEVec4f operator-(const CMP_SSEVec4f& rhs) const { return CMP_SSEVec4f(_mm_sub_ps(vec128, rhs.vec128)); };
inline CMP_SSEVec4f& operator-= (const CMP_SSEVec4f& rhs) { vec128 = _mm_sub_ps(vec128, rhs.vec128); return *this; };
// division
inline CMP_SSEVec4f operator/(const CMP_SSEVec4f& rhs) const { return CMP_SSEVec4f(_mm_div_ps(vec128, rhs.vec128)); };
inline CMP_SSEVec4f& operator/= (const CMP_SSEVec4f& rhs) { vec128 = _mm_div_ps(vec128, rhs.vec128); return *this; };
// scalar division
inline CMP_SSEVec4f operator/(float rhs) const { return CMP_SSEVec4f(_mm_div_ps(vec128, _mm_load1_ps(&rhs))); };
inline CMP_SSEVec4f& operator/=(float rhs) { vec128 = _mm_div_ps(vec128, _mm_load1_ps(&rhs)); return *this; };
// comparison
// these return 0 or 0xffffffff in each component
inline CMP_SSEVec4f operator< (const CMP_SSEVec4f& rhs) const { return CMP_SSEVec4f(_mm_cmplt_ps(vec128, rhs.vec128)); };
inline CMP_SSEVec4f operator> (const CMP_SSEVec4f& rhs) const { return CMP_SSEVec4f(_mm_cmpgt_ps(vec128, rhs.vec128)); };
inline CMP_SSEVec4f operator<=(const CMP_SSEVec4f& rhs) const { return CMP_SSEVec4f(_mm_cmple_ps(vec128, rhs.vec128)); };
inline CMP_SSEVec4f operator>=(const CMP_SSEVec4f& rhs) const { return CMP_SSEVec4f(_mm_cmpge_ps(vec128, rhs.vec128)); };
inline CMP_SSEVec4f operator==(const CMP_SSEVec4f& rhs) const { return CMP_SSEVec4f(_mm_cmpeq_ps(vec128, rhs.vec128)); };
// bitwise operators
inline CMP_SSEVec4f operator|(const CMP_SSEVec4f& rhs) const { return CMP_SSEVec4f(_mm_or_ps(vec128, rhs.vec128)); };
inline CMP_SSEVec4f operator&(const CMP_SSEVec4f& rhs) const { return CMP_SSEVec4f(_mm_and_ps(vec128, rhs.vec128)); };
inline CMP_SSEVec4f operator^(const CMP_SSEVec4f& rhs) const { return CMP_SSEVec4f(_mm_xor_ps(vec128, rhs.vec128)); };
inline const CMP_SSEVec4f& operator|=(const CMP_SSEVec4f& rhs) { vec128 = _mm_or_ps(vec128, rhs.vec128); return *this; };
inline const CMP_SSEVec4f& operator&=(const CMP_SSEVec4f& rhs) { vec128 = _mm_and_ps(vec128, rhs.vec128); return *this; };
// for some horrible reason,there's no bitwise not instruction for SSE,
// so we have to do xor with 0xfffffff in order to fake it.
// TO get a 0xffffffff, we execute 0=0
inline CMP_SSEVec4f operator~() const
{
__m128 zero = _mm_setzero_ps();
__m128 is_true = _mm_cmpeq_ps(zero, zero);
return _mm_xor_ps(is_true, vec128);
};
};
typedef Vec4<float> CMP_Vec4f;
typedef Vec4<double> CMP_Vec4d;
typedef Vec4<int> CMP_Vec4i;
typedef Vec4<unsigned int> CMP_Vec4ui; // unsigned 16 bit x,y,x,w
typedef Vec4<unsigned char> CMP_Vec4uc; // unsigned 8 bit x,y,x,w
typedef Vec4<unsigned char> CGU_Vec4uc; // unsigned 8 bit x,y,x,w
typedef Vec4<unsigned char> CGV_Vec4uc; // unsigned 8 bit x,y,x,w
#endif // not ASPM_GPU
#endif // Header Guard

520
extern/CMP_Core/test/BlockConstants.h vendored Normal file
View File

@ -0,0 +1,520 @@
#ifndef BLOCKCONSTANTS_H
#define BLOCKCONSTANTS_H
#include <string>
#include <unordered_map>
struct Block { const unsigned char* data; const unsigned char* color; };
struct BlockBC6 { const unsigned char* data; const float* color; };
static const unsigned char BC1_Red_Ignore_Alpha [] {0x0 , 0xf8, 0x0 , 0xf8, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC1_Blue_Half_Alpha [] {0x0 , 0x0 , 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
static const unsigned char BC1_White_Half_Alpha [] {0x0 , 0x0 , 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
static const unsigned char BC1_Black_Half_Alpha [] {0x0 , 0x0 , 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
static const unsigned char BC1_Red_Blue_Half_Alpha [] {0x0 , 0x0 , 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
static const unsigned char BC1_Red_Green_Half_Alpha [] {0x0 , 0x0 , 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
static const unsigned char BC1_Green_Blue_Half_Alpha [] {0x0 , 0x0 , 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
static const unsigned char BC1_Red_Full_Alpha [] {0x0 , 0x0 , 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
static const unsigned char BC1_Green_Full_Alpha [] {0x0 , 0x0 , 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
static const unsigned char BC1_Blue_Full_Alpha [] {0x0 , 0x0 , 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
static const unsigned char BC1_White_Full_Alpha [] {0x0 , 0x0 , 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
static const unsigned char BC1_Green_Ignore_Alpha [] {0xe0, 0x7 , 0xe0, 0x7 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC1_Black_Full_Alpha [] {0x0 , 0x0 , 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
static const unsigned char BC1_Red_Blue_Full_Alpha [] {0x0 , 0x0 , 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
static const unsigned char BC1_Red_Green_Full_Alpha [] {0x0 , 0x0 , 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
static const unsigned char BC1_Green_Blue_Full_Alpha [] {0x0 , 0x0 , 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
static const unsigned char BC1_Blue_Ignore_Alpha [] {0x1f, 0x0 , 0x1f, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC1_White_Ignore_Alpha [] {0xff, 0xff, 0xff, 0xff, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC1_Black_Ignore_Alpha [] {0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC1_Red_Blue_Ignore_Alpha [] {0x1f, 0xf8, 0x1f, 0xf8, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC1_Red_Green_Ignore_Alpha [] {0xe0, 0xff, 0xe0, 0xff, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC1_Green_Blue_Ignore_Alpha [] {0xff, 0x7 , 0xff, 0x7 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC1_Red_Half_Alpha [] {0x0 , 0x0 , 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
static const unsigned char BC1_Green_Half_Alpha [] {0x0 , 0x0 , 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
static const unsigned char BC2_Red_Ignore_Alpha [] {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0 , 0xf8, 0x0 , 0xf8, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC2_Blue_Half_Alpha [] {0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x1f, 0x0 , 0x1f, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC2_White_Half_Alpha [] {0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0xff, 0xff, 0xff, 0xff, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC2_Black_Half_Alpha [] {0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC2_Red_Blue_Half_Alpha [] {0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x1f, 0xf8, 0x1f, 0xf8, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC2_Red_Green_Half_Alpha [] {0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0xe0, 0xff, 0xe0, 0xff, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC2_Green_Blue_Half_Alpha [] {0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0xff, 0x7 , 0xff, 0x7 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC2_Red_Full_Alpha [] {0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xf8, 0x0 , 0xf8, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC2_Green_Full_Alpha [] {0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xe0, 0x7 , 0xe0, 0x7 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC2_Blue_Full_Alpha [] {0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x1f, 0x0 , 0x1f, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC2_White_Full_Alpha [] {0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xff, 0xff, 0xff, 0xff, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC2_Green_Ignore_Alpha [] {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x7 , 0xe0, 0x7 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC2_Black_Full_Alpha [] {0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC2_Red_Blue_Full_Alpha [] {0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x1f, 0xf8, 0x1f, 0xf8, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC2_Red_Green_Full_Alpha [] {0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xe0, 0xff, 0xe0, 0xff, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC2_Green_Blue_Full_Alpha [] {0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xff, 0x7 , 0xff, 0x7 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC2_Blue_Ignore_Alpha [] {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x0 , 0x1f, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC2_White_Ignore_Alpha [] {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC2_Black_Ignore_Alpha [] {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC2_Red_Blue_Ignore_Alpha [] {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xf8, 0x1f, 0xf8, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC2_Red_Green_Ignore_Alpha [] {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC2_Green_Blue_Ignore_Alpha [] {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7 , 0xff, 0x7 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC2_Red_Half_Alpha [] {0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x0 , 0xf8, 0x0 , 0xf8, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC2_Green_Half_Alpha [] {0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0xe0, 0x7 , 0xe0, 0x7 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC3_Red_Ignore_Alpha [] {0xff, 0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xf8, 0x0 , 0xf8, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC3_Blue_Half_Alpha [] {0x7b, 0x7b, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x1f, 0x0 , 0x1f, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC3_White_Half_Alpha [] {0x7b, 0x7b, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xff, 0xff, 0xff, 0xff, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC3_Black_Half_Alpha [] {0x7b, 0x7b, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC3_Red_Blue_Half_Alpha [] {0x7b, 0x7b, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x1f, 0xf8, 0x1f, 0xf8, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC3_Red_Green_Half_Alpha [] {0x7b, 0x7b, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xe0, 0xff, 0xe0, 0xff, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC3_Green_Blue_Half_Alpha [] {0x7b, 0x7b, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xff, 0x7 , 0xff, 0x7 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC3_Red_Full_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24, 0x0 , 0xf8, 0x0 , 0xf8, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC3_Green_Full_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24, 0xe0, 0x7 , 0xe0, 0x7 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC3_Blue_Full_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24, 0x1f, 0x0 , 0x1f, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC3_White_Full_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24, 0xff, 0xff, 0xff, 0xff, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC3_Green_Ignore_Alpha [] {0xff, 0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xe0, 0x7 , 0xe0, 0x7 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC3_Black_Full_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC3_Red_Blue_Full_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24, 0x1f, 0xf8, 0x1f, 0xf8, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC3_Red_Green_Full_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24, 0xe0, 0xff, 0xe0, 0xff, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC3_Green_Blue_Full_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24, 0xff, 0x7 , 0xff, 0x7 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC3_Blue_Ignore_Alpha [] {0xff, 0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x1f, 0x0 , 0x1f, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC3_White_Ignore_Alpha [] {0xff, 0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xff, 0xff, 0xff, 0xff, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC3_Black_Ignore_Alpha [] {0xff, 0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC3_Red_Blue_Ignore_Alpha [] {0xff, 0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x1f, 0xf8, 0x1f, 0xf8, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC3_Red_Green_Ignore_Alpha [] {0xff, 0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xe0, 0xff, 0xe0, 0xff, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC3_Green_Blue_Ignore_Alpha [] {0xff, 0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xff, 0x7 , 0xff, 0x7 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC3_Red_Half_Alpha [] {0x7b, 0x7b, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xf8, 0x0 , 0xf8, 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC3_Green_Half_Alpha [] {0x7b, 0x7b, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xe0, 0x7 , 0xe0, 0x7 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC4_Red_Ignore_Alpha [] {0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC4_Blue_Half_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
static const unsigned char BC4_White_Half_Alpha [] {0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC4_Black_Half_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
static const unsigned char BC4_Red_Blue_Half_Alpha [] {0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC4_Red_Green_Half_Alpha [] {0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC4_Green_Blue_Half_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
static const unsigned char BC4_Red_Full_Alpha [] {0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC4_Green_Full_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
static const unsigned char BC4_Blue_Full_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
static const unsigned char BC4_White_Full_Alpha [] {0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC4_Green_Ignore_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
static const unsigned char BC4_Black_Full_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
static const unsigned char BC4_Red_Blue_Full_Alpha [] {0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC4_Red_Green_Full_Alpha [] {0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC4_Green_Blue_Full_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
static const unsigned char BC4_Blue_Ignore_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
static const unsigned char BC4_White_Ignore_Alpha [] {0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC4_Black_Ignore_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
static const unsigned char BC4_Red_Blue_Ignore_Alpha [] {0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC4_Red_Green_Ignore_Alpha [] {0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC4_Green_Blue_Ignore_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
static const unsigned char BC4_Red_Half_Alpha [] {0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC4_Green_Half_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
static const unsigned char BC5_Red_Ignore_Alpha [] {0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
static const unsigned char BC5_Blue_Half_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24, 0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
static const unsigned char BC5_White_Half_Alpha [] {0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC5_Black_Half_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24, 0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
static const unsigned char BC5_Red_Blue_Half_Alpha [] {0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
static const unsigned char BC5_Red_Green_Half_Alpha [] {0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC5_Green_Blue_Half_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24, 0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC5_Red_Full_Alpha [] {0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
static const unsigned char BC5_Green_Full_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24, 0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC5_Blue_Full_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24, 0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
static const unsigned char BC5_White_Full_Alpha [] {0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC5_Green_Ignore_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24, 0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC5_Black_Full_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24, 0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
static const unsigned char BC5_Red_Blue_Full_Alpha [] {0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
static const unsigned char BC5_Red_Green_Full_Alpha [] {0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC5_Green_Blue_Full_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24, 0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC5_Blue_Ignore_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24, 0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
static const unsigned char BC5_White_Ignore_Alpha [] {0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC5_Black_Ignore_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24, 0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
static const unsigned char BC5_Red_Blue_Ignore_Alpha [] {0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
static const unsigned char BC5_Red_Green_Ignore_Alpha [] {0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC5_Green_Blue_Ignore_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24, 0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC5_Red_Half_Alpha [] {0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24};
static const unsigned char BC5_Green_Half_Alpha [] {0xff, 0x0 , 0x49, 0x92, 0x24, 0x49, 0x92, 0x24, 0xff, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC6_Red_Ignore_Alpha [] {0xe3, 0x3d, 0x0 , 0x0 , 0x78, 0xf , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC6_Blue_Half_Alpha [] {0x3 , 0x0 , 0x0 , 0xde, 0x3 , 0x0 , 0x80, 0xf7, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC6_White_Half_Alpha [] {0xe3, 0xbd, 0xf7, 0xde, 0x7b, 0xef, 0xbd, 0xf7, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC6_Black_Half_Alpha [] {0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC6_Red_Blue_Half_Alpha [] {0xe3, 0x3d, 0x0 , 0xde, 0x7b, 0xf , 0x80, 0xf7, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC6_Red_Green_Half_Alpha [] {0xe3, 0xbd, 0xf7, 0x0 , 0x78, 0xef, 0x3d, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC6_Green_Blue_Half_Alpha [] {0x3 , 0x80, 0xf7, 0xde, 0x3 , 0xe0, 0xbd, 0xf7, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC6_Red_Full_Alpha [] {0xe3, 0x3d, 0x0 , 0x0 , 0x78, 0xf , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC6_Green_Full_Alpha [] {0x3 , 0x80, 0xf7, 0x0 , 0x0 , 0xe0, 0x3d, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC6_Blue_Full_Alpha [] {0x3 , 0x0 , 0x0 , 0xde, 0x3 , 0x0 , 0x80, 0xf7, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC6_White_Full_Alpha [] {0xe3, 0xbd, 0xf7, 0xde, 0x7b, 0xef, 0xbd, 0xf7, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC6_Green_Ignore_Alpha [] {0x3 , 0x80, 0xf7, 0x0 , 0x0 , 0xe0, 0x3d, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC6_Black_Full_Alpha [] {0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC6_Red_Blue_Full_Alpha [] {0xe3, 0x3d, 0x0 , 0xde, 0x7b, 0xf , 0x80, 0xf7, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC6_Red_Green_Full_Alpha [] {0xe3, 0xbd, 0xf7, 0x0 , 0x78, 0xef, 0x3d, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC6_Green_Blue_Full_Alpha [] {0x3 , 0x80, 0xf7, 0xde, 0x3 , 0xe0, 0xbd, 0xf7, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC6_Blue_Ignore_Alpha [] {0x3 , 0x0 , 0x0 , 0xde, 0x3 , 0x0 , 0x80, 0xf7, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC6_White_Ignore_Alpha [] {0xe3, 0xbd, 0xf7, 0xde, 0x7b, 0xef, 0xbd, 0xf7, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC6_Black_Ignore_Alpha [] {0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC6_Red_Blue_Ignore_Alpha [] {0xe3, 0x3d, 0x0 , 0xde, 0x7b, 0xf , 0x80, 0xf7, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC6_Red_Green_Ignore_Alpha [] {0xe3, 0xbd, 0xf7, 0x0 , 0x78, 0xef, 0x3d, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC6_Green_Blue_Ignore_Alpha [] {0x3 , 0x80, 0xf7, 0xde, 0x3 , 0xe0, 0xbd, 0xf7, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC6_Red_Half_Alpha [] {0xe3, 0x3d, 0x0 , 0x0 , 0x78, 0xf , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC6_Green_Half_Alpha [] {0x3 , 0x80, 0xf7, 0x0 , 0x0 , 0xe0, 0x3d, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC7_Red_Ignore_Alpha [] {0x10, 0xff, 0x3 , 0x0 , 0xc0, 0xff, 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC7_Blue_Half_Alpha [] {0x20, 0x0 , 0x0 , 0x0 , 0xf0, 0xff, 0xef, 0xed, 0x1 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC7_White_Half_Alpha [] {0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xed, 0x1 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC7_Black_Half_Alpha [] {0x20, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0xec, 0xed, 0x1 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC7_Red_Blue_Half_Alpha [] {0x20, 0xff, 0x3f, 0x0 , 0xf0, 0xff, 0xef, 0xed, 0x1 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC7_Red_Green_Half_Alpha [] {0x20, 0xff, 0xff, 0xff, 0xf , 0x0 , 0xec, 0xed, 0x1 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC7_Green_Blue_Half_Alpha [] {0x20, 0x0 , 0xc0, 0xff, 0xff, 0xff, 0xef, 0xed, 0x1 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC7_Red_Full_Alpha [] {0x10, 0xff, 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC7_Green_Full_Alpha [] {0x10, 0x0 , 0xfc, 0xf , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC7_Blue_Full_Alpha [] {0x10, 0x0 , 0x0 , 0xf0, 0x3f, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC7_White_Full_Alpha [] {0x10, 0xff, 0xff, 0xff, 0x3f, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC7_Green_Ignore_Alpha [] {0x10, 0x0 , 0xfc, 0xf , 0xc0, 0xff, 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC7_Black_Full_Alpha [] {0x10, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC7_Red_Blue_Full_Alpha [] {0x10, 0xff, 0x3 , 0xf0, 0x3f, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC7_Red_Green_Full_Alpha [] {0x10, 0xff, 0xff, 0xf , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC7_Green_Blue_Full_Alpha [] {0x10, 0x0 , 0xfc, 0xff, 0x3f, 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC7_Blue_Ignore_Alpha [] {0x10, 0x0 , 0x0 , 0xf0, 0xff, 0xff, 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC7_White_Ignore_Alpha [] {0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC7_Black_Ignore_Alpha [] {0x10, 0x0 , 0x0 , 0x0 , 0xc0, 0xff, 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC7_Red_Blue_Ignore_Alpha [] {0x10, 0xff, 0x3 , 0xf0, 0xff, 0xff, 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC7_Red_Green_Ignore_Alpha [] {0x10, 0xff, 0xff, 0xf , 0xc0, 0xff, 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC7_Green_Blue_Ignore_Alpha [] {0x10, 0x0 , 0xfc, 0xff, 0xff, 0xff, 0x3 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC7_Red_Half_Alpha [] {0x20, 0xff, 0x3f, 0x0 , 0x0 , 0x0 , 0xec, 0xed, 0x1 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
static const unsigned char BC7_Green_Half_Alpha [] {0x20, 0x0 , 0xc0, 0xff, 0xf , 0x0 , 0xec, 0xed, 0x1 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
Block BC1_Red_Ignore_Alpha_Block = {BC1_Red_Ignore_Alpha, nullptr};
Block BC1_Blue_Half_Alpha_Block = {BC1_Blue_Half_Alpha, nullptr};
Block BC1_White_Half_Alpha_Block = {BC1_White_Half_Alpha, nullptr};
Block BC1_Black_Half_Alpha_Block = {BC1_Black_Half_Alpha, nullptr};
Block BC1_Red_Blue_Half_Alpha_Block = {BC1_Red_Blue_Half_Alpha, nullptr};
Block BC1_Red_Green_Half_Alpha_Block = {BC1_Red_Green_Half_Alpha, nullptr};
Block BC1_Green_Blue_Half_Alpha_Block = {BC1_Green_Blue_Half_Alpha, nullptr};
Block BC1_Red_Full_Alpha_Block = {BC1_Red_Full_Alpha, nullptr};
Block BC1_Green_Full_Alpha_Block = {BC1_Green_Full_Alpha, nullptr};
Block BC1_Blue_Full_Alpha_Block = {BC1_Blue_Full_Alpha, nullptr};
Block BC1_White_Full_Alpha_Block = {BC1_White_Full_Alpha, nullptr};
Block BC1_Green_Ignore_Alpha_Block = {BC1_Green_Ignore_Alpha, nullptr};
Block BC1_Black_Full_Alpha_Block = {BC1_Black_Full_Alpha, nullptr};
Block BC1_Red_Blue_Full_Alpha_Block = {BC1_Red_Blue_Full_Alpha, nullptr};
Block BC1_Red_Green_Full_Alpha_Block = {BC1_Red_Green_Full_Alpha, nullptr};
Block BC1_Green_Blue_Full_Alpha_Block = {BC1_Green_Blue_Full_Alpha, nullptr};
Block BC1_Blue_Ignore_Alpha_Block = {BC1_Blue_Ignore_Alpha, nullptr};
Block BC1_White_Ignore_Alpha_Block = {BC1_White_Ignore_Alpha, nullptr};
Block BC1_Black_Ignore_Alpha_Block = {BC1_Black_Ignore_Alpha, nullptr};
Block BC1_Red_Blue_Ignore_Alpha_Block = {BC1_Red_Blue_Ignore_Alpha, nullptr};
Block BC1_Red_Green_Ignore_Alpha_Block = {BC1_Red_Green_Ignore_Alpha, nullptr};
Block BC1_Green_Blue_Ignore_Alpha_Block = {BC1_Green_Blue_Ignore_Alpha, nullptr};
Block BC1_Red_Half_Alpha_Block = {BC1_Red_Half_Alpha, nullptr};
Block BC1_Green_Half_Alpha_Block = {BC1_Green_Half_Alpha, nullptr};
Block BC2_Red_Ignore_Alpha_Block = {BC2_Red_Ignore_Alpha, nullptr};
Block BC2_Blue_Half_Alpha_Block = {BC2_Blue_Half_Alpha, nullptr};
Block BC2_White_Half_Alpha_Block = {BC2_White_Half_Alpha, nullptr};
Block BC2_Black_Half_Alpha_Block = {BC2_Black_Half_Alpha, nullptr};
Block BC2_Red_Blue_Half_Alpha_Block = {BC2_Red_Blue_Half_Alpha, nullptr};
Block BC2_Red_Green_Half_Alpha_Block = {BC2_Red_Green_Half_Alpha, nullptr};
Block BC2_Green_Blue_Half_Alpha_Block = {BC2_Green_Blue_Half_Alpha, nullptr};
Block BC2_Red_Full_Alpha_Block = {BC2_Red_Full_Alpha, nullptr};
Block BC2_Green_Full_Alpha_Block = {BC2_Green_Full_Alpha, nullptr};
Block BC2_Blue_Full_Alpha_Block = {BC2_Blue_Full_Alpha, nullptr};
Block BC2_White_Full_Alpha_Block = {BC2_White_Full_Alpha, nullptr};
Block BC2_Green_Ignore_Alpha_Block = {BC2_Green_Ignore_Alpha, nullptr};
Block BC2_Black_Full_Alpha_Block = {BC2_Black_Full_Alpha, nullptr};
Block BC2_Red_Blue_Full_Alpha_Block = {BC2_Red_Blue_Full_Alpha, nullptr};
Block BC2_Red_Green_Full_Alpha_Block = {BC2_Red_Green_Full_Alpha, nullptr};
Block BC2_Green_Blue_Full_Alpha_Block = {BC2_Green_Blue_Full_Alpha, nullptr};
Block BC2_Blue_Ignore_Alpha_Block = {BC2_Blue_Ignore_Alpha, nullptr};
Block BC2_White_Ignore_Alpha_Block = {BC2_White_Ignore_Alpha, nullptr};
Block BC2_Black_Ignore_Alpha_Block = {BC2_Black_Ignore_Alpha, nullptr};
Block BC2_Red_Blue_Ignore_Alpha_Block = {BC2_Red_Blue_Ignore_Alpha, nullptr};
Block BC2_Red_Green_Ignore_Alpha_Block = {BC2_Red_Green_Ignore_Alpha, nullptr};
Block BC2_Green_Blue_Ignore_Alpha_Block = {BC2_Green_Blue_Ignore_Alpha, nullptr};
Block BC2_Red_Half_Alpha_Block = {BC2_Red_Half_Alpha, nullptr};
Block BC2_Green_Half_Alpha_Block = {BC2_Green_Half_Alpha, nullptr};
Block BC3_Red_Ignore_Alpha_Block = {BC3_Red_Ignore_Alpha, nullptr};
Block BC3_Blue_Half_Alpha_Block = {BC3_Blue_Half_Alpha, nullptr};
Block BC3_White_Half_Alpha_Block = {BC3_White_Half_Alpha, nullptr};
Block BC3_Black_Half_Alpha_Block = {BC3_Black_Half_Alpha, nullptr};
Block BC3_Red_Blue_Half_Alpha_Block = {BC3_Red_Blue_Half_Alpha, nullptr};
Block BC3_Red_Green_Half_Alpha_Block = {BC3_Red_Green_Half_Alpha, nullptr};
Block BC3_Green_Blue_Half_Alpha_Block = {BC3_Green_Blue_Half_Alpha, nullptr};
Block BC3_Red_Full_Alpha_Block = {BC3_Red_Full_Alpha, nullptr};
Block BC3_Green_Full_Alpha_Block = {BC3_Green_Full_Alpha, nullptr};
Block BC3_Blue_Full_Alpha_Block = {BC3_Blue_Full_Alpha, nullptr};
Block BC3_White_Full_Alpha_Block = {BC3_White_Full_Alpha, nullptr};
Block BC3_Green_Ignore_Alpha_Block = {BC3_Green_Ignore_Alpha, nullptr};
Block BC3_Black_Full_Alpha_Block = {BC3_Black_Full_Alpha, nullptr};
Block BC3_Red_Blue_Full_Alpha_Block = {BC3_Red_Blue_Full_Alpha, nullptr};
Block BC3_Red_Green_Full_Alpha_Block = {BC3_Red_Green_Full_Alpha, nullptr};
Block BC3_Green_Blue_Full_Alpha_Block = {BC3_Green_Blue_Full_Alpha, nullptr};
Block BC3_Blue_Ignore_Alpha_Block = {BC3_Blue_Ignore_Alpha, nullptr};
Block BC3_White_Ignore_Alpha_Block = {BC3_White_Ignore_Alpha, nullptr};
Block BC3_Black_Ignore_Alpha_Block = {BC3_Black_Ignore_Alpha, nullptr};
Block BC3_Red_Blue_Ignore_Alpha_Block = {BC3_Red_Blue_Ignore_Alpha, nullptr};
Block BC3_Red_Green_Ignore_Alpha_Block = {BC3_Red_Green_Ignore_Alpha, nullptr};
Block BC3_Green_Blue_Ignore_Alpha_Block = {BC3_Green_Blue_Ignore_Alpha, nullptr};
Block BC3_Red_Half_Alpha_Block = {BC3_Red_Half_Alpha, nullptr};
Block BC3_Green_Half_Alpha_Block = {BC3_Green_Half_Alpha, nullptr};
Block BC4_Red_Ignore_Alpha_Block = {BC4_Red_Ignore_Alpha, nullptr};
Block BC4_Blue_Half_Alpha_Block = {BC4_Blue_Half_Alpha, nullptr};
Block BC4_White_Half_Alpha_Block = {BC4_White_Half_Alpha, nullptr};
Block BC4_Black_Half_Alpha_Block = {BC4_Black_Half_Alpha, nullptr};
Block BC4_Red_Blue_Half_Alpha_Block = {BC4_Red_Blue_Half_Alpha, nullptr};
Block BC4_Red_Green_Half_Alpha_Block = {BC4_Red_Green_Half_Alpha, nullptr};
Block BC4_Green_Blue_Half_Alpha_Block = {BC4_Green_Blue_Half_Alpha, nullptr};
Block BC4_Red_Full_Alpha_Block = {BC4_Red_Full_Alpha, nullptr};
Block BC4_Green_Full_Alpha_Block = {BC4_Green_Full_Alpha, nullptr};
Block BC4_Blue_Full_Alpha_Block = {BC4_Blue_Full_Alpha, nullptr};
Block BC4_White_Full_Alpha_Block = {BC4_White_Full_Alpha, nullptr};
Block BC4_Green_Ignore_Alpha_Block = {BC4_Green_Ignore_Alpha, nullptr};
Block BC4_Black_Full_Alpha_Block = {BC4_Black_Full_Alpha, nullptr};
Block BC4_Red_Blue_Full_Alpha_Block = {BC4_Red_Blue_Full_Alpha, nullptr};
Block BC4_Red_Green_Full_Alpha_Block = {BC4_Red_Green_Full_Alpha, nullptr};
Block BC4_Green_Blue_Full_Alpha_Block = {BC4_Green_Blue_Full_Alpha, nullptr};
Block BC4_Blue_Ignore_Alpha_Block = {BC4_Blue_Ignore_Alpha, nullptr};
Block BC4_White_Ignore_Alpha_Block = {BC4_White_Ignore_Alpha, nullptr};
Block BC4_Black_Ignore_Alpha_Block = {BC4_Black_Ignore_Alpha, nullptr};
Block BC4_Red_Blue_Ignore_Alpha_Block = {BC4_Red_Blue_Ignore_Alpha, nullptr};
Block BC4_Red_Green_Ignore_Alpha_Block = {BC4_Red_Green_Ignore_Alpha, nullptr};
Block BC4_Green_Blue_Ignore_Alpha_Block = {BC4_Green_Blue_Ignore_Alpha, nullptr};
Block BC4_Red_Half_Alpha_Block = {BC4_Red_Half_Alpha, nullptr};
Block BC4_Green_Half_Alpha_Block = {BC4_Green_Half_Alpha, nullptr};
Block BC5_Red_Ignore_Alpha_Block = {BC5_Red_Ignore_Alpha, nullptr};
Block BC5_Blue_Half_Alpha_Block = {BC5_Blue_Half_Alpha, nullptr};
Block BC5_White_Half_Alpha_Block = {BC5_White_Half_Alpha, nullptr};
Block BC5_Black_Half_Alpha_Block = {BC5_Black_Half_Alpha, nullptr};
Block BC5_Red_Blue_Half_Alpha_Block = {BC5_Red_Blue_Half_Alpha, nullptr};
Block BC5_Red_Green_Half_Alpha_Block = {BC5_Red_Green_Half_Alpha, nullptr};
Block BC5_Green_Blue_Half_Alpha_Block = {BC5_Green_Blue_Half_Alpha, nullptr};
Block BC5_Red_Full_Alpha_Block = {BC5_Red_Full_Alpha, nullptr};
Block BC5_Green_Full_Alpha_Block = {BC5_Green_Full_Alpha, nullptr};
Block BC5_Blue_Full_Alpha_Block = {BC5_Blue_Full_Alpha, nullptr};
Block BC5_White_Full_Alpha_Block = {BC5_White_Full_Alpha, nullptr};
Block BC5_Green_Ignore_Alpha_Block = {BC5_Green_Ignore_Alpha, nullptr};
Block BC5_Black_Full_Alpha_Block = {BC5_Black_Full_Alpha, nullptr};
Block BC5_Red_Blue_Full_Alpha_Block = {BC5_Red_Blue_Full_Alpha, nullptr};
Block BC5_Red_Green_Full_Alpha_Block = {BC5_Red_Green_Full_Alpha, nullptr};
Block BC5_Green_Blue_Full_Alpha_Block = {BC5_Green_Blue_Full_Alpha, nullptr};
Block BC5_Blue_Ignore_Alpha_Block = {BC5_Blue_Ignore_Alpha, nullptr};
Block BC5_White_Ignore_Alpha_Block = {BC5_White_Ignore_Alpha, nullptr};
Block BC5_Black_Ignore_Alpha_Block = {BC5_Black_Ignore_Alpha, nullptr};
Block BC5_Red_Blue_Ignore_Alpha_Block = {BC5_Red_Blue_Ignore_Alpha, nullptr};
Block BC5_Red_Green_Ignore_Alpha_Block = {BC5_Red_Green_Ignore_Alpha, nullptr};
Block BC5_Green_Blue_Ignore_Alpha_Block = {BC5_Green_Blue_Ignore_Alpha, nullptr};
Block BC5_Red_Half_Alpha_Block = {BC5_Red_Half_Alpha, nullptr};
Block BC5_Green_Half_Alpha_Block = {BC5_Green_Half_Alpha, nullptr};
BlockBC6 BC6_Red_Ignore_Alpha_Block = {BC6_Red_Ignore_Alpha, nullptr};
BlockBC6 BC6_Blue_Half_Alpha_Block = {BC6_Blue_Half_Alpha, nullptr};
BlockBC6 BC6_White_Half_Alpha_Block = {BC6_White_Half_Alpha, nullptr};
BlockBC6 BC6_Black_Half_Alpha_Block = {BC6_Black_Half_Alpha, nullptr};
BlockBC6 BC6_Red_Blue_Half_Alpha_Block = {BC6_Red_Blue_Half_Alpha, nullptr};
BlockBC6 BC6_Red_Green_Half_Alpha_Block = {BC6_Red_Green_Half_Alpha, nullptr};
BlockBC6 BC6_Green_Blue_Half_Alpha_Block = {BC6_Green_Blue_Half_Alpha, nullptr};
BlockBC6 BC6_Red_Full_Alpha_Block = {BC6_Red_Full_Alpha, nullptr};
BlockBC6 BC6_Green_Full_Alpha_Block = {BC6_Green_Full_Alpha, nullptr};
BlockBC6 BC6_Blue_Full_Alpha_Block = {BC6_Blue_Full_Alpha, nullptr};
BlockBC6 BC6_White_Full_Alpha_Block = {BC6_White_Full_Alpha, nullptr};
BlockBC6 BC6_Green_Ignore_Alpha_Block = {BC6_Green_Ignore_Alpha, nullptr};
BlockBC6 BC6_Black_Full_Alpha_Block = {BC6_Black_Full_Alpha, nullptr};
BlockBC6 BC6_Red_Blue_Full_Alpha_Block = {BC6_Red_Blue_Full_Alpha, nullptr};
BlockBC6 BC6_Red_Green_Full_Alpha_Block = {BC6_Red_Green_Full_Alpha, nullptr};
BlockBC6 BC6_Green_Blue_Full_Alpha_Block = {BC6_Green_Blue_Full_Alpha, nullptr};
BlockBC6 BC6_Blue_Ignore_Alpha_Block = {BC6_Blue_Ignore_Alpha, nullptr};
BlockBC6 BC6_White_Ignore_Alpha_Block = {BC6_White_Ignore_Alpha, nullptr};
BlockBC6 BC6_Black_Ignore_Alpha_Block = {BC6_Black_Ignore_Alpha, nullptr};
BlockBC6 BC6_Red_Blue_Ignore_Alpha_Block = {BC6_Red_Blue_Ignore_Alpha, nullptr};
BlockBC6 BC6_Red_Green_Ignore_Alpha_Block = {BC6_Red_Green_Ignore_Alpha, nullptr};
BlockBC6 BC6_Green_Blue_Ignore_Alpha_Block = {BC6_Green_Blue_Ignore_Alpha, nullptr};
BlockBC6 BC6_Red_Half_Alpha_Block = {BC6_Red_Half_Alpha, nullptr};
BlockBC6 BC6_Green_Half_Alpha_Block = {BC6_Green_Half_Alpha, nullptr};
Block BC7_Red_Ignore_Alpha_Block = {BC7_Red_Ignore_Alpha, nullptr};
Block BC7_Blue_Half_Alpha_Block = {BC7_Blue_Half_Alpha, nullptr};
Block BC7_White_Half_Alpha_Block = {BC7_White_Half_Alpha, nullptr};
Block BC7_Black_Half_Alpha_Block = {BC7_Black_Half_Alpha, nullptr};
Block BC7_Red_Blue_Half_Alpha_Block = {BC7_Red_Blue_Half_Alpha, nullptr};
Block BC7_Red_Green_Half_Alpha_Block = {BC7_Red_Green_Half_Alpha, nullptr};
Block BC7_Green_Blue_Half_Alpha_Block = {BC7_Green_Blue_Half_Alpha, nullptr};
Block BC7_Red_Full_Alpha_Block = {BC7_Red_Full_Alpha, nullptr};
Block BC7_Green_Full_Alpha_Block = {BC7_Green_Full_Alpha, nullptr};
Block BC7_Blue_Full_Alpha_Block = {BC7_Blue_Full_Alpha, nullptr};
Block BC7_White_Full_Alpha_Block = {BC7_White_Full_Alpha, nullptr};
Block BC7_Green_Ignore_Alpha_Block = {BC7_Green_Ignore_Alpha, nullptr};
Block BC7_Black_Full_Alpha_Block = {BC7_Black_Full_Alpha, nullptr};
Block BC7_Red_Blue_Full_Alpha_Block = {BC7_Red_Blue_Full_Alpha, nullptr};
Block BC7_Red_Green_Full_Alpha_Block = {BC7_Red_Green_Full_Alpha, nullptr};
Block BC7_Green_Blue_Full_Alpha_Block = {BC7_Green_Blue_Full_Alpha, nullptr};
Block BC7_Blue_Ignore_Alpha_Block = {BC7_Blue_Ignore_Alpha, nullptr};
Block BC7_White_Ignore_Alpha_Block = {BC7_White_Ignore_Alpha, nullptr};
Block BC7_Black_Ignore_Alpha_Block = {BC7_Black_Ignore_Alpha, nullptr};
Block BC7_Red_Blue_Ignore_Alpha_Block = {BC7_Red_Blue_Ignore_Alpha, nullptr};
Block BC7_Red_Green_Ignore_Alpha_Block = {BC7_Red_Green_Ignore_Alpha, nullptr};
Block BC7_Green_Blue_Ignore_Alpha_Block = {BC7_Green_Blue_Ignore_Alpha, nullptr};
Block BC7_Red_Half_Alpha_Block = {BC7_Red_Half_Alpha, nullptr};
Block BC7_Green_Half_Alpha_Block = {BC7_Green_Half_Alpha, nullptr};
static std::unordered_map<std::string, Block> blocks {
{ "BC1_Red_Ignore_Alpha", BC1_Red_Ignore_Alpha_Block},
{ "BC1_Blue_Half_Alpha", BC1_Blue_Half_Alpha_Block},
{ "BC1_White_Half_Alpha", BC1_White_Half_Alpha_Block},
{ "BC1_Black_Half_Alpha", BC1_Black_Half_Alpha_Block},
{ "BC1_Red_Blue_Half_Alpha", BC1_Red_Blue_Half_Alpha_Block},
{ "BC1_Red_Green_Half_Alpha", BC1_Red_Green_Half_Alpha_Block},
{ "BC1_Green_Blue_Half_Alpha", BC1_Green_Blue_Half_Alpha_Block},
{ "BC1_Red_Full_Alpha", BC1_Red_Full_Alpha_Block},
{ "BC1_Green_Full_Alpha", BC1_Green_Full_Alpha_Block},
{ "BC1_Blue_Full_Alpha", BC1_Blue_Full_Alpha_Block},
{ "BC1_White_Full_Alpha", BC1_White_Full_Alpha_Block},
{ "BC1_Green_Ignore_Alpha", BC1_Green_Ignore_Alpha_Block},
{ "BC1_Black_Full_Alpha", BC1_Black_Full_Alpha_Block},
{ "BC1_Red_Blue_Full_Alpha", BC1_Red_Blue_Full_Alpha_Block},
{ "BC1_Red_Green_Full_Alpha", BC1_Red_Green_Full_Alpha_Block},
{ "BC1_Green_Blue_Full_Alpha", BC1_Green_Blue_Full_Alpha_Block},
{ "BC1_Blue_Ignore_Alpha", BC1_Blue_Ignore_Alpha_Block},
{ "BC1_White_Ignore_Alpha", BC1_White_Ignore_Alpha_Block},
{ "BC1_Black_Ignore_Alpha", BC1_Black_Ignore_Alpha_Block},
{ "BC1_Red_Blue_Ignore_Alpha", BC1_Red_Blue_Ignore_Alpha_Block},
{ "BC1_Red_Green_Ignore_Alpha", BC1_Red_Green_Ignore_Alpha_Block},
{ "BC1_Green_Blue_Ignore_Alpha", BC1_Green_Blue_Ignore_Alpha_Block},
{ "BC1_Red_Half_Alpha", BC1_Red_Half_Alpha_Block},
{ "BC1_Green_Half_Alpha", BC1_Green_Half_Alpha_Block},
{ "BC2_Red_Ignore_Alpha", BC2_Red_Ignore_Alpha_Block},
{ "BC2_Blue_Half_Alpha", BC2_Blue_Half_Alpha_Block},
{ "BC2_White_Half_Alpha", BC2_White_Half_Alpha_Block},
{ "BC2_Black_Half_Alpha", BC2_Black_Half_Alpha_Block},
{ "BC2_Red_Blue_Half_Alpha", BC2_Red_Blue_Half_Alpha_Block},
{ "BC2_Red_Green_Half_Alpha", BC2_Red_Green_Half_Alpha_Block},
{ "BC2_Green_Blue_Half_Alpha", BC2_Green_Blue_Half_Alpha_Block},
{ "BC2_Red_Full_Alpha", BC2_Red_Full_Alpha_Block},
{ "BC2_Green_Full_Alpha", BC2_Green_Full_Alpha_Block},
{ "BC2_Blue_Full_Alpha", BC2_Blue_Full_Alpha_Block},
{ "BC2_White_Full_Alpha", BC2_White_Full_Alpha_Block},
{ "BC2_Green_Ignore_Alpha", BC2_Green_Ignore_Alpha_Block},
{ "BC2_Black_Full_Alpha", BC2_Black_Full_Alpha_Block},
{ "BC2_Red_Blue_Full_Alpha", BC2_Red_Blue_Full_Alpha_Block},
{ "BC2_Red_Green_Full_Alpha", BC2_Red_Green_Full_Alpha_Block},
{ "BC2_Green_Blue_Full_Alpha", BC2_Green_Blue_Full_Alpha_Block},
{ "BC2_Blue_Ignore_Alpha", BC2_Blue_Ignore_Alpha_Block},
{ "BC2_White_Ignore_Alpha", BC2_White_Ignore_Alpha_Block},
{ "BC2_Black_Ignore_Alpha", BC2_Black_Ignore_Alpha_Block},
{ "BC2_Red_Blue_Ignore_Alpha", BC2_Red_Blue_Ignore_Alpha_Block},
{ "BC2_Red_Green_Ignore_Alpha", BC2_Red_Green_Ignore_Alpha_Block},
{ "BC2_Green_Blue_Ignore_Alpha", BC2_Green_Blue_Ignore_Alpha_Block},
{ "BC2_Red_Half_Alpha", BC2_Red_Half_Alpha_Block},
{ "BC2_Green_Half_Alpha", BC2_Green_Half_Alpha_Block},
{ "BC3_Red_Ignore_Alpha", BC3_Red_Ignore_Alpha_Block},
{ "BC3_Blue_Half_Alpha", BC3_Blue_Half_Alpha_Block},
{ "BC3_White_Half_Alpha", BC3_White_Half_Alpha_Block},
{ "BC3_Black_Half_Alpha", BC3_Black_Half_Alpha_Block},
{ "BC3_Red_Blue_Half_Alpha", BC3_Red_Blue_Half_Alpha_Block},
{ "BC3_Red_Green_Half_Alpha", BC3_Red_Green_Half_Alpha_Block},
{ "BC3_Green_Blue_Half_Alpha", BC3_Green_Blue_Half_Alpha_Block},
{ "BC3_Red_Full_Alpha", BC3_Red_Full_Alpha_Block},
{ "BC3_Green_Full_Alpha", BC3_Green_Full_Alpha_Block},
{ "BC3_Blue_Full_Alpha", BC3_Blue_Full_Alpha_Block},
{ "BC3_White_Full_Alpha", BC3_White_Full_Alpha_Block},
{ "BC3_Green_Ignore_Alpha", BC3_Green_Ignore_Alpha_Block},
{ "BC3_Black_Full_Alpha", BC3_Black_Full_Alpha_Block},
{ "BC3_Red_Blue_Full_Alpha", BC3_Red_Blue_Full_Alpha_Block},
{ "BC3_Red_Green_Full_Alpha", BC3_Red_Green_Full_Alpha_Block},
{ "BC3_Green_Blue_Full_Alpha", BC3_Green_Blue_Full_Alpha_Block},
{ "BC3_Blue_Ignore_Alpha", BC3_Blue_Ignore_Alpha_Block},
{ "BC3_White_Ignore_Alpha", BC3_White_Ignore_Alpha_Block},
{ "BC3_Black_Ignore_Alpha", BC3_Black_Ignore_Alpha_Block},
{ "BC3_Red_Blue_Ignore_Alpha", BC3_Red_Blue_Ignore_Alpha_Block},
{ "BC3_Red_Green_Ignore_Alpha", BC3_Red_Green_Ignore_Alpha_Block},
{ "BC3_Green_Blue_Ignore_Alpha", BC3_Green_Blue_Ignore_Alpha_Block},
{ "BC3_Red_Half_Alpha", BC3_Red_Half_Alpha_Block},
{ "BC3_Green_Half_Alpha", BC3_Green_Half_Alpha_Block},
{ "BC4_Red_Ignore_Alpha", BC4_Red_Ignore_Alpha_Block},
{ "BC4_Blue_Half_Alpha", BC4_Blue_Half_Alpha_Block},
{ "BC4_White_Half_Alpha", BC4_White_Half_Alpha_Block},
{ "BC4_Black_Half_Alpha", BC4_Black_Half_Alpha_Block},
{ "BC4_Red_Blue_Half_Alpha", BC4_Red_Blue_Half_Alpha_Block},
{ "BC4_Red_Green_Half_Alpha", BC4_Red_Green_Half_Alpha_Block},
{ "BC4_Green_Blue_Half_Alpha", BC4_Green_Blue_Half_Alpha_Block},
{ "BC4_Red_Full_Alpha", BC4_Red_Full_Alpha_Block},
{ "BC4_Green_Full_Alpha", BC4_Green_Full_Alpha_Block},
{ "BC4_Blue_Full_Alpha", BC4_Blue_Full_Alpha_Block},
{ "BC4_White_Full_Alpha", BC4_White_Full_Alpha_Block},
{ "BC4_Green_Ignore_Alpha", BC4_Green_Ignore_Alpha_Block},
{ "BC4_Black_Full_Alpha", BC4_Black_Full_Alpha_Block},
{ "BC4_Red_Blue_Full_Alpha", BC4_Red_Blue_Full_Alpha_Block},
{ "BC4_Red_Green_Full_Alpha", BC4_Red_Green_Full_Alpha_Block},
{ "BC4_Green_Blue_Full_Alpha", BC4_Green_Blue_Full_Alpha_Block},
{ "BC4_Blue_Ignore_Alpha", BC4_Blue_Ignore_Alpha_Block},
{ "BC4_White_Ignore_Alpha", BC4_White_Ignore_Alpha_Block},
{ "BC4_Black_Ignore_Alpha", BC4_Black_Ignore_Alpha_Block},
{ "BC4_Red_Blue_Ignore_Alpha", BC4_Red_Blue_Ignore_Alpha_Block},
{ "BC4_Red_Green_Ignore_Alpha", BC4_Red_Green_Ignore_Alpha_Block},
{ "BC4_Green_Blue_Ignore_Alpha", BC4_Green_Blue_Ignore_Alpha_Block},
{ "BC4_Red_Half_Alpha", BC4_Red_Half_Alpha_Block},
{ "BC4_Green_Half_Alpha", BC4_Green_Half_Alpha_Block},
{ "BC5_Red_Ignore_Alpha", BC5_Red_Ignore_Alpha_Block},
{ "BC5_Blue_Half_Alpha", BC5_Blue_Half_Alpha_Block},
{ "BC5_White_Half_Alpha", BC5_White_Half_Alpha_Block},
{ "BC5_Black_Half_Alpha", BC5_Black_Half_Alpha_Block},
{ "BC5_Red_Blue_Half_Alpha", BC5_Red_Blue_Half_Alpha_Block},
{ "BC5_Red_Green_Half_Alpha", BC5_Red_Green_Half_Alpha_Block},
{ "BC5_Green_Blue_Half_Alpha", BC5_Green_Blue_Half_Alpha_Block},
{ "BC5_Red_Full_Alpha", BC5_Red_Full_Alpha_Block},
{ "BC5_Green_Full_Alpha", BC5_Green_Full_Alpha_Block},
{ "BC5_Blue_Full_Alpha", BC5_Blue_Full_Alpha_Block},
{ "BC5_White_Full_Alpha", BC5_White_Full_Alpha_Block},
{ "BC5_Green_Ignore_Alpha", BC5_Green_Ignore_Alpha_Block},
{ "BC5_Black_Full_Alpha", BC5_Black_Full_Alpha_Block},
{ "BC5_Red_Blue_Full_Alpha", BC5_Red_Blue_Full_Alpha_Block},
{ "BC5_Red_Green_Full_Alpha", BC5_Red_Green_Full_Alpha_Block},
{ "BC5_Green_Blue_Full_Alpha", BC5_Green_Blue_Full_Alpha_Block},
{ "BC5_Blue_Ignore_Alpha", BC5_Blue_Ignore_Alpha_Block},
{ "BC5_White_Ignore_Alpha", BC5_White_Ignore_Alpha_Block},
{ "BC5_Black_Ignore_Alpha", BC5_Black_Ignore_Alpha_Block},
{ "BC5_Red_Blue_Ignore_Alpha", BC5_Red_Blue_Ignore_Alpha_Block},
{ "BC5_Red_Green_Ignore_Alpha", BC5_Red_Green_Ignore_Alpha_Block},
{ "BC5_Green_Blue_Ignore_Alpha", BC5_Green_Blue_Ignore_Alpha_Block},
{ "BC5_Red_Half_Alpha", BC5_Red_Half_Alpha_Block},
{ "BC5_Green_Half_Alpha", BC5_Green_Half_Alpha_Block},
{ "BC7_Red_Ignore_Alpha", BC7_Red_Ignore_Alpha_Block},
{ "BC7_Blue_Half_Alpha", BC7_Blue_Half_Alpha_Block},
{ "BC7_White_Half_Alpha", BC7_White_Half_Alpha_Block},
{ "BC7_Black_Half_Alpha", BC7_Black_Half_Alpha_Block},
{ "BC7_Red_Blue_Half_Alpha", BC7_Red_Blue_Half_Alpha_Block},
{ "BC7_Red_Green_Half_Alpha", BC7_Red_Green_Half_Alpha_Block},
{ "BC7_Green_Blue_Half_Alpha", BC7_Green_Blue_Half_Alpha_Block},
{ "BC7_Red_Full_Alpha", BC7_Red_Full_Alpha_Block},
{ "BC7_Green_Full_Alpha", BC7_Green_Full_Alpha_Block},
{ "BC7_Blue_Full_Alpha", BC7_Blue_Full_Alpha_Block},
{ "BC7_White_Full_Alpha", BC7_White_Full_Alpha_Block},
{ "BC7_Green_Ignore_Alpha", BC7_Green_Ignore_Alpha_Block},
{ "BC7_Black_Full_Alpha", BC7_Black_Full_Alpha_Block},
{ "BC7_Red_Blue_Full_Alpha", BC7_Red_Blue_Full_Alpha_Block},
{ "BC7_Red_Green_Full_Alpha", BC7_Red_Green_Full_Alpha_Block},
{ "BC7_Green_Blue_Full_Alpha", BC7_Green_Blue_Full_Alpha_Block},
{ "BC7_Blue_Ignore_Alpha", BC7_Blue_Ignore_Alpha_Block},
{ "BC7_White_Ignore_Alpha", BC7_White_Ignore_Alpha_Block},
{ "BC7_Black_Ignore_Alpha", BC7_Black_Ignore_Alpha_Block},
{ "BC7_Red_Blue_Ignore_Alpha", BC7_Red_Blue_Ignore_Alpha_Block},
{ "BC7_Red_Green_Ignore_Alpha", BC7_Red_Green_Ignore_Alpha_Block},
{ "BC7_Green_Blue_Ignore_Alpha", BC7_Green_Blue_Ignore_Alpha_Block},
{ "BC7_Red_Half_Alpha", BC7_Red_Half_Alpha_Block},
{ "BC7_Green_Half_Alpha", BC7_Green_Half_Alpha_Block}
};
static std::unordered_map<std::string, BlockBC6> blocksBC6 {
{ "BC6_Red_Ignore_Alpha", BC6_Red_Ignore_Alpha_Block},
{ "BC6_Blue_Half_Alpha", BC6_Blue_Half_Alpha_Block},
{ "BC6_White_Half_Alpha", BC6_White_Half_Alpha_Block},
{ "BC6_Black_Half_Alpha", BC6_Black_Half_Alpha_Block},
{ "BC6_Red_Blue_Half_Alpha", BC6_Red_Blue_Half_Alpha_Block},
{ "BC6_Red_Green_Half_Alpha", BC6_Red_Green_Half_Alpha_Block},
{ "BC6_Green_Blue_Half_Alpha", BC6_Green_Blue_Half_Alpha_Block},
{ "BC6_Red_Full_Alpha", BC6_Red_Full_Alpha_Block},
{ "BC6_Green_Full_Alpha", BC6_Green_Full_Alpha_Block},
{ "BC6_Blue_Full_Alpha", BC6_Blue_Full_Alpha_Block},
{ "BC6_White_Full_Alpha", BC6_White_Full_Alpha_Block},
{ "BC6_Green_Ignore_Alpha", BC6_Green_Ignore_Alpha_Block},
{ "BC6_Black_Full_Alpha", BC6_Black_Full_Alpha_Block},
{ "BC6_Red_Blue_Full_Alpha", BC6_Red_Blue_Full_Alpha_Block},
{ "BC6_Red_Green_Full_Alpha", BC6_Red_Green_Full_Alpha_Block},
{ "BC6_Green_Blue_Full_Alpha", BC6_Green_Blue_Full_Alpha_Block},
{ "BC6_Blue_Ignore_Alpha", BC6_Blue_Ignore_Alpha_Block},
{ "BC6_White_Ignore_Alpha", BC6_White_Ignore_Alpha_Block},
{ "BC6_Black_Ignore_Alpha", BC6_Black_Ignore_Alpha_Block},
{ "BC6_Red_Blue_Ignore_Alpha", BC6_Red_Blue_Ignore_Alpha_Block},
{ "BC6_Red_Green_Ignore_Alpha", BC6_Red_Green_Ignore_Alpha_Block},
{ "BC6_Green_Blue_Ignore_Alpha", BC6_Green_Blue_Ignore_Alpha_Block},
{ "BC6_Red_Half_Alpha", BC6_Red_Half_Alpha_Block},
{ "BC6_Green_Half_Alpha", BC6_Green_Half_Alpha_Block}
};
#endif

15
extern/CMP_Core/test/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 3.5)
project(CMP_Core_Tests)
add_executable(Tests TestsMain.cpp)
add_subdirectory(../../../Common/Lib/Ext/Catch2
Common/Lib/Ext/Catch2/bin)
target_sources(Tests
PRIVATE
CompressonatorTests.cpp
CompressonatorTests.h
BlockConstants.h
../../Applications/_Plugins/Common/UtilFuncs.cpp
../../Applications/_Plugins/Common/UtilFuncs.h
)
target_link_libraries(Tests Catch2::Catch2 CMP_Core)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,6 @@
#ifndef COMPRESSONATOR_TESTS_H
#define COMPRESSONATOR_TESTS_H
void AssignExpectedColorsToBlocks();
#endif

10
extern/CMP_Core/test/TestsMain.cpp vendored Normal file
View File

@ -0,0 +1,10 @@
#define CATCH_CONFIG_RUNNER
#include "../../../Common/Lib/Ext/Catch2/catch.hpp"
#include "CompressonatorTests.h"
int main(int argc, char* argv[]) {
AssignExpectedColorsToBlocks();
int result = Catch::Session().run(argc, argv);
return result;
}

13
extern/CMakeLists.txt vendored
View File

@ -1,6 +1,11 @@
IF(WIN32)
ADD_SUBDIRECTORY(gnuwin32)
ENDIF(WIN32)
ADD_SUBDIRECTORY(poshlib)
ADD_SUBDIRECTORY(EtcLib)
ADD_SUBDIRECTORY(rg_etc1_v104)
#ADD_SUBDIRECTORY(etcpack)
ADD_SUBDIRECTORY(libsquish-1.15)
ADD_SUBDIRECTORY(CMP_Core)

24
extern/EtcLib/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,24 @@
# Copyright 2015 The Etc2Comp Authors.
#
# 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.
project(EtcLib)
include_directories(./Etc)
include_directories(./EtcCodec)
file(GLOB SOURCES
${PROJECT_SOURCE_DIR}/Etc/*.h
${PROJECT_SOURCE_DIR}/EtcCodec/*.h
${PROJECT_SOURCE_DIR}/Etc/*.cpp
${PROJECT_SOURCE_DIR}/EtcCodec/*.cpp)
ADD_LIBRARY(EtcLib STATIC ${SOURCES})

58
extern/EtcLib/Etc/Etc.cpp vendored Normal file
View File

@ -0,0 +1,58 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
#include "EtcConfig.h"
#include "Etc.h"
#include <string.h>
namespace Etc
{
// ----------------------------------------------------------------------------------------------------
// C-style inteface to the encoder
//
void Encode(float *a_pafSourceRGBA,
unsigned int a_uiSourceWidth,
unsigned int a_uiSourceHeight,
Image::Format a_format,
ErrorMetric a_eErrMetric,
float a_fEffort,
unsigned int a_uiJobs,
unsigned int a_uiMaxJobs,
unsigned char **a_ppaucEncodingBits,
unsigned int *a_puiEncodingBitsBytes,
unsigned int *a_puiExtendedWidth,
unsigned int *a_puiExtendedHeight,
int *a_piEncodingTime_ms, bool a_bVerboseOutput)
{
Image image(a_pafSourceRGBA, a_uiSourceWidth,
a_uiSourceHeight,
a_eErrMetric);
image.m_bVerboseOutput = a_bVerboseOutput;
image.Encode(a_format, a_eErrMetric, a_fEffort, a_uiJobs, a_uiMaxJobs);
*a_ppaucEncodingBits = image.GetEncodingBits();
*a_puiEncodingBitsBytes = image.GetEncodingBitsBytes();
*a_puiExtendedWidth = image.GetExtendedWidth();
*a_puiExtendedHeight = image.GetExtendedHeight();
*a_piEncodingTime_ms = image.GetEncodingTimeMs();
}
// ----------------------------------------------------------------------------------------------------
//
}

47
extern/EtcLib/Etc/Etc.h vendored Normal file
View File

@ -0,0 +1,47 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
#pragma once
#include "EtcConfig.h"
#include "EtcImage.h"
#include "EtcColor.h"
#include "EtcErrorMetric.h"
#define ETCCOMP_MIN_EFFORT_LEVEL (0.0f)
#define ETCCOMP_DEFAULT_EFFORT_LEVEL (40.0f)
#define ETCCOMP_MAX_EFFORT_LEVEL (100.0f)
namespace Etc
{
class Block4x4EncodingBits;
// C-style inteface to the encoder
void Encode(float *a_pafSourceRGBA,
unsigned int a_uiSourceWidth,
unsigned int a_uiSourceHeight,
Image::Format a_format,
ErrorMetric a_eErrMetric,
float a_fEffort,
unsigned int a_uiJobs,
unsigned int a_uimaxJobs,
unsigned char **a_ppaucEncodingBits,
unsigned int *a_puiEncodingBitsBytes,
unsigned int *a_puiExtendedWidth,
unsigned int *a_puiExtendedHeight,
int *a_piEncodingTime_ms, bool a_bVerboseOutput = false);
}

64
extern/EtcLib/Etc/EtcColor.h vendored Normal file
View File

@ -0,0 +1,64 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
#pragma once
#include <math.h>
namespace Etc
{
inline float LogToLinear(float a_fLog)
{
static const float ALPHA = 0.055f;
static const float ONE_PLUS_ALPHA = 1.0f + ALPHA;
if (a_fLog <= 0.04045f)
{
return a_fLog / 12.92f;
}
else
{
return powf((a_fLog + ALPHA) / ONE_PLUS_ALPHA, 2.4f);
}
}
inline float LinearToLog(float &a_fLinear)
{
static const float ALPHA = 0.055f;
static const float ONE_PLUS_ALPHA = 1.0f + ALPHA;
if (a_fLinear <= 0.0031308f)
{
return 12.92f * a_fLinear;
}
else
{
return ONE_PLUS_ALPHA * powf(a_fLinear, (1.0f/2.4f)) - ALPHA;
}
}
class ColorR8G8B8A8
{
public:
unsigned char ucR;
unsigned char ucG;
unsigned char ucB;
unsigned char ucA;
};
}

321
extern/EtcLib/Etc/EtcColorFloatRGBA.h vendored Normal file
View File

@ -0,0 +1,321 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
#pragma once
#include "EtcConfig.h"
#include "EtcColor.h"
#include <math.h>
namespace Etc
{
class ColorFloatRGBA
{
public:
ColorFloatRGBA(void)
{
fR = fG = fB = fA = 0.0f;
}
ColorFloatRGBA(float a_fR, float a_fG, float a_fB, float a_fA)
{
fR = a_fR;
fG = a_fG;
fB = a_fB;
fA = a_fA;
}
inline ColorFloatRGBA operator+(ColorFloatRGBA& a_rfrgba)
{
ColorFloatRGBA frgba;
frgba.fR = fR + a_rfrgba.fR;
frgba.fG = fG + a_rfrgba.fG;
frgba.fB = fB + a_rfrgba.fB;
frgba.fA = fA + a_rfrgba.fA;
return frgba;
}
inline ColorFloatRGBA operator+(float a_f)
{
ColorFloatRGBA frgba;
frgba.fR = fR + a_f;
frgba.fG = fG + a_f;
frgba.fB = fB + a_f;
frgba.fA = fA;
return frgba;
}
inline ColorFloatRGBA operator-(float a_f)
{
ColorFloatRGBA frgba;
frgba.fR = fR - a_f;
frgba.fG = fG - a_f;
frgba.fB = fB - a_f;
frgba.fA = fA;
return frgba;
}
inline ColorFloatRGBA operator-(ColorFloatRGBA& a_rfrgba)
{
ColorFloatRGBA frgba;
frgba.fR = fR - a_rfrgba.fR;
frgba.fG = fG - a_rfrgba.fG;
frgba.fB = fB - a_rfrgba.fB;
frgba.fA = fA - a_rfrgba.fA;
return frgba;
}
inline ColorFloatRGBA operator*(float a_f)
{
ColorFloatRGBA frgba;
frgba.fR = fR * a_f;
frgba.fG = fG * a_f;
frgba.fB = fB * a_f;
frgba.fA = fA;
return frgba;
}
inline ColorFloatRGBA ScaleRGB(float a_f)
{
ColorFloatRGBA frgba;
frgba.fR = a_f * fR;
frgba.fG = a_f * fG;
frgba.fB = a_f * fB;
frgba.fA = fA;
return frgba;
}
inline ColorFloatRGBA RoundRGB(void)
{
ColorFloatRGBA frgba;
frgba.fR = roundf(fR);
frgba.fG = roundf(fG);
frgba.fB = roundf(fB);
return frgba;
}
inline ColorFloatRGBA ToLinear()
{
ColorFloatRGBA frgbaLinear;
frgbaLinear.fR = LogToLinear(fR);
frgbaLinear.fG = LogToLinear(fG);
frgbaLinear.fB = LogToLinear(fB);
frgbaLinear.fA = fA;
return frgbaLinear;
}
inline ColorFloatRGBA ToLog(void)
{
ColorFloatRGBA frgbaLog;
frgbaLog.fR = LinearToLog(fR);
frgbaLog.fG = LinearToLog(fG);
frgbaLog.fB = LinearToLog(fB);
frgbaLog.fA = fA;
return frgbaLog;
}
inline static ColorFloatRGBA ConvertFromRGBA8(unsigned char a_ucR,
unsigned char a_ucG, unsigned char a_ucB, unsigned char a_ucA)
{
ColorFloatRGBA frgba;
frgba.fR = (float)a_ucR / 255.0f;
frgba.fG = (float)a_ucG / 255.0f;
frgba.fB = (float)a_ucB / 255.0f;
frgba.fA = (float)a_ucA / 255.0f;
return frgba;
}
inline static ColorFloatRGBA ConvertFromRGB4(unsigned char a_ucR4,
unsigned char a_ucG4,
unsigned char a_ucB4)
{
ColorFloatRGBA frgba;
unsigned char ucR8 = (unsigned char)((a_ucR4 << 4) + a_ucR4);
unsigned char ucG8 = (unsigned char)((a_ucG4 << 4) + a_ucG4);
unsigned char ucB8 = (unsigned char)((a_ucB4 << 4) + a_ucB4);
frgba.fR = (float)ucR8 / 255.0f;
frgba.fG = (float)ucG8 / 255.0f;
frgba.fB = (float)ucB8 / 255.0f;
frgba.fA = 1.0f;
return frgba;
}
inline static ColorFloatRGBA ConvertFromRGB5(unsigned char a_ucR5,
unsigned char a_ucG5,
unsigned char a_ucB5)
{
ColorFloatRGBA frgba;
unsigned char ucR8 = (unsigned char)((a_ucR5 << 3) + (a_ucR5 >> 2));
unsigned char ucG8 = (unsigned char)((a_ucG5 << 3) + (a_ucG5 >> 2));
unsigned char ucB8 = (unsigned char)((a_ucB5 << 3) + (a_ucB5 >> 2));
frgba.fR = (float)ucR8 / 255.0f;
frgba.fG = (float)ucG8 / 255.0f;
frgba.fB = (float)ucB8 / 255.0f;
frgba.fA = 1.0f;
return frgba;
}
inline static ColorFloatRGBA ConvertFromR6G7B6(unsigned char a_ucR6,
unsigned char a_ucG7,
unsigned char a_ucB6)
{
ColorFloatRGBA frgba;
unsigned char ucR8 = (unsigned char)((a_ucR6 << 2) + (a_ucR6 >> 4));
unsigned char ucG8 = (unsigned char)((a_ucG7 << 1) + (a_ucG7 >> 6));
unsigned char ucB8 = (unsigned char)((a_ucB6 << 2) + (a_ucB6 >> 4));
frgba.fR = (float)ucR8 / 255.0f;
frgba.fG = (float)ucG8 / 255.0f;
frgba.fB = (float)ucB8 / 255.0f;
frgba.fA = 1.0f;
return frgba;
}
// quantize to 4 bits, expand to 8 bits
inline ColorFloatRGBA QuantizeR4G4B4(void) const
{
ColorFloatRGBA frgba = *this;
// quantize to 4 bits
frgba = frgba.ClampRGB().ScaleRGB(15.0f).RoundRGB();
unsigned int uiR4 = (unsigned int)frgba.fR;
unsigned int uiG4 = (unsigned int)frgba.fG;
unsigned int uiB4 = (unsigned int)frgba.fB;
// expand to 8 bits
frgba.fR = (float) ((uiR4 << 4) + uiR4);
frgba.fG = (float) ((uiG4 << 4) + uiG4);
frgba.fB = (float) ((uiB4 << 4) + uiB4);
frgba = frgba.ScaleRGB(1.0f/255.0f);
return frgba;
}
// quantize to 5 bits, expand to 8 bits
inline ColorFloatRGBA QuantizeR5G5B5(void) const
{
ColorFloatRGBA frgba = *this;
// quantize to 5 bits
frgba = frgba.ClampRGB().ScaleRGB(31.0f).RoundRGB();
unsigned int uiR5 = (unsigned int)frgba.fR;
unsigned int uiG5 = (unsigned int)frgba.fG;
unsigned int uiB5 = (unsigned int)frgba.fB;
// expand to 8 bits
frgba.fR = (float)((uiR5 << 3) + (uiR5 >> 2));
frgba.fG = (float)((uiG5 << 3) + (uiG5 >> 2));
frgba.fB = (float)((uiB5 << 3) + (uiB5 >> 2));
frgba = frgba.ScaleRGB(1.0f / 255.0f);
return frgba;
}
// quantize to 6/7/6 bits, expand to 8 bits
inline ColorFloatRGBA QuantizeR6G7B6(void) const
{
ColorFloatRGBA frgba = *this;
// quantize to 6/7/6 bits
ColorFloatRGBA frgba6 = frgba.ClampRGB().ScaleRGB(63.0f).RoundRGB();
ColorFloatRGBA frgba7 = frgba.ClampRGB().ScaleRGB(127.0f).RoundRGB();
unsigned int uiR6 = (unsigned int)frgba6.fR;
unsigned int uiG7 = (unsigned int)frgba7.fG;
unsigned int uiB6 = (unsigned int)frgba6.fB;
// expand to 8 bits
frgba.fR = (float)((uiR6 << 2) + (uiR6 >> 4));
frgba.fG = (float)((uiG7 << 1) + (uiG7 >> 6));
frgba.fB = (float)((uiB6 << 2) + (uiB6 >> 4));
frgba = frgba.ScaleRGB(1.0f / 255.0f);
return frgba;
}
inline ColorFloatRGBA ClampRGB(void)
{
ColorFloatRGBA frgba = *this;
if (frgba.fR < 0.0f) { frgba.fR = 0.0f; }
if (frgba.fR > 1.0f) { frgba.fR = 1.0f; }
if (frgba.fG < 0.0f) { frgba.fG = 0.0f; }
if (frgba.fG > 1.0f) { frgba.fG = 1.0f; }
if (frgba.fB < 0.0f) { frgba.fB = 0.0f; }
if (frgba.fB > 1.0f) { frgba.fB = 1.0f; }
return frgba;
}
inline ColorFloatRGBA ClampRGBA(void)
{
ColorFloatRGBA frgba = *this;
if (frgba.fR < 0.0f) { frgba.fR = 0.0f; }
if (frgba.fR > 1.0f) { frgba.fR = 1.0f; }
if (frgba.fG < 0.0f) { frgba.fG = 0.0f; }
if (frgba.fG > 1.0f) { frgba.fG = 1.0f; }
if (frgba.fB < 0.0f) { frgba.fB = 0.0f; }
if (frgba.fB > 1.0f) { frgba.fB = 1.0f; }
if (frgba.fA < 0.0f) { frgba.fA = 0.0f; }
if (frgba.fA > 1.0f) { frgba.fA = 1.0f; }
return frgba;
}
inline int IntRed(float a_fScale)
{
return (int)roundf(fR * a_fScale);
}
inline int IntGreen(float a_fScale)
{
return (int)roundf(fG * a_fScale);
}
inline int IntBlue(float a_fScale)
{
return (int)roundf(fB * a_fScale);
}
inline int IntAlpha(float a_fScale)
{
return (int)roundf(fA * a_fScale);
}
float fR, fG, fB, fA;
};
}

67
extern/EtcLib/Etc/EtcConfig.h vendored Normal file
View File

@ -0,0 +1,67 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
#pragma once
#ifdef _WIN32
#define ETC_WINDOWS (1)
#else
#define ETC_WINDOWS (0)
#endif
#if __APPLE__
#define ETC_OSX (1)
#else
#define ETC_OSX (0)
#endif
#if __unix__
#define ETC_UNIX (1)
#else
#define ETC_UNIX (0)
#endif
// short names for common types
#include <stdint.h>
typedef int8_t i8;
typedef int16_t i16;
typedef int32_t i32;
typedef int64_t i64;
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef float f32;
typedef double f64;
// Keep asserts enabled in release builds during development
#undef NDEBUG
// 0=disable. stb_image can be used if you need to compress
//other image formats like jpg
#define USE_STB_IMAGE_LOAD 0
#if ETC_WINDOWS
#include <SDKDDKVer.h>
#define _CRT_SECURE_NO_WARNINGS (1)
#include <tchar.h>
#endif
#include <stdio.h>

685
extern/EtcLib/Etc/EtcImage.cpp vendored Normal file
View File

@ -0,0 +1,685 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
/*
EtcImage.cpp
Image is an array of 4x4 blocks that represent the encoding of the source image
*/
#include "EtcConfig.h"
#include <stdlib.h>
#include "EtcImage.h"
#include "Etc.h"
#include "EtcBlock4x4.h"
#include "EtcBlock4x4EncodingBits.h"
#include "EtcSortedBlockList.h"
#if ETC_WINDOWS
#include <windows.h>
#endif
#include <ctime>
#include <chrono>
#include <future>
#include <stdio.h>
#include <string.h>
#include <assert.h>
// fix conflict with Block4x4::AlphaMix
#ifdef OPAQUE
#undef OPAQUE
#endif
#ifdef TRANSPARENT
#undef TRANSPARENT
#endif
namespace Etc
{
// ----------------------------------------------------------------------------------------------------
//
Image::Image(void)
{
m_encodingStatus = EncodingStatus::SUCCESS;
m_warningsToCapture = EncodingStatus::SUCCESS;
m_pafrgbaSource = nullptr;
m_pablock = nullptr;
m_encodingbitsformat = Block4x4EncodingBits::Format::UNKNOWN;
m_uiEncodingBitsBytes = 0;
m_paucEncodingBits = nullptr;
m_format = Format::UNKNOWN;
m_iNumOpaquePixels = 0;
m_iNumTranslucentPixels = 0;
m_iNumTransparentPixels = 0;
}
// ----------------------------------------------------------------------------------------------------
// constructor using source image
// used to set state before Encode() is called
//
Image::Image(float *a_pafSourceRGBA, unsigned int a_uiSourceWidth,
unsigned int a_uiSourceHeight,
ErrorMetric a_errormetric)
{
m_encodingStatus = EncodingStatus::SUCCESS;
m_warningsToCapture = EncodingStatus::SUCCESS;
m_pafrgbaSource = (ColorFloatRGBA *) a_pafSourceRGBA;
m_uiSourceWidth = a_uiSourceWidth;
m_uiSourceHeight = a_uiSourceHeight;
m_uiExtendedWidth = CalcExtendedDimension((unsigned short)m_uiSourceWidth);
m_uiExtendedHeight = CalcExtendedDimension((unsigned short)m_uiSourceHeight);
m_uiBlockColumns = m_uiExtendedWidth >> 2;
m_uiBlockRows = m_uiExtendedHeight >> 2;
m_pablock = new Block4x4[GetNumberOfBlocks()];
assert(m_pablock);
m_format = Format::UNKNOWN;
m_encodingbitsformat = Block4x4EncodingBits::Format::UNKNOWN;
m_uiEncodingBitsBytes = 0;
m_paucEncodingBits = nullptr;
m_errormetric = a_errormetric;
m_fEffort = 0.0f;
m_iEncodeTime_ms = -1;
m_iNumOpaquePixels = 0;
m_iNumTranslucentPixels = 0;
m_iNumTransparentPixels = 0;
m_bVerboseOutput = false;
}
// ----------------------------------------------------------------------------------------------------
// constructor using encoding bits
// recreates encoding state using a previously encoded image
//
Image::Image(Format a_format,
unsigned int a_uiSourceWidth, unsigned int a_uiSourceHeight,
unsigned char *a_paucEncidingBits, unsigned int a_uiEncodingBitsBytes,
Image *a_pimageSource, ErrorMetric a_errormetric)
{
m_encodingStatus = EncodingStatus::SUCCESS;
m_pafrgbaSource = nullptr;
m_uiSourceWidth = a_uiSourceWidth;
m_uiSourceHeight = a_uiSourceHeight;
m_uiExtendedWidth = CalcExtendedDimension((unsigned short)m_uiSourceWidth);
m_uiExtendedHeight = CalcExtendedDimension((unsigned short)m_uiSourceHeight);
m_uiBlockColumns = m_uiExtendedWidth >> 2;
m_uiBlockRows = m_uiExtendedHeight >> 2;
unsigned int uiBlocks = GetNumberOfBlocks();
m_pablock = new Block4x4[uiBlocks];
assert(m_pablock);
m_format = a_format;
m_iNumOpaquePixels = 0;
m_iNumTranslucentPixels = 0;
m_iNumTransparentPixels = 0;
m_encodingbitsformat = DetermineEncodingBitsFormat(m_format);
if (m_encodingbitsformat == Block4x4EncodingBits::Format::UNKNOWN)
{
AddToEncodingStatus(ERROR_UNKNOWN_FORMAT);
return;
}
m_uiEncodingBitsBytes = a_uiEncodingBitsBytes;
m_paucEncodingBits = a_paucEncidingBits;
m_errormetric = a_errormetric;
m_fEffort = 0.0f;
m_bVerboseOutput = false;
m_iEncodeTime_ms = -1;
unsigned char *paucEncodingBits = m_paucEncodingBits;
unsigned int uiEncodingBitsBytesPerBlock = Block4x4EncodingBits::GetBytesPerBlock(m_encodingbitsformat);
unsigned int uiH = 0;
unsigned int uiV = 0;
for (unsigned int uiBlock = 0; uiBlock < uiBlocks; uiBlock++)
{
m_pablock[uiBlock].InitFromEtcEncodingBits(a_format, uiH, uiV, paucEncodingBits,
a_pimageSource, a_errormetric);
paucEncodingBits += uiEncodingBitsBytesPerBlock;
uiH += 4;
if (uiH >= m_uiSourceWidth)
{
uiH = 0;
uiV += 4;
}
}
}
// ----------------------------------------------------------------------------------------------------
//
Image::~Image(void)
{
if (m_pablock != nullptr)
{
delete[] m_pablock;
m_pablock = nullptr;
}
/*if (m_paucEncodingBits != nullptr)
{
delete[] m_paucEncodingBits;
m_paucEncodingBits = nullptr;
}*/
}
// ----------------------------------------------------------------------------------------------------
// encode an image
// create a set of encoding bits that conforms to a_format
// find best fit using a_errormetric
// explore a range of possible encodings based on a_fEffort (range = [0:100])
// speed up process using a_uiJobs as the number of process threads (a_uiJobs must not excede a_uiMaxJobs)
//
Image::EncodingStatus Image::Encode(Format a_format, ErrorMetric a_errormetric, float a_fEffort, unsigned int a_uiJobs, unsigned int a_uiMaxJobs)
{
auto start = std::chrono::steady_clock::now();
m_encodingStatus = EncodingStatus::SUCCESS;
m_format = a_format;
m_errormetric = a_errormetric;
m_fEffort = a_fEffort;
if (m_errormetric < 0 || m_errormetric > ERROR_METRICS)
{
AddToEncodingStatus(ERROR_UNKNOWN_ERROR_METRIC);
return m_encodingStatus;
}
if (m_fEffort < ETCCOMP_MIN_EFFORT_LEVEL)
{
AddToEncodingStatus(WARNING_EFFORT_OUT_OF_RANGE);
m_fEffort = ETCCOMP_MIN_EFFORT_LEVEL;
}
else if (m_fEffort > ETCCOMP_MAX_EFFORT_LEVEL)
{
AddToEncodingStatus(WARNING_EFFORT_OUT_OF_RANGE);
m_fEffort = ETCCOMP_MAX_EFFORT_LEVEL;
}
if (a_uiJobs < 1)
{
a_uiJobs = 1;
AddToEncodingStatus(WARNING_JOBS_OUT_OF_RANGE);
}
else if (a_uiJobs > a_uiMaxJobs)
{
a_uiJobs = a_uiMaxJobs;
AddToEncodingStatus(WARNING_JOBS_OUT_OF_RANGE);
}
m_encodingbitsformat = DetermineEncodingBitsFormat(m_format);
if (m_encodingbitsformat == Block4x4EncodingBits::Format::UNKNOWN)
{
AddToEncodingStatus(ERROR_UNKNOWN_FORMAT);
return m_encodingStatus;
}
assert(m_paucEncodingBits == nullptr);
m_uiEncodingBitsBytes = GetNumberOfBlocks() * Block4x4EncodingBits::GetBytesPerBlock(m_encodingbitsformat);
m_paucEncodingBits = new unsigned char[m_uiEncodingBitsBytes];
InitBlocksAndBlockSorter();
std::future<void> *handle = new std::future<void>[a_uiMaxJobs];
unsigned int uiNumThreadsNeeded = 0;
unsigned int uiUnfinishedBlocks = GetNumberOfBlocks();
uiNumThreadsNeeded = (uiUnfinishedBlocks < a_uiJobs) ? uiUnfinishedBlocks : a_uiJobs;
for (int i = 0; i < (int)uiNumThreadsNeeded - 1; i++)
{
handle[i] = async(std::launch::async, &Image::RunFirstPass, this, i, uiNumThreadsNeeded);
}
RunFirstPass(uiNumThreadsNeeded - 1, uiNumThreadsNeeded);
for (int i = 0; i < (int)uiNumThreadsNeeded - 1; i++)
{
handle[i].get();
}
// perform effort-based encoding
if (m_fEffort > ETCCOMP_MIN_EFFORT_LEVEL)
{
unsigned int uiFinishedBlocks = 0;
unsigned int uiTotalEffortBlocks = static_cast<unsigned int>(roundf(0.01f * m_fEffort * GetNumberOfBlocks()));
if (m_bVerboseOutput)
{
printf("effortblocks = %d\n", uiTotalEffortBlocks);
}
unsigned int uiPass = 0;
while (1)
{
if (m_bVerboseOutput)
{
uiPass++;
printf("pass %u\n", uiPass);
}
m_psortedblocklist->Sort();
uiUnfinishedBlocks = m_psortedblocklist->GetNumberOfSortedBlocks();
uiFinishedBlocks = GetNumberOfBlocks() - uiUnfinishedBlocks;
if (m_bVerboseOutput)
{
printf(" %u unfinished blocks\n", uiUnfinishedBlocks);
// m_psortedblocklist->Print();
}
//stop enocding when we did enough to satify the effort percentage
if (uiFinishedBlocks >= uiTotalEffortBlocks)
{
if (m_bVerboseOutput)
{
printf("Finished %d Blocks out of %d\n", uiFinishedBlocks, uiTotalEffortBlocks);
}
break;
}
unsigned int uiIteratedBlocks = 0;
unsigned int blocksToIterateThisPass = (uiTotalEffortBlocks - uiFinishedBlocks);
uiNumThreadsNeeded = (uiUnfinishedBlocks < a_uiJobs) ? uiUnfinishedBlocks : a_uiJobs;
if (uiNumThreadsNeeded <= 1)
{
//since we already how many blocks each thread will process
//cap the thread limit to do the proper amount of work, and not more
uiIteratedBlocks = IterateThroughWorstBlocks(blocksToIterateThisPass, 0, 1);
}
else
{
//we have a lot of work to do, so lets multi thread it
std::future<unsigned int> *handleToBlockEncoders = new std::future<unsigned int>[uiNumThreadsNeeded-1];
for (int i = 0; i < (int)uiNumThreadsNeeded - 1; i++)
{
handleToBlockEncoders[i] = async(std::launch::async, &Image::IterateThroughWorstBlocks, this, blocksToIterateThisPass, i, uiNumThreadsNeeded);
}
uiIteratedBlocks = IterateThroughWorstBlocks(blocksToIterateThisPass, uiNumThreadsNeeded - 1, uiNumThreadsNeeded);
for (int i = 0; i < (int)uiNumThreadsNeeded - 1; i++)
{
uiIteratedBlocks += handleToBlockEncoders[i].get();
}
delete[] handleToBlockEncoders;
}
if (m_bVerboseOutput)
{
printf(" %u iterated blocks\n", uiIteratedBlocks);
}
}
}
// generate Etc2-compatible bit-format 4x4 blocks
for (int i = 0; i < (int)a_uiJobs - 1; i++)
{
handle[i] = async(std::launch::async, &Image::SetEncodingBits, this, i, a_uiJobs);
}
SetEncodingBits(a_uiJobs - 1, a_uiJobs);
for (int i = 0; i < (int)a_uiJobs - 1; i++)
{
handle[i].get();
}
auto end = std::chrono::steady_clock::now();
std::chrono::milliseconds elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
m_iEncodeTime_ms = (int)elapsed.count();
delete[] handle;
delete m_psortedblocklist;
return m_encodingStatus;
}
// ----------------------------------------------------------------------------------------------------
// iterate the encoding thru the blocks with the worst error
// stop when a_uiMaxBlocks blocks have been iterated
// split the blocks between the process threads using a_uiMultithreadingOffset and a_uiMultithreadingStride
//
unsigned int Image::IterateThroughWorstBlocks(unsigned int a_uiMaxBlocks,
unsigned int a_uiMultithreadingOffset,
unsigned int a_uiMultithreadingStride)
{
assert(a_uiMultithreadingStride > 0);
unsigned int uiIteratedBlocks = a_uiMultithreadingOffset;
SortedBlockList::Link *plink = m_psortedblocklist->GetLinkToFirstBlock();
for (plink = plink->Advance(a_uiMultithreadingOffset);
plink != nullptr;
plink = plink->Advance(a_uiMultithreadingStride) )
{
if (uiIteratedBlocks >= a_uiMaxBlocks)
{
break;
}
plink->GetBlock()->PerformEncodingIteration(m_fEffort);
uiIteratedBlocks += a_uiMultithreadingStride;
}
return uiIteratedBlocks;
}
// ----------------------------------------------------------------------------------------------------
// determine which warnings to check for during Encode() based on encoding format
//
void Image::FindEncodingWarningTypesForCurFormat()
{
TrackEncodingWarning(WARNING_ALL_TRANSPARENT_PIXELS);
TrackEncodingWarning(WARNING_SOME_RGBA_NOT_0_TO_1);
switch (m_format)
{
case Image::Format::ETC1:
case Image::Format::RGB8:
case Image::Format::SRGB8:
TrackEncodingWarning(WARNING_SOME_NON_OPAQUE_PIXELS);
TrackEncodingWarning(WARNING_SOME_TRANSLUCENT_PIXELS);
break;
case Image::Format::RGB8A1:
case Image::Format::SRGB8A1:
TrackEncodingWarning(WARNING_SOME_TRANSLUCENT_PIXELS);
TrackEncodingWarning(WARNING_ALL_OPAQUE_PIXELS);
break;
case Image::Format::RGBA8:
case Image::Format::SRGBA8:
TrackEncodingWarning(WARNING_ALL_OPAQUE_PIXELS);
break;
case Image::Format::R11:
case Image::Format::SIGNED_R11:
TrackEncodingWarning(WARNING_SOME_NON_OPAQUE_PIXELS);
TrackEncodingWarning(WARNING_SOME_TRANSLUCENT_PIXELS);
TrackEncodingWarning(WARNING_SOME_GREEN_VALUES_ARE_NOT_ZERO);
TrackEncodingWarning(WARNING_SOME_BLUE_VALUES_ARE_NOT_ZERO);
break;
case Image::Format::RG11:
case Image::Format::SIGNED_RG11:
TrackEncodingWarning(WARNING_SOME_NON_OPAQUE_PIXELS);
TrackEncodingWarning(WARNING_SOME_TRANSLUCENT_PIXELS);
TrackEncodingWarning(WARNING_SOME_BLUE_VALUES_ARE_NOT_ZERO);
break;
case Image::Format::FORMATS:
case Image::Format::UNKNOWN:
default:
assert(0);
break;
}
}
// ----------------------------------------------------------------------------------------------------
// examine source pixels to check for warnings
//
void Image::FindAndSetEncodingWarnings()
{
int numPixels = (m_uiBlockRows * 4) * (m_uiBlockColumns * 4);
if (m_iNumOpaquePixels == numPixels)
{
AddToEncodingStatusIfSignfigant(Image::EncodingStatus::WARNING_ALL_OPAQUE_PIXELS);
}
if (m_iNumOpaquePixels < numPixels)
{
AddToEncodingStatusIfSignfigant(Image::EncodingStatus::WARNING_SOME_NON_OPAQUE_PIXELS);
}
if (m_iNumTranslucentPixels > 0)
{
AddToEncodingStatusIfSignfigant(Image::EncodingStatus::WARNING_SOME_TRANSLUCENT_PIXELS);
}
if (m_iNumTransparentPixels == numPixels)
{
AddToEncodingStatusIfSignfigant(Image::EncodingStatus::WARNING_ALL_TRANSPARENT_PIXELS);
}
if (m_numColorValues.fB > 0.0f)
{
AddToEncodingStatusIfSignfigant(Image::EncodingStatus::WARNING_SOME_BLUE_VALUES_ARE_NOT_ZERO);
}
if (m_numColorValues.fG > 0.0f)
{
AddToEncodingStatusIfSignfigant(Image::EncodingStatus::WARNING_SOME_GREEN_VALUES_ARE_NOT_ZERO);
}
if (m_numOutOfRangeValues.fR > 0.0f || m_numOutOfRangeValues.fG > 0.0f)
{
AddToEncodingStatusIfSignfigant(Image::EncodingStatus::WARNING_SOME_RGBA_NOT_0_TO_1);
}
if (m_numOutOfRangeValues.fB > 0.0f || m_numOutOfRangeValues.fA > 0.0f)
{
AddToEncodingStatusIfSignfigant(Image::EncodingStatus::WARNING_SOME_RGBA_NOT_0_TO_1);
}
}
// ----------------------------------------------------------------------------------------------------
// return a string name for a given image format
//
const char * Image::EncodingFormatToString(Image::Format a_format)
{
switch (a_format)
{
case Image::Format::ETC1:
return "ETC1";
case Image::Format::RGB8:
return "RGB8";
case Image::Format::SRGB8:
return "SRGB8";
case Image::Format::RGB8A1:
return "RGB8A1";
case Image::Format::SRGB8A1:
return "SRGB8A1";
case Image::Format::RGBA8:
return "RGBA8";
case Image::Format::SRGBA8:
return "SRGBA8";
case Image::Format::R11:
return "R11";
case Image::Format::SIGNED_R11:
return "SIGNED_R11";
case Image::Format::RG11:
return "RG11";
case Image::Format::SIGNED_RG11:
return "SIGNED_RG11";
case Image::Format::FORMATS:
case Image::Format::UNKNOWN:
default:
return "UNKNOWN";
}
}
// ----------------------------------------------------------------------------------------------------
// return a string name for the image's format
//
const char * Image::EncodingFormatToString(void)
{
return EncodingFormatToString(m_format);
}
// ----------------------------------------------------------------------------------------------------
// init image blocks prior to encoding
// init block sorter for subsequent sortings
// check for encoding warnings
//
void Image::InitBlocksAndBlockSorter(void)
{
FindEncodingWarningTypesForCurFormat();
// init each block
Block4x4 *pblock = m_pablock;
unsigned char *paucEncodingBits = m_paucEncodingBits;
for (unsigned int uiBlockRow = 0; uiBlockRow < m_uiBlockRows; uiBlockRow++)
{
unsigned int uiBlockV = uiBlockRow * 4;
for (unsigned int uiBlockColumn = 0; uiBlockColumn < m_uiBlockColumns; uiBlockColumn++)
{
unsigned int uiBlockH = uiBlockColumn * 4;
pblock->InitFromSource(this, uiBlockH, uiBlockV, paucEncodingBits, m_errormetric);
paucEncodingBits += Block4x4EncodingBits::GetBytesPerBlock(m_encodingbitsformat);
pblock++;
}
}
FindAndSetEncodingWarnings();
// init block sorter
{
m_psortedblocklist = new SortedBlockList(GetNumberOfBlocks(), 100);
for (unsigned int uiBlock = 0; uiBlock < GetNumberOfBlocks(); uiBlock++)
{
pblock = &m_pablock[uiBlock];
m_psortedblocklist->AddBlock(pblock);
}
}
}
// ----------------------------------------------------------------------------------------------------
// run the first pass of the encoder
// the encoder generally finds a reasonable, fast encoding
// this is run on all blocks regardless of effort to ensure that all blocks have a valid encoding
//
void Image::RunFirstPass(unsigned int a_uiMultithreadingOffset, unsigned int a_uiMultithreadingStride)
{
assert(a_uiMultithreadingStride > 0);
for (unsigned int uiBlock = a_uiMultithreadingOffset;
uiBlock < GetNumberOfBlocks();
uiBlock += a_uiMultithreadingStride)
{
Block4x4 *pblock = &m_pablock[uiBlock];
pblock->PerformEncodingIteration(m_fEffort);
}
}
// ----------------------------------------------------------------------------------------------------
// set the encoding bits (for the output file) based on the best encoding for each block
//
void Image::SetEncodingBits(unsigned int a_uiMultithreadingOffset,
unsigned int a_uiMultithreadingStride)
{
assert(a_uiMultithreadingStride > 0);
for (unsigned int uiBlock = a_uiMultithreadingOffset;
uiBlock < GetNumberOfBlocks();
uiBlock += a_uiMultithreadingStride)
{
Block4x4 *pblock = &m_pablock[uiBlock];
pblock->SetEncodingBitsFromEncoding();
}
}
// ----------------------------------------------------------------------------------------------------
// return the image error
// image error is the sum of all block errors
//
float Image::GetError(void)
{
float fError = 0.0f;
for (unsigned int uiBlock = 0; uiBlock < GetNumberOfBlocks(); uiBlock++)
{
Block4x4 *pblock = &m_pablock[uiBlock];
fError += pblock->GetError();
}
return fError;
}
// ----------------------------------------------------------------------------------------------------
// determine the encoding bits format based on the encoding format
// the encoding bits format is a family of bit encodings that are shared across various encoding formats
//
Block4x4EncodingBits::Format Image::DetermineEncodingBitsFormat(Format a_format)
{
Block4x4EncodingBits::Format encodingbitsformat;
// determine encoding bits format from image format
switch (a_format)
{
case Format::ETC1:
case Format::RGB8:
case Format::SRGB8:
encodingbitsformat = Block4x4EncodingBits::Format::RGB8;
break;
case Format::RGBA8:
case Format::SRGBA8:
encodingbitsformat = Block4x4EncodingBits::Format::RGBA8;
break;
case Format::R11:
case Format::SIGNED_R11:
encodingbitsformat = Block4x4EncodingBits::Format::R11;
break;
case Format::RG11:
case Format::SIGNED_RG11:
encodingbitsformat = Block4x4EncodingBits::Format::RG11;
break;
case Format::RGB8A1:
case Format::SRGB8A1:
encodingbitsformat = Block4x4EncodingBits::Format::RGB8A1;
break;
default:
encodingbitsformat = Block4x4EncodingBits::Format::UNKNOWN;
break;
}
return encodingbitsformat;
}
// ----------------------------------------------------------------------------------------------------
//
} // namespace Etc

249
extern/EtcLib/Etc/EtcImage.h vendored Normal file
View File

@ -0,0 +1,249 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
#pragma once
//#include "Etc.h"
#include "EtcColorFloatRGBA.h"
#include "EtcBlock4x4EncodingBits.h"
#include "EtcErrorMetric.h"
namespace Etc
{
class Block4x4;
class EncoderSpec;
class SortedBlockList;
class Image
{
public:
//the differnt warning and errors that can come up during encoding
enum EncodingStatus
{
SUCCESS = 0,
//
WARNING_THRESHOLD = 1 << 0,
//
WARNING_EFFORT_OUT_OF_RANGE = 1 << 1,
WARNING_JOBS_OUT_OF_RANGE = 1 << 2,
WARNING_SOME_NON_OPAQUE_PIXELS = 1 << 3,//just for opaque formats, etc1, rgb8, r11, rg11
WARNING_ALL_OPAQUE_PIXELS = 1 << 4,
WARNING_ALL_TRANSPARENT_PIXELS = 1 << 5,
WARNING_SOME_TRANSLUCENT_PIXELS = 1 << 6,//just for rgb8A1
WARNING_SOME_RGBA_NOT_0_TO_1 = 1 << 7,
WARNING_SOME_BLUE_VALUES_ARE_NOT_ZERO = 1 << 8,
WARNING_SOME_GREEN_VALUES_ARE_NOT_ZERO = 1 << 9,
//
ERROR_THRESHOLD = 1 << 16,
//
ERROR_UNKNOWN_FORMAT = 1 << 17,
ERROR_UNKNOWN_ERROR_METRIC = 1 << 18,
ERROR_ZERO_WIDTH_OR_HEIGHT = 1 << 19,
//
};
enum class Format
{
UNKNOWN,
//
ETC1,
//
// ETC2 formats
RGB8,
SRGB8,
RGBA8,
SRGBA8,
R11,
SIGNED_R11,
RG11,
SIGNED_RG11,
RGB8A1,
SRGB8A1,
//
FORMATS,
//
DEFAULT = SRGB8
};
// constructor using source image
Image(float *a_pafSourceRGBA, unsigned int a_uiSourceWidth,
unsigned int a_uiSourceHeight,
ErrorMetric a_errormetric);
// constructor using encoding bits
Image(Format a_format,
unsigned int a_uiSourceWidth, unsigned int a_uiSourceHeight,
unsigned char *a_paucEncidingBits, unsigned int a_uiEncodingBitsBytes,
Image *a_pimageSource,
ErrorMetric a_errormetric);
~Image(void);
EncodingStatus Encode(Format a_format, ErrorMetric a_errormetric, float a_fEffort,
unsigned int a_uiJobs, unsigned int a_uiMaxJobs);
inline void AddToEncodingStatus(EncodingStatus a_encStatus)
{
m_encodingStatus = (EncodingStatus)((unsigned int)m_encodingStatus | (unsigned int)a_encStatus);
}
inline unsigned int GetSourceWidth(void)
{
return m_uiSourceWidth;
}
inline unsigned int GetSourceHeight(void)
{
return m_uiSourceHeight;
}
inline unsigned int GetExtendedWidth(void)
{
return m_uiExtendedWidth;
}
inline unsigned int GetExtendedHeight(void)
{
return m_uiExtendedHeight;
}
inline unsigned int GetNumberOfBlocks()
{
return m_uiBlockColumns * m_uiBlockRows;
}
inline Block4x4 * GetBlocks()
{
return m_pablock;
}
inline unsigned char * GetEncodingBits(void)
{
return m_paucEncodingBits;
}
inline unsigned int GetEncodingBitsBytes(void)
{
return m_uiEncodingBitsBytes;
}
inline int GetEncodingTimeMs(void)
{
return m_iEncodeTime_ms;
}
float GetError(void);
inline ColorFloatRGBA * GetSourcePixel(unsigned int a_uiH, unsigned int a_uiV)
{
if (a_uiH >= m_uiSourceWidth || a_uiV >= m_uiSourceHeight)
{
return nullptr;
}
return &m_pafrgbaSource[a_uiV*m_uiSourceWidth + a_uiH];
}
inline Format GetFormat(void)
{
return m_format;
}
static Block4x4EncodingBits::Format DetermineEncodingBitsFormat(Format a_format);
inline static unsigned short CalcExtendedDimension(unsigned short a_ushOriginalDimension)
{
return (unsigned short)((a_ushOriginalDimension + 3) & ~3);
}
inline ErrorMetric GetErrorMetric(void)
{
return m_errormetric;
}
static const char * EncodingFormatToString(Image::Format a_format);
const char * EncodingFormatToString(void);
//used to get basic information about the image data
int m_iNumOpaquePixels;
int m_iNumTranslucentPixels;
int m_iNumTransparentPixels;
ColorFloatRGBA m_numColorValues;
ColorFloatRGBA m_numOutOfRangeValues;
bool m_bVerboseOutput;
private:
//add a warning or error to check for while encoding
inline void TrackEncodingWarning(EncodingStatus a_encStatus)
{
m_warningsToCapture = (EncodingStatus)((unsigned int)m_warningsToCapture | (unsigned int)a_encStatus);
}
//report the warning if it is something we care about for this encoding
inline void AddToEncodingStatusIfSignfigant(EncodingStatus a_encStatus)
{
if ((EncodingStatus)((unsigned int)m_warningsToCapture & (unsigned int)a_encStatus) == a_encStatus)
{
AddToEncodingStatus(a_encStatus);
}
}
Image(void);
void FindEncodingWarningTypesForCurFormat();
void FindAndSetEncodingWarnings();
void InitBlocksAndBlockSorter(void);
void RunFirstPass(unsigned int a_uiMultithreadingOffset,
unsigned int a_uiMultithreadingStride);
void SetEncodingBits(unsigned int a_uiMultithreadingOffset,
unsigned int a_uiMultithreadingStride);
unsigned int IterateThroughWorstBlocks(unsigned int a_uiMaxBlocks,
unsigned int a_uiMultithreadingOffset,
unsigned int a_uiMultithreadingStride);
// inputs
ColorFloatRGBA *m_pafrgbaSource;
unsigned int m_uiSourceWidth;
unsigned int m_uiSourceHeight;
unsigned int m_uiExtendedWidth;
unsigned int m_uiExtendedHeight;
unsigned int m_uiBlockColumns;
unsigned int m_uiBlockRows;
// intermediate data
Block4x4 *m_pablock;
// encoding
Format m_format;
Block4x4EncodingBits::Format m_encodingbitsformat;
unsigned int m_uiEncodingBitsBytes; // for entire image
unsigned char *m_paucEncodingBits;
ErrorMetric m_errormetric;
float m_fEffort;
// stats
int m_iEncodeTime_ms;
SortedBlockList *m_psortedblocklist;
//this will hold any warning or errors that happen during encoding
EncodingStatus m_encodingStatus;
//these will be the warnings we are tracking
EncodingStatus m_warningsToCapture;
};
} // namespace Etc

64
extern/EtcLib/Etc/EtcMath.cpp vendored Normal file
View File

@ -0,0 +1,64 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
#include "EtcConfig.h"
#include "EtcMath.h"
namespace Etc
{
// ----------------------------------------------------------------------------------------------------
// calculate the line that best fits the set of XY points contained in a_afX[] and a_afY[]
// use a_fSlope and a_fOffset to define that line
//
bool Regression(float a_afX[], float a_afY[], unsigned int a_Points,
float *a_fSlope, float *a_fOffset)
{
float fPoints = (float)a_Points;
float fSumX = 0.0f;
float fSumY = 0.0f;
float fSumXY = 0.0f;
float fSumX2 = 0.0f;
for (unsigned int uiPoint = 0; uiPoint < a_Points; uiPoint++)
{
fSumX += a_afX[uiPoint];
fSumY += a_afY[uiPoint];
fSumXY += a_afX[uiPoint] * a_afY[uiPoint];
fSumX2 += a_afX[uiPoint] * a_afX[uiPoint];
}
float fDivisor = fPoints*fSumX2 - fSumX*fSumX;
// if vertical line
if (fDivisor == 0.0f)
{
*a_fSlope = 0.0f;
*a_fOffset = 0.0f;
return true;
}
*a_fSlope = (fPoints*fSumXY - fSumX*fSumY) / fDivisor;
*a_fOffset = (fSumY - (*a_fSlope)*fSumX) / fPoints;
return false;
}
// ----------------------------------------------------------------------------------------------------
//
} // namespace Etc

40
extern/EtcLib/Etc/EtcMath.h vendored Normal file
View File

@ -0,0 +1,40 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
#pragma once
#include <math.h>
namespace Etc
{
// ----------------------------------------------------------------------------------------------------
// return true if vertical line
bool Regression(float a_afX[], float a_afY[], unsigned int a_Points,
float *a_fSlope, float *a_fOffset);
inline float ConvertMSEToPSNR(float a_fMSE)
{
if (a_fMSE == 0.0f)
{
return INFINITY;
}
return 10.0f * log10f(1.0f / a_fMSE);
}
}

417
extern/EtcLib/EtcCodec/EtcBlock4x4.cpp vendored Normal file
View File

@ -0,0 +1,417 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
/*
EtcBlock4x4.cpp
Implements the state associated with each 4x4 block of pixels in an image
Source images that are not a multiple of 4x4 are extended to fill the Block4x4 using pixels with an
alpha of NAN
*/
#include "EtcConfig.h"
#include "EtcBlock4x4.h"
#include "EtcBlock4x4EncodingBits.h"
#include "EtcColor.h"
#include "EtcImage.h"
#include "EtcColorFloatRGBA.h"
#include "EtcBlock4x4Encoding_RGB8.h"
#include "EtcBlock4x4Encoding_RGBA8.h"
#include "EtcBlock4x4Encoding_RGB8A1.h"
#include "EtcBlock4x4Encoding_R11.h"
#include "EtcBlock4x4Encoding_RG11.h"
#include <stdio.h>
#include <string.h>
#include <assert.h>
namespace Etc
{
// ETC pixels are scanned vertically.
// this mapping is for when someone wants to scan the ETC pixels horizontally
const unsigned int Block4x4::s_auiPixelOrderHScan[PIXELS] = { 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15 };
// ----------------------------------------------------------------------------------------------------
//
Block4x4::Block4x4(void)
{
m_pimageSource = nullptr;
m_uiSourceH = 0;
m_uiSourceV = 0;
m_sourcealphamix = SourceAlphaMix::UNKNOWN;
m_boolBorderPixels = false;
m_boolPunchThroughPixels = false;
m_pencoding = nullptr;
m_errormetric = ErrorMetric::NUMERIC;
}
Block4x4::~Block4x4()
{
m_pimageSource = nullptr;
if (m_pencoding)
{
delete m_pencoding;
m_pencoding = nullptr;
}
}
// ----------------------------------------------------------------------------------------------------
// initialization prior to encoding from a source image
// [a_uiSourceH,a_uiSourceV] is the location of the block in a_pimageSource
// a_paucEncodingBits is the place to store the final encoding
// a_errormetric is used for finding the best encoding
//
void Block4x4::InitFromSource(Image *a_pimageSource,
unsigned int a_uiSourceH, unsigned int a_uiSourceV,
unsigned char *a_paucEncodingBits,
ErrorMetric a_errormetric)
{
Block4x4();
m_pimageSource = a_pimageSource;
m_uiSourceH = a_uiSourceH;
m_uiSourceV = a_uiSourceV;
m_errormetric = a_errormetric;
SetSourcePixels();
// set block encoder function
switch (m_pimageSource->GetFormat())
{
case Image::Format::ETC1:
m_pencoding = new Block4x4Encoding_ETC1;
break;
case Image::Format::RGB8:
case Image::Format::SRGB8:
m_pencoding = new Block4x4Encoding_RGB8;
break;
case Image::Format::RGBA8:
case Image::Format::SRGBA8:
switch (m_sourcealphamix)
{
case SourceAlphaMix::OPAQUE:
m_pencoding = new Block4x4Encoding_RGBA8_Opaque;
break;
case SourceAlphaMix::TRANSPARENT:
m_pencoding = new Block4x4Encoding_RGBA8_Transparent;
break;
case SourceAlphaMix::TRANSLUCENT:
m_pencoding = new Block4x4Encoding_RGBA8;
break;
default:
assert(0);
break;
}
break;
case Image::Format::RGB8A1:
case Image::Format::SRGB8A1:
switch (m_sourcealphamix)
{
case SourceAlphaMix::OPAQUE:
m_pencoding = new Block4x4Encoding_RGB8A1_Opaque;
break;
case SourceAlphaMix::TRANSPARENT:
m_pencoding = new Block4x4Encoding_RGB8A1_Transparent;
break;
case SourceAlphaMix::TRANSLUCENT:
if (m_boolPunchThroughPixels)
{
m_pencoding = new Block4x4Encoding_RGB8A1;
}
else
{
m_pencoding = new Block4x4Encoding_RGB8A1_Opaque;
}
break;
default:
assert(0);
break;
}
break;
case Image::Format::R11:
case Image::Format::SIGNED_R11:
m_pencoding = new Block4x4Encoding_R11;
break;
case Image::Format::RG11:
case Image::Format::SIGNED_RG11:
m_pencoding = new Block4x4Encoding_RG11;
break;
default:
assert(0);
break;
}
m_pencoding->InitFromSource(this, m_afrgbaSource,
a_paucEncodingBits, a_errormetric);
}
// ----------------------------------------------------------------------------------------------------
// initialization of encoding state from a prior encoding using encoding bits
// [a_uiSourceH,a_uiSourceV] is the location of the block in a_pimageSource
// a_paucEncodingBits is the place to read the prior encoding
// a_imageformat is used to determine how to interpret a_paucEncodingBits
// a_errormetric was used for the prior encoding
//
void Block4x4::InitFromEtcEncodingBits(Image::Format a_imageformat,
unsigned int a_uiSourceH, unsigned int a_uiSourceV,
unsigned char *a_paucEncodingBits,
Image *a_pimageSource,
ErrorMetric a_errormetric)
{
Block4x4();
m_pimageSource = a_pimageSource;
m_uiSourceH = a_uiSourceH;
m_uiSourceV = a_uiSourceV;
m_errormetric = a_errormetric;
SetSourcePixels();
// set block encoder function
switch (a_imageformat)
{
case Image::Format::ETC1:
m_pencoding = new Block4x4Encoding_ETC1;
break;
case Image::Format::RGB8:
case Image::Format::SRGB8:
m_pencoding = new Block4x4Encoding_RGB8;
break;
case Image::Format::RGBA8:
case Image::Format::SRGBA8:
m_pencoding = new Block4x4Encoding_RGBA8;
break;
case Image::Format::RGB8A1:
case Image::Format::SRGB8A1:
m_pencoding = new Block4x4Encoding_RGB8A1;
break;
case Image::Format::R11:
case Image::Format::SIGNED_R11:
m_pencoding = new Block4x4Encoding_R11;
break;
case Image::Format::RG11:
case Image::Format::SIGNED_RG11:
m_pencoding = new Block4x4Encoding_RG11;
break;
default:
assert(0);
break;
}
m_pencoding->InitFromEncodingBits(this, a_paucEncodingBits, m_afrgbaSource,
m_pimageSource->GetErrorMetric());
}
// ----------------------------------------------------------------------------------------------------
// set source pixels from m_pimageSource
// set m_alphamix
//
void Block4x4::SetSourcePixels(void)
{
Image::Format imageformat = m_pimageSource->GetFormat();
// alpha census
unsigned int uiTransparentSourcePixels = 0;
unsigned int uiOpaqueSourcePixels = 0;
// copy source to consecutive memory locations
// convert from image horizontal scan to block vertical scan
unsigned int uiPixel = 0;
for (unsigned int uiBlockPixelH = 0; uiBlockPixelH < Block4x4::COLUMNS; uiBlockPixelH++)
{
unsigned int uiSourcePixelH = m_uiSourceH + uiBlockPixelH;
for (unsigned int uiBlockPixelV = 0; uiBlockPixelV < Block4x4::ROWS; uiBlockPixelV++)
{
unsigned int uiSourcePixelV = m_uiSourceV + uiBlockPixelV;
ColorFloatRGBA *pfrgbaSource = m_pimageSource->GetSourcePixel(uiSourcePixelH, uiSourcePixelV);
// if pixel extends beyond source image because of block padding
if (pfrgbaSource == nullptr)
{
m_afrgbaSource[uiPixel] = ColorFloatRGBA(0.0f, 0.0f, 0.0f, NAN); // denotes border pixel
m_boolBorderPixels = true;
uiTransparentSourcePixels++;
}
else
{
//get teh current pixel data, and store some of the attributes
//before capping values to fit the encoder type
m_afrgbaSource[uiPixel] = (*pfrgbaSource).ClampRGBA();
if (m_afrgbaSource[uiPixel].fA == 1.0f)
{
m_pimageSource->m_iNumOpaquePixels++;
}
else if (m_afrgbaSource[uiPixel].fA == 0.0f)
{
m_pimageSource->m_iNumTransparentPixels++;
}
else if(m_afrgbaSource[uiPixel].fA > 0.0f && m_afrgbaSource[uiPixel].fA < 1.0f)
{
m_pimageSource->m_iNumTranslucentPixels++;
}
else
{
m_pimageSource->m_numOutOfRangeValues.fA++;
}
if (m_afrgbaSource[uiPixel].fR != 0.0f)
{
m_pimageSource->m_numColorValues.fR++;
//make sure we are getting a float between 0-1
if (m_afrgbaSource[uiPixel].fR - 1.0f > 0.0f)
{
m_pimageSource->m_numOutOfRangeValues.fR++;
}
}
if (m_afrgbaSource[uiPixel].fG != 0.0f)
{
m_pimageSource->m_numColorValues.fG++;
if (m_afrgbaSource[uiPixel].fG - 1.0f > 0.0f)
{
m_pimageSource->m_numOutOfRangeValues.fG++;
}
}
if (m_afrgbaSource[uiPixel].fB != 0.0f)
{
m_pimageSource->m_numColorValues.fB++;
if (m_afrgbaSource[uiPixel].fB - 1.0f > 0.0f)
{
m_pimageSource->m_numOutOfRangeValues.fB++;
}
}
// for formats with no alpha, set source alpha to 1
if (imageformat == Image::Format::ETC1 ||
imageformat == Image::Format::RGB8 ||
imageformat == Image::Format::SRGB8)
{
m_afrgbaSource[uiPixel].fA = 1.0f;
}
if (imageformat == Image::Format::R11 ||
imageformat == Image::Format::SIGNED_R11)
{
m_afrgbaSource[uiPixel].fA = 1.0f;
m_afrgbaSource[uiPixel].fG = 0.0f;
m_afrgbaSource[uiPixel].fB = 0.0f;
}
if (imageformat == Image::Format::RG11 ||
imageformat == Image::Format::SIGNED_RG11)
{
m_afrgbaSource[uiPixel].fA = 1.0f;
m_afrgbaSource[uiPixel].fB = 0.0f;
}
// for RGB8A1, set source alpha to 0.0 or 1.0
// set punch through flag
if (imageformat == Image::Format::RGB8A1 ||
imageformat == Image::Format::SRGB8A1)
{
if (m_afrgbaSource[uiPixel].fA >= 0.5f)
{
m_afrgbaSource[uiPixel].fA = 1.0f;
}
else
{
m_afrgbaSource[uiPixel].fA = 0.0f;
m_boolPunchThroughPixels = true;
}
}
if (m_afrgbaSource[uiPixel].fA == 1.0f)
{
uiOpaqueSourcePixels++;
}
else if (m_afrgbaSource[uiPixel].fA == 0.0f)
{
uiTransparentSourcePixels++;
}
}
uiPixel += 1;
}
}
if (uiOpaqueSourcePixels == PIXELS)
{
m_sourcealphamix = SourceAlphaMix::OPAQUE;
}
else if (uiTransparentSourcePixels == PIXELS)
{
m_sourcealphamix = SourceAlphaMix::TRANSPARENT;
}
else
{
m_sourcealphamix = SourceAlphaMix::TRANSLUCENT;
}
}
// ----------------------------------------------------------------------------------------------------
// return a name for the encoding mode
//
const char * Block4x4::GetEncodingModeName(void)
{
switch (m_pencoding->GetMode())
{
case Block4x4Encoding::MODE_ETC1:
return "ETC1";
case Block4x4Encoding::MODE_T:
return "T";
case Block4x4Encoding::MODE_H:
return "H";
case Block4x4Encoding::MODE_PLANAR:
return "PLANAR";
default:
return "???";
}
}
// ----------------------------------------------------------------------------------------------------
//
}

172
extern/EtcLib/EtcCodec/EtcBlock4x4.h vendored Normal file
View File

@ -0,0 +1,172 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
#pragma once
#include "EtcColor.h"
#include "EtcColorFloatRGBA.h"
#include "EtcErrorMetric.h"
#include "EtcImage.h"
#include "EtcBlock4x4Encoding.h"
namespace Etc
{
class Block4x4EncodingBits;
class Block4x4
{
public:
static const unsigned int ROWS = 4;
static const unsigned int COLUMNS = 4;
static const unsigned int PIXELS = ROWS * COLUMNS;
// the alpha mix for a 4x4 block of pixels
enum class SourceAlphaMix
{
UNKNOWN,
//
OPAQUE, // all 1.0
TRANSPARENT, // all 0.0 or NAN
TRANSLUCENT // not all opaque or transparent
};
typedef void (Block4x4::*EncoderFunctionPtr)(void);
Block4x4(void);
~Block4x4();
void InitFromSource(Image *a_pimageSource,
unsigned int a_uiSourceH,
unsigned int a_uiSourceV,
unsigned char *a_paucEncodingBits,
ErrorMetric a_errormetric);
void InitFromEtcEncodingBits(Image::Format a_imageformat,
unsigned int a_uiSourceH,
unsigned int a_uiSourceV,
unsigned char *a_paucEncodingBits,
Image *a_pimageSource,
ErrorMetric a_errormetric);
// return true if final iteration was performed
inline void PerformEncodingIteration(float a_fEffort)
{
m_pencoding->PerformIteration(a_fEffort);
}
inline void SetEncodingBitsFromEncoding(void)
{
m_pencoding->SetEncodingBits();
}
inline unsigned int GetSourceH(void)
{
return m_uiSourceH;
}
inline unsigned int GetSourceV(void)
{
return m_uiSourceV;
}
inline float GetError(void)
{
return m_pencoding->GetError();
}
static const unsigned int s_auiPixelOrderHScan[PIXELS];
inline ColorFloatRGBA * GetDecodedColors(void)
{
return m_pencoding->GetDecodedColors();
}
inline float * GetDecodedAlphas(void)
{
return m_pencoding->GetDecodedAlphas();
}
inline Block4x4Encoding::Mode GetEncodingMode(void)
{
return m_pencoding->GetMode();
}
inline bool GetFlip(void)
{
return m_pencoding->GetFlip();
}
inline bool IsDifferential(void)
{
return m_pencoding->IsDifferential();
}
inline ColorFloatRGBA * GetSource()
{
return m_afrgbaSource;
}
inline ErrorMetric GetErrorMetric()
{
return m_errormetric;
}
const char * GetEncodingModeName(void);
inline Block4x4Encoding * GetEncoding(void)
{
return m_pencoding;
}
inline SourceAlphaMix GetSourceAlphaMix(void)
{
return m_sourcealphamix;
}
inline Image * GetImageSource(void)
{
return m_pimageSource;
}
inline bool HasBorderPixels(void)
{
return m_boolBorderPixels;
}
inline bool HasPunchThroughPixels(void)
{
return m_boolPunchThroughPixels;
}
private:
void SetSourcePixels(void);
Image *m_pimageSource;
unsigned int m_uiSourceH;
unsigned int m_uiSourceV;
ErrorMetric m_errormetric;
ColorFloatRGBA m_afrgbaSource[PIXELS]; // vertical scan
SourceAlphaMix m_sourcealphamix;
bool m_boolBorderPixels; // marked as rgba(NAN, NAN, NAN, NAN)
bool m_boolPunchThroughPixels; // RGB8A1 or SRGB8A1 with any pixels with alpha < 0.5
Block4x4Encoding *m_pencoding;
};
} // namespace Etc

View File

@ -0,0 +1,250 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
/*
EtcBlock4x4Encoding.cpp
Block4x4Encoding is the abstract base class for the different encoders. Each encoder targets a
particular file format (e.g. ETC1, RGB8, RGBA8, R11)
*/
#include "EtcConfig.h"
#include "EtcBlock4x4Encoding.h"
#include "EtcBlock4x4EncodingBits.h"
#include "EtcBlock4x4.h"
#include <stdio.h>
#include <string.h>
#include <assert.h>
namespace Etc
{
// ----------------------------------------------------------------------------------------------------
//
const float Block4x4Encoding::LUMA_WEIGHT = 3.0f;
const float Block4x4Encoding::CHROMA_BLUE_WEIGHT = 0.5f;
// ----------------------------------------------------------------------------------------------------
//
Block4x4Encoding::Block4x4Encoding(void)
{
m_pblockParent = nullptr;
m_pafrgbaSource = nullptr;
m_boolBorderPixels = false;
m_fError = -1.0f;
m_mode = MODE_UNKNOWN;
m_uiEncodingIterations = 0;
m_boolDone = false;
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
m_afrgbaDecodedColors[uiPixel] = ColorFloatRGBA(-1.0f, -1.0f, -1.0f, -1.0f);
m_afDecodedAlphas[uiPixel] = -1.0f;
}
}
// ----------------------------------------------------------------------------------------------------
// initialize the generic encoding for a 4x4 block
// a_pblockParent points to the block associated with this encoding
// a_errormetric is used to choose the best encoding
// init the decoded pixels to -1 to mark them as undefined
// init the error to -1 to mark it as undefined
//
void Block4x4Encoding::Init(Block4x4 *a_pblockParent,
ColorFloatRGBA *a_pafrgbaSource,
ErrorMetric a_errormetric)
{
m_pblockParent = a_pblockParent;
m_pafrgbaSource = a_pafrgbaSource;
m_boolBorderPixels = m_pblockParent->HasBorderPixels();
m_fError = -1.0f;
m_uiEncodingIterations = 0;
m_errormetric = a_errormetric;
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
m_afrgbaDecodedColors[uiPixel] = ColorFloatRGBA(-1.0f, -1.0f, -1.0f, -1.0f);
m_afDecodedAlphas[uiPixel] = -1.0f;
}
}
// ----------------------------------------------------------------------------------------------------
// calculate the error for the block by summing the pixel errors
//
void Block4x4Encoding::CalcBlockError(void)
{
m_fError = 0.0f;
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
m_fError += CalcPixelError(m_afrgbaDecodedColors[uiPixel], m_afDecodedAlphas[uiPixel],
m_pafrgbaSource[uiPixel]);
}
}
// ----------------------------------------------------------------------------------------------------
// calculate the error between the source pixel and the decoded pixel
// the error amount is base on the error metric
//
float Block4x4Encoding::CalcPixelError(ColorFloatRGBA a_frgbaDecodedColor, float a_fDecodedAlpha,
ColorFloatRGBA a_frgbaSourcePixel)
{
// if a border pixel
if (isnan(a_frgbaSourcePixel.fA))
{
return 0.0f;
}
if (m_errormetric == ErrorMetric::RGBA)
{
assert(a_fDecodedAlpha >= 0.0f);
float fDRed = (a_fDecodedAlpha * a_frgbaDecodedColor.fR) -
(a_frgbaSourcePixel.fA * a_frgbaSourcePixel.fR);
float fDGreen = (a_fDecodedAlpha * a_frgbaDecodedColor.fG) -
(a_frgbaSourcePixel.fA * a_frgbaSourcePixel.fG);
float fDBlue = (a_fDecodedAlpha * a_frgbaDecodedColor.fB) -
(a_frgbaSourcePixel.fA * a_frgbaSourcePixel.fB);
float fDAlpha = a_fDecodedAlpha - a_frgbaSourcePixel.fA;
return fDRed*fDRed + fDGreen*fDGreen + fDBlue*fDBlue + fDAlpha*fDAlpha;
}
else if (m_errormetric == ErrorMetric::REC709)
{
assert(a_fDecodedAlpha >= 0.0f);
float fLuma1 = a_frgbaSourcePixel.fR*0.2126f + a_frgbaSourcePixel.fG*0.7152f + a_frgbaSourcePixel.fB*0.0722f;
float fChromaR1 = 0.5f * ((a_frgbaSourcePixel.fR - fLuma1) * (1.0f / (1.0f - 0.2126f)));
float fChromaB1 = 0.5f * ((a_frgbaSourcePixel.fB - fLuma1) * (1.0f / (1.0f - 0.0722f)));
float fLuma2 = a_frgbaDecodedColor.fR*0.2126f +
a_frgbaDecodedColor.fG*0.7152f +
a_frgbaDecodedColor.fB*0.0722f;
float fChromaR2 = 0.5f * ((a_frgbaDecodedColor.fR - fLuma2) * (1.0f / (1.0f - 0.2126f)));
float fChromaB2 = 0.5f * ((a_frgbaDecodedColor.fB - fLuma2) * (1.0f / (1.0f - 0.0722f)));
float fDeltaL = a_frgbaSourcePixel.fA * fLuma1 - a_fDecodedAlpha * fLuma2;
float fDeltaCr = a_frgbaSourcePixel.fA * fChromaR1 - a_fDecodedAlpha * fChromaR2;
float fDeltaCb = a_frgbaSourcePixel.fA * fChromaB1 - a_fDecodedAlpha * fChromaB2;
float fDAlpha = a_fDecodedAlpha - a_frgbaSourcePixel.fA;
// Favor Luma accuracy over Chroma, and Red over Blue
return LUMA_WEIGHT*fDeltaL*fDeltaL +
fDeltaCr*fDeltaCr +
CHROMA_BLUE_WEIGHT*fDeltaCb*fDeltaCb +
fDAlpha*fDAlpha;
#if 0
float fDRed = a_frgbaDecodedPixel.fR - a_frgbaSourcePixel.fR;
float fDGreen = a_frgbaDecodedPixel.fG - a_frgbaSourcePixel.fG;
float fDBlue = a_frgbaDecodedPixel.fB - a_frgbaSourcePixel.fB;
return 2.0f * 3.0f * fDeltaL * fDeltaL + fDRed*fDRed + fDGreen*fDGreen + fDBlue*fDBlue;
#endif
}
else if (m_errormetric == ErrorMetric::NORMALXYZ)
{
float fDecodedX = 2.0f * a_frgbaDecodedColor.fR - 1.0f;
float fDecodedY = 2.0f * a_frgbaDecodedColor.fG - 1.0f;
float fDecodedZ = 2.0f * a_frgbaDecodedColor.fB - 1.0f;
float fDecodedLength = sqrtf(fDecodedX*fDecodedX + fDecodedY*fDecodedY + fDecodedZ*fDecodedZ);
if (fDecodedLength < 0.5f)
{
return 1.0f;
}
else if (fDecodedLength == 0.0f)
{
fDecodedX = 1.0f;
fDecodedY = 0.0f;
fDecodedZ = 0.0f;
}
else
{
fDecodedX /= fDecodedLength;
fDecodedY /= fDecodedLength;
fDecodedZ /= fDecodedLength;
}
float fSourceX = 2.0f * a_frgbaSourcePixel.fR - 1.0f;
float fSourceY = 2.0f * a_frgbaSourcePixel.fG - 1.0f;
float fSourceZ = 2.0f * a_frgbaSourcePixel.fB - 1.0f;
float fSourceLength = sqrtf(fSourceX*fSourceX + fSourceY*fSourceY + fSourceZ*fSourceZ);
if (fSourceLength == 0.0f)
{
fSourceX = 1.0f;
fSourceY = 0.0f;
fSourceZ = 0.0f;
}
else
{
fSourceX /= fSourceLength;
fSourceY /= fSourceLength;
fSourceZ /= fSourceLength;
}
float fDotProduct = fSourceX*fDecodedX + fSourceY*fDecodedY + fSourceZ*fDecodedZ;
float fNormalizedDotProduct = 1.0f - 0.5f * (fDotProduct + 1.0f);
float fDotProductError = fNormalizedDotProduct * fNormalizedDotProduct;
float fLength2 = fDecodedX*fDecodedX + fDecodedY*fDecodedY + fDecodedZ*fDecodedZ;
float fLength2Error = fabsf(1.0f - fLength2);
float fDeltaW = a_frgbaDecodedColor.fA - a_frgbaSourcePixel.fA;
float fErrorW = fDeltaW * fDeltaW;
return fDotProductError + fLength2Error + fErrorW;
}
else // ErrorMetric::NUMERIC
{
assert(a_fDecodedAlpha >= 0.0f);
float fDX = a_frgbaDecodedColor.fR - a_frgbaSourcePixel.fR;
float fDY = a_frgbaDecodedColor.fG - a_frgbaSourcePixel.fG;
float fDZ = a_frgbaDecodedColor.fB - a_frgbaSourcePixel.fB;
float fDW = a_frgbaDecodedColor.fA - a_frgbaSourcePixel.fA;
return fDX*fDX + fDY*fDY + fDZ*fDZ + fDW*fDW;
}
}
// ----------------------------------------------------------------------------------------------------
//
} // namespace Etc

View File

@ -0,0 +1,148 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
#pragma once
#include "EtcColorFloatRGBA.h"
#include "EtcErrorMetric.h"
#include <assert.h>
#include <float.h>
namespace Etc
{
class Block4x4;
// abstract base class for specific encodings
class Block4x4Encoding
{
public:
static const unsigned int ROWS = 4;
static const unsigned int COLUMNS = 4;
static const unsigned int PIXELS = ROWS * COLUMNS;
static const float LUMA_WEIGHT;
static const float CHROMA_BLUE_WEIGHT;
typedef enum
{
MODE_UNKNOWN,
//
MODE_ETC1,
MODE_T,
MODE_H,
MODE_PLANAR,
MODE_R11,
MODE_RG11,
//
MODES
} Mode;
Block4x4Encoding(void);
//virtual ~Block4x4Encoding(void) =0;
virtual ~Block4x4Encoding(void) {}
virtual void InitFromSource(Block4x4 *a_pblockParent,
ColorFloatRGBA *a_pafrgbaSource,
unsigned char *a_paucEncodingBits, ErrorMetric a_errormetric) = 0;
virtual void InitFromEncodingBits(Block4x4 *a_pblockParent,
unsigned char *a_paucEncodingBits,
ColorFloatRGBA *a_pafrgbaSource,
ErrorMetric a_errormetric) = 0;
// perform an iteration of the encoding
// the first iteration must generate a complete, valid (if poor) encoding
virtual void PerformIteration(float a_fEffort) = 0;
void CalcBlockError(void);
inline float GetError(void)
{
assert(m_fError >= 0.0f);
return m_fError;
}
inline ColorFloatRGBA * GetDecodedColors(void)
{
return m_afrgbaDecodedColors;
}
inline float * GetDecodedAlphas(void)
{
return m_afDecodedAlphas;
}
virtual void SetEncodingBits(void) = 0;
virtual bool GetFlip(void) = 0;
virtual bool IsDifferential(void) = 0;
virtual bool HasSeverelyBentDifferentialColors(void) const = 0;
inline Mode GetMode(void)
{
return m_mode;
}
inline bool IsDone(void)
{
return m_boolDone;
}
inline void SetDoneIfPerfect()
{
if (GetError() == 0.0f)
{
m_boolDone = true;
}
}
float CalcPixelError(ColorFloatRGBA a_frgbaDecodedColor, float a_fDecodedAlpha,
ColorFloatRGBA a_frgbaSourcePixel);
protected:
void Init(Block4x4 *a_pblockParent,
ColorFloatRGBA *a_pafrgbaSource,
ErrorMetric a_errormetric);
Block4x4 *m_pblockParent;
ColorFloatRGBA *m_pafrgbaSource;
bool m_boolBorderPixels; // if block has any border pixels
ColorFloatRGBA m_afrgbaDecodedColors[PIXELS]; // decoded RGB components, ignore Alpha
float m_afDecodedAlphas[PIXELS]; // decoded alpha component
float m_fError; // error for RGBA relative to m_pafrgbaSource
// intermediate encoding
Mode m_mode;
unsigned int m_uiEncodingIterations;
bool m_boolDone; // all iterations have been done
ErrorMetric m_errormetric;
private:
};
} // namespace Etc

View File

@ -0,0 +1,315 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
#pragma once
#include <assert.h>
namespace Etc
{
// ################################################################################
// Block4x4EncodingBits
// Base class for Block4x4EncodingBits_XXXX
// ################################################################################
class Block4x4EncodingBits
{
public:
enum class Format
{
UNKNOWN,
//
RGB8,
RGBA8,
R11,
RG11,
RGB8A1,
//
FORMATS
};
static unsigned int GetBytesPerBlock(Format a_format)
{
switch (a_format)
{
case Format::RGB8:
case Format::R11:
case Format::RGB8A1:
return 8;
break;
case Format::RGBA8:
case Format::RG11:
return 16;
break;
default:
return 0;
break;
}
}
};
// ################################################################################
// Block4x4EncodingBits_RGB8
// Encoding bits for the RGB portion of ETC1, RGB8, RGB8A1 and RGBA8
// ################################################################################
class Block4x4EncodingBits_RGB8
{
public:
static const unsigned int BYTES_PER_BLOCK = 8;
inline Block4x4EncodingBits_RGB8(void)
{
assert(sizeof(Block4x4EncodingBits_RGB8) == BYTES_PER_BLOCK);
for (unsigned int uiByte = 0; uiByte < BYTES_PER_BLOCK; uiByte++)
{
auc[uiByte] = 0;
}
}
typedef struct
{
unsigned red2 : 4;
unsigned red1 : 4;
//
unsigned green2 : 4;
unsigned green1 : 4;
//
unsigned blue2 : 4;
unsigned blue1 : 4;
//
unsigned flip : 1;
unsigned diff : 1;
unsigned cw2 : 3;
unsigned cw1 : 3;
//
unsigned int selectors;
} Individual;
typedef struct
{
signed dred2 : 3;
unsigned red1 : 5;
//
signed dgreen2 : 3;
unsigned green1 : 5;
//
signed dblue2 : 3;
unsigned blue1 : 5;
//
unsigned flip : 1;
unsigned diff : 1;
unsigned cw2 : 3;
unsigned cw1 : 3;
//
unsigned int selectors;
} Differential;
typedef struct
{
unsigned red1b : 2;
unsigned detect2 : 1;
unsigned red1a : 2;
unsigned detect1 : 3;
//
unsigned blue1 : 4;
unsigned green1 : 4;
//
unsigned green2 : 4;
unsigned red2 : 4;
//
unsigned db : 1;
unsigned diff : 1;
unsigned da : 2;
unsigned blue2 : 4;
//
unsigned int selectors;
} T;
typedef struct
{
unsigned green1a : 3;
unsigned red1 : 4;
unsigned detect1 : 1;
//
unsigned blue1b : 2;
unsigned detect3 : 1;
unsigned blue1a : 1;
unsigned green1b : 1;
unsigned detect2 : 3;
//
unsigned green2a : 3;
unsigned red2 : 4;
unsigned blue1c : 1;
//
unsigned db : 1;
unsigned diff : 1;
unsigned da : 1;
unsigned blue2 : 4;
unsigned green2b : 1;
//
unsigned int selectors;
} H;
typedef struct
{
unsigned originGreen1 : 1;
unsigned originRed : 6;
unsigned detect1 : 1;
//
unsigned originBlue1 : 1;
unsigned originGreen2 : 6;
unsigned detect2 : 1;
//
unsigned originBlue3 : 2;
unsigned detect4 : 1;
unsigned originBlue2 : 2;
unsigned detect3 : 3;
//
unsigned horizRed2 : 1;
unsigned diff : 1;
unsigned horizRed1 : 5;
unsigned originBlue4 : 1;
//
unsigned horizBlue1: 1;
unsigned horizGreen : 7;
//
unsigned vertRed1 : 3;
unsigned horizBlue2 : 5;
//
unsigned vertGreen1 : 5;
unsigned vertRed2 : 3;
//
unsigned vertBlue : 6;
unsigned vertGreen2 : 2;
} Planar;
union
{
unsigned char auc[BYTES_PER_BLOCK];
unsigned long int ul;
Individual individual;
Differential differential;
T t;
H h;
Planar planar;
};
};
// ################################################################################
// Block4x4EncodingBits_A8
// Encoding bits for the A portion of RGBA8
// ################################################################################
class Block4x4EncodingBits_A8
{
public:
static const unsigned int BYTES_PER_BLOCK = 8;
static const unsigned int SELECTOR_BYTES = 6;
typedef struct
{
unsigned base : 8;
unsigned table : 4;
unsigned multiplier : 4;
unsigned selectors0 : 8;
unsigned selectors1 : 8;
unsigned selectors2 : 8;
unsigned selectors3 : 8;
unsigned selectors4 : 8;
unsigned selectors5 : 8;
} Data;
Data data;
};
// ################################################################################
// Block4x4EncodingBits_R11
// Encoding bits for the R portion of R11
// ################################################################################
class Block4x4EncodingBits_R11
{
public:
static const unsigned int BYTES_PER_BLOCK = 8;
static const unsigned int SELECTOR_BYTES = 6;
typedef struct
{
unsigned base : 8;
unsigned table : 4;
unsigned multiplier : 4;
unsigned selectors0 : 8;
unsigned selectors1 : 8;
unsigned selectors2 : 8;
unsigned selectors3 : 8;
unsigned selectors4 : 8;
unsigned selectors5 : 8;
} Data;
Data data;
};
class Block4x4EncodingBits_RG11
{
public:
static const unsigned int BYTES_PER_BLOCK = 16;
static const unsigned int SELECTOR_BYTES = 12;
typedef struct
{
//Red portion
unsigned baseR : 8;
unsigned tableIndexR : 4;
unsigned multiplierR : 4;
unsigned selectorsR0 : 8;
unsigned selectorsR1 : 8;
unsigned selectorsR2 : 8;
unsigned selectorsR3 : 8;
unsigned selectorsR4 : 8;
unsigned selectorsR5 : 8;
//Green portion
unsigned baseG : 8;
unsigned tableIndexG : 4;
unsigned multiplierG : 4;
unsigned selectorsG0 : 8;
unsigned selectorsG1 : 8;
unsigned selectorsG2 : 8;
unsigned selectorsG3 : 8;
unsigned selectorsG4 : 8;
unsigned selectorsG5 : 8;
} Data;
Data data;
};
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,186 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
#pragma once
#include "EtcBlock4x4Encoding.h"
#include "EtcBlock4x4EncodingBits.h"
#include "EtcDifferentialTrys.h"
#include "EtcIndividualTrys.h"
namespace Etc
{
// base class for Block4x4Encoding_RGB8
class Block4x4Encoding_ETC1 : public Block4x4Encoding
{
public:
Block4x4Encoding_ETC1(void);
virtual ~Block4x4Encoding_ETC1(void);
virtual void InitFromSource(Block4x4 *a_pblockParent,
ColorFloatRGBA *a_pafrgbaSource,
unsigned char *a_paucEncodingBits,
ErrorMetric a_errormetric);
virtual void InitFromEncodingBits(Block4x4 *a_pblockParent,
unsigned char *a_paucEncodingBits,
ColorFloatRGBA *a_pafrgbaSource,
ErrorMetric a_errormetric);
virtual void PerformIteration(float a_fEffort);
inline virtual bool GetFlip(void)
{
return m_boolFlip;
}
inline virtual bool IsDifferential(void)
{
return m_boolDiff;
}
virtual void SetEncodingBits(void);
void Decode(void);
inline ColorFloatRGBA GetColor1(void) const
{
return m_frgbaColor1;
}
inline ColorFloatRGBA GetColor2(void) const
{
return m_frgbaColor2;
}
inline const unsigned int * GetSelectors(void) const
{
return m_auiSelectors;
}
inline unsigned int GetCW1(void) const
{
return m_uiCW1;
}
inline unsigned int GetCW2(void) const
{
return m_uiCW2;
}
inline bool HasSeverelyBentDifferentialColors(void) const
{
return m_boolSeverelyBentDifferentialColors;
}
protected:
static const unsigned int s_auiPixelOrderFlip0[PIXELS];
static const unsigned int s_auiPixelOrderFlip1[PIXELS];
static const unsigned int s_auiPixelOrderHScan[PIXELS];
static const unsigned int s_auiLeftPixelMapping[8];
static const unsigned int s_auiRightPixelMapping[8];
static const unsigned int s_auiTopPixelMapping[8];
static const unsigned int s_auiBottomPixelMapping[8];
static const unsigned int SELECTOR_BITS = 2;
static const unsigned int SELECTORS = 1 << SELECTOR_BITS;
static const unsigned int CW_BITS = 3;
static const unsigned int CW_RANGES = 1 << CW_BITS;
static float s_aafCwTable[CW_RANGES][SELECTORS];
static unsigned char s_aucDifferentialCwRange[256];
static const int MAX_DIFFERENTIAL = 3;
static const int MIN_DIFFERENTIAL = -4;
void InitFromEncodingBits_Selectors(void);
void PerformFirstIteration(void);
void CalculateMostLikelyFlip(void);
void TryDifferential(bool a_boolFlip, unsigned int a_uiRadius,
int a_iGrayOffset1, int a_iGrayOffset2);
void TryDifferentialHalf(DifferentialTrys::Half *a_phalf);
void TryIndividual(bool a_boolFlip, unsigned int a_uiRadius);
void TryIndividualHalf(IndividualTrys::Half *a_phalf);
void TryDegenerates1(void);
void TryDegenerates2(void);
void TryDegenerates3(void);
void TryDegenerates4(void);
void CalculateSelectors();
void CalculateHalfOfTheSelectors(unsigned int a_uiHalf,
const unsigned int *pauiPixelMapping);
// calculate the distance2 of r_frgbaPixel from r_frgbaTarget's gray line
inline float CalcGrayDistance2(ColorFloatRGBA &r_frgbaPixel,
ColorFloatRGBA &r_frgbaTarget)
{
float fDeltaGray = ((r_frgbaPixel.fR - r_frgbaTarget.fR) +
(r_frgbaPixel.fG - r_frgbaTarget.fG) +
(r_frgbaPixel.fB - r_frgbaTarget.fB)) / 3.0f;
ColorFloatRGBA frgbaPointOnGrayLine = (r_frgbaTarget + fDeltaGray).ClampRGB();
float fDR = r_frgbaPixel.fR - frgbaPointOnGrayLine.fR;
float fDG = r_frgbaPixel.fG - frgbaPointOnGrayLine.fG;
float fDB = r_frgbaPixel.fB - frgbaPointOnGrayLine.fB;
return (fDR*fDR) + (fDG*fDG) + (fDB*fDB);
}
void SetEncodingBits_Selectors(void);
// intermediate encoding
bool m_boolDiff;
bool m_boolFlip;
ColorFloatRGBA m_frgbaColor1;
ColorFloatRGBA m_frgbaColor2;
unsigned int m_uiCW1;
unsigned int m_uiCW2;
unsigned int m_auiSelectors[PIXELS];
// state shared between iterations
ColorFloatRGBA m_frgbaSourceAverageLeft;
ColorFloatRGBA m_frgbaSourceAverageRight;
ColorFloatRGBA m_frgbaSourceAverageTop;
ColorFloatRGBA m_frgbaSourceAverageBottom;
bool m_boolMostLikelyFlip;
// stats
float m_fError1; // error for Etc1 half 1
float m_fError2; // error for Etc1 half 2
bool m_boolSeverelyBentDifferentialColors; // only valid if m_boolDiff;
// final encoding
Block4x4EncodingBits_RGB8 *m_pencodingbitsRGB8; // or RGB8 portion of Block4x4EncodingBits_RGB8A8
private:
void CalculateSourceAverages(void);
};
} // namespace Etc

View File

@ -0,0 +1,429 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
/*
EtcBlock4x4Encoding_R11.cpp
Block4x4Encoding_R11 is the encoder to use when targetting file format R11 and SR11 (signed R11).
*/
#include "EtcConfig.h"
#include "EtcBlock4x4Encoding_R11.h"
#include "EtcBlock4x4EncodingBits.h"
#include "EtcBlock4x4.h"
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <float.h>
#include <limits>
namespace Etc
{
// modifier values to use for R11, SR11, RG11 and SRG11
float Block4x4Encoding_R11::s_aafModifierTable[MODIFIER_TABLE_ENTRYS][SELECTORS]
{
{ -3.0f / 255.0f, -6.0f / 255.0f, -9.0f / 255.0f, -15.0f / 255.0f, 2.0f / 255.0f, 5.0f / 255.0f, 8.0f / 255.0f, 14.0f / 255.0f },
{ -3.0f / 255.0f, -7.0f / 255.0f, -10.0f / 255.0f, -13.0f / 255.0f, 2.0f / 255.0f, 6.0f / 255.0f, 9.0f / 255.0f, 12.0f / 255.0f },
{ -2.0f / 255.0f, -5.0f / 255.0f, -8.0f / 255.0f, -13.0f / 255.0f, 1.0f / 255.0f, 4.0f / 255.0f, 7.0f / 255.0f, 12.0f / 255.0f },
{ -2.0f / 255.0f, -4.0f / 255.0f, -6.0f / 255.0f, -13.0f / 255.0f, 1.0f / 255.0f, 3.0f / 255.0f, 5.0f / 255.0f, 12.0f / 255.0f },
{ -3.0f / 255.0f, -6.0f / 255.0f, -8.0f / 255.0f, -12.0f / 255.0f, 2.0f / 255.0f, 5.0f / 255.0f, 7.0f / 255.0f, 11.0f / 255.0f },
{ -3.0f / 255.0f, -7.0f / 255.0f, -9.0f / 255.0f, -11.0f / 255.0f, 2.0f / 255.0f, 6.0f / 255.0f, 8.0f / 255.0f, 10.0f / 255.0f },
{ -4.0f / 255.0f, -7.0f / 255.0f, -8.0f / 255.0f, -11.0f / 255.0f, 3.0f / 255.0f, 6.0f / 255.0f, 7.0f / 255.0f, 10.0f / 255.0f },
{ -3.0f / 255.0f, -5.0f / 255.0f, -8.0f / 255.0f, -11.0f / 255.0f, 2.0f / 255.0f, 4.0f / 255.0f, 7.0f / 255.0f, 10.0f / 255.0f },
{ -2.0f / 255.0f, -6.0f / 255.0f, -8.0f / 255.0f, -10.0f / 255.0f, 1.0f / 255.0f, 5.0f / 255.0f, 7.0f / 255.0f, 9.0f / 255.0f },
{ -2.0f / 255.0f, -5.0f / 255.0f, -8.0f / 255.0f, -10.0f / 255.0f, 1.0f / 255.0f, 4.0f / 255.0f, 7.0f / 255.0f, 9.0f / 255.0f },
{ -2.0f / 255.0f, -4.0f / 255.0f, -8.0f / 255.0f, -10.0f / 255.0f, 1.0f / 255.0f, 3.0f / 255.0f, 7.0f / 255.0f, 9.0f / 255.0f },
{ -2.0f / 255.0f, -5.0f / 255.0f, -7.0f / 255.0f, -10.0f / 255.0f, 1.0f / 255.0f, 4.0f / 255.0f, 6.0f / 255.0f, 9.0f / 255.0f },
{ -3.0f / 255.0f, -4.0f / 255.0f, -7.0f / 255.0f, -10.0f / 255.0f, 2.0f / 255.0f, 3.0f / 255.0f, 6.0f / 255.0f, 9.0f / 255.0f },
{ -1.0f / 255.0f, -2.0f / 255.0f, -3.0f / 255.0f, -10.0f / 255.0f, 0.0f / 255.0f, 1.0f / 255.0f, 2.0f / 255.0f, 9.0f / 255.0f },
{ -4.0f / 255.0f, -6.0f / 255.0f, -8.0f / 255.0f, -9.0f / 255.0f, 3.0f / 255.0f, 5.0f / 255.0f, 7.0f / 255.0f, 8.0f / 255.0f },
{ -3.0f / 255.0f, -5.0f / 255.0f, -7.0f / 255.0f, -9.0f / 255.0f, 2.0f / 255.0f, 4.0f / 255.0f, 6.0f / 255.0f, 8.0f / 255.0f }
};
// ----------------------------------------------------------------------------------------------------
//
Block4x4Encoding_R11::Block4x4Encoding_R11(void)
{
m_pencodingbitsR11 = nullptr;
}
Block4x4Encoding_R11::~Block4x4Encoding_R11(void) {}
// ----------------------------------------------------------------------------------------------------
// initialization prior to encoding
// a_pblockParent points to the block associated with this encoding
// a_errormetric is used to choose the best encoding
// a_pafrgbaSource points to a 4x4 block subset of the source image
// a_paucEncodingBits points to the final encoding bits
//
void Block4x4Encoding_R11::InitFromSource(Block4x4 *a_pblockParent,
ColorFloatRGBA *a_pafrgbaSource,
unsigned char *a_paucEncodingBits, ErrorMetric a_errormetric)
{
Block4x4Encoding::Init(a_pblockParent, a_pafrgbaSource,a_errormetric);
m_pencodingbitsR11 = (Block4x4EncodingBits_R11 *)a_paucEncodingBits;
}
// ----------------------------------------------------------------------------------------------------
// initialization from the encoding bits of a previous encoding
// a_pblockParent points to the block associated with this encoding
// a_errormetric is used to choose the best encoding
// a_pafrgbaSource points to a 4x4 block subset of the source image
// a_paucEncodingBits points to the final encoding bits of a previous encoding
//
void Block4x4Encoding_R11::InitFromEncodingBits(Block4x4 *a_pblockParent,
unsigned char *a_paucEncodingBits,
ColorFloatRGBA *a_pafrgbaSource,
ErrorMetric a_errormetric)
{
m_pencodingbitsR11 = (Block4x4EncodingBits_R11 *)a_paucEncodingBits;
// init RGB portion
Block4x4Encoding_RGB8::InitFromEncodingBits(a_pblockParent,
(unsigned char *)m_pencodingbitsR11,
a_pafrgbaSource,
a_errormetric);
// init R11 portion
{
m_mode = MODE_R11;
if (a_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_R11 || a_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_RG11)
{
m_fRedBase = (float)(signed char)m_pencodingbitsR11->data.base;
}
else
{
m_fRedBase = (float)(unsigned char)m_pencodingbitsR11->data.base;
}
m_fRedMultiplier = (float)m_pencodingbitsR11->data.multiplier;
m_uiRedModifierTableIndex = m_pencodingbitsR11->data.table;
unsigned long long int ulliSelectorBits = 0;
ulliSelectorBits |= (unsigned long long int)m_pencodingbitsR11->data.selectors0 << 40;
ulliSelectorBits |= (unsigned long long int)m_pencodingbitsR11->data.selectors1 << 32;
ulliSelectorBits |= (unsigned long long int)m_pencodingbitsR11->data.selectors2 << 24;
ulliSelectorBits |= (unsigned long long int)m_pencodingbitsR11->data.selectors3 << 16;
ulliSelectorBits |= (unsigned long long int)m_pencodingbitsR11->data.selectors4 << 8;
ulliSelectorBits |= (unsigned long long int)m_pencodingbitsR11->data.selectors5;
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
unsigned int uiShift = 45 - (3 * uiPixel);
m_auiRedSelectors[uiPixel] = (ulliSelectorBits >> uiShift) & (SELECTORS - 1);
}
// decode the red channel
// calc red error
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
float fDecodedPixelData = 0.0f;
if (a_pblockParent->GetImageSource()->GetFormat() == Image::Format::R11 || a_pblockParent->GetImageSource()->GetFormat() == Image::Format::RG11)
{
fDecodedPixelData = DecodePixelRed(m_fRedBase, m_fRedMultiplier,
m_uiRedModifierTableIndex,
m_auiRedSelectors[uiPixel]);
}
else if (a_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_R11 || a_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_RG11)
{
fDecodedPixelData = DecodePixelRed(m_fRedBase + 128, m_fRedMultiplier,
m_uiRedModifierTableIndex,
m_auiRedSelectors[uiPixel]);
}
else
{
assert(0);
}
m_afrgbaDecodedColors[uiPixel] = ColorFloatRGBA(fDecodedPixelData, 0.0f, 0.0f, 1.0f);
}
CalcBlockError();
}
}
// ----------------------------------------------------------------------------------------------------
// perform a single encoding iteration
// replace the encoding if a better encoding was found
// subsequent iterations generally take longer for each iteration
// set m_boolDone if encoding is perfect or encoding is finished based on a_fEffort
//
void Block4x4Encoding_R11::PerformIteration(float a_fEffort)
{
assert(!m_boolDone);
m_mode = MODE_R11;
switch (m_uiEncodingIterations)
{
case 0:
m_fError = FLT_MAX;
m_fRedBlockError = FLT_MAX; // artificially high value
CalculateR11(8, 0.0f, 0.0f);
m_fError = m_fRedBlockError;
break;
case 1:
CalculateR11(8, 2.0f, 1.0f);
m_fError = m_fRedBlockError;
if (a_fEffort <= 24.5f)
{
m_boolDone = true;
}
break;
case 2:
CalculateR11(8, 12.0f, 1.0f);
m_fError = m_fRedBlockError;
if (a_fEffort <= 49.5f)
{
m_boolDone = true;
}
break;
case 3:
CalculateR11(7, 6.0f, 1.0f);
m_fError = m_fRedBlockError;
break;
case 4:
CalculateR11(6, 3.0f, 1.0f);
m_fError = m_fRedBlockError;
break;
case 5:
CalculateR11(5, 1.0f, 0.0f);
m_fError = m_fRedBlockError;
m_boolDone = true;
break;
default:
assert(0);
break;
}
m_uiEncodingIterations++;
SetDoneIfPerfect();
}
// ----------------------------------------------------------------------------------------------------
// find the best combination of base color, multiplier and selectors
//
// a_uiSelectorsUsed limits the number of selector combinations to try
// a_fBaseRadius limits the range of base colors to try
// a_fMultiplierRadius limits the range of multipliers to try
//
void Block4x4Encoding_R11::CalculateR11(unsigned int a_uiSelectorsUsed,
float a_fBaseRadius, float a_fMultiplierRadius)
{
// maps from virtual (monotonic) selector to ETC selector
static const unsigned int auiVirtualSelectorMap[8] = {3, 2, 1, 0, 4, 5, 6, 7};
// find min/max red
float fMinRed = 1.0f;
float fMaxRed = 0.0f;
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
// ignore border pixels
float fAlpha = m_pafrgbaSource[uiPixel].fA;
if (isnan(fAlpha))
{
continue;
}
float fRed = m_pafrgbaSource[uiPixel].fR;
if (fRed < fMinRed)
{
fMinRed = fRed;
}
if (fRed > fMaxRed)
{
fMaxRed = fRed;
}
}
assert(fMinRed <= fMaxRed);
float fRedRange = (fMaxRed - fMinRed);
// try each modifier table entry
for (unsigned int uiTableEntry = 0; uiTableEntry < MODIFIER_TABLE_ENTRYS; uiTableEntry++)
{
for (unsigned int uiMinVirtualSelector = 0;
uiMinVirtualSelector <= (8- a_uiSelectorsUsed);
uiMinVirtualSelector++)
{
unsigned int uiMaxVirtualSelector = uiMinVirtualSelector + a_uiSelectorsUsed - 1;
unsigned int uiMinSelector = auiVirtualSelectorMap[uiMinVirtualSelector];
unsigned int uiMaxSelector = auiVirtualSelectorMap[uiMaxVirtualSelector];
float fTableEntryCenter = -s_aafModifierTable[uiTableEntry][uiMinSelector];
float fTableEntryRange = s_aafModifierTable[uiTableEntry][uiMaxSelector] -
s_aafModifierTable[uiTableEntry][uiMinSelector];
float fCenterRatio = fTableEntryCenter / fTableEntryRange;
float fCenter = fMinRed + fCenterRatio*fRedRange;
fCenter = roundf(255.0f * fCenter) / 255.0f;
float fMinBase = fCenter - (a_fBaseRadius / 255.0f);
if (fMinBase < 0.0f)
{
fMinBase = 0.0f;
}
float fMaxBase = fCenter + (a_fBaseRadius / 255.0f);
if (fMaxBase > 1.0f)
{
fMaxBase = 1.0f;
}
for (float fBase = fMinBase; fBase <= fMaxBase; fBase += (0.999999f / 255.0f))
{
float fRangeMultiplier = roundf(fRedRange / fTableEntryRange);
float fMinMultiplier = fRangeMultiplier - a_fMultiplierRadius;
if (fMinMultiplier < 1.0f)
{
fMinMultiplier = 0.0f;
}
else if (fMinMultiplier > 15.0f)
{
fMinMultiplier = 15.0f;
}
float fMaxMultiplier = fRangeMultiplier + a_fMultiplierRadius;
if (fMaxMultiplier < 1.0f)
{
fMaxMultiplier = 1.0f;
}
else if (fMaxMultiplier > 15.0f)
{
fMaxMultiplier = 15.0f;
}
for (float fMultiplier = fMinMultiplier; fMultiplier <= fMaxMultiplier; fMultiplier += 1.0f)
{
// find best selector for each pixel
unsigned int auiBestSelectors[PIXELS];
float afBestRedError[PIXELS];
float afBestPixelRed[PIXELS];
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
float fBestPixelRedError = FLT_MAX;
for (unsigned int uiSelector = 0; uiSelector < SELECTORS; uiSelector++)
{
float fPixelRed = DecodePixelRed(fBase * 255.0f, fMultiplier, uiTableEntry, uiSelector);
ColorFloatRGBA frgba(fPixelRed, m_pafrgbaSource[uiPixel].fG,0.0f,1.0f);
float fPixelRedError = CalcPixelError(frgba, 1.0f, m_pafrgbaSource[uiPixel]);
if (fPixelRedError < fBestPixelRedError)
{
fBestPixelRedError = fPixelRedError;
auiBestSelectors[uiPixel] = uiSelector;
afBestRedError[uiPixel] = fBestPixelRedError;
afBestPixelRed[uiPixel] = fPixelRed;
}
}
}
float fBlockError = 0.0f;
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
fBlockError += afBestRedError[uiPixel];
}
if (fBlockError < m_fRedBlockError)
{
m_fRedBlockError = fBlockError;
if (m_pblockParent->GetImageSource()->GetFormat() == Image::Format::R11 || m_pblockParent->GetImageSource()->GetFormat() == Image::Format::RG11)
{
m_fRedBase = 255.0f * fBase;
}
else if (m_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_R11 || m_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_RG11)
{
m_fRedBase = (fBase * 255) - 128;
}
else
{
assert(0);
}
m_fRedMultiplier = fMultiplier;
m_uiRedModifierTableIndex = uiTableEntry;
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
m_auiRedSelectors[uiPixel] = auiBestSelectors[uiPixel];
float fBestPixelRed = afBestPixelRed[uiPixel];
m_afrgbaDecodedColors[uiPixel] = ColorFloatRGBA(fBestPixelRed, 0.0f, 0.0f, 1.0f);
m_afDecodedAlphas[uiPixel] = 1.0f;
}
}
}
}
}
}
}
// ----------------------------------------------------------------------------------------------------
// set the encoding bits based on encoding state
//
void Block4x4Encoding_R11::SetEncodingBits(void)
{
if (m_pblockParent->GetImageSource()->GetFormat() == Image::Format::R11 || m_pblockParent->GetImageSource()->GetFormat() == Image::Format::RG11)
{
m_pencodingbitsR11->data.base = (unsigned char)roundf(m_fRedBase);
}
else if (m_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_R11 || m_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_RG11)
{
m_pencodingbitsR11->data.base = (signed char)roundf(m_fRedBase);
}
else
{
assert(0);
}
m_pencodingbitsR11->data.table = m_uiRedModifierTableIndex;
m_pencodingbitsR11->data.multiplier = (unsigned char)roundf(m_fRedMultiplier);
unsigned long long int ulliSelectorBits = 0;
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
unsigned int uiShift = 45 - (3 * uiPixel);
ulliSelectorBits |= ((unsigned long long int)m_auiRedSelectors[uiPixel]) << uiShift;
}
m_pencodingbitsR11->data.selectors0 = ulliSelectorBits >> 40;
m_pencodingbitsR11->data.selectors1 = ulliSelectorBits >> 32;
m_pencodingbitsR11->data.selectors2 = ulliSelectorBits >> 24;
m_pencodingbitsR11->data.selectors3 = ulliSelectorBits >> 16;
m_pencodingbitsR11->data.selectors4 = ulliSelectorBits >> 8;
m_pencodingbitsR11->data.selectors5 = ulliSelectorBits;
}
// ----------------------------------------------------------------------------------------------------
//
}

View File

@ -0,0 +1,122 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
#pragma once
#include "EtcBlock4x4Encoding_RGB8.h"
namespace Etc
{
class Block4x4EncodingBits_R11;
// ################################################################################
// Block4x4Encoding_R11
// ################################################################################
class Block4x4Encoding_R11 : public Block4x4Encoding_RGB8
{
public:
Block4x4Encoding_R11(void);
virtual ~Block4x4Encoding_R11(void);
virtual void InitFromSource(Block4x4 *a_pblockParent,
ColorFloatRGBA *a_pafrgbaSource,
unsigned char *a_paucEncodingBits, ErrorMetric a_errormetric);
virtual void InitFromEncodingBits(Block4x4 *a_pblockParent,
unsigned char *a_paucEncodingBits,
ColorFloatRGBA *a_pafrgbaSource,
ErrorMetric a_errormetric);
virtual void PerformIteration(float a_fEffort);
virtual void SetEncodingBits(void);
inline float GetRedBase(void) const
{
return m_fRedBase;
}
inline float GetRedMultiplier(void) const
{
return m_fRedMultiplier;
}
inline int GetRedTableIndex(void) const
{
return m_uiRedModifierTableIndex;
}
inline const unsigned int * GetRedSelectors(void) const
{
return m_auiRedSelectors;
}
protected:
static const unsigned int MODIFIER_TABLE_ENTRYS = 16;
static const unsigned int SELECTOR_BITS = 3;
static const unsigned int SELECTORS = 1 << SELECTOR_BITS;
static float s_aafModifierTable[MODIFIER_TABLE_ENTRYS][SELECTORS];
void CalculateR11(unsigned int a_uiSelectorsUsed,
float a_fBaseRadius, float a_fMultiplierRadius);
inline float DecodePixelRed(float a_fBase, float a_fMultiplier,
unsigned int a_uiTableIndex, unsigned int a_uiSelector)
{
float fMultiplier = a_fMultiplier;
if (fMultiplier <= 0.0f)
{
fMultiplier = 1.0f / 8.0f;
}
float fPixelRed = a_fBase * 8 + 4 +
8 * fMultiplier*s_aafModifierTable[a_uiTableIndex][a_uiSelector]*255;
fPixelRed /= 2047.0f;
if (fPixelRed < 0.0f)
{
fPixelRed = 0.0f;
}
else if (fPixelRed > 1.0f)
{
fPixelRed = 1.0f;
}
return fPixelRed;
}
Block4x4EncodingBits_R11 *m_pencodingbitsR11;
float m_fRedBase;
float m_fRedMultiplier;
float m_fRedBlockError;
unsigned int m_uiRedModifierTableIndex;
unsigned int m_auiRedSelectors[PIXELS];
};
// ----------------------------------------------------------------------------------------------------
//
} // namespace Etc

View File

@ -0,0 +1,447 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
/*
EtcBlock4x4Encoding_RG11.cpp
Block4x4Encoding_RG11 is the encoder to use when targetting file format RG11 and SRG11 (signed RG11).
*/
#include "EtcConfig.h"
#include "EtcBlock4x4Encoding_RG11.h"
#include "EtcBlock4x4EncodingBits.h"
#include "EtcBlock4x4.h"
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <float.h>
#include <limits>
namespace Etc
{
// ----------------------------------------------------------------------------------------------------
//
Block4x4Encoding_RG11::Block4x4Encoding_RG11(void)
{
m_pencodingbitsRG11 = nullptr;
}
Block4x4Encoding_RG11::~Block4x4Encoding_RG11(void) {}
// ----------------------------------------------------------------------------------------------------
// initialization prior to encoding
// a_pblockParent points to the block associated with this encoding
// a_errormetric is used to choose the best encoding
// a_pafrgbaSource points to a 4x4 block subset of the source image
// a_paucEncodingBits points to the final encoding bits
//
void Block4x4Encoding_RG11::InitFromSource(Block4x4 *a_pblockParent,
ColorFloatRGBA *a_pafrgbaSource,
unsigned char *a_paucEncodingBits, ErrorMetric a_errormetric)
{
Block4x4Encoding::Init(a_pblockParent, a_pafrgbaSource,a_errormetric);
m_pencodingbitsRG11 = (Block4x4EncodingBits_RG11 *)a_paucEncodingBits;
}
// ----------------------------------------------------------------------------------------------------
// initialization from the encoding bits of a previous encoding
// a_pblockParent points to the block associated with this encoding
// a_errormetric is used to choose the best encoding
// a_pafrgbaSource points to a 4x4 block subset of the source image
// a_paucEncodingBits points to the final encoding bits of a previous encoding
//
void Block4x4Encoding_RG11::InitFromEncodingBits(Block4x4 *a_pblockParent,
unsigned char *a_paucEncodingBits,
ColorFloatRGBA *a_pafrgbaSource,
ErrorMetric a_errormetric)
{
m_pencodingbitsRG11 = (Block4x4EncodingBits_RG11 *)a_paucEncodingBits;
// init RGB portion
Block4x4Encoding_RGB8::InitFromEncodingBits(a_pblockParent,
(unsigned char *)m_pencodingbitsRG11,
a_pafrgbaSource,
a_errormetric);
m_fError = 0.0f;
{
m_mode = MODE_RG11;
if (a_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_RG11)
{
m_fRedBase = (float)(signed char)m_pencodingbitsRG11->data.baseR;
m_fGrnBase = (float)(signed char)m_pencodingbitsRG11->data.baseG;
}
else
{
m_fRedBase = (float)(unsigned char)m_pencodingbitsRG11->data.baseR;
m_fGrnBase = (float)(unsigned char)m_pencodingbitsRG11->data.baseG;
}
m_fRedMultiplier = (float)m_pencodingbitsRG11->data.multiplierR;
m_fGrnMultiplier = (float)m_pencodingbitsRG11->data.multiplierG;
m_uiRedModifierTableIndex = m_pencodingbitsRG11->data.tableIndexR;
m_uiGrnModifierTableIndex = m_pencodingbitsRG11->data.tableIndexG;
unsigned long long int ulliSelectorBitsR = 0;
ulliSelectorBitsR |= (unsigned long long int)m_pencodingbitsRG11->data.selectorsR0 << 40;
ulliSelectorBitsR |= (unsigned long long int)m_pencodingbitsRG11->data.selectorsR1 << 32;
ulliSelectorBitsR |= (unsigned long long int)m_pencodingbitsRG11->data.selectorsR2 << 24;
ulliSelectorBitsR |= (unsigned long long int)m_pencodingbitsRG11->data.selectorsR3 << 16;
ulliSelectorBitsR |= (unsigned long long int)m_pencodingbitsRG11->data.selectorsR4 << 8;
ulliSelectorBitsR |= (unsigned long long int)m_pencodingbitsRG11->data.selectorsR5;
unsigned long long int ulliSelectorBitsG = 0;
ulliSelectorBitsG |= (unsigned long long int)m_pencodingbitsRG11->data.selectorsG0 << 40;
ulliSelectorBitsG |= (unsigned long long int)m_pencodingbitsRG11->data.selectorsG1 << 32;
ulliSelectorBitsG |= (unsigned long long int)m_pencodingbitsRG11->data.selectorsG2 << 24;
ulliSelectorBitsG |= (unsigned long long int)m_pencodingbitsRG11->data.selectorsG3 << 16;
ulliSelectorBitsG |= (unsigned long long int)m_pencodingbitsRG11->data.selectorsG4 << 8;
ulliSelectorBitsG |= (unsigned long long int)m_pencodingbitsRG11->data.selectorsG5;
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
unsigned int uiShift = 45 - (3 * uiPixel);
m_auiRedSelectors[uiPixel] = (ulliSelectorBitsR >> uiShift) & (SELECTORS - 1);
m_auiGrnSelectors[uiPixel] = (ulliSelectorBitsG >> uiShift) & (SELECTORS - 1);
}
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
float fRedDecodedData = 0.0f;
float fGrnDecodedData = 0.0f;
if (a_pblockParent->GetImageSource()->GetFormat() == Image::Format::RG11)
{
fRedDecodedData = DecodePixelRed(m_fRedBase, m_fRedMultiplier, m_uiRedModifierTableIndex, m_auiRedSelectors[uiPixel]);
fGrnDecodedData = DecodePixelRed(m_fGrnBase, m_fGrnMultiplier, m_uiGrnModifierTableIndex, m_auiGrnSelectors[uiPixel]);
}
else if (a_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_RG11)
{
fRedDecodedData = DecodePixelRed(m_fRedBase + 128, m_fRedMultiplier, m_uiRedModifierTableIndex, m_auiRedSelectors[uiPixel]);
fGrnDecodedData = DecodePixelRed(m_fGrnBase + 128, m_fGrnMultiplier, m_uiGrnModifierTableIndex, m_auiGrnSelectors[uiPixel]);
}
else
{
assert(0);
}
m_afrgbaDecodedColors[uiPixel] = ColorFloatRGBA(fRedDecodedData, fGrnDecodedData, 0.0f, 1.0f);
}
}
CalcBlockError();
}
// ----------------------------------------------------------------------------------------------------
// perform a single encoding iteration
// replace the encoding if a better encoding was found
// subsequent iterations generally take longer for each iteration
// set m_boolDone if encoding is perfect or encoding is finished based on a_fEffort
//
void Block4x4Encoding_RG11::PerformIteration(float a_fEffort)
{
assert(!m_boolDone);
switch (m_uiEncodingIterations)
{
case 0:
m_fError = FLT_MAX;
m_fGrnBlockError = FLT_MAX; // artificially high value
m_fRedBlockError = FLT_MAX;
CalculateR11(8, 0.0f, 0.0f);
CalculateG11(8, 0.0f, 0.0f);
m_fError = (m_fGrnBlockError + m_fRedBlockError);
break;
case 1:
CalculateR11(8, 2.0f, 1.0f);
CalculateG11(8, 2.0f, 1.0f);
m_fError = (m_fGrnBlockError + m_fRedBlockError);
if (a_fEffort <= 24.5f)
{
m_boolDone = true;
}
break;
case 2:
CalculateR11(8, 12.0f, 1.0f);
CalculateG11(8, 12.0f, 1.0f);
m_fError = (m_fGrnBlockError + m_fRedBlockError);
if (a_fEffort <= 49.5f)
{
m_boolDone = true;
}
break;
case 3:
CalculateR11(7, 6.0f, 1.0f);
CalculateG11(7, 6.0f, 1.0f);
m_fError = (m_fGrnBlockError + m_fRedBlockError);
break;
case 4:
CalculateR11(6, 3.0f, 1.0f);
CalculateG11(6, 3.0f, 1.0f);
m_fError = (m_fGrnBlockError + m_fRedBlockError);
break;
case 5:
CalculateR11(5, 1.0f, 0.0f);
CalculateG11(5, 1.0f, 0.0f);
m_fError = (m_fGrnBlockError + m_fRedBlockError);
m_boolDone = true;
break;
default:
assert(0);
break;
}
m_uiEncodingIterations++;
SetDoneIfPerfect();
}
// ----------------------------------------------------------------------------------------------------
// find the best combination of base color, multiplier and selectors
//
// a_uiSelectorsUsed limits the number of selector combinations to try
// a_fBaseRadius limits the range of base colors to try
// a_fMultiplierRadius limits the range of multipliers to try
//
void Block4x4Encoding_RG11::CalculateG11(unsigned int a_uiSelectorsUsed,
float a_fBaseRadius, float a_fMultiplierRadius)
{
// maps from virtual (monotonic) selector to etc selector
static const unsigned int auiVirtualSelectorMap[8] = { 3, 2, 1, 0, 4, 5, 6, 7 };
// find min/max Grn
float fMinGrn = 1.0f;
float fMaxGrn = 0.0f;
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
// ignore border pixels
float fAlpha = m_pafrgbaSource[uiPixel].fA;
if (isnan(fAlpha))
{
continue;
}
float fGrn = m_pafrgbaSource[uiPixel].fG;
if (fGrn < fMinGrn)
{
fMinGrn = fGrn;
}
if (fGrn > fMaxGrn)
{
fMaxGrn = fGrn;
}
}
assert(fMinGrn <= fMaxGrn);
float fGrnRange = (fMaxGrn - fMinGrn);
// try each modifier table entry
for (unsigned int uiTableEntry = 0; uiTableEntry < MODIFIER_TABLE_ENTRYS; uiTableEntry++)
{
for (unsigned int uiMinVirtualSelector = 0;
uiMinVirtualSelector <= (8 - a_uiSelectorsUsed);
uiMinVirtualSelector++)
{
unsigned int uiMaxVirtualSelector = uiMinVirtualSelector + a_uiSelectorsUsed - 1;
unsigned int uiMinSelector = auiVirtualSelectorMap[uiMinVirtualSelector];
unsigned int uiMaxSelector = auiVirtualSelectorMap[uiMaxVirtualSelector];
float fTableEntryCenter = -s_aafModifierTable[uiTableEntry][uiMinSelector];
float fTableEntryRange = s_aafModifierTable[uiTableEntry][uiMaxSelector] -
s_aafModifierTable[uiTableEntry][uiMinSelector];
float fCenterRatio = fTableEntryCenter / fTableEntryRange;
float fCenter = fMinGrn + fCenterRatio*fGrnRange;
fCenter = roundf(255.0f * fCenter) / 255.0f;
float fMinBase = fCenter - (a_fBaseRadius / 255.0f);
if (fMinBase < 0.0f)
{
fMinBase = 0.0f;
}
float fMaxBase = fCenter + (a_fBaseRadius / 255.0f);
if (fMaxBase > 1.0f)
{
fMaxBase = 1.0f;
}
for (float fBase = fMinBase; fBase <= fMaxBase; fBase += (0.999999f / 255.0f))
{
float fRangeMultiplier = roundf(fGrnRange / fTableEntryRange);
float fMinMultiplier = fRangeMultiplier - a_fMultiplierRadius;
if (fMinMultiplier < 1.0f)
{
fMinMultiplier = 0.0f;
}
else if (fMinMultiplier > 15.0f)
{
fMinMultiplier = 15.0f;
}
float fMaxMultiplier = fRangeMultiplier + a_fMultiplierRadius;
if (fMaxMultiplier < 1.0f)
{
fMaxMultiplier = 1.0f;
}
else if (fMaxMultiplier > 15.0f)
{
fMaxMultiplier = 15.0f;
}
for (float fMultiplier = fMinMultiplier; fMultiplier <= fMaxMultiplier; fMultiplier += 1.0f)
{
// find best selector for each pixel
unsigned int auiBestSelectors[PIXELS];
float afBestGrnError[PIXELS];
float afBestPixelGrn[PIXELS];
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
float fBestPixelGrnError = FLT_MAX;
for (unsigned int uiSelector = 0; uiSelector < SELECTORS; uiSelector++)
{
//DecodePixelRed is not red channel specific
float fPixelGrn = DecodePixelRed(fBase * 255.0f, fMultiplier, uiTableEntry, uiSelector);
ColorFloatRGBA frgba(m_pafrgbaSource[uiPixel].fR, fPixelGrn, 0.0f, 1.0f);
float fPixelGrnError = CalcPixelError(frgba, 1.0f, m_pafrgbaSource[uiPixel]);
if (fPixelGrnError < fBestPixelGrnError)
{
fBestPixelGrnError = fPixelGrnError;
auiBestSelectors[uiPixel] = uiSelector;
afBestGrnError[uiPixel] = fBestPixelGrnError;
afBestPixelGrn[uiPixel] = fPixelGrn;
}
}
}
float fBlockError = 0.0f;
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
fBlockError += afBestGrnError[uiPixel];
}
if (fBlockError < m_fGrnBlockError)
{
m_fGrnBlockError = fBlockError;
if (m_pblockParent->GetImageSource()->GetFormat() == Image::Format::RG11)
{
m_fGrnBase = 255.0f * fBase;
}
else if (m_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_RG11)
{
m_fGrnBase = (fBase * 255) - 128;
}
else
{
assert(0);
}
m_fGrnMultiplier = fMultiplier;
m_uiGrnModifierTableIndex = uiTableEntry;
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
m_auiGrnSelectors[uiPixel] = auiBestSelectors[uiPixel];
m_afrgbaDecodedColors[uiPixel].fG = afBestPixelGrn[uiPixel];
m_afDecodedAlphas[uiPixel] = 1.0f;
}
}
}
}
}
}
}
// ----------------------------------------------------------------------------------------------------
// set the encoding bits based on encoding state
//
void Block4x4Encoding_RG11::SetEncodingBits(void)
{
unsigned long long int ulliSelectorBitsR = 0;
unsigned long long int ulliSelectorBitsG = 0;
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
unsigned int uiShift = 45 - (3 * uiPixel);
ulliSelectorBitsR |= ((unsigned long long int)m_auiRedSelectors[uiPixel]) << uiShift;
ulliSelectorBitsG |= ((unsigned long long int)m_auiGrnSelectors[uiPixel]) << uiShift;
}
if (m_pblockParent->GetImageSource()->GetFormat() == Image::Format::RG11)
{
m_pencodingbitsRG11->data.baseR = (unsigned char)roundf(m_fRedBase);
}
else if (m_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_RG11)
{
m_pencodingbitsRG11->data.baseR = (signed char)roundf(m_fRedBase);
}
else
{
assert(0);
}
m_pencodingbitsRG11->data.tableIndexR = m_uiRedModifierTableIndex;
m_pencodingbitsRG11->data.multiplierR = (unsigned char)roundf(m_fRedMultiplier);
m_pencodingbitsRG11->data.selectorsR0 = ulliSelectorBitsR >> 40;
m_pencodingbitsRG11->data.selectorsR1 = ulliSelectorBitsR >> 32;
m_pencodingbitsRG11->data.selectorsR2 = ulliSelectorBitsR >> 24;
m_pencodingbitsRG11->data.selectorsR3 = ulliSelectorBitsR >> 16;
m_pencodingbitsRG11->data.selectorsR4 = ulliSelectorBitsR >> 8;
m_pencodingbitsRG11->data.selectorsR5 = ulliSelectorBitsR;
if (m_pblockParent->GetImageSource()->GetFormat() == Image::Format::RG11)
{
m_pencodingbitsRG11->data.baseG = (unsigned char)roundf(m_fGrnBase);
}
else if (m_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_RG11)
{
m_pencodingbitsRG11->data.baseG = (signed char)roundf(m_fGrnBase);
}
else
{
assert(0);
}
m_pencodingbitsRG11->data.tableIndexG = m_uiGrnModifierTableIndex;
m_pencodingbitsRG11->data.multiplierG = (unsigned char)roundf(m_fGrnMultiplier);
m_pencodingbitsRG11->data.selectorsG0 = ulliSelectorBitsG >> 40;
m_pencodingbitsRG11->data.selectorsG1 = ulliSelectorBitsG >> 32;
m_pencodingbitsRG11->data.selectorsG2 = ulliSelectorBitsG >> 24;
m_pencodingbitsRG11->data.selectorsG3 = ulliSelectorBitsG >> 16;
m_pencodingbitsRG11->data.selectorsG4 = ulliSelectorBitsG >> 8;
m_pencodingbitsRG11->data.selectorsG5 = ulliSelectorBitsG;
}
// ----------------------------------------------------------------------------------------------------
//
}

View File

@ -0,0 +1,86 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
#pragma once
#include "EtcBlock4x4Encoding_RGB8.h"
#include "EtcBlock4x4Encoding_R11.h"
namespace Etc
{
class Block4x4EncodingBits_RG11;
// ################################################################################
// Block4x4Encoding_RG11
// ################################################################################
class Block4x4Encoding_RG11 : public Block4x4Encoding_R11
{
float m_fGrnBase;
float m_fGrnMultiplier;
float m_fGrnBlockError;
unsigned int m_auiGrnSelectors[PIXELS];
unsigned int m_uiGrnModifierTableIndex;
public:
Block4x4Encoding_RG11(void);
virtual ~Block4x4Encoding_RG11(void);
virtual void InitFromSource(Block4x4 *a_pblockParent,
ColorFloatRGBA *a_pafrgbaSource,
unsigned char *a_paucEncodingBits, ErrorMetric a_errormetric);
virtual void InitFromEncodingBits(Block4x4 *a_pblockParent,
unsigned char *a_paucEncodingBits,
ColorFloatRGBA *a_pafrgbaSource,
ErrorMetric a_errormetric);
virtual void PerformIteration(float a_fEffort);
virtual void SetEncodingBits(void);
Block4x4EncodingBits_RG11 *m_pencodingbitsRG11;
void CalculateG11(unsigned int a_uiSelectorsUsed, float a_fBaseRadius, float a_fMultiplierRadius);
inline float GetGrnBase(void) const
{
return m_fGrnBase;
}
inline float GetGrnMultiplier(void) const
{
return m_fGrnMultiplier;
}
inline int GetGrnTableIndex(void) const
{
return m_uiGrnModifierTableIndex;
}
inline const unsigned int * GetGrnSelectors(void) const
{
return m_auiGrnSelectors;
}
};
// ----------------------------------------------------------------------------------------------------
//
} // namespace Etc

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,96 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
#pragma once
#include "EtcBlock4x4Encoding_ETC1.h"
namespace Etc
{
class Block4x4Encoding_RGB8 : public Block4x4Encoding_ETC1
{
public:
Block4x4Encoding_RGB8(void);
virtual ~Block4x4Encoding_RGB8(void);
virtual void InitFromEncodingBits(Block4x4 *a_pblockParent,
unsigned char *a_paucEncodingBits,
ColorFloatRGBA *a_pafrgbaSource,
ErrorMetric a_errormetric);
virtual void PerformIteration(float a_fEffort);
virtual void SetEncodingBits(void);
inline ColorFloatRGBA GetColor3(void) const
{
return m_frgbaColor3;
}
protected:
static const unsigned int PLANAR_CORNER_COLORS = 3;
static const unsigned int MAX_PLANAR_REGRESSION_SIZE = 4;
static const unsigned int TH_DISTANCES = 8;
static float s_afTHDistanceTable[TH_DISTANCES];
void TryPlanar(unsigned int a_uiRadius);
void TryTAndH(unsigned int a_uiRadius);
void InitFromEncodingBits_Planar(void);
ColorFloatRGBA m_frgbaColor3; // used for planar
void SetEncodingBits_T(void);
void SetEncodingBits_H(void);
void SetEncodingBits_Planar(void);
// state shared between iterations
ColorFloatRGBA m_frgbaOriginalColor1_TAndH;
ColorFloatRGBA m_frgbaOriginalColor2_TAndH;
void CalculateBaseColorsForTAndH(void);
void TryT(unsigned int a_uiRadius);
void TryT_BestSelectorCombination(void);
void TryH(unsigned int a_uiRadius);
void TryH_BestSelectorCombination(void);
private:
void InitFromEncodingBits_T(void);
void InitFromEncodingBits_H(void);
void CalculatePlanarCornerColors(void);
void ColorRegression(ColorFloatRGBA *a_pafrgbaPixels, unsigned int a_uiPixels,
ColorFloatRGBA *a_pfrgbaSlope, ColorFloatRGBA *a_pfrgbaOffset);
bool TwiddlePlanar(void);
bool TwiddlePlanarR();
bool TwiddlePlanarG();
bool TwiddlePlanarB();
void DecodePixels_T(void);
void DecodePixels_H(void);
void DecodePixels_Planar(void);
};
} // namespace Etc

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,129 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
#pragma once
#include "EtcBlock4x4Encoding_RGB8.h"
#include "EtcErrorMetric.h"
#include "EtcBlock4x4EncodingBits.h"
namespace Etc
{
// ################################################################################
// Block4x4Encoding_RGB8A1
// RGB8A1 if not completely opaque or transparent
// ################################################################################
class Block4x4Encoding_RGB8A1 : public Block4x4Encoding_RGB8
{
public:
static const unsigned int TRANSPARENT_SELECTOR = 2;
Block4x4Encoding_RGB8A1(void);
virtual ~Block4x4Encoding_RGB8A1(void);
virtual void InitFromSource(Block4x4 *a_pblockParent,
ColorFloatRGBA *a_pafrgbaSource,
unsigned char *a_paucEncodingBits,
ErrorMetric a_errormetric);
virtual void InitFromEncodingBits(Block4x4 *a_pblockParent,
unsigned char *a_paucEncodingBits,
ColorFloatRGBA *a_pafrgbaSource,
ErrorMetric a_errormetric);
virtual void PerformIteration(float a_fEffort);
virtual void SetEncodingBits(void);
void InitFromEncodingBits_ETC1(Block4x4 *a_pblockParent,
unsigned char *a_paucEncodingBits,
ColorFloatRGBA *a_pafrgbaSource,
ErrorMetric a_errormetric);
void InitFromEncodingBits_T(void);
void InitFromEncodingBits_H(void);
void PerformFirstIteration(void);
void Decode_ETC1(void);
void DecodePixels_T(void);
void DecodePixels_H(void);
void SetEncodingBits_ETC1(void);
void SetEncodingBits_T(void);
void SetEncodingBits_H(void);
protected:
bool m_boolOpaque; // all source pixels have alpha >= 0.5
bool m_boolTransparent; // all source pixels have alpha < 0.5
bool m_boolPunchThroughPixels; // some source pixels have alpha < 0.5
static float s_aafCwOpaqueUnsetTable[CW_RANGES][SELECTORS];
private:
void TryDifferential(bool a_boolFlip, unsigned int a_uiRadius,
int a_iGrayOffset1, int a_iGrayOffset2);
void TryDifferentialHalf(DifferentialTrys::Half *a_phalf);
void TryT(unsigned int a_uiRadius);
void TryT_BestSelectorCombination(void);
void TryH(unsigned int a_uiRadius);
void TryH_BestSelectorCombination(void);
void TryDegenerates1(void);
void TryDegenerates2(void);
void TryDegenerates3(void);
void TryDegenerates4(void);
};
// ################################################################################
// Block4x4Encoding_RGB8A1_Opaque
// RGB8A1 if all pixels have alpha==1
// ################################################################################
class Block4x4Encoding_RGB8A1_Opaque : public Block4x4Encoding_RGB8A1
{
public:
virtual void PerformIteration(float a_fEffort);
void PerformFirstIteration(void);
private:
};
// ################################################################################
// Block4x4Encoding_RGB8A1_Transparent
// RGB8A1 if all pixels have alpha==0
// ################################################################################
class Block4x4Encoding_RGB8A1_Transparent : public Block4x4Encoding_RGB8A1
{
public:
virtual void PerformIteration(float a_fEffort);
private:
};
} // namespace Etc

View File

@ -0,0 +1,474 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
/*
EtcBlock4x4Encoding_RGBA8.cpp contains:
Block4x4Encoding_RGBA8
Block4x4Encoding_RGBA8_Opaque
Block4x4Encoding_RGBA8_Transparent
These encoders are used when targetting file format RGBA8.
Block4x4Encoding_RGBA8_Opaque is used when all pixels in the 4x4 block are opaque
Block4x4Encoding_RGBA8_Transparent is used when all pixels in the 4x4 block are transparent
Block4x4Encoding_RGBA8 is used when there is a mixture of alphas in the 4x4 block
*/
#include "EtcConfig.h"
#include "EtcBlock4x4Encoding_RGBA8.h"
#include "EtcBlock4x4EncodingBits.h"
#include "EtcBlock4x4.h"
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <float.h>
#include <limits>
namespace Etc
{
// ####################################################################################################
// Block4x4Encoding_RGBA8
// ####################################################################################################
float Block4x4Encoding_RGBA8::s_aafModifierTable[MODIFIER_TABLE_ENTRYS][ALPHA_SELECTORS]
{
{ -3.0f / 255.0f, -6.0f / 255.0f, -9.0f / 255.0f, -15.0f / 255.0f, 2.0f / 255.0f, 5.0f / 255.0f, 8.0f / 255.0f, 14.0f / 255.0f },
{ -3.0f / 255.0f, -7.0f / 255.0f, -10.0f / 255.0f, -13.0f / 255.0f, 2.0f / 255.0f, 6.0f / 255.0f, 9.0f / 255.0f, 12.0f / 255.0f },
{ -2.0f / 255.0f, -5.0f / 255.0f, -8.0f / 255.0f, -13.0f / 255.0f, 1.0f / 255.0f, 4.0f / 255.0f, 7.0f / 255.0f, 12.0f / 255.0f },
{ -2.0f / 255.0f, -4.0f / 255.0f, -6.0f / 255.0f, -13.0f / 255.0f, 1.0f / 255.0f, 3.0f / 255.0f, 5.0f / 255.0f, 12.0f / 255.0f },
{ -3.0f / 255.0f, -6.0f / 255.0f, -8.0f / 255.0f, -12.0f / 255.0f, 2.0f / 255.0f, 5.0f / 255.0f, 7.0f / 255.0f, 11.0f / 255.0f },
{ -3.0f / 255.0f, -7.0f / 255.0f, -9.0f / 255.0f, -11.0f / 255.0f, 2.0f / 255.0f, 6.0f / 255.0f, 8.0f / 255.0f, 10.0f / 255.0f },
{ -4.0f / 255.0f, -7.0f / 255.0f, -8.0f / 255.0f, -11.0f / 255.0f, 3.0f / 255.0f, 6.0f / 255.0f, 7.0f / 255.0f, 10.0f / 255.0f },
{ -3.0f / 255.0f, -5.0f / 255.0f, -8.0f / 255.0f, -11.0f / 255.0f, 2.0f / 255.0f, 4.0f / 255.0f, 7.0f / 255.0f, 10.0f / 255.0f },
{ -2.0f / 255.0f, -6.0f / 255.0f, -8.0f / 255.0f, -10.0f / 255.0f, 1.0f / 255.0f, 5.0f / 255.0f, 7.0f / 255.0f, 9.0f / 255.0f },
{ -2.0f / 255.0f, -5.0f / 255.0f, -8.0f / 255.0f, -10.0f / 255.0f, 1.0f / 255.0f, 4.0f / 255.0f, 7.0f / 255.0f, 9.0f / 255.0f },
{ -2.0f / 255.0f, -4.0f / 255.0f, -8.0f / 255.0f, -10.0f / 255.0f, 1.0f / 255.0f, 3.0f / 255.0f, 7.0f / 255.0f, 9.0f / 255.0f },
{ -2.0f / 255.0f, -5.0f / 255.0f, -7.0f / 255.0f, -10.0f / 255.0f, 1.0f / 255.0f, 4.0f / 255.0f, 6.0f / 255.0f, 9.0f / 255.0f },
{ -3.0f / 255.0f, -4.0f / 255.0f, -7.0f / 255.0f, -10.0f / 255.0f, 2.0f / 255.0f, 3.0f / 255.0f, 6.0f / 255.0f, 9.0f / 255.0f },
{ -1.0f / 255.0f, -2.0f / 255.0f, -3.0f / 255.0f, -10.0f / 255.0f, 0.0f / 255.0f, 1.0f / 255.0f, 2.0f / 255.0f, 9.0f / 255.0f },
{ -4.0f / 255.0f, -6.0f / 255.0f, -8.0f / 255.0f, -9.0f / 255.0f, 3.0f / 255.0f, 5.0f / 255.0f, 7.0f / 255.0f, 8.0f / 255.0f },
{ -3.0f / 255.0f, -5.0f / 255.0f, -7.0f / 255.0f, -9.0f / 255.0f, 2.0f / 255.0f, 4.0f / 255.0f, 6.0f / 255.0f, 8.0f / 255.0f }
};
// ----------------------------------------------------------------------------------------------------
//
Block4x4Encoding_RGBA8::Block4x4Encoding_RGBA8(void)
{
m_pencodingbitsA8 = nullptr;
}
Block4x4Encoding_RGBA8::~Block4x4Encoding_RGBA8(void) {}
// ----------------------------------------------------------------------------------------------------
// initialization prior to encoding
// a_pblockParent points to the block associated with this encoding
// a_errormetric is used to choose the best encoding
// a_pafrgbaSource points to a 4x4 block subset of the source image
// a_paucEncodingBits points to the final encoding bits
//
void Block4x4Encoding_RGBA8::InitFromSource(Block4x4 *a_pblockParent,
ColorFloatRGBA *a_pafrgbaSource,
unsigned char *a_paucEncodingBits, ErrorMetric a_errormetric)
{
Block4x4Encoding::Init(a_pblockParent, a_pafrgbaSource,a_errormetric);
m_pencodingbitsA8 = (Block4x4EncodingBits_A8 *)a_paucEncodingBits;
m_pencodingbitsRGB8 = (Block4x4EncodingBits_RGB8 *)(a_paucEncodingBits + sizeof(Block4x4EncodingBits_A8));
}
// ----------------------------------------------------------------------------------------------------
// initialization from the encoding bits of a previous encoding
// a_pblockParent points to the block associated with this encoding
// a_errormetric is used to choose the best encoding
// a_pafrgbaSource points to a 4x4 block subset of the source image
// a_paucEncodingBits points to the final encoding bits of a previous encoding
//
void Block4x4Encoding_RGBA8::InitFromEncodingBits(Block4x4 *a_pblockParent,
unsigned char *a_paucEncodingBits,
ColorFloatRGBA *a_pafrgbaSource,
ErrorMetric a_errormetric)
{
m_pencodingbitsA8 = (Block4x4EncodingBits_A8 *)a_paucEncodingBits;
m_pencodingbitsRGB8 = (Block4x4EncodingBits_RGB8 *)(a_paucEncodingBits + sizeof(Block4x4EncodingBits_A8));
// init RGB portion
Block4x4Encoding_RGB8::InitFromEncodingBits(a_pblockParent,
(unsigned char *) m_pencodingbitsRGB8,
a_pafrgbaSource,
a_errormetric);
// init A8 portion
// has to be done after InitFromEncodingBits()
{
m_fBase = m_pencodingbitsA8->data.base / 255.0f;
m_fMultiplier = (float)m_pencodingbitsA8->data.multiplier;
m_uiModifierTableIndex = m_pencodingbitsA8->data.table;
unsigned long long int ulliSelectorBits = 0;
ulliSelectorBits |= (unsigned long long int)m_pencodingbitsA8->data.selectors0 << 40;
ulliSelectorBits |= (unsigned long long int)m_pencodingbitsA8->data.selectors1 << 32;
ulliSelectorBits |= (unsigned long long int)m_pencodingbitsA8->data.selectors2 << 24;
ulliSelectorBits |= (unsigned long long int)m_pencodingbitsA8->data.selectors3 << 16;
ulliSelectorBits |= (unsigned long long int)m_pencodingbitsA8->data.selectors4 << 8;
ulliSelectorBits |= (unsigned long long int)m_pencodingbitsA8->data.selectors5;
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
unsigned int uiShift = 45 - (3 * uiPixel);
m_auiAlphaSelectors[uiPixel] = (ulliSelectorBits >> uiShift) & (ALPHA_SELECTORS - 1);
}
// decode the alphas
// calc alpha error
m_fError = 0.0f;
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
m_afDecodedAlphas[uiPixel] = DecodePixelAlpha(m_fBase, m_fMultiplier,
m_uiModifierTableIndex,
m_auiAlphaSelectors[uiPixel]);
float fDeltaAlpha = m_afDecodedAlphas[uiPixel] - m_pafrgbaSource[uiPixel].fA;
m_fError += fDeltaAlpha * fDeltaAlpha;
}
}
// redo error calc to include alpha
CalcBlockError();
}
// ----------------------------------------------------------------------------------------------------
// perform a single encoding iteration
// replace the encoding if a better encoding was found
// subsequent iterations generally take longer for each iteration
// set m_boolDone if encoding is perfect or encoding is finished based on a_fEffort
//
// similar to Block4x4Encoding_RGB8_Base::Encode_RGB8(), but with alpha added
//
void Block4x4Encoding_RGBA8::PerformIteration(float a_fEffort)
{
assert(!m_boolDone);
if (m_uiEncodingIterations == 0)
{
if (a_fEffort < 24.9f)
{
CalculateA8(0.0f);
}
else if (a_fEffort < 49.9f)
{
CalculateA8(1.0f);
}
else
{
CalculateA8(2.0f);
}
}
Block4x4Encoding_RGB8::PerformIteration(a_fEffort);
}
// ----------------------------------------------------------------------------------------------------
// find the best combination of base alpga, multiplier and selectors
//
// a_fRadius limits the range of base alpha to try
//
void Block4x4Encoding_RGBA8::CalculateA8(float a_fRadius)
{
// find min/max alpha
float fMinAlpha = 1.0f;
float fMaxAlpha = 0.0f;
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
float fAlpha = m_pafrgbaSource[uiPixel].fA;
// ignore border pixels
if (isnan(fAlpha))
{
continue;
}
if (fAlpha < fMinAlpha)
{
fMinAlpha = fAlpha;
}
if (fAlpha > fMaxAlpha)
{
fMaxAlpha = fAlpha;
}
}
assert(fMinAlpha <= fMaxAlpha);
float fAlphaRange = fMaxAlpha - fMinAlpha;
// try each modifier table entry
m_fError = FLT_MAX; // artificially high value
for (unsigned int uiTableEntry = 0; uiTableEntry < MODIFIER_TABLE_ENTRYS; uiTableEntry++)
{
static const unsigned int MIN_VALUE_SELECTOR = 3;
static const unsigned int MAX_VALUE_SELECTOR = 7;
float fTableEntryCenter = -s_aafModifierTable[uiTableEntry][MIN_VALUE_SELECTOR];
float fTableEntryRange = s_aafModifierTable[uiTableEntry][MAX_VALUE_SELECTOR] -
s_aafModifierTable[uiTableEntry][MIN_VALUE_SELECTOR];
float fCenterRatio = fTableEntryCenter / fTableEntryRange;
float fCenter = fMinAlpha + fCenterRatio*fAlphaRange;
fCenter = roundf(255.0f * fCenter) / 255.0f;
float fMinBase = fCenter - (a_fRadius / 255.0f);
if (fMinBase < 0.0f)
{
fMinBase = 0.0f;
}
float fMaxBase = fCenter + (a_fRadius / 255.0f);
if (fMaxBase > 1.0f)
{
fMaxBase = 1.0f;
}
for (float fBase = fMinBase; fBase <= fMaxBase; fBase += (0.999999f / 255.0f))
{
float fRangeMultiplier = roundf(fAlphaRange / fTableEntryRange);
float fMinMultiplier = fRangeMultiplier - a_fRadius;
if (fMinMultiplier < 1.0f)
{
fMinMultiplier = 1.0f;
}
else if (fMinMultiplier > 15.0f)
{
fMinMultiplier = 15.0f;
}
float fMaxMultiplier = fRangeMultiplier + a_fRadius;
if (fMaxMultiplier < 1.0f)
{
fMaxMultiplier = 1.0f;
}
else if (fMaxMultiplier > 15.0f)
{
fMaxMultiplier = 15.0f;
}
for (float fMultiplier = fMinMultiplier; fMultiplier <= fMaxMultiplier; fMultiplier += 1.0f)
{
// find best selector for each pixel
unsigned int auiBestSelectors[PIXELS];
float afBestAlphaError[PIXELS];
float afBestDecodedAlphas[PIXELS];
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
float fBestPixelAlphaError = FLT_MAX;
for (unsigned int uiSelector = 0; uiSelector < ALPHA_SELECTORS; uiSelector++)
{
float fDecodedAlpha = DecodePixelAlpha(fBase, fMultiplier, uiTableEntry, uiSelector);
// border pixels (NAN) should have zero error
float fPixelDeltaAlpha = isnan(m_pafrgbaSource[uiPixel].fA) ?
0.0f :
fDecodedAlpha - m_pafrgbaSource[uiPixel].fA;
float fPixelAlphaError = fPixelDeltaAlpha * fPixelDeltaAlpha;
if (fPixelAlphaError < fBestPixelAlphaError)
{
fBestPixelAlphaError = fPixelAlphaError;
auiBestSelectors[uiPixel] = uiSelector;
afBestAlphaError[uiPixel] = fBestPixelAlphaError;
afBestDecodedAlphas[uiPixel] = fDecodedAlpha;
}
}
}
float fBlockError = 0.0f;
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
fBlockError += afBestAlphaError[uiPixel];
}
if (fBlockError < m_fError)
{
m_fError = fBlockError;
m_fBase = fBase;
m_fMultiplier = fMultiplier;
m_uiModifierTableIndex = uiTableEntry;
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
m_auiAlphaSelectors[uiPixel] = auiBestSelectors[uiPixel];
m_afDecodedAlphas[uiPixel] = afBestDecodedAlphas[uiPixel];
}
}
}
}
}
}
// ----------------------------------------------------------------------------------------------------
// set the encoding bits based on encoding state
//
void Block4x4Encoding_RGBA8::SetEncodingBits(void)
{
// set the RGB8 portion
Block4x4Encoding_RGB8::SetEncodingBits();
// set the A8 portion
{
m_pencodingbitsA8->data.base = (unsigned char)roundf(255.0f * m_fBase);
m_pencodingbitsA8->data.table = m_uiModifierTableIndex;
m_pencodingbitsA8->data.multiplier = (unsigned char)roundf(m_fMultiplier);
unsigned long long int ulliSelectorBits = 0;
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
unsigned int uiShift = 45 - (3 * uiPixel);
ulliSelectorBits |= ((unsigned long long int)m_auiAlphaSelectors[uiPixel]) << uiShift;
}
m_pencodingbitsA8->data.selectors0 = ulliSelectorBits >> 40;
m_pencodingbitsA8->data.selectors1 = ulliSelectorBits >> 32;
m_pencodingbitsA8->data.selectors2 = ulliSelectorBits >> 24;
m_pencodingbitsA8->data.selectors3 = ulliSelectorBits >> 16;
m_pencodingbitsA8->data.selectors4 = ulliSelectorBits >> 8;
m_pencodingbitsA8->data.selectors5 = ulliSelectorBits;
}
}
// ####################################################################################################
// Block4x4Encoding_RGBA8_Opaque
// ####################################################################################################
// ----------------------------------------------------------------------------------------------------
// perform a single encoding iteration
// replace the encoding if a better encoding was found
// subsequent iterations generally take longer for each iteration
// set m_boolDone if encoding is perfect or encoding is finished based on a_fEffort
//
void Block4x4Encoding_RGBA8_Opaque::PerformIteration(float a_fEffort)
{
assert(!m_boolDone);
if (m_uiEncodingIterations == 0)
{
m_fError = 0.0f;
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
m_afDecodedAlphas[uiPixel] = 1.0f;
}
}
Block4x4Encoding_RGB8::PerformIteration(a_fEffort);
}
// ----------------------------------------------------------------------------------------------------
// set the encoding bits based on encoding state
//
void Block4x4Encoding_RGBA8_Opaque::SetEncodingBits(void)
{
// set the RGB8 portion
Block4x4Encoding_RGB8::SetEncodingBits();
// set the A8 portion
m_pencodingbitsA8->data.base = 255;
m_pencodingbitsA8->data.table = 15;
m_pencodingbitsA8->data.multiplier = 15;
m_pencodingbitsA8->data.selectors0 = 0xFF;
m_pencodingbitsA8->data.selectors1 = 0xFF;
m_pencodingbitsA8->data.selectors2 = 0xFF;
m_pencodingbitsA8->data.selectors3 = 0xFF;
m_pencodingbitsA8->data.selectors4 = 0xFF;
m_pencodingbitsA8->data.selectors5 = 0xFF;
}
// ####################################################################################################
// Block4x4Encoding_RGBA8_Transparent
// ####################################################################################################
// ----------------------------------------------------------------------------------------------------
// perform a single encoding iteration
// replace the encoding if a better encoding was found
// subsequent iterations generally take longer for each iteration
// set m_boolDone if encoding is perfect or encoding is finished based on a_fEffort
//
void Block4x4Encoding_RGBA8_Transparent::PerformIteration(float )
{
assert(!m_boolDone);
assert(m_uiEncodingIterations == 0);
m_mode = MODE_ETC1;
m_boolDiff = true;
m_boolFlip = false;
for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
{
m_afrgbaDecodedColors[uiPixel] = ColorFloatRGBA();
m_afDecodedAlphas[uiPixel] = 0.0f;
}
m_fError = 0.0f;
m_boolDone = true;
m_uiEncodingIterations++;
}
// ----------------------------------------------------------------------------------------------------
// set the encoding bits based on encoding state
//
void Block4x4Encoding_RGBA8_Transparent::SetEncodingBits(void)
{
Block4x4Encoding_RGB8::SetEncodingBits();
// set the A8 portion
m_pencodingbitsA8->data.base = 0;
m_pencodingbitsA8->data.table = 0;
m_pencodingbitsA8->data.multiplier = 1;
m_pencodingbitsA8->data.selectors0 = 0;
m_pencodingbitsA8->data.selectors1 = 0;
m_pencodingbitsA8->data.selectors2 = 0;
m_pencodingbitsA8->data.selectors3 = 0;
m_pencodingbitsA8->data.selectors4 = 0;
m_pencodingbitsA8->data.selectors5 = 0;
}
// ----------------------------------------------------------------------------------------------------
//
}

View File

@ -0,0 +1,121 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
#pragma once
#include "EtcBlock4x4Encoding_RGB8.h"
namespace Etc
{
class Block4x4EncodingBits_A8;
// ################################################################################
// Block4x4Encoding_RGBA8
// RGBA8 if not completely opaque or transparent
// ################################################################################
class Block4x4Encoding_RGBA8 : public Block4x4Encoding_RGB8
{
public:
Block4x4Encoding_RGBA8(void);
virtual ~Block4x4Encoding_RGBA8(void);
virtual void InitFromSource(Block4x4 *a_pblockParent,
ColorFloatRGBA *a_pafrgbaSource,
unsigned char *a_paucEncodingBits, ErrorMetric a_errormetric);
virtual void InitFromEncodingBits(Block4x4 *a_pblockParent,
unsigned char *a_paucEncodingBits,
ColorFloatRGBA *a_pafrgbaSource,
ErrorMetric a_errormetric);
virtual void PerformIteration(float a_fEffort);
virtual void SetEncodingBits(void);
protected:
static const unsigned int MODIFIER_TABLE_ENTRYS = 16;
static const unsigned int ALPHA_SELECTOR_BITS = 3;
static const unsigned int ALPHA_SELECTORS = 1 << ALPHA_SELECTOR_BITS;
static float s_aafModifierTable[MODIFIER_TABLE_ENTRYS][ALPHA_SELECTORS];
void CalculateA8(float a_fRadius);
Block4x4EncodingBits_A8 *m_pencodingbitsA8; // A8 portion of Block4x4EncodingBits_RGBA8
float m_fBase;
float m_fMultiplier;
unsigned int m_uiModifierTableIndex;
unsigned int m_auiAlphaSelectors[PIXELS];
private:
inline float DecodePixelAlpha(float a_fBase, float a_fMultiplier,
unsigned int a_uiTableIndex, unsigned int a_uiSelector)
{
float fPixelAlpha = a_fBase +
a_fMultiplier*s_aafModifierTable[a_uiTableIndex][a_uiSelector];
if (fPixelAlpha < 0.0f)
{
fPixelAlpha = 0.0f;
}
else if (fPixelAlpha > 1.0f)
{
fPixelAlpha = 1.0f;
}
return fPixelAlpha;
}
};
// ################################################################################
// Block4x4Encoding_RGBA8_Opaque
// RGBA8 if all pixels have alpha==1
// ################################################################################
class Block4x4Encoding_RGBA8_Opaque : public Block4x4Encoding_RGBA8
{
public:
virtual void PerformIteration(float a_fEffort);
virtual void SetEncodingBits(void);
};
// ################################################################################
// Block4x4Encoding_RGBA8_Transparent
// RGBA8 if all pixels have alpha==0
// ################################################################################
class Block4x4Encoding_RGBA8_Transparent : public Block4x4Encoding_RGBA8
{
public:
virtual void PerformIteration(float a_fEffort);
virtual void SetEncodingBits(void);
};
// ----------------------------------------------------------------------------------------------------
//
} // namespace Etc

View File

@ -0,0 +1,173 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
/*
EtcDifferentialTrys.cpp
Gathers the results of the various encoding trys for both halves of a 4x4 block for Differential mode
*/
#include "EtcConfig.h"
#include "EtcDifferentialTrys.h"
#include <assert.h>
namespace Etc
{
// ----------------------------------------------------------------------------------------------------
// construct a list of trys (encoding attempts)
//
// a_frgbaColor1 is the basecolor for the first half
// a_frgbaColor2 is the basecolor for the second half
// a_pauiPixelMapping1 is the pixel order for the first half
// a_pauiPixelMapping2 is the pixel order for the second half
// a_uiRadius is the amount to vary the base colors
//
DifferentialTrys::DifferentialTrys(ColorFloatRGBA a_frgbaColor1, ColorFloatRGBA a_frgbaColor2,
const unsigned int *a_pauiPixelMapping1,
const unsigned int *a_pauiPixelMapping2,
unsigned int a_uiRadius,
int a_iGrayOffset1, int a_iGrayOffset2)
{
assert(a_uiRadius <= MAX_RADIUS);
m_boolSeverelyBentColors = false;
ColorFloatRGBA frgbaQuantizedColor1 = a_frgbaColor1.QuantizeR5G5B5();
ColorFloatRGBA frgbaQuantizedColor2 = a_frgbaColor2.QuantizeR5G5B5();
// quantize base colors
// ensure that trys with a_uiRadius don't overflow
int iRed1 = MoveAwayFromEdge(frgbaQuantizedColor1.IntRed(31.0f)+a_iGrayOffset1, a_uiRadius);
int iGreen1 = MoveAwayFromEdge(frgbaQuantizedColor1.IntGreen(31.0f) + a_iGrayOffset1, a_uiRadius);
int iBlue1 = MoveAwayFromEdge(frgbaQuantizedColor1.IntBlue(31.0f) + a_iGrayOffset1, a_uiRadius);
int iRed2 = MoveAwayFromEdge(frgbaQuantizedColor2.IntRed(31.0f) + a_iGrayOffset2, a_uiRadius);
int iGreen2 = MoveAwayFromEdge(frgbaQuantizedColor2.IntGreen(31.0f) + a_iGrayOffset2, a_uiRadius);
int iBlue2 = MoveAwayFromEdge(frgbaQuantizedColor2.IntBlue(31.0f) + a_iGrayOffset2, a_uiRadius);
int iDeltaRed = iRed2 - iRed1;
int iDeltaGreen = iGreen2 - iGreen1;
int iDeltaBlue = iBlue2 - iBlue1;
// make sure components are within range
{
if (iDeltaRed > 3)
{
if (iDeltaRed > 7)
{
m_boolSeverelyBentColors = true;
}
iRed1 += (iDeltaRed - 3) / 2;
iRed2 = iRed1 + 3;
iDeltaRed = 3;
}
else if (iDeltaRed < -4)
{
if (iDeltaRed < -8)
{
m_boolSeverelyBentColors = true;
}
iRed1 += (iDeltaRed + 4) / 2;
iRed2 = iRed1 - 4;
iDeltaRed = -4;
}
assert(iRed1 >= (signed)(0 + a_uiRadius) && iRed1 <= (signed)(31 - a_uiRadius));
assert(iRed2 >= (signed)(0 + a_uiRadius) && iRed2 <= (signed)(31 - a_uiRadius));
assert(iDeltaRed >= -4 && iDeltaRed <= 3);
if (iDeltaGreen > 3)
{
if (iDeltaGreen > 7)
{
m_boolSeverelyBentColors = true;
}
iGreen1 += (iDeltaGreen - 3) / 2;
iGreen2 = iGreen1 + 3;
iDeltaGreen = 3;
}
else if (iDeltaGreen < -4)
{
if (iDeltaGreen < -8)
{
m_boolSeverelyBentColors = true;
}
iGreen1 += (iDeltaGreen + 4) / 2;
iGreen2 = iGreen1 - 4;
iDeltaGreen = -4;
}
assert(iGreen1 >= (signed)(0 + a_uiRadius) && iGreen1 <= (signed)(31 - a_uiRadius));
assert(iGreen2 >= (signed)(0 + a_uiRadius) && iGreen2 <= (signed)(31 - a_uiRadius));
assert(iDeltaGreen >= -4 && iDeltaGreen <= 3);
if (iDeltaBlue > 3)
{
if (iDeltaBlue > 7)
{
m_boolSeverelyBentColors = true;
}
iBlue1 += (iDeltaBlue - 3) / 2;
iBlue2 = iBlue1 + 3;
iDeltaBlue = 3;
}
else if (iDeltaBlue < -4)
{
if (iDeltaBlue < -8)
{
m_boolSeverelyBentColors = true;
}
iBlue1 += (iDeltaBlue + 4) / 2;
iBlue2 = iBlue1 - 4;
iDeltaBlue = -4;
}
assert(iBlue1 >= (signed)(0+a_uiRadius) && iBlue1 <= (signed)(31 - a_uiRadius));
assert(iBlue2 >= (signed)(0 + a_uiRadius) && iBlue2 <= (signed)(31 - a_uiRadius));
assert(iDeltaBlue >= -4 && iDeltaBlue <= 3);
}
m_half1.Init(iRed1, iGreen1, iBlue1, a_pauiPixelMapping1, a_uiRadius);
m_half2.Init(iRed2, iGreen2, iBlue2, a_pauiPixelMapping2, a_uiRadius);
}
// ----------------------------------------------------------------------------------------------------
//
void DifferentialTrys::Half::Init(int a_iRed, int a_iGreen, int a_iBlue,
const unsigned int *a_pauiPixelMapping, unsigned int a_uiRadius)
{
m_iRed = a_iRed;
m_iGreen = a_iGreen;
m_iBlue = a_iBlue;
m_pauiPixelMapping = a_pauiPixelMapping;
m_uiRadius = a_uiRadius;
m_uiTrys = 0;
}
// ----------------------------------------------------------------------------------------------------
//
} // namespace Etc

View File

@ -0,0 +1,97 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
#pragma once
#include "EtcColorFloatRGBA.h"
namespace Etc
{
class DifferentialTrys
{
public:
static const unsigned int MAX_RADIUS = 2;
DifferentialTrys(ColorFloatRGBA a_frgbaColor1,
ColorFloatRGBA a_frgbaColor2,
const unsigned int *a_pauiPixelMapping1,
const unsigned int *a_pauiPixelMapping2,
unsigned int a_uiRadius,
int a_iGrayOffset1, int a_iGrayOffset2);
inline static int MoveAwayFromEdge(int a_i, int a_iDistance)
{
if (a_i < (0+ a_iDistance))
{
return (0 + a_iDistance);
}
else if (a_i > (31- a_iDistance))
{
return (31 - a_iDistance);
}
return a_i;
}
class Try
{
public :
static const unsigned int SELECTORS = 8; // per half
int m_iRed;
int m_iGreen;
int m_iBlue;
unsigned int m_uiCW;
unsigned int m_auiSelectors[SELECTORS];
float m_fError;
};
class Half
{
public:
static const unsigned int MAX_TRYS = 125;
void Init(int a_iRed, int a_iGreen, int a_iBlue,
const unsigned int *a_pauiPixelMapping,
unsigned int a_uiRadius);
// center of trys
int m_iRed;
int m_iGreen;
int m_iBlue;
const unsigned int *m_pauiPixelMapping;
unsigned int m_uiRadius;
unsigned int m_uiTrys;
Try m_atry[MAX_TRYS];
Try *m_ptryBest;
};
Half m_half1;
Half m_half2;
bool m_boolSeverelyBentColors;
};
// ----------------------------------------------------------------------------------------------------
//
} // namespace Etc

51
extern/EtcLib/EtcCodec/EtcErrorMetric.h vendored Normal file
View File

@ -0,0 +1,51 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
#pragma once
namespace Etc
{
enum ErrorMetric
{
RGBA,
REC709,
NUMERIC,
NORMALXYZ,
//
ERROR_METRICS,
//
BT709 = REC709
};
inline const char *ErrorMetricToString(ErrorMetric errorMetric)
{
switch (errorMetric)
{
case RGBA:
return "RGBA";
case REC709:
return "REC709";
case NUMERIC:
return "NUMERIC";
case NORMALXYZ:
return "NORMALXYZ";
case ERROR_METRICS:
default:
return "UNKNOWN";
}
}
} // namespace Etc

View File

@ -0,0 +1,85 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
/*
EtcIndividualTrys.cpp
Gathers the results of the various encoding trys for both halves of a 4x4 block for Individual mode
*/
#include "EtcConfig.h"
#include "EtcIndividualTrys.h"
#include <assert.h>
namespace Etc
{
// ----------------------------------------------------------------------------------------------------
// construct a list of trys (encoding attempts)
//
// a_frgbaColor1 is the basecolor for the first half
// a_frgbaColor2 is the basecolor for the second half
// a_pauiPixelMapping1 is the pixel order for the first half
// a_pauiPixelMapping2 is the pixel order for the second half
// a_uiRadius is the amount to vary the base colors
//
IndividualTrys::IndividualTrys(ColorFloatRGBA a_frgbaColor1, ColorFloatRGBA a_frgbaColor2,
const unsigned int *a_pauiPixelMapping1,
const unsigned int *a_pauiPixelMapping2,
unsigned int a_uiRadius)
{
assert(a_uiRadius <= MAX_RADIUS);
ColorFloatRGBA frgbaQuantizedColor1 = a_frgbaColor1.QuantizeR4G4B4();
ColorFloatRGBA frgbaQuantizedColor2 = a_frgbaColor2.QuantizeR4G4B4();
// quantize base colors
// ensure that trys with a_uiRadius don't overflow
int iRed1 = MoveAwayFromEdge(frgbaQuantizedColor1.IntRed(15.0f), a_uiRadius);
int iGreen1 = MoveAwayFromEdge(frgbaQuantizedColor1.IntGreen(15.0f), a_uiRadius);
int iBlue1 = MoveAwayFromEdge(frgbaQuantizedColor1.IntBlue(15.0f), a_uiRadius);
int iRed2 = MoveAwayFromEdge(frgbaQuantizedColor2.IntRed(15.0f), a_uiRadius);
int iGreen2 = MoveAwayFromEdge(frgbaQuantizedColor2.IntGreen(15.0f), a_uiRadius);
int iBlue2 = MoveAwayFromEdge(frgbaQuantizedColor2.IntBlue(15.0f), a_uiRadius);
m_half1.Init(iRed1, iGreen1, iBlue1, a_pauiPixelMapping1, a_uiRadius);
m_half2.Init(iRed2, iGreen2, iBlue2, a_pauiPixelMapping2, a_uiRadius);
}
// ----------------------------------------------------------------------------------------------------
//
void IndividualTrys::Half::Init(int a_iRed, int a_iGreen, int a_iBlue,
const unsigned int *a_pauiPixelMapping, unsigned int a_uiRadius)
{
m_iRed = a_iRed;
m_iGreen = a_iGreen;
m_iBlue = a_iBlue;
m_pauiPixelMapping = a_pauiPixelMapping;
m_uiRadius = a_uiRadius;
m_uiTrys = 0;
}
// ----------------------------------------------------------------------------------------------------
//
} // namespace Etc

View File

@ -0,0 +1,95 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
#pragma once
#include "EtcColorFloatRGBA.h"
namespace Etc
{
class IndividualTrys
{
public:
static const unsigned int MAX_RADIUS = 1;
IndividualTrys(ColorFloatRGBA a_frgbaColor1,
ColorFloatRGBA a_frgbaColor2,
const unsigned int *a_pauiPixelMapping1,
const unsigned int *a_pauiPixelMapping2,
unsigned int a_uiRadius);
inline static int MoveAwayFromEdge(int a_i, int a_iDistance)
{
if (a_i < (0+ a_iDistance))
{
return (0 + a_iDistance);
}
else if (a_i > (15- a_iDistance))
{
return (15 - a_iDistance);
}
return a_i;
}
class Try
{
public :
static const unsigned int SELECTORS = 8; // per half
int m_iRed;
int m_iGreen;
int m_iBlue;
unsigned int m_uiCW;
unsigned int m_auiSelectors[SELECTORS];
float m_fError;
};
class Half
{
public:
static const unsigned int MAX_TRYS = 27;
void Init(int a_iRed, int a_iGreen, int a_iBlue,
const unsigned int *a_pauiPixelMapping,
unsigned int a_uiRadius);
// center of trys
int m_iRed;
int m_iGreen;
int m_iBlue;
const unsigned int *m_pauiPixelMapping;
unsigned int m_uiRadius;
unsigned int m_uiTrys;
Try m_atry[MAX_TRYS];
Try *m_ptryBest;
};
Half m_half1;
Half m_half2;
};
// ----------------------------------------------------------------------------------------------------
//
} // namespace Etc

View File

@ -0,0 +1,228 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
/*
EtcSortedBlockList.cpp
SortedBlockList is a list of 4x4 blocks that can be used by the "effort" system to prioritize
the encoding of the 4x4 blocks.
The sorting is done with buckets, where each bucket is an indication of how much error each 4x4 block has
*/
#include "EtcConfig.h"
#include "EtcSortedBlockList.h"
#include "EtcBlock4x4.h"
#include <stdio.h>
#include <string.h>
#include <assert.h>
namespace Etc
{
// ----------------------------------------------------------------------------------------------------
// construct an empty list
//
// allocate enough memory to add all of the image's 4x4 blocks later
// allocate enough buckets to sort the blocks
//
SortedBlockList::SortedBlockList(unsigned int a_uiImageBlocks, unsigned int a_uiBuckets)
{
m_uiImageBlocks = a_uiImageBlocks;
m_iBuckets = (int)a_uiBuckets;
m_uiAddedBlocks = 0;
m_uiSortedBlocks = 0;
m_palinkPool = new Link[m_uiImageBlocks];
m_pabucket = new Bucket[m_iBuckets];
m_fMaxError = 0.0f;
InitBuckets();
}
// ----------------------------------------------------------------------------------------------------
//
SortedBlockList::~SortedBlockList(void)
{
delete[] m_palinkPool;
delete[] m_pabucket;
}
// ----------------------------------------------------------------------------------------------------
// add a 4x4 block to the list
// the 4x4 block will be sorted later
//
void SortedBlockList::AddBlock(Block4x4 *a_pblock)
{
assert(m_uiAddedBlocks < m_uiImageBlocks);
Link *plink = &m_palinkPool[m_uiAddedBlocks++];
plink->Init(a_pblock);
}
// ----------------------------------------------------------------------------------------------------
// sort all of the 4x4 blocks that have been added to the list
//
// first, determine the maximum error, then assign an error range to each bucket
// next, determine which bucket each 4x4 block belongs to based on the 4x4 block's error
// add the 4x4 block to the appropriate bucket
// lastly, walk thru the buckets and add each bucket to a sorted linked list
//
// the resultant sorting is an approximate sorting from most to least error
//
void SortedBlockList::Sort(void)
{
assert(m_uiAddedBlocks == m_uiImageBlocks);
InitBuckets();
// find max block error
m_fMaxError = -1.0f;
for (unsigned int uiLink = 0; uiLink < m_uiAddedBlocks; uiLink++)
{
Link *plinkBlock = &m_palinkPool[uiLink];
float fBlockError = plinkBlock->GetBlock()->GetError();
if (fBlockError > m_fMaxError)
{
m_fMaxError = fBlockError;
}
}
// prevent divide by zero or divide by negative
if (m_fMaxError <= 0.0f)
{
m_fMaxError = 1.0f;
}
//used for debugging
//int numDone = 0;
// put all of the blocks with unfinished encodings into the appropriate bucket
m_uiSortedBlocks = 0;
for (unsigned int uiLink = 0; uiLink < m_uiAddedBlocks; uiLink++)
{
Link *plinkBlock = &m_palinkPool[uiLink];
// if the encoding is done, don't add it to the list
if (plinkBlock->GetBlock()->GetEncoding()->IsDone())
{
//numDone++;
continue;
}
// calculate the appropriate sort bucket
float fBlockError = plinkBlock->GetBlock()->GetError();
int iBucket = (int) floorf(m_iBuckets * fBlockError / m_fMaxError);
// clamp to bucket index
iBucket = iBucket < 0 ? 0 : iBucket >= m_iBuckets ? m_iBuckets - 1 : iBucket;
// add block to bucket
{
Bucket *pbucket = &m_pabucket[iBucket];
if (pbucket->plinkLast)
{
pbucket->plinkLast->SetNext(plinkBlock);
pbucket->plinkLast = plinkBlock;
}
else
{
pbucket->plinkFirst = pbucket->plinkLast = plinkBlock;
}
plinkBlock->SetNext(nullptr);
}
m_uiSortedBlocks++;
if (0)
{
printf("%u: e=%.3f\n", uiLink, fBlockError);
Print();
printf("\n\n\n");
}
}
//printf("num blocks already done: %d\n",numDone);
//link the blocks together across buckets
m_plinkFirst = nullptr;
m_plinkLast = nullptr;
for (int iBucket = m_iBuckets - 1; iBucket >= 0; iBucket--)
{
Bucket *pbucket = &m_pabucket[iBucket];
if (pbucket->plinkFirst)
{
if (m_plinkFirst == nullptr)
{
m_plinkFirst = pbucket->plinkFirst;
}
else
{
assert(pbucket->plinkLast->GetNext() == nullptr);
m_plinkLast->SetNext(pbucket->plinkFirst);
}
m_plinkLast = pbucket->plinkLast;
}
}
}
// ----------------------------------------------------------------------------------------------------
// clear all of the buckets. normally done in preparation for a sort
//
void SortedBlockList::InitBuckets(void)
{
for (int iBucket = 0; iBucket < m_iBuckets; iBucket++)
{
Bucket *pbucket = &m_pabucket[iBucket];
pbucket->plinkFirst = 0;
pbucket->plinkLast = 0;
}
}
// ----------------------------------------------------------------------------------------------------
// print out the list of sorted 4x4 blocks
// normally used for debugging
//
void SortedBlockList::Print(void)
{
for (int iBucket = m_iBuckets-1; iBucket >= 0; iBucket--)
{
Bucket *pbucket = &m_pabucket[iBucket];
unsigned int uiBlocks = 0;
for (Link *plink = pbucket->plinkFirst; plink != nullptr; plink = plink->GetNext() )
{
uiBlocks++;
if (plink == pbucket->plinkLast)
{
break;
}
}
float fBucketError = m_fMaxError * iBucket / m_iBuckets;
float fBucketRMS = sqrtf(fBucketError / (4.0f*16.0f) );
printf("%3d: e=%.3f rms=%.6f %u\n", iBucket, fBucketError, fBucketRMS, uiBlocks);
}
}
// ----------------------------------------------------------------------------------------------------
//
} // namespace Etc

View File

@ -0,0 +1,124 @@
/*
* Copyright 2015 The Etc2Comp Authors.
*
* 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.
*/
#pragma once
namespace Etc
{
class Block4x4;
class SortedBlockList
{
public:
class Link
{
public:
inline void Init(Block4x4 *a_pblock)
{
m_pblock = a_pblock;
m_plinkNext = nullptr;
}
inline Block4x4 * GetBlock(void)
{
return m_pblock;
}
inline void SetNext(Link *a_plinkNext)
{
m_plinkNext = a_plinkNext;
}
inline Link * GetNext(void)
{
return m_plinkNext;
}
inline Link * Advance(unsigned int a_uiSteps = 1)
{
Link *plink = this;
for (unsigned int uiStep = 0; uiStep < a_uiSteps; uiStep++)
{
if (plink == nullptr)
{
break;
}
plink = plink->m_plinkNext;
}
return plink;
}
private:
Block4x4 *m_pblock;
Link *m_plinkNext;
};
SortedBlockList(unsigned int a_uiImageBlocks, unsigned int a_uiBuckets);
~SortedBlockList(void);
void AddBlock(Block4x4 *a_pblock);
void Sort(void);
inline Link * GetLinkToFirstBlock(void)
{
return m_plinkFirst;
}
inline unsigned int GetNumberOfAddedBlocks(void)
{
return m_uiAddedBlocks;
}
inline unsigned int GetNumberOfSortedBlocks(void)
{
return m_uiSortedBlocks;
}
void Print(void);
private:
void InitBuckets(void);
class Bucket
{
public:
Link *plinkFirst;
Link *plinkLast;
};
unsigned int m_uiImageBlocks;
int m_iBuckets;
unsigned int m_uiAddedBlocks;
unsigned int m_uiSortedBlocks;
Link *m_palinkPool;
Bucket *m_pabucket;
float m_fMaxError;
Link *m_plinkFirst;
Link *m_plinkLast;
};
} // namespace Etc

View File

@ -1,227 +0,0 @@
LIBRARY FreeImage.dll
EXPORTS
FreeImage_OutputMessageProc
FreeImage_AcquireMemory@12
FreeImage_AdjustBrightness@12
FreeImage_AdjustColors@32
FreeImage_AdjustContrast@12
FreeImage_AdjustCurve@12
FreeImage_AdjustGamma@12
FreeImage_Allocate@24
FreeImage_AllocateEx@36
FreeImage_AllocateExT@40
FreeImage_AllocateT@28
FreeImage_AppendPage@8
FreeImage_ApplyColorMapping@24
FreeImage_ApplyPaletteIndexMapping@20
FreeImage_Clone@4
FreeImage_CloneMetadata@8
FreeImage_CloneTag@4
FreeImage_CloseMemory@4
FreeImage_CloseMultiBitmap@8
FreeImage_ColorQuantize@8
FreeImage_ColorQuantizeEx@20
FreeImage_Composite@16
FreeImage_ConvertFromRawBits@36
FreeImage_ConvertLine16To24_555@12
FreeImage_ConvertLine16To24_565@12
FreeImage_ConvertLine16To32_555@12
FreeImage_ConvertLine16To32_565@12
FreeImage_ConvertLine16To4_555@12
FreeImage_ConvertLine16To4_565@12
FreeImage_ConvertLine16To8_555@12
FreeImage_ConvertLine16To8_565@12
FreeImage_ConvertLine16_555_To16_565@12
FreeImage_ConvertLine16_565_To16_555@12
FreeImage_ConvertLine1To16_555@16
FreeImage_ConvertLine1To16_565@16
FreeImage_ConvertLine1To24@16
FreeImage_ConvertLine1To32@16
FreeImage_ConvertLine1To4@12
FreeImage_ConvertLine1To8@12
FreeImage_ConvertLine24To16_555@12
FreeImage_ConvertLine24To16_565@12
FreeImage_ConvertLine24To32@12
FreeImage_ConvertLine24To4@12
FreeImage_ConvertLine24To8@12
FreeImage_ConvertLine32To16_555@12
FreeImage_ConvertLine32To16_565@12
FreeImage_ConvertLine32To24@12
FreeImage_ConvertLine32To4@12
FreeImage_ConvertLine32To8@12
FreeImage_ConvertLine4To16_555@16
FreeImage_ConvertLine4To16_565@16
FreeImage_ConvertLine4To24@16
FreeImage_ConvertLine4To32@16
FreeImage_ConvertLine4To8@12
FreeImage_ConvertLine8To16_555@16
FreeImage_ConvertLine8To16_565@16
FreeImage_ConvertLine8To24@16
FreeImage_ConvertLine8To32@16
FreeImage_ConvertLine8To4@16
FreeImage_ConvertTo16Bits555@4
FreeImage_ConvertTo16Bits565@4
FreeImage_ConvertTo24Bits@4
FreeImage_ConvertTo32Bits@4
FreeImage_ConvertTo4Bits@4
FreeImage_ConvertTo8Bits@4
FreeImage_ConvertToGreyscale@4
FreeImage_ConvertToRGBF@4
FreeImage_ConvertToRawBits@32
FreeImage_ConvertToStandardType@8
FreeImage_ConvertToType@12
FreeImage_Copy@20
FreeImage_CreateICCProfile@12
FreeImage_CreateTag@0
FreeImage_DeInitialise@0
FreeImage_DeletePage@8
FreeImage_DeleteTag@4
FreeImage_DestroyICCProfile@4
FreeImage_Dither@8
FreeImage_EnlargeCanvas@28
FreeImage_FIFSupportsExportBPP@8
FreeImage_FIFSupportsExportType@8
FreeImage_FIFSupportsICCProfiles@4
FreeImage_FIFSupportsReading@4
FreeImage_FIFSupportsWriting@4
FreeImage_FillBackground@12
FreeImage_FindCloseMetadata@4
FreeImage_FindFirstMetadata@12
FreeImage_FindNextMetadata@8
FreeImage_FlipHorizontal@4
FreeImage_FlipVertical@4
FreeImage_GetAdjustColorsLookupTable@32
FreeImage_GetBPP@4
FreeImage_GetBackgroundColor@8
FreeImage_GetBits@4
FreeImage_GetBlueMask@4
FreeImage_GetChannel@8
FreeImage_GetColorType@4
FreeImage_GetColorsUsed@4
FreeImage_GetComplexChannel@8
FreeImage_GetCopyrightMessage@0
FreeImage_GetDIBSize@4
FreeImage_GetDotsPerMeterX@4
FreeImage_GetDotsPerMeterY@4
FreeImage_GetFIFCount@0
FreeImage_GetFIFDescription@4
FreeImage_GetFIFExtensionList@4
FreeImage_GetFIFFromFilename@4
FreeImage_GetFIFFromFilenameU@4
FreeImage_GetFIFFromFormat@4
FreeImage_GetFIFFromMime@4
FreeImage_GetFIFMimeType@4
FreeImage_GetFIFRegExpr@4
FreeImage_GetFileType@8
FreeImage_GetFileTypeFromHandle@12
FreeImage_GetFileTypeFromMemory@8
FreeImage_GetFileTypeU@8
FreeImage_GetFormatFromFIF@4
FreeImage_GetGreenMask@4
FreeImage_GetHeight@4
FreeImage_GetHistogram@12
FreeImage_GetICCProfile@4
FreeImage_GetImageType@4
FreeImage_GetInfo@4
FreeImage_GetInfoHeader@4
FreeImage_GetLine@4
FreeImage_GetLockedPageNumbers@12
FreeImage_GetMetadata@16
FreeImage_GetMetadataCount@8
FreeImage_GetPageCount@4
FreeImage_GetPalette@4
FreeImage_GetPitch@4
FreeImage_GetPixelColor@16
FreeImage_GetPixelIndex@16
FreeImage_GetRedMask@4
FreeImage_GetScanLine@8
FreeImage_GetTagCount@4
FreeImage_GetTagDescription@4
FreeImage_GetTagID@4
FreeImage_GetTagKey@4
FreeImage_GetTagLength@4
FreeImage_GetTagType@4
FreeImage_GetTagValue@4
FreeImage_GetTransparencyCount@4
FreeImage_GetTransparencyTable@4
FreeImage_GetTransparentIndex@4
FreeImage_GetVersion@0
FreeImage_GetWidth@4
FreeImage_HasBackgroundColor@4
FreeImage_Initialise@4
FreeImage_InsertPage@12
FreeImage_Invert@4
FreeImage_IsLittleEndian@0
FreeImage_IsPluginEnabled@4
FreeImage_IsTransparent@4
FreeImage_JPEGCrop@24
FreeImage_JPEGCropU@24
FreeImage_JPEGTransform@16
FreeImage_JPEGTransformU@16
FreeImage_Load@12
FreeImage_LoadFromHandle@16
FreeImage_LoadFromMemory@12
FreeImage_LoadMultiBitmapFromMemory@12
FreeImage_LoadU@12
FreeImage_LockPage@8
FreeImage_LookupSVGColor@16
FreeImage_LookupX11Color@16
FreeImage_MakeThumbnail@12
FreeImage_MovePage@12
FreeImage_MultigridPoissonSolver@8
FreeImage_OpenMemory@8
FreeImage_OpenMultiBitmap@24
FreeImage_OpenMultiBitmapFromHandle@16
FreeImage_Paste@20
FreeImage_PreMultiplyWithAlpha@4
FreeImage_ReadMemory@16
FreeImage_RegisterExternalPlugin@20
FreeImage_RegisterLocalPlugin@20
FreeImage_Rescale@16
FreeImage_Rotate@16
FreeImage_RotateClassic@12
FreeImage_RotateEx@48
FreeImage_Save@16
FreeImage_SaveToHandle@20
FreeImage_SaveToMemory@16
FreeImage_SaveU@16
FreeImage_SeekMemory@12
FreeImage_SetBackgroundColor@8
FreeImage_SetChannel@12
FreeImage_SetComplexChannel@12
FreeImage_SetDotsPerMeterX@8
FreeImage_SetDotsPerMeterY@8
FreeImage_SetMetadata@16
FreeImage_SetOutputMessage@4
FreeImage_SetOutputMessageStdCall@4
FreeImage_SetPixelColor@16
FreeImage_SetPixelIndex@16
FreeImage_SetPluginEnabled@8
FreeImage_SetTagCount@8
FreeImage_SetTagDescription@8
FreeImage_SetTagID@8
FreeImage_SetTagKey@8
FreeImage_SetTagLength@8
FreeImage_SetTagType@8
FreeImage_SetTagValue@8
FreeImage_SetTransparencyTable@12
FreeImage_SetTransparent@8
FreeImage_SetTransparentIndex@8
FreeImage_SwapColors@16
FreeImage_SwapPaletteIndices@12
FreeImage_TagToString@12
FreeImage_TellMemory@4
FreeImage_Threshold@8
FreeImage_TmoDrago03@20
FreeImage_TmoFattal02@20
FreeImage_TmoReinhard05@20
FreeImage_TmoReinhard05Ex@36
FreeImage_ToneMapping@24
FreeImage_Unload@4
FreeImage_UnlockPage@12
FreeImage_WriteMemory@16
FreeImage_ZLibCRC32@12
FreeImage_ZLibCompress@16
FreeImage_ZLibGUnzip@16
FreeImage_ZLibGZip@16
FreeImage_ZLibUncompress@16

Some files were not shown because too many files have changed in this diff Show More