Merge branch 'master' into MinGW

This commit is contained in:
Pavel Krajcevski 2014-01-21 16:25:49 -05:00
commit f64c2d57a2
29 changed files with 1676 additions and 70 deletions

2
.gitmodules vendored
View file

@ -1,3 +1,3 @@
[submodule "Windows"]
path = Windows
url = git@github.com:Mokosha/FasTC-MSVCLibs.git
url = https://github.com/Mokosha/FasTC-MSVCLibs.git

View file

@ -45,6 +45,11 @@ INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include)
INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/BPTCEncoder/include)
INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/BPTCEncoder/include)
IF(NOT "" STREQUAL "${AVPCLLIB_ROOT}")
INCLUDE_DIRECTORIES(${AVPCLLIB_INCLUDE_DIR})
SET(FOUND_NVTT_BC7_EXPORT TRUE)
ENDIF()
INCLUDE(CheckCXXSourceRuns)
IF( NOT HAS_INLINE_ASSEMBLY AND NOT HAS_INLINE_ASSEMBLY_WITH_FLAGS )
@ -145,9 +150,20 @@ IF( HAS_INLINE_ASSEMBLY_WITH_FLAGS )
ENDIF()
ENDIF()
IF(NOT "" STREQUAL "${AVPCLLIB_ROOT}")
SET( SOURCES
${SOURCES}
src/CompressNVTT.cpp
)
ENDIF()
ADD_LIBRARY( BPTCEncoder
${HEADERS}
${SOURCES}
)
TARGET_LINK_LIBRARIES( BPTCEncoder FasTCBase )
IF(NOT "" STREQUAL "${AVPCLLIB_ROOT}")
TARGET_LINK_LIBRARIES( BPTCEncoder avpcl )
ENDIF()

View file

@ -52,3 +52,5 @@
#cmakedefine HAS_ATOMICS
#cmakedefine HAS_GCC_ATOMICS
#cmakedefine HAS_MSVC_ATOMICS
#cmakedefine FOUND_NVTT_BC7_EXPORT

View file

@ -138,6 +138,14 @@ namespace BC7C {
void CompressAtomic(FasTC::CompressionJobList &);
#endif
#ifdef FOUND_NVTT_BC7_EXPORT
// These functions take the same arguments as Compress and CompressWithStats,
// but they use the NVTT compressor if it was supplied to CMake.
void CompressNVTT(const FasTC::CompressionJob &);
void CompressNVTTWithStats(const FasTC::CompressionJob &,
std::ostream *logStream);
#endif
// Decompress the image given as BC7 data to R8G8B8A8 format. Width and Height
// are the dimensions of the image in pixels.
void Decompress(const FasTC::DecompressionJob &);

View file

@ -1016,10 +1016,11 @@ double BC7CompressionMode::CompressCluster(
a2 = std::min(255.0f, std::max(0.0f, a2));
// Quantize
const int8 maskSeed = -0x7F;
const uint8 a1b = ::QuantizeChannel(
uint8(a1), (0x80 >> (GetAlphaChannelPrecision() - 1)));
uint8(a1), (maskSeed >> (GetAlphaChannelPrecision() - 1)));
const uint8 a2b = ::QuantizeChannel(
uint8(a2), (0x80 >> (GetAlphaChannelPrecision() - 1)));
uint8(a2), (maskSeed >> (GetAlphaChannelPrecision() - 1)));
// Compute error
alphaError = 0.0;

View file

@ -0,0 +1,207 @@
/* FasTC
* Copyright (c) 2013 University of North Carolina at Chapel Hill.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for educational, research, and non-profit purposes, without
* fee, and without a written agreement is hereby granted, provided that the
* above copyright notice, this paragraph, and the following four paragraphs
* appear in all copies.
*
* Permission to incorporate this software into commercial products may be
* obtained by contacting the authors or the Office of Technology Development
* at the University of North Carolina at Chapel Hill <otd@unc.edu>.
*
* This software program and documentation are copyrighted by the University of
* North Carolina at Chapel Hill. The software program and documentation are
* supplied "as is," without any accompanying services from the University of
* North Carolina at Chapel Hill or the authors. The University of North
* Carolina at Chapel Hill and the authors do not warrant that the operation of
* the program will be uninterrupted or error-free. The end-user understands
* that the program was developed for research purposes and is advised not to
* rely exclusively on the program for any reason.
*
* IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE
* AUTHORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
* OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
* THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA
* AT CHAPEL HILL OR THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY
* DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY
* STATUTORY WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON
* AN "AS IS" BASIS, AND THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND
* THE AUTHORS HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
* ENHANCEMENTS, OR MODIFICATIONS.
*
* Please send all BUG REPORTS to <pavel@cs.unc.edu>.
*
* The authors may be contacted via:
*
* Pavel Krajcevski
* Dept of Computer Science
* 201 S Columbia St
* Frederick P. Brooks, Jr. Computer Science Bldg
* Chapel Hill, NC 27599-3175
* USA
*
* <http://gamma.cs.unc.edu/FasTC/>
*/
#include "BC7Compressor.h"
#include "BC7CompressionMode.h"
#undef DBL_MAX
#include "BitStream.h"
#include "TexCompTypes.h"
#include <iostream>
#include <sstream>
#include <cstring>
#include "avpcl.h"
namespace BC7C {
void GetBlock(uint32 x, uint32 y, uint32 width, const uint32 *pixels, Tile &t) {
for(uint32 j = 0; j < 4; j++)
for(uint32 i = 0; i < 4; i++) {
uint32 pixel = pixels[(y+j)*width + (x+i)];
t.data[j][i].X() = pixel & 0xFF;
t.data[j][i].Y() = (pixel >> 8) & 0xFF;
t.data[j][i].Z() = (pixel >> 16) & 0xFF;
t.data[j][i].W() = (pixel >> 24) & 0xFF;
}
}
class BlockLogger {
public:
BlockLogger(uint64 blockIdx, std::ostream &os)
: m_BlockIdx(blockIdx), m_Stream(os) { }
template<typename T>
friend std::ostream &operator<<(const BlockLogger &bl, const T &v);
uint64 m_BlockIdx;
std::ostream &m_Stream;
};
template<typename T>
std::ostream &operator<<(const BlockLogger &bl, const T &v) {
std::stringstream ss;
ss << bl.m_BlockIdx << ": " << v;
return bl.m_Stream << ss.str();
}
template<typename T>
static void PrintStat(const BlockLogger &lgr, const char *stat, const T &v) {
std::stringstream ss;
ss << stat << " -- " << v << std::endl;
lgr << ss.str();
}
// Compress an image using BC7 compression. Use the inBuf parameter to point
// to an image in 4-byte RGBA format. The width and height parameters specify
// the size of the image in pixels. The buffer pointed to by outBuf should be
// large enough to store the compressed image. This implementation has an 4:1
// compression ratio.
void CompressNVTT(const FasTC::CompressionJob &cj) {
const uint32 *inPixels = reinterpret_cast<const uint32 *>(cj.InBuf());
const uint32 kBlockSz = GetBlockSize(FasTC::eCompressionFormat_BPTC);
uint8 *outBuf = cj.OutBuf() + cj.CoordsToBlockIdx(cj.XStart(), cj.YStart()) * kBlockSz;
uint32 startX = cj.XStart();
bool done = false;
for(uint32 j = cj.YStart(); !done; j += 4) {
for(uint32 i = startX; !done && i < cj.Width(); i += 4) {
Tile block(4, 4);
GetBlock(i, j, cj.Width(), inPixels, block);
AVPCL::compress(block, reinterpret_cast<char *>(outBuf), NULL);
outBuf += kBlockSz;
done = i+4 >= cj.XEnd() && j+(i+4 == cj.Width()? 4 : 0) >= cj.YEnd();
}
startX = 0;
}
}
typedef double (*ModeCompressFunc)(const Tile &, char* out);
static ModeCompressFunc kModeFuncs[8] = {
AVPCL::compress_mode0,
AVPCL::compress_mode1,
AVPCL::compress_mode2,
AVPCL::compress_mode3,
AVPCL::compress_mode4,
AVPCL::compress_mode5,
AVPCL::compress_mode6,
AVPCL::compress_mode7
};
double CompressMode(uint32 mode, const Tile &t, char *out, BlockLogger &log) {
std::stringstream ss;
ss << "Mode_" << mode << "_error";
double mse = kModeFuncs[mode](t, out);
PrintStat(log, ss.str().c_str(), mse);
BitStreamReadOnly strm(reinterpret_cast<uint8 *>(out));
while(!strm.ReadBit());
const BC7CompressionMode::Attributes *attrs =
BC7CompressionMode::GetAttributesForMode(mode);
const uint32 nSubsets = attrs->numSubsets;
ss.str("");
ss << "Mode_" << mode << "_shape";
uint32 shapeIdx = 0;
if ( nSubsets > 1 ) {
shapeIdx = strm.ReadBits(mode == 0? 4 : 6);
PrintStat(log, ss.str().c_str(), shapeIdx);
} else {
PrintStat(log, ss.str().c_str(), -1);
}
return mse;
}
void CompressNVTTWithStats(const FasTC::CompressionJob &cj, std::ostream *logStream) {
const uint32 *inPixels = reinterpret_cast<const uint32 *>(cj.InBuf());
const uint32 kBlockSz = GetBlockSize(FasTC::eCompressionFormat_BPTC);
uint8 *outBuf = cj.OutBuf() + cj.CoordsToBlockIdx(cj.XStart(), cj.YStart()) * kBlockSz;
uint32 startX = cj.XStart();
bool done = false;
for(uint32 j = cj.YStart(); !done; j += 4) {
for(uint32 i = startX; !done && i < cj.Width(); i += 4) {
Tile block(4, 4);
GetBlock(i, j, cj.Width(), inPixels, block);
if(logStream) {
BlockLogger logger(cj.CoordsToBlockIdx(i, j), *logStream);
char tempblock[16];
double msebest = 1e30;
for(uint32 mode = 0; mode < 8; mode++) {
double mse_mode = CompressMode(mode, block, tempblock, logger);
if(mse_mode < msebest) {
msebest = mse_mode;
memcpy(outBuf, tempblock, AVPCL::BLOCKSIZE);
}
}
} else {
AVPCL::compress(block, reinterpret_cast<char *>(outBuf), NULL);
}
outBuf += 16;
done = i+4 >= cj.XEnd() && j+(i+4 == cj.Width()? 4 : 0) >= cj.YEnd();
}
startX = 0;
}
}
} // namespace BC7C

View file

@ -59,6 +59,12 @@ SET(TESTS
FOREACH(TEST ${TESTS})
SET(TEST_NAME Test_Base_${TEST})
SET(TEST_MODULE Test${TEST}.cpp)
# HACK for MSVC 2012...
IF(MSVC)
ADD_DEFINITIONS(-D_VARIADIC_MAX=10)
ENDIF()
ADD_EXECUTABLE(${TEST_NAME} ${TEST_MODULE})
TARGET_LINK_LIBRARIES(${TEST_NAME} FasTCBase)
TARGET_LINK_LIBRARIES(${TEST_NAME} gtest_main)

View file

@ -75,8 +75,10 @@ void PrintUsage() {
fprintf(stderr, "Usage: tc [OPTIONS] imagefile\n");
fprintf(stderr, "\n");
fprintf(stderr, "\t-v\t\tVerbose mode: prints out Entropy, Mean Local Entropy, and MSSIM\n");
fprintf(stderr, "\t-f\t\tFormat to use. Either \"BPTC\", \"ETC1\", \"DXT1\", \"DXT5\", or \"PVRTC\". Default: BPTC\n");
fprintf(stderr, "\t-f <fmt>\tFormat to use. Either \"BPTC\", \"ETC1\", \"DXT1\", \"DXT5\", or \"PVRTC\". Default: BPTC\n");
fprintf(stderr, "\t-l\t\tSave an output log.\n");
fprintf(stderr, "\t-d <file>\tSpecify decompressed output (currently only png files supported, default: basename-<fmt>.png)\n");
fprintf(stderr, "\t-nd\t\tSuppress decompressed output\n");
fprintf(stderr, "\t-q <quality>\tSet compression quality level. Default: 50\n");
fprintf(stderr, "\t-n <num>\tCompress the image num times and give the average time and PSNR. Default: 1\n");
fprintf(stderr, "\t-simd\t\tUse SIMD compression path\n");
@ -113,6 +115,8 @@ int main(int argc, char **argv) {
exit(1);
}
char decompressedOutput[256]; decompressedOutput[0] = '\0';
bool bNoDecompress = false;
int numJobs = 0;
int quality = 50;
int numThreads = 1;
@ -121,6 +125,7 @@ int main(int argc, char **argv) {
bool bSaveLog = false;
bool bUseAtomics = false;
bool bUsePVRTexLib = false;
bool bUseNVTT = false;
bool bVerbose = false;
FasTC::ECompressionFormat format = FasTC::eCompressionFormat_BPTC;
@ -153,6 +158,9 @@ int main(int argc, char **argv) {
} else if(!strcmp(argv[fileArg], "PVRTCLib")) {
format = FasTC::eCompressionFormat_PVRTC;
bUsePVRTexLib = true;
} else if(!strcmp(argv[fileArg], "BPTCLib")) {
format = FasTC::eCompressionFormat_BPTC;
bUseNVTT = true;
} else if(!strcmp(argv[fileArg], "ETC1")) {
format = FasTC::eCompressionFormat_ETC1;
} else if(!strcmp(argv[fileArg], "DXT1")) {
@ -167,6 +175,30 @@ int main(int argc, char **argv) {
continue;
}
if(strcmp(argv[fileArg], "-d") == 0) {
fileArg++;
if(fileArg == argc) {
PrintUsage();
exit(1);
} else {
size_t sz = 255;
sz = ::std::min(sz, static_cast<size_t>(strlen(argv[fileArg])));
memcpy(decompressedOutput, argv[fileArg], sz + 1);
}
fileArg++;
knowArg = true;
continue;
}
if(strcmp(argv[fileArg], "-nd") == 0) {
fileArg++;
bNoDecompress = true;
knowArg = true;
continue;
}
if(strcmp(argv[fileArg], "-l") == 0) {
fileArg++;
bSaveLog = true;
@ -275,6 +307,7 @@ int main(int argc, char **argv) {
settings.iNumCompressions = numCompressions;
settings.iJobSize = numJobs;
settings.bUsePVRTexLib = bUsePVRTexLib;
settings.bUseNVTT = bUseNVTT;
if(bSaveLog) {
settings.logStream = &logStream;
} else {
@ -304,18 +337,22 @@ int main(int argc, char **argv) {
}
}
if(format == FasTC::eCompressionFormat_BPTC) {
strcat(basename, "-bc7.png");
} else if(format == FasTC::eCompressionFormat_PVRTC) {
strcat(basename, "-pvrtc.png");
} else if(format == FasTC::eCompressionFormat_DXT1) {
strcat(basename, "-dxt1.png");
} else if(format == FasTC::eCompressionFormat_ETC1) {
strcat(basename, "-etc1.png");
}
if(!bNoDecompress) {
if(decompressedOutput[0] != '\0') {
memcpy(basename, decompressedOutput, 256);
} else if(format == FasTC::eCompressionFormat_BPTC) {
strcat(basename, "-bc7.png");
} else if(format == FasTC::eCompressionFormat_PVRTC) {
strcat(basename, "-pvrtc.png");
} else if(format == FasTC::eCompressionFormat_DXT1) {
strcat(basename, "-dxt1.png");
} else if(format == FasTC::eCompressionFormat_ETC1) {
strcat(basename, "-etc1.png");
}
ImageFile cImgFile (basename, eFileFormat_PNG, *ci);
cImgFile.Write();
ImageFile cImgFile (basename, eFileFormat_PNG, *ci);
cImgFile.Write();
}
// Cleanup
delete ci;

View file

@ -91,6 +91,7 @@ ENDIF(TREAT_WARNINGS_AS_ERRORS)
SET(CMAKE_MODULE_PATH "${FasTC_SOURCE_DIR}/CMakeModules" ${CMAKE_MODULE_PATH})
FIND_PACKAGE(PVRTexLib)
FIND_PACKAGE(BC7Export)
SET(FASTC_DIRECTORIES
Base Core IO BPTCEncoder PVRTCEncoder DXTEncoder ETCEncoder

View file

@ -0,0 +1,71 @@
# FasTC
# Copyright (c) 2013 University of North Carolina at Chapel Hill.
# All rights reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for educational, research, and non-profit purposes, without
# fee, and without a written agreement is hereby granted, provided that the
# above copyright notice, this paragraph, and the following four paragraphs
# appear in all copies.
#
# Permission to incorporate this software into commercial products may be
# obtained by contacting the authors or the Office of Technology Development
# at the University of North Carolina at Chapel Hill <otd@unc.edu>.
#
# This software program and documentation are copyrighted by the University of
# North Carolina at Chapel Hill. The software program and documentation are
# supplied "as is," without any accompanying services from the University of
# North Carolina at Chapel Hill or the authors. The University of North
# Carolina at Chapel Hill and the authors do not warrant that the operation of
# the program will be uninterrupted or error-free. The end-user understands
# that the program was developed for research purposes and is advised not to
# rely exclusively on the program for any reason.
#
# IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE
# AUTHORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
# OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
# THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA
# AT CHAPEL HILL OR THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#
# THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY
# DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY
# STATUTORY WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON
# AN "AS IS" BASIS, AND THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND
# THE AUTHORS HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
# ENHANCEMENTS, OR MODIFICATIONS.
#
# Please send all BUG REPORTS to <pavel@cs.unc.edu>.
#
# The authors may be contacted via:
#
# Pavel Krajcevski
# Dept of Computer Science
# 201 S Columbia St
# Frederick P. Brooks, Jr. Computer Science Bldg
# Chapel Hill, NC 27599-3175
# USA
#
# <http://gamma.cs.unc.edu/FasTC/>
# - Try to find libPVRTexLib
# Once done this will define
# PVRTEXLIB_FOUND - System has PVRTexLib
# PVRTEXLIB_INCLUDE_DIRS - The PVRTexLib include directories
# PVRTEXLIB_LIBRARIES - The libraries needed to use PVRTexLib
SET(AVPCLLIB_ROOT "" CACHE STRING "Location of the BC7 Export library from NVTT")
IF(NOT AVPCLLIB_ROOT STREQUAL "")
IF(NOT EXISTS "${AVPCLLIB_ROOT}/src/CMakeLists.txt")
CONFIGURE_FILE(
"${CMAKE_CURRENT_LIST_DIR}/bc7_export/CMakeLists.txt"
"${AVPCLLIB_ROOT}/src"
COPYONLY)
ENDIF()
ADD_SUBDIRECTORY(${AVPCLLIB_ROOT}/src ${CMAKE_CURRENT_BINARY_DIR}/bc7_export)
set(AVPCLLIB_INCLUDE_DIR ${AVPCLLIB_ROOT}/src )
ENDIF()
mark_as_advanced( FORCE AVPCLLIB_ROOT AVPCLLIB_INCLUDE_DIR )

View file

@ -0,0 +1,104 @@
# FasTC
# Copyright (c) 2012 University of North Carolina at Chapel Hill. All rights reserved.
#
# Permission to use, copy, modify, and distribute this software and its documentation for educational,
# research, and non-profit purposes, without fee, and without a written agreement is hereby granted,
# provided that the above copyright notice, this paragraph, and the following four paragraphs appear
# in all copies.
#
# Permission to incorporate this software into commercial products may be obtained by contacting the
# authors or the Office of Technology Development at the University of North Carolina at Chapel Hill <otd@unc.edu>.
#
# This software program and documentation are copyrighted by the University of North Carolina at Chapel Hill.
# The software program and documentation are supplied "as is," without any accompanying services from the
# University of North Carolina at Chapel Hill or the authors. The University of North Carolina at Chapel Hill
# and the authors do not warrant that the operation of the program will be uninterrupted or error-free. The
# end-user understands that the program was developed for research purposes and is advised not to rely
# exclusively on the program for any reason.
#
# IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS BE LIABLE TO ANY PARTY FOR
# DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE
# USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE
# AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY
# STATUTORY WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY
# OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
# ENHANCEMENTS, OR MODIFICATIONS.
#
# Please send all BUG REPORTS to <pavel@cs.unc.edu>.
#
# The authors may be contacted via:
#
# Pavel Krajcevski
# Dept of Computer Science
# 201 S Columbia St
# Frederick P. Brooks, Jr. Computer Science Bldg
# Chapel Hill, NC 27599-3175
# USA
#
# <http://gamma.cs.unc.edu/FasTC/>
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_LIST_DIR})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_LIST_DIR}/arvo)
SET( HEADERS
avpcl.h
bits.h
endpts.h
ImfArray.h
rgba.h
shapes_three.h
shapes_two.h
targa.h
tile.h
utils.h
arvo/ArvoMath.h
arvo/Char.h
arvo/Complex.h
arvo/form.h
arvo/Matrix.h
arvo/Perm.h
arvo/Rand.h
arvo/SI_units.h
arvo/SphTri.h
arvo/SVD.h
arvo/Token.h
arvo/Vec2.h
arvo/Vec3.h
arvo/Vec4.h
arvo/Vector.h
)
SET( SOURCES
avpcl.cpp
avpcl_mode0.cpp
avpcl_mode1.cpp
avpcl_mode2.cpp
avpcl_mode3.cpp
avpcl_mode4.cpp
avpcl_mode5.cpp
avpcl_mode6.cpp
avpcl_mode7.cpp
targa.cpp
utils.cpp
arvo/ArvoMath.cpp
arvo/Char.cpp
arvo/Complex.cpp
arvo/Matrix.cpp
arvo/Perm.cpp
arvo/Rand.cpp
arvo/SphTri.cpp
arvo/SVD.cpp
arvo/Token.cpp
arvo/Vec2.cpp
arvo/Vec3.cpp
arvo/Vec4.cpp
arvo/Vector.cpp
)
ADD_LIBRARY( avpcl
${HEADERS}
${SOURCES}
)

View file

@ -91,6 +91,11 @@ struct SCompressionSettings {
// ignored. The quality being used is the fastest compression quality.
bool bUsePVRTexLib;
// This flag instructs the infrastructure to use the compression routine from
// NVidia Texture Tools. If no such lib is found during configuration then this
// flag is ignored.
bool bUseNVTT;
// This is the output stream with which we should output the logs for the
// compression functions.
std::ostream *logStream;

View file

@ -104,6 +104,11 @@ static CompressionFuncWithStats ChooseFuncFromSettingsWithStats(const SCompress
case FasTC::eCompressionFormat_BPTC:
{
#ifdef FOUND_NVTT_BC7_EXPORT
if(s.bUseNVTT)
return BC7C::CompressNVTTWithStats;
else
#endif
return BC7C::CompressWithStats;
}
break;
@ -136,7 +141,13 @@ static CompressionFunc ChooseFuncFromSettings(const SCompressionSettings &s) {
return BC7C::CompressImageBC7SIMD;
}
#endif
return BC7C::Compress;
#ifdef FOUND_NVTT_BC7_EXPORT
if(s.bUseNVTT)
return BC7C::CompressNVTT;
else
#endif
return BC7C::Compress;
}
break;

View file

@ -71,6 +71,7 @@ macro(config_compiler_and_linker)
set(cxx_exception_flags "-EHsc -D_HAS_EXCEPTIONS=1")
set(cxx_no_exception_flags "-D_HAS_EXCEPTIONS=0")
set(cxx_no_rtti_flags "-GR-")
add_definitions(-D_VARIADIC_MAX=10)
elseif (CMAKE_COMPILER_IS_GNUCXX)
set(cxx_base_flags "-Wall -Wshadow")
set(cxx_exception_flags "-fexceptions")

View file

@ -78,6 +78,15 @@ IF( PVRTEXLIB_FOUND )
SET( HEADERS ${HEADERS} "src/ImageLoaderPVR.h" )
ENDIF( PVRTEXLIB_FOUND )
# Add third-party TGA library...
SET( SOURCES ${SOURCES} "third_party/tga/targa.c" )
SET( HEADERS ${HEADERS} "third_party/tga/targa.h" )
INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR}/IO/third_party/tga )
# Add TGA loaders
SET( SOURCES ${SOURCES} "src/ImageLoaderTGA.cpp" )
SET( HEADERS ${HEADERS} "src/ImageLoaderTGA.h" )
CONFIGURE_FILE(
"config/ImageLoader.h.in"
"include/ImageLoader.h"

View file

@ -52,6 +52,7 @@ class ImageLoader {
protected:
const uint8 *const m_RawData;
const int32 m_NumRawDataBytes;
uint8 *m_PixelData;
uint32 m_Width;
@ -71,6 +72,18 @@ class ImageLoader {
ImageLoader(const uint8 *rawData)
: m_RawData(rawData)
, m_NumRawDataBytes(-1)
, m_PixelData(0)
, m_Width(0), m_Height(0)
, m_RedChannelPrecision(0), m_RedData(0)
, m_GreenChannelPrecision(0), m_GreenData(0)
, m_BlueChannelPrecision(0), m_BlueData(0)
, m_AlphaChannelPrecision(0), m_AlphaData(0)
{ }
ImageLoader(const uint8 *rawData, const int32 numBytes)
: m_RawData(rawData)
, m_NumRawDataBytes(numBytes)
, m_PixelData(0)
, m_Width(0), m_Height(0)
, m_RedChannelPrecision(0), m_RedData(0)
@ -81,6 +94,8 @@ class ImageLoader {
uint32 GetChannelForPixel(uint32 x, uint32 y, uint32 ch);
bool LoadFromPixelBuffer(uint32 *data, bool flipY = false);
public:
virtual ~ImageLoader() {
if(m_RedData) {

View file

@ -91,12 +91,15 @@ public:
const EImageFileFormat m_FileFormat;
uint8 *m_FileData;
int32 m_FileDataSz;
FasTC::Image<> *m_Image;
static unsigned char *ReadFileData(const CHAR *filename);
bool ReadFileData(const CHAR *filename);
static bool WriteImageDataToFile(const uint8 *data, const uint32 dataSz, const CHAR *filename);
static EImageFileFormat DetectFileFormat(const CHAR *filename);
FasTC::Image<> *LoadImage(const unsigned char *rawImageData) const;
FasTC::Image<> *LoadImage() const;
};
#endif // _IMAGE_FILE_H_

View file

@ -47,6 +47,7 @@
enum EImageFileFormat {
eFileFormat_PNG,
eFileFormat_PVR,
eFileFormat_TGA,
kNumImageFileFormats
};

View file

@ -65,6 +65,8 @@
# include "ImageLoaderPVR.h"
#endif
#include "ImageLoaderTGA.h"
//////////////////////////////////////////////////////////////////////////////////////////
//
// Static helper functions
@ -93,6 +95,8 @@ static inline T abs(const T &a) {
ImageFile::ImageFile(const CHAR *filename)
: m_FileFormat( DetectFileFormat(filename) )
, m_FileData(NULL)
, m_FileDataSz(-1)
, m_Image(NULL)
{
strncpy(m_Filename, filename, kMaxFilenameSz);
@ -100,6 +104,8 @@ ImageFile::ImageFile(const CHAR *filename)
ImageFile::ImageFile(const CHAR *filename, EImageFileFormat format)
: m_FileFormat(format)
, m_FileData(NULL)
, m_FileDataSz(-1)
, m_Image(NULL)
{
strncpy(m_Filename, filename, kMaxFilenameSz);
@ -107,6 +113,8 @@ ImageFile::ImageFile(const CHAR *filename, EImageFileFormat format)
ImageFile::ImageFile(const char *filename, EImageFileFormat format, const FasTC::Image<> &image)
: m_FileFormat(format)
, m_FileData(NULL)
, m_FileDataSz(-1)
, m_Image(image.Clone())
{
strncpy(m_Filename, filename, kMaxFilenameSz);
@ -117,6 +125,11 @@ ImageFile::~ImageFile() {
delete m_Image;
m_Image = NULL;
}
if(m_FileData) {
delete m_FileData;
m_FileData = NULL;
}
}
bool ImageFile::Load() {
@ -126,10 +139,13 @@ bool ImageFile::Load() {
m_Image = NULL;
}
unsigned char *rawData = ReadFileData(m_Filename);
if(rawData) {
m_Image = LoadImage(rawData);
delete [] rawData;
if(m_FileData) {
delete m_FileData;
m_FileData = NULL;
}
if(ReadFileData(m_Filename)) {
m_Image = LoadImage();
}
return m_Image != NULL;
@ -165,23 +181,27 @@ bool ImageFile::Write() {
return true;
}
FasTC::Image<> *ImageFile::LoadImage(const unsigned char *rawImageData) const {
FasTC::Image<> *ImageFile::LoadImage() const {
ImageLoader *loader = NULL;
switch(m_FileFormat) {
#ifdef PNG_FOUND
case eFileFormat_PNG:
loader = new ImageLoaderPNG(rawImageData);
loader = new ImageLoaderPNG(m_FileData);
break;
#endif // PNG_FOUND
#ifdef PVRTEXLIB_FOUND
case eFileFormat_PVR:
loader = new ImageLoaderPVR(rawImageData);
loader = new ImageLoaderPVR(m_FileData);
break;
#endif // PVRTEXLIB_FOUND
case eFileFormat_TGA:
loader = new ImageLoaderTGA(m_FileData, m_FileDataSz);
break;
default:
fprintf(stderr, "Unable to load image: unknown file format.\n");
return NULL;
@ -242,11 +262,14 @@ EImageFileFormat ImageFile::DetectFileFormat(const CHAR *filename) {
else if(strcmp(ext, ".pvr") == 0) {
return eFileFormat_PVR;
}
else if(strcmp(ext, ".tga") == 0) {
return eFileFormat_TGA;
}
return kNumImageFileFormats;
}
unsigned char *ImageFile::ReadFileData(const CHAR *filename) {
bool ImageFile::ReadFileData(const CHAR *filename) {
FileStream fstr (filename, eFileMode_ReadBinary);
if(fstr.Tell() < 0) {
fprintf(stderr, "Error opening file for reading: %s\n", filename);
@ -258,7 +281,7 @@ unsigned char *ImageFile::ReadFileData(const CHAR *filename) {
uint32 fileSize = fstr.Tell();
// Allocate data for file contents
unsigned char *rawData = new unsigned char[fileSize];
m_FileData = new unsigned char[fileSize];
// Return stream to beginning of file
fstr.Seek(0, FileStream::eSeekPosition_Beginning);
@ -268,7 +291,7 @@ unsigned char *ImageFile::ReadFileData(const CHAR *filename) {
uint64 totalBytesRead = 0;
uint64 totalBytesLeft = fileSize;
int32 bytesRead;
while((bytesRead = fstr.Read(rawData, uint32(fileSize))) > 0) {
while((bytesRead = fstr.Read(m_FileData, uint32(fileSize))) > 0) {
totalBytesRead += bytesRead;
totalBytesLeft -= bytesRead;
}
@ -276,11 +299,11 @@ unsigned char *ImageFile::ReadFileData(const CHAR *filename) {
if(totalBytesRead != fileSize) {
assert(!"We didn't read as much data as we thought we had!");
fprintf(stderr, "Internal error: Incorrect file size assumption\n");
return 0;
return false;
}
// Return the data..
return rawData;
m_FileDataSz = fileSize;
return true;
}
bool ImageFile::WriteImageDataToFile(const uint8 *data,

View file

@ -137,6 +137,35 @@ unsigned int ImageLoader::GetChannelForPixel(uint32 x, uint32 y, uint32 ch) {
return val;
}
bool ImageLoader::LoadFromPixelBuffer(uint32 *data, bool flipY) {
m_RedChannelPrecision = 8;
m_GreenChannelPrecision = 8;
m_BlueChannelPrecision = 8;
m_AlphaChannelPrecision = 8;
const int nPixels = m_Width * m_Height;
m_RedData = new uint8[nPixels];
m_GreenData = new uint8[nPixels];
m_BlueData = new uint8[nPixels];
m_AlphaData = new uint8[nPixels];
for (uint32 i = 0; i < m_Width; i++) {
for (uint32 j = 0; j < m_Height; j++) {
uint32 idx = j*m_Height + i;
uint32 pIdx = idx;
if(flipY)
idx = (m_Height - j - 1)*m_Height + i;
uint32 pixel = data[idx];
m_RedData[pIdx] = pixel & 0xFF;
m_GreenData[pIdx] = (pixel >> 8) & 0xFF;
m_BlueData[pIdx] = (pixel >> 16) & 0xFF;
m_AlphaData[pIdx] = (pixel >> 24) & 0xFF;
}
}
return true;
}
bool ImageLoader::LoadImage() {
// Do we already have pixel data?

View file

@ -156,7 +156,13 @@ bool ImageLoaderPNG::ReadData() {
png_colorp palette;
int nPaletteEntries;
png_uint_32 ret = png_get_PLTE(png_ptr, info_ptr, &palette, &nPaletteEntries);
assert(ret == PNG_INFO_PLTE);
if(ret != PNG_INFO_PLTE) {
memset(m_BlueData, 0, numPixels);
memset(m_RedData, 0, numPixels);
memset(m_GreenData, 0, numPixels);
assert(!"Couldn't find PLTE chunk");
break;
}
for(uint32 i = 0; i < m_Height; i++) {
png_read_row(png_ptr, rowData, NULL);

View file

@ -74,34 +74,11 @@ bool ImageLoaderPVR::ReadData() {
return false;
}
m_RedChannelPrecision = 8;
m_GreenChannelPrecision = 8;
m_BlueChannelPrecision = 8;
m_AlphaChannelPrecision = 8;
const pvrtexture::CPVRTextureHeader &hdr = pvrTex.getHeader();
m_Width = hdr.getWidth();
m_Height = hdr.getHeight();
const int nPixels = m_Width * m_Height;
m_RedData = new uint8[nPixels];
m_GreenData = new uint8[nPixels];
m_BlueData = new uint8[nPixels];
m_AlphaData = new uint8[nPixels];
uint32 *data = (uint32 *)(pvrTex.getDataPtr());
for (uint32 i = 0; i < m_Width; i++) {
for (uint32 j = 0; j < m_Height; j++) {
uint32 idx = j*m_Height + i;
uint32 pixel = data[idx];
m_RedData[idx] = pixel & 0xFF;
m_GreenData[idx] = (pixel >> 8) & 0xFF;
m_BlueData[idx] = (pixel >> 16) & 0xFF;
m_AlphaData[idx] = (pixel >> 24) & 0xFF;
}
}
return true;
return LoadFromPixelBuffer(reinterpret_cast<uint32 *>(pvrTex.getDataPtr()));
}

81
IO/src/ImageLoaderTGA.cpp Normal file
View file

@ -0,0 +1,81 @@
/* FasTC
* Copyright (c) 2013 University of North Carolina at Chapel Hill.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for educational, research, and non-profit purposes, without
* fee, and without a written agreement is hereby granted, provided that the
* above copyright notice, this paragraph, and the following four paragraphs
* appear in all copies.
*
* Permission to incorporate this software into commercial products may be
* obtained by contacting the authors or the Office of Technology Development
* at the University of North Carolina at Chapel Hill <otd@unc.edu>.
*
* This software program and documentation are copyrighted by the University of
* North Carolina at Chapel Hill. The software program and documentation are
* supplied "as is," without any accompanying services from the University of
* North Carolina at Chapel Hill or the authors. The University of North
* Carolina at Chapel Hill and the authors do not warrant that the operation of
* the program will be uninterrupted or error-free. The end-user understands
* that the program was developed for research purposes and is advised not to
* rely exclusively on the program for any reason.
*
* IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE
* AUTHORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
* OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
* THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA
* AT CHAPEL HILL OR THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY
* DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY
* STATUTORY WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON
* AN "AS IS" BASIS, AND THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND
* THE AUTHORS HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
* ENHANCEMENTS, OR MODIFICATIONS.
*
* Please send all BUG REPORTS to <pavel@cs.unc.edu>.
*
* The authors may be contacted via:
*
* Pavel Krajcevski
* Dept of Computer Science
* 201 S Columbia St
* Frederick P. Brooks, Jr. Computer Science Bldg
* Chapel Hill, NC 27599-3175
* USA
*
* <http://gamma.cs.unc.edu/FasTC/>
*/
#include "ImageLoaderTGA.h"
#include <algorithm>
#include <cstdio>
#include <cassert>
#include <iostream>
#include "TexCompTypes.h"
#include "targa.h"
ImageLoaderTGA::ImageLoaderTGA(const uint8 *rawData, const int32 rawDataSz)
: ImageLoader(rawData, rawDataSz)
{ }
ImageLoaderTGA::~ImageLoaderTGA() { }
bool ImageLoaderTGA::ReadData() {
Targa tga;
targa_loadFromData(&tga, m_RawData, m_NumRawDataBytes);
m_Width = tga.width;
m_Height = tga.height;
assert(static_cast<uint32>(tga.imageLength) == m_Width * m_Height * 4);
return LoadFromPixelBuffer(reinterpret_cast<uint32 *>(tga.image), true);
}

66
IO/src/ImageLoaderTGA.h Normal file
View file

@ -0,0 +1,66 @@
/* FasTC
* Copyright (c) 2013 University of North Carolina at Chapel Hill.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for educational, research, and non-profit purposes, without
* fee, and without a written agreement is hereby granted, provided that the
* above copyright notice, this paragraph, and the following four paragraphs
* appear in all copies.
*
* Permission to incorporate this software into commercial products may be
* obtained by contacting the authors or the Office of Technology Development
* at the University of North Carolina at Chapel Hill <otd@unc.edu>.
*
* This software program and documentation are copyrighted by the University of
* North Carolina at Chapel Hill. The software program and documentation are
* supplied "as is," without any accompanying services from the University of
* North Carolina at Chapel Hill or the authors. The University of North
* Carolina at Chapel Hill and the authors do not warrant that the operation of
* the program will be uninterrupted or error-free. The end-user understands
* that the program was developed for research purposes and is advised not to
* rely exclusively on the program for any reason.
*
* IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE
* AUTHORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
* OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
* THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA
* AT CHAPEL HILL OR THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY
* DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY
* STATUTORY WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON
* AN "AS IS" BASIS, AND THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND
* THE AUTHORS HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
* ENHANCEMENTS, OR MODIFICATIONS.
*
* Please send all BUG REPORTS to <pavel@cs.unc.edu>.
*
* The authors may be contacted via:
*
* Pavel Krajcevski
* Dept of Computer Science
* 201 S Columbia St
* Frederick P. Brooks, Jr. Computer Science Bldg
* Chapel Hill, NC 27599-3175
* USA
*
* <http://gamma.cs.unc.edu/FasTC/>
*/
#ifndef IO_SRC_IMAGELOADERTGA_H_
#define IO_SRC_IMAGELOADERTGA_H_
#include "ImageLoader.h"
class ImageLoaderTGA : public ImageLoader {
public:
ImageLoaderTGA(const uint8 *rawData, const int32 rawDataSz);
virtual ~ImageLoaderTGA();
virtual bool ReadData();
};
#endif // IO_SRC_IMAGELOADERTGA_H_

648
IO/third_party/tga/targa.c vendored Executable file
View file

@ -0,0 +1,648 @@
/*
* targa.c
*
* Copyright (C) 2006 - 2009 by Joshua S. English.
*
* This software is the intellectual property of Joshua S. English. This
* software is provided 'as-is', without any express or implied warranty. In no
* event will the author be held liable for any damages arising from the use of
* this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software in
* a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source version must be plainly marked as such, and must not be
* misrepresented as being original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
*
* Notes:
*
* A plugin to read targa (TGA) image files into an OpenGL-compatible RGBA
* format.
*
* Written by Joshua S. English.
*/
// preprocessor directives
#ifdef _MSC_VER
# define WIN32_LEAN_AND_MEAN
# define _CRT_SECURE_NO_WARNINGS
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "targa.h"
// define targa private constants
#define TGA_COLOR_MAP_NONE 0
#define TGA_IMAGE_TYPE_NONE 0
#define TGA_IMAGE_TYPE_CM 1
#define TGA_IMAGE_TYPE_BGR 2
#define TGA_IMAGE_TYPE_BW 3
#define TGA_IMAGE_TYPE_RLE_CM 9
#define TGA_IMAGE_TYPE_RLE_BGR 10
#define TGA_IMAGE_TYPE_RLE_BW 11
#define TGA_R 0
#define TGA_G 1
#define TGA_B 2
#define TGA_A 3
// declare targa private functions
static int handleTargaError(FILE *fh, int errorCode, const char *function,
size_t line);
static int ctoi(char value);
static char *localStrndup(char *string, int length);
// define targa private macros
#define targaErrorf() \
handleTargaError(fh, rc, __FUNCTION__, __LINE__)
// define targa private functions
static int handleTargaError(FILE *fh, int errorCode, const char *function,
size_t line)
{
char *errorMessage = NULL;
if((errorMessage = strerror(errno)) == NULL) {
errorMessage = "uknown error";
}
fprintf(stderr, "[%s():%i] error(%i) - #%i, '%s'.\n",
(char *)function, (int)line, errorCode, (int)errno, errorMessage);
if(fh != NULL) {
fclose(fh);
}
return -1;
}
static int ctoi(char value)
{
return (int)((unsigned char)value);
}
static char *localStrndup(char *string, int length)
{
char *result = NULL;
if((string == NULL) || (length < 1)) {
fprintf(stderr, "[%s():%i] error - invalid or missing argument(s).\n",
__FUNCTION__, __LINE__);
return NULL;
}
#if defined(_GNU_SOURCE)
result = strndup(string, length);
#else // !_GNU_SOURCE
result = (char *)malloc(sizeof(char) * (length + 1));
memset(result, 0, (sizeof(char) * (length + 1)));
memcpy(result, string, length);
#endif // _GNU_SOURCE
return result;
}
// define targa public functions
int targa_init(Targa *targa)
{
if(targa == NULL) {
fprintf(stderr, "[%s():%i] error - invalid or missing argument(s).\n",
__FUNCTION__, __LINE__);
return -1;
}
memset((void *)targa, 0, sizeof(Targa));
targa->width = 0;
targa->height = 0;
targa->imageLength = 0;
targa->image = NULL;
return 0;
}
int targa_free(Targa *targa)
{
if(targa == NULL) {
fprintf(stderr, "[%s():%i] error - invalid or missing argument(s).\n",
__FUNCTION__, __LINE__);
return -1;
}
if(targa->image != NULL) {
free(targa->image);
}
memset((void *)targa, 0, sizeof(Targa));
return 0;
}
int targa_getDimensions(Targa *targa, int *width, int *height)
{
if((targa == NULL) || (width == NULL) || (height == NULL)) {
fprintf(stderr, "[%s():%i] error - invalid or missing argument(s).\n",
__FUNCTION__, __LINE__);
return -1;
}
*width = targa->width;
*height = targa->height;
return 0;
}
int targa_getImageLength(Targa *targa, int *imageLength)
{
if((targa == NULL) || (imageLength == NULL)) {
fprintf(stderr, "[%s():%i] error - invalid or missing argument(s).\n",
__FUNCTION__, __LINE__);
return -1;
}
*imageLength = targa->imageLength;
return 0;
}
int targa_getRgbaTexture(Targa *targa, char **texture, int *textureLength)
{
if((targa == NULL) || (texture == NULL) || (textureLength == NULL)) {
fprintf(stderr, "[%s():%i] error - invalid or missing argument(s).\n",
__FUNCTION__, __LINE__);
return -1;
}
*texture = (char *)targa->image;
*textureLength = targa->imageLength;
return 0;
}
int targa_loadFromFile(Targa *targa, char *filename)
{
int rc = 0;
int fileLength = 0;
unsigned char *buffer = NULL;
FILE *fh = NULL;
if((targa == NULL) || (filename == NULL)) {
fprintf(stderr, "[%s():%i] error - invalid or missing argument(s).\n",
__FUNCTION__, __LINE__);
return -1;
}
if((fh = fopen(filename, "r+b")) == NULL) {
return targaErrorf();
}
if((rc = fseek(fh, 0, SEEK_END)) != 0) {
return targaErrorf();
}
if((fileLength = ftell(fh)) < 0) {
return targaErrorf();
}
if((rc = fseek(fh, 0, SEEK_SET)) != 0) {
return targaErrorf();
}
if(fileLength < 18) {
fprintf(stderr, "error - TGA file '%s' length %i invalid.\n",
filename, fileLength);
fclose(fh);
return -1;
}
buffer = (unsigned char *)malloc(sizeof(unsigned char) * fileLength);
memset(buffer, 0, (sizeof(unsigned char) * fileLength));
rc = (int)fread((char *)buffer, sizeof(char), fileLength, fh);
if(rc != fileLength) {
return targaErrorf();
}
fclose(fh);
rc = targa_loadFromData(targa, buffer, fileLength);
free(buffer);
return rc;
}
int targa_loadFromData(Targa *targa, const unsigned char *data, int dataLength)
{
short sNumber = 0;
int ii = 0;
int nn = 0;
int imageIdLength = 0;
int colorMap = 0;
int imageType = 0;
int bitLength = 0;
int colorMode = 0;
int length = 0;
int rleId = 0;
int pixel[4];
unsigned char *imageId = NULL;
const unsigned char *ptr = NULL;
if((targa == NULL) || (data == NULL) || (dataLength < 18)) {
fprintf(stderr, "[%s():%i] error - invalid or missing argument(s).\n",
__FUNCTION__, __LINE__);
return -1;
}
ptr = data;
// determine image ID length
imageIdLength = (int)ptr[0];
ptr++;
if((int)(ptr - data) > dataLength) {
fprintf(stderr, "[%s():%i] error - detected data overrun with %i vs "
"%i.\n", __FUNCTION__, __LINE__, (int)(ptr - data),
dataLength);
return -1;
}
// check for color map
colorMap = (int)ptr[0];
ptr++;
if((int)(ptr - data) > dataLength) {
fprintf(stderr, "[%s():%i] error - detected data overrun with %i vs "
"%i.\n", __FUNCTION__, __LINE__, (int)(ptr - data),
dataLength);
return -1;
}
if(colorMap != TGA_COLOR_MAP_NONE) {
fprintf(stderr, "[%s():%i] error - unable to read TARGA color map "
"%i.\n", __FUNCTION__, __LINE__, colorMap);
return -1;
}
// obtain image type
imageType = (int)ptr[0];
ptr++;
if((int)(ptr - data) > dataLength) {
fprintf(stderr, "[%s():%i] error - detected data overrun with %i vs "
"%i.\n", __FUNCTION__, __LINE__, (int)(ptr - data),
dataLength);
return -1;
}
if((imageType == TGA_IMAGE_TYPE_NONE) ||
(imageType == TGA_IMAGE_TYPE_CM) ||
(imageType == TGA_IMAGE_TYPE_RLE_CM)) {
fprintf(stderr, "[%s():%i] error - unsupported image type %i.\n",
__FUNCTION__, __LINE__, imageType);
return -1;
}
// skip 9 bytes (color-map information and x & y origins)
ptr += 9;
if((int)(ptr - data) > dataLength) {
fprintf(stderr, "[%s():%i] error - detected data overrun with %i vs "
"%i.\n", __FUNCTION__, __LINE__, (int)(ptr - data),
dataLength);
return -1;
}
// obtain image width
memcpy((char *)&sNumber, ptr, sizeof(short));
ptr += sizeof(short);
if((int)(ptr - data) > dataLength) {
fprintf(stderr, "[%s():%i] error - detected data overrun with %i vs "
"%i.\n", __FUNCTION__, __LINE__, (int)(ptr - data),
dataLength);
return -1;
}
if(sNumber < 1) {
fprintf(stderr, "[%s():%i] error - invalid image width %i.\n",
__FUNCTION__, __LINE__, (int)sNumber);
return -1;
}
targa->width = (int)sNumber;
// obtain image height
memcpy((char *)&sNumber, ptr, sizeof(short));
ptr += sizeof(short);
if((int)(ptr - data) > dataLength) {
fprintf(stderr, "[%s():%i] error - detected data overrun with %i vs "
"%i.\n", __FUNCTION__, __LINE__, (int)(ptr - data),
dataLength);
return -1;
}
if(sNumber < 1) {
fprintf(stderr, "[%s():%i] error - invalid image height %i.\n",
__FUNCTION__, __LINE__, (int)sNumber);
return -1;
}
targa->height = (int)sNumber;
// determine pixel depth
bitLength = (int)ptr[0];
ptr++;
if((int)(ptr - data) > dataLength) {
fprintf(stderr, "[%s():%i] error - detected data overrun with %i vs "
"%i.\n", __FUNCTION__, __LINE__, (int)(ptr - data),
dataLength);
return -1;
}
if((bitLength != 16) && (bitLength != 24) && (bitLength != 32)) {
fprintf(stderr, "[%s():%i] error - unknown pixel depth of %i-bits.\n",
__FUNCTION__, __LINE__, bitLength);
return -1;
}
if((bitLength == 16) &&
((imageType != TGA_IMAGE_TYPE_BGR) &&
(imageType != TGA_IMAGE_TYPE_BW))) {
fprintf(stderr, "[%s():%i] error - unable to RLE-decode pixel depth "
"of %i-bits.\n", __FUNCTION__, __LINE__, bitLength);
return -1;
}
// skip 1 byte (image descriptor)
ptr++;
if((int)(ptr - data) > dataLength) {
fprintf(stderr, "[%s():%i] error - detected data overrun with %i vs "
"%i.\n", __FUNCTION__, __LINE__, (int)(ptr - data),
dataLength);
return -1;
}
// obtain the image ID
if(imageIdLength > 0) {
if(((int)(ptr - data) + imageIdLength) > dataLength) {
fprintf(stderr, "[%s():%i] error - detected data overrun at %i "
"(image ID) by %i bytes.\n", __FUNCTION__, __LINE__,
(int)(ptr - data),
(((int)(ptr - data) + imageIdLength) - dataLength));
return -1;
}
imageId = (unsigned char *)localStrndup((char *)ptr, imageIdLength);
ptr += imageIdLength;
if((int)(ptr - data) > dataLength) {
fprintf(stderr, "[%s():%i] error - detected data overrun with %i "
"vs %i.\n", __FUNCTION__, __LINE__, (int)(ptr - data),
dataLength);
return -1;
}
}
// process the image
targa->imageLength = (long int)(targa->width * targa->height * 4);
targa->image = (unsigned char *)malloc(sizeof(unsigned char) *
targa->imageLength);
if((imageType == TGA_IMAGE_TYPE_BGR) || (imageType == TGA_IMAGE_TYPE_BW)) {
if(bitLength == 16) {
colorMode = 2;
}
else {
colorMode = (bitLength / 8);
}
length = (targa->width * targa->height * colorMode);
if(((int)(ptr - data) + length) > dataLength) {
fprintf(stderr, "[%s():%i] error - detected data overrun at %i "
"(image pixels) by %i bytes.\n", __FUNCTION__, __LINE__,
(int)(ptr - data),
(((int)(ptr - data) + length) - dataLength));
return -1;
}
for(ii = 0, nn = 0; ((ii < length) && (nn < targa->imageLength));
ii += colorMode, nn += 4) {
if(colorMode == 2) {
memcpy((char *)&sNumber, ptr, sizeof(short));
pixel[TGA_R] = ctoi((sNumber & 0x1f) << 3);
pixel[TGA_G] = ctoi(((sNumber >> 5) & 0x1f) << 3);
pixel[TGA_B] = ctoi(((sNumber >> 10) & 0x1f) << 3);
pixel[TGA_A] = 255;
}
else {
pixel[TGA_R] = ctoi(ptr[2]);
pixel[TGA_G] = ctoi(ptr[1]);
pixel[TGA_B] = ctoi(ptr[0]);
if(colorMode == 3) {
pixel[TGA_A] = 255;
}
else {
pixel[TGA_A] = ctoi(ptr[3]);
}
}
targa->image[(nn + 0)] = (unsigned char)pixel[TGA_R];
targa->image[(nn + 1)] = (unsigned char)pixel[TGA_G];
targa->image[(nn + 2)] = (unsigned char)pixel[TGA_B];
targa->image[(nn + 3)] = (unsigned char)pixel[TGA_A];
ptr += colorMode;
}
}
else { // RLE image
ii = 0;
nn = 0;
rleId = 0;
colorMode = (bitLength / 8);
length = (targa->width * targa->height);
while(ii < length) {
rleId = (int)ptr[0];
ptr++;
if((int)(ptr - data) > dataLength) {
fprintf(stderr, "[%s():%i] error - detected data overrun with "
"%i vs %i.\n", __FUNCTION__, __LINE__,
(int)(ptr - data), dataLength);
return -1;
}
if(rleId < 128) {
rleId++;
while(rleId > 0) {
pixel[TGA_R] = ctoi(ptr[2]);
pixel[TGA_G] = ctoi(ptr[1]);
pixel[TGA_B] = ctoi(ptr[0]);
if(colorMode == 3) {
pixel[TGA_A] = 255;
}
else {
pixel[TGA_A] = ctoi(ptr[3]);
}
targa->image[(nn + 0)] = (unsigned char)pixel[TGA_R];
targa->image[(nn + 1)] = (unsigned char)pixel[TGA_G];
targa->image[(nn + 2)] = (unsigned char)pixel[TGA_B];
targa->image[(nn + 3)] = (unsigned char)pixel[TGA_A];
rleId--;
ii++;
nn += 4;
if(nn >= targa->imageLength) {
break;
}
ptr += colorMode;
if((int)(ptr - data) > dataLength) {
fprintf(stderr, "[%s():%i] error - detected data "
"overrun with %i vs %i.\n", __FUNCTION__,
__LINE__, (int)(ptr - data), dataLength);
return -1;
}
}
}
else {
pixel[TGA_R] = ctoi(ptr[2]);
pixel[TGA_G] = ctoi(ptr[1]);
pixel[TGA_B] = ctoi(ptr[0]);
if(colorMode == 3) {
pixel[TGA_A] = 255;
}
else {
pixel[TGA_A] = ctoi(ptr[3]);
}
ptr += colorMode;
if((int)(ptr - data) > dataLength) {
fprintf(stderr, "[%s():%i] error - detected data overrun "
"with %i vs %i.\n", __FUNCTION__, __LINE__,
(int)(ptr - data), dataLength);
return -1;
}
rleId -= 127;
while(rleId > 0) {
targa->image[(nn + 0)] = (unsigned char)pixel[TGA_R];
targa->image[(nn + 1)] = (unsigned char)pixel[TGA_G];
targa->image[(nn + 2)] = (unsigned char)pixel[TGA_B];
targa->image[(nn + 3)] = (unsigned char)pixel[TGA_A];
rleId--;
ii++;
nn += 4;
if(nn >= targa->imageLength) {
break;
}
}
}
if(nn >= targa->imageLength) {
break;
}
}
}
if(imageId != NULL) {
free(imageId);
}
return 0;
}
int targa_applyRgbaMask(Targa *targa, int colorType, unsigned char value)
{
int ii = 0;
int startPosition = 0;
if((targa == NULL) ||
((colorType != TARGA_COLOR_RED) &&
(colorType != TARGA_COLOR_GREEN) &&
(colorType != TARGA_COLOR_BLUE) &&
(colorType != TARGA_COLOR_ALPHA))) {
fprintf(stderr, "[%s():%i] error - invalid or missing argument(s).\n",
__FUNCTION__, __LINE__);
return -1;
}
switch(colorType) {
case TARGA_COLOR_RED:
startPosition = 0;
break;
case TARGA_COLOR_GREEN:
startPosition = 1;
break;
case TARGA_COLOR_BLUE:
startPosition = 2;
break;
case TARGA_COLOR_ALPHA:
startPosition = 3;
break;
}
for(ii = startPosition; ii < targa->imageLength; ii += 4) {
targa->image[ii] += value;
}
return 0;
}
int targa_setRgbaChannel(Targa *targa, int colorType, unsigned char value)
{
int ii = 0;
int startPosition = 0;
if((targa == NULL) ||
((colorType != TARGA_COLOR_RED) &&
(colorType != TARGA_COLOR_GREEN) &&
(colorType != TARGA_COLOR_BLUE) &&
(colorType != TARGA_COLOR_ALPHA))) {
fprintf(stderr, "[%s():%i] error - invalid or missing argument(s).\n",
__FUNCTION__, __LINE__);
return -1;
}
switch(colorType) {
case TARGA_COLOR_RED:
startPosition = 0;
break;
case TARGA_COLOR_GREEN:
startPosition = 1;
break;
case TARGA_COLOR_BLUE:
startPosition = 2;
break;
case TARGA_COLOR_ALPHA:
startPosition = 3;
break;
}
for(ii = startPosition; ii < targa->imageLength; ii += 4) {
targa->image[ii] = value;
}
return 0;
}

232
IO/third_party/tga/targa.h vendored Executable file
View file

@ -0,0 +1,232 @@
/*
* targa.h
*
* Copyright (C) 2006 - 2009 by Joshua S. English.
*
* This software is the intellectual property of Joshua S. English. This
* software is provided 'as-is', without any express or implied warranty. In no
* event will the author be held liable for any damages arising from the use of
* this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software in
* a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source version must be plainly marked as such, and must not be
* misrepresented as being original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
*
* Notes:
*
* A plugin to read targa (TGA) image files into an OpenGL-compatible RGBA
* format, header file.
*
* Written by Joshua S. English.
*
*
* The TARGA Specification:
*
* Position: Length: Description:
* -------- ------ -----------
* 0 1 length of the image ID
* 1 1 type of color map included (if any)
* 0 => no color map
* 1 => has color map
* 2 1 image type
* 0 => no image data
* 1 => color-mapped image
* 2 => true-color image
* 3 => black & white image
* 9 => RLE color-mapped image
* 10 => RLE true-color image
* 11 => RLE black & white image
* 3 2 index of the first color-map entry as an offest
* into the color-map table
* 5 2 color-map length (number of entries)
* 7 1 color-map entry length - (number of bits per entry)
* 8 2 x-origin of image
* 10 2 y-origin of image
* 12 2 image width in pixels
* 14 2 image height in pixels
* 16 1 pixel depth - the number of bits per pixel
* 17 1 image descriptor
* n var image id - only exists if non-zero
* n var color-map data - only exists if non-zero
* n var image data
*/
#if !defined(_TARGA_H)
#define _TARGA_H
// define targa public constants
#define TARGA_COLOR_RED 1
#define TARGA_COLOR_GREEN 2
#define TARGA_COLOR_BLUE 3
#define TARGA_COLOR_ALPHA 4
// define targa public data types
typedef struct _Targa {
int width;
int height;
int imageLength;
unsigned char *image;
} Targa;
#ifdef __cplusplus
extern "C" {
#endif
// declare targa public functions
/**
* targa_init()
*
* Initilize the Targa structure for utilization.
*
* @param targa(in) The Targa struct to initialize.
*
* @return An integer where zero is pass, less than zero is failure.
*/
int targa_init(Targa *targa);
/**
* targa_free()
*
* Free the Targa structure.
*
* @param targa(in) The Targa struct to free.
*
* @return An integer where zero is pass, less than zero is failure.
*/
int targa_free(Targa *targa);
/**
* targa_getDimensions()
*
* Obtain the width and height in pixels of a loaded Targa image.
*
* @param targa(in) The Targa struct of a loaded image.
*
* @param width(out) The width in pixels of a loaded Targa image.
*
* @param height(out) The height in pixels of a loaded Targa image.
*
* @return An integer where zero is pass, less than zero is failure.
*/
int targa_getDimensions(Targa *targa, int *width, int *height);
/**
* targa_getImageLength()
*
* Obtain the length in bytes of the serialized RGBA image.
*
* @param targa(in) The Targa struct of a loaded image.
*
* @param imageLength(out) The length in bytes of the RGBA image.
*
* @return An integer where zero is pass, less than zero is failure.
*/
int targa_getImageLength(Targa *targa, int *imageLength);
/**
* targa_getRgbaTexture()
*
* Obtain the serialized RGBA texture and its' length from a Targa image.
*
* @param targa(in) The Targa struct of a loaded image.
*
* @param texture(out) The serialized RGBA image pointer.
*
* @param textureLength(out) The serialized RGBA image length in bytes.
*
* @return An integer where zero is pass, less than zero is failure.
*/
int targa_getRgbaTexture(Targa *targa, char **texture, int *textureLength);
/**
* targa_loadFromFile()
*
* Load a targa file and decode it into a 32-bit RGBA serialized image.
*
* @param targa(in) The Targa struct of an image to load.
*
* @param filename(in) The filename of the image to load.
*
* @return An integer where zero is pass, less than zero is failure.
*/
int targa_loadFromFile(Targa *targa, char *filename);
/**
* targa_loadFromData()
*
* Load the targa from an in-memory location and decode it into a 32-bit RGBA
* serialize image.
*
* @param targa(in) The Targa struct an image to load.
*
* @param data(in) A pointer to an in-memory location containing a
* Targa image.
*
* @param dataLength(in) The length of the Targa in-memory image.
*
* @return An integer where zero is pass, less than zero is failure.
*/
int targa_loadFromData(Targa *targa, const unsigned char *data, int dataLength);
/**
* targa_applyRgbaMask()
*
* Apply a red, green, blue or alpha-channel additive color-mask to a loaded
* Targa image.
*
* @param targa(in) The Targa struct of a loaded image.
*
* @param colorType(in) The color channel to mask.
*
* @param value(in) The color code (0 - 255) to mask.
*
* @return An integer where zero is pass, less than zero is failure.
*/
int targa_applyRgbaMask(Targa *targa, int colorType, unsigned char value);
/**
* targa_setRgbaChannel()
*
* Apply a red, green, blue or alpha-channel additive color-channel
* replacement to a loaded Targa image.
*
* @param targa(in) The Targa struct of a loaded image.
*
* @param colorType(in) The color channel to replace.
*
* @param value(in) The color code (0 - 255) to replace.
*
* @return An integer where zero is pass, less than zero is failure.
*/
int targa_setRgbaChannel(Targa *targa, int colorType, unsigned char value);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // _TARGA_H

View file

@ -63,6 +63,12 @@ SET(TESTS
FOREACH(TEST ${TESTS})
SET(TEST_NAME Test_PVRTCEncoder_${TEST})
SET(TEST_MODULE ${TEST}Test.cpp)
# HACK for MSVC 2012...
IF(MSVC)
ADD_DEFINITIONS(-D_VARIADIC_MAX=10)
ENDIF()
ADD_EXECUTABLE(${TEST_NAME} ${TEST_MODULE})
TARGET_LINK_LIBRARIES(${TEST_NAME} PVRTCEncoder)
TARGET_LINK_LIBRARIES(${TEST_NAME} gtest_main)
@ -91,6 +97,11 @@ IF(PVRTEXLIB_FOUND)
INCLUDE_DIRECTORIES( ${PVRTEXLIB_INCLUDE_DIRS} )
INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR}/Core/include )
# HACK for MSVC 2012...
IF(MSVC)
ADD_DEFINITIONS(-D_VARIADIC_MAX=10)
ENDIF()
# The cpp file to compile for the test
ADD_EXECUTABLE(${TEST_NAME} DecompTestPVR.cpp)

View file

@ -1,8 +1,9 @@
FasTC
=======
A **Fas**t **T**exture **C**ompressor for the BPTC (a.k.a. BC7) format. This compressor
supports multi-threading through Boost's threading API and runs on Windows, OS X, and Linux
A **Fas**t **T**exture **C**ompressor for a variety of formats. This compressor
supports multi-threading via native Win32 threads on Windows and pthreads on other
operating systems. It has been tested on Windows, OS X, and Ubuntu Linux.
---
@ -10,7 +11,6 @@ Requirements:
--------------
[CMake](http://www.cmake.org) (2.8.8) <br>
[Boost](http://www.boost.org) (tested with v1.50 and higher) <br>
[libpng](http://www.libpng.org/pub/png/libpng.html) (1.5.13) <br>
[zlib](http://www.zlib.net) (1.2.5)
@ -33,7 +33,7 @@ Once you do this you will be able to run some examples.
#### Using Visual Studio on Windows ####
Due to the C/C++ runtime requirements in Visual Studio, you must have a compiled version of
each library that you wish to link to. In order to save time, I have uploaded various versions
of Boost, libpng, and zlib to a submodule in the source directory. Before running the steps above,
of libpng, and zlib to a submodule in the source directory. Before running the steps above,
make sure to instantiate the submodule in git:
cd FasTC/src
@ -41,30 +41,57 @@ make sure to instantiate the submodule in git:
git submodule update
This will download all of the Release versions of the necessary libraries (which means there will
be linker errors during the build process). I have compiled versions for Visual Studio 2008, 2010,
and 2012.
be linker warnings during the build process under the Debug configuration). I have compiled
versions for Visual Studio 2008, 2010, and 2012.
Testing:
--------------
Once the compressor is built, you may test it against any images you wish as long as their dimensions
are multiples of four and they are in the png file format. If you'd like to convert from one format to
another, I suggest taking a look at [ImageMagick](http://www.imagemagick.org/script/index.php)
are supported by the compression format and they are in the png file format. If you'd like to convert
from one format to another, I suggest taking a look at [ImageMagick](http://www.imagemagick.org/script/index.php)
The quickest test will be to simply run the compressor on a PNG image:
cd FasTC/build
make
CLTool/tc path/to/image.png
This will compress `image.png` into the BPTC (BC7) format using 50 steps of simulated annealing without
SIMD optimization or multithreading.
There are various run-time options available:
* `-t`: Specifies the number of threads to use for compression. The default is one.
* `-l`: Save an output log of various statistics during compression. This is mostly only useful for debugging.
* `-q <num>`: Use `num` steps of simulated annealing during each endpoint compression. Default is 50
* `-v`: Enabled verbosity, which reports Entropy, Mean Local Entropy, and MSSIM in addition to
compression time and PSNR.
* `-f <fmt>`: Specifies the format use for compression. `fmt` can be any one of the following:
* [BPTC](http://www.opengl.org/registry/specs/ARB/texture_compression_bptc.txt) (**Default**)
* [ETC1](http://www.khronos.org/registry/gles/extensions/OES/OES_compressed_ETC1_RGB8_texture.txt) [1]
* [DXT1](http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt) [2]
* [DXT5](http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt) [2]
* [PVRTC](http://web.onetel.net.uk/~simonnihal/assorted3d/fenney03texcomp.pdf)
* `-t`: Specifies the number of threads to use for compression.
* **Default**: 1
* **Formats**: BPTC, ETC1, DXT1, DXT5
* `-l`: Save an output log of various statistics during compression. This is mostly only useful for
debugging.
* **Formats**: BPTC
* `-q <num>`: Use `num` steps of simulated annealing during each endpoint compression. Default is 50.
Available only for BPTC.
* **Default**: 50
* **Formats**: BPTC
* `-n <num>`: Perform `num` compressions in a row. This is good for testing metrics.
* `-a`: Use a parallel algorithm that uses Fetch-And-Add and Test-And-Set to perform mutual exclusion and avoid synchronization primitives. This algorithm is very useful when compressing a list of textures. Cannot be used with the `-j` option.
* `-j <num>`: This specifies the number of 4x4 blocks that the compressor will crunch per thread. The default is to split the image up so that each thread compresses an equal share of the image. However, for many images, certain blocks compress faster than others, and you might want a more fine grained control over how to switch between compressing different blocks.
* **Default**: 1
* **Formats**: All
* `-a`: Use a parallel algorithm that uses Fetch-And-Add and Test-And-Set to perform mutual exclusion
and avoid synchronization primitives. This algorithm is very useful when compressing a list of textures.
Cannot be used with the `-j` option.
* **Formats**: BPTC
* `-j <num>`: This specifies the number of blocks that the compressor will request to crunch per thread. If this
flag is not specified or set to zero, the image will be split up so that each thread compresses an
equal share. However, for many images, certain blocks compress faster than others, and you might want
a more fine grained control over how to switch between compressing different blocks.
* **Formats**: BPTC, ETC1, DXT1, DXT5
As an example, if I wanted to test compressing a texture using no simulated annealing, 4 threads, and 32 blocks per job,
I would invoke the following command:
@ -76,3 +103,11 @@ with atomic synchronization primitives, I would invoke the following command:
CLTool/tc -n 100 -a path/to/image.png
If I wanted to compress a texture into PVRTC, I would invoke the following command:
CLTool/tc -f PVRTC path/to/image.png
[1] Compression code courtesy of [Rich Geldreich](https://code.google.com/p/rg-etc1/) <br>
[2] Compression code courtesy of [Intel](http://software.intel.com/en-us/vcsource/samples/fast-texture-compression).
The idea implemented in this compressor was originally designed by [J. M. P. Van Waveren](http://www.gamedev.no/projects/MegatextureCompression/324337_324337.pdf)

@ -1 +1 @@
Subproject commit 326dfccf36295f9ae43822a4d3fe3f21d87fbf94
Subproject commit 4feeeb6550851ba3541c3f9505c76018e665667e