mirror of
https://github.com/yuzu-emu/FasTC.git
synced 2025-01-07 01:45:28 +00:00
Merge branch 'master' into MinGW
This commit is contained in:
commit
f64c2d57a2
2
.gitmodules
vendored
2
.gitmodules
vendored
|
@ -1,3 +1,3 @@
|
|||
[submodule "Windows"]
|
||||
path = Windows
|
||||
url = git@github.com:Mokosha/FasTC-MSVCLibs.git
|
||||
url = https://github.com/Mokosha/FasTC-MSVCLibs.git
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -52,3 +52,5 @@
|
|||
#cmakedefine HAS_ATOMICS
|
||||
#cmakedefine HAS_GCC_ATOMICS
|
||||
#cmakedefine HAS_MSVC_ATOMICS
|
||||
|
||||
#cmakedefine FOUND_NVTT_BC7_EXPORT
|
||||
|
|
|
@ -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 &);
|
||||
|
|
|
@ -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;
|
||||
|
|
207
BPTCEncoder/src/CompressNVTT.cpp
Normal file
207
BPTCEncoder/src/CompressNVTT.cpp
Normal 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
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
71
CMakeModules/FindBC7Export.cmake
Normal file
71
CMakeModules/FindBC7Export.cmake
Normal 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 )
|
104
CMakeModules/bc7_export/CMakeLists.txt
Normal file
104
CMakeModules/bc7_export/CMakeLists.txt
Normal 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}
|
||||
)
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
enum EImageFileFormat {
|
||||
eFileFormat_PNG,
|
||||
eFileFormat_PVR,
|
||||
eFileFormat_TGA,
|
||||
|
||||
kNumImageFileFormats
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
81
IO/src/ImageLoaderTGA.cpp
Normal 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
66
IO/src/ImageLoaderTGA.h
Normal 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
648
IO/third_party/tga/targa.c
vendored
Executable 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
232
IO/third_party/tga/targa.h
vendored
Executable 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
|
||||
|
|
@ -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)
|
||||
|
||||
|
|
61
README.md
61
README.md
|
@ -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)
|
||||
|
|
2
Windows
2
Windows
|
@ -1 +1 @@
|
|||
Subproject commit 326dfccf36295f9ae43822a4d3fe3f21d87fbf94
|
||||
Subproject commit 4feeeb6550851ba3541c3f9505c76018e665667e
|
Loading…
Reference in a new issue