diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2971fa2..96279c9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -30,6 +30,13 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
endif()
endif()
+find_package(LibSquish REQUIRED)
+set_package_properties(LibSquish PROPERTIES
+ URL "https://sourceforge.net/projects/libsquish/"
+ DESCRIPTION "DXT Compression library"
+ TYPE REQUIRED
+)
+
find_package(OpenGL REQUIRED)
set_package_properties(OpenGL PROPERTIES
DESCRIPTION "libGL and libGLU libraries"
@@ -71,9 +78,5 @@ include_directories(${OPENGL_INCLUDE_DIR})
include_directories(${GLM_INCLUDE_DIRS})
include_directories(${ZLIB_INCLUDE_DIR})
-# 3rd party Squish library for DXT codecs
-include_directories(libsquish)
-add_subdirectory(libsquish)
-
# The imaginaryMyst application
add_subdirectory(src)
diff --git a/cmake/FindLibSquish.cmake b/cmake/FindLibSquish.cmake
new file mode 100644
index 0000000..dd62e8c
--- /dev/null
+++ b/cmake/FindLibSquish.cmake
@@ -0,0 +1,30 @@
+#################################################
+#
+# Finds the open source DXT Library, Squish
+#
+# https://sourceforge.net/projects/libsquish/
+#
+#
+# Supplies:
+# LIBSQUISH_FOUND
+# LIBSQUISH_INCLUDE_DIR
+# LIBSQUISH_LIBRARIES
+#
+
+# Additional modules
+include(FindPackageHandleStandardArgs)
+include(SelectLibraryConfigurations)
+
+set(LIBSQUISH_PATH CACHE PATH "Path to libSquish installation")
+
+if(LIBSQUISH_PATH)
+ file(TO_CMAKE_PATH ${LIBSQUISH_PATH}/include LIBSQUISH_INC_SEARCH )
+ file(TO_CMAKE_PATH ${LIBSQUISH_PATH}/lib LIBSQUISH_LIB_SEARCH)
+endif(LIBSQUISH_PATH)
+
+find_path(LIBSQUISH_INCLUDE_DIR squish.h PATHS ${LIBSQUISH_INC_SEARCH} DOC "Path containing libSquish header")
+find_library(LIBSQUISH_LIBRARY_RELEASE NAMES squish libsquish PATHS ${LIBSQUISH_LIB_SEARCH} PATH_SUFFIXES lib DOC "Path to libSquish release library")
+find_library(LIBSQUISH_LIBRARY_DEBUG NAMES squishd libsquishd PATHS ${LIBSQUISH_LIB_SEARCH} PATH_SUFFIXES lib DOC "Path to libSquish debug library")
+
+select_library_configurations(LIBSQUISH)
+find_package_handle_standard_args(LibSquish REQUIRED_VARS LIBSQUISH_LIBRARY LIBSQUISH_INCLUDE_DIR)
diff --git a/libsquish/CMakeLists.txt b/libsquish/CMakeLists.txt
deleted file mode 100644
index bb3254a..0000000
--- a/libsquish/CMakeLists.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-# This file is part of imaginaryMyst.
-#
-# imaginaryMyst is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# imaginaryMyst is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with imaginaryMyst. If not, see .
-
-set(squish_SOURCES
- alpha.h
- alpha.cpp
- clusterfit.h
- clusterfit.cpp
- colourblock.h
- colourblock.cpp
- colourfit.h
- colourfit.cpp
- colourset.h
- colourset.cpp
- maths.h
- maths.cpp
- rangefit.h
- rangefit.cpp
- simd.h
- simd_float.h
- simd_sse.h
- singlecolourfit.h
- singlecolourfit.cpp
- squish.h
- squish.cpp
-)
-
-if(ENABLE_SSE2)
- # Use SSE2 optimized squish codecs
- set(-DSQUISH_USE_SSE=2)
-endif()
-
-add_library(squish STATIC ${squish_SOURCES})
diff --git a/libsquish/ChangeLog b/libsquish/ChangeLog
deleted file mode 100644
index ba03f4c..0000000
--- a/libsquish/ChangeLog
+++ /dev/null
@@ -1,52 +0,0 @@
-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/libsquish/Doxyfile b/libsquish/Doxyfile
deleted file mode 100644
index 3ec51e4..0000000
--- a/libsquish/Doxyfile
+++ /dev/null
@@ -1,223 +0,0 @@
-# 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/libsquish/Makefile b/libsquish/Makefile
deleted file mode 100644
index 75a72fe..0000000
--- a/libsquish/Makefile
+++ /dev/null
@@ -1,31 +0,0 @@
-
-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)
-
-install : $(LIB)
- install squish.h $(INSTALL_DIR)/include
- install libsquish.a $(INSTALL_DIR)/lib
-
-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)
-
-
-
diff --git a/libsquish/README b/libsquish/README
deleted file mode 100644
index d26b72e..0000000
--- a/libsquish/README
+++ /dev/null
@@ -1,35 +0,0 @@
-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/libsquish/alpha.cpp b/libsquish/alpha.cpp
deleted file mode 100644
index ba7a287..0000000
--- a/libsquish/alpha.cpp
+++ /dev/null
@@ -1,349 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- 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
-#include
-
-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/libsquish/alpha.h b/libsquish/alpha.h
deleted file mode 100644
index 5736052..0000000
--- a/libsquish/alpha.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- 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
-
-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/libsquish/clusterfit.cpp b/libsquish/clusterfit.cpp
deleted file mode 100644
index afea848..0000000
--- a/libsquish/clusterfit.cpp
+++ /dev/null
@@ -1,393 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- 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
-
-namespace squish {
-
-ClusterFit::ClusterFit( ColourSet const* colours, int flags )
- : ColourFit( colours, flags )
-{
- // set the iteration count
- m_iterationCount = ( m_flags & kColourIterativeClusterFit ) ? kMaxIterations : 1;
-
- // initialise the best error
- m_besterror = VEC4_CONST( FLT_MAX );
-
- // initialise the metric
- bool perceptual = ( ( m_flags & kColourMetricPerceptual ) != 0 );
- if( perceptual )
- m_metric = Vec4( 0.2126f, 0.7152f, 0.0722f, 0.0f );
- else
- m_metric = VEC4_CONST( 1.0f );
-
- // 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/libsquish/clusterfit.h b/libsquish/clusterfit.h
deleted file mode 100644
index 17db5d3..0000000
--- a/libsquish/clusterfit.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- 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
-#include "maths.h"
-#include "simd.h"
-#include "colourfit.h"
-
-namespace squish {
-
-class ClusterFit : public ColourFit
-{
-public:
- ClusterFit( ColourSet const* colours, int flags );
-
-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/libsquish/colourblock.cpp b/libsquish/colourblock.cpp
deleted file mode 100644
index e6a5788..0000000
--- a/libsquish/colourblock.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- 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/libsquish/colourblock.h b/libsquish/colourblock.h
deleted file mode 100644
index df0a472..0000000
--- a/libsquish/colourblock.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- 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
-#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/libsquish/colourfit.cpp b/libsquish/colourfit.cpp
deleted file mode 100644
index dba2b87..0000000
--- a/libsquish/colourfit.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- 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 )
-{
-}
-
-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/libsquish/colourfit.h b/libsquish/colourfit.h
deleted file mode 100644
index a2d0559..0000000
--- a/libsquish/colourfit.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- 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
-#include "maths.h"
-
-namespace squish {
-
-class ColourSet;
-
-class ColourFit
-{
-public:
- ColourFit( ColourSet const* colours, int flags );
-
- 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/libsquish/colourset.cpp b/libsquish/colourset.cpp
deleted file mode 100644
index 97d29d9..0000000
--- a/libsquish/colourset.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- 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/libsquish/colourset.h b/libsquish/colourset.h
deleted file mode 100644
index dcf56ae..0000000
--- a/libsquish/colourset.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- 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
-#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/libsquish/config b/libsquish/config
deleted file mode 100644
index 3d9a477..0000000
--- a/libsquish/config
+++ /dev/null
@@ -1,22 +0,0 @@
-# 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 ?= /usr/local
-
diff --git a/libsquish/config.h b/libsquish/config.h
deleted file mode 100644
index 7bf3760..0000000
--- a/libsquish/config.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- 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
-#define SQUISH_USE_ALTIVEC 0
-#endif
-
-// Set to 1 or 2 when building squish to use SSE or SSE2 instructions.
-#ifndef SQUISH_USE_SSE
-#define SQUISH_USE_SSE 0
-#endif
-
-// Internally et 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/libsquish/extra/squishgen.cpp b/libsquish/extra/squishgen.cpp
deleted file mode 100644
index d7d1ee0..0000000
--- a/libsquish/extra/squishgen.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- 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
-
-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/libsquish/extra/squishpng.cpp b/libsquish/extra/squishpng.cpp
deleted file mode 100644
index ccb4895..0000000
--- a/libsquish/extra/squishpng.cpp
+++ /dev/null
@@ -1,605 +0,0 @@
-/* -----------------------------------------------------------------------------
-
- 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 Example program that converts between the PNG and DXT formats.
-
- This program requires libpng for PNG input and output, and is designed
- to show how to prepare data for the squish library when it is not simply
- a contiguous block of memory.
-*/
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#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:
- explicit Mem( int size ) : m_p( new u8[size] ) {}
- ~Mem() { delete[] m_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 width, int height, int stride ) : m_width( width ), m_height( height )
- {
- m_rows = ( png_bytep* )malloc( m_height*sizeof( png_bytep ) );
- for( int i = 0; i < m_height; ++i )
- m_rows[i] = ( png_bytep )malloc( m_width*stride );
- }
-
- ~PngRows()
- {
- for( int i = 0; i < m_height; ++i )
- free( m_rows[i] );
- free( m_rows );
- }
-
- png_bytep* Get() const { return m_rows; }
-
-private:
- png_bytep* m_rows;
- int m_width, m_height;
-};
-
-class PngImage
-{
-public:
- explicit PngImage( std::string const& fileName );
-
- int GetWidth() const { return m_width; }
- int GetHeight() const { return m_height; }
- int GetStride() const { return m_stride; }
- bool IsColour() const { return m_colour; }
- bool IsAlpha() const { return m_alpha; }
-
- u8 const* GetRow( int row ) const { return ( u8* )m_rows[row]; }
-
-private:
- PngReadStruct m_png;
-
- int m_width;
- int m_height;
- int m_stride;
- bool m_colour;
- bool m_alpha;
-
- png_bytep* m_rows;
-};
-
-PngImage::PngImage( 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];
- fread( header, 1, 8, file.Get() );
- 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
- png_init_io( m_png.GetPng(), file.Get() );
- png_set_sig_bytes( m_png.GetPng(), 8 );
- png_read_png( m_png.GetPng(), m_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( m_png.GetPng(), m_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() );
- }
-
- // save the info
- m_width = width;
- m_height = height;
- m_colour = ( ( colourType & PNG_COLOR_MASK_COLOR ) != 0 );
- m_alpha = ( ( colourType & PNG_COLOR_MASK_ALPHA ) != 0 );
- m_stride = ( m_colour ? 3 : 1 ) + ( m_alpha ? 1 : 0 );
-
- // get the image rows
- m_rows = png_get_rows( m_png.GetPng(), m_png.GetInfo() );
- if( !m_rows )
- throw Error( "failed to get image rows" );
-}
-
-static void Compress( std::string const& sourceFileName, std::string const& targetFileName, int flags )
-{
- // load the source image
- PngImage sourceImage( sourceFileName );
-
- // get the image info
- int width = sourceImage.GetWidth();
- int height = sourceImage.GetHeight();
- int stride = sourceImage.GetStride();
- bool colour = sourceImage.IsColour();
- bool alpha = sourceImage.IsAlpha();
-
- // check the image dimensions
- if( ( width % 4 ) != 0 || ( height % 4 ) != 0 )
- {
- std::ostringstream oss;
- oss << "cannot compress " << width << "x" << height
- << "image (dimensions must be multiples of 4)";
- throw Error( oss.str() );
- }
-
- // create the target data
- int bytesPerBlock = ( ( flags & kDxt1 ) != 0 ) ? 8 : 16;
- int targetDataSize = bytesPerBlock*width*height/16;
- Mem targetData( targetDataSize );
-
- // loop over blocks and compress them
- clock_t start = std::clock();
- u8* targetBlock = targetData.Get();
- for( int y = 0; y < height; y += 4 )
- {
- // process a row of blocks
- for( int x = 0; x < width; x += 4 )
- {
- // get the block data
- u8 sourceRgba[16*4];
- for( int py = 0, i = 0; py < 4; ++py )
- {
- u8 const* row = sourceImage.GetRow( y + py ) + x*stride;
- for( int px = 0; px < 4; ++px, ++i )
- {
- // get the pixel colour
- if( colour )
- {
- for( int j = 0; j < 3; ++j )
- sourceRgba[4*i + j] = *row++;
- }
- else
- {
- for( int j = 0; j < 3; ++j )
- sourceRgba[4*i + j] = *row;
- ++row;
- }
-
- // skip alpha for now
- if( alpha )
- sourceRgba[4*i + 3] = *row++;
- else
- sourceRgba[4*i + 3] = 255;
- }
- }
-
- // compress this block
- Compress( sourceRgba, targetBlock, flags );
-
- // advance
- targetBlock += bytesPerBlock;
- }
- }
- clock_t end = std::clock();
- double duration = ( double )( end - start ) / CLOCKS_PER_SEC;
- std::cout << "time taken: " << duration << " seconds" << std::endl;
-
- // open the target file
- File targetFile( fopen( targetFileName.c_str(), "wb" ) );
- if( !targetFile.IsValid() )
- {
- std::ostringstream oss;
- oss << "failed to open \"" << sourceFileName << "\" for writing";
- throw Error( oss.str() );
- }
-
- // write the header
- fwrite( &width, sizeof( int ), 1, targetFile.Get() );
- fwrite( &height, sizeof( int ), 1, targetFile.Get() );
-
- // write the data
- fwrite( targetData.Get(), 1, targetDataSize, targetFile.Get() );
-}
-
-static void Decompress( std::string const& sourceFileName, std::string const& targetFileName, int flags )
-{
- // open the source file
- File sourceFile( fopen( sourceFileName.c_str(), "rb" ) );
- if( !sourceFile.IsValid() )
- {
- std::ostringstream oss;
- oss << "failed to open \"" << sourceFileName << "\" for reading";
- throw Error( oss.str() );
- }
-
- // get the width and height
- int width, height;
- fread( &width, sizeof( int ), 1, sourceFile.Get() );
- fread( &height, sizeof( int ), 1, sourceFile.Get() );
-
- // work out the data size
- int bytesPerBlock = ( ( flags & kDxt1 ) != 0 ) ? 8 : 16;
- int sourceDataSize = bytesPerBlock*width*height/16;
- Mem sourceData( sourceDataSize );
-
- // read the source data
- fread( sourceData.Get(), 1, sourceDataSize, sourceFile.Get() );
-
- // create the target rows
- PngRows targetRows( width, height, 4 );
-
- // loop over blocks and compress them
- u8 const* sourceBlock = sourceData.Get();
- for( int y = 0; y < height; y += 4 )
- {
- // process a row of blocks
- for( int x = 0; x < width; x += 4 )
- {
- // decompress back
- u8 targetRgba[16*4];
- Decompress( targetRgba, sourceBlock, flags );
-
- // write the data into the target rows
- for( int py = 0, i = 0; py < 4; ++py )
- {
- u8* row = ( u8* )targetRows.Get()[y + py] + x*4;
- for( int px = 0; px < 4; ++px, ++i )
- {
- for( int j = 0; j < 4; ++j )
- *row++ = targetRgba[4*i + j];
- }
- }
-
- // advance
- sourceBlock += bytesPerBlock;
- }
- }
-
- // create the target PNG
- PngWriteStruct targetPng;
-
- // set up the image
- png_set_IHDR(
- targetPng.GetPng(), targetPng.GetInfo(), width, height,
- 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE,
- PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT
- );
-
- // open the target file
- File targetFile( fopen( targetFileName.c_str(), "wb" ) );
- if( !targetFile.IsValid() )
- {
- std::ostringstream oss;
- oss << "failed to open \"" << targetFileName << "\" for writing";
- throw Error( oss.str() );
- }
-
- // write the image
- png_set_rows( targetPng.GetPng(), targetPng.GetInfo(), targetRows.Get() );
- png_init_io( targetPng.GetPng(), targetFile.Get() );
- png_write_png( targetPng.GetPng(), targetPng.GetInfo(), PNG_TRANSFORM_IDENTITY, 0 );
-}
-
-static void Diff( std::string const& sourceFileName, std::string const& targetFileName )
-{
- // load the images
- PngImage sourceImage( sourceFileName );
- PngImage targetImage( targetFileName );
-
- // get the image info
- int width = sourceImage.GetWidth();
- int height = sourceImage.GetHeight();
- int sourceStride = sourceImage.GetStride();
- int targetStride = targetImage.GetStride();
- int stride = std::min( sourceStride, targetStride );
-
- // check they match
- if( width != targetImage.GetWidth() || height != targetImage.GetHeight() )
- throw Error( "source and target dimensions do not match" );
-
- // work out the error
- double error = 0.0;
- for( int y = 0; y < height; ++y )
- {
- u8 const* sourceRow = sourceImage.GetRow( y );
- u8 const* targetRow = targetImage.GetRow( y );
- for( int x = 0; x < width; ++x )
- {
- u8 const* sourcePixel = sourceRow + x*sourceStride;
- u8 const* targetPixel = targetRow + x*targetStride;
- for( int i = 0; i < stride; ++i )
- {
- int diff = ( int )sourcePixel[i] - ( int )targetPixel[i];
- error += ( double )( diff*diff );
- }
- }
- }
- error = std::sqrt( error / ( width*height ) );
-
- // print it out
- std::cout << "rms error: " << error << std::endl;
-}
-
-enum Mode
-{
- kCompress,
- kDecompress,
- kDiff
-};
-
-int main( int argc, char* argv[] )
-{
- try
- {
- // parse the command-line
- std::string sourceFileName;
- std::string targetFileName;
- Mode mode = kCompress;
- int method = kDxt1;
- int metric = kColourMetricPerceptual;
- int fit = kColourClusterFit;
- int extra = 0;
- bool help = false;
- bool arguments = true;
- 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 'c': mode = kCompress; break;
- case 'd': mode = kDecompress; break;
- case 'e': mode = kDiff; break;
- case '1': method = kDxt1; break;
- case '3': method = kDxt3; break;
- case '5': method = kDxt5; break;
- case 'u': metric = kColourMetricUniform; break;
- case 'r': fit = kColourRangeFit; break;
- case 'i': fit = kColourIterativeClusterFit; break;
- case 'w': extra = kWeightColourByAlpha; break;
- case '-': arguments = false; break;
- default:
- std::cerr << "unknown option '" << word[j] << "'" << std::endl;
- return -1;
- }
- }
- }
- else
- {
- if( sourceFileName.empty() )
- sourceFileName.assign( word );
- else if( targetFileName.empty() )
- targetFileName.assign( word );
- else
- {
- std::cerr << "unexpected argument \"" << word << "\"" << std::endl;
- }
- }
- }
-
- // check arguments
- if( help )
- {
- std::cout
- << "SYNTAX" << std::endl
- << "\tsquishpng [-cde135]