diff options
author | wsnipex <wsnipex@a1.net> | 2015-01-03 09:31:29 +0100 |
---|---|---|
committer | Memphiz <memphis@machzwo.de> | 2015-01-08 21:59:01 +0100 |
commit | 1f31c0e05976e9537c814fff0a219d32dd7ffbbe (patch) | |
tree | ac145f76a6adf38ac6e6a507e4dbc0a281b94224 /tools | |
parent | dea07fa969774e107d41784e5d5117af9a978d16 (diff) |
[libsquish] - move libsquish to native depends
Diffstat (limited to 'tools')
42 files changed, 7097 insertions, 0 deletions
diff --git a/tools/depends/native/libsquish-native/Makefile b/tools/depends/native/libsquish-native/Makefile new file mode 100644 index 0000000000..7bf6e5e5b6 --- /dev/null +++ b/tools/depends/native/libsquish-native/Makefile @@ -0,0 +1,46 @@ +DEPS= ../../Makefile.include.in Makefile +ROOT_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) +-include ../../Makefile.include + +ifeq ($(NATIVEPREFIX),) + PREFIX = $(ROOT_DIR)/squish-install +else + PREFIX = $(NATIVEPREFIX) +endif + +ifeq ($(NATIVEPLATFORM),) + PLATFORM = native +else + PLATFORM = $(NATIVEPLATFORM) +endif + +APPNAME=squish +SOURCE=$(ROOT_DIR)/src + +DYLIB=$(PLATFORM)/libsquish.a + +all: .installed-$(PLATFORM) + +$(PLATFORM): +ifeq ($(PREFIX),) + @echo + @echo "ERROR: please set PREFIX to the xbmc install path e.g. make PREFIX=/usr/local" + @exit 1 +endif + -rm -rf $(PLATFORM)/*; mkdir -p $(PLATFORM) + cd $(PLATFORM); cp -a $(SOURCE)/* . + cd $(PLATFORM); sed "s|@PREFIX@|$(PREFIX)|" config.in > config + cd $(PLATFORM); mkdir -p $(PREFIX)/include; mkdir -p $(PREFIX)/lib/pkgconfig + +$(DYLIB): $(PLATFORM) + $(MAKE) -C $(PLATFORM) + +.installed-$(PLATFORM): $(DYLIB) + $(MAKE) -C $(PLATFORM) install + touch $@ + +clean: + $(MAKE) -C $(PLATFORM) clean + +distclean:: + rm -rf $(PLATFORM) .installed-$(PLATFORM) diff --git a/tools/depends/native/libsquish-native/src/ChangeLog b/tools/depends/native/libsquish-native/src/ChangeLog new file mode 100644 index 0000000000..ba03f4c574 --- /dev/null +++ b/tools/depends/native/libsquish-native/src/ChangeLog @@ -0,0 +1,52 @@ +1.10 +* Iterative cluster fit is now considered to be a new compression mode +* The core cluster fit is now 4x faster using contributions by Ignacio +Castano from NVIDIA +* The single colour lookup table has been halved by exploiting symmetry + +1.9 +* Added contributed SSE1 truncate implementation +* Changed use of SQUISH_USE_SSE to be 1 for SSE and 2 for SSE2 instructions +* Cluster fit is now iterative to further reduce image error + +1.8 +* Switched from using floor to trunc for much better SSE performance (again) +* Xcode build now expects libpng in /usr/local for extra/squishpng + +1.7 +* Fixed floating-point equality issue in clusterfit sort (x86 affected only) +* Implemented proper SSE(2) floor function for 50% speedup on SSE builds +* The range fit implementation now uses the correct colour metric + +1.6 +* Fixed bug in CompressImage where masked pixels were not skipped over +* DXT3 and DXT5 alpha compression now properly use the mask to ignore pixels +* Fixed major DXT1 bug that can generate unexpected transparent pixels + +1.5 +* Added CompressMasked function to handle incomplete DXT blocks more cleanly +* Added kWeightColourByAlpha flag for better quality images when alpha blending + +1.4 +* Fixed stack overflow in rangefit + +1.3 +* Worked around SSE floor implementation bug, proper fix needed! +* This release has visual studio and makefile builds that work + +1.2 +* Added provably optimal single colour compressor +* Added extra/squishgen.cpp that generates single colour lookup tables + +1.1 +* Fixed a DXT1 colour output bug +* Changed argument order for Decompress function to match Compress +* Added GetStorageRequirements function +* Added CompressImage function +* Added DecompressImage function +* Moved squishtool.cpp to extra/squishpng.cpp +* Added extra/squishtest.cpp + +1.0 +* Initial release + diff --git a/tools/depends/native/libsquish-native/src/Doxyfile b/tools/depends/native/libsquish-native/src/Doxyfile new file mode 100644 index 0000000000..3ec51e4bde --- /dev/null +++ b/tools/depends/native/libsquish-native/src/Doxyfile @@ -0,0 +1,223 @@ +# Doxyfile 1.4.6 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = squish +PROJECT_NUMBER = 1.1 +OUTPUT_DIRECTORY = docs +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 4 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +BUILTIN_STL_SUPPORT = NO +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = YES +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = NO +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = NO +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = YES +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = squish.h +FILE_PATTERNS = +RECURSIVE = NO +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = YES +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = /Applications/Graphviz.app/Contents/MacOS +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/tools/depends/native/libsquish-native/src/Makefile b/tools/depends/native/libsquish-native/src/Makefile new file mode 100644 index 0000000000..d560e0af6d --- /dev/null +++ b/tools/depends/native/libsquish-native/src/Makefile @@ -0,0 +1,33 @@ + +include config + +SRC = alpha.cpp clusterfit.cpp colourblock.cpp colourfit.cpp colourset.cpp maths.cpp rangefit.cpp singlecolourfit.cpp squish.cpp + +OBJ = $(SRC:%.cpp=%.o) + +LIB = libsquish.a + +all : $(LIB) squish.pc + +install : $(LIB) squish.pc + install squish.h $(INSTALL_DIR)/include + install libsquish.a $(INSTALL_DIR)/lib + install squish.pc $(INSTALL_DIR)/lib/pkgconfig + +uninstall: + $(RM) $(INSTALL_DIR)/include/squish.h + $(RM) $(INSTALL_DIR)/lib/libsquish.a + +$(LIB) : $(OBJ) + $(AR) cr $@ $? + ranlib $@ + +%.o : %.cpp + $(CXX) $(CPPFLAGS) -I. $(CXXFLAGS) -o$@ -c $< + +clean : + $(RM) $(OBJ) $(LIB) + +squish.pc: + sed 's|@PREFIX@|$(INSTALL_DIR)|' $@.in > $@ + diff --git a/tools/depends/native/libsquish-native/src/Makefile.in b/tools/depends/native/libsquish-native/src/Makefile.in new file mode 100644 index 0000000000..ef57bb884d --- /dev/null +++ b/tools/depends/native/libsquish-native/src/Makefile.in @@ -0,0 +1,35 @@ +ARCH=@ARCH@ + +SRCS= \ + alpha.cpp \ + clusterfit.cpp \ + colourblock.cpp \ + colourfit.cpp \ + colourset.cpp \ + maths.cpp \ + rangefit.cpp \ + singlecolourfit.cpp \ + squish.cpp + +CXXFLAGS += -I. +CXXFLAGS_FOR_BUILD += -I. +LIB = libsquish.a +NATIVE_LIB = libsquish-native.so +CLEAN_FILES += $(NATIVE_LIB) + +ifeq ($(findstring Darwin,$(shell uname -s)),Darwin) + CXXFLAGS_FOR_BUILD += @DARWIN_NATIVE_ARCH@ +endif + +all: $(LIB) + +# TexturePacker links to libsquish and needs to run on build system, so make a native flavor. +$(NATIVE_LIB): $(SRCS) +ifeq ($(findstring Darwin,$(shell uname -s)),Darwin) + $(CXX_FOR_BUILD) $(CXXFLAGS_FOR_BUILD) $(SRCS) -dynamiclib -install_name `pwd`/$(NATIVE_LIB) -o $@ +else + $(CXX_FOR_BUILD) $(CXXFLAGS_FOR_BUILD) $(SRCS) -shared -fPIC -Wl,-soname,`pwd`/$(NATIVE_LIB) -o $@ +endif + +include ../../Makefile.include +-include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS))) diff --git a/tools/depends/native/libsquish-native/src/README b/tools/depends/native/libsquish-native/src/README new file mode 100644 index 0000000000..d26b72ed5c --- /dev/null +++ b/tools/depends/native/libsquish-native/src/README @@ -0,0 +1,35 @@ +LICENSE +------- + +The squish library is distributed under the terms and conditions of the MIT +license. This license is specified at the top of each source file and must be +preserved in its entirety. + +BUILDING AND INSTALLING THE LIBRARY +----------------------------------- + +If you are using Visual Studio 2003 or above under Windows then load the Visual +Studio 2003 project in the vs7 folder. By default, the library is built using +SSE2 optimisations. To change this either change or remove the SQUISH_USE_SSE=2 +from the preprocessor symbols. + +If you are using a Mac then load the Xcode 2.2 project in the distribution. By +default, the library is built using Altivec optimisations. To change this +either change or remove SQUISH_USE_ALTIVEC=1 from the preprocessor symbols. I +guess I'll have to think about changing this for the new Intel Macs that are +rolling out... + +If you are using unix then first edit the config file in the base directory of +the distribution, enabling Altivec or SSE with the USE_ALTIVEC or USE_SSE +variables, and editing the optimisation flags passed to the C++ compiler if +necessary. Then make can be used to build the library, and make install (from +the superuser account) can be used to install (into /usr/local by default). + +REPORTING BUGS OR FEATURE REQUESTS +---------------------------------- + +Feedback can be sent to Simon Brown (the developer) at si@sjbrown.co.uk + +New releases are announced on the squish library homepage at +http://sjbrown.co.uk/?code=squish + diff --git a/tools/depends/native/libsquish-native/src/alpha.cpp b/tools/depends/native/libsquish-native/src/alpha.cpp new file mode 100644 index 0000000000..30c1f55a01 --- /dev/null +++ b/tools/depends/native/libsquish-native/src/alpha.cpp @@ -0,0 +1,349 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + + 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 "alpha.h" +#include <limits.h> +#include <algorithm> + +namespace squish { + +static int FloatToInt( float a, int limit ) +{ + // use ANSI round-to-zero behaviour to get round-to-nearest + int i = ( int )( a + 0.5f ); + + // clamp to the limit + if( i < 0 ) + i = 0; + else if( i > limit ) + i = limit; + + // done + return i; +} + +void CompressAlphaDxt3( u8 const* rgba, int mask, void* block ) +{ + u8* bytes = reinterpret_cast< u8* >( block ); + + // quantise and pack the alpha values pairwise + for( int i = 0; i < 8; ++i ) + { + // quantise down to 4 bits + float alpha1 = ( float )rgba[8*i + 3] * ( 15.0f/255.0f ); + float alpha2 = ( float )rgba[8*i + 7] * ( 15.0f/255.0f ); + int quant1 = FloatToInt( alpha1, 15 ); + int quant2 = FloatToInt( alpha2, 15 ); + + // set alpha to zero where masked + int bit1 = 1 << ( 2*i ); + int bit2 = 1 << ( 2*i + 1 ); + if( ( mask & bit1 ) == 0 ) + quant1 = 0; + if( ( mask & bit2 ) == 0 ) + quant2 = 0; + + // pack into the byte + bytes[i] = ( u8 )( quant1 | ( quant2 << 4 ) ); + } +} + +void DecompressAlphaDxt3( u8* rgba, void const* block ) +{ + u8 const* bytes = reinterpret_cast< u8 const* >( block ); + + // unpack the alpha values pairwise + for( int i = 0; i < 8; ++i ) + { + // quantise down to 4 bits + u8 quant = bytes[i]; + + // unpack the values + u8 lo = quant & 0x0f; + u8 hi = quant & 0xf0; + + // convert back up to bytes + rgba[8*i + 3] = lo | ( lo << 4 ); + rgba[8*i + 7] = hi | ( hi >> 4 ); + } +} + +static void FixRange( int& min, int& max, int steps ) +{ + if( max - min < steps ) + max = std::min( min + steps, 255 ); + if( max - min < steps ) + min = std::max( 0, max - steps ); +} + +static int FitCodes( u8 const* rgba, int mask, u8 const* codes, u8* indices ) +{ + // fit each alpha value to the codebook + int err = 0; + for( int i = 0; i < 16; ++i ) + { + // check this pixel is valid + int bit = 1 << i; + if( ( mask & bit ) == 0 ) + { + // use the first code + indices[i] = 0; + continue; + } + + // find the least error and corresponding index + int value = rgba[4*i + 3]; + int least = INT_MAX; + int index = 0; + for( int j = 0; j < 8; ++j ) + { + // get the squared error from this code + int dist = ( int )value - ( int )codes[j]; + dist *= dist; + + // compare with the best so far + if( dist < least ) + { + least = dist; + index = j; + } + } + + // save this index and accumulate the error + indices[i] = ( u8 )index; + err += least; + } + + // return the total error + return err; +} + +static void WriteAlphaBlock( int alpha0, int alpha1, u8 const* indices, void* block ) +{ + u8* bytes = reinterpret_cast< u8* >( block ); + + // write the first two bytes + bytes[0] = ( u8 )alpha0; + bytes[1] = ( u8 )alpha1; + + // pack the indices with 3 bits each + u8* dest = bytes + 2; + u8 const* src = indices; + for( int i = 0; i < 2; ++i ) + { + // pack 8 3-bit values + int value = 0; + for( int j = 0; j < 8; ++j ) + { + int index = *src++; + value |= ( index << 3*j ); + } + + // store in 3 bytes + for( int j = 0; j < 3; ++j ) + { + int byte = ( value >> 8*j ) & 0xff; + *dest++ = ( u8 )byte; + } + } +} + +static void WriteAlphaBlock5( int alpha0, int alpha1, u8 const* indices, void* block ) +{ + // check the relative values of the endpoints + if( alpha0 > alpha1 ) + { + // swap the indices + u8 swapped[16]; + for( int i = 0; i < 16; ++i ) + { + u8 index = indices[i]; + if( index == 0 ) + swapped[i] = 1; + else if( index == 1 ) + swapped[i] = 0; + else if( index <= 5 ) + swapped[i] = 7 - index; + else + swapped[i] = index; + } + + // write the block + WriteAlphaBlock( alpha1, alpha0, swapped, block ); + } + else + { + // write the block + WriteAlphaBlock( alpha0, alpha1, indices, block ); + } +} + +static void WriteAlphaBlock7( int alpha0, int alpha1, u8 const* indices, void* block ) +{ + // check the relative values of the endpoints + if( alpha0 < alpha1 ) + { + // swap the indices + u8 swapped[16]; + for( int i = 0; i < 16; ++i ) + { + u8 index = indices[i]; + if( index == 0 ) + swapped[i] = 1; + else if( index == 1 ) + swapped[i] = 0; + else + swapped[i] = 9 - index; + } + + // write the block + WriteAlphaBlock( alpha1, alpha0, swapped, block ); + } + else + { + // write the block + WriteAlphaBlock( alpha0, alpha1, indices, block ); + } +} + +void CompressAlphaDxt5( u8 const* rgba, int mask, void* block ) +{ + // get the range for 5-alpha and 7-alpha interpolation + int min5 = 255; + int max5 = 0; + int min7 = 255; + int max7 = 0; + for( int i = 0; i < 16; ++i ) + { + // check this pixel is valid + int bit = 1 << i; + if( ( mask & bit ) == 0 ) + continue; + + // incorporate into the min/max + int value = rgba[4*i + 3]; + if( value < min7 ) + min7 = value; + if( value > max7 ) + max7 = value; + if( value != 0 && value < min5 ) + min5 = value; + if( value != 255 && value > max5 ) + max5 = value; + } + + // handle the case that no valid range was found + if( min5 > max5 ) + min5 = max5; + if( min7 > max7 ) + min7 = max7; + + // fix the range to be the minimum in each case + FixRange( min5, max5, 5 ); + FixRange( min7, max7, 7 ); + + // set up the 5-alpha code book + u8 codes5[8]; + codes5[0] = ( u8 )min5; + codes5[1] = ( u8 )max5; + for( int i = 1; i < 5; ++i ) + codes5[1 + i] = ( u8 )( ( ( 5 - i )*min5 + i*max5 )/5 ); + codes5[6] = 0; + codes5[7] = 255; + + // set up the 7-alpha code book + u8 codes7[8]; + codes7[0] = ( u8 )min7; + codes7[1] = ( u8 )max7; + for( int i = 1; i < 7; ++i ) + codes7[1 + i] = ( u8 )( ( ( 7 - i )*min7 + i*max7 )/7 ); + + // fit the data to both code books + u8 indices5[16]; + u8 indices7[16]; + int err5 = FitCodes( rgba, mask, codes5, indices5 ); + int err7 = FitCodes( rgba, mask, codes7, indices7 ); + + // save the block with least error + if( err5 <= err7 ) + WriteAlphaBlock5( min5, max5, indices5, block ); + else + WriteAlphaBlock7( min7, max7, indices7, block ); +} + +void DecompressAlphaDxt5( u8* rgba, void const* block ) +{ + // get the two alpha values + u8 const* bytes = reinterpret_cast< u8 const* >( block ); + int alpha0 = bytes[0]; + int alpha1 = bytes[1]; + + // compare the values to build the codebook + u8 codes[8]; + codes[0] = ( u8 )alpha0; + codes[1] = ( u8 )alpha1; + if( alpha0 <= alpha1 ) + { + // use 5-alpha codebook + for( int i = 1; i < 5; ++i ) + codes[1 + i] = ( u8 )( ( ( 5 - i )*alpha0 + i*alpha1 )/5 ); + codes[6] = 0; + codes[7] = 255; + } + else + { + // use 7-alpha codebook + for( int i = 1; i < 7; ++i ) + codes[1 + i] = ( u8 )( ( ( 7 - i )*alpha0 + i*alpha1 )/7 ); + } + + // decode the indices + u8 indices[16]; + u8 const* src = bytes + 2; + u8* dest = indices; + for( int i = 0; i < 2; ++i ) + { + // grab 3 bytes + int value = 0; + for( int j = 0; j < 3; ++j ) + { + int byte = *src++; + value |= ( byte << 8*j ); + } + + // unpack 8 3-bit values from it + for( int j = 0; j < 8; ++j ) + { + int index = ( value >> 3*j ) & 0x7; + *dest++ = ( u8 )index; + } + } + + // write out the indexed codebook values + for( int i = 0; i < 16; ++i ) + rgba[4*i + 3] = codes[indices[i]]; +} + +} // namespace squish diff --git a/tools/depends/native/libsquish-native/src/alpha.h b/tools/depends/native/libsquish-native/src/alpha.h new file mode 100644 index 0000000000..5736052551 --- /dev/null +++ b/tools/depends/native/libsquish-native/src/alpha.h @@ -0,0 +1,41 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + + 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 SQUISH_ALPHA_H +#define SQUISH_ALPHA_H + +#include <squish.h> + +namespace squish { + +void CompressAlphaDxt3( u8 const* rgba, int mask, void* block ); +void CompressAlphaDxt5( u8 const* rgba, int mask, void* block ); + +void DecompressAlphaDxt3( u8* rgba, void const* block ); +void DecompressAlphaDxt5( u8* rgba, void const* block ); + +} // namespace squish + +#endif // ndef SQUISH_ALPHA_H diff --git a/tools/depends/native/libsquish-native/src/clusterfit.cpp b/tools/depends/native/libsquish-native/src/clusterfit.cpp new file mode 100644 index 0000000000..96704460ec --- /dev/null +++ b/tools/depends/native/libsquish-native/src/clusterfit.cpp @@ -0,0 +1,392 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + Copyright (c) 2007 Ignacio Castano icastano@nvidia.com + + 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 "clusterfit.h" +#include "colourset.h" +#include "colourblock.h" +#include <cfloat> + +namespace squish { + +ClusterFit::ClusterFit( ColourSet const* colours, int flags, float* metric ) + : ColourFit( colours, flags ) +{ + // set the iteration count + m_iterationCount = ( m_flags & kColourIterativeClusterFit ) ? kMaxIterations : 1; + + // initialise the metric (old perceptual = 0.2126f, 0.7152f, 0.0722f) + if( metric ) + m_metric = Vec4( metric[0], metric[1], metric[2], 1.0f ); + else + m_metric = VEC4_CONST( 1.0f ); + + // initialise the best error + m_besterror = VEC4_CONST( FLT_MAX ); + + // cache some values + int const count = m_colours->GetCount(); + Vec3 const* values = m_colours->GetPoints(); + + // get the covariance matrix + Sym3x3 covariance = ComputeWeightedCovariance( count, values, m_colours->GetWeights() ); + + // compute the principle component + m_principle = ComputePrincipleComponent( covariance ); +} + +bool ClusterFit::ConstructOrdering( Vec3 const& axis, int iteration ) +{ + // cache some values + int const count = m_colours->GetCount(); + Vec3 const* values = m_colours->GetPoints(); + + // build the list of dot products + float dps[16]; + u8* order = ( u8* )m_order + 16*iteration; + for( int i = 0; i < count; ++i ) + { + dps[i] = Dot( values[i], axis ); + order[i] = ( u8 )i; + } + + // stable sort using them + for( int i = 0; i < count; ++i ) + { + for( int j = i; j > 0 && dps[j] < dps[j - 1]; --j ) + { + std::swap( dps[j], dps[j - 1] ); + std::swap( order[j], order[j - 1] ); + } + } + + // check this ordering is unique + for( int it = 0; it < iteration; ++it ) + { + u8 const* prev = ( u8* )m_order + 16*it; + bool same = true; + for( int i = 0; i < count; ++i ) + { + if( order[i] != prev[i] ) + { + same = false; + break; + } + } + if( same ) + return false; + } + + // copy the ordering and weight all the points + Vec3 const* unweighted = m_colours->GetPoints(); + float const* weights = m_colours->GetWeights(); + m_xsum_wsum = VEC4_CONST( 0.0f ); + for( int i = 0; i < count; ++i ) + { + int j = order[i]; + Vec4 p( unweighted[j].X(), unweighted[j].Y(), unweighted[j].Z(), 1.0f ); + Vec4 w( weights[j] ); + Vec4 x = p*w; + m_points_weights[i] = x; + m_xsum_wsum += x; + } + return true; +} + +void ClusterFit::Compress3( void* block ) +{ + // declare variables + int const count = m_colours->GetCount(); + Vec4 const two = VEC4_CONST( 2.0 ); + Vec4 const one = VEC4_CONST( 1.0f ); + Vec4 const half_half2( 0.5f, 0.5f, 0.5f, 0.25f ); + Vec4 const zero = VEC4_CONST( 0.0f ); + Vec4 const half = VEC4_CONST( 0.5f ); + Vec4 const grid( 31.0f, 63.0f, 31.0f, 0.0f ); + Vec4 const gridrcp( 1.0f/31.0f, 1.0f/63.0f, 1.0f/31.0f, 0.0f ); + + // prepare an ordering using the principle axis + ConstructOrdering( m_principle, 0 ); + + // check all possible clusters and iterate on the total order + Vec4 beststart = VEC4_CONST( 0.0f ); + Vec4 bestend = VEC4_CONST( 0.0f ); + Vec4 besterror = m_besterror; + u8 bestindices[16]; + int bestiteration = 0; + int besti = 0, bestj = 0; + + // loop over iterations (we avoid the case that all points in first or last cluster) + for( int iterationIndex = 0;; ) + { + // first cluster [0,i) is at the start + Vec4 part0 = VEC4_CONST( 0.0f ); + for( int i = 0; i < count; ++i ) + { + // second cluster [i,j) is half along + Vec4 part1 = ( i == 0 ) ? m_points_weights[0] : VEC4_CONST( 0.0f ); + int jmin = ( i == 0 ) ? 1 : i; + for( int j = jmin;; ) + { + // last cluster [j,count) is at the end + Vec4 part2 = m_xsum_wsum - part1 - part0; + + // compute least squares terms directly + Vec4 alphax_sum = MultiplyAdd( part1, half_half2, part0 ); + Vec4 alpha2_sum = alphax_sum.SplatW(); + + Vec4 betax_sum = MultiplyAdd( part1, half_half2, part2 ); + Vec4 beta2_sum = betax_sum.SplatW(); + + Vec4 alphabeta_sum = ( part1*half_half2 ).SplatW(); + + // compute the least-squares optimal points + Vec4 factor = Reciprocal( NegativeMultiplySubtract( alphabeta_sum, alphabeta_sum, alpha2_sum*beta2_sum ) ); + Vec4 a = NegativeMultiplySubtract( betax_sum, alphabeta_sum, alphax_sum*beta2_sum )*factor; + Vec4 b = NegativeMultiplySubtract( alphax_sum, alphabeta_sum, betax_sum*alpha2_sum )*factor; + + // clamp to the grid + a = Min( one, Max( zero, a ) ); + b = Min( one, Max( zero, b ) ); + a = Truncate( MultiplyAdd( grid, a, half ) )*gridrcp; + b = Truncate( MultiplyAdd( grid, b, half ) )*gridrcp; + + // compute the error (we skip the constant xxsum) + Vec4 e1 = MultiplyAdd( a*a, alpha2_sum, b*b*beta2_sum ); + Vec4 e2 = NegativeMultiplySubtract( a, alphax_sum, a*b*alphabeta_sum ); + Vec4 e3 = NegativeMultiplySubtract( b, betax_sum, e2 ); + Vec4 e4 = MultiplyAdd( two, e3, e1 ); + + // apply the metric to the error term + Vec4 e5 = e4*m_metric; + Vec4 error = e5.SplatX() + e5.SplatY() + e5.SplatZ(); + + // keep the solution if it wins + if( CompareAnyLessThan( error, besterror ) ) + { + beststart = a; + bestend = b; + besti = i; + bestj = j; + besterror = error; + bestiteration = iterationIndex; + } + + // advance + if( j == count ) + break; + part1 += m_points_weights[j]; + ++j; + } + + // advance + part0 += m_points_weights[i]; + } + + // stop if we didn't improve in this iteration + if( bestiteration != iterationIndex ) + break; + + // advance if possible + ++iterationIndex; + if( iterationIndex == m_iterationCount ) + break; + + // stop if a new iteration is an ordering that has already been tried + Vec3 axis = ( bestend - beststart ).GetVec3(); + if( !ConstructOrdering( axis, iterationIndex ) ) + break; + } + + // save the block if necessary + if( CompareAnyLessThan( besterror, m_besterror ) ) + { + // remap the indices + u8 const* order = ( u8* )m_order + 16*bestiteration; + + u8 unordered[16]; + for( int m = 0; m < besti; ++m ) + unordered[order[m]] = 0; + for( int m = besti; m < bestj; ++m ) + unordered[order[m]] = 2; + for( int m = bestj; m < count; ++m ) + unordered[order[m]] = 1; + + m_colours->RemapIndices( unordered, bestindices ); + + // save the block + WriteColourBlock3( beststart.GetVec3(), bestend.GetVec3(), bestindices, block ); + + // save the error + m_besterror = besterror; + } +} + +void ClusterFit::Compress4( void* block ) +{ + // declare variables + int const count = m_colours->GetCount(); + Vec4 const two = VEC4_CONST( 2.0f ); + Vec4 const one = VEC4_CONST( 1.0f ); + Vec4 const onethird_onethird2( 1.0f/3.0f, 1.0f/3.0f, 1.0f/3.0f, 1.0f/9.0f ); + Vec4 const twothirds_twothirds2( 2.0f/3.0f, 2.0f/3.0f, 2.0f/3.0f, 4.0f/9.0f ); + Vec4 const twonineths = VEC4_CONST( 2.0f/9.0f ); + Vec4 const zero = VEC4_CONST( 0.0f ); + Vec4 const half = VEC4_CONST( 0.5f ); + Vec4 const grid( 31.0f, 63.0f, 31.0f, 0.0f ); + Vec4 const gridrcp( 1.0f/31.0f, 1.0f/63.0f, 1.0f/31.0f, 0.0f ); + + // prepare an ordering using the principle axis + ConstructOrdering( m_principle, 0 ); + + // check all possible clusters and iterate on the total order + Vec4 beststart = VEC4_CONST( 0.0f ); + Vec4 bestend = VEC4_CONST( 0.0f ); + Vec4 besterror = m_besterror; + u8 bestindices[16]; + int bestiteration = 0; + int besti = 0, bestj = 0, bestk = 0; + + // loop over iterations (we avoid the case that all points in first or last cluster) + for( int iterationIndex = 0;; ) + { + // first cluster [0,i) is at the start + Vec4 part0 = VEC4_CONST( 0.0f ); + for( int i = 0; i < count; ++i ) + { + // second cluster [i,j) is one third along + Vec4 part1 = VEC4_CONST( 0.0f ); + for( int j = i;; ) + { + // third cluster [j,k) is two thirds along + Vec4 part2 = ( j == 0 ) ? m_points_weights[0] : VEC4_CONST( 0.0f ); + int kmin = ( j == 0 ) ? 1 : j; + for( int k = kmin;; ) + { + // last cluster [k,count) is at the end + Vec4 part3 = m_xsum_wsum - part2 - part1 - part0; + + // compute least squares terms directly + Vec4 const alphax_sum = MultiplyAdd( part2, onethird_onethird2, MultiplyAdd( part1, twothirds_twothirds2, part0 ) ); + Vec4 const alpha2_sum = alphax_sum.SplatW(); + + Vec4 const betax_sum = MultiplyAdd( part1, onethird_onethird2, MultiplyAdd( part2, twothirds_twothirds2, part3 ) ); + Vec4 const beta2_sum = betax_sum.SplatW(); + + Vec4 const alphabeta_sum = twonineths*( part1 + part2 ).SplatW(); + + // compute the least-squares optimal points + Vec4 factor = Reciprocal( NegativeMultiplySubtract( alphabeta_sum, alphabeta_sum, alpha2_sum*beta2_sum ) ); + Vec4 a = NegativeMultiplySubtract( betax_sum, alphabeta_sum, alphax_sum*beta2_sum )*factor; + Vec4 b = NegativeMultiplySubtract( alphax_sum, alphabeta_sum, betax_sum*alpha2_sum )*factor; + + // clamp to the grid + a = Min( one, Max( zero, a ) ); + b = Min( one, Max( zero, b ) ); + a = Truncate( MultiplyAdd( grid, a, half ) )*gridrcp; + b = Truncate( MultiplyAdd( grid, b, half ) )*gridrcp; + + // compute the error (we skip the constant xxsum) + Vec4 e1 = MultiplyAdd( a*a, alpha2_sum, b*b*beta2_sum ); + Vec4 e2 = NegativeMultiplySubtract( a, alphax_sum, a*b*alphabeta_sum ); + Vec4 e3 = NegativeMultiplySubtract( b, betax_sum, e2 ); + Vec4 e4 = MultiplyAdd( two, e3, e1 ); + + // apply the metric to the error term + Vec4 e5 = e4*m_metric; + Vec4 error = e5.SplatX() + e5.SplatY() + e5.SplatZ(); + + // keep the solution if it wins + if( CompareAnyLessThan( error, besterror ) ) + { + beststart = a; + bestend = b; + besterror = error; + besti = i; + bestj = j; + bestk = k; + bestiteration = iterationIndex; + } + + // advance + if( k == count ) + break; + part2 += m_points_weights[k]; + ++k; + } + + // advance + if( j == count ) + break; + part1 += m_points_weights[j]; + ++j; + } + + // advance + part0 += m_points_weights[i]; + } + + // stop if we didn't improve in this iteration + if( bestiteration != iterationIndex ) + break; + + // advance if possible + ++iterationIndex; + if( iterationIndex == m_iterationCount ) + break; + + // stop if a new iteration is an ordering that has already been tried + Vec3 axis = ( bestend - beststart ).GetVec3(); + if( !ConstructOrdering( axis, iterationIndex ) ) + break; + } + + // save the block if necessary + if( CompareAnyLessThan( besterror, m_besterror ) ) + { + // remap the indices + u8 const* order = ( u8* )m_order + 16*bestiteration; + + u8 unordered[16]; + for( int m = 0; m < besti; ++m ) + unordered[order[m]] = 0; + for( int m = besti; m < bestj; ++m ) + unordered[order[m]] = 2; + for( int m = bestj; m < bestk; ++m ) + unordered[order[m]] = 3; + for( int m = bestk; m < count; ++m ) + unordered[order[m]] = 1; + + m_colours->RemapIndices( unordered, bestindices ); + + // save the block + WriteColourBlock4( beststart.GetVec3(), bestend.GetVec3(), bestindices, block ); + + // save the error + m_besterror = besterror; + } +} + +} // namespace squish diff --git a/tools/depends/native/libsquish-native/src/clusterfit.h b/tools/depends/native/libsquish-native/src/clusterfit.h new file mode 100644 index 0000000000..ef5959c45a --- /dev/null +++ b/tools/depends/native/libsquish-native/src/clusterfit.h @@ -0,0 +1,61 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + Copyright (c) 2007 Ignacio Castano icastano@nvidia.com + + 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 SQUISH_CLUSTERFIT_H +#define SQUISH_CLUSTERFIT_H + +#include <squish.h> +#include "maths.h" +#include "simd.h" +#include "colourfit.h" + +namespace squish { + +class ClusterFit : public ColourFit +{ +public: + ClusterFit( ColourSet const* colours, int flags, float* metric ); + +private: + bool ConstructOrdering( Vec3 const& axis, int iteration ); + + virtual void Compress3( void* block ); + virtual void Compress4( void* block ); + + enum { kMaxIterations = 8 }; + + int m_iterationCount; + Vec3 m_principle; + u8 m_order[16*kMaxIterations]; + Vec4 m_points_weights[16]; + Vec4 m_xsum_wsum; + Vec4 m_metric; + Vec4 m_besterror; +}; + +} // namespace squish + +#endif // ndef SQUISH_CLUSTERFIT_H diff --git a/tools/depends/native/libsquish-native/src/colourblock.cpp b/tools/depends/native/libsquish-native/src/colourblock.cpp new file mode 100644 index 0000000000..e6a5788b74 --- /dev/null +++ b/tools/depends/native/libsquish-native/src/colourblock.cpp @@ -0,0 +1,214 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + + 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 "colourblock.h" + +namespace squish { + +static int FloatToInt( float a, int limit ) +{ + // use ANSI round-to-zero behaviour to get round-to-nearest + int i = ( int )( a + 0.5f ); + + // clamp to the limit + if( i < 0 ) + i = 0; + else if( i > limit ) + i = limit; + + // done + return i; +} + +static int FloatTo565( Vec3::Arg colour ) +{ + // get the components in the correct range + int r = FloatToInt( 31.0f*colour.X(), 31 ); + int g = FloatToInt( 63.0f*colour.Y(), 63 ); + int b = FloatToInt( 31.0f*colour.Z(), 31 ); + + // pack into a single value + return ( r << 11 ) | ( g << 5 ) | b; +} + +static void WriteColourBlock( int a, int b, u8* indices, void* block ) +{ + // get the block as bytes + u8* bytes = ( u8* )block; + + // write the endpoints + bytes[0] = ( u8 )( a & 0xff ); + bytes[1] = ( u8 )( a >> 8 ); + bytes[2] = ( u8 )( b & 0xff ); + bytes[3] = ( u8 )( b >> 8 ); + + // write the indices + for( int i = 0; i < 4; ++i ) + { + u8 const* ind = indices + 4*i; + bytes[4 + i] = ind[0] | ( ind[1] << 2 ) | ( ind[2] << 4 ) | ( ind[3] << 6 ); + } +} + +void WriteColourBlock3( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* block ) +{ + // get the packed values + int a = FloatTo565( start ); + int b = FloatTo565( end ); + + // remap the indices + u8 remapped[16]; + if( a <= b ) + { + // use the indices directly + for( int i = 0; i < 16; ++i ) + remapped[i] = indices[i]; + } + else + { + // swap a and b + std::swap( a, b ); + for( int i = 0; i < 16; ++i ) + { + if( indices[i] == 0 ) + remapped[i] = 1; + else if( indices[i] == 1 ) + remapped[i] = 0; + else + remapped[i] = indices[i]; + } + } + + // write the block + WriteColourBlock( a, b, remapped, block ); +} + +void WriteColourBlock4( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* block ) +{ + // get the packed values + int a = FloatTo565( start ); + int b = FloatTo565( end ); + + // remap the indices + u8 remapped[16]; + if( a < b ) + { + // swap a and b + std::swap( a, b ); + for( int i = 0; i < 16; ++i ) + remapped[i] = ( indices[i] ^ 0x1 ) & 0x3; + } + else if( a == b ) + { + // use index 0 + for( int i = 0; i < 16; ++i ) + remapped[i] = 0; + } + else + { + // use the indices directly + for( int i = 0; i < 16; ++i ) + remapped[i] = indices[i]; + } + + // write the block + WriteColourBlock( a, b, remapped, block ); +} + +static int Unpack565( u8 const* packed, u8* colour ) +{ + // build the packed value + int value = ( int )packed[0] | ( ( int )packed[1] << 8 ); + + // get the components in the stored range + u8 red = ( u8 )( ( value >> 11 ) & 0x1f ); + u8 green = ( u8 )( ( value >> 5 ) & 0x3f ); + u8 blue = ( u8 )( value & 0x1f ); + + // scale up to 8 bits + colour[0] = ( red << 3 ) | ( red >> 2 ); + colour[1] = ( green << 2 ) | ( green >> 4 ); + colour[2] = ( blue << 3 ) | ( blue >> 2 ); + colour[3] = 255; + + // return the value + return value; +} + +void DecompressColour( u8* rgba, void const* block, bool isDxt1 ) +{ + // get the block bytes + u8 const* bytes = reinterpret_cast< u8 const* >( block ); + + // unpack the endpoints + u8 codes[16]; + int a = Unpack565( bytes, codes ); + int b = Unpack565( bytes + 2, codes + 4 ); + + // generate the midpoints + for( int i = 0; i < 3; ++i ) + { + int c = codes[i]; + int d = codes[4 + i]; + + if( isDxt1 && a <= b ) + { + codes[8 + i] = ( u8 )( ( c + d )/2 ); + codes[12 + i] = 0; + } + else + { + codes[8 + i] = ( u8 )( ( 2*c + d )/3 ); + codes[12 + i] = ( u8 )( ( c + 2*d )/3 ); + } + } + + // fill in alpha for the intermediate values + codes[8 + 3] = 255; + codes[12 + 3] = ( isDxt1 && a <= b ) ? 0 : 255; + + // unpack the indices + u8 indices[16]; + for( int i = 0; i < 4; ++i ) + { + u8* ind = indices + 4*i; + u8 packed = bytes[4 + i]; + + ind[0] = packed & 0x3; + ind[1] = ( packed >> 2 ) & 0x3; + ind[2] = ( packed >> 4 ) & 0x3; + ind[3] = ( packed >> 6 ) & 0x3; + } + + // store out the colours + for( int i = 0; i < 16; ++i ) + { + u8 offset = 4*indices[i]; + for( int j = 0; j < 4; ++j ) + rgba[4*i + j] = codes[offset + j]; + } +} + +} // namespace squish diff --git a/tools/depends/native/libsquish-native/src/colourblock.h b/tools/depends/native/libsquish-native/src/colourblock.h new file mode 100644 index 0000000000..df0a47217f --- /dev/null +++ b/tools/depends/native/libsquish-native/src/colourblock.h @@ -0,0 +1,41 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + + 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 SQUISH_COLOURBLOCK_H +#define SQUISH_COLOURBLOCK_H + +#include <squish.h> +#include "maths.h" + +namespace squish { + +void WriteColourBlock3( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* block ); +void WriteColourBlock4( Vec3::Arg start, Vec3::Arg end, u8 const* indices, void* block ); + +void DecompressColour( u8* rgba, void const* block, bool isDxt1 ); + +} // namespace squish + +#endif // ndef SQUISH_COLOURBLOCK_H diff --git a/tools/depends/native/libsquish-native/src/colourfit.cpp b/tools/depends/native/libsquish-native/src/colourfit.cpp new file mode 100644 index 0000000000..11efa46748 --- /dev/null +++ b/tools/depends/native/libsquish-native/src/colourfit.cpp @@ -0,0 +1,54 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + + 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 "colourfit.h" +#include "colourset.h" + +namespace squish { + +ColourFit::ColourFit( ColourSet const* colours, int flags ) + : m_colours( colours ), + m_flags( flags ) +{ +} + +ColourFit::~ColourFit() +{ +} + +void ColourFit::Compress( void* block ) +{ + bool isDxt1 = ( ( m_flags & kDxt1 ) != 0 ); + if( isDxt1 ) + { + Compress3( block ); + if( !m_colours->IsTransparent() ) + Compress4( block ); + } + else + Compress4( block ); +} + +} // namespace squish diff --git a/tools/depends/native/libsquish-native/src/colourfit.h b/tools/depends/native/libsquish-native/src/colourfit.h new file mode 100644 index 0000000000..5b684a923a --- /dev/null +++ b/tools/depends/native/libsquish-native/src/colourfit.h @@ -0,0 +1,55 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + + 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 SQUISH_COLOURFIT_H +#define SQUISH_COLOURFIT_H + +#include <squish.h> +#include <limits.h> +#include "maths.h" + +namespace squish { + +class ColourSet; + +class ColourFit +{ +public: + ColourFit( ColourSet const* colours, int flags ); + virtual ~ColourFit(); + + void Compress( void* block ); + +protected: + virtual void Compress3( void* block ) = 0; + virtual void Compress4( void* block ) = 0; + + ColourSet const* m_colours; + int m_flags; +}; + +} // namespace squish + +#endif // ndef SQUISH_COLOURFIT_H diff --git a/tools/depends/native/libsquish-native/src/colourset.cpp b/tools/depends/native/libsquish-native/src/colourset.cpp new file mode 100644 index 0000000000..97d29d9873 --- /dev/null +++ b/tools/depends/native/libsquish-native/src/colourset.cpp @@ -0,0 +1,121 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + + 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 "colourset.h" + +namespace squish { + +ColourSet::ColourSet( u8 const* rgba, int mask, int flags ) + : m_count( 0 ), + m_transparent( false ) +{ + // check the compression mode for dxt1 + bool isDxt1 = ( ( flags & kDxt1 ) != 0 ); + bool weightByAlpha = ( ( flags & kWeightColourByAlpha ) != 0 ); + + // create the minimal set + for( int i = 0; i < 16; ++i ) + { + // check this pixel is enabled + int bit = 1 << i; + if( ( mask & bit ) == 0 ) + { + m_remap[i] = -1; + continue; + } + + // check for transparent pixels when using dxt1 + if( isDxt1 && rgba[4*i + 3] < 128 ) + { + m_remap[i] = -1; + m_transparent = true; + continue; + } + + // loop over previous points for a match + for( int j = 0;; ++j ) + { + // allocate a new point + if( j == i ) + { + // normalise coordinates to [0,1] + float x = ( float )rgba[4*i] / 255.0f; + float y = ( float )rgba[4*i + 1] / 255.0f; + float z = ( float )rgba[4*i + 2] / 255.0f; + + // ensure there is always non-zero weight even for zero alpha + float w = ( float )( rgba[4*i + 3] + 1 ) / 256.0f; + + // add the point + m_points[m_count] = Vec3( x, y, z ); + m_weights[m_count] = ( weightByAlpha ? w : 1.0f ); + m_remap[i] = m_count; + + // advance + ++m_count; + break; + } + + // check for a match + int oldbit = 1 << j; + bool match = ( ( mask & oldbit ) != 0 ) + && ( rgba[4*i] == rgba[4*j] ) + && ( rgba[4*i + 1] == rgba[4*j + 1] ) + && ( rgba[4*i + 2] == rgba[4*j + 2] ) + && ( rgba[4*j + 3] >= 128 || !isDxt1 ); + if( match ) + { + // get the index of the match + int index = m_remap[j]; + + // ensure there is always non-zero weight even for zero alpha + float w = ( float )( rgba[4*i + 3] + 1 ) / 256.0f; + + // map to this point and increase the weight + m_weights[index] += ( weightByAlpha ? w : 1.0f ); + m_remap[i] = index; + break; + } + } + } + + // square root the weights + for( int i = 0; i < m_count; ++i ) + m_weights[i] = std::sqrt( m_weights[i] ); +} + +void ColourSet::RemapIndices( u8 const* source, u8* target ) const +{ + for( int i = 0; i < 16; ++i ) + { + int j = m_remap[i]; + if( j == -1 ) + target[i] = 3; + else + target[i] = source[j]; + } +} + +} // namespace squish diff --git a/tools/depends/native/libsquish-native/src/colourset.h b/tools/depends/native/libsquish-native/src/colourset.h new file mode 100644 index 0000000000..dcf56ae28e --- /dev/null +++ b/tools/depends/native/libsquish-native/src/colourset.h @@ -0,0 +1,58 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + + 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 SQUISH_COLOURSET_H +#define SQUISH_COLOURSET_H + +#include <squish.h> +#include "maths.h" + +namespace squish { + +/*! @brief Represents a set of block colours +*/ +class ColourSet +{ +public: + ColourSet( u8 const* rgba, int mask, int flags ); + + int GetCount() const { return m_count; } + Vec3 const* GetPoints() const { return m_points; } + float const* GetWeights() const { return m_weights; } + bool IsTransparent() const { return m_transparent; } + + void RemapIndices( u8 const* source, u8* target ) const; + +private: + int m_count; + Vec3 m_points[16]; + float m_weights[16]; + int m_remap[16]; + bool m_transparent; +}; + +} // namespace sqish + +#endif // ndef SQUISH_COLOURSET_H diff --git a/tools/depends/native/libsquish-native/src/config.h b/tools/depends/native/libsquish-native/src/config.h new file mode 100644 index 0000000000..00a2d068bf --- /dev/null +++ b/tools/depends/native/libsquish-native/src/config.h @@ -0,0 +1,59 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + + 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 SQUISH_CONFIG_H +#define SQUISH_CONFIG_H + +// Set to 1 when building squish to use Altivec instructions. +#ifndef SQUISH_USE_ALTIVEC +#if defined(__ALTIVEC__) +#define SQUISH_USE_ALTIVEC 1 +#else +#define SQUISH_USE_ALTIVEC 0 +#endif +#endif + +// Set to 1 or 2 when building squish to use SSE or SSE2 instructions. +#ifndef SQUISH_USE_SSE +#if defined(__SSE2__) +#define SQUISH_USE_SSE 2 +#elif defined(__SSE__) +#define SQUISH_USE_SSE 1 +#else +#define SQUISH_USE_SSE 0 +#endif +#endif + +// Internally set SQUISH_USE_SIMD when either Altivec or SSE is available. +#if SQUISH_USE_ALTIVEC && SQUISH_USE_SSE +#error "Cannot enable both Altivec and SSE!" +#endif +#if SQUISH_USE_ALTIVEC || SQUISH_USE_SSE +#define SQUISH_USE_SIMD 1 +#else +#define SQUISH_USE_SIMD 0 +#endif + +#endif // ndef SQUISH_CONFIG_H diff --git a/tools/depends/native/libsquish-native/src/config.in b/tools/depends/native/libsquish-native/src/config.in new file mode 100644 index 0000000000..fdca022003 --- /dev/null +++ b/tools/depends/native/libsquish-native/src/config.in @@ -0,0 +1,21 @@ +# config file used for the Makefile only + +# define to 1 to use Altivec instructions +USE_ALTIVEC ?= 0 + +# define to 1 to use SSE2 instructions +USE_SSE ?= 0 + +# default flags +CXXFLAGS ?= -O2 +ifeq ($(USE_ALTIVEC),1) +CPPFLAGS += -DSQUISH_USE_ALTIVEC=1 +CXXFLAGS += -maltivec +endif +ifeq ($(USE_SSE),1) +CPPFLAGS += -DSQUISH_USE_SSE=2 +CXXFLAGS += -msse +endif + +# where should we install to +INSTALL_DIR ?= @PREFIX@ diff --git a/tools/depends/native/libsquish-native/src/extra/squishgen.cpp b/tools/depends/native/libsquish-native/src/extra/squishgen.cpp new file mode 100644 index 0000000000..d7d1ee0d90 --- /dev/null +++ b/tools/depends/native/libsquish-native/src/extra/squishgen.cpp @@ -0,0 +1,151 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + + 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 <iostream> + +struct SourceBlock +{ + int start; + int end; + int error; +}; + +struct TargetValue +{ + SourceBlock sources[2]; +}; + +static void GenerateData( std::string const& name, int bits, int colours ) +{ + TargetValue values[256]; + + // initialise the data + for( int target = 0; target < 256; ++target ) + for( int index = 0; index < colours; ++index ) + values[target].sources[index].error = 255; + + // loop over all possible source points + int count = ( 1 << bits ); + for( int value1 = 0; value1 < count; ++value1 ) + { + for( int value2 = 0; value2 < count; ++value2 ) + { + // compute the 8-bit endpoints + int a = ( value1 << ( 8 - bits ) ) | ( value1 >> ( 2*bits - 8 ) ); + int b = ( value2 << ( 8 - bits ) ) | ( value2 >> ( 2*bits - 8 ) ); + + // fill in the codebook with the these and intermediates + int codes[2]; + codes[0] = a; + if( colours == 3 ) + codes[1] = ( a + b )/2; + else + codes[1] = ( 2*a + b )/3; + + // mark each target point with the endpoints and index needed for it + for( int index = 0; index < 2; ++index ) + { + int target = codes[index]; + + SourceBlock& block = values[target].sources[index]; + if( block.error != 0 ) + { + block.start = value1; + block.end = value2; + block.error = 0; + } + } + } + } + + // iteratively fill in the missing values + for( ;; ) + { + bool stable = true; + for( int index = 0; index < 2; ++index ) + { + for( int target = 0; target < 256; ++target ) + { + if( target != 255 ) + { + SourceBlock& current = values[target].sources[index]; + SourceBlock& next = values[target + 1].sources[index]; + if( current.error > next.error + 1 ) + { + current.start = next.start; + current.end = next.end; + current.error = next.error + 1; + stable = false; + } + } + if( target != 0 ) + { + SourceBlock& current = values[target].sources[index]; + SourceBlock& previous = values[target - 1].sources[index]; + if( current.error > previous.error + 1 ) + { + current.start = previous.start; + current.end = previous.end; + current.error = previous.error + 1; + stable = false; + } + } + } + } + if( stable ) + break; + } + + // debug + std::cout << "\nstatic SingleColourLookup const " << name << "[] = \n{\n"; + for( int i = 0;; ) + { + std::cout << "\t{ { "; + for( int j = 0;; ) + { + SourceBlock const& block = values[i].sources[j]; + if( j < colours ) + std::cout << "{ " << block.start << ", " << block.end << ", " << block.error << " }"; + else + std::cout << "{ 0, 0, 0 }"; + if( ++j == 2 ) + break; + std::cout << ", "; + } + std::cout << " } }"; + if( ++i == 256 ) + break; + std::cout << ",\n"; + } + std::cout << "\n};\n"; +} + +int main() +{ + GenerateData( "lookup_5_3", 5, 3 ); + GenerateData( "lookup_6_3", 6, 3 ); + GenerateData( "lookup_5_4", 5, 4 ); + GenerateData( "lookup_6_4", 6, 4 ); +} diff --git a/tools/depends/native/libsquish-native/src/extra/squishpng.cpp b/tools/depends/native/libsquish-native/src/extra/squishpng.cpp new file mode 100644 index 0000000000..f443656dab --- /dev/null +++ b/tools/depends/native/libsquish-native/src/extra/squishpng.cpp @@ -0,0 +1,546 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + + 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 + + @brief Test program that compresses images loaded using the PNG format. + + This program requires libpng for PNG input and output, and is designed to + test the RMS error for DXT compression for a set of test images. + + This program uses the high-level image compression and decompression + functions that process an entire image at a time. +*/ + +#include <iostream> +#include <string> +#include <sstream> +#include <ctime> +#include <cmath> +#include <squish.h> +#include <png.h> + +#ifdef _MSC_VER +#pragma warning( disable: 4511 4512 ) +#endif // def _MSC_VER + +using namespace squish; + +//! Simple exception class. +class Error : public std::exception +{ +public: + Error( std::string const& excuse ) : m_excuse( excuse ) {} + ~Error() throw() {} + + virtual char const* what() const throw() { return m_excuse.c_str(); } + +private: + std::string m_excuse; +}; + +//! Base class to make derived classes non-copyable +class NonCopyable +{ +public: + NonCopyable() {} + +private: + NonCopyable( NonCopyable const& ); + NonCopyable& operator=( NonCopyable const& ); +}; + +//! Memory object. +class Mem : NonCopyable +{ +public: + Mem() : m_p( 0 ) {} + explicit Mem( int size ) : m_p( new u8[size] ) {} + ~Mem() { delete[] m_p; } + + void Reset( int size ) + { + u8 *p = new u8[size]; + delete m_p; + m_p = p; + } + + u8* Get() const { return m_p; } + +private: + u8* m_p; +}; + +//! File object. +class File : NonCopyable +{ +public: + explicit File( FILE* fp ) : m_fp( fp ) {} + ~File() { if( m_fp ) fclose( m_fp ); } + + bool IsValid() const { return m_fp != 0; } + FILE* Get() const { return m_fp; } + +private: + FILE* m_fp; +}; + +//! PNG read object. +class PngReadStruct : NonCopyable +{ +public: + PngReadStruct() + : m_png( 0 ), + m_info( 0 ), + m_end( 0 ) + { + m_png = png_create_read_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 ); + if( !m_png ) + throw Error( "failed to create png read struct" ); + + m_info = png_create_info_struct( m_png ); + m_end = png_create_info_struct( m_png ); + if( !m_info || !m_end ) + { + png_infopp info = m_info ? &m_info : 0; + png_infopp end = m_end ? &m_end : 0; + png_destroy_read_struct( &m_png, info, end ); + throw Error( "failed to create png info structs" ); + } + } + + ~PngReadStruct() + { + png_destroy_read_struct( &m_png, &m_info, &m_end ); + } + + png_structp GetPng() const { return m_png; } + png_infop GetInfo() const { return m_info; } + +private: + png_structp m_png; + png_infop m_info, m_end; +}; + +//! PNG write object. +class PngWriteStruct : NonCopyable +{ +public: + PngWriteStruct() + : m_png( 0 ), + m_info( 0 ) + { + m_png = png_create_write_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 ); + if( !m_png ) + throw Error( "failed to create png read struct" ); + + m_info = png_create_info_struct( m_png ); + if( !m_info ) + { + png_infopp info = m_info ? &m_info : 0; + png_destroy_write_struct( &m_png, info ); + throw Error( "failed to create png info structs" ); + } + } + + ~PngWriteStruct() + { + png_destroy_write_struct( &m_png, &m_info ); + } + + png_structp GetPng() const { return m_png; } + png_infop GetInfo() const { return m_info; } + +private: + png_structp m_png; + png_infop m_info; +}; + +//! PNG rows object. +class PngRows : NonCopyable +{ +public: + PngRows( int pitch, int height ) : m_height( height ) + { + m_rows = new png_bytep[m_height]; + for( int i = 0; i < m_height; ++i ) + m_rows[i] = new png_byte[pitch]; + } + + ~PngRows() + { + for( int i = 0; i < m_height; ++i ) + delete[] m_rows[i]; + delete[] m_rows; + } + + png_bytep* Get() const { return m_rows; } + + png_bytep operator[](int y) const { return m_rows[y]; } + +private: + png_bytep* m_rows; + int m_height; +}; + +//! Represents a DXT compressed image in memory. +struct DxtData +{ + int width; + int height; + int format; //!< Either kDxt1, kDxt3 or kDxt5. + Mem data; + bool isColour; + bool isAlpha; +}; + +//! Represents an uncompressed RGBA image in memory. +class Image +{ +public: + Image(); + + void LoadPng( std::string const& fileName ); + void SavePng( std::string const& fileName ) const; + + void Decompress( DxtData const& dxt ); + void Compress( DxtData& dxt, int flags ) const; + + double GetRmsError( Image const& image ) const; + +private: + int m_width; + int m_height; + bool m_isColour; //!< Either colour or luminance. + bool m_isAlpha; //!< Either alpha or not. + Mem m_pixels; +}; + +Image::Image() + : m_width( 0 ), + m_height( 0 ), + m_isColour( false ), + m_isAlpha( false ) +{ +} + +void Image::LoadPng( std::string const& fileName ) +{ + // open the source file + File file( fopen( fileName.c_str(), "rb" ) ); + if( !file.IsValid() ) + { + std::ostringstream oss; + oss << "failed to open \"" << fileName << "\" for reading"; + throw Error( oss.str() ); + } + + // check the signature bytes + png_byte header[8]; + size_t check = fread( header, 1, 8, file.Get() ); + if( check != 8 ) + throw Error( "file read error" ); + if( png_sig_cmp( header, 0, 8 ) ) + { + std::ostringstream oss; + oss << "\"" << fileName << "\" does not look like a png file"; + throw Error( oss.str() ); + } + + // read the image into memory + PngReadStruct png; + png_init_io( png.GetPng(), file.Get() ); + png_set_sig_bytes( png.GetPng(), 8 ); + png_read_png( png.GetPng(), png.GetInfo(), PNG_TRANSFORM_EXPAND, 0 ); + + // get the image info + png_uint_32 width; + png_uint_32 height; + int bitDepth; + int colourType; + png_get_IHDR( png.GetPng(), png.GetInfo(), &width, &height, &bitDepth, &colourType, 0, 0, 0 ); + + // check the image is 8 bit + if( bitDepth != 8 ) + { + std::ostringstream oss; + oss << "cannot process " << bitDepth << "-bit image (bit depth must be 8)"; + throw Error( oss.str() ); + } + + // copy the data into a contiguous array + m_width = width; + m_height = height; + m_isColour = ( ( colourType & PNG_COLOR_MASK_COLOR ) != 0 ); + m_isAlpha = ( ( colourType & PNG_COLOR_MASK_ALPHA ) != 0 ); + m_pixels.Reset(4*width*height); + + // get the image rows + png_bytep const *rows = png_get_rows( png.GetPng(), png.GetInfo() ); + if( !rows ) + throw Error( "failed to get image rows" ); + + // copy the pixels into the storage + u8 *dest = m_pixels.Get(); + for( int y = 0; y < m_height; ++y ) + { + u8 const *src = rows[y]; + for( int x = 0; x < m_width; ++x ) + { + if( m_isColour ) + { + dest[0] = src[0]; + dest[1] = src[1]; + dest[2] = src[2]; + src += 3; + } + else + { + u8 lum = *src++; + dest[0] = lum; + dest[1] = lum; + dest[2] = lum; + } + + if( m_isAlpha ) + dest[3] = *src++; + else + dest[3] = 255; + + dest += 4; + } + } +} + +void Image::SavePng( std::string const& fileName ) const +{ + // create the target rows + int const pixelSize = ( m_isColour ? 3 : 1 ) + ( m_isAlpha ? 1 : 0 ); + PngRows rows( m_width*pixelSize, m_height ); + + // fill the rows with pixel data + u8 const *src = m_pixels.Get(); + for( int y = 0; y < m_height; ++y ) + { + u8 *dest = rows[y]; + for( int x = 0; x < m_width; ++x ) + { + if( m_isColour ) + { + dest[0] = src[0]; + dest[1] = src[1]; + dest[2] = src[2]; + dest += 3; + } + else + *dest++ = src[1]; + + if( m_isAlpha ) + *dest++ = src[3]; + + src += 4; + } + } + + // set up the image + PngWriteStruct png; + png_set_IHDR( + png.GetPng(), png.GetInfo(), m_width, m_height, + 8, ( m_isColour ? PNG_COLOR_MASK_COLOR : 0) | ( m_isAlpha ? PNG_COLOR_MASK_ALPHA : 0 ), + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT + ); + + // open the target file + File file( fopen( fileName.c_str(), "wb" ) ); + if( !file.IsValid() ) + { + std::ostringstream oss; + oss << "failed to open \"" << fileName << "\" for writing"; + throw Error( oss.str() ); + } + + // write the image + png_set_rows( png.GetPng(), png.GetInfo(), rows.Get() ); + png_init_io( png.GetPng(), file.Get() ); + png_write_png( png.GetPng(), png.GetInfo(), PNG_TRANSFORM_IDENTITY, 0 ); +} + +void Image::Decompress( DxtData const& dxt ) +{ + // allocate storage + m_width = dxt.width; + m_height = dxt.height; + m_isColour = dxt.isColour; + m_isAlpha = dxt.isAlpha; + m_pixels.Reset( 4*m_width*m_height ); + + // use the whole image decompression function to do the work + DecompressImage( m_pixels.Get(), m_width, m_height, dxt.data.Get(), dxt.format ); +} + +void Image::Compress( DxtData& dxt, int flags ) const +{ + // work out how much memory we need + int storageSize = GetStorageRequirements( m_width, m_height, flags ); + + // set the structure fields and allocate it + dxt.width = m_width; + dxt.height = m_height; + dxt.format = flags & ( kDxt1 | kDxt3 | kDxt5 ); + dxt.isColour = m_isColour; + dxt.isAlpha = m_isAlpha; + dxt.data.Reset( storageSize ); + + // use the whole image compression function to do the work + CompressImage( m_pixels.Get(), m_width, m_height, dxt.data.Get(), flags ); +} + +double Image::GetRmsError( Image const& image ) const +{ + if( m_width != image.m_width || m_height != image.m_height ) + throw Error( "image dimensions mismatch when computing RMS error" ); + + // accumulate colour error + double difference = 0; + u8 const *a = m_pixels.Get(); + u8 const *b = image.m_pixels.Get(); + for( int y = 0; y < m_height; ++y ) + { + for( int x = 0; x < m_width; ++x ) + { + int d0 = ( int )a[0] - ( int )b[0]; + int d1 = ( int )a[1] - ( int )b[1]; + int d2 = ( int )a[2] - ( int )b[2]; + difference += ( double )( d0*d0 + d1*d1 + d2*d2 ); + a += 4; + b += 4; + } + } + return std::sqrt( difference/( double )( m_width*m_height ) ); +} + +int main( int argc, char* argv[] ) +{ + try + { + // parse the command-line + std::string sourceFileName; + std::string targetFileName; + int format = kDxt1; + int fit = kColourClusterFit; + int extra = 0; + bool help = false; + bool arguments = true; + bool error = false; + for( int i = 1; i < argc; ++i ) + { + // check for options + char const* word = argv[i]; + if( arguments && word[0] == '-' ) + { + for( int j = 1; word[j] != '\0'; ++j ) + { + switch( word[j] ) + { + case 'h': help = true; break; + case '1': format = kDxt1; break; + case '3': format = kDxt3; break; + case '5': format = kDxt5; break; + case 'r': fit = kColourRangeFit; break; + case 'i': fit = kColourIterativeClusterFit; break; + case 'w': extra = kWeightColourByAlpha; break; + case '-': arguments = false; break; + default: + std::cerr << "squishpng error: unknown option '" << word[j] << "'" << std::endl; + error = true; + } + } + } + else + { + if( sourceFileName.empty() ) + sourceFileName.assign( word ); + else if( targetFileName.empty() ) + targetFileName.assign( word ); + else + { + std::cerr << "squishpng error: unexpected argument \"" << word << "\"" << std::endl; + error = true; + } + } + } + + // check arguments + if( sourceFileName.empty() ) + { + std::cerr << "squishpng error: no source file given" << std::endl; + error = true; + } + if( help || error ) + { + std::cout + << "SYNTAX" << std::endl + << "\tsquishpng [-135riw] <source> [<target>]" << std::endl + << "OPTIONS" << std::endl + << "\t-h\tPrint this help message" << std::endl + << "\t-135\tSpecifies whether to use DXT1 (default), DXT3 or DXT5 compression" << std::endl + << "\t-r\tUse the fast but inferior range-based colour compressor" << std::endl + << "\t-i\tUse the very slow but slightly better iterative colour compressor" << std::endl + << "\t-w\tWeight colour values by alpha in the cluster colour compressor" << std::endl + ; + + return error ? -1 : 0; + } + + // load the source image + Image sourceImage; + sourceImage.LoadPng( sourceFileName ); + + // compress to DXT + DxtData dxt; + sourceImage.Compress( dxt, format | fit | extra ); + + // decompress back + Image targetImage; + targetImage.Decompress( dxt ); + + // compare the images + double rmsError = sourceImage.GetRmsError( targetImage ); + std::cout << sourceFileName << " " << rmsError << std::endl; + + // save the target image if necessary + if( !targetFileName.empty() ) + targetImage.SavePng( targetFileName ); + } + catch( std::exception& excuse ) + { + // complain + std::cerr << "squishpng error: " << excuse.what() << std::endl; + return -1; + } + + // done + return 0; +} diff --git a/tools/depends/native/libsquish-native/src/extra/squishtest.cpp b/tools/depends/native/libsquish-native/src/extra/squishtest.cpp new file mode 100644 index 0000000000..fb09208694 --- /dev/null +++ b/tools/depends/native/libsquish-native/src/extra/squishtest.cpp @@ -0,0 +1,206 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + + 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 + + @brief This program tests the error for 1 and 2-colour DXT compression. + + This tests the effectiveness of the DXT compression algorithm for all + possible 1 and 2-colour blocks of pixels. +*/ + +#include <squish.h> +#include <iostream> +#include <cmath> +#include <cfloat> +#include <cstdlib> + +using namespace squish; + +double GetColourError( u8 const* a, u8 const* b ) +{ + double error = 0.0; + for( int i = 0; i < 16; ++i ) + { + for( int j = 0; j < 3; ++j ) + { + int index = 4*i + j; + int diff = ( int )a[index] - ( int )b[index]; + error += ( double )( diff*diff ); + } + } + return error / 16.0; +} + +void TestOneColour( int flags ) +{ + u8 input[4*16]; + u8 output[4*16]; + u8 block[16]; + + double avg = 0.0, min = DBL_MAX, max = -DBL_MAX; + int counter = 0; + + // test all single-channel colours + for( int i = 0; i < 16*4; ++i ) + input[i] = ( ( i % 4 ) == 3 ) ? 255 : 0; + for( int channel = 0; channel < 3; ++channel ) + { + for( int value = 0; value < 255; ++value ) + { + // set the channnel value + for( int i = 0; i < 16; ++i ) + input[4*i + channel] = ( u8 )value; + + // compress and decompress + Compress( input, block, flags ); + Decompress( output, block, flags ); + + // test the results + double rm = GetColourError( input, output ); + double rms = std::sqrt( rm ); + + // accumulate stats + min = std::min( min, rms ); + max = std::max( max, rms ); + avg += rm; + ++counter; + } + + // reset the channel value + for( int i = 0; i < 16; ++i ) + input[4*i + channel] = 0; + } + + // finish stats + avg = std::sqrt( avg/counter ); + + // show stats + std::cout << "one colour error (min, max, avg): " + << min << ", " << max << ", " << avg << std::endl; +} + +void TestOneColourRandom( int flags ) +{ + u8 input[4*16]; + u8 output[4*16]; + u8 block[16]; + + double avg = 0.0, min = DBL_MAX, max = -DBL_MAX; + int counter = 0; + + // test all single-channel colours + for( int test = 0; test < 1000; ++test ) + { + // set a constant random colour + for( int channel = 0; channel < 3; ++channel ) + { + u8 value = ( u8 )( rand() & 0xff ); + for( int i = 0; i < 16; ++i ) + input[4*i + channel] = value; + } + for( int i = 0; i < 16; ++i ) + input[4*i + 3] = 255; + + // compress and decompress + Compress( input, block, flags ); + Decompress( output, block, flags ); + + // test the results + double rm = GetColourError( input, output ); + double rms = std::sqrt( rm ); + + // accumulate stats + min = std::min( min, rms ); + max = std::max( max, rms ); + avg += rm; + ++counter; + } + + // finish stats + avg = std::sqrt( avg/counter ); + + // show stats + std::cout << "random one colour error (min, max, avg): " + << min << ", " << max << ", " << avg << std::endl; +} + +void TestTwoColour( int flags ) +{ + u8 input[4*16]; + u8 output[4*16]; + u8 block[16]; + + double avg = 0.0, min = DBL_MAX, max = -DBL_MAX; + int counter = 0; + + // test all single-channel colours + for( int i = 0; i < 16*4; ++i ) + input[i] = ( ( i % 4 ) == 3 ) ? 255 : 0; + for( int channel = 0; channel < 3; ++channel ) + { + for( int value1 = 0; value1 < 255; ++value1 ) + { + for( int value2 = value1 + 1; value2 < 255; ++value2 ) + { + // set the channnel value + for( int i = 0; i < 16; ++i ) + input[4*i + channel] = ( u8 )( ( i < 8 ) ? value1 : value2 ); + + // compress and decompress + Compress( input, block, flags ); + Decompress( output, block, flags ); + + // test the results + double rm = GetColourError( input, output ); + double rms = std::sqrt( rm ); + + // accumulate stats + min = std::min( min, rms ); + max = std::max( max, rms ); + avg += rm; + ++counter; + } + } + + // reset the channel value + for( int i = 0; i < 16; ++i ) + input[4*i + channel] = 0; + } + + // finish stats + avg = std::sqrt( avg/counter ); + + // show stats + std::cout << "two colour error (min, max, avg): " + << min << ", " << max << ", " << avg << std::endl; +} + +int main() +{ + TestOneColourRandom( kDxt1 | kColourRangeFit ); + TestOneColour( kDxt1 ); + TestTwoColour( kDxt1 ); +} diff --git a/tools/depends/native/libsquish-native/src/maths.cpp b/tools/depends/native/libsquish-native/src/maths.cpp new file mode 100644 index 0000000000..9af4197d38 --- /dev/null +++ b/tools/depends/native/libsquish-native/src/maths.cpp @@ -0,0 +1,259 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + + 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 + + The symmetric eigensystem solver algorithm is from + http://www.geometrictools.com/Documentation/EigenSymmetric3x3.pdf +*/ + +#include "maths.h" +#include "simd.h" +#include <cfloat> + +namespace squish { + +Sym3x3 ComputeWeightedCovariance( int n, Vec3 const* points, float const* weights ) +{ + // compute the centroid + float total = 0.0f; + Vec3 centroid( 0.0f ); + for( int i = 0; i < n; ++i ) + { + total += weights[i]; + centroid += weights[i]*points[i]; + } + if( total > FLT_EPSILON ) + centroid /= total; + + // accumulate the covariance matrix + Sym3x3 covariance( 0.0f ); + for( int i = 0; i < n; ++i ) + { + Vec3 a = points[i] - centroid; + Vec3 b = weights[i]*a; + + covariance[0] += a.X()*b.X(); + covariance[1] += a.X()*b.Y(); + covariance[2] += a.X()*b.Z(); + covariance[3] += a.Y()*b.Y(); + covariance[4] += a.Y()*b.Z(); + covariance[5] += a.Z()*b.Z(); + } + + // return it + return covariance; +} + +#if 0 + +static Vec3 GetMultiplicity1Evector( Sym3x3 const& matrix, float evalue ) +{ + // compute M + Sym3x3 m; + m[0] = matrix[0] - evalue; + m[1] = matrix[1]; + m[2] = matrix[2]; + m[3] = matrix[3] - evalue; + m[4] = matrix[4]; + m[5] = matrix[5] - evalue; + + // compute U + Sym3x3 u; + u[0] = m[3]*m[5] - m[4]*m[4]; + u[1] = m[2]*m[4] - m[1]*m[5]; + u[2] = m[1]*m[4] - m[2]*m[3]; + u[3] = m[0]*m[5] - m[2]*m[2]; + u[4] = m[1]*m[2] - m[4]*m[0]; + u[5] = m[0]*m[3] - m[1]*m[1]; + + // find the largest component + float mc = std::fabs( u[0] ); + int mi = 0; + for( int i = 1; i < 6; ++i ) + { + float c = std::fabs( u[i] ); + if( c > mc ) + { + mc = c; + mi = i; + } + } + + // pick the column with this component + switch( mi ) + { + case 0: + return Vec3( u[0], u[1], u[2] ); + + case 1: + case 3: + return Vec3( u[1], u[3], u[4] ); + + default: + return Vec3( u[2], u[4], u[5] ); + } +} + +static Vec3 GetMultiplicity2Evector( Sym3x3 const& matrix, float evalue ) +{ + // compute M + Sym3x3 m; + m[0] = matrix[0] - evalue; + m[1] = matrix[1]; + m[2] = matrix[2]; + m[3] = matrix[3] - evalue; + m[4] = matrix[4]; + m[5] = matrix[5] - evalue; + + // find the largest component + float mc = std::fabs( m[0] ); + int mi = 0; + for( int i = 1; i < 6; ++i ) + { + float c = std::fabs( m[i] ); + if( c > mc ) + { + mc = c; + mi = i; + } + } + + // pick the first eigenvector based on this index + switch( mi ) + { + case 0: + case 1: + return Vec3( -m[1], m[0], 0.0f ); + + case 2: + return Vec3( m[2], 0.0f, -m[0] ); + + case 3: + case 4: + return Vec3( 0.0f, -m[4], m[3] ); + + default: + return Vec3( 0.0f, -m[5], m[4] ); + } +} + +Vec3 ComputePrincipleComponent( Sym3x3 const& matrix ) +{ + // compute the cubic coefficients + float c0 = matrix[0]*matrix[3]*matrix[5] + + 2.0f*matrix[1]*matrix[2]*matrix[4] + - matrix[0]*matrix[4]*matrix[4] + - matrix[3]*matrix[2]*matrix[2] + - matrix[5]*matrix[1]*matrix[1]; + float c1 = matrix[0]*matrix[3] + matrix[0]*matrix[5] + matrix[3]*matrix[5] + - matrix[1]*matrix[1] - matrix[2]*matrix[2] - matrix[4]*matrix[4]; + float c2 = matrix[0] + matrix[3] + matrix[5]; + + // compute the quadratic coefficients + float a = c1 - ( 1.0f/3.0f )*c2*c2; + float b = ( -2.0f/27.0f )*c2*c2*c2 + ( 1.0f/3.0f )*c1*c2 - c0; + + // compute the root count check + float Q = 0.25f*b*b + ( 1.0f/27.0f )*a*a*a; + + // test the multiplicity + if( FLT_EPSILON < Q ) + { + // only one root, which implies we have a multiple of the identity + return Vec3( 1.0f ); + } + else if( Q < -FLT_EPSILON ) + { + // three distinct roots + float theta = std::atan2( std::sqrt( -Q ), -0.5f*b ); + float rho = std::sqrt( 0.25f*b*b - Q ); + + float rt = std::pow( rho, 1.0f/3.0f ); + float ct = std::cos( theta/3.0f ); + float st = std::sin( theta/3.0f ); + + float l1 = ( 1.0f/3.0f )*c2 + 2.0f*rt*ct; + float l2 = ( 1.0f/3.0f )*c2 - rt*( ct + ( float )sqrt( 3.0f )*st ); + float l3 = ( 1.0f/3.0f )*c2 - rt*( ct - ( float )sqrt( 3.0f )*st ); + + // pick the larger + if( std::fabs( l2 ) > std::fabs( l1 ) ) + l1 = l2; + if( std::fabs( l3 ) > std::fabs( l1 ) ) + l1 = l3; + + // get the eigenvector + return GetMultiplicity1Evector( matrix, l1 ); + } + else // if( -FLT_EPSILON <= Q && Q <= FLT_EPSILON ) + { + // two roots + float rt; + if( b < 0.0f ) + rt = -std::pow( -0.5f*b, 1.0f/3.0f ); + else + rt = std::pow( 0.5f*b, 1.0f/3.0f ); + + float l1 = ( 1.0f/3.0f )*c2 + rt; // repeated + float l2 = ( 1.0f/3.0f )*c2 - 2.0f*rt; + + // get the eigenvector + if( std::fabs( l1 ) > std::fabs( l2 ) ) + return GetMultiplicity2Evector( matrix, l1 ); + else + return GetMultiplicity1Evector( matrix, l2 ); + } +} + +#else + +#define POWER_ITERATION_COUNT 8 + +Vec3 ComputePrincipleComponent( Sym3x3 const& matrix ) +{ + Vec4 const row0( matrix[0], matrix[1], matrix[2], 0.0f ); + Vec4 const row1( matrix[1], matrix[3], matrix[4], 0.0f ); + Vec4 const row2( matrix[2], matrix[4], matrix[5], 0.0f ); + Vec4 v = VEC4_CONST( 1.0f ); + for( int i = 0; i < POWER_ITERATION_COUNT; ++i ) + { + // matrix multiply + Vec4 w = row0*v.SplatX(); + w = MultiplyAdd(row1, v.SplatY(), w); + w = MultiplyAdd(row2, v.SplatZ(), w); + + // get max component from xyz in all channels + Vec4 a = Max(w.SplatX(), Max(w.SplatY(), w.SplatZ())); + + // divide through and advance + v = w*Reciprocal(a); + } + return v.GetVec3(); +} + +#endif + +} // namespace squish diff --git a/tools/depends/native/libsquish-native/src/maths.h b/tools/depends/native/libsquish-native/src/maths.h new file mode 100644 index 0000000000..769ae463f7 --- /dev/null +++ b/tools/depends/native/libsquish-native/src/maths.h @@ -0,0 +1,233 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + + 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 SQUISH_MATHS_H +#define SQUISH_MATHS_H + +#include <cmath> +#include <algorithm> +#include "config.h" + +namespace squish { + +class Vec3 +{ +public: + typedef Vec3 const& Arg; + + Vec3() + { + } + + explicit Vec3( float s ) + { + m_x = s; + m_y = s; + m_z = s; + } + + Vec3( float x, float y, float z ) + { + m_x = x; + m_y = y; + m_z = z; + } + + float X() const { return m_x; } + float Y() const { return m_y; } + float Z() const { return m_z; } + + Vec3 operator-() const + { + return Vec3( -m_x, -m_y, -m_z ); + } + + Vec3& operator+=( Arg v ) + { + m_x += v.m_x; + m_y += v.m_y; + m_z += v.m_z; + return *this; + } + + Vec3& operator-=( Arg v ) + { + m_x -= v.m_x; + m_y -= v.m_y; + m_z -= v.m_z; + return *this; + } + + Vec3& operator*=( Arg v ) + { + m_x *= v.m_x; + m_y *= v.m_y; + m_z *= v.m_z; + return *this; + } + + Vec3& operator*=( float s ) + { + m_x *= s; + m_y *= s; + m_z *= s; + return *this; + } + + Vec3& operator/=( Arg v ) + { + m_x /= v.m_x; + m_y /= v.m_y; + m_z /= v.m_z; + return *this; + } + + Vec3& operator/=( float s ) + { + float t = 1.0f/s; + m_x *= t; + m_y *= t; + m_z *= t; + return *this; + } + + friend Vec3 operator+( Arg left, Arg right ) + { + Vec3 copy( left ); + return copy += right; + } + + friend Vec3 operator-( Arg left, Arg right ) + { + Vec3 copy( left ); + return copy -= right; + } + + friend Vec3 operator*( Arg left, Arg right ) + { + Vec3 copy( left ); + return copy *= right; + } + + friend Vec3 operator*( Arg left, float right ) + { + Vec3 copy( left ); + return copy *= right; + } + + friend Vec3 operator*( float left, Arg right ) + { + Vec3 copy( right ); + return copy *= left; + } + + friend Vec3 operator/( Arg left, Arg right ) + { + Vec3 copy( left ); + return copy /= right; + } + + friend Vec3 operator/( Arg left, float right ) + { + Vec3 copy( left ); + return copy /= right; + } + + friend float Dot( Arg left, Arg right ) + { + return left.m_x*right.m_x + left.m_y*right.m_y + left.m_z*right.m_z; + } + + friend Vec3 Min( Arg left, Arg right ) + { + return Vec3( + std::min( left.m_x, right.m_x ), + std::min( left.m_y, right.m_y ), + std::min( left.m_z, right.m_z ) + ); + } + + friend Vec3 Max( Arg left, Arg right ) + { + return Vec3( + std::max( left.m_x, right.m_x ), + std::max( left.m_y, right.m_y ), + std::max( left.m_z, right.m_z ) + ); + } + + friend Vec3 Truncate( Arg v ) + { + return Vec3( + v.m_x > 0.0f ? std::floor( v.m_x ) : std::ceil( v.m_x ), + v.m_y > 0.0f ? std::floor( v.m_y ) : std::ceil( v.m_y ), + v.m_z > 0.0f ? std::floor( v.m_z ) : std::ceil( v.m_z ) + ); + } + +private: + float m_x; + float m_y; + float m_z; +}; + +inline float LengthSquared( Vec3::Arg v ) +{ + return Dot( v, v ); +} + +class Sym3x3 +{ +public: + Sym3x3() + { + } + + Sym3x3( float s ) + { + for( int i = 0; i < 6; ++i ) + m_x[i] = s; + } + + float operator[]( int index ) const + { + return m_x[index]; + } + + float& operator[]( int index ) + { + return m_x[index]; + } + +private: + float m_x[6]; +}; + +Sym3x3 ComputeWeightedCovariance( int n, Vec3 const* points, float const* weights ); +Vec3 ComputePrincipleComponent( Sym3x3 const& matrix ); + +} // namespace squish + +#endif // ndef SQUISH_MATHS_H diff --git a/tools/depends/native/libsquish-native/src/rangefit.cpp b/tools/depends/native/libsquish-native/src/rangefit.cpp new file mode 100644 index 0000000000..3fca1245eb --- /dev/null +++ b/tools/depends/native/libsquish-native/src/rangefit.cpp @@ -0,0 +1,201 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + + 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 "rangefit.h" +#include "colourset.h" +#include "colourblock.h" +#include <cfloat> + +namespace squish { + +RangeFit::RangeFit( ColourSet const* colours, int flags, float* metric ) + : ColourFit( colours, flags ) +{ + // initialise the metric (old perceptual = 0.2126f, 0.7152f, 0.0722f) + if( metric ) + m_metric = Vec3( metric[0], metric[1], metric[2] ); + else + m_metric = Vec3( 1.0f ); + + // initialise the best error + m_besterror = FLT_MAX; + + // cache some values + int const count = m_colours->GetCount(); + Vec3 const* values = m_colours->GetPoints(); + float const* weights = m_colours->GetWeights(); + + // get the covariance matrix + Sym3x3 covariance = ComputeWeightedCovariance( count, values, weights ); + + // compute the principle component + Vec3 principle = ComputePrincipleComponent( covariance ); + + // get the min and max range as the codebook endpoints + Vec3 start( 0.0f ); + Vec3 end( 0.0f ); + if( count > 0 ) + { + float min, max; + + // compute the range + start = end = values[0]; + min = max = Dot( values[0], principle ); + for( int i = 1; i < count; ++i ) + { + float val = Dot( values[i], principle ); + if( val < min ) + { + start = values[i]; + min = val; + } + else if( val > max ) + { + end = values[i]; + max = val; + } + } + } + + // clamp the output to [0, 1] + Vec3 const one( 1.0f ); + Vec3 const zero( 0.0f ); + start = Min( one, Max( zero, start ) ); + end = Min( one, Max( zero, end ) ); + + // clamp to the grid and save + Vec3 const grid( 31.0f, 63.0f, 31.0f ); + Vec3 const gridrcp( 1.0f/31.0f, 1.0f/63.0f, 1.0f/31.0f ); + Vec3 const half( 0.5f ); + m_start = Truncate( grid*start + half )*gridrcp; + m_end = Truncate( grid*end + half )*gridrcp; +} + +void RangeFit::Compress3( void* block ) +{ + // cache some values + int const count = m_colours->GetCount(); + Vec3 const* values = m_colours->GetPoints(); + + // create a codebook + Vec3 codes[3]; + codes[0] = m_start; + codes[1] = m_end; + codes[2] = 0.5f*m_start + 0.5f*m_end; + + // match each point to the closest code + u8 closest[16]; + float error = 0.0f; + for( int i = 0; i < count; ++i ) + { + // find the closest code + float dist = FLT_MAX; + int idx = 0; + for( int j = 0; j < 3; ++j ) + { + float d = LengthSquared( m_metric*( values[i] - codes[j] ) ); + if( d < dist ) + { + dist = d; + idx = j; + } + } + + // save the index + closest[i] = ( u8 )idx; + + // accumulate the error + error += dist; + } + + // save this scheme if it wins + if( error < m_besterror ) + { + // remap the indices + u8 indices[16]; + m_colours->RemapIndices( closest, indices ); + + // save the block + WriteColourBlock3( m_start, m_end, indices, block ); + + // save the error + m_besterror = error; + } +} + +void RangeFit::Compress4( void* block ) +{ + // cache some values + int const count = m_colours->GetCount(); + Vec3 const* values = m_colours->GetPoints(); + + // create a codebook + Vec3 codes[4]; + codes[0] = m_start; + codes[1] = m_end; + codes[2] = ( 2.0f/3.0f )*m_start + ( 1.0f/3.0f )*m_end; + codes[3] = ( 1.0f/3.0f )*m_start + ( 2.0f/3.0f )*m_end; + + // match each point to the closest code + u8 closest[16]; + float error = 0.0f; + for( int i = 0; i < count; ++i ) + { + // find the closest code + float dist = FLT_MAX; + int idx = 0; + for( int j = 0; j < 4; ++j ) + { + float d = LengthSquared( m_metric*( values[i] - codes[j] ) ); + if( d < dist ) + { + dist = d; + idx = j; + } + } + + // save the index + closest[i] = ( u8 )idx; + + // accumulate the error + error += dist; + } + + // save this scheme if it wins + if( error < m_besterror ) + { + // remap the indices + u8 indices[16]; + m_colours->RemapIndices( closest, indices ); + + // save the block + WriteColourBlock4( m_start, m_end, indices, block ); + + // save the error + m_besterror = error; + } +} + +} // namespace squish diff --git a/tools/depends/native/libsquish-native/src/rangefit.h b/tools/depends/native/libsquish-native/src/rangefit.h new file mode 100644 index 0000000000..0207bd1c3f --- /dev/null +++ b/tools/depends/native/libsquish-native/src/rangefit.h @@ -0,0 +1,54 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + + 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 SQUISH_RANGEFIT_H +#define SQUISH_RANGEFIT_H + +#include <squish.h> +#include "colourfit.h" +#include "maths.h" + +namespace squish { + +class ColourSet; + +class RangeFit : public ColourFit +{ +public: + RangeFit( ColourSet const* colours, int flags, float* metric ); + +private: + virtual void Compress3( void* block ); + virtual void Compress4( void* block ); + + Vec3 m_metric; + Vec3 m_start; + Vec3 m_end; + float m_besterror; +}; + +} // squish + +#endif // ndef SQUISH_RANGEFIT_H diff --git a/tools/depends/native/libsquish-native/src/simd.h b/tools/depends/native/libsquish-native/src/simd.h new file mode 100644 index 0000000000..22bd10a460 --- /dev/null +++ b/tools/depends/native/libsquish-native/src/simd.h @@ -0,0 +1,40 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + + 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 SQUISH_SIMD_H +#define SQUISH_SIMD_H + +#include "maths.h" + +#if SQUISH_USE_ALTIVEC +#include "simd_ve.h" +#elif SQUISH_USE_SSE +#include "simd_sse.h" +#else +#include "simd_float.h" +#endif + + +#endif // ndef SQUISH_SIMD_H diff --git a/tools/depends/native/libsquish-native/src/simd_float.h b/tools/depends/native/libsquish-native/src/simd_float.h new file mode 100644 index 0000000000..e6351b80eb --- /dev/null +++ b/tools/depends/native/libsquish-native/src/simd_float.h @@ -0,0 +1,183 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + + 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 SQUISH_SIMD_FLOAT_H +#define SQUISH_SIMD_FLOAT_H + +#include <algorithm> + +namespace squish { + +#define VEC4_CONST( X ) Vec4( X ) + +class Vec4 +{ +public: + typedef Vec4 const& Arg; + + Vec4() {} + + explicit Vec4( float s ) + : m_x( s ), + m_y( s ), + m_z( s ), + m_w( s ) + { + } + + Vec4( float x, float y, float z, float w ) + : m_x( x ), + m_y( y ), + m_z( z ), + m_w( w ) + { + } + + Vec3 GetVec3() const + { + return Vec3( m_x, m_y, m_z ); + } + + Vec4 SplatX() const { return Vec4( m_x ); } + Vec4 SplatY() const { return Vec4( m_y ); } + Vec4 SplatZ() const { return Vec4( m_z ); } + Vec4 SplatW() const { return Vec4( m_w ); } + + Vec4& operator+=( Arg v ) + { + m_x += v.m_x; + m_y += v.m_y; + m_z += v.m_z; + m_w += v.m_w; + return *this; + } + + Vec4& operator-=( Arg v ) + { + m_x -= v.m_x; + m_y -= v.m_y; + m_z -= v.m_z; + m_w -= v.m_w; + return *this; + } + + Vec4& operator*=( Arg v ) + { + m_x *= v.m_x; + m_y *= v.m_y; + m_z *= v.m_z; + m_w *= v.m_w; + return *this; + } + + friend Vec4 operator+( Vec4::Arg left, Vec4::Arg right ) + { + Vec4 copy( left ); + return copy += right; + } + + friend Vec4 operator-( Vec4::Arg left, Vec4::Arg right ) + { + Vec4 copy( left ); + return copy -= right; + } + + friend Vec4 operator*( Vec4::Arg left, Vec4::Arg right ) + { + Vec4 copy( left ); + return copy *= right; + } + + //! Returns a*b + c + friend Vec4 MultiplyAdd( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c ) + { + return a*b + c; + } + + //! Returns -( a*b - c ) + friend Vec4 NegativeMultiplySubtract( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c ) + { + return c - a*b; + } + + friend Vec4 Reciprocal( Vec4::Arg v ) + { + return Vec4( + 1.0f/v.m_x, + 1.0f/v.m_y, + 1.0f/v.m_z, + 1.0f/v.m_w + ); + } + + friend Vec4 Min( Vec4::Arg left, Vec4::Arg right ) + { + return Vec4( + std::min( left.m_x, right.m_x ), + std::min( left.m_y, right.m_y ), + std::min( left.m_z, right.m_z ), + std::min( left.m_w, right.m_w ) + ); + } + + friend Vec4 Max( Vec4::Arg left, Vec4::Arg right ) + { + return Vec4( + std::max( left.m_x, right.m_x ), + std::max( left.m_y, right.m_y ), + std::max( left.m_z, right.m_z ), + std::max( left.m_w, right.m_w ) + ); + } + + friend Vec4 Truncate( Vec4::Arg v ) + { + return Vec4( + v.m_x > 0.0f ? std::floor( v.m_x ) : std::ceil( v.m_x ), + v.m_y > 0.0f ? std::floor( v.m_y ) : std::ceil( v.m_y ), + v.m_z > 0.0f ? std::floor( v.m_z ) : std::ceil( v.m_z ), + v.m_w > 0.0f ? std::floor( v.m_w ) : std::ceil( v.m_w ) + ); + } + + friend bool CompareAnyLessThan( Vec4::Arg left, Vec4::Arg right ) + { + return left.m_x < right.m_x + || left.m_y < right.m_y + || left.m_z < right.m_z + || left.m_w < right.m_w; + } + +private: + float m_x; + float m_y; + float m_z; + float m_w; +}; + +} // namespace squish + +#endif // ndef SQUISH_SIMD_FLOAT_H + diff --git a/tools/depends/native/libsquish-native/src/simd_sse.h b/tools/depends/native/libsquish-native/src/simd_sse.h new file mode 100644 index 0000000000..e584f2a0e5 --- /dev/null +++ b/tools/depends/native/libsquish-native/src/simd_sse.h @@ -0,0 +1,180 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + + 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 SQUISH_SIMD_SSE_H +#define SQUISH_SIMD_SSE_H + +#include <xmmintrin.h> +#if ( SQUISH_USE_SSE > 1 ) +#include <emmintrin.h> +#endif + +#define SQUISH_SSE_SPLAT( a ) \ + ( ( a ) | ( ( a ) << 2 ) | ( ( a ) << 4 ) | ( ( a ) << 6 ) ) + +#define SQUISH_SSE_SHUF( x, y, z, w ) \ + ( ( x ) | ( ( y ) << 2 ) | ( ( z ) << 4 ) | ( ( w ) << 6 ) ) + +namespace squish { + +#define VEC4_CONST( X ) Vec4( X ) + +class Vec4 +{ +public: + typedef Vec4 const& Arg; + + Vec4() {} + + explicit Vec4( __m128 v ) : m_v( v ) {} + + Vec4( Vec4 const& arg ) : m_v( arg.m_v ) {} + + Vec4& operator=( Vec4 const& arg ) + { + m_v = arg.m_v; + return *this; + } + + explicit Vec4( float s ) : m_v( _mm_set1_ps( s ) ) {} + + Vec4( float x, float y, float z, float w ) : m_v( _mm_setr_ps( x, y, z, w ) ) {} + + Vec3 GetVec3() const + { +#ifdef __GNUC__ + __attribute__ ((__aligned__ (16))) float c[4]; +#else + __declspec(align(16)) float c[4]; +#endif + _mm_store_ps( c, m_v ); + return Vec3( c[0], c[1], c[2] ); + } + + Vec4 SplatX() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 0 ) ) ); } + Vec4 SplatY() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 1 ) ) ); } + Vec4 SplatZ() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 2 ) ) ); } + Vec4 SplatW() const { return Vec4( _mm_shuffle_ps( m_v, m_v, SQUISH_SSE_SPLAT( 3 ) ) ); } + + Vec4& operator+=( Arg v ) + { + m_v = _mm_add_ps( m_v, v.m_v ); + return *this; + } + + Vec4& operator-=( Arg v ) + { + m_v = _mm_sub_ps( m_v, v.m_v ); + return *this; + } + + Vec4& operator*=( Arg v ) + { + m_v = _mm_mul_ps( m_v, v.m_v ); + return *this; + } + + friend Vec4 operator+( Vec4::Arg left, Vec4::Arg right ) + { + return Vec4( _mm_add_ps( left.m_v, right.m_v ) ); + } + + friend Vec4 operator-( Vec4::Arg left, Vec4::Arg right ) + { + return Vec4( _mm_sub_ps( left.m_v, right.m_v ) ); + } + + friend Vec4 operator*( Vec4::Arg left, Vec4::Arg right ) + { + return Vec4( _mm_mul_ps( left.m_v, right.m_v ) ); + } + + //! Returns a*b + c + friend Vec4 MultiplyAdd( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c ) + { + return Vec4( _mm_add_ps( _mm_mul_ps( a.m_v, b.m_v ), c.m_v ) ); + } + + //! Returns -( a*b - c ) + friend Vec4 NegativeMultiplySubtract( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c ) + { + return Vec4( _mm_sub_ps( c.m_v, _mm_mul_ps( a.m_v, b.m_v ) ) ); + } + + friend Vec4 Reciprocal( Vec4::Arg v ) + { + // get the reciprocal estimate + __m128 estimate = _mm_rcp_ps( v.m_v ); + + // one round of Newton-Rhaphson refinement + __m128 diff = _mm_sub_ps( _mm_set1_ps( 1.0f ), _mm_mul_ps( estimate, v.m_v ) ); + return Vec4( _mm_add_ps( _mm_mul_ps( diff, estimate ), estimate ) ); + } + + friend Vec4 Min( Vec4::Arg left, Vec4::Arg right ) + { + return Vec4( _mm_min_ps( left.m_v, right.m_v ) ); + } + + friend Vec4 Max( Vec4::Arg left, Vec4::Arg right ) + { + return Vec4( _mm_max_ps( left.m_v, right.m_v ) ); + } + + friend Vec4 Truncate( Vec4::Arg v ) + { +#if ( SQUISH_USE_SSE == 1 ) + // convert to ints + __m128 input = v.m_v; + __m64 lo = _mm_cvttps_pi32( input ); + __m64 hi = _mm_cvttps_pi32( _mm_movehl_ps( input, input ) ); + + // convert to floats + __m128 part = _mm_movelh_ps( input, _mm_cvtpi32_ps( input, hi ) ); + __m128 truncated = _mm_cvtpi32_ps( part, lo ); + + // clear out the MMX multimedia state to allow FP calls later + _mm_empty(); + return Vec4( truncated ); +#else + // use SSE2 instructions + return Vec4( _mm_cvtepi32_ps( _mm_cvttps_epi32( v.m_v ) ) ); +#endif + } + + friend bool CompareAnyLessThan( Vec4::Arg left, Vec4::Arg right ) + { + __m128 bits = _mm_cmplt_ps( left.m_v, right.m_v ); + int value = _mm_movemask_ps( bits ); + return value != 0; + } + +private: + __m128 m_v; +}; + +} // namespace squish + +#endif // ndef SQUISH_SIMD_SSE_H diff --git a/tools/depends/native/libsquish-native/src/simd_ve.h b/tools/depends/native/libsquish-native/src/simd_ve.h new file mode 100644 index 0000000000..70cb32621e --- /dev/null +++ b/tools/depends/native/libsquish-native/src/simd_ve.h @@ -0,0 +1,166 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + + 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 SQUISH_SIMD_VE_H +#define SQUISH_SIMD_VE_H + +#include <altivec.h> +#undef bool + +namespace squish { + +#define VEC4_CONST( X ) Vec4( ( vector float ){ X } ) + +class Vec4 +{ +public: + typedef Vec4 Arg; + + Vec4() {} + + explicit Vec4( vector float v ) : m_v( v ) {} + + Vec4( Vec4 const& arg ) : m_v( arg.m_v ) {} + + Vec4& operator=( Vec4 const& arg ) + { + m_v = arg.m_v; + return *this; + } + + explicit Vec4( float s ) + { + union { vector float v; float c[4]; } u; + u.c[0] = s; + u.c[1] = s; + u.c[2] = s; + u.c[3] = s; + m_v = u.v; + } + + Vec4( float x, float y, float z, float w ) + { + union { vector float v; float c[4]; } u; + u.c[0] = x; + u.c[1] = y; + u.c[2] = z; + u.c[3] = w; + m_v = u.v; + } + + Vec3 GetVec3() const + { + union { vector float v; float c[4]; } u; + u.v = m_v; + return Vec3( u.c[0], u.c[1], u.c[2] ); + } + + Vec4 SplatX() const { return Vec4( vec_splat( m_v, 0 ) ); } + Vec4 SplatY() const { return Vec4( vec_splat( m_v, 1 ) ); } + Vec4 SplatZ() const { return Vec4( vec_splat( m_v, 2 ) ); } + Vec4 SplatW() const { return Vec4( vec_splat( m_v, 3 ) ); } + + Vec4& operator+=( Arg v ) + { + m_v = vec_add( m_v, v.m_v ); + return *this; + } + + Vec4& operator-=( Arg v ) + { + m_v = vec_sub( m_v, v.m_v ); + return *this; + } + + Vec4& operator*=( Arg v ) + { + m_v = vec_madd( m_v, v.m_v, ( vector float ){ -0.0f } ); + return *this; + } + + friend Vec4 operator+( Vec4::Arg left, Vec4::Arg right ) + { + return Vec4( vec_add( left.m_v, right.m_v ) ); + } + + friend Vec4 operator-( Vec4::Arg left, Vec4::Arg right ) + { + return Vec4( vec_sub( left.m_v, right.m_v ) ); + } + + friend Vec4 operator*( Vec4::Arg left, Vec4::Arg right ) + { + return Vec4( vec_madd( left.m_v, right.m_v, ( vector float ){ -0.0f } ) ); + } + + //! Returns a*b + c + friend Vec4 MultiplyAdd( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c ) + { + return Vec4( vec_madd( a.m_v, b.m_v, c.m_v ) ); + } + + //! Returns -( a*b - c ) + friend Vec4 NegativeMultiplySubtract( Vec4::Arg a, Vec4::Arg b, Vec4::Arg c ) + { + return Vec4( vec_nmsub( a.m_v, b.m_v, c.m_v ) ); + } + + friend Vec4 Reciprocal( Vec4::Arg v ) + { + // get the reciprocal estimate + vector float estimate = vec_re( v.m_v ); + + // one round of Newton-Rhaphson refinement + vector float diff = vec_nmsub( estimate, v.m_v, ( vector float ){ 1.0f } ); + return Vec4( vec_madd( diff, estimate, estimate ) ); + } + + friend Vec4 Min( Vec4::Arg left, Vec4::Arg right ) + { + return Vec4( vec_min( left.m_v, right.m_v ) ); + } + + friend Vec4 Max( Vec4::Arg left, Vec4::Arg right ) + { + return Vec4( vec_max( left.m_v, right.m_v ) ); + } + + friend Vec4 Truncate( Vec4::Arg v ) + { + return Vec4( vec_trunc( v.m_v ) ); + } + + friend bool CompareAnyLessThan( Vec4::Arg left, Vec4::Arg right ) + { + return vec_any_lt( left.m_v, right.m_v ) != 0; + } + +private: + vector float m_v; +}; + +} // namespace squish + +#endif // ndef SQUISH_SIMD_VE_H diff --git a/tools/depends/native/libsquish-native/src/singlecolourfit.cpp b/tools/depends/native/libsquish-native/src/singlecolourfit.cpp new file mode 100644 index 0000000000..e8a0117698 --- /dev/null +++ b/tools/depends/native/libsquish-native/src/singlecolourfit.cpp @@ -0,0 +1,172 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + + 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 "singlecolourfit.h" +#include "colourset.h" +#include "colourblock.h" + +namespace squish { + +struct SourceBlock +{ + u8 start; + u8 end; + u8 error; +}; + +struct SingleColourLookup +{ + SourceBlock sources[2]; +}; + +#include "singlecolourlookup.inl" + +static int FloatToInt( float a, int limit ) +{ + // use ANSI round-to-zero behaviour to get round-to-nearest + int i = ( int )( a + 0.5f ); + + // clamp to the limit + if( i < 0 ) + i = 0; + else if( i > limit ) + i = limit; + + // done + return i; +} + +SingleColourFit::SingleColourFit( ColourSet const* colours, int flags ) + : ColourFit( colours, flags ) +{ + // grab the single colour + Vec3 const* values = m_colours->GetPoints(); + m_colour[0] = ( u8 )FloatToInt( 255.0f*values->X(), 255 ); + m_colour[1] = ( u8 )FloatToInt( 255.0f*values->Y(), 255 ); + m_colour[2] = ( u8 )FloatToInt( 255.0f*values->Z(), 255 ); + + // initialise the best error + m_besterror = INT_MAX; +} + +void SingleColourFit::Compress3( void* block ) +{ + // build the table of lookups + SingleColourLookup const* const lookups[] = + { + lookup_5_3, + lookup_6_3, + lookup_5_3 + }; + + // find the best end-points and index + ComputeEndPoints( lookups ); + + // build the block if we win + if( m_error < m_besterror ) + { + // remap the indices + u8 indices[16]; + m_colours->RemapIndices( &m_index, indices ); + + // save the block + WriteColourBlock3( m_start, m_end, indices, block ); + + // save the error + m_besterror = m_error; + } +} + +void SingleColourFit::Compress4( void* block ) +{ + // build the table of lookups + SingleColourLookup const* const lookups[] = + { + lookup_5_4, + lookup_6_4, + lookup_5_4 + }; + + // find the best end-points and index + ComputeEndPoints( lookups ); + + // build the block if we win + if( m_error < m_besterror ) + { + // remap the indices + u8 indices[16]; + m_colours->RemapIndices( &m_index, indices ); + + // save the block + WriteColourBlock4( m_start, m_end, indices, block ); + + // save the error + m_besterror = m_error; + } +} + +void SingleColourFit::ComputeEndPoints( SingleColourLookup const* const* lookups ) +{ + // check each index combination (endpoint or intermediate) + m_error = INT_MAX; + for( int index = 0; index < 2; ++index ) + { + // check the error for this codebook index + SourceBlock const* sources[3]; + int error = 0; + for( int channel = 0; channel < 3; ++channel ) + { + // grab the lookup table and index for this channel + SingleColourLookup const* lookup = lookups[channel]; + int target = m_colour[channel]; + + // store a pointer to the source for this channel + sources[channel] = lookup[target].sources + index; + + // accumulate the error + int diff = sources[channel]->error; + error += diff*diff; + } + + // keep it if the error is lower + if( error < m_error ) + { + m_start = Vec3( + ( float )sources[0]->start/31.0f, + ( float )sources[1]->start/63.0f, + ( float )sources[2]->start/31.0f + ); + m_end = Vec3( + ( float )sources[0]->end/31.0f, + ( float )sources[1]->end/63.0f, + ( float )sources[2]->end/31.0f + ); + m_index = ( u8 )( 2*index ); + m_error = error; + } + } +} + +} // namespace squish diff --git a/tools/depends/native/libsquish-native/src/singlecolourfit.h b/tools/depends/native/libsquish-native/src/singlecolourfit.h new file mode 100644 index 0000000000..0388fda028 --- /dev/null +++ b/tools/depends/native/libsquish-native/src/singlecolourfit.h @@ -0,0 +1,58 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + + 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 SQUISH_SINGLECOLOURFIT_H +#define SQUISH_SINGLECOLOURFIT_H + +#include <squish.h> +#include "colourfit.h" + +namespace squish { + +class ColourSet; +struct SingleColourLookup; + +class SingleColourFit : public ColourFit +{ +public: + SingleColourFit( ColourSet const* colours, int flags ); + +private: + virtual void Compress3( void* block ); + virtual void Compress4( void* block ); + + void ComputeEndPoints( SingleColourLookup const* const* lookups ); + + u8 m_colour[3]; + Vec3 m_start; + Vec3 m_end; + u8 m_index; + int m_error; + int m_besterror; +}; + +} // namespace squish + +#endif // ndef SQUISH_SINGLECOLOURFIT_H diff --git a/tools/depends/native/libsquish-native/src/singlecolourlookup.inl b/tools/depends/native/libsquish-native/src/singlecolourlookup.inl new file mode 100644 index 0000000000..f1c95a1028 --- /dev/null +++ b/tools/depends/native/libsquish-native/src/singlecolourlookup.inl @@ -0,0 +1,1040 @@ + +static SingleColourLookup const lookup_5_3[] = +{ + { { { 0, 0, 0 }, { 0, 0, 0 } } }, + { { { 0, 0, 1 }, { 0, 0, 1 } } }, + { { { 0, 0, 2 }, { 0, 0, 2 } } }, + { { { 0, 0, 3 }, { 0, 1, 1 } } }, + { { { 0, 0, 4 }, { 0, 1, 0 } } }, + { { { 1, 0, 3 }, { 0, 1, 1 } } }, + { { { 1, 0, 2 }, { 0, 1, 2 } } }, + { { { 1, 0, 1 }, { 0, 2, 1 } } }, + { { { 1, 0, 0 }, { 0, 2, 0 } } }, + { { { 1, 0, 1 }, { 0, 2, 1 } } }, + { { { 1, 0, 2 }, { 0, 2, 2 } } }, + { { { 1, 0, 3 }, { 0, 3, 1 } } }, + { { { 1, 0, 4 }, { 0, 3, 0 } } }, + { { { 2, 0, 3 }, { 0, 3, 1 } } }, + { { { 2, 0, 2 }, { 0, 3, 2 } } }, + { { { 2, 0, 1 }, { 0, 4, 1 } } }, + { { { 2, 0, 0 }, { 0, 4, 0 } } }, + { { { 2, 0, 1 }, { 0, 4, 1 } } }, + { { { 2, 0, 2 }, { 0, 4, 2 } } }, + { { { 2, 0, 3 }, { 0, 5, 1 } } }, + { { { 2, 0, 4 }, { 0, 5, 0 } } }, + { { { 3, 0, 3 }, { 0, 5, 1 } } }, + { { { 3, 0, 2 }, { 0, 5, 2 } } }, + { { { 3, 0, 1 }, { 0, 6, 1 } } }, + { { { 3, 0, 0 }, { 0, 6, 0 } } }, + { { { 3, 0, 1 }, { 0, 6, 1 } } }, + { { { 3, 0, 2 }, { 0, 6, 2 } } }, + { { { 3, 0, 3 }, { 0, 7, 1 } } }, + { { { 3, 0, 4 }, { 0, 7, 0 } } }, + { { { 4, 0, 4 }, { 0, 7, 1 } } }, + { { { 4, 0, 3 }, { 0, 7, 2 } } }, + { { { 4, 0, 2 }, { 1, 7, 1 } } }, + { { { 4, 0, 1 }, { 1, 7, 0 } } }, + { { { 4, 0, 0 }, { 0, 8, 0 } } }, + { { { 4, 0, 1 }, { 0, 8, 1 } } }, + { { { 4, 0, 2 }, { 2, 7, 1 } } }, + { { { 4, 0, 3 }, { 2, 7, 0 } } }, + { { { 4, 0, 4 }, { 0, 9, 0 } } }, + { { { 5, 0, 3 }, { 0, 9, 1 } } }, + { { { 5, 0, 2 }, { 3, 7, 1 } } }, + { { { 5, 0, 1 }, { 3, 7, 0 } } }, + { { { 5, 0, 0 }, { 0, 10, 0 } } }, + { { { 5, 0, 1 }, { 0, 10, 1 } } }, + { { { 5, 0, 2 }, { 0, 10, 2 } } }, + { { { 5, 0, 3 }, { 0, 11, 1 } } }, + { { { 5, 0, 4 }, { 0, 11, 0 } } }, + { { { 6, 0, 3 }, { 0, 11, 1 } } }, + { { { 6, 0, 2 }, { 0, 11, 2 } } }, + { { { 6, 0, 1 }, { 0, 12, 1 } } }, + { { { 6, 0, 0 }, { 0, 12, 0 } } }, + { { { 6, 0, 1 }, { 0, 12, 1 } } }, + { { { 6, 0, 2 }, { 0, 12, 2 } } }, + { { { 6, 0, 3 }, { 0, 13, 1 } } }, + { { { 6, 0, 4 }, { 0, 13, 0 } } }, + { { { 7, 0, 3 }, { 0, 13, 1 } } }, + { { { 7, 0, 2 }, { 0, 13, 2 } } }, + { { { 7, 0, 1 }, { 0, 14, 1 } } }, + { { { 7, 0, 0 }, { 0, 14, 0 } } }, + { { { 7, 0, 1 }, { 0, 14, 1 } } }, + { { { 7, 0, 2 }, { 0, 14, 2 } } }, + { { { 7, 0, 3 }, { 0, 15, 1 } } }, + { { { 7, 0, 4 }, { 0, 15, 0 } } }, + { { { 8, 0, 4 }, { 0, 15, 1 } } }, + { { { 8, 0, 3 }, { 0, 15, 2 } } }, + { { { 8, 0, 2 }, { 1, 15, 1 } } }, + { { { 8, 0, 1 }, { 1, 15, 0 } } }, + { { { 8, 0, 0 }, { 0, 16, 0 } } }, + { { { 8, 0, 1 }, { 0, 16, 1 } } }, + { { { 8, 0, 2 }, { 2, 15, 1 } } }, + { { { 8, 0, 3 }, { 2, 15, 0 } } }, + { { { 8, 0, 4 }, { 0, 17, 0 } } }, + { { { 9, 0, 3 }, { 0, 17, 1 } } }, + { { { 9, 0, 2 }, { 3, 15, 1 } } }, + { { { 9, 0, 1 }, { 3, 15, 0 } } }, + { { { 9, 0, 0 }, { 0, 18, 0 } } }, + { { { 9, 0, 1 }, { 0, 18, 1 } } }, + { { { 9, 0, 2 }, { 0, 18, 2 } } }, + { { { 9, 0, 3 }, { 0, 19, 1 } } }, + { { { 9, 0, 4 }, { 0, 19, 0 } } }, + { { { 10, 0, 3 }, { 0, 19, 1 } } }, + { { { 10, 0, 2 }, { 0, 19, 2 } } }, + { { { 10, 0, 1 }, { 0, 20, 1 } } }, + { { { 10, 0, 0 }, { 0, 20, 0 } } }, + { { { 10, 0, 1 }, { 0, 20, 1 } } }, + { { { 10, 0, 2 }, { 0, 20, 2 } } }, + { { { 10, 0, 3 }, { 0, 21, 1 } } }, + { { { 10, 0, 4 }, { 0, 21, 0 } } }, + { { { 11, 0, 3 }, { 0, 21, 1 } } }, + { { { 11, 0, 2 }, { 0, 21, 2 } } }, + { { { 11, 0, 1 }, { 0, 22, 1 } } }, + { { { 11, 0, 0 }, { 0, 22, 0 } } }, + { { { 11, 0, 1 }, { 0, 22, 1 } } }, + { { { 11, 0, 2 }, { 0, 22, 2 } } }, + { { { 11, 0, 3 }, { 0, 23, 1 } } }, + { { { 11, 0, 4 }, { 0, 23, 0 } } }, + { { { 12, 0, 4 }, { 0, 23, 1 } } }, + { { { 12, 0, 3 }, { 0, 23, 2 } } }, + { { { 12, 0, 2 }, { 1, 23, 1 } } }, + { { { 12, 0, 1 }, { 1, 23, 0 } } }, + { { { 12, 0, 0 }, { 0, 24, 0 } } }, + { { { 12, 0, 1 }, { 0, 24, 1 } } }, + { { { 12, 0, 2 }, { 2, 23, 1 } } }, + { { { 12, 0, 3 }, { 2, 23, 0 } } }, + { { { 12, 0, 4 }, { 0, 25, 0 } } }, + { { { 13, 0, 3 }, { 0, 25, 1 } } }, + { { { 13, 0, 2 }, { 3, 23, 1 } } }, + { { { 13, 0, 1 }, { 3, 23, 0 } } }, + { { { 13, 0, 0 }, { 0, 26, 0 } } }, + { { { 13, 0, 1 }, { 0, 26, 1 } } }, + { { { 13, 0, 2 }, { 0, 26, 2 } } }, + { { { 13, 0, 3 }, { 0, 27, 1 } } }, + { { { 13, 0, 4 }, { 0, 27, 0 } } }, + { { { 14, 0, 3 }, { 0, 27, 1 } } }, + { { { 14, 0, 2 }, { 0, 27, 2 } } }, + { { { 14, 0, 1 }, { 0, 28, 1 } } }, + { { { 14, 0, 0 }, { 0, 28, 0 } } }, + { { { 14, 0, 1 }, { 0, 28, 1 } } }, + { { { 14, 0, 2 }, { 0, 28, 2 } } }, + { { { 14, 0, 3 }, { 0, 29, 1 } } }, + { { { 14, 0, 4 }, { 0, 29, 0 } } }, + { { { 15, 0, 3 }, { 0, 29, 1 } } }, + { { { 15, 0, 2 }, { 0, 29, 2 } } }, + { { { 15, 0, 1 }, { 0, 30, 1 } } }, + { { { 15, 0, 0 }, { 0, 30, 0 } } }, + { { { 15, 0, 1 }, { 0, 30, 1 } } }, + { { { 15, 0, 2 }, { 0, 30, 2 } } }, + { { { 15, 0, 3 }, { 0, 31, 1 } } }, + { { { 15, 0, 4 }, { 0, 31, 0 } } }, + { { { 16, 0, 4 }, { 0, 31, 1 } } }, + { { { 16, 0, 3 }, { 0, 31, 2 } } }, + { { { 16, 0, 2 }, { 1, 31, 1 } } }, + { { { 16, 0, 1 }, { 1, 31, 0 } } }, + { { { 16, 0, 0 }, { 4, 28, 0 } } }, + { { { 16, 0, 1 }, { 4, 28, 1 } } }, + { { { 16, 0, 2 }, { 2, 31, 1 } } }, + { { { 16, 0, 3 }, { 2, 31, 0 } } }, + { { { 16, 0, 4 }, { 4, 29, 0 } } }, + { { { 17, 0, 3 }, { 4, 29, 1 } } }, + { { { 17, 0, 2 }, { 3, 31, 1 } } }, + { { { 17, 0, 1 }, { 3, 31, 0 } } }, + { { { 17, 0, 0 }, { 4, 30, 0 } } }, + { { { 17, 0, 1 }, { 4, 30, 1 } } }, + { { { 17, 0, 2 }, { 4, 30, 2 } } }, + { { { 17, 0, 3 }, { 4, 31, 1 } } }, + { { { 17, 0, 4 }, { 4, 31, 0 } } }, + { { { 18, 0, 3 }, { 4, 31, 1 } } }, + { { { 18, 0, 2 }, { 4, 31, 2 } } }, + { { { 18, 0, 1 }, { 5, 31, 1 } } }, + { { { 18, 0, 0 }, { 5, 31, 0 } } }, + { { { 18, 0, 1 }, { 5, 31, 1 } } }, + { { { 18, 0, 2 }, { 5, 31, 2 } } }, + { { { 18, 0, 3 }, { 6, 31, 1 } } }, + { { { 18, 0, 4 }, { 6, 31, 0 } } }, + { { { 19, 0, 3 }, { 6, 31, 1 } } }, + { { { 19, 0, 2 }, { 6, 31, 2 } } }, + { { { 19, 0, 1 }, { 7, 31, 1 } } }, + { { { 19, 0, 0 }, { 7, 31, 0 } } }, + { { { 19, 0, 1 }, { 7, 31, 1 } } }, + { { { 19, 0, 2 }, { 7, 31, 2 } } }, + { { { 19, 0, 3 }, { 8, 31, 1 } } }, + { { { 19, 0, 4 }, { 8, 31, 0 } } }, + { { { 20, 0, 4 }, { 8, 31, 1 } } }, + { { { 20, 0, 3 }, { 8, 31, 2 } } }, + { { { 20, 0, 2 }, { 9, 31, 1 } } }, + { { { 20, 0, 1 }, { 9, 31, 0 } } }, + { { { 20, 0, 0 }, { 12, 28, 0 } } }, + { { { 20, 0, 1 }, { 12, 28, 1 } } }, + { { { 20, 0, 2 }, { 10, 31, 1 } } }, + { { { 20, 0, 3 }, { 10, 31, 0 } } }, + { { { 20, 0, 4 }, { 12, 29, 0 } } }, + { { { 21, 0, 3 }, { 12, 29, 1 } } }, + { { { 21, 0, 2 }, { 11, 31, 1 } } }, + { { { 21, 0, 1 }, { 11, 31, 0 } } }, + { { { 21, 0, 0 }, { 12, 30, 0 } } }, + { { { 21, 0, 1 }, { 12, 30, 1 } } }, + { { { 21, 0, 2 }, { 12, 30, 2 } } }, + { { { 21, 0, 3 }, { 12, 31, 1 } } }, + { { { 21, 0, 4 }, { 12, 31, 0 } } }, + { { { 22, 0, 3 }, { 12, 31, 1 } } }, + { { { 22, 0, 2 }, { 12, 31, 2 } } }, + { { { 22, 0, 1 }, { 13, 31, 1 } } }, + { { { 22, 0, 0 }, { 13, 31, 0 } } }, + { { { 22, 0, 1 }, { 13, 31, 1 } } }, + { { { 22, 0, 2 }, { 13, 31, 2 } } }, + { { { 22, 0, 3 }, { 14, 31, 1 } } }, + { { { 22, 0, 4 }, { 14, 31, 0 } } }, + { { { 23, 0, 3 }, { 14, 31, 1 } } }, + { { { 23, 0, 2 }, { 14, 31, 2 } } }, + { { { 23, 0, 1 }, { 15, 31, 1 } } }, + { { { 23, 0, 0 }, { 15, 31, 0 } } }, + { { { 23, 0, 1 }, { 15, 31, 1 } } }, + { { { 23, 0, 2 }, { 15, 31, 2 } } }, + { { { 23, 0, 3 }, { 16, 31, 1 } } }, + { { { 23, 0, 4 }, { 16, 31, 0 } } }, + { { { 24, 0, 4 }, { 16, 31, 1 } } }, + { { { 24, 0, 3 }, { 16, 31, 2 } } }, + { { { 24, 0, 2 }, { 17, 31, 1 } } }, + { { { 24, 0, 1 }, { 17, 31, 0 } } }, + { { { 24, 0, 0 }, { 20, 28, 0 } } }, + { { { 24, 0, 1 }, { 20, 28, 1 } } }, + { { { 24, 0, 2 }, { 18, 31, 1 } } }, + { { { 24, 0, 3 }, { 18, 31, 0 } } }, + { { { 24, 0, 4 }, { 20, 29, 0 } } }, + { { { 25, 0, 3 }, { 20, 29, 1 } } }, + { { { 25, 0, 2 }, { 19, 31, 1 } } }, + { { { 25, 0, 1 }, { 19, 31, 0 } } }, + { { { 25, 0, 0 }, { 20, 30, 0 } } }, + { { { 25, 0, 1 }, { 20, 30, 1 } } }, + { { { 25, 0, 2 }, { 20, 30, 2 } } }, + { { { 25, 0, 3 }, { 20, 31, 1 } } }, + { { { 25, 0, 4 }, { 20, 31, 0 } } }, + { { { 26, 0, 3 }, { 20, 31, 1 } } }, + { { { 26, 0, 2 }, { 20, 31, 2 } } }, + { { { 26, 0, 1 }, { 21, 31, 1 } } }, + { { { 26, 0, 0 }, { 21, 31, 0 } } }, + { { { 26, 0, 1 }, { 21, 31, 1 } } }, + { { { 26, 0, 2 }, { 21, 31, 2 } } }, + { { { 26, 0, 3 }, { 22, 31, 1 } } }, + { { { 26, 0, 4 }, { 22, 31, 0 } } }, + { { { 27, 0, 3 }, { 22, 31, 1 } } }, + { { { 27, 0, 2 }, { 22, 31, 2 } } }, + { { { 27, 0, 1 }, { 23, 31, 1 } } }, + { { { 27, 0, 0 }, { 23, 31, 0 } } }, + { { { 27, 0, 1 }, { 23, 31, 1 } } }, + { { { 27, 0, 2 }, { 23, 31, 2 } } }, + { { { 27, 0, 3 }, { 24, 31, 1 } } }, + { { { 27, 0, 4 }, { 24, 31, 0 } } }, + { { { 28, 0, 4 }, { 24, 31, 1 } } }, + { { { 28, 0, 3 }, { 24, 31, 2 } } }, + { { { 28, 0, 2 }, { 25, 31, 1 } } }, + { { { 28, 0, 1 }, { 25, 31, 0 } } }, + { { { 28, 0, 0 }, { 28, 28, 0 } } }, + { { { 28, 0, 1 }, { 28, 28, 1 } } }, + { { { 28, 0, 2 }, { 26, 31, 1 } } }, + { { { 28, 0, 3 }, { 26, 31, 0 } } }, + { { { 28, 0, 4 }, { 28, 29, 0 } } }, + { { { 29, 0, 3 }, { 28, 29, 1 } } }, + { { { 29, 0, 2 }, { 27, 31, 1 } } }, + { { { 29, 0, 1 }, { 27, 31, 0 } } }, + { { { 29, 0, 0 }, { 28, 30, 0 } } }, + { { { 29, 0, 1 }, { 28, 30, 1 } } }, + { { { 29, 0, 2 }, { 28, 30, 2 } } }, + { { { 29, 0, 3 }, { 28, 31, 1 } } }, + { { { 29, 0, 4 }, { 28, 31, 0 } } }, + { { { 30, 0, 3 }, { 28, 31, 1 } } }, + { { { 30, 0, 2 }, { 28, 31, 2 } } }, + { { { 30, 0, 1 }, { 29, 31, 1 } } }, + { { { 30, 0, 0 }, { 29, 31, 0 } } }, + { { { 30, 0, 1 }, { 29, 31, 1 } } }, + { { { 30, 0, 2 }, { 29, 31, 2 } } }, + { { { 30, 0, 3 }, { 30, 31, 1 } } }, + { { { 30, 0, 4 }, { 30, 31, 0 } } }, + { { { 31, 0, 3 }, { 30, 31, 1 } } }, + { { { 31, 0, 2 }, { 30, 31, 2 } } }, + { { { 31, 0, 1 }, { 31, 31, 1 } } }, + { { { 31, 0, 0 }, { 31, 31, 0 } } } +}; + +static SingleColourLookup const lookup_6_3[] = +{ + { { { 0, 0, 0 }, { 0, 0, 0 } } }, + { { { 0, 0, 1 }, { 0, 1, 1 } } }, + { { { 0, 0, 2 }, { 0, 1, 0 } } }, + { { { 1, 0, 1 }, { 0, 2, 1 } } }, + { { { 1, 0, 0 }, { 0, 2, 0 } } }, + { { { 1, 0, 1 }, { 0, 3, 1 } } }, + { { { 1, 0, 2 }, { 0, 3, 0 } } }, + { { { 2, 0, 1 }, { 0, 4, 1 } } }, + { { { 2, 0, 0 }, { 0, 4, 0 } } }, + { { { 2, 0, 1 }, { 0, 5, 1 } } }, + { { { 2, 0, 2 }, { 0, 5, 0 } } }, + { { { 3, 0, 1 }, { 0, 6, 1 } } }, + { { { 3, 0, 0 }, { 0, 6, 0 } } }, + { { { 3, 0, 1 }, { 0, 7, 1 } } }, + { { { 3, 0, 2 }, { 0, 7, 0 } } }, + { { { 4, 0, 1 }, { 0, 8, 1 } } }, + { { { 4, 0, 0 }, { 0, 8, 0 } } }, + { { { 4, 0, 1 }, { 0, 9, 1 } } }, + { { { 4, 0, 2 }, { 0, 9, 0 } } }, + { { { 5, 0, 1 }, { 0, 10, 1 } } }, + { { { 5, 0, 0 }, { 0, 10, 0 } } }, + { { { 5, 0, 1 }, { 0, 11, 1 } } }, + { { { 5, 0, 2 }, { 0, 11, 0 } } }, + { { { 6, 0, 1 }, { 0, 12, 1 } } }, + { { { 6, 0, 0 }, { 0, 12, 0 } } }, + { { { 6, 0, 1 }, { 0, 13, 1 } } }, + { { { 6, 0, 2 }, { 0, 13, 0 } } }, + { { { 7, 0, 1 }, { 0, 14, 1 } } }, + { { { 7, 0, 0 }, { 0, 14, 0 } } }, + { { { 7, 0, 1 }, { 0, 15, 1 } } }, + { { { 7, 0, 2 }, { 0, 15, 0 } } }, + { { { 8, 0, 1 }, { 0, 16, 1 } } }, + { { { 8, 0, 0 }, { 0, 16, 0 } } }, + { { { 8, 0, 1 }, { 0, 17, 1 } } }, + { { { 8, 0, 2 }, { 0, 17, 0 } } }, + { { { 9, 0, 1 }, { 0, 18, 1 } } }, + { { { 9, 0, 0 }, { 0, 18, 0 } } }, + { { { 9, 0, 1 }, { 0, 19, 1 } } }, + { { { 9, 0, 2 }, { 0, 19, 0 } } }, + { { { 10, 0, 1 }, { 0, 20, 1 } } }, + { { { 10, 0, 0 }, { 0, 20, 0 } } }, + { { { 10, 0, 1 }, { 0, 21, 1 } } }, + { { { 10, 0, 2 }, { 0, 21, 0 } } }, + { { { 11, 0, 1 }, { 0, 22, 1 } } }, + { { { 11, 0, 0 }, { 0, 22, 0 } } }, + { { { 11, 0, 1 }, { 0, 23, 1 } } }, + { { { 11, 0, 2 }, { 0, 23, 0 } } }, + { { { 12, 0, 1 }, { 0, 24, 1 } } }, + { { { 12, 0, 0 }, { 0, 24, 0 } } }, + { { { 12, 0, 1 }, { 0, 25, 1 } } }, + { { { 12, 0, 2 }, { 0, 25, 0 } } }, + { { { 13, 0, 1 }, { 0, 26, 1 } } }, + { { { 13, 0, 0 }, { 0, 26, 0 } } }, + { { { 13, 0, 1 }, { 0, 27, 1 } } }, + { { { 13, 0, 2 }, { 0, 27, 0 } } }, + { { { 14, 0, 1 }, { 0, 28, 1 } } }, + { { { 14, 0, 0 }, { 0, 28, 0 } } }, + { { { 14, 0, 1 }, { 0, 29, 1 } } }, + { { { 14, 0, 2 }, { 0, 29, 0 } } }, + { { { 15, 0, 1 }, { 0, 30, 1 } } }, + { { { 15, 0, 0 }, { 0, 30, 0 } } }, + { { { 15, 0, 1 }, { 0, 31, 1 } } }, + { { { 15, 0, 2 }, { 0, 31, 0 } } }, + { { { 16, 0, 2 }, { 1, 31, 1 } } }, + { { { 16, 0, 1 }, { 1, 31, 0 } } }, + { { { 16, 0, 0 }, { 0, 32, 0 } } }, + { { { 16, 0, 1 }, { 2, 31, 0 } } }, + { { { 16, 0, 2 }, { 0, 33, 0 } } }, + { { { 17, 0, 1 }, { 3, 31, 0 } } }, + { { { 17, 0, 0 }, { 0, 34, 0 } } }, + { { { 17, 0, 1 }, { 4, 31, 0 } } }, + { { { 17, 0, 2 }, { 0, 35, 0 } } }, + { { { 18, 0, 1 }, { 5, 31, 0 } } }, + { { { 18, 0, 0 }, { 0, 36, 0 } } }, + { { { 18, 0, 1 }, { 6, 31, 0 } } }, + { { { 18, 0, 2 }, { 0, 37, 0 } } }, + { { { 19, 0, 1 }, { 7, 31, 0 } } }, + { { { 19, 0, 0 }, { 0, 38, 0 } } }, + { { { 19, 0, 1 }, { 8, 31, 0 } } }, + { { { 19, 0, 2 }, { 0, 39, 0 } } }, + { { { 20, 0, 1 }, { 9, 31, 0 } } }, + { { { 20, 0, 0 }, { 0, 40, 0 } } }, + { { { 20, 0, 1 }, { 10, 31, 0 } } }, + { { { 20, 0, 2 }, { 0, 41, 0 } } }, + { { { 21, 0, 1 }, { 11, 31, 0 } } }, + { { { 21, 0, 0 }, { 0, 42, 0 } } }, + { { { 21, 0, 1 }, { 12, 31, 0 } } }, + { { { 21, 0, 2 }, { 0, 43, 0 } } }, + { { { 22, 0, 1 }, { 13, 31, 0 } } }, + { { { 22, 0, 0 }, { 0, 44, 0 } } }, + { { { 22, 0, 1 }, { 14, 31, 0 } } }, + { { { 22, 0, 2 }, { 0, 45, 0 } } }, + { { { 23, 0, 1 }, { 15, 31, 0 } } }, + { { { 23, 0, 0 }, { 0, 46, 0 } } }, + { { { 23, 0, 1 }, { 0, 47, 1 } } }, + { { { 23, 0, 2 }, { 0, 47, 0 } } }, + { { { 24, 0, 1 }, { 0, 48, 1 } } }, + { { { 24, 0, 0 }, { 0, 48, 0 } } }, + { { { 24, 0, 1 }, { 0, 49, 1 } } }, + { { { 24, 0, 2 }, { 0, 49, 0 } } }, + { { { 25, 0, 1 }, { 0, 50, 1 } } }, + { { { 25, 0, 0 }, { 0, 50, 0 } } }, + { { { 25, 0, 1 }, { 0, 51, 1 } } }, + { { { 25, 0, 2 }, { 0, 51, 0 } } }, + { { { 26, 0, 1 }, { 0, 52, 1 } } }, + { { { 26, 0, 0 }, { 0, 52, 0 } } }, + { { { 26, 0, 1 }, { 0, 53, 1 } } }, + { { { 26, 0, 2 }, { 0, 53, 0 } } }, + { { { 27, 0, 1 }, { 0, 54, 1 } } }, + { { { 27, 0, 0 }, { 0, 54, 0 } } }, + { { { 27, 0, 1 }, { 0, 55, 1 } } }, + { { { 27, 0, 2 }, { 0, 55, 0 } } }, + { { { 28, 0, 1 }, { 0, 56, 1 } } }, + { { { 28, 0, 0 }, { 0, 56, 0 } } }, + { { { 28, 0, 1 }, { 0, 57, 1 } } }, + { { { 28, 0, 2 }, { 0, 57, 0 } } }, + { { { 29, 0, 1 }, { 0, 58, 1 } } }, + { { { 29, 0, 0 }, { 0, 58, 0 } } }, + { { { 29, 0, 1 }, { 0, 59, 1 } } }, + { { { 29, 0, 2 }, { 0, 59, 0 } } }, + { { { 30, 0, 1 }, { 0, 60, 1 } } }, + { { { 30, 0, 0 }, { 0, 60, 0 } } }, + { { { 30, 0, 1 }, { 0, 61, 1 } } }, + { { { 30, 0, 2 }, { 0, 61, 0 } } }, + { { { 31, 0, 1 }, { 0, 62, 1 } } }, + { { { 31, 0, 0 }, { 0, 62, 0 } } }, + { { { 31, 0, 1 }, { 0, 63, 1 } } }, + { { { 31, 0, 2 }, { 0, 63, 0 } } }, + { { { 32, 0, 2 }, { 1, 63, 1 } } }, + { { { 32, 0, 1 }, { 1, 63, 0 } } }, + { { { 32, 0, 0 }, { 16, 48, 0 } } }, + { { { 32, 0, 1 }, { 2, 63, 0 } } }, + { { { 32, 0, 2 }, { 16, 49, 0 } } }, + { { { 33, 0, 1 }, { 3, 63, 0 } } }, + { { { 33, 0, 0 }, { 16, 50, 0 } } }, + { { { 33, 0, 1 }, { 4, 63, 0 } } }, + { { { 33, 0, 2 }, { 16, 51, 0 } } }, + { { { 34, 0, 1 }, { 5, 63, 0 } } }, + { { { 34, 0, 0 }, { 16, 52, 0 } } }, + { { { 34, 0, 1 }, { 6, 63, 0 } } }, + { { { 34, 0, 2 }, { 16, 53, 0 } } }, + { { { 35, 0, 1 }, { 7, 63, 0 } } }, + { { { 35, 0, 0 }, { 16, 54, 0 } } }, + { { { 35, 0, 1 }, { 8, 63, 0 } } }, + { { { 35, 0, 2 }, { 16, 55, 0 } } }, + { { { 36, 0, 1 }, { 9, 63, 0 } } }, + { { { 36, 0, 0 }, { 16, 56, 0 } } }, + { { { 36, 0, 1 }, { 10, 63, 0 } } }, + { { { 36, 0, 2 }, { 16, 57, 0 } } }, + { { { 37, 0, 1 }, { 11, 63, 0 } } }, + { { { 37, 0, 0 }, { 16, 58, 0 } } }, + { { { 37, 0, 1 }, { 12, 63, 0 } } }, + { { { 37, 0, 2 }, { 16, 59, 0 } } }, + { { { 38, 0, 1 }, { 13, 63, 0 } } }, + { { { 38, 0, 0 }, { 16, 60, 0 } } }, + { { { 38, 0, 1 }, { 14, 63, 0 } } }, + { { { 38, 0, 2 }, { 16, 61, 0 } } }, + { { { 39, 0, 1 }, { 15, 63, 0 } } }, + { { { 39, 0, 0 }, { 16, 62, 0 } } }, + { { { 39, 0, 1 }, { 16, 63, 1 } } }, + { { { 39, 0, 2 }, { 16, 63, 0 } } }, + { { { 40, 0, 1 }, { 17, 63, 1 } } }, + { { { 40, 0, 0 }, { 17, 63, 0 } } }, + { { { 40, 0, 1 }, { 18, 63, 1 } } }, + { { { 40, 0, 2 }, { 18, 63, 0 } } }, + { { { 41, 0, 1 }, { 19, 63, 1 } } }, + { { { 41, 0, 0 }, { 19, 63, 0 } } }, + { { { 41, 0, 1 }, { 20, 63, 1 } } }, + { { { 41, 0, 2 }, { 20, 63, 0 } } }, + { { { 42, 0, 1 }, { 21, 63, 1 } } }, + { { { 42, 0, 0 }, { 21, 63, 0 } } }, + { { { 42, 0, 1 }, { 22, 63, 1 } } }, + { { { 42, 0, 2 }, { 22, 63, 0 } } }, + { { { 43, 0, 1 }, { 23, 63, 1 } } }, + { { { 43, 0, 0 }, { 23, 63, 0 } } }, + { { { 43, 0, 1 }, { 24, 63, 1 } } }, + { { { 43, 0, 2 }, { 24, 63, 0 } } }, + { { { 44, 0, 1 }, { 25, 63, 1 } } }, + { { { 44, 0, 0 }, { 25, 63, 0 } } }, + { { { 44, 0, 1 }, { 26, 63, 1 } } }, + { { { 44, 0, 2 }, { 26, 63, 0 } } }, + { { { 45, 0, 1 }, { 27, 63, 1 } } }, + { { { 45, 0, 0 }, { 27, 63, 0 } } }, + { { { 45, 0, 1 }, { 28, 63, 1 } } }, + { { { 45, 0, 2 }, { 28, 63, 0 } } }, + { { { 46, 0, 1 }, { 29, 63, 1 } } }, + { { { 46, 0, 0 }, { 29, 63, 0 } } }, + { { { 46, 0, 1 }, { 30, 63, 1 } } }, + { { { 46, 0, 2 }, { 30, 63, 0 } } }, + { { { 47, 0, 1 }, { 31, 63, 1 } } }, + { { { 47, 0, 0 }, { 31, 63, 0 } } }, + { { { 47, 0, 1 }, { 32, 63, 1 } } }, + { { { 47, 0, 2 }, { 32, 63, 0 } } }, + { { { 48, 0, 2 }, { 33, 63, 1 } } }, + { { { 48, 0, 1 }, { 33, 63, 0 } } }, + { { { 48, 0, 0 }, { 48, 48, 0 } } }, + { { { 48, 0, 1 }, { 34, 63, 0 } } }, + { { { 48, 0, 2 }, { 48, 49, 0 } } }, + { { { 49, 0, 1 }, { 35, 63, 0 } } }, + { { { 49, 0, 0 }, { 48, 50, 0 } } }, + { { { 49, 0, 1 }, { 36, 63, 0 } } }, + { { { 49, 0, 2 }, { 48, 51, 0 } } }, + { { { 50, 0, 1 }, { 37, 63, 0 } } }, + { { { 50, 0, 0 }, { 48, 52, 0 } } }, + { { { 50, 0, 1 }, { 38, 63, 0 } } }, + { { { 50, 0, 2 }, { 48, 53, 0 } } }, + { { { 51, 0, 1 }, { 39, 63, 0 } } }, + { { { 51, 0, 0 }, { 48, 54, 0 } } }, + { { { 51, 0, 1 }, { 40, 63, 0 } } }, + { { { 51, 0, 2 }, { 48, 55, 0 } } }, + { { { 52, 0, 1 }, { 41, 63, 0 } } }, + { { { 52, 0, 0 }, { 48, 56, 0 } } }, + { { { 52, 0, 1 }, { 42, 63, 0 } } }, + { { { 52, 0, 2 }, { 48, 57, 0 } } }, + { { { 53, 0, 1 }, { 43, 63, 0 } } }, + { { { 53, 0, 0 }, { 48, 58, 0 } } }, + { { { 53, 0, 1 }, { 44, 63, 0 } } }, + { { { 53, 0, 2 }, { 48, 59, 0 } } }, + { { { 54, 0, 1 }, { 45, 63, 0 } } }, + { { { 54, 0, 0 }, { 48, 60, 0 } } }, + { { { 54, 0, 1 }, { 46, 63, 0 } } }, + { { { 54, 0, 2 }, { 48, 61, 0 } } }, + { { { 55, 0, 1 }, { 47, 63, 0 } } }, + { { { 55, 0, 0 }, { 48, 62, 0 } } }, + { { { 55, 0, 1 }, { 48, 63, 1 } } }, + { { { 55, 0, 2 }, { 48, 63, 0 } } }, + { { { 56, 0, 1 }, { 49, 63, 1 } } }, + { { { 56, 0, 0 }, { 49, 63, 0 } } }, + { { { 56, 0, 1 }, { 50, 63, 1 } } }, + { { { 56, 0, 2 }, { 50, 63, 0 } } }, + { { { 57, 0, 1 }, { 51, 63, 1 } } }, + { { { 57, 0, 0 }, { 51, 63, 0 } } }, + { { { 57, 0, 1 }, { 52, 63, 1 } } }, + { { { 57, 0, 2 }, { 52, 63, 0 } } }, + { { { 58, 0, 1 }, { 53, 63, 1 } } }, + { { { 58, 0, 0 }, { 53, 63, 0 } } }, + { { { 58, 0, 1 }, { 54, 63, 1 } } }, + { { { 58, 0, 2 }, { 54, 63, 0 } } }, + { { { 59, 0, 1 }, { 55, 63, 1 } } }, + { { { 59, 0, 0 }, { 55, 63, 0 } } }, + { { { 59, 0, 1 }, { 56, 63, 1 } } }, + { { { 59, 0, 2 }, { 56, 63, 0 } } }, + { { { 60, 0, 1 }, { 57, 63, 1 } } }, + { { { 60, 0, 0 }, { 57, 63, 0 } } }, + { { { 60, 0, 1 }, { 58, 63, 1 } } }, + { { { 60, 0, 2 }, { 58, 63, 0 } } }, + { { { 61, 0, 1 }, { 59, 63, 1 } } }, + { { { 61, 0, 0 }, { 59, 63, 0 } } }, + { { { 61, 0, 1 }, { 60, 63, 1 } } }, + { { { 61, 0, 2 }, { 60, 63, 0 } } }, + { { { 62, 0, 1 }, { 61, 63, 1 } } }, + { { { 62, 0, 0 }, { 61, 63, 0 } } }, + { { { 62, 0, 1 }, { 62, 63, 1 } } }, + { { { 62, 0, 2 }, { 62, 63, 0 } } }, + { { { 63, 0, 1 }, { 63, 63, 1 } } }, + { { { 63, 0, 0 }, { 63, 63, 0 } } } +}; + +static SingleColourLookup const lookup_5_4[] = +{ + { { { 0, 0, 0 }, { 0, 0, 0 } } }, + { { { 0, 0, 1 }, { 0, 1, 1 } } }, + { { { 0, 0, 2 }, { 0, 1, 0 } } }, + { { { 0, 0, 3 }, { 0, 1, 1 } } }, + { { { 0, 0, 4 }, { 0, 2, 1 } } }, + { { { 1, 0, 3 }, { 0, 2, 0 } } }, + { { { 1, 0, 2 }, { 0, 2, 1 } } }, + { { { 1, 0, 1 }, { 0, 3, 1 } } }, + { { { 1, 0, 0 }, { 0, 3, 0 } } }, + { { { 1, 0, 1 }, { 1, 2, 1 } } }, + { { { 1, 0, 2 }, { 1, 2, 0 } } }, + { { { 1, 0, 3 }, { 0, 4, 0 } } }, + { { { 1, 0, 4 }, { 0, 5, 1 } } }, + { { { 2, 0, 3 }, { 0, 5, 0 } } }, + { { { 2, 0, 2 }, { 0, 5, 1 } } }, + { { { 2, 0, 1 }, { 0, 6, 1 } } }, + { { { 2, 0, 0 }, { 0, 6, 0 } } }, + { { { 2, 0, 1 }, { 2, 3, 1 } } }, + { { { 2, 0, 2 }, { 2, 3, 0 } } }, + { { { 2, 0, 3 }, { 0, 7, 0 } } }, + { { { 2, 0, 4 }, { 1, 6, 1 } } }, + { { { 3, 0, 3 }, { 1, 6, 0 } } }, + { { { 3, 0, 2 }, { 0, 8, 0 } } }, + { { { 3, 0, 1 }, { 0, 9, 1 } } }, + { { { 3, 0, 0 }, { 0, 9, 0 } } }, + { { { 3, 0, 1 }, { 0, 9, 1 } } }, + { { { 3, 0, 2 }, { 0, 10, 1 } } }, + { { { 3, 0, 3 }, { 0, 10, 0 } } }, + { { { 3, 0, 4 }, { 2, 7, 1 } } }, + { { { 4, 0, 4 }, { 2, 7, 0 } } }, + { { { 4, 0, 3 }, { 0, 11, 0 } } }, + { { { 4, 0, 2 }, { 1, 10, 1 } } }, + { { { 4, 0, 1 }, { 1, 10, 0 } } }, + { { { 4, 0, 0 }, { 0, 12, 0 } } }, + { { { 4, 0, 1 }, { 0, 13, 1 } } }, + { { { 4, 0, 2 }, { 0, 13, 0 } } }, + { { { 4, 0, 3 }, { 0, 13, 1 } } }, + { { { 4, 0, 4 }, { 0, 14, 1 } } }, + { { { 5, 0, 3 }, { 0, 14, 0 } } }, + { { { 5, 0, 2 }, { 2, 11, 1 } } }, + { { { 5, 0, 1 }, { 2, 11, 0 } } }, + { { { 5, 0, 0 }, { 0, 15, 0 } } }, + { { { 5, 0, 1 }, { 1, 14, 1 } } }, + { { { 5, 0, 2 }, { 1, 14, 0 } } }, + { { { 5, 0, 3 }, { 0, 16, 0 } } }, + { { { 5, 0, 4 }, { 0, 17, 1 } } }, + { { { 6, 0, 3 }, { 0, 17, 0 } } }, + { { { 6, 0, 2 }, { 0, 17, 1 } } }, + { { { 6, 0, 1 }, { 0, 18, 1 } } }, + { { { 6, 0, 0 }, { 0, 18, 0 } } }, + { { { 6, 0, 1 }, { 2, 15, 1 } } }, + { { { 6, 0, 2 }, { 2, 15, 0 } } }, + { { { 6, 0, 3 }, { 0, 19, 0 } } }, + { { { 6, 0, 4 }, { 1, 18, 1 } } }, + { { { 7, 0, 3 }, { 1, 18, 0 } } }, + { { { 7, 0, 2 }, { 0, 20, 0 } } }, + { { { 7, 0, 1 }, { 0, 21, 1 } } }, + { { { 7, 0, 0 }, { 0, 21, 0 } } }, + { { { 7, 0, 1 }, { 0, 21, 1 } } }, + { { { 7, 0, 2 }, { 0, 22, 1 } } }, + { { { 7, 0, 3 }, { 0, 22, 0 } } }, + { { { 7, 0, 4 }, { 2, 19, 1 } } }, + { { { 8, 0, 4 }, { 2, 19, 0 } } }, + { { { 8, 0, 3 }, { 0, 23, 0 } } }, + { { { 8, 0, 2 }, { 1, 22, 1 } } }, + { { { 8, 0, 1 }, { 1, 22, 0 } } }, + { { { 8, 0, 0 }, { 0, 24, 0 } } }, + { { { 8, 0, 1 }, { 0, 25, 1 } } }, + { { { 8, 0, 2 }, { 0, 25, 0 } } }, + { { { 8, 0, 3 }, { 0, 25, 1 } } }, + { { { 8, 0, 4 }, { 0, 26, 1 } } }, + { { { 9, 0, 3 }, { 0, 26, 0 } } }, + { { { 9, 0, 2 }, { 2, 23, 1 } } }, + { { { 9, 0, 1 }, { 2, 23, 0 } } }, + { { { 9, 0, 0 }, { 0, 27, 0 } } }, + { { { 9, 0, 1 }, { 1, 26, 1 } } }, + { { { 9, 0, 2 }, { 1, 26, 0 } } }, + { { { 9, 0, 3 }, { 0, 28, 0 } } }, + { { { 9, 0, 4 }, { 0, 29, 1 } } }, + { { { 10, 0, 3 }, { 0, 29, 0 } } }, + { { { 10, 0, 2 }, { 0, 29, 1 } } }, + { { { 10, 0, 1 }, { 0, 30, 1 } } }, + { { { 10, 0, 0 }, { 0, 30, 0 } } }, + { { { 10, 0, 1 }, { 2, 27, 1 } } }, + { { { 10, 0, 2 }, { 2, 27, 0 } } }, + { { { 10, 0, 3 }, { 0, 31, 0 } } }, + { { { 10, 0, 4 }, { 1, 30, 1 } } }, + { { { 11, 0, 3 }, { 1, 30, 0 } } }, + { { { 11, 0, 2 }, { 4, 24, 0 } } }, + { { { 11, 0, 1 }, { 1, 31, 1 } } }, + { { { 11, 0, 0 }, { 1, 31, 0 } } }, + { { { 11, 0, 1 }, { 1, 31, 1 } } }, + { { { 11, 0, 2 }, { 2, 30, 1 } } }, + { { { 11, 0, 3 }, { 2, 30, 0 } } }, + { { { 11, 0, 4 }, { 2, 31, 1 } } }, + { { { 12, 0, 4 }, { 2, 31, 0 } } }, + { { { 12, 0, 3 }, { 4, 27, 0 } } }, + { { { 12, 0, 2 }, { 3, 30, 1 } } }, + { { { 12, 0, 1 }, { 3, 30, 0 } } }, + { { { 12, 0, 0 }, { 4, 28, 0 } } }, + { { { 12, 0, 1 }, { 3, 31, 1 } } }, + { { { 12, 0, 2 }, { 3, 31, 0 } } }, + { { { 12, 0, 3 }, { 3, 31, 1 } } }, + { { { 12, 0, 4 }, { 4, 30, 1 } } }, + { { { 13, 0, 3 }, { 4, 30, 0 } } }, + { { { 13, 0, 2 }, { 6, 27, 1 } } }, + { { { 13, 0, 1 }, { 6, 27, 0 } } }, + { { { 13, 0, 0 }, { 4, 31, 0 } } }, + { { { 13, 0, 1 }, { 5, 30, 1 } } }, + { { { 13, 0, 2 }, { 5, 30, 0 } } }, + { { { 13, 0, 3 }, { 8, 24, 0 } } }, + { { { 13, 0, 4 }, { 5, 31, 1 } } }, + { { { 14, 0, 3 }, { 5, 31, 0 } } }, + { { { 14, 0, 2 }, { 5, 31, 1 } } }, + { { { 14, 0, 1 }, { 6, 30, 1 } } }, + { { { 14, 0, 0 }, { 6, 30, 0 } } }, + { { { 14, 0, 1 }, { 6, 31, 1 } } }, + { { { 14, 0, 2 }, { 6, 31, 0 } } }, + { { { 14, 0, 3 }, { 8, 27, 0 } } }, + { { { 14, 0, 4 }, { 7, 30, 1 } } }, + { { { 15, 0, 3 }, { 7, 30, 0 } } }, + { { { 15, 0, 2 }, { 8, 28, 0 } } }, + { { { 15, 0, 1 }, { 7, 31, 1 } } }, + { { { 15, 0, 0 }, { 7, 31, 0 } } }, + { { { 15, 0, 1 }, { 7, 31, 1 } } }, + { { { 15, 0, 2 }, { 8, 30, 1 } } }, + { { { 15, 0, 3 }, { 8, 30, 0 } } }, + { { { 15, 0, 4 }, { 10, 27, 1 } } }, + { { { 16, 0, 4 }, { 10, 27, 0 } } }, + { { { 16, 0, 3 }, { 8, 31, 0 } } }, + { { { 16, 0, 2 }, { 9, 30, 1 } } }, + { { { 16, 0, 1 }, { 9, 30, 0 } } }, + { { { 16, 0, 0 }, { 12, 24, 0 } } }, + { { { 16, 0, 1 }, { 9, 31, 1 } } }, + { { { 16, 0, 2 }, { 9, 31, 0 } } }, + { { { 16, 0, 3 }, { 9, 31, 1 } } }, + { { { 16, 0, 4 }, { 10, 30, 1 } } }, + { { { 17, 0, 3 }, { 10, 30, 0 } } }, + { { { 17, 0, 2 }, { 10, 31, 1 } } }, + { { { 17, 0, 1 }, { 10, 31, 0 } } }, + { { { 17, 0, 0 }, { 12, 27, 0 } } }, + { { { 17, 0, 1 }, { 11, 30, 1 } } }, + { { { 17, 0, 2 }, { 11, 30, 0 } } }, + { { { 17, 0, 3 }, { 12, 28, 0 } } }, + { { { 17, 0, 4 }, { 11, 31, 1 } } }, + { { { 18, 0, 3 }, { 11, 31, 0 } } }, + { { { 18, 0, 2 }, { 11, 31, 1 } } }, + { { { 18, 0, 1 }, { 12, 30, 1 } } }, + { { { 18, 0, 0 }, { 12, 30, 0 } } }, + { { { 18, 0, 1 }, { 14, 27, 1 } } }, + { { { 18, 0, 2 }, { 14, 27, 0 } } }, + { { { 18, 0, 3 }, { 12, 31, 0 } } }, + { { { 18, 0, 4 }, { 13, 30, 1 } } }, + { { { 19, 0, 3 }, { 13, 30, 0 } } }, + { { { 19, 0, 2 }, { 16, 24, 0 } } }, + { { { 19, 0, 1 }, { 13, 31, 1 } } }, + { { { 19, 0, 0 }, { 13, 31, 0 } } }, + { { { 19, 0, 1 }, { 13, 31, 1 } } }, + { { { 19, 0, 2 }, { 14, 30, 1 } } }, + { { { 19, 0, 3 }, { 14, 30, 0 } } }, + { { { 19, 0, 4 }, { 14, 31, 1 } } }, + { { { 20, 0, 4 }, { 14, 31, 0 } } }, + { { { 20, 0, 3 }, { 16, 27, 0 } } }, + { { { 20, 0, 2 }, { 15, 30, 1 } } }, + { { { 20, 0, 1 }, { 15, 30, 0 } } }, + { { { 20, 0, 0 }, { 16, 28, 0 } } }, + { { { 20, 0, 1 }, { 15, 31, 1 } } }, + { { { 20, 0, 2 }, { 15, 31, 0 } } }, + { { { 20, 0, 3 }, { 15, 31, 1 } } }, + { { { 20, 0, 4 }, { 16, 30, 1 } } }, + { { { 21, 0, 3 }, { 16, 30, 0 } } }, + { { { 21, 0, 2 }, { 18, 27, 1 } } }, + { { { 21, 0, 1 }, { 18, 27, 0 } } }, + { { { 21, 0, 0 }, { 16, 31, 0 } } }, + { { { 21, 0, 1 }, { 17, 30, 1 } } }, + { { { 21, 0, 2 }, { 17, 30, 0 } } }, + { { { 21, 0, 3 }, { 20, 24, 0 } } }, + { { { 21, 0, 4 }, { 17, 31, 1 } } }, + { { { 22, 0, 3 }, { 17, 31, 0 } } }, + { { { 22, 0, 2 }, { 17, 31, 1 } } }, + { { { 22, 0, 1 }, { 18, 30, 1 } } }, + { { { 22, 0, 0 }, { 18, 30, 0 } } }, + { { { 22, 0, 1 }, { 18, 31, 1 } } }, + { { { 22, 0, 2 }, { 18, 31, 0 } } }, + { { { 22, 0, 3 }, { 20, 27, 0 } } }, + { { { 22, 0, 4 }, { 19, 30, 1 } } }, + { { { 23, 0, 3 }, { 19, 30, 0 } } }, + { { { 23, 0, 2 }, { 20, 28, 0 } } }, + { { { 23, 0, 1 }, { 19, 31, 1 } } }, + { { { 23, 0, 0 }, { 19, 31, 0 } } }, + { { { 23, 0, 1 }, { 19, 31, 1 } } }, + { { { 23, 0, 2 }, { 20, 30, 1 } } }, + { { { 23, 0, 3 }, { 20, 30, 0 } } }, + { { { 23, 0, 4 }, { 22, 27, 1 } } }, + { { { 24, 0, 4 }, { 22, 27, 0 } } }, + { { { 24, 0, 3 }, { 20, 31, 0 } } }, + { { { 24, 0, 2 }, { 21, 30, 1 } } }, + { { { 24, 0, 1 }, { 21, 30, 0 } } }, + { { { 24, 0, 0 }, { 24, 24, 0 } } }, + { { { 24, 0, 1 }, { 21, 31, 1 } } }, + { { { 24, 0, 2 }, { 21, 31, 0 } } }, + { { { 24, 0, 3 }, { 21, 31, 1 } } }, + { { { 24, 0, 4 }, { 22, 30, 1 } } }, + { { { 25, 0, 3 }, { 22, 30, 0 } } }, + { { { 25, 0, 2 }, { 22, 31, 1 } } }, + { { { 25, 0, 1 }, { 22, 31, 0 } } }, + { { { 25, 0, 0 }, { 24, 27, 0 } } }, + { { { 25, 0, 1 }, { 23, 30, 1 } } }, + { { { 25, 0, 2 }, { 23, 30, 0 } } }, + { { { 25, 0, 3 }, { 24, 28, 0 } } }, + { { { 25, 0, 4 }, { 23, 31, 1 } } }, + { { { 26, 0, 3 }, { 23, 31, 0 } } }, + { { { 26, 0, 2 }, { 23, 31, 1 } } }, + { { { 26, 0, 1 }, { 24, 30, 1 } } }, + { { { 26, 0, 0 }, { 24, 30, 0 } } }, + { { { 26, 0, 1 }, { 26, 27, 1 } } }, + { { { 26, 0, 2 }, { 26, 27, 0 } } }, + { { { 26, 0, 3 }, { 24, 31, 0 } } }, + { { { 26, 0, 4 }, { 25, 30, 1 } } }, + { { { 27, 0, 3 }, { 25, 30, 0 } } }, + { { { 27, 0, 2 }, { 28, 24, 0 } } }, + { { { 27, 0, 1 }, { 25, 31, 1 } } }, + { { { 27, 0, 0 }, { 25, 31, 0 } } }, + { { { 27, 0, 1 }, { 25, 31, 1 } } }, + { { { 27, 0, 2 }, { 26, 30, 1 } } }, + { { { 27, 0, 3 }, { 26, 30, 0 } } }, + { { { 27, 0, 4 }, { 26, 31, 1 } } }, + { { { 28, 0, 4 }, { 26, 31, 0 } } }, + { { { 28, 0, 3 }, { 28, 27, 0 } } }, + { { { 28, 0, 2 }, { 27, 30, 1 } } }, + { { { 28, 0, 1 }, { 27, 30, 0 } } }, + { { { 28, 0, 0 }, { 28, 28, 0 } } }, + { { { 28, 0, 1 }, { 27, 31, 1 } } }, + { { { 28, 0, 2 }, { 27, 31, 0 } } }, + { { { 28, 0, 3 }, { 27, 31, 1 } } }, + { { { 28, 0, 4 }, { 28, 30, 1 } } }, + { { { 29, 0, 3 }, { 28, 30, 0 } } }, + { { { 29, 0, 2 }, { 30, 27, 1 } } }, + { { { 29, 0, 1 }, { 30, 27, 0 } } }, + { { { 29, 0, 0 }, { 28, 31, 0 } } }, + { { { 29, 0, 1 }, { 29, 30, 1 } } }, + { { { 29, 0, 2 }, { 29, 30, 0 } } }, + { { { 29, 0, 3 }, { 29, 30, 1 } } }, + { { { 29, 0, 4 }, { 29, 31, 1 } } }, + { { { 30, 0, 3 }, { 29, 31, 0 } } }, + { { { 30, 0, 2 }, { 29, 31, 1 } } }, + { { { 30, 0, 1 }, { 30, 30, 1 } } }, + { { { 30, 0, 0 }, { 30, 30, 0 } } }, + { { { 30, 0, 1 }, { 30, 31, 1 } } }, + { { { 30, 0, 2 }, { 30, 31, 0 } } }, + { { { 30, 0, 3 }, { 30, 31, 1 } } }, + { { { 30, 0, 4 }, { 31, 30, 1 } } }, + { { { 31, 0, 3 }, { 31, 30, 0 } } }, + { { { 31, 0, 2 }, { 31, 30, 1 } } }, + { { { 31, 0, 1 }, { 31, 31, 1 } } }, + { { { 31, 0, 0 }, { 31, 31, 0 } } } +}; + +static SingleColourLookup const lookup_6_4[] = +{ + { { { 0, 0, 0 }, { 0, 0, 0 } } }, + { { { 0, 0, 1 }, { 0, 1, 0 } } }, + { { { 0, 0, 2 }, { 0, 2, 0 } } }, + { { { 1, 0, 1 }, { 0, 3, 1 } } }, + { { { 1, 0, 0 }, { 0, 3, 0 } } }, + { { { 1, 0, 1 }, { 0, 4, 0 } } }, + { { { 1, 0, 2 }, { 0, 5, 0 } } }, + { { { 2, 0, 1 }, { 0, 6, 1 } } }, + { { { 2, 0, 0 }, { 0, 6, 0 } } }, + { { { 2, 0, 1 }, { 0, 7, 0 } } }, + { { { 2, 0, 2 }, { 0, 8, 0 } } }, + { { { 3, 0, 1 }, { 0, 9, 1 } } }, + { { { 3, 0, 0 }, { 0, 9, 0 } } }, + { { { 3, 0, 1 }, { 0, 10, 0 } } }, + { { { 3, 0, 2 }, { 0, 11, 0 } } }, + { { { 4, 0, 1 }, { 0, 12, 1 } } }, + { { { 4, 0, 0 }, { 0, 12, 0 } } }, + { { { 4, 0, 1 }, { 0, 13, 0 } } }, + { { { 4, 0, 2 }, { 0, 14, 0 } } }, + { { { 5, 0, 1 }, { 0, 15, 1 } } }, + { { { 5, 0, 0 }, { 0, 15, 0 } } }, + { { { 5, 0, 1 }, { 0, 16, 0 } } }, + { { { 5, 0, 2 }, { 1, 15, 0 } } }, + { { { 6, 0, 1 }, { 0, 17, 0 } } }, + { { { 6, 0, 0 }, { 0, 18, 0 } } }, + { { { 6, 0, 1 }, { 0, 19, 0 } } }, + { { { 6, 0, 2 }, { 3, 14, 0 } } }, + { { { 7, 0, 1 }, { 0, 20, 0 } } }, + { { { 7, 0, 0 }, { 0, 21, 0 } } }, + { { { 7, 0, 1 }, { 0, 22, 0 } } }, + { { { 7, 0, 2 }, { 4, 15, 0 } } }, + { { { 8, 0, 1 }, { 0, 23, 0 } } }, + { { { 8, 0, 0 }, { 0, 24, 0 } } }, + { { { 8, 0, 1 }, { 0, 25, 0 } } }, + { { { 8, 0, 2 }, { 6, 14, 0 } } }, + { { { 9, 0, 1 }, { 0, 26, 0 } } }, + { { { 9, 0, 0 }, { 0, 27, 0 } } }, + { { { 9, 0, 1 }, { 0, 28, 0 } } }, + { { { 9, 0, 2 }, { 7, 15, 0 } } }, + { { { 10, 0, 1 }, { 0, 29, 0 } } }, + { { { 10, 0, 0 }, { 0, 30, 0 } } }, + { { { 10, 0, 1 }, { 0, 31, 0 } } }, + { { { 10, 0, 2 }, { 9, 14, 0 } } }, + { { { 11, 0, 1 }, { 0, 32, 0 } } }, + { { { 11, 0, 0 }, { 0, 33, 0 } } }, + { { { 11, 0, 1 }, { 2, 30, 0 } } }, + { { { 11, 0, 2 }, { 0, 34, 0 } } }, + { { { 12, 0, 1 }, { 0, 35, 0 } } }, + { { { 12, 0, 0 }, { 0, 36, 0 } } }, + { { { 12, 0, 1 }, { 3, 31, 0 } } }, + { { { 12, 0, 2 }, { 0, 37, 0 } } }, + { { { 13, 0, 1 }, { 0, 38, 0 } } }, + { { { 13, 0, 0 }, { 0, 39, 0 } } }, + { { { 13, 0, 1 }, { 5, 30, 0 } } }, + { { { 13, 0, 2 }, { 0, 40, 0 } } }, + { { { 14, 0, 1 }, { 0, 41, 0 } } }, + { { { 14, 0, 0 }, { 0, 42, 0 } } }, + { { { 14, 0, 1 }, { 6, 31, 0 } } }, + { { { 14, 0, 2 }, { 0, 43, 0 } } }, + { { { 15, 0, 1 }, { 0, 44, 0 } } }, + { { { 15, 0, 0 }, { 0, 45, 0 } } }, + { { { 15, 0, 1 }, { 8, 30, 0 } } }, + { { { 15, 0, 2 }, { 0, 46, 0 } } }, + { { { 16, 0, 2 }, { 0, 47, 0 } } }, + { { { 16, 0, 1 }, { 1, 46, 0 } } }, + { { { 16, 0, 0 }, { 0, 48, 0 } } }, + { { { 16, 0, 1 }, { 0, 49, 0 } } }, + { { { 16, 0, 2 }, { 0, 50, 0 } } }, + { { { 17, 0, 1 }, { 2, 47, 0 } } }, + { { { 17, 0, 0 }, { 0, 51, 0 } } }, + { { { 17, 0, 1 }, { 0, 52, 0 } } }, + { { { 17, 0, 2 }, { 0, 53, 0 } } }, + { { { 18, 0, 1 }, { 4, 46, 0 } } }, + { { { 18, 0, 0 }, { 0, 54, 0 } } }, + { { { 18, 0, 1 }, { 0, 55, 0 } } }, + { { { 18, 0, 2 }, { 0, 56, 0 } } }, + { { { 19, 0, 1 }, { 5, 47, 0 } } }, + { { { 19, 0, 0 }, { 0, 57, 0 } } }, + { { { 19, 0, 1 }, { 0, 58, 0 } } }, + { { { 19, 0, 2 }, { 0, 59, 0 } } }, + { { { 20, 0, 1 }, { 7, 46, 0 } } }, + { { { 20, 0, 0 }, { 0, 60, 0 } } }, + { { { 20, 0, 1 }, { 0, 61, 0 } } }, + { { { 20, 0, 2 }, { 0, 62, 0 } } }, + { { { 21, 0, 1 }, { 8, 47, 0 } } }, + { { { 21, 0, 0 }, { 0, 63, 0 } } }, + { { { 21, 0, 1 }, { 1, 62, 0 } } }, + { { { 21, 0, 2 }, { 1, 63, 0 } } }, + { { { 22, 0, 1 }, { 10, 46, 0 } } }, + { { { 22, 0, 0 }, { 2, 62, 0 } } }, + { { { 22, 0, 1 }, { 2, 63, 0 } } }, + { { { 22, 0, 2 }, { 3, 62, 0 } } }, + { { { 23, 0, 1 }, { 11, 47, 0 } } }, + { { { 23, 0, 0 }, { 3, 63, 0 } } }, + { { { 23, 0, 1 }, { 4, 62, 0 } } }, + { { { 23, 0, 2 }, { 4, 63, 0 } } }, + { { { 24, 0, 1 }, { 13, 46, 0 } } }, + { { { 24, 0, 0 }, { 5, 62, 0 } } }, + { { { 24, 0, 1 }, { 5, 63, 0 } } }, + { { { 24, 0, 2 }, { 6, 62, 0 } } }, + { { { 25, 0, 1 }, { 14, 47, 0 } } }, + { { { 25, 0, 0 }, { 6, 63, 0 } } }, + { { { 25, 0, 1 }, { 7, 62, 0 } } }, + { { { 25, 0, 2 }, { 7, 63, 0 } } }, + { { { 26, 0, 1 }, { 16, 45, 0 } } }, + { { { 26, 0, 0 }, { 8, 62, 0 } } }, + { { { 26, 0, 1 }, { 8, 63, 0 } } }, + { { { 26, 0, 2 }, { 9, 62, 0 } } }, + { { { 27, 0, 1 }, { 16, 48, 0 } } }, + { { { 27, 0, 0 }, { 9, 63, 0 } } }, + { { { 27, 0, 1 }, { 10, 62, 0 } } }, + { { { 27, 0, 2 }, { 10, 63, 0 } } }, + { { { 28, 0, 1 }, { 16, 51, 0 } } }, + { { { 28, 0, 0 }, { 11, 62, 0 } } }, + { { { 28, 0, 1 }, { 11, 63, 0 } } }, + { { { 28, 0, 2 }, { 12, 62, 0 } } }, + { { { 29, 0, 1 }, { 16, 54, 0 } } }, + { { { 29, 0, 0 }, { 12, 63, 0 } } }, + { { { 29, 0, 1 }, { 13, 62, 0 } } }, + { { { 29, 0, 2 }, { 13, 63, 0 } } }, + { { { 30, 0, 1 }, { 16, 57, 0 } } }, + { { { 30, 0, 0 }, { 14, 62, 0 } } }, + { { { 30, 0, 1 }, { 14, 63, 0 } } }, + { { { 30, 0, 2 }, { 15, 62, 0 } } }, + { { { 31, 0, 1 }, { 16, 60, 0 } } }, + { { { 31, 0, 0 }, { 15, 63, 0 } } }, + { { { 31, 0, 1 }, { 24, 46, 0 } } }, + { { { 31, 0, 2 }, { 16, 62, 0 } } }, + { { { 32, 0, 2 }, { 16, 63, 0 } } }, + { { { 32, 0, 1 }, { 17, 62, 0 } } }, + { { { 32, 0, 0 }, { 25, 47, 0 } } }, + { { { 32, 0, 1 }, { 17, 63, 0 } } }, + { { { 32, 0, 2 }, { 18, 62, 0 } } }, + { { { 33, 0, 1 }, { 18, 63, 0 } } }, + { { { 33, 0, 0 }, { 27, 46, 0 } } }, + { { { 33, 0, 1 }, { 19, 62, 0 } } }, + { { { 33, 0, 2 }, { 19, 63, 0 } } }, + { { { 34, 0, 1 }, { 20, 62, 0 } } }, + { { { 34, 0, 0 }, { 28, 47, 0 } } }, + { { { 34, 0, 1 }, { 20, 63, 0 } } }, + { { { 34, 0, 2 }, { 21, 62, 0 } } }, + { { { 35, 0, 1 }, { 21, 63, 0 } } }, + { { { 35, 0, 0 }, { 30, 46, 0 } } }, + { { { 35, 0, 1 }, { 22, 62, 0 } } }, + { { { 35, 0, 2 }, { 22, 63, 0 } } }, + { { { 36, 0, 1 }, { 23, 62, 0 } } }, + { { { 36, 0, 0 }, { 31, 47, 0 } } }, + { { { 36, 0, 1 }, { 23, 63, 0 } } }, + { { { 36, 0, 2 }, { 24, 62, 0 } } }, + { { { 37, 0, 1 }, { 24, 63, 0 } } }, + { { { 37, 0, 0 }, { 32, 47, 0 } } }, + { { { 37, 0, 1 }, { 25, 62, 0 } } }, + { { { 37, 0, 2 }, { 25, 63, 0 } } }, + { { { 38, 0, 1 }, { 26, 62, 0 } } }, + { { { 38, 0, 0 }, { 32, 50, 0 } } }, + { { { 38, 0, 1 }, { 26, 63, 0 } } }, + { { { 38, 0, 2 }, { 27, 62, 0 } } }, + { { { 39, 0, 1 }, { 27, 63, 0 } } }, + { { { 39, 0, 0 }, { 32, 53, 0 } } }, + { { { 39, 0, 1 }, { 28, 62, 0 } } }, + { { { 39, 0, 2 }, { 28, 63, 0 } } }, + { { { 40, 0, 1 }, { 29, 62, 0 } } }, + { { { 40, 0, 0 }, { 32, 56, 0 } } }, + { { { 40, 0, 1 }, { 29, 63, 0 } } }, + { { { 40, 0, 2 }, { 30, 62, 0 } } }, + { { { 41, 0, 1 }, { 30, 63, 0 } } }, + { { { 41, 0, 0 }, { 32, 59, 0 } } }, + { { { 41, 0, 1 }, { 31, 62, 0 } } }, + { { { 41, 0, 2 }, { 31, 63, 0 } } }, + { { { 42, 0, 1 }, { 32, 61, 0 } } }, + { { { 42, 0, 0 }, { 32, 62, 0 } } }, + { { { 42, 0, 1 }, { 32, 63, 0 } } }, + { { { 42, 0, 2 }, { 41, 46, 0 } } }, + { { { 43, 0, 1 }, { 33, 62, 0 } } }, + { { { 43, 0, 0 }, { 33, 63, 0 } } }, + { { { 43, 0, 1 }, { 34, 62, 0 } } }, + { { { 43, 0, 2 }, { 42, 47, 0 } } }, + { { { 44, 0, 1 }, { 34, 63, 0 } } }, + { { { 44, 0, 0 }, { 35, 62, 0 } } }, + { { { 44, 0, 1 }, { 35, 63, 0 } } }, + { { { 44, 0, 2 }, { 44, 46, 0 } } }, + { { { 45, 0, 1 }, { 36, 62, 0 } } }, + { { { 45, 0, 0 }, { 36, 63, 0 } } }, + { { { 45, 0, 1 }, { 37, 62, 0 } } }, + { { { 45, 0, 2 }, { 45, 47, 0 } } }, + { { { 46, 0, 1 }, { 37, 63, 0 } } }, + { { { 46, 0, 0 }, { 38, 62, 0 } } }, + { { { 46, 0, 1 }, { 38, 63, 0 } } }, + { { { 46, 0, 2 }, { 47, 46, 0 } } }, + { { { 47, 0, 1 }, { 39, 62, 0 } } }, + { { { 47, 0, 0 }, { 39, 63, 0 } } }, + { { { 47, 0, 1 }, { 40, 62, 0 } } }, + { { { 47, 0, 2 }, { 48, 46, 0 } } }, + { { { 48, 0, 2 }, { 40, 63, 0 } } }, + { { { 48, 0, 1 }, { 41, 62, 0 } } }, + { { { 48, 0, 0 }, { 41, 63, 0 } } }, + { { { 48, 0, 1 }, { 48, 49, 0 } } }, + { { { 48, 0, 2 }, { 42, 62, 0 } } }, + { { { 49, 0, 1 }, { 42, 63, 0 } } }, + { { { 49, 0, 0 }, { 43, 62, 0 } } }, + { { { 49, 0, 1 }, { 48, 52, 0 } } }, + { { { 49, 0, 2 }, { 43, 63, 0 } } }, + { { { 50, 0, 1 }, { 44, 62, 0 } } }, + { { { 50, 0, 0 }, { 44, 63, 0 } } }, + { { { 50, 0, 1 }, { 48, 55, 0 } } }, + { { { 50, 0, 2 }, { 45, 62, 0 } } }, + { { { 51, 0, 1 }, { 45, 63, 0 } } }, + { { { 51, 0, 0 }, { 46, 62, 0 } } }, + { { { 51, 0, 1 }, { 48, 58, 0 } } }, + { { { 51, 0, 2 }, { 46, 63, 0 } } }, + { { { 52, 0, 1 }, { 47, 62, 0 } } }, + { { { 52, 0, 0 }, { 47, 63, 0 } } }, + { { { 52, 0, 1 }, { 48, 61, 0 } } }, + { { { 52, 0, 2 }, { 48, 62, 0 } } }, + { { { 53, 0, 1 }, { 56, 47, 0 } } }, + { { { 53, 0, 0 }, { 48, 63, 0 } } }, + { { { 53, 0, 1 }, { 49, 62, 0 } } }, + { { { 53, 0, 2 }, { 49, 63, 0 } } }, + { { { 54, 0, 1 }, { 58, 46, 0 } } }, + { { { 54, 0, 0 }, { 50, 62, 0 } } }, + { { { 54, 0, 1 }, { 50, 63, 0 } } }, + { { { 54, 0, 2 }, { 51, 62, 0 } } }, + { { { 55, 0, 1 }, { 59, 47, 0 } } }, + { { { 55, 0, 0 }, { 51, 63, 0 } } }, + { { { 55, 0, 1 }, { 52, 62, 0 } } }, + { { { 55, 0, 2 }, { 52, 63, 0 } } }, + { { { 56, 0, 1 }, { 61, 46, 0 } } }, + { { { 56, 0, 0 }, { 53, 62, 0 } } }, + { { { 56, 0, 1 }, { 53, 63, 0 } } }, + { { { 56, 0, 2 }, { 54, 62, 0 } } }, + { { { 57, 0, 1 }, { 62, 47, 0 } } }, + { { { 57, 0, 0 }, { 54, 63, 0 } } }, + { { { 57, 0, 1 }, { 55, 62, 0 } } }, + { { { 57, 0, 2 }, { 55, 63, 0 } } }, + { { { 58, 0, 1 }, { 56, 62, 1 } } }, + { { { 58, 0, 0 }, { 56, 62, 0 } } }, + { { { 58, 0, 1 }, { 56, 63, 0 } } }, + { { { 58, 0, 2 }, { 57, 62, 0 } } }, + { { { 59, 0, 1 }, { 57, 63, 1 } } }, + { { { 59, 0, 0 }, { 57, 63, 0 } } }, + { { { 59, 0, 1 }, { 58, 62, 0 } } }, + { { { 59, 0, 2 }, { 58, 63, 0 } } }, + { { { 60, 0, 1 }, { 59, 62, 1 } } }, + { { { 60, 0, 0 }, { 59, 62, 0 } } }, + { { { 60, 0, 1 }, { 59, 63, 0 } } }, + { { { 60, 0, 2 }, { 60, 62, 0 } } }, + { { { 61, 0, 1 }, { 60, 63, 1 } } }, + { { { 61, 0, 0 }, { 60, 63, 0 } } }, + { { { 61, 0, 1 }, { 61, 62, 0 } } }, + { { { 61, 0, 2 }, { 61, 63, 0 } } }, + { { { 62, 0, 1 }, { 62, 62, 1 } } }, + { { { 62, 0, 0 }, { 62, 62, 0 } } }, + { { { 62, 0, 1 }, { 62, 63, 0 } } }, + { { { 62, 0, 2 }, { 63, 62, 0 } } }, + { { { 63, 0, 1 }, { 63, 63, 1 } } }, + { { { 63, 0, 0 }, { 63, 63, 0 } } } +}; diff --git a/tools/depends/native/libsquish-native/src/squish-Info.plist b/tools/depends/native/libsquish-native/src/squish-Info.plist new file mode 100644 index 0000000000..5cb05e056c --- /dev/null +++ b/tools/depends/native/libsquish-native/src/squish-Info.plist @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleExecutable</key> + <string>${EXECUTABLE_NAME}</string> + <key>CFBundleIdentifier</key> + <string>com.sjbrown.squish</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundlePackageType</key> + <string>FMWK</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleVersion</key> + <string>1.0</string> +</dict> +</plist> diff --git a/tools/depends/native/libsquish-native/src/squish.cpp b/tools/depends/native/libsquish-native/src/squish.cpp new file mode 100644 index 0000000000..c0ce058457 --- /dev/null +++ b/tools/depends/native/libsquish-native/src/squish.cpp @@ -0,0 +1,360 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + + 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 <string.h> +#include <squish.h> +#include "colourset.h" +#include "maths.h" +#include "rangefit.h" +#include "clusterfit.h" +#include "colourblock.h" +#include "alpha.h" +#include "singlecolourfit.h" + +namespace squish { + +static int FixFlags( int flags ) +{ + // grab the flag bits + int method = flags & ( kDxt1 | kDxt3 | kDxt5 ); + int fit = flags & ( kColourIterativeClusterFit | kColourClusterFit | kColourRangeFit ); + int extra = flags & ( kWeightColourByAlpha | kSourceBGRA ); + + // set defaults + if( method != kDxt3 && method != kDxt5 ) + method = kDxt1; + if( fit != kColourRangeFit && fit != kColourIterativeClusterFit ) + fit = kColourClusterFit; + + // done + return method | fit | extra; +} + +void CompressMasked( u8 const* rgba, int mask, void* block, int flags, float* metric ) +{ + // fix any bad flags + flags = FixFlags( flags ); + + // get the block locations + void* colourBlock = block; + void* alphaBock = block; + if( ( flags & ( kDxt3 | kDxt5 ) ) != 0 ) + colourBlock = reinterpret_cast< u8* >( block ) + 8; + + // create the minimal point set + ColourSet colours( rgba, mask, flags ); + + // check the compression type and compress colour + if( colours.GetCount() == 1 ) + { + // always do a single colour fit + SingleColourFit fit( &colours, flags ); + fit.Compress( colourBlock ); + } + else if( ( flags & kColourRangeFit ) != 0 || colours.GetCount() == 0 ) + { + // do a range fit + RangeFit fit( &colours, flags, metric ); + fit.Compress( colourBlock ); + } + else + { + // default to a cluster fit (could be iterative or not) + ClusterFit fit( &colours, flags, metric ); + fit.Compress( colourBlock ); + } + + // compress alpha separately if necessary + if( ( flags & kDxt3 ) != 0 ) + CompressAlphaDxt3( rgba, mask, alphaBock ); + else if( ( flags & kDxt5 ) != 0 ) + CompressAlphaDxt5( rgba, mask, alphaBock ); +} + +void Decompress( u8* rgba, void const* block, int flags ) +{ + // fix any bad flags + flags = FixFlags( flags ); + + // get the block locations + void const* colourBlock = block; + void const* alphaBock = block; + if( ( flags & ( kDxt3 | kDxt5 ) ) != 0 ) + colourBlock = reinterpret_cast< u8 const* >( block ) + 8; + + // decompress colour + DecompressColour( rgba, colourBlock, ( flags & kDxt1 ) != 0 ); + + // decompress alpha separately if necessary + if( ( flags & kDxt3 ) != 0 ) + DecompressAlphaDxt3( rgba, alphaBock ); + else if( ( flags & kDxt5 ) != 0 ) + DecompressAlphaDxt5( rgba, alphaBock ); +} + +int GetStorageRequirements( int width, int height, int flags ) +{ + // fix any bad flags + flags = FixFlags( flags ); + + // compute the storage requirements + int blockcount = ( ( width + 3 )/4 ) * ( ( height + 3 )/4 ); + int blocksize = ( ( flags & kDxt1 ) != 0 ) ? 8 : 16; + return blockcount*blocksize; +} + +void CopyRGBA( u8 const* source, u8* dest, int flags ) +{ + if (flags & kSourceBGRA) + { + // convert from bgra to rgba + dest[0] = source[2]; + dest[1] = source[1]; + dest[2] = source[0]; + dest[3] = source[3]; + } + else + { + for( int i = 0; i < 4; ++i ) + *dest++ = *source++; + } +} + +void CompressImage( u8 const* rgba, int width, int height, void* blocks, int flags, float* metric ) +{ + CompressImage(rgba, width, height, width*4, blocks, flags, metric); +} + +void CompressImage( u8 const* rgba, int width, int height, int pitch, void* blocks, int flags, float* metric ) +{ + // fix any bad flags + flags = FixFlags( flags ); + + // initialise the block output + u8* targetBlock = reinterpret_cast< u8* >( blocks ); + int bytesPerBlock = ( ( flags & kDxt1 ) != 0 ) ? 8 : 16; + + // loop over blocks + for( int y = 0; y < height; y += 4 ) + { + for( int x = 0; x < width; x += 4 ) + { + // build the 4x4 block of pixels + u8 sourceRgba[16*4]; + u8* targetPixel = sourceRgba; + int mask = 0; + for( int py = 0; py < 4; ++py ) + { + for( int px = 0; px < 4; ++px ) + { + // get the source pixel in the image + int sx = x + px; + int sy = y + py; + + // enable if we're in the image + if( sx < width && sy < height ) + { + // copy the rgba value + u8 const* sourcePixel = rgba + pitch*sy + 4*sx; + CopyRGBA(sourcePixel, targetPixel, flags); + // enable this pixel + mask |= ( 1 << ( 4*py + px ) ); + } + targetPixel += 4; + } + } + + // compress it into the output + CompressMasked( sourceRgba, mask, targetBlock, flags, metric ); + + // advance + targetBlock += bytesPerBlock; + } + } +} + +void DecompressImage( u8* rgba, int width, int height, void const* blocks, int flags ) +{ + DecompressImage( rgba, width, height, width*4, blocks, flags ); +} + +void DecompressImage( u8* rgba, int width, int height, int pitch, void const* blocks, int flags ) +{ + // fix any bad flags + flags = FixFlags( flags ); + + // initialise the block input + u8 const* sourceBlock = reinterpret_cast< u8 const* >( blocks ); + int bytesPerBlock = ( ( flags & kDxt1 ) != 0 ) ? 8 : 16; + + // loop over blocks + for( int y = 0; y < height; y += 4 ) + { + for( int x = 0; x < width; x += 4 ) + { + // decompress the block + u8 targetRgba[4*16]; + Decompress( targetRgba, sourceBlock, flags ); + + // write the decompressed pixels to the correct image locations + u8 const* sourcePixel = targetRgba; + for( int py = 0; py < 4; ++py ) + { + for( int px = 0; px < 4; ++px ) + { + // get the target location + int sx = x + px; + int sy = y + py; + if( sx < width && sy < height ) + { + u8* targetPixel = rgba + pitch*sy + 4*sx; + + // copy the rgba value + CopyRGBA(sourcePixel, targetPixel, flags); + } + sourcePixel += 4; + } + } + + // advance + sourceBlock += bytesPerBlock; + } + } +} + +static double ErrorSq(double x, double y) +{ + return (x - y) * (x - y); +} + +static void ComputeBlockWMSE(u8 const *original, u8 const *compressed, unsigned int w, unsigned int h, double &cmse, double &amse) +{ + // Computes the MSE for the block and weights it by the variance of the original block. + // If the variance of the original block is less than 4 (i.e. a standard deviation of 1 per channel) + // then the block is close to being a single colour. Quantisation errors in single colour blocks + // are easier to see than similar errors in blocks that contain more colours, particularly when there + // are many such blocks in a large area (eg a blue sky background) as they cause banding. Given that + // banding is easier to see than small errors in "complex" blocks, we weight the errors by a factor + // of 5. This implies that images with large, single colour areas will have a higher potential WMSE + // than images with lots of detail. + + cmse = amse = 0; + unsigned int sum_p[4]; // per channel sum of pixels + unsigned int sum_p2[4]; // per channel sum of pixels squared + memset(sum_p, 0, sizeof(sum_p)); + memset(sum_p2, 0, sizeof(sum_p2)); + for( unsigned int py = 0; py < 4; ++py ) + { + for( unsigned int px = 0; px < 4; ++px ) + { + if( px < w && py < h ) + { + double pixelCMSE = 0; + for( int i = 0; i < 3; ++i ) + { + pixelCMSE += ErrorSq(original[i], compressed[i]); + sum_p[i] += original[i]; + sum_p2[i] += (unsigned int)original[i]*original[i]; + } + if( original[3] == 0 && compressed[3] == 0 ) + pixelCMSE = 0; // transparent in both, so colour is inconsequential + amse += ErrorSq(original[3], compressed[3]); + cmse += pixelCMSE; + sum_p[3] += original[3]; + sum_p2[3] += (unsigned int)original[3]*original[3]; + } + original += 4; + compressed += 4; + } + } + unsigned int variance = 0; + for( int i = 0; i < 4; ++i ) + variance += w*h*sum_p2[i] - sum_p[i]*sum_p[i]; + if( variance < 4 * w * w * h * h ) + { + amse *= 5; + cmse *= 5; + } +} + +void ComputeMSE( u8 const *rgba, int width, int height, u8 const *dxt, int flags, double &colourMSE, double &alphaMSE ) +{ + ComputeMSE(rgba, width, height, width*4, dxt, flags, colourMSE, alphaMSE); +} + +void ComputeMSE( u8 const *rgba, int width, int height, int pitch, u8 const *dxt, int flags, double &colourMSE, double &alphaMSE ) +{ + // fix any bad flags + flags = FixFlags( flags ); + colourMSE = alphaMSE = 0; + + // initialise the block input + squish::u8 const* sourceBlock = dxt; + int bytesPerBlock = ( ( flags & squish::kDxt1 ) != 0 ) ? 8 : 16; + + // loop over blocks + for( int y = 0; y < height; y += 4 ) + { + for( int x = 0; x < width; x += 4 ) + { + // decompress the block + u8 targetRgba[4*16]; + Decompress( targetRgba, sourceBlock, flags ); + u8 const* sourcePixel = targetRgba; + + // copy across to a similar pixel block + u8 originalRgba[4*16]; + u8* originalPixel = originalRgba; + + for( int py = 0; py < 4; ++py ) + { + for( int px = 0; px < 4; ++px ) + { + int sx = x + px; + int sy = y + py; + if( sx < width && sy < height ) + { + u8 const* targetPixel = rgba + pitch*sy + 4*sx; + CopyRGBA(targetPixel, originalPixel, flags); + } + sourcePixel += 4; + originalPixel += 4; + } + } + + // compute the weighted MSE of the block + double blockCMSE, blockAMSE; + ComputeBlockWMSE(originalRgba, targetRgba, std::min(4, width - x), std::min(4, height - y), blockCMSE, blockAMSE); + colourMSE += blockCMSE; + alphaMSE += blockAMSE; + // advance + sourceBlock += bytesPerBlock; + } + } + colourMSE /= (width * height * 3); + alphaMSE /= (width * height); +} + +} // namespace squish diff --git a/tools/depends/native/libsquish-native/src/squish.h b/tools/depends/native/libsquish-native/src/squish.h new file mode 100644 index 0000000000..c68f5c548e --- /dev/null +++ b/tools/depends/native/libsquish-native/src/squish.h @@ -0,0 +1,295 @@ +/* ----------------------------------------------------------------------------- + + Copyright (c) 2006 Simon Brown si@sjbrown.co.uk + + 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 SQUISH_H +#define SQUISH_H + +//! All squish API functions live in this namespace. +namespace squish { + +// ----------------------------------------------------------------------------- + +//! Typedef a quantity that is a single unsigned byte. +typedef unsigned char u8; + +// ----------------------------------------------------------------------------- + +enum +{ + //! Use DXT1 compression. + kDxt1 = ( 1 << 0 ), + + //! Use DXT3 compression. + kDxt3 = ( 1 << 1 ), + + //! Use DXT5 compression. + kDxt5 = ( 1 << 2 ), + + //! Use a very slow but very high quality colour compressor. + kColourIterativeClusterFit = ( 1 << 8 ), + + //! Use a slow but high quality colour compressor (the default). + kColourClusterFit = ( 1 << 3 ), + + //! Use a fast but low quality colour compressor. + kColourRangeFit = ( 1 << 4 ), + + //! Weight the colour by alpha during cluster fit (disabled by default). + kWeightColourByAlpha = ( 1 << 7 ), + + //! Source is BGRA rather than RGBA + kSourceBGRA = ( 1 << 9 ), +}; + +// ----------------------------------------------------------------------------- + +/*! @brief Compresses a 4x4 block of pixels. + + @param rgba The rgba values of the 16 source pixels. + @param mask The valid pixel mask. + @param block Storage for the compressed DXT block. + @param flags Compression flags. + @param metric An optional perceptual metric. + + The source pixels should be presented as a contiguous array of 16 rgba + values, with each component as 1 byte each. In memory this should be: + + { r1, g1, b1, a1, .... , r16, g16, b16, a16 } + + The mask parameter enables only certain pixels within the block. The lowest + bit enables the first pixel and so on up to the 16th bit. Bits beyond the + 16th bit are ignored. Pixels that are not enabled are allowed to take + arbitrary colours in the output block. An example of how this can be used + is in the CompressImage function to disable pixels outside the bounds of + the image when the width or height is not divisible by 4. + + The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression, + however, DXT1 will be used by default if none is specified. When using DXT1 + compression, 8 bytes of storage are required for the compressed DXT block. + DXT3 and DXT5 compression require 16 bytes of storage per block. + + The flags parameter can also specify a preferred colour compressor to use + when fitting the RGB components of the data. Possible colour compressors + are: kColourClusterFit (the default), kColourRangeFit (very fast, low + quality) or kColourIterativeClusterFit (slowest, best quality). + + When using kColourClusterFit or kColourIterativeClusterFit, an additional + flag can be specified to weight the importance of each pixel by its alpha + value. For images that are rendered using alpha blending, this can + significantly increase the perceived quality. + + The metric parameter can be used to weight the relative importance of each + colour channel, or pass NULL to use the default uniform weight of + { 1.0f, 1.0f, 1.0f }. This replaces the previous flag-based control that + allowed either uniform or "perceptual" weights with the fixed values + { 0.2126f, 0.7152f, 0.0722f }. If non-NULL, the metric should point to a + contiguous array of 3 floats. +*/ +void CompressMasked( u8 const* rgba, int mask, void* block, int flags, float* metric = 0 ); + +// ----------------------------------------------------------------------------- + +/*! @brief Compresses a 4x4 block of pixels. + + @param rgba The rgba values of the 16 source pixels. + @param block Storage for the compressed DXT block. + @param flags Compression flags. + @param metric An optional perceptual metric. + + The source pixels should be presented as a contiguous array of 16 rgba + values, with each component as 1 byte each. In memory this should be: + + { r1, g1, b1, a1, .... , r16, g16, b16, a16 } + + The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression, + however, DXT1 will be used by default if none is specified. When using DXT1 + compression, 8 bytes of storage are required for the compressed DXT block. + DXT3 and DXT5 compression require 16 bytes of storage per block. + + The flags parameter can also specify a preferred colour compressor to use + when fitting the RGB components of the data. Possible colour compressors + are: kColourClusterFit (the default), kColourRangeFit (very fast, low + quality) or kColourIterativeClusterFit (slowest, best quality). + + When using kColourClusterFit or kColourIterativeClusterFit, an additional + flag can be specified to weight the importance of each pixel by its alpha + value. For images that are rendered using alpha blending, this can + significantly increase the perceived quality. + + The metric parameter can be used to weight the relative importance of each + colour channel, or pass NULL to use the default uniform weight of + { 1.0f, 1.0f, 1.0f }. This replaces the previous flag-based control that + allowed either uniform or "perceptual" weights with the fixed values + { 0.2126f, 0.7152f, 0.0722f }. If non-NULL, the metric should point to a + contiguous array of 3 floats. + + This method is an inline that calls CompressMasked with a mask of 0xffff, + provided for compatibility with older versions of squish. +*/ +inline void Compress( u8 const* rgba, void* block, int flags, float* metric = 0 ) +{ + CompressMasked( rgba, 0xffff, block, flags, metric ); +} + +// ----------------------------------------------------------------------------- + +/*! @brief Decompresses a 4x4 block of pixels. + + @param rgba Storage for the 16 decompressed pixels. + @param block The compressed DXT block. + @param flags Compression flags. + + The decompressed pixels will be written as a contiguous array of 16 rgba + values, with each component as 1 byte each. In memory this is: + + { r1, g1, b1, a1, .... , r16, g16, b16, a16 } + + The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression, + however, DXT1 will be used by default if none is specified. All other flags + are ignored. +*/ +void Decompress( u8* rgba, void const* block, int flags ); + +// ----------------------------------------------------------------------------- + +/*! @brief Computes the amount of compressed storage required. + + @param width The width of the image. + @param height The height of the image. + @param flags Compression flags. + + The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression, + however, DXT1 will be used by default if none is specified. All other flags + are ignored. + + Most DXT images will be a multiple of 4 in each dimension, but this + function supports arbitrary size images by allowing the outer blocks to + be only partially used. +*/ +int GetStorageRequirements( int width, int height, int flags ); + +// ----------------------------------------------------------------------------- + +/*! @brief Compresses an image in memory. + + @param rgba The pixels of the source. + @param width The width of the source image. + @param height The height of the source image. + @param pitch The pitch of the source image. + @param blocks Storage for the compressed output. + @param flags Compression flags. + @param metric An optional perceptual metric. + + The source pixels should be presented as a contiguous array of width*height + rgba values, with each component as 1 byte each. In memory this should be: + + { r1, g1, b1, a1, .... , rn, gn, bn, an } for n = width*height + + The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression, + however, DXT1 will be used by default if none is specified. When using DXT1 + compression, 8 bytes of storage are required for each compressed DXT block. + DXT3 and DXT5 compression require 16 bytes of storage per block. + + The flags parameter can also specify a preferred colour compressor to use + when fitting the RGB components of the data. Possible colour compressors + are: kColourClusterFit (the default), kColourRangeFit (very fast, low + quality) or kColourIterativeClusterFit (slowest, best quality). + + When using kColourClusterFit or kColourIterativeClusterFit, an additional + flag can be specified to weight the importance of each pixel by its alpha + value. For images that are rendered using alpha blending, this can + significantly increase the perceived quality. + + The metric parameter can be used to weight the relative importance of each + colour channel, or pass NULL to use the default uniform weight of + { 1.0f, 1.0f, 1.0f }. This replaces the previous flag-based control that + allowed either uniform or "perceptual" weights with the fixed values + { 0.2126f, 0.7152f, 0.0722f }. If non-NULL, the metric should point to a + contiguous array of 3 floats. + + Internally this function calls squish::CompressMasked for each block, which + allows for pixels outside the image to take arbitrary values. The function + squish::GetStorageRequirements can be called to compute the amount of memory + to allocate for the compressed output. +*/ +void CompressImage( u8 const* rgba, int width, int height, void* blocks, int flags, float* metric = 0 ); +void CompressImage( u8 const* rgba, int width, int height, int pitch, void* blocks, int flags, float* metric = 0 ); + +// ----------------------------------------------------------------------------- + +/*! @brief Decompresses an image in memory. + + @param rgba Storage for the decompressed pixels. + @param width The width of the source image. + @param height The height of the source image. + @param pitch The pitch of the decompressed pixels. + @param blocks The compressed DXT blocks. + @param flags Compression flags. + + The decompressed pixels will be written as a contiguous array of width*height + 16 rgba values, with each component as 1 byte each. In memory this is: + + { r1, g1, b1, a1, .... , rn, gn, bn, an } for n = width*height + + The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression, + however, DXT1 will be used by default if none is specified. All other flags + are ignored. + + Internally this function calls squish::Decompress for each block. +*/ +void DecompressImage( u8* rgba, int width, int height, void const* blocks, int flags ); +void DecompressImage( u8* rgba, int width, int height, int pitch, void const* blocks, int flags ); + +// ----------------------------------------------------------------------------- + +/*! @brief Computes MSE of an compressed image in memory. + + @param rgba The original image pixels. + @param width The width of the source image. + @param height The height of the source image. + @param pitch The pitch of the source image. + @param dxt The compressed dxt blocks + @param flags Compression flags. + @param colourMSE The MSE of the colour values. + @param alphaMSE The MSE of the alpha values. + + The colour MSE and alpha MSE are computed across all pixels. The colour MSE is + averaged across all rgb values (i.e. colourMSE = sum sum_k ||dxt.k - rgba.k||/3) + + The flags parameter should specify either kDxt1, kDxt3 or kDxt5 compression, + however, DXT1 will be used by default if none is specified. All other flags + are ignored. + + Internally this function calls squish::Decompress for each block. +*/ +void ComputeMSE(u8 const *rgba, int width, int height, u8 const *dxt, int flags, double &colourMSE, double &alphaMSE); +void ComputeMSE(u8 const *rgba, int width, int height, int pitch, u8 const *dxt, int flags, double &colourMSE, double &alphaMSE); + +// ----------------------------------------------------------------------------- + +} // namespace squish + +#endif // ndef SQUISH_H + diff --git a/tools/depends/native/libsquish-native/src/squish.pc.in b/tools/depends/native/libsquish-native/src/squish.pc.in new file mode 100644 index 0000000000..ca04334393 --- /dev/null +++ b/tools/depends/native/libsquish-native/src/squish.pc.in @@ -0,0 +1,13 @@ +prefix=@PREFIX@ +exec_prefix=${prefix} +libdir=${prefix}/lib +sharedlibdir=${libdir} +includedir=${prefix}/include + +Name: squish +Description: squish DXT lib +Version: 1.0.0-kodi + +Requires: +Libs: -L${libdir} -L${sharedlibdir} -lsquish +Cflags: -I${includedir} diff --git a/tools/depends/native/libsquish-native/src/texture_compression_s3tc.txt b/tools/depends/native/libsquish-native/src/texture_compression_s3tc.txt new file mode 100644 index 0000000000..f229cf3678 --- /dev/null +++ b/tools/depends/native/libsquish-native/src/texture_compression_s3tc.txt @@ -0,0 +1,508 @@ +Name + + EXT_texture_compression_s3tc + +Name Strings + + GL_EXT_texture_compression_s3tc + +Contact + + Pat Brown, NVIDIA Corporation (pbrown 'at' nvidia.com) + +Status + + FINAL + +Version + + 1.1, 16 November 2001 (containing only clarifications relative to + version 1.0, dated 7 July 2000) + +Number + + 198 + +Dependencies + + OpenGL 1.1 is required. + + GL_ARB_texture_compression is required. + + This extension is written against the OpenGL 1.2.1 Specification. + +Overview + + This extension provides additional texture compression functionality + specific to S3's S3TC format (called DXTC in Microsoft's DirectX API), + subject to all the requirements and limitations described by the extension + GL_ARB_texture_compression. + + This extension supports DXT1, DXT3, and DXT5 texture compression formats. + For the DXT1 image format, this specification supports an RGB-only mode + and a special RGBA mode with single-bit "transparent" alpha. + +IP Status + + Contact S3 Incorporated (http://www.s3.com) regarding any intellectual + property issues associated with implementing this extension. + + WARNING: Vendors able to support S3TC texture compression in Direct3D + drivers do not necessarily have the right to use the same functionality in + OpenGL. + +Issues + + (1) Should DXT2 and DXT4 (premultiplied alpha) formats be supported? + + RESOLVED: No -- insufficient interest. Supporting DXT2 and DXT4 + would require some rework to the TexEnv definition (maybe add a new + base internal format RGBA_PREMULTIPLIED_ALPHA) for these formats. + Note that the EXT_texture_env_combine extension (which extends normal + TexEnv modes) can be used to support textures with premultipled alpha. + + (2) Should generic "RGB_S3TC_EXT" and "RGBA_S3TC_EXT" enums be supported + or should we use only the DXT<n> enums? + + RESOLVED: No. A generic RGBA_S3TC_EXT is problematic because DXT3 + and DXT5 are both nominally RGBA (and DXT1 with the 1-bit alpha is + also) yet one format must be chosen up front. + + (3) Should TexSubImage support all block-aligned edits or just the minimal + functionality required by the ARB_texture_compression extension? + + RESOLVED: Allow all valid block-aligned edits. + + (4) A pre-compressed image with a DXT1 format can be used as either an + RGB_S3TC_DXT1 or an RGBA_S3TC_DXT1 image. If the image has + transparent texels, how are they treated in each format? + + RESOLVED: The renderer has to make sure that an RGB_S3TC_DXT1 format + is decoded as RGB (where alpha is effectively one for all texels), + while RGBA_S3TC_DXT1 is decoded as RGBA (where alpha is zero for all + texels with "transparent" encodings). Otherwise, the formats are + identical. + + (5) Is the encoding of the RGB components for DXT1 formats correct in this + spec? MSDN documentation does not specify an RGB color for the + "transparent" encoding. Is it really black? + + RESOLVED: Yes. The specification for the DXT1 format initially + required black, but later changed that requirement to a + recommendation. All vendors involved in the definition of this + specification support black. In addition, specifying black has a + useful behavior. + + When blending multiple texels (GL_LINEAR filtering), mixing opaque and + transparent samples is problematic. Defining a black color on + transparent texels achieves a sensible result that works like a + texture with premultiplied alpha. For example, if three opaque white + and one transparent sample is being averaged, the result would be a + 75% intensity gray (with an alpha of 75%). This is the same result on + the color channels as would be obtained using a white color, 75% + alpha, and a SRC_ALPHA blend factor. + + (6) Is the encoding of the RGB components for DXT3 and DXT5 formats + correct in this spec? MSDN documentation suggests that the RGB blocks + for DXT3 and DXT5 are decoded as described by the DXT1 format. + + RESOLVED: Yes -- this appears to be a bug in the MSDN documentation. + The specification for the DXT2-DXT5 formats require decoding using the + opaque block encoding, regardless of the relative values of "color0" + and "color1". + +New Procedures and Functions + + None. + +New Tokens + + Accepted by the <internalformat> parameter of TexImage2D, CopyTexImage2D, + and CompressedTexImage2DARB and the <format> parameter of + CompressedTexSubImage2DARB: + + COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 + COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 + COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 + COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 + +Additions to Chapter 2 of the OpenGL 1.2.1 Specification (OpenGL Operation) + + None. + +Additions to Chapter 3 of the OpenGL 1.2.1 Specification (Rasterization) + + Add to Table 3.16.1: Specific Compressed Internal Formats + + Compressed Internal Format Base Internal Format + ========================== ==================== + COMPRESSED_RGB_S3TC_DXT1_EXT RGB + COMPRESSED_RGBA_S3TC_DXT1_EXT RGBA + COMPRESSED_RGBA_S3TC_DXT3_EXT RGBA + COMPRESSED_RGBA_S3TC_DXT5_EXT RGBA + + + Modify Section 3.8.2, Alternate Image Specification + + (add to end of TexSubImage discussion, p.123 -- after edit from the + ARB_texture_compression spec) + + If the internal format of the texture image being modified is + COMPRESSED_RGB_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT1_EXT, + COMPRESSED_RGBA_S3TC_DXT3_EXT, or COMPRESSED_RGBA_S3TC_DXT5_EXT, the + texture is stored using one of the several S3TC compressed texture image + formats. Such images are easily edited along 4x4 texel boundaries, so the + limitations on TexSubImage2D or CopyTexSubImage2D parameters are relaxed. + TexSubImage2D and CopyTexSubImage2D will result in an INVALID_OPERATION + error only if one of the following conditions occurs: + + * <width> is not a multiple of four or equal to TEXTURE_WIDTH, + unless <xoffset> and <yoffset> are both zero. + * <height> is not a multiple of four or equal to TEXTURE_HEIGHT, + unless <xoffset> and <yoffset> are both zero. + * <xoffset> or <yoffset> is not a multiple of four. + + The contents of any 4x4 block of texels of an S3TC compressed texture + image that does not intersect the area being modified are preserved during + valid TexSubImage2D and CopyTexSubImage2D calls. + + + Add to Section 3.8.2, Alternate Image Specification (adding to the end of + the CompressedTexImage section introduced by the ARB_texture_compression + spec) + + If <internalformat> is COMPRESSED_RGB_S3TC_DXT1_EXT, + COMPRESSED_RGBA_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT3_EXT, or + COMPRESSED_RGBA_S3TC_DXT5_EXT, the compressed texture is stored using one + of several S3TC compressed texture image formats. The S3TC texture + compression algorithm supports only 2D images without borders. + CompressedTexImage1DARB and CompressedTexImage3DARB produce an + INVALID_ENUM error if <internalformat> is an S3TC format. + CompressedTexImage2DARB will produce an INVALID_OPERATION error if + <border> is non-zero. + + + Add to Section 3.8.2, Alternate Image Specification (adding to the end of + the CompressedTexSubImage section introduced by the + ARB_texture_compression spec) + + If the internal format of the texture image being modified is + COMPRESSED_RGB_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT1_EXT, + COMPRESSED_RGBA_S3TC_DXT3_EXT, or COMPRESSED_RGBA_S3TC_DXT5_EXT, the + texture is stored using one of the several S3TC compressed texture image + formats. Since the S3TC texture compression algorithm supports only 2D + images, CompressedTexSubImage1DARB and CompressedTexSubImage3DARB produce + an INVALID_ENUM error if <format> is an S3TC format. Since S3TC images + are easily edited along 4x4 texel boundaries, the limitations on + CompressedTexSubImage2D are relaxed. CompressedTexSubImage2D will result + in an INVALID_OPERATION error only if one of the following conditions + occurs: + + * <width> is not a multiple of four or equal to TEXTURE_WIDTH. + * <height> is not a multiple of four or equal to TEXTURE_HEIGHT. + * <xoffset> or <yoffset> is not a multiple of four. + + The contents of any 4x4 block of texels of an S3TC compressed texture + image that does not intersect the area being modified are preserved during + valid TexSubImage2D and CopyTexSubImage2D calls. + +Additions to Chapter 4 of the OpenGL 1.2.1 Specification (Per-Fragment +Operations and the Frame Buffer) + + None. + +Additions to Chapter 5 of the OpenGL 1.2.1 Specification (Special Functions) + + None. + +Additions to Chapter 6 of the OpenGL 1.2.1 Specification (State and +State Requests) + + None. + +Additions to Appendix A of the OpenGL 1.2.1 Specification (Invariance) + + None. + +Additions to the AGL/GLX/WGL Specifications + + None. + +GLX Protocol + + None. + +Errors + + INVALID_ENUM is generated by CompressedTexImage1DARB or + CompressedTexImage3DARB if <internalformat> is + COMPRESSED_RGB_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT1_EXT, + COMPRESSED_RGBA_S3TC_DXT3_EXT, or COMPRESSED_RGBA_S3TC_DXT5_EXT. + + INVALID_OPERATION is generated by CompressedTexImage2DARB if + <internalformat> is COMPRESSED_RGB_S3TC_DXT1_EXT, + COMPRESSED_RGBA_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT3_EXT, or + COMPRESSED_RGBA_S3TC_DXT5_EXT and <border> is not equal to zero. + + INVALID_ENUM is generated by CompressedTexSubImage1DARB or + CompressedTexSubImage3DARB if <format> is COMPRESSED_RGB_S3TC_DXT1_EXT, + COMPRESSED_RGBA_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT3_EXT, or + COMPRESSED_RGBA_S3TC_DXT5_EXT. + + INVALID_OPERATION is generated by TexSubImage2D CopyTexSubImage2D, or + CompressedTexSubImage2D if TEXTURE_INTERNAL_FORMAT is + COMPRESSED_RGB_S3TC_DXT1_EXT, COMPRESSED_RGBA_S3TC_DXT1_EXT, + COMPRESSED_RGBA_S3TC_DXT3_EXT, or COMPRESSED_RGBA_S3TC_DXT5_EXT and any of + the following apply: <width> is not a multiple of four or equal to + TEXTURE_WIDTH; <height> is not a multiple of four or equal to + TEXTURE_HEIGHT; <xoffset> or <yoffset> is not a multiple of four. + + + The following restrictions from the ARB_texture_compression specification + do not apply to S3TC texture formats, since subimage modification is + straightforward as long as the subimage is properly aligned. + + DELETE: INVALID_OPERATION is generated by TexSubImage1D, TexSubImage2D, + DELETE: TexSubImage3D, CopyTexSubImage1D, CopyTexSubImage2D, or + DELETE: CopyTexSubImage3D if the internal format of the texture image is + DELETE: compressed and <xoffset>, <yoffset>, or <zoffset> does not equal + DELETE: -b, where b is value of TEXTURE_BORDER. + + DELETE: INVALID_VALUE is generated by CompressedTexSubImage1DARB, + DELETE: CompressedTexSubImage2DARB, or CompressedTexSubImage3DARB if the + DELETE: entire texture image is not being edited: if <xoffset>, + DELETE: <yoffset>, or <zoffset> is greater than -b, <xoffset> + <width> is + DELETE: less than w+b, <yoffset> + <height> is less than h+b, or <zoffset> + DELETE: + <depth> is less than d+b, where b is the value of + DELETE: TEXTURE_BORDER, w is the value of TEXTURE_WIDTH, h is the value of + DELETE: TEXTURE_HEIGHT, and d is the value of TEXTURE_DEPTH. + + See also errors in the GL_ARB_texture_compression specification. + +New State + + In the "Textures" state table, increment the TEXTURE_INTERNAL_FORMAT + subscript for Z by 4 in the "Type" row. + +New Implementation Dependent State + + None + +Appendix + + S3TC Compressed Texture Image Formats + + Compressed texture images stored using the S3TC compressed image formats + are represented as a collection of 4x4 texel blocks, where each block + contains 64 or 128 bits of texel data. The image is encoded as a normal + 2D raster image in which each 4x4 block is treated as a single pixel. If + an S3TC image has a width or height less than four, the data corresponding + to texels outside the image are irrelevant and undefined. + + When an S3TC image with a width of <w>, height of <h>, and block size of + <blocksize> (8 or 16 bytes) is decoded, the corresponding image size (in + bytes) is: + + ceil(<w>/4) * ceil(<h>/4) * blocksize. + + When decoding an S3TC image, the block containing the texel at offset + (<x>, <y>) begins at an offset (in bytes) relative to the base of the + image of: + + blocksize * (ceil(<w>/4) * floor(<y>/4) + floor(<x>/4)). + + The data corresponding to a specific texel (<x>, <y>) are extracted from a + 4x4 texel block using a relative (x,y) value of + + (<x> modulo 4, <y> modulo 4). + + There are four distinct S3TC image formats: + + COMPRESSED_RGB_S3TC_DXT1_EXT: Each 4x4 block of texels consists of 64 + bits of RGB image data. + + Each RGB image data block is encoded as a sequence of 8 bytes, called (in + order of increasing address): + + c0_lo, c0_hi, c1_lo, c1_hi, bits_0, bits_1, bits_2, bits_3 + + The 8 bytes of the block are decoded into three quantities: + + color0 = c0_lo + c0_hi * 256 + color1 = c1_lo + c1_hi * 256 + bits = bits_0 + 256 * (bits_1 + 256 * (bits_2 + 256 * bits_3)) + + color0 and color1 are 16-bit unsigned integers that are unpacked to + RGB colors RGB0 and RGB1 as though they were 16-bit packed pixels with + a <format> of RGB and a type of UNSIGNED_SHORT_5_6_5. + + bits is a 32-bit unsigned integer, from which a two-bit control code + is extracted for a texel at location (x,y) in the block using: + + code(x,y) = bits[2*(4*y+x)+1..2*(4*y+x)+0] + + where bit 31 is the most significant and bit 0 is the least + significant bit. + + The RGB color for a texel at location (x,y) in the block is given by: + + RGB0, if color0 > color1 and code(x,y) == 0 + RGB1, if color0 > color1 and code(x,y) == 1 + (2*RGB0+RGB1)/3, if color0 > color1 and code(x,y) == 2 + (RGB0+2*RGB1)/3, if color0 > color1 and code(x,y) == 3 + + RGB0, if color0 <= color1 and code(x,y) == 0 + RGB1, if color0 <= color1 and code(x,y) == 1 + (RGB0+RGB1)/2, if color0 <= color1 and code(x,y) == 2 + BLACK, if color0 <= color1 and code(x,y) == 3 + + Arithmetic operations are done per component, and BLACK refers to an + RGB color where red, green, and blue are all zero. + + Since this image has an RGB format, there is no alpha component and the + image is considered fully opaque. + + + COMPRESSED_RGBA_S3TC_DXT1_EXT: Each 4x4 block of texels consists of 64 + bits of RGB image data and minimal alpha information. The RGB components + of a texel are extracted in the same way as COMPRESSED_RGB_S3TC_DXT1_EXT. + + The alpha component for a texel at location (x,y) in the block is + given by: + + 0.0, if color0 <= color1 and code(x,y) == 3 + 1.0, otherwise + + IMPORTANT: When encoding an RGBA image into a format using 1-bit + alpha, any texels with an alpha component less than 0.5 end up with an + alpha of 0.0 and any texels with an alpha component greater than or + equal to 0.5 end up with an alpha of 1.0. When encoding an RGBA image + into the COMPRESSED_RGBA_S3TC_DXT1_EXT format, the resulting red, + green, and blue components of any texels with a final alpha of 0.0 + will automatically be zero (black). If this behavior is not desired + by an application, it should not use COMPRESSED_RGBA_S3TC_DXT1_EXT. + This format will never be used when a generic compressed internal + format (Table 3.16.2) is specified, although the nearly identical + format COMPRESSED_RGB_S3TC_DXT1_EXT (above) may be. + + + COMPRESSED_RGBA_S3TC_DXT3_EXT: Each 4x4 block of texels consists of 64 + bits of uncompressed alpha image data followed by 64 bits of RGB image + data. + + Each RGB image data block is encoded according to the + COMPRESSED_RGB_S3TC_DXT1_EXT format, with the exception that the two code + bits always use the non-transparent encodings. In other words, they are + treated as though color0 > color1, regardless of the actual values of + color0 and color1. + + Each alpha image data block is encoded as a sequence of 8 bytes, called + (in order of increasing address): + + a0, a1, a2, a3, a4, a5, a6, a7 + + The 8 bytes of the block are decoded into one 64-bit integer: + + alpha = a0 + 256 * (a1 + 256 * (a2 + 256 * (a3 + 256 * (a4 + + 256 * (a5 + 256 * (a6 + 256 * a7)))))) + + alpha is a 64-bit unsigned integer, from which a four-bit alpha value + is extracted for a texel at location (x,y) in the block using: + + alpha(x,y) = bits[4*(4*y+x)+3..4*(4*y+x)+0] + + where bit 63 is the most significant and bit 0 is the least + significant bit. + + The alpha component for a texel at location (x,y) in the block is + given by alpha(x,y) / 15. + + + COMPRESSED_RGBA_S3TC_DXT5_EXT: Each 4x4 block of texels consists of 64 + bits of compressed alpha image data followed by 64 bits of RGB image data. + + Each RGB image data block is encoded according to the + COMPRESSED_RGB_S3TC_DXT1_EXT format, with the exception that the two code + bits always use the non-transparent encodings. In other words, they are + treated as though color0 > color1, regardless of the actual values of + color0 and color1. + + Each alpha image data block is encoded as a sequence of 8 bytes, called + (in order of increasing address): + + alpha0, alpha1, bits_0, bits_1, bits_2, bits_3, bits_4, bits_5 + + The alpha0 and alpha1 are 8-bit unsigned bytes converted to alpha + components by multiplying by 1/255. + + The 6 "bits" bytes of the block are decoded into one 48-bit integer: + + bits = bits_0 + 256 * (bits_1 + 256 * (bits_2 + 256 * (bits_3 + + 256 * (bits_4 + 256 * bits_5)))) + + bits is a 48-bit unsigned integer, from which a three-bit control code + is extracted for a texel at location (x,y) in the block using: + + code(x,y) = bits[3*(4*y+x)+1..3*(4*y+x)+0] + + where bit 47 is the most significant and bit 0 is the least + significant bit. + + The alpha component for a texel at location (x,y) in the block is + given by: + + alpha0, code(x,y) == 0 + alpha1, code(x,y) == 1 + + (6*alpha0 + 1*alpha1)/7, alpha0 > alpha1 and code(x,y) == 2 + (5*alpha0 + 2*alpha1)/7, alpha0 > alpha1 and code(x,y) == 3 + (4*alpha0 + 3*alpha1)/7, alpha0 > alpha1 and code(x,y) == 4 + (3*alpha0 + 4*alpha1)/7, alpha0 > alpha1 and code(x,y) == 5 + (2*alpha0 + 5*alpha1)/7, alpha0 > alpha1 and code(x,y) == 6 + (1*alpha0 + 6*alpha1)/7, alpha0 > alpha1 and code(x,y) == 7 + + (4*alpha0 + 1*alpha1)/5, alpha0 <= alpha1 and code(x,y) == 2 + (3*alpha0 + 2*alpha1)/5, alpha0 <= alpha1 and code(x,y) == 3 + (2*alpha0 + 3*alpha1)/5, alpha0 <= alpha1 and code(x,y) == 4 + (1*alpha0 + 4*alpha1)/5, alpha0 <= alpha1 and code(x,y) == 5 + 0.0, alpha0 <= alpha1 and code(x,y) == 6 + 1.0, alpha0 <= alpha1 and code(x,y) == 7 + + +Revision History + + 1.1, 11/16/01 pbrown: Updated contact info, clarified where texels + fall within a single block. + + 1.0, 07/07/00 prbrown1: Published final version agreed to by working + group members. + + 0.9, 06/24/00 prbrown1: Documented that block-aligned TexSubImage calls + do not modify existing texels outside the + modified blocks. Added caveat to allow for a + (0,0)-anchored TexSubImage operation of + arbitrary size. + + 0.7, 04/11/00 prbrown1: Added issues on DXT1, DXT3, and DXT5 encodings + where the MSDN documentation doesn't match what + is really done. Added enum values from the + extension registry. + + 0.4, 03/28/00 prbrown1: Updated to reflect final version of the + ARB_texture_compression extension. Allowed + block-aligned TexSubImage calls. + + 0.3, 03/07/00 prbrown1: Resolved issues pertaining to the format of RGB + blocks in the DXT3 and DXT5 formats (they don't + ever use the "transparent" encoding). Fixed + decoding of DXT1 blocks. Pointed out issue of + "transparent" texels in DXT1 encodings having + different behaviors for RGB and RGBA internal + formats. + + 0.2, 02/23/00 prbrown1: Minor revisions; added several issues. + + 0.11, 02/17/00 prbrown1: Slight modification to error semantics + (INVALID_ENUM instead of INVALID_OPERATION). + + 0.1, 02/15/00 prbrown1: Initial revision. diff --git a/tools/depends/native/libsquish-native/src/vs7/squish.sln b/tools/depends/native/libsquish-native/src/vs7/squish.sln new file mode 100644 index 0000000000..ae23f85c46 --- /dev/null +++ b/tools/depends/native/libsquish-native/src/vs7/squish.sln @@ -0,0 +1,39 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "squish", "squish\squish.vcproj", "{6A8518C3-D81A-4428-BD7F-C37933088AC1}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "squishpng", "squishpng\squishpng.vcproj", "{3BC7CF47-F1C8-4BDA-BE30-92F17B21D2C7}" + ProjectSection(ProjectDependencies) = postProject + {6A8518C3-D81A-4428-BD7F-C37933088AC1} = {6A8518C3-D81A-4428-BD7F-C37933088AC1} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "squishtest", "squishtest\squishtest.vcproj", "{77A3F26C-A1D6-4535-9E37-7D3DF34E4B4B}" + ProjectSection(ProjectDependencies) = postProject + {6A8518C3-D81A-4428-BD7F-C37933088AC1} = {6A8518C3-D81A-4428-BD7F-C37933088AC1} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {6A8518C3-D81A-4428-BD7F-C37933088AC1}.Debug.ActiveCfg = Debug|Win32 + {6A8518C3-D81A-4428-BD7F-C37933088AC1}.Debug.Build.0 = Debug|Win32 + {6A8518C3-D81A-4428-BD7F-C37933088AC1}.Release.ActiveCfg = Release|Win32 + {6A8518C3-D81A-4428-BD7F-C37933088AC1}.Release.Build.0 = Release|Win32 + {3BC7CF47-F1C8-4BDA-BE30-92F17B21D2C7}.Debug.ActiveCfg = Debug|Win32 + {3BC7CF47-F1C8-4BDA-BE30-92F17B21D2C7}.Debug.Build.0 = Debug|Win32 + {3BC7CF47-F1C8-4BDA-BE30-92F17B21D2C7}.Release.ActiveCfg = Release|Win32 + {3BC7CF47-F1C8-4BDA-BE30-92F17B21D2C7}.Release.Build.0 = Release|Win32 + {77A3F26C-A1D6-4535-9E37-7D3DF34E4B4B}.Debug.ActiveCfg = Debug|Win32 + {77A3F26C-A1D6-4535-9E37-7D3DF34E4B4B}.Debug.Build.0 = Debug|Win32 + {77A3F26C-A1D6-4535-9E37-7D3DF34E4B4B}.Release.ActiveCfg = Release|Win32 + {77A3F26C-A1D6-4535-9E37-7D3DF34E4B4B}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/tools/depends/native/libsquish-native/src/vs7/squish/squish_2010.vcxproj b/tools/depends/native/libsquish-native/src/vs7/squish/squish_2010.vcxproj new file mode 100644 index 0000000000..dfcecbc8eb --- /dev/null +++ b/tools/depends/native/libsquish-native/src/vs7/squish/squish_2010.vcxproj @@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectName>squish</ProjectName> + <ProjectGuid>{6A8518C3-D81A-4428-BD7F-C37933088AC1}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="$(SolutionDir)\XBMC.core-defaults.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(SolutionDir)\XBMC.defaults.props" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(SolutionDir)\XBMC.defaults.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)libs\$(TargetName)\$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)objs\$(TargetName)\$(Configuration)\</IntDir> + <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)libs\$(TargetName)\$(Configuration)\</OutDir> + <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)objs\$(TargetName)\$(Configuration)\</IntDir> + <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectName)d</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <AdditionalIncludeDirectories>..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_LIB;SQUISH_USE_SSE=2;_SECURE_SCL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <WarningLevel>Level4</WarningLevel> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> + </Lib> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <AdditionalIncludeDirectories>..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_LIB;SQUISH_USE_SSE=2;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <WarningLevel>Level4</WarningLevel> + </ClCompile> + <Lib> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries> + <LinkTimeCodeGeneration>true</LinkTimeCodeGeneration> + </Lib> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\alpha.cpp" /> + <ClCompile Include="..\..\clusterfit.cpp" /> + <ClCompile Include="..\..\colourblock.cpp" /> + <ClCompile Include="..\..\colourfit.cpp" /> + <ClCompile Include="..\..\colourset.cpp" /> + <ClCompile Include="..\..\maths.cpp" /> + <ClCompile Include="..\..\rangefit.cpp" /> + <ClCompile Include="..\..\singlecolourfit.cpp" /> + <ClCompile Include="..\..\squish.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\alpha.h" /> + <ClInclude Include="..\..\clusterfit.h" /> + <ClInclude Include="..\..\colourblock.h" /> + <ClInclude Include="..\..\colourfit.h" /> + <ClInclude Include="..\..\colourset.h" /> + <ClInclude Include="..\..\config.h" /> + <ClInclude Include="..\..\maths.h" /> + <ClInclude Include="..\..\rangefit.h" /> + <ClInclude Include="..\..\simd.h" /> + <ClInclude Include="..\..\simd_float.h" /> + <ClInclude Include="..\..\simd_sse.h" /> + <ClInclude Include="..\..\simd_ve.h" /> + <ClInclude Include="..\..\singlecolourfit.h" /> + <ClInclude Include="..\..\squish.h" /> + </ItemGroup> + <ItemGroup> + <None Include="..\..\singlecolourlookup.inl" /> + <None Include="..\..\texture_compression_s3tc.txt" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/tools/depends/native/libsquish-native/src/vs7/squish/squish_2010.vcxproj.filters b/tools/depends/native/libsquish-native/src/vs7/squish/squish_2010.vcxproj.filters new file mode 100644 index 0000000000..a898002d4b --- /dev/null +++ b/tools/depends/native/libsquish-native/src/vs7/squish/squish_2010.vcxproj.filters @@ -0,0 +1,98 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\alpha.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\clusterfit.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\colourblock.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\colourfit.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\colourset.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\maths.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\rangefit.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\singlecolourfit.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\squish.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\alpha.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\clusterfit.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\colourblock.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\colourfit.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\colourset.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\config.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\maths.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\rangefit.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\simd.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\simd_float.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\simd_sse.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\simd_ve.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\singlecolourfit.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\squish.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <None Include="..\..\singlecolourlookup.inl"> + <Filter>Header Files</Filter> + </None> + <None Include="..\..\texture_compression_s3tc.txt"> + <Filter>Resource Files</Filter> + </None> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/tools/depends/native/libsquish-native/src/vs7/squishpng/squishpng.vcproj b/tools/depends/native/libsquish-native/src/vs7/squishpng/squishpng.vcproj new file mode 100644 index 0000000000..1154d7bc9a --- /dev/null +++ b/tools/depends/native/libsquish-native/src/vs7/squishpng/squishpng.vcproj @@ -0,0 +1,140 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="squishpng" + ProjectGUID="{3BC7CF47-F1C8-4BDA-BE30-92F17B21D2C7}" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + ForceConformanceInForLoopScope="TRUE" + UsePrecompiledHeader="0" + WarningLevel="4" + WarnAsError="TRUE" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="libpng13d.lib" + OutputFile="../../bin/squishpngd.exe" + LinkIncremental="2" + GenerateDebugInformation="TRUE" + ProgramDatabaseFile="$(OutDir)/squishpng.pdb" + SubSystem="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="2" + ForceConformanceInForLoopScope="TRUE" + UsePrecompiledHeader="0" + WarningLevel="4" + WarnAsError="TRUE" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="libpng.lib" + OutputFile="../../bin/squishpng.exe" + LinkIncremental="1" + GenerateDebugInformation="TRUE" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> + <File + RelativePath="..\..\extra\squishpng.cpp"> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/tools/depends/native/libsquish-native/src/vs7/squishtest/squishtest.vcproj b/tools/depends/native/libsquish-native/src/vs7/squishtest/squishtest.vcproj new file mode 100644 index 0000000000..930bfc4077 --- /dev/null +++ b/tools/depends/native/libsquish-native/src/vs7/squishtest/squishtest.vcproj @@ -0,0 +1,138 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="squishtest" + ProjectGUID="{77A3F26C-A1D6-4535-9E37-7D3DF34E4B4B}" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="Debug" + IntermediateDirectory="Debug" + ConfigurationType="1" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="..\.." + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + ForceConformanceInForLoopScope="TRUE" + UsePrecompiledHeader="0" + WarningLevel="4" + WarnAsError="TRUE" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + OutputFile="../../bin/squishtestd.exe" + LinkIncremental="2" + GenerateDebugInformation="TRUE" + ProgramDatabaseFile="$(OutDir)/squishtest.pdb" + SubSystem="1" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="Release" + IntermediateDirectory="Release" + ConfigurationType="1" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="..\.." + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="2" + ForceConformanceInForLoopScope="TRUE" + UsePrecompiledHeader="0" + WarningLevel="4" + WarnAsError="TRUE" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + OutputFile="../../bin/squishtest.exe" + LinkIncremental="1" + GenerateDebugInformation="TRUE" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> + <File + RelativePath="..\..\extra\squishtest.cpp"> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> |