diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..1321102 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "Windows"] + path = Windows + url = git@github.com:Mokosha/FasTC-MSVCLibs.git diff --git a/BPTCEncoder/src/BC7Compressor.cpp b/BPTCEncoder/src/BC7Compressor.cpp index 2985e4b..65f34e6 100755 --- a/BPTCEncoder/src/BC7Compressor.cpp +++ b/BPTCEncoder/src/BC7Compressor.cpp @@ -1526,12 +1526,11 @@ namespace BC7C // implementation has an 4:1 compression ratio. void CompressImageBC7(const unsigned char *inBuf, unsigned char *outBuf, unsigned int width, unsigned int height) { - uint32 block[16]; BC7CompressionMode::MaxAnnealingIterations = min(BC7CompressionMode::kMaxAnnealingIterations, GetQualityLevel()); - for(int j = 0; j < height; j += 4) + for(uint32 j = 0; j < height; j += 4) { - for(int i = 0; i < width; i += 4) + for(uint32 i = 0; i < width; i += 4) { // ExtractBlock(inBuf + i * 4, width, block); CompressBC7Block((const uint32 *)inBuf, outBuf); @@ -1569,12 +1568,11 @@ namespace BC7C unsigned int height, BlockStatManager &statManager ) { - uint32 block[16]; BC7CompressionMode::MaxAnnealingIterations = min(BC7CompressionMode::kMaxAnnealingIterations, GetQualityLevel()); - for(int j = 0; j < height; j += 4) + for(uint32 j = 0; j < height; j += 4) { - for(int i = 0; i < width; i += 4) + for(uint32 i = 0; i < width; i += 4) { // ExtractBlock(inBuf + i * 4, width, block); CompressBC7Block((const uint32 *)inBuf, outBuf, statManager); @@ -2387,7 +2385,7 @@ namespace BC7C assert(idxMode < 2); assert(rotMode < 4); - assert(shapeIdx < ((mode == 0)? 16 : 64)); + assert(shapeIdx < uint32((mode == 0)? 16 : 64)); uint32 cp = attrs->colorChannelPrecision; const uint32 shift = 8 - cp; diff --git a/BPTCEncoder/src/RGBAEndpoints.cpp b/BPTCEncoder/src/RGBAEndpoints.cpp index 452bf11..b709b03 100755 --- a/BPTCEncoder/src/RGBAEndpoints.cpp +++ b/BPTCEncoder/src/RGBAEndpoints.cpp @@ -505,7 +505,7 @@ static uint32 PowerIteration(const RGBAMatrix &mat, RGBADir &eigVec, double &eig for(int nTries = 0; nTries < 3; nTries++) { // !SPEED! Find eigenvectors by using the power method. This is good because the // matrix is only 4x4, which allows us to use SIMD... - RGBAVector b = RGBAVector(rand()); + RGBAVector b = RGBAVector(float(rand())); assert(b.Length() > 0); b /= b.Length(); @@ -528,7 +528,7 @@ static uint32 PowerIteration(const RGBAMatrix &mat, RGBADir &eigVec, double &eig } eigVal = newB.Length(); - newB /= eigVal; + newB /= float(eigVal); if(fabs(1.0f - (b * newB)) < 1e-5) fixed = true; diff --git a/CLTool/CMakeLists.txt b/CLTool/CMakeLists.txt index 7712500..58166f0 100644 --- a/CLTool/CMakeLists.txt +++ b/CLTool/CMakeLists.txt @@ -54,6 +54,12 @@ ADD_EXECUTABLE( ${SOURCES} ) +# Make sure that if we're using boost libraries for threading then we add this linker path. +# Personally, I believe this is a bug in CMAKE but I'm not exactly sure. +#IF( THREAD_API MATCHES "Boost" ) +# SET_TARGET_PROPERTIES(tc PROPERTIES LINK_FLAGS "/LIBPATH:\"${Boost_LIBRARY_DIRS}\"") +#ENDIF() + TARGET_LINK_LIBRARIES( tc BPTCEncoder ) TARGET_LINK_LIBRARIES( tc TexCompIO ) TARGET_LINK_LIBRARIES( tc TexCompCore ) diff --git a/CLTool/src/clwin32.cpp b/CLTool/src/clwin32.cpp index e5f7a4c..44859cb 100644 --- a/CLTool/src/clwin32.cpp +++ b/CLTool/src/clwin32.cpp @@ -40,6 +40,187 @@ * * */ +#include +#include +#include +#include +#include -int main(int argc, char **argv) { +#include "BlockStats.h" +#include "TexComp.h" +#include "ImageFile.h" +#include "Image.h" + +void PrintUsage() { + fprintf(stderr, "Usage: tc [-l] [-q ] [-n ] [-simd] [-t [-j ]] \n"); +} + +void ExtractBasename(const char *filename, char *buf, uint32 bufSz) { + size_t len = strlen(filename); + const char *end = filename + len; + while(--end != filename) { + if(*end == '.') + { + uint32 numChars = int32(end - filename + 1); + uint32 toCopy = (numChars > bufSz)? bufSz : numChars; + memcpy(buf, filename, toCopy); + buf[toCopy - 1] = '\0'; + return; + } + } +} + +int _tmain(int argc, _TCHAR* argv[]) +{ + int fileArg = 1; + if(fileArg == argc) { + PrintUsage(); + exit(1); + } + + int numJobs = 0; + int quality = 50; + int numThreads = 1; + int numCompressions = 1; + bool bUseSIMD = false; + bool bSaveLog = false; + + bool knowArg = false; + do { + knowArg = false; + + if(strcmp(argv[fileArg], "-n") == 0) { + fileArg++; + + if(fileArg == argc || (numCompressions = atoi(argv[fileArg])) < 0) { + PrintUsage(); + exit(1); + } + + fileArg++; + knowArg = true; + continue; + } + + if(strcmp(argv[fileArg], "-l") == 0) { + fileArg++; + bSaveLog = true; + knowArg = true; + continue; + } + + if(strcmp(argv[fileArg], "-simd") == 0) { + fileArg++; + bUseSIMD = true; + knowArg = true; + continue; + } + + if(strcmp(argv[fileArg], "-t") == 0) { + fileArg++; + + if(fileArg == argc || (numThreads = atoi(argv[fileArg])) < 1) { + PrintUsage(); + exit(1); + } + + fileArg++; + knowArg = true; + continue; + } + + if(strcmp(argv[fileArg], "-q") == 0) { + fileArg++; + + if(fileArg == argc || (quality = atoi(argv[fileArg])) < 0) { + PrintUsage(); + exit(1); + } + + fileArg++; + knowArg = true; + continue; + } + + if(strcmp(argv[fileArg], "-j") == 0) { + fileArg++; + + if(fileArg == argc || (numJobs = atoi(argv[fileArg])) < 0) { + PrintUsage(); + exit(1); + } + + fileArg++; + knowArg = true; + continue; + } + + } while(knowArg && fileArg < argc); + + if(numThreads > 1 && bSaveLog) { + bSaveLog = false; + fprintf(stderr, "WARNING: Will not save log because implementation is not thread safe.\n" + "If you'd like, send a complaint to pavel@cs.unc.edu to get this done faster.\n"); + } + + if(fileArg == argc) { + PrintUsage(); + exit(1); + } + + char basename[256]; + ExtractBasename(argv[fileArg], basename, 256); + + ImageFile file (argv[fileArg]); + if(!file.Load()) { + fprintf(stderr, "Error loading file: %s\n", argv[fileArg]); + return 1; + } + + const Image *img = file.GetImage(); + + int numBlocks = (img->GetWidth() * img->GetHeight())/16; + BlockStatManager *statManager = NULL; + if(bSaveLog) { + statManager = new BlockStatManager(numBlocks); + } + + SCompressionSettings settings; + settings.bUseSIMD = bUseSIMD; + settings.iNumThreads = numThreads; + settings.iQuality = quality; + settings.iNumCompressions = numCompressions; + settings.iJobSize = numJobs; + settings.pStatManager = statManager; + + CompressedImage *ci = img->Compress(settings); + if(NULL == ci) { + fprintf(stderr, "Error compressing image!\n"); + return 1; + } + + double PSNR = img->ComputePSNR(*ci); + if(PSNR > 0.0) { + fprintf(stdout, "PSNR: %.3f\n", PSNR); + } + else { + fprintf(stderr, "Error computing PSNR\n"); + } + + if(bSaveLog) { + strcat_s(basename, ".log"); + statManager->ToFile(basename); + basename[strlen(basename) - 4] = '\0'; + } + strcat_s(basename, "-bc7.png"); + Image cImg (*ci); + ImageFile cImgFile (basename, eFileFormat_PNG, cImg); + cImgFile.Write(); + + // Cleanup + delete ci; + if(statManager) + delete statManager; + + return 0; } diff --git a/CMakeLists.txt b/CMakeLists.txt index 5dffcf0..0736be7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,31 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR) PROJECT(TexC) +IF(MSVC) + SET(MSVC_INSTALL_PATH "${PROJECT_SOURCE_DIR}/Windows") + SET(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH};${MSVC_INSTALL_PATH}") + + IF(MSVC10) + SET(MSVC_VERSION_STRING vc100) + ELSEIF(MSVC11) + SET(MSVC_VERSION_STRING vc110) + ELSEIF(MSVC90) + SET(MSVC_VERSION_STRING vc90) + ELSEIF(MSVC80) + SET(MSVC_VERSION_STRING vc80) + ENDIF() + + # !FIXME! Actually detect compiler architecture version.... + IF( CMAKE_SIZEOF_VOID_P EQUAL 8 ) + SET(MSVC_ARCHITECTURE_STRING x64) + ELSE() + SET(MSVC_ARCHITECTURE_STRING x86) + ENDIF() + + SET(MSVC_LIB_DIR "${MSVC_INSTALL_PATH}/lib/${MSVC_ARCHITECTURE_STRING}/${MSVC_VERSION_STRING}") + SET(CMAKE_LIBRARY_PATH "${CMAKE_LIBRARY_PATH};${MSVC_LIB_DIR}") +ENDIF(MSVC) + ADD_SUBDIRECTORY(BPTCEncoder) ADD_SUBDIRECTORY(IO) ADD_SUBDIRECTORY(Core) diff --git a/Core/CMakeLists.txt b/Core/CMakeLists.txt index c7d4bc1..6c970ad 100644 --- a/Core/CMakeLists.txt +++ b/Core/CMakeLists.txt @@ -80,7 +80,15 @@ INCLUDE_DIRECTORIES( ${TexC_SOURCE_DIR}/Core/include ) SET( THREAD_API ) SET( THREAD_APIS_AVAILABLE "None" ) -FIND_PACKAGE( Boost COMPONENTS thread system ) +###### Find Boost... + +IF( MSVC ) + SET(ENV{BOOSTLIBDIR} "${MSVC_LIB_DIR}") + SET(ENV{BOOSTINCLUDEDIR} "${MSVC_INSTALL_PATH}/include") +ENDIF( MSVC ) + +SET( Boost_USE_STATIC_LIBS ON ) +FIND_PACKAGE( Boost COMPONENTS thread system date_time chrono ) IF( Boost_FOUND ) SET( THREAD_APIS_AVAILABLE "Boost" ${THREAD_APIS_AVAILABLE} ) @@ -90,6 +98,8 @@ IF( Boost_FOUND ) ENDIF() +###### Find PThreads.... + FIND_PACKAGE( Threads ) IF( CMAKE_USE_PTHREADS_INIT ) @@ -111,7 +121,7 @@ SET_PROPERTY( CACHE THREAD_API PROPERTY STRINGS ${THREAD_APIS_AVAILABLE} ) IF( THREAD_API MATCHES "Boost") INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIR} ) SET( SOURCES ${SOURCES} "src/ThreadBoost.cpp" ) - LINK_DIRECTORIES( ${Boost_LIBRARY_DIR} ) + LINK_DIRECTORIES( ${Boost_LIBRARY_DIRS} ) ENDIF() IF( THREAD_API MATCHES "PThread" ) @@ -125,7 +135,7 @@ ELSE() SET( SOURCES ${SOURCES} "src/ThreadGroup.cpp" ) SET( SOURCES ${SOURCES} "src/WorkerQueue.cpp" ) - SET( HEADERS ${HEADERS} "include/Thread.h" ) + SET( HEADERS ${HEADERS} "src/Thread.h" ) SET( HEADERS ${HEADERS} "src/ThreadGroup.h" ) SET( HEADERS ${HEADERS} "src/WorkerQueue.h" ) ENDIF() diff --git a/Core/include/BlockStats.h b/Core/include/BlockStats.h index af1c63b..ea75e81 100644 --- a/Core/include/BlockStats.h +++ b/Core/include/BlockStats.h @@ -46,7 +46,19 @@ #include "TexCompTypes.h" #include "ReferenceCounter.h" -#include "Thread.h" + +/////////////////////////////////////////////////////////////////////////////// +// +// Forward declarations +// +/////////////////////////////////////////////////////////////////////////////// +class TCMutex; + +/////////////////////////////////////////////////////////////////////////////// +// +// class BlockStat +// +/////////////////////////////////////////////////////////////////////////////// struct BlockStat { friend class BlockStatManager; @@ -57,7 +69,7 @@ public: BlockStat(const BlockStat &); BlockStat &operator=(const BlockStat &); - void ToString(char *buf, int bufSz) const; + void ToString(CHAR *buf, int bufSz) const; private: const enum Type { @@ -79,6 +91,8 @@ class BlockStatManager { public: BlockStatManager(int nBlocks); + BlockStatManager(const BlockStatManager &); + BlockStatManager &operator=(const BlockStatManager &); ~BlockStatManager(); uint32 BeginBlock(); @@ -90,6 +104,7 @@ class BlockStatManager { class BlockStatList { public: BlockStatList(); + BlockStatList(const BlockStatList &other); ~BlockStatList(); void AddStat(const BlockStat &stat); @@ -106,9 +121,12 @@ class BlockStatManager { } *m_BlockStatList; uint32 m_BlockStatListSz; - TCMutex m_Mutex; + TCMutex *m_Mutex; uint32 m_NextBlock; ReferenceCounter m_Counter; + + // Note: we probably shouldn't call this... + void Copy(const BlockStatManager &); }; #endif // __BLOCK_STATS_H__ diff --git a/Core/include/TexCompTypes.h b/Core/include/TexCompTypes.h index d6f5946..5290b41 100644 --- a/Core/include/TexCompTypes.h +++ b/Core/include/TexCompTypes.h @@ -52,16 +52,17 @@ #ifdef _MSC_VER typedef __int16 int16; -typedef __uint16 uint16; +typedef unsigned __int16 uint16; typedef __int32 int32; -typedef __uint32 uint32; +typedef unsigned __int32 uint32; typedef __int8 int8; -typedef __uint8 uint8; +typedef unsigned __int8 uint8; -typedef __uint64 uint64; +typedef unsigned __int64 uint64; typedef __int64 int64; -typedef __int32_ptr int32_ptr; +#include +typedef TCHAR CHAR; // If not, assume GCC, or at least standard defines... #else @@ -78,7 +79,6 @@ typedef uint16_t uint16; typedef uint32_t uint32; typedef uint64_t uint64; -typedef uintptr_t int32_ptr; typedef char CHAR; #endif // _MSC_VER diff --git a/Core/src/BlockStats.cpp b/Core/src/BlockStats.cpp index 72a3ed6..8af48e1 100644 --- a/Core/src/BlockStats.cpp +++ b/Core/src/BlockStats.cpp @@ -49,6 +49,7 @@ #include #include "FileStream.h" +#include "Thread.h" template static T max(const T &a, const T &b) { @@ -65,14 +66,22 @@ BlockStat::BlockStat(const CHAR *statName, int stat) : m_IntStat(stat) , m_Type(eType_Int) { +#ifdef _MSC_VER + strncpy_s(m_StatName, statName, kStatNameSz); +#else strncpy(m_StatName, statName, kStatNameSz); +#endif } BlockStat::BlockStat(const CHAR *statName, double stat) : m_FloatStat(stat) , m_Type(eType_Float) { +#ifdef _MSC_VER + strncpy_s(m_StatName, statName, kStatNameSz); +#else strncpy(m_StatName, statName, kStatNameSz); +#endif } BlockStat::BlockStat(const BlockStat &other) : m_Type(other.m_Type) { @@ -81,16 +90,25 @@ BlockStat::BlockStat(const BlockStat &other) : m_Type(other.m_Type) { BlockStat &BlockStat::operator=(const BlockStat &other) { memcpy(this, &other, sizeof(*this)); + return *this; } -void BlockStat::ToString(char *buf, int bufSz) const { +void BlockStat::ToString(CHAR *buf, int bufSz) const { switch(m_Type) { case BlockStat::eType_Float: +#ifdef _MSC_VER + _sntprintf_s(buf, bufSz, _TRUNCATE, "%s,%f", m_StatName, m_FloatStat); +#else snprintf(buf, bufSz, "%s,%f", m_StatName, m_FloatStat); +#endif break; case BlockStat::eType_Int: +#ifdef _MSC_VER + _sntprintf_s(buf, bufSz, _TRUNCATE, "%s,%llu", m_StatName, m_IntStat); +#else snprintf(buf, bufSz, "%s,%llu", m_StatName, m_IntStat); +#endif break; default: @@ -105,9 +123,36 @@ void BlockStat::ToString(char *buf, int bufSz) const { // //////////////////////////////////////////////////////////////////////////////// +void BlockStatManager::Copy(const BlockStatManager &other) { + // This is a bug. If we copy the manager then all of the lists and pointers + // become shared and can cause dereferencing issues. Check to see where you're + // copying this class and make sure to actually create a new instance. + assert(!"We shouldn't be copying these in this manner!"); + + m_BlockStatList = new BlockStatList(*other.m_BlockStatList); + m_BlockStatListSz = other.m_BlockStatListSz; + m_NextBlock = other.m_NextBlock; + + // If we do copy them, then make sure that we are actually using the exact same + // pointers for our synchronization primitives... otherwise we could run into + // deadlock issues. + m_Mutex = other.m_Mutex; +} + +BlockStatManager::BlockStatManager(const BlockStatManager &other) { + Copy(other); +} + +BlockStatManager &BlockStatManager::operator=(const BlockStatManager &other) { + m_Counter = other.m_Counter; + Copy(other); + return *this; +} + BlockStatManager::BlockStatManager(int nBlocks) : m_BlockStatListSz(max(nBlocks, 0)) , m_NextBlock(0) + , m_Mutex(new TCMutex) { m_BlockStatList = new BlockStatList[m_BlockStatListSz]; if(!m_BlockStatList) { @@ -121,6 +166,12 @@ BlockStatManager::~BlockStatManager() { if(m_Counter.GetRefCount() == 0) { delete [] m_BlockStatList; } + + if(m_Mutex) + { + delete m_Mutex; + m_Mutex = 0; + } } uint32 BlockStatManager::BeginBlock() { @@ -130,7 +181,7 @@ uint32 BlockStatManager::BeginBlock() { return m_NextBlock-1; } - TCLock lock (m_Mutex); + TCLock lock (*m_Mutex); return m_NextBlock++; } @@ -141,7 +192,7 @@ void BlockStatManager::AddStat(uint32 blockIdx, const BlockStat &stat) { return; } - TCLock lock (m_Mutex); + TCLock lock (*m_Mutex); m_BlockStatList[blockIdx].AddStat(stat); } @@ -149,7 +200,7 @@ void BlockStatManager::ToFile(const CHAR *filename) { FileStream fstr (filename, eFileMode_Write); - for(int i = 0; i < m_BlockStatListSz; i++) { + for(uint32 i = 0; i < m_BlockStatListSz; i++) { const BlockStatList *head = &(m_BlockStatList[i]); while(head) { BlockStat s = head->GetStat(); @@ -158,12 +209,16 @@ void BlockStatManager::ToFile(const CHAR *filename) { s.ToString(statStr, 256); CHAR str[256]; +#ifdef _MSC_VER + _sntprintf_s(str, 256, _TRUNCATE, "%d,%s\n", i, statStr); +#else snprintf(str, 256, "%d,%s\n", i, statStr); +#endif - int strLen = strlen(str); + uint32 strLen = uint32(strlen(str)); if(strLen > 255) { - str[255] = '\n'; - strLen = 256; + str[255] = '\n'; + strLen = 256; } fstr.Write((uint8 *)str, strLen); @@ -179,7 +234,7 @@ void BlockStatManager::ToFile(const CHAR *filename) { // //////////////////////////////////////////////////////////////////////////////// static const CHAR *kNullBlockString = "NULL_BLOCK_STAT"; -static const uint32 kNullBlockStringLength = strlen(kNullBlockString); +static const uint32 kNullBlockStringLength = uint32(strlen(kNullBlockString)); BlockStatManager::BlockStatList::BlockStatList() : m_Tail(0) @@ -190,8 +245,14 @@ BlockStatManager::BlockStatList::BlockStatList(const BlockStat &stat) : m_Tail(0) , m_Stat(stat) { + assert(!"If you're copying a block stat list then you're probably not using them properly."); } +BlockStatManager::BlockStatList::BlockStatList(const BlockStatList &other) + : m_Tail(new BlockStatList(*other.m_Tail)) + , m_Stat(other.m_Stat) +{} + BlockStatManager::BlockStatList::~BlockStatList() { if(m_Counter.GetRefCount() == 0 && m_Tail) { delete m_Tail; diff --git a/Core/src/CompressedImage.cpp b/Core/src/CompressedImage.cpp index 64b8a4d..de09bee 100644 --- a/Core/src/CompressedImage.cpp +++ b/Core/src/CompressedImage.cpp @@ -48,6 +48,7 @@ #include #include +#include "TexCompTypes.h" #include "BC7Compressor.h" CompressedImage::CompressedImage() @@ -109,7 +110,7 @@ CompressedImage::~CompressedImage() { bool CompressedImage::DecompressImage(unsigned char *outBuf, unsigned int outBufSz) const { // First make sure that we have enough data - int dataSz = 0; + uint32 dataSz = 0; switch(m_Format) { case eCompressionFormat_DXT1: dataSz = m_DataSz * 8; break; case eCompressionFormat_DXT5: dataSz = m_DataSz * 4; break; diff --git a/Core/src/Image.cpp b/Core/src/Image.cpp index 0884f71..d586f4f 100644 --- a/Core/src/Image.cpp +++ b/Core/src/Image.cpp @@ -118,7 +118,7 @@ double Image::ComputePSNR(const CompressedImage &ci) const { const double wb = 1.0; double MSE = 0.0; - for(int i = 0; i < imageSz; i+=4) { + for(uint32 i = 0; i < imageSz; i+=4) { const unsigned char *pixelDataRaw = m_PixelData + i; const unsigned char *pixelDataUncomp = unCompData + i; diff --git a/Core/src/StopWatchWin32.cpp b/Core/src/StopWatchWin32.cpp index a8701f4..1827701 100755 --- a/Core/src/StopWatchWin32.cpp +++ b/Core/src/StopWatchWin32.cpp @@ -67,12 +67,14 @@ #include "TexCompTypes.h" #include +#include class StopWatchImpl { +public: uint64 frequency; uint64 start; uint64 stop; - uintptr affinityMask; + uintptr_t affinityMask; StopWatchImpl() : start(0), stop(0), affinityMask(0) @@ -85,6 +87,8 @@ class StopWatchImpl { } }; +StopWatch::StopWatch() : impl(new StopWatchImpl) { } + StopWatch::StopWatch(const StopWatch &other) { impl = new StopWatchImpl(); memcpy(impl, other.impl, sizeof(StopWatchImpl)); @@ -96,6 +100,7 @@ StopWatch &StopWatch::operator=(const StopWatch &other) { } impl = new StopWatchImpl(); memcpy(impl, other.impl, sizeof(StopWatchImpl)); + return *this; } StopWatch::~StopWatch() { @@ -156,7 +161,7 @@ double StopWatch::TimeInSeconds() const { // Return the elapsed time in seconds. assert((impl->stop - impl->start) > 0); - return double(impl->stop - impl->start) / double(frequency); + return double(impl->stop - impl->start) / double(impl->frequency); } // Get the elapsed time in milliseconds. @@ -164,7 +169,7 @@ double StopWatch::TimeInMilliseconds() const { // Return the elapsed time in milliseconds. assert((impl->stop - impl->start) > 0); - return double(impl->stop - impl->start) / double(frequency) * 1000.0; + return double(impl->stop - impl->start) / double(impl->frequency) * 1000.0; } // Get the elapsed time in microseconds. diff --git a/Core/src/TexComp.cpp b/Core/src/TexComp.cpp index 243ee1a..6d2e990 100644 --- a/Core/src/TexComp.cpp +++ b/Core/src/TexComp.cpp @@ -268,7 +268,7 @@ bool CompressImageData( } // Allocate data based on the compression method - int cmpDataSzNeeded = 0; + uint32 cmpDataSzNeeded = 0; switch(settings.format) { case eCompressionFormat_DXT1: cmpDataSzNeeded = dataSz / 8; case eCompressionFormat_DXT5: cmpDataSzNeeded = dataSz / 4; diff --git a/Core/src/Thread.cpp b/Core/src/Thread.cpp index 59eade2..d1442d3 100644 --- a/Core/src/Thread.cpp +++ b/Core/src/Thread.cpp @@ -77,6 +77,8 @@ TCThreadBase &TCThreadBase::operator=(const TCThreadBase &other) { // Our implementation is now the same as the other. m_Impl = other.m_Impl; m_Impl->IncreaseReferenceCount(); + + return *this; } TCThreadBase::~TCThreadBase() { diff --git a/Core/include/Thread.h b/Core/src/Thread.h similarity index 98% rename from Core/include/Thread.h rename to Core/src/Thread.h index 2d90d17..3ec68c6 100644 --- a/Core/include/Thread.h +++ b/Core/src/Thread.h @@ -46,6 +46,11 @@ #include "TexCompTypes.h" +//!HACK! Apparently MSVC has issues with Yield()...???? +#ifdef _MSC_VER +#undef Yield +#endif + //////////////////////////////////////////////////////////////////////////////// // // Base implementation @@ -111,9 +116,9 @@ class TCThread : public TCThreadBase { public: TCThread(TCCallable &); - - void Join(); + static void Yield(); + void Join(); }; //////////////////////////////////////////////////////////////////////////////// diff --git a/Core/src/ThreadGroup.cpp b/Core/src/ThreadGroup.cpp index 0654b61..1587082 100644 --- a/Core/src/ThreadGroup.cpp +++ b/Core/src/ThreadGroup.cpp @@ -286,6 +286,8 @@ bool ThreadGroup::CleanUpThreads() { // Reset active number of threads... m_ActiveThreads = 0; m_ExitFlag = false; + + return true; } void ThreadGroup::Join() { diff --git a/Core/src/WorkerQueue.cpp b/Core/src/WorkerQueue.cpp index 44d41a6..62a802c 100644 --- a/Core/src/WorkerQueue.cpp +++ b/Core/src/WorkerQueue.cpp @@ -191,7 +191,7 @@ void WorkerQueue::Run() { // Spawn a bunch of threads... TCLock lock(m_Mutex); - for(int i = 0; i < m_NumThreads; i++) { + for(uint32 i = 0; i < m_NumThreads; i++) { m_Workers[i] = new WorkerThread(this, i); m_ThreadHandles[m_ActiveThreads] = new TCThread(*m_Workers[i]); m_ActiveThreads++; @@ -211,7 +211,7 @@ void WorkerQueue::Run() { m_StopWatch.Stop(); // Join them all together.. - for(int i = 0; i < m_NumThreads; i++) { + for(uint32 i = 0; i < m_NumThreads; i++) { m_ThreadHandles[i]->Join(); delete m_ThreadHandles[i]; delete m_Workers[i]; @@ -274,7 +274,7 @@ WorkerThread::EAction WorkerQueue::AcceptThreadData(uint32 threadIdx) { const uint8 *WorkerQueue::GetSrcForThread(const int threadIdx) const { assert(m_Offsets[threadIdx] >= 0); assert(threadIdx >= 0); - assert(threadIdx < m_NumThreads); + assert(threadIdx < int(m_NumThreads)); const uint32 inBufBlockSz = 16 * 4; return m_InBuf + m_Offsets[threadIdx] * inBufBlockSz; @@ -283,7 +283,7 @@ const uint8 *WorkerQueue::GetSrcForThread(const int threadIdx) const { uint8 *WorkerQueue::GetDstForThread(const int threadIdx) const { assert(m_Offsets[threadIdx] >= 0); assert(threadIdx >= 0); - assert(threadIdx < m_NumThreads); + assert(threadIdx < int(m_NumThreads)); const uint32 outBufBlockSz = 16; return m_OutBuf + m_Offsets[threadIdx] * outBufBlockSz; @@ -292,7 +292,7 @@ uint8 *WorkerQueue::GetDstForThread(const int threadIdx) const { uint32 WorkerQueue::GetNumBlocksForThread(const int threadIdx) const { assert(m_Offsets[threadIdx] >= 0); assert(threadIdx >= 0); - assert(threadIdx < m_NumThreads); + assert(threadIdx < int(m_NumThreads)); return m_NumBlocks[threadIdx]; } diff --git a/Core/src/WorkerQueue.h b/Core/src/WorkerQueue.h index 49dbec9..97d6833 100644 --- a/Core/src/WorkerQueue.h +++ b/Core/src/WorkerQueue.h @@ -53,7 +53,7 @@ class WorkerQueue; #include "Thread.h" #include "StopWatch.h" -struct WorkerThread : public TCCallable { +class WorkerThread : public TCCallable { friend class WorkerQueue; public: diff --git a/IO/CMakeLists.txt b/IO/CMakeLists.txt index 27a9079..1f23aa9 100644 --- a/IO/CMakeLists.txt +++ b/IO/CMakeLists.txt @@ -43,7 +43,6 @@ SET( SOURCES "src/ImageWriter.cpp" "src/ImageLoader.cpp" - "src/FileStream.cpp" "src/ImageFile.cpp" ) @@ -54,6 +53,15 @@ SET( HEADERS "include/FileStream.h" ) +IF( WIN32 ) + SET( SOURCES ${SOURCES} "src/FileStreamWin32.cpp" ) +ELSE() + SET( SOURCES ${SOURCES} "src/FileStreamUnix.cpp" ) + + # Assume compiler is GCC + SET( LINK_FLAGS -lrt ${LINK_FLAGS} ) +ENDIF() + FIND_PACKAGE( PNG ) IF( PNG_FOUND ) INCLUDE_DIRECTORIES( ${PNG_INCLUDE_DIR} ) diff --git a/IO/include/ImageFile.h b/IO/include/ImageFile.h index 143b319..9f13fc0 100644 --- a/IO/include/ImageFile.h +++ b/IO/include/ImageFile.h @@ -82,7 +82,7 @@ public: const EImageFileFormat m_FileFormat; static unsigned char *ReadFileData(const CHAR *filename); - static bool WriteImageDataToFile(const uint8 *data, const uint32 dataSz, const CHAR *filename); + static bool WriteImageDataToFile(const uint8 *data, const uint32 dataSz, const CHAR *filename); static EImageFileFormat DetectFileFormat(const CHAR *filename); Image *LoadImage(const unsigned char *rawImageData) const; diff --git a/IO/src/FileStream.cpp b/IO/src/FileStreamUnix.cpp similarity index 99% rename from IO/src/FileStream.cpp rename to IO/src/FileStreamUnix.cpp index 3b881f7..da9e40b 100644 --- a/IO/src/FileStream.cpp +++ b/IO/src/FileStreamUnix.cpp @@ -139,6 +139,8 @@ FileStream &FileStream::operator=(const FileStream &other) { m_Mode = other.m_Mode; strncpy(m_Filename, other.m_Filename, kMaxFilenameSz); + + return *this; } FileStream::~FileStream() { diff --git a/IO/src/FileStreamWin32.cpp b/IO/src/FileStreamWin32.cpp new file mode 100755 index 0000000..176b519 --- /dev/null +++ b/IO/src/FileStreamWin32.cpp @@ -0,0 +1,253 @@ +#include "FileStream.h" + +#include +#include +#include + +class FileStreamImpl { + +private: + // Track the number of references to this filestream so + // that we know whether or not we need to close it when + // the object gets destroyed. + uint32 m_ReferenceCount; + + HANDLE m_Handle; + +public: + FileStreamImpl(const CHAR *filename, EFileMode mode) + : m_ReferenceCount(1) + { + + DWORD dwDesiredAccess = GENERIC_READ; + DWORD dwShareMode = 0; + switch(mode) { + default: + case eFileMode_ReadBinary: + case eFileMode_Read: + // Do nothing. + break; + + case eFileMode_Write: + case eFileMode_WriteBinary: + dwDesiredAccess = GENERIC_WRITE; + break; + + case eFileMode_WriteAppend: + case eFileMode_WriteBinaryAppend: + dwDesiredAccess = FILE_APPEND_DATA; + break; + } + + m_Handle = CreateFile(filename, dwDesiredAccess, dwShareMode, NULL, 0, FILE_ATTRIBUTE_NORMAL, NULL); + assert(m_Handle != INVALID_HANDLE_VALUE); + } + + ~FileStreamImpl() { + CloseHandle(m_Handle); + } + + void IncreaseReferenceCount() { m_ReferenceCount++; } + void DecreaseReferenceCount() { m_ReferenceCount--; } + + uint32 GetReferenceCount() { return m_ReferenceCount; } + + HANDLE GetFileHandle() const { return m_Handle; } +}; + +FileStream::FileStream(const CHAR *filename, EFileMode mode) + : m_Impl(new FileStreamImpl(filename, mode)) + , m_Mode(mode) +{ + strncpy_s(m_Filename, filename, kMaxFilenameSz); + m_Filename[kMaxFilenameSz - 1] = CHAR('\0'); +} + +FileStream::FileStream(const FileStream &other) + : m_Impl(other.m_Impl) + , m_Mode(other.m_Mode) +{ + m_Impl->IncreaseReferenceCount(); + strncpy_s(m_Filename, other.m_Filename, kMaxFilenameSz); +} + +FileStream &FileStream::operator=(const FileStream &other) { + + // We no longer reference this implementation. + m_Impl->DecreaseReferenceCount(); + + // If we're the last ones to reference it, then it should be destroyed. + if(m_Impl->GetReferenceCount() <= 0) { + assert(m_Impl->GetReferenceCount() == 0); + delete m_Impl; + m_Impl = 0; + } + + m_Impl = other.m_Impl; + m_Impl->IncreaseReferenceCount(); + + m_Mode = other.m_Mode; + strncpy_s(m_Filename, other.m_Filename, kMaxFilenameSz); + + return *this; +} + +FileStream::~FileStream() { + // We no longer reference this implementation. + m_Impl->DecreaseReferenceCount(); + + // If we're the last ones to reference it, then it should be destroyed. + if(m_Impl->GetReferenceCount() <= 0) { + assert(m_Impl->GetReferenceCount() == 0); + delete m_Impl; + m_Impl = 0; + } +} + +int32 FileStream::Read(uint8 *buf, uint32 bufSz) { + + if( + m_Mode == eFileMode_Write || + m_Mode == eFileMode_WriteBinary || + m_Mode == eFileMode_WriteAppend || + m_Mode == eFileMode_WriteBinaryAppend + ) { + CHAR errStr[256]; + _sntprintf_s(errStr, 256, "Cannot read from file '%s': File opened for reading.", m_Filename); + OutputDebugString(errStr); + return -2; + } + + HANDLE fp = m_Impl->GetFileHandle(); + if(INVALID_HANDLE_VALUE == fp) + return -1; + + DWORD oldPosition = SetFilePointer(fp, 0, NULL, FILE_CURRENT); + if(INVALID_SET_FILE_POINTER == oldPosition) { + CHAR errStr[256]; + _sntprintf_s(errStr, 256, "Error querying the file position before reading from file '%s'(0x%x).", m_Filename, GetLastError()); + OutputDebugString(errStr); + return -1; + } + + DWORD amtRead; + BOOL success = ReadFile(fp, buf, bufSz, &amtRead, NULL); + if(!success) { + CHAR errStr[256]; + _sntprintf_s(errStr, 256, "Error reading from file '%s'.", m_Filename); + OutputDebugString(errStr); + return -1; + } + + DWORD newPosition = SetFilePointer(fp, 0, NULL, FILE_CURRENT); + if(INVALID_SET_FILE_POINTER == newPosition) { + CHAR errStr[256]; + _sntprintf_s(errStr, 256, "Error querying the file position after reading from file '%s'(0x%x).", m_Filename, GetLastError()); + OutputDebugString(errStr); + return -1; + } + + return newPosition - oldPosition; +} + +int32 FileStream::Write(const uint8 *buf, uint32 bufSz) { + if( + m_Mode == eFileMode_Read || + m_Mode == eFileMode_ReadBinary + ) { + CHAR errStr[256]; + _sntprintf_s(errStr, 256, "Cannot write to file '%s': File opened for writing.", m_Filename); + OutputDebugString(errStr); + return -2; + } + + HANDLE fp = m_Impl->GetFileHandle(); + if(NULL == fp) + return -1; + + DWORD dwPos; + if(m_Mode == eFileMode_WriteBinaryAppend || m_Mode == eFileMode_WriteAppend) { + dwPos = SetFilePointer(fp, 0, NULL, FILE_END); + } + else { + dwPos = SetFilePointer(fp, 0, NULL, FILE_CURRENT); + } + + if(INVALID_SET_FILE_POINTER == dwPos) { + CHAR errStr[256]; + _sntprintf_s(errStr, 256, "Error querying the file position before reading to file '%s'(0x%x).", m_Filename, GetLastError()); + OutputDebugString(errStr); + return -1; + } + + while(!LockFile(fp, dwPos, 0, bufSz, 0)) Sleep(1); + + DWORD amtWritten; + BOOL success = WriteFile(fp, buf, bufSz, &amtWritten, NULL); + + UnlockFile(fp, dwPos, 0, bufSz, 0); + + if(!success) { + CHAR errStr[256]; + _sntprintf_s(errStr, 256, "Error writing to file '%s'.", m_Filename); + OutputDebugString(errStr); + return -1; + } + + return amtWritten; +} + +int64 FileStream::Tell() { + HANDLE fp = m_Impl->GetFileHandle(); + if(NULL == fp) { + return -1; + } + + DWORD pos = SetFilePointer(fp, 0, NULL, FILE_CURRENT); + if(INVALID_SET_FILE_POINTER == pos) { + CHAR errStr[256]; + _sntprintf_s(errStr, 256, "Error querying the file position before reading to file '%s'(0x%x).", m_Filename, GetLastError()); + OutputDebugString(errStr); + return -1; + } + + return pos; +} + +bool FileStream::Seek(uint32 offset, ESeekPosition pos) { + + // We cannot seek in append mode. + if(m_Mode == eFileMode_WriteAppend || m_Mode == eFileMode_WriteBinaryAppend) + return false; + + HANDLE fp = m_Impl->GetFileHandle(); + if(NULL == fp) return false; + + DWORD origin = FILE_BEGIN; + switch(pos) { + default: + case eSeekPosition_Beginning: + // Do nothing + break; + + case eSeekPosition_Current: + origin = FILE_CURRENT; + break; + + case eSeekPosition_End: + origin = FILE_END; + break; + } + + if(SetFilePointer(fp, offset, NULL, origin) == INVALID_SET_FILE_POINTER) + return false; + + return true; +} + +void FileStream::Flush() { + HANDLE fp = m_Impl->GetFileHandle(); + if(NULL == fp) return; + + FlushFileBuffers(fp); +} diff --git a/IO/src/ImageFile.cpp b/IO/src/ImageFile.cpp index d919b24..c9ceca3 100644 --- a/IO/src/ImageFile.cpp +++ b/IO/src/ImageFile.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include "ImageWriter.h" #include "ImageLoader.h" @@ -75,10 +76,10 @@ static inline T abs(const T &a) { return a > 0? a : -a; } -template -static inline T min(const T &a, const T &b) { - return (a < b)? a : b; -} +//!HACK! +#ifdef _MSC_VER +#define strncpy strncpy_s +#endif ////////////////////////////////////////////////////////////////////////////////////////// // @@ -156,7 +157,7 @@ bool ImageFile::Write() { return false; } - WriteImageDataToFile(writer->GetRawFileData(), writer->GetRawFileDataSz(), m_Filename); + WriteImageDataToFile(writer->GetRawFileData(), uint32(writer->GetRawFileDataSz()), m_Filename); delete writer; return true; @@ -197,13 +198,13 @@ Image *ImageFile::LoadImage(const unsigned char *rawImageData) const { EImageFileFormat ImageFile::DetectFileFormat(const CHAR *filename) { - int len = strlen(filename); + size_t len = strlen(filename); if(len >= 256) { // !FIXME! Report Error... return kNumImageFileFormats; } - int dotPos = len - 1; + size_t dotPos = len - 1; while(dotPos >= 0 && filename[dotPos--] != '.'); @@ -242,8 +243,16 @@ unsigned char *ImageFile::ReadFileData(const CHAR *filename) { assert(fstr.Tell() == 0); // Read all of the data - int32 bytesRead = fstr.Read(rawData, fileSize); - if(bytesRead != fileSize) { + uint64 totalBytesRead = 0; + uint64 totalBytesLeft = fileSize; + uint32 bytesToRead = uint32(std::min(totalBytesLeft, uint64(1 << 31))); + int32 bytesRead; + while((bytesRead = fstr.Read(rawData, uint32(fileSize))) > 0) { + totalBytesRead += bytesRead; + totalBytesLeft -= bytesRead; + } + + 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; diff --git a/IO/src/ImageLoader.cpp b/IO/src/ImageLoader.cpp index af1caa4..1d06c27 100644 --- a/IO/src/ImageLoader.cpp +++ b/IO/src/ImageLoader.cpp @@ -48,6 +48,12 @@ #include #include +/////////////////////////////////////////////////////////////////////////////// +// +// Static helper functions +// +/////////////////////////////////////////////////////////////////////////////// + template static inline T min(const T &a, const T &b) { return (a > b)? b : a; @@ -58,6 +64,11 @@ static inline T abs(const T &a) { return (a > 0)? a : -a; } +template +static inline T sad(const T &a, const T &b) { + return (a > b)? a - b : b - a; +} + void ReportError(const char *str) { fprintf(stderr, "ImageLoader.cpp -- ERROR: %s\n", str); } @@ -102,8 +113,8 @@ unsigned int ImageLoader::GetChannelForPixel(uint32 x, uint32 y, uint32 ch) { const uint32 val = data[pixelIdx]; if(prec < 8) { - uint32 ret = 0; - for(uint32 precLeft = 8; precLeft > 0; precLeft -= min(prec, abs(prec - precLeft))) { + int32 ret = 0; + for(uint32 precLeft = 8; precLeft > 0; precLeft -= min(prec, sad(prec, precLeft))) { if(prec > precLeft) { const int toShift = prec - precLeft; @@ -120,7 +131,7 @@ unsigned int ImageLoader::GetChannelForPixel(uint32 x, uint32 y, uint32 ch) { return ret; } else if(prec > 8) { - const int toShift = prec - 8; + const int32 toShift = prec - 8; return val >> toShift; } @@ -156,59 +167,59 @@ bool ImageLoader::LoadImage() { #endif int byteIdx = 0; - for(int i = 0; i < ah; i+=4) { - for(int j = 0; j < aw; j+= 4) { + for(uint32 i = 0; i < ah; i+=4) { + for(uint32 j = 0; j < aw; j+= 4) { // For each block, visit the pixels in sequential order - for(int y = i; y < i+4; y++) { - for(int x = j; x < j+4; x++) { + for(uint32 y = i; y < i+4; y++) { + for(uint32 x = j; x < j+4; x++) { - if(y >= m_Height || x >= m_Width) { - m_PixelData[byteIdx++] = 0; // r - m_PixelData[byteIdx++] = 0; // g - m_PixelData[byteIdx++] = 0; // b - m_PixelData[byteIdx++] = 0; // a - continue; - } + if(y >= m_Height || x >= m_Width) { + m_PixelData[byteIdx++] = 0; // r + m_PixelData[byteIdx++] = 0; // g + m_PixelData[byteIdx++] = 0; // b + m_PixelData[byteIdx++] = 0; // a + continue; + } - unsigned int redVal = GetChannelForPixel(x, y, 0); - if(redVal == INT_MAX) - return false; + unsigned int redVal = GetChannelForPixel(x, y, 0); + if(redVal == INT_MAX) + return false; - unsigned int greenVal = redVal; - unsigned int blueVal = redVal; + unsigned int greenVal = redVal; + unsigned int blueVal = redVal; - if(GetGreenChannelPrecision() > 0) { - greenVal = GetChannelForPixel(x, y, 1); - if(greenVal == INT_MAX) - return false; - } + if(GetGreenChannelPrecision() > 0) { + greenVal = GetChannelForPixel(x, y, 1); + if(greenVal == INT_MAX) + return false; + } - if(GetBlueChannelPrecision() > 0) { - blueVal = GetChannelForPixel(x, y, 2); - if(blueVal == INT_MAX) - return false; - } + if(GetBlueChannelPrecision() > 0) { + blueVal = GetChannelForPixel(x, y, 2); + if(blueVal == INT_MAX) + return false; + } - unsigned int alphaVal = 0xFF; - if(GetAlphaChannelPrecision() > 0) { - alphaVal = GetChannelForPixel(x, y, 3); - if(alphaVal == INT_MAX) - return false; - } + unsigned int alphaVal = 0xFF; + if(GetAlphaChannelPrecision() > 0) { + alphaVal = GetChannelForPixel(x, y, 3); + if(alphaVal == INT_MAX) + return false; + } - // Red channel - m_PixelData[byteIdx++] = redVal & 0xFF; + // Red channel + m_PixelData[byteIdx++] = redVal & 0xFF; - // Green channel - m_PixelData[byteIdx++] = greenVal & 0xFF; + // Green channel + m_PixelData[byteIdx++] = greenVal & 0xFF; - // Blue channel - m_PixelData[byteIdx++] = blueVal & 0xFF; + // Blue channel + m_PixelData[byteIdx++] = blueVal & 0xFF; - // Alpha channel - m_PixelData[byteIdx++] = alphaVal & 0xFF; - } + // Alpha channel + m_PixelData[byteIdx++] = alphaVal & 0xFF; + } } } } diff --git a/IO/src/ImageLoaderPNG.cpp b/IO/src/ImageLoaderPNG.cpp index dc298a7..48f4411 100644 --- a/IO/src/ImageLoaderPNG.cpp +++ b/IO/src/ImageLoaderPNG.cpp @@ -150,14 +150,14 @@ bool ImageLoaderPNG::ReadData() { m_RedChannelPrecision = bitDepth; m_RedData = new unsigned char[numPixels]; - for(int i = 0; i < m_Height; i++) { + for(uint32 i = 0; i < m_Height; i++) { png_read_row(png_ptr, rowData, NULL); unsigned int rowOffset = i * m_Width; unsigned int byteIdx = 0; - for(int j = 0; j < m_Width; j++) { + for(uint32 j = 0; j < m_Width; j++) { m_RedData[rowOffset + j] = rowData[byteIdx++]; } @@ -174,14 +174,14 @@ bool ImageLoaderPNG::ReadData() { m_BlueChannelPrecision = bitDepth; m_BlueData = new unsigned char[numPixels]; - for(int i = 0; i < m_Height; i++) { + for(uint32 i = 0; i < m_Height; i++) { png_read_row(png_ptr, rowData, NULL); unsigned int rowOffset = i * m_Width; unsigned int byteIdx = 0; - for(int j = 0; j < m_Width; j++) { + for(uint32 j = 0; j < m_Width; j++) { m_RedData[rowOffset + j] = rowData[byteIdx++]; m_GreenData[rowOffset + j] = rowData[byteIdx++]; m_BlueData[rowOffset + j] = rowData[byteIdx++]; @@ -201,14 +201,14 @@ bool ImageLoaderPNG::ReadData() { m_AlphaChannelPrecision = bitDepth; m_AlphaData = new unsigned char[numPixels]; - for(int i = 0; i < m_Height; i++) { + for(uint32 i = 0; i < m_Height; i++) { png_read_row(png_ptr, rowData, NULL); unsigned int rowOffset = i * m_Width; unsigned int byteIdx = 0; - for(int j = 0; j < m_Width; j++) { + for(uint32 j = 0; j < m_Width; j++) { m_RedData[rowOffset + j] = rowData[byteIdx++]; m_GreenData[rowOffset + j] = rowData[byteIdx++]; m_BlueData[rowOffset + j] = rowData[byteIdx++]; @@ -225,14 +225,14 @@ bool ImageLoaderPNG::ReadData() { m_AlphaChannelPrecision = bitDepth; m_AlphaData = new unsigned char[numPixels]; - for(int i = 0; i < m_Height; i++) { + for(uint32 i = 0; i < m_Height; i++) { png_read_row(png_ptr, rowData, NULL); unsigned int rowOffset = i * m_Width; unsigned int byteIdx = 0; - for(int j = 0; j < m_Width; j++) { + for(uint32 j = 0; j < m_Width; j++) { m_RedData[rowOffset + j] = rowData[byteIdx++]; m_AlphaData[rowOffset + j] = rowData[byteIdx++]; } diff --git a/IO/src/ImageLoaderPNG.h b/IO/src/ImageLoaderPNG.h index c1532a6..6fc63f0 100644 --- a/IO/src/ImageLoaderPNG.h +++ b/IO/src/ImageLoaderPNG.h @@ -54,7 +54,7 @@ class ImageLoaderPNG : public ImageLoader { virtual bool ReadData(); private: - unsigned int m_StreamPosition; + uint64 m_StreamPosition; friend class PNGStreamReader; }; diff --git a/IO/src/ImageWriterPNG.cpp b/IO/src/ImageWriterPNG.cpp index 0fbed87..c61fa57 100644 --- a/IO/src/ImageWriterPNG.cpp +++ b/IO/src/ImageWriterPNG.cpp @@ -125,13 +125,13 @@ bool ImageWriterPNG::WriteImage() { /* Initialize rows of PNG. */ row_pointers = (png_byte **)png_malloc (png_ptr, m_Height * sizeof (png_byte *)); - for (int y = 0; y < m_Height; ++y) { + for (uint32 y = 0; y < m_Height; ++y) { png_byte *row = (png_byte *)png_malloc (png_ptr, sizeof (uint8) * m_Width * pixel_size); row_pointers[y] = row; - for (int x = 0; x < m_Width; ++x) { - for(int ch = 0; ch < 4; ch++) { + for (uint32 x = 0; x < m_Width; ++x) { + for(uint32 ch = 0; ch < 4; ch++) { *row++ = GetChannelForPixel(x, y, ch); } } @@ -141,7 +141,7 @@ bool ImageWriterPNG::WriteImage() { png_set_rows (png_ptr, info_ptr, row_pointers); png_write_png (png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); - for (int y = 0; y < m_Height; y++) { + for (uint32 y = 0; y < m_Height; y++) { png_free (png_ptr, row_pointers[y]); } png_free (png_ptr, row_pointers); diff --git a/IO/src/ImageWriterPNG.h b/IO/src/ImageWriterPNG.h index 7899817..e9bfb85 100644 --- a/IO/src/ImageWriterPNG.h +++ b/IO/src/ImageWriterPNG.h @@ -55,7 +55,7 @@ class ImageWriterPNG : public ImageWriter { virtual bool WriteImage(); private: - uint32 m_StreamPosition; + uint64 m_StreamPosition; uint32 m_TotalBytesWritten; friend class PNGStreamWriter; }; diff --git a/Windows b/Windows new file mode 160000 index 0000000..1fad7ec --- /dev/null +++ b/Windows @@ -0,0 +1 @@ +Subproject commit 1fad7ec01fd8b3cc88d5346231b5c6a92cfd0325