aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorwsnipex <wsnipex@a1.net>2015-01-03 09:31:29 +0100
committerMemphiz <memphis@machzwo.de>2015-01-08 21:59:01 +0100
commit1f31c0e05976e9537c814fff0a219d32dd7ffbbe (patch)
treeac145f76a6adf38ac6e6a507e4dbc0a281b94224 /tools
parentdea07fa969774e107d41784e5d5117af9a978d16 (diff)
[libsquish] - move libsquish to native depends
Diffstat (limited to 'tools')
-rw-r--r--tools/depends/native/libsquish-native/Makefile46
-rw-r--r--tools/depends/native/libsquish-native/src/ChangeLog52
-rw-r--r--tools/depends/native/libsquish-native/src/Doxyfile223
-rw-r--r--tools/depends/native/libsquish-native/src/Makefile33
-rw-r--r--tools/depends/native/libsquish-native/src/Makefile.in35
-rw-r--r--tools/depends/native/libsquish-native/src/README35
-rw-r--r--tools/depends/native/libsquish-native/src/alpha.cpp349
-rw-r--r--tools/depends/native/libsquish-native/src/alpha.h41
-rw-r--r--tools/depends/native/libsquish-native/src/clusterfit.cpp392
-rw-r--r--tools/depends/native/libsquish-native/src/clusterfit.h61
-rw-r--r--tools/depends/native/libsquish-native/src/colourblock.cpp214
-rw-r--r--tools/depends/native/libsquish-native/src/colourblock.h41
-rw-r--r--tools/depends/native/libsquish-native/src/colourfit.cpp54
-rw-r--r--tools/depends/native/libsquish-native/src/colourfit.h55
-rw-r--r--tools/depends/native/libsquish-native/src/colourset.cpp121
-rw-r--r--tools/depends/native/libsquish-native/src/colourset.h58
-rw-r--r--tools/depends/native/libsquish-native/src/config.h59
-rw-r--r--tools/depends/native/libsquish-native/src/config.in21
-rw-r--r--tools/depends/native/libsquish-native/src/extra/squishgen.cpp151
-rw-r--r--tools/depends/native/libsquish-native/src/extra/squishpng.cpp546
-rw-r--r--tools/depends/native/libsquish-native/src/extra/squishtest.cpp206
-rw-r--r--tools/depends/native/libsquish-native/src/maths.cpp259
-rw-r--r--tools/depends/native/libsquish-native/src/maths.h233
-rw-r--r--tools/depends/native/libsquish-native/src/rangefit.cpp201
-rw-r--r--tools/depends/native/libsquish-native/src/rangefit.h54
-rw-r--r--tools/depends/native/libsquish-native/src/simd.h40
-rw-r--r--tools/depends/native/libsquish-native/src/simd_float.h183
-rw-r--r--tools/depends/native/libsquish-native/src/simd_sse.h180
-rw-r--r--tools/depends/native/libsquish-native/src/simd_ve.h166
-rw-r--r--tools/depends/native/libsquish-native/src/singlecolourfit.cpp172
-rw-r--r--tools/depends/native/libsquish-native/src/singlecolourfit.h58
-rw-r--r--tools/depends/native/libsquish-native/src/singlecolourlookup.inl1040
-rw-r--r--tools/depends/native/libsquish-native/src/squish-Info.plist20
-rw-r--r--tools/depends/native/libsquish-native/src/squish.cpp360
-rw-r--r--tools/depends/native/libsquish-native/src/squish.h295
-rw-r--r--tools/depends/native/libsquish-native/src/squish.pc.in13
-rw-r--r--tools/depends/native/libsquish-native/src/texture_compression_s3tc.txt508
-rw-r--r--tools/depends/native/libsquish-native/src/vs7/squish.sln39
-rw-r--r--tools/depends/native/libsquish-native/src/vs7/squish/squish_2010.vcxproj107
-rw-r--r--tools/depends/native/libsquish-native/src/vs7/squish/squish_2010.vcxproj.filters98
-rw-r--r--tools/depends/native/libsquish-native/src/vs7/squishpng/squishpng.vcproj140
-rw-r--r--tools/depends/native/libsquish-native/src/vs7/squishtest/squishtest.vcproj138
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>