From e3757fde740764ed5b1be40aefb5594e6aef4cfb Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Wed, 7 Nov 2012 15:20:25 -0500 Subject: [PATCH 01/21] Fix MSVC interpretation of our types. --- Core/include/TexCompTypes.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Core/include/TexCompTypes.h b/Core/include/TexCompTypes.h index 9e26fa9..81b61ec 100644 --- a/Core/include/TexCompTypes.h +++ b/Core/include/TexCompTypes.h @@ -12,16 +12,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 @@ -38,7 +39,6 @@ typedef uint16_t uint16; typedef uint32_t uint32; typedef uint64_t uint64; -typedef uintptr_t int32_ptr; typedef char CHAR; #endif // _MSC_VER From 9360e80a56ee0fd5536d3198f1611726a97a0e75 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Wed, 7 Nov 2012 15:21:02 -0500 Subject: [PATCH 02/21] Fix issues with stop watch on windows. --- Core/src/StopWatchWin32.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Core/src/StopWatchWin32.cpp b/Core/src/StopWatchWin32.cpp index bace45c..6f6025c 100755 --- a/Core/src/StopWatchWin32.cpp +++ b/Core/src/StopWatchWin32.cpp @@ -19,12 +19,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) @@ -108,7 +110,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. @@ -116,7 +118,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. From 53b8d4c9a947698ef3803ed15d7ba6a078f0fa62 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Wed, 7 Nov 2012 15:21:55 -0500 Subject: [PATCH 03/21] Fix compiler errors with functions not returning values. --- Core/src/Thread.cpp | 2 ++ Core/src/ThreadGroup.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Core/src/Thread.cpp b/Core/src/Thread.cpp index cb39052..24da37b 100644 --- a/Core/src/Thread.cpp +++ b/Core/src/Thread.cpp @@ -34,6 +34,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/src/ThreadGroup.cpp b/Core/src/ThreadGroup.cpp index d76a116..7c64454 100644 --- a/Core/src/ThreadGroup.cpp +++ b/Core/src/ThreadGroup.cpp @@ -243,6 +243,8 @@ bool ThreadGroup::CleanUpThreads() { // Reset active number of threads... m_ActiveThreads = 0; m_ExitFlag = false; + + return true; } void ThreadGroup::Join() { From b43373c0aaff23248c500c3fabc6dc3e2e2e60bb Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Wed, 7 Nov 2012 15:23:07 -0500 Subject: [PATCH 04/21] Fix some indentation and signedness mismatch --- BPTCEncoder/src/BC7Compressor.cpp | 10 ++-- IO/include/ImageFile.h | 2 +- IO/src/ImageLoader.cpp | 99 +++++++++++++++++-------------- 3 files changed, 60 insertions(+), 51 deletions(-) diff --git a/BPTCEncoder/src/BC7Compressor.cpp b/BPTCEncoder/src/BC7Compressor.cpp index 47798ae..bcfa8a4 100755 --- a/BPTCEncoder/src/BC7Compressor.cpp +++ b/BPTCEncoder/src/BC7Compressor.cpp @@ -1478,12 +1478,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); @@ -1521,12 +1520,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); diff --git a/IO/include/ImageFile.h b/IO/include/ImageFile.h index 94d3113..c224cc2 100644 --- a/IO/include/ImageFile.h +++ b/IO/include/ImageFile.h @@ -39,7 +39,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/ImageLoader.cpp b/IO/src/ImageLoader.cpp index d1050e5..23df16f 100644 --- a/IO/src/ImageLoader.cpp +++ b/IO/src/ImageLoader.cpp @@ -5,6 +5,12 @@ #include #include +/////////////////////////////////////////////////////////////////////////////// +// +// Static helper functions +// +/////////////////////////////////////////////////////////////////////////////// + template static inline T min(const T &a, const T &b) { return (a > b)? b : a; @@ -15,6 +21,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); } @@ -59,8 +70,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; @@ -77,7 +88,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; } @@ -113,59 +124,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; + } } } } From 96f223c509f54e97594a5114e78284a9388667d1 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Wed, 7 Nov 2012 15:26:33 -0500 Subject: [PATCH 05/21] Split filestream implementation into unix and windows versions. --- IO/CMakeLists.txt | 10 +- IO/src/{FileStream.cpp => FileStreamUnix.cpp} | 2 + IO/src/FileStreamWin32.cpp | 213 ++++++++++++++++++ 3 files changed, 224 insertions(+), 1 deletion(-) rename IO/src/{FileStream.cpp => FileStreamUnix.cpp} (99%) create mode 100755 IO/src/FileStreamWin32.cpp diff --git a/IO/CMakeLists.txt b/IO/CMakeLists.txt index 0d24cfb..4e28bee 100644 --- a/IO/CMakeLists.txt +++ b/IO/CMakeLists.txt @@ -2,7 +2,6 @@ SET( SOURCES "src/ImageWriter.cpp" "src/ImageLoader.cpp" - "src/FileStream.cpp" "src/ImageFile.cpp" ) @@ -13,6 +12,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/src/FileStream.cpp b/IO/src/FileStreamUnix.cpp similarity index 99% rename from IO/src/FileStream.cpp rename to IO/src/FileStreamUnix.cpp index 085e6ab..5393edf 100644 --- a/IO/src/FileStream.cpp +++ b/IO/src/FileStreamUnix.cpp @@ -96,6 +96,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..05bb087 --- /dev/null +++ b/IO/src/FileStreamWin32.cpp @@ -0,0 +1,213 @@ +#include "FileStream.h" + +#include +#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; + + FILE *m_FilePtr; + +public: + FileStreamImpl(const CHAR *filename, EFileMode mode) + : m_ReferenceCount(1) + { + + const char *modeStr = "r"; + switch(mode) { + default: + case eFileMode_Read: + // Do nothing. + break; + + case eFileMode_ReadBinary: + modeStr = "rb"; + break; + + case eFileMode_Write: + modeStr = "w"; + break; + + case eFileMode_WriteBinary: + modeStr = "wb"; + break; + + case eFileMode_WriteAppend: + modeStr = "a"; + break; + + case eFileMode_WriteBinaryAppend: + modeStr = "ab"; + break; + } + + m_FilePtr = fopen(filename, modeStr); + } + + ~FileStreamImpl() { + fclose(m_FilePtr); + } + + void IncreaseReferenceCount() { m_ReferenceCount++; } + void DecreaseReferenceCount() { m_ReferenceCount--; } + + uint32 GetReferenceCount() { return m_ReferenceCount; } + + FILE *GetFilePtr() const { return m_FilePtr; } +}; + +FileStream::FileStream(const CHAR *filename, EFileMode mode) + : m_Impl(new FileStreamImpl(filename, mode)) + , m_Mode(mode) +{ + strncpy(m_Filename, filename, kMaxFilenameSz); + m_Filename[kMaxFilenameSz - 1] = '\0'; +} + +FileStream::FileStream(const FileStream &other) + : m_Impl(other.m_Impl) + , m_Mode(other.m_Mode) +{ + m_Impl->IncreaseReferenceCount(); + strncpy(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(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 + ) { + fprintf(stderr, "Cannot read from file '%s': File opened for reading.", m_Filename); + return -2; + } + + FILE *fp = m_Impl->GetFilePtr(); + if(NULL == fp) + return -1; + + uint32 amtRead = fread(buf, 1, bufSz, fp); + if(amtRead != bufSz && !feof(fp)) { + fprintf(stderr, "Error reading from file '%s'.", m_Filename); + return -1; + } + + return amtRead; +} + +int32 FileStream::Write(const uint8 *buf, uint32 bufSz) { + if( + m_Mode == eFileMode_Read || + m_Mode == eFileMode_ReadBinary + ) { + fprintf(stderr, "Cannot write to file '%s': File opened for writing.", m_Filename); + return -2; + } + + FILE *fp = m_Impl->GetFilePtr(); + if(NULL == fp) + return -1; + + uint32 amtWritten = fwrite(buf, 1, bufSz, fp); + if(amtWritten != bufSz) { + fprintf(stderr, "Error writing to file '%s'.", m_Filename); + return -1; + } + + return amtWritten; +} + +int64 FileStream::Tell() { + FILE *fp = m_Impl->GetFilePtr(); + if(NULL == fp) { + return -1; + } + + long int ret = ftell(fp); + if(-1L == ret) { + perror("Error opening file"); + return -1; + } + + return ret; +} + +bool FileStream::Seek(uint32 offset, ESeekPosition pos) { + + // We cannot seek in append mode. + if(m_Mode == eFileMode_WriteAppend || m_Mode == eFileMode_WriteBinaryAppend) + return false; + + FILE *fp = m_Impl->GetFilePtr(); + if(NULL == fp) return false; + + int origin = SEEK_SET; + switch(pos) { + default: + case eSeekPosition_Beginning: + // Do nothing + break; + + case eSeekPosition_Current: + origin = SEEK_CUR; + break; + + case eSeekPosition_End: + origin = SEEK_END; + break; + } + + if(fseek(fp, offset, origin)) + return false; + + return true; +} + +void FileStream::Flush() { + FILE *fp = m_Impl->GetFilePtr(); + if(NULL != fp) { + fflush(fp); + } +} From 113749c82f4c65321ce0b20266a88c1eedc8224e Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Wed, 7 Nov 2012 16:38:34 -0500 Subject: [PATCH 06/21] Make the windows based filestream actually use the MSDN file IO functions --- IO/src/FileStreamWin32.cpp | 140 ++++++++++++++++++++++++------------- 1 file changed, 90 insertions(+), 50 deletions(-) diff --git a/IO/src/FileStreamWin32.cpp b/IO/src/FileStreamWin32.cpp index 05bb087..176b519 100755 --- a/IO/src/FileStreamWin32.cpp +++ b/IO/src/FileStreamWin32.cpp @@ -1,8 +1,7 @@ #include "FileStream.h" +#include #include -#include -#include #include class FileStreamImpl { @@ -13,46 +12,39 @@ private: // the object gets destroyed. uint32 m_ReferenceCount; - FILE *m_FilePtr; + HANDLE m_Handle; public: FileStreamImpl(const CHAR *filename, EFileMode mode) : m_ReferenceCount(1) { - const char *modeStr = "r"; + DWORD dwDesiredAccess = GENERIC_READ; + DWORD dwShareMode = 0; switch(mode) { default: + case eFileMode_ReadBinary: case eFileMode_Read: // Do nothing. break; - case eFileMode_ReadBinary: - modeStr = "rb"; - break; - case eFileMode_Write: - modeStr = "w"; - break; - case eFileMode_WriteBinary: - modeStr = "wb"; + dwDesiredAccess = GENERIC_WRITE; break; case eFileMode_WriteAppend: - modeStr = "a"; - break; - case eFileMode_WriteBinaryAppend: - modeStr = "ab"; + dwDesiredAccess = FILE_APPEND_DATA; break; } - m_FilePtr = fopen(filename, modeStr); + m_Handle = CreateFile(filename, dwDesiredAccess, dwShareMode, NULL, 0, FILE_ATTRIBUTE_NORMAL, NULL); + assert(m_Handle != INVALID_HANDLE_VALUE); } ~FileStreamImpl() { - fclose(m_FilePtr); + CloseHandle(m_Handle); } void IncreaseReferenceCount() { m_ReferenceCount++; } @@ -60,15 +52,15 @@ public: uint32 GetReferenceCount() { return m_ReferenceCount; } - FILE *GetFilePtr() const { return m_FilePtr; } + HANDLE GetFileHandle() const { return m_Handle; } }; FileStream::FileStream(const CHAR *filename, EFileMode mode) : m_Impl(new FileStreamImpl(filename, mode)) , m_Mode(mode) { - strncpy(m_Filename, filename, kMaxFilenameSz); - m_Filename[kMaxFilenameSz - 1] = '\0'; + strncpy_s(m_Filename, filename, kMaxFilenameSz); + m_Filename[kMaxFilenameSz - 1] = CHAR('\0'); } FileStream::FileStream(const FileStream &other) @@ -76,7 +68,7 @@ FileStream::FileStream(const FileStream &other) , m_Mode(other.m_Mode) { m_Impl->IncreaseReferenceCount(); - strncpy(m_Filename, other.m_Filename, kMaxFilenameSz); + strncpy_s(m_Filename, other.m_Filename, kMaxFilenameSz); } FileStream &FileStream::operator=(const FileStream &other) { @@ -95,7 +87,7 @@ FileStream &FileStream::operator=(const FileStream &other) { m_Impl->IncreaseReferenceCount(); m_Mode = other.m_Mode; - strncpy(m_Filename, other.m_Filename, kMaxFilenameSz); + strncpy_s(m_Filename, other.m_Filename, kMaxFilenameSz); return *this; } @@ -120,21 +112,42 @@ int32 FileStream::Read(uint8 *buf, uint32 bufSz) { m_Mode == eFileMode_WriteAppend || m_Mode == eFileMode_WriteBinaryAppend ) { - fprintf(stderr, "Cannot read from file '%s': File opened for reading.", m_Filename); + CHAR errStr[256]; + _sntprintf_s(errStr, 256, "Cannot read from file '%s': File opened for reading.", m_Filename); + OutputDebugString(errStr); return -2; } - FILE *fp = m_Impl->GetFilePtr(); - if(NULL == fp) + HANDLE fp = m_Impl->GetFileHandle(); + if(INVALID_HANDLE_VALUE == fp) return -1; - uint32 amtRead = fread(buf, 1, bufSz, fp); - if(amtRead != bufSz && !feof(fp)) { - fprintf(stderr, "Error reading from file '%s'.", m_Filename); + 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; } - return amtRead; + 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) { @@ -142,17 +155,42 @@ int32 FileStream::Write(const uint8 *buf, uint32 bufSz) { m_Mode == eFileMode_Read || m_Mode == eFileMode_ReadBinary ) { - fprintf(stderr, "Cannot write to file '%s': File opened for writing.", m_Filename); + CHAR errStr[256]; + _sntprintf_s(errStr, 256, "Cannot write to file '%s': File opened for writing.", m_Filename); + OutputDebugString(errStr); return -2; } - FILE *fp = m_Impl->GetFilePtr(); + HANDLE fp = m_Impl->GetFileHandle(); if(NULL == fp) return -1; - uint32 amtWritten = fwrite(buf, 1, bufSz, fp); - if(amtWritten != bufSz) { - fprintf(stderr, "Error writing to file '%s'.", m_Filename); + 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; } @@ -160,18 +198,20 @@ int32 FileStream::Write(const uint8 *buf, uint32 bufSz) { } int64 FileStream::Tell() { - FILE *fp = m_Impl->GetFilePtr(); + HANDLE fp = m_Impl->GetFileHandle(); if(NULL == fp) { return -1; } - long int ret = ftell(fp); - if(-1L == ret) { - perror("Error opening file"); - 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 ret; + return pos; } bool FileStream::Seek(uint32 offset, ESeekPosition pos) { @@ -180,10 +220,10 @@ bool FileStream::Seek(uint32 offset, ESeekPosition pos) { if(m_Mode == eFileMode_WriteAppend || m_Mode == eFileMode_WriteBinaryAppend) return false; - FILE *fp = m_Impl->GetFilePtr(); + HANDLE fp = m_Impl->GetFileHandle(); if(NULL == fp) return false; - int origin = SEEK_SET; + DWORD origin = FILE_BEGIN; switch(pos) { default: case eSeekPosition_Beginning: @@ -191,23 +231,23 @@ bool FileStream::Seek(uint32 offset, ESeekPosition pos) { break; case eSeekPosition_Current: - origin = SEEK_CUR; + origin = FILE_CURRENT; break; case eSeekPosition_End: - origin = SEEK_END; + origin = FILE_END; break; } - if(fseek(fp, offset, origin)) + if(SetFilePointer(fp, offset, NULL, origin) == INVALID_SET_FILE_POINTER) return false; return true; } void FileStream::Flush() { - FILE *fp = m_Impl->GetFilePtr(); - if(NULL != fp) { - fflush(fp); - } + HANDLE fp = m_Impl->GetFileHandle(); + if(NULL == fp) return; + + FlushFileBuffers(fp); } From 562d9e905d5efcd492f439668007cde8976f3a77 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Wed, 7 Nov 2012 16:51:44 -0500 Subject: [PATCH 07/21] Make sure to return a value for the = operator... --- Core/src/StopWatchWin32.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/src/StopWatchWin32.cpp b/Core/src/StopWatchWin32.cpp index 6f6025c..c51965b 100755 --- a/Core/src/StopWatchWin32.cpp +++ b/Core/src/StopWatchWin32.cpp @@ -50,6 +50,7 @@ StopWatch &StopWatch::operator=(const StopWatch &other) { } impl = new StopWatchImpl(); memcpy(impl, other.impl, sizeof(StopWatchImpl)); + return *this; } StopWatch::~StopWatch() { From 05e6ca0bc90ea9c945c218981386b36742e9eaec Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Wed, 7 Nov 2012 16:52:06 -0500 Subject: [PATCH 08/21] Fix windows issues with blockstats... --- Core/include/BlockStats.h | 2 +- Core/src/BlockStats.cpp | 33 +++++++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/Core/include/BlockStats.h b/Core/include/BlockStats.h index 7cea424..19a4ddd 100644 --- a/Core/include/BlockStats.h +++ b/Core/include/BlockStats.h @@ -14,7 +14,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 { diff --git a/Core/src/BlockStats.cpp b/Core/src/BlockStats.cpp index 11a6f09..b9f2fdb 100644 --- a/Core/src/BlockStats.cpp +++ b/Core/src/BlockStats.cpp @@ -22,14 +22,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) { @@ -38,16 +46,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: @@ -106,7 +123,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(); @@ -115,12 +132,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); @@ -136,7 +157,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) From 680625d03ef8d2ba2c34ce5257c2de422cfc788f Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Wed, 7 Nov 2012 17:10:26 -0500 Subject: [PATCH 09/21] Fix a bunch of compiler warnings. --- BPTCEncoder/src/RGBAEndpoints.cpp | 4 ++-- Core/src/CompressedImage.cpp | 3 ++- Core/src/Image.cpp | 2 +- Core/src/TexComp.cpp | 2 +- Core/src/WorkerQueue.cpp | 4 ++-- Core/src/WorkerQueue.h | 2 +- IO/src/ImageFile.cpp | 27 ++++++++++++++++++--------- IO/src/ImageLoaderPNG.cpp | 16 ++++++++-------- IO/src/ImageLoaderPNG.h | 2 +- IO/src/ImageWriterPNG.cpp | 8 ++++---- IO/src/ImageWriterPNG.h | 2 +- 11 files changed, 41 insertions(+), 31 deletions(-) diff --git a/BPTCEncoder/src/RGBAEndpoints.cpp b/BPTCEncoder/src/RGBAEndpoints.cpp index 6a02713..0483d7a 100755 --- a/BPTCEncoder/src/RGBAEndpoints.cpp +++ b/BPTCEncoder/src/RGBAEndpoints.cpp @@ -457,7 +457,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(); @@ -480,7 +480,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/Core/src/CompressedImage.cpp b/Core/src/CompressedImage.cpp index 3404aeb..9ab288a 100644 --- a/Core/src/CompressedImage.cpp +++ b/Core/src/CompressedImage.cpp @@ -5,6 +5,7 @@ #include #include +#include "TexCompTypes.h" #include "BC7Compressor.h" CompressedImage::CompressedImage() @@ -66,7 +67,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 66d516b..629188c 100644 --- a/Core/src/Image.cpp +++ b/Core/src/Image.cpp @@ -75,7 +75,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/TexComp.cpp b/Core/src/TexComp.cpp index a06951e..563ea0a 100644 --- a/Core/src/TexComp.cpp +++ b/Core/src/TexComp.cpp @@ -225,7 +225,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/WorkerQueue.cpp b/Core/src/WorkerQueue.cpp index f8a3c23..113fa09 100644 --- a/Core/src/WorkerQueue.cpp +++ b/Core/src/WorkerQueue.cpp @@ -148,7 +148,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++; @@ -168,7 +168,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]; diff --git a/Core/src/WorkerQueue.h b/Core/src/WorkerQueue.h index 3a13546..42a885c 100644 --- a/Core/src/WorkerQueue.h +++ b/Core/src/WorkerQueue.h @@ -10,7 +10,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/src/ImageFile.cpp b/IO/src/ImageFile.cpp index 6451bfc..bbb0576 100644 --- a/IO/src/ImageFile.cpp +++ b/IO/src/ImageFile.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "ImageWriter.h" #include "ImageLoader.h" @@ -32,10 +33,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 ////////////////////////////////////////////////////////////////////////////////////////// // @@ -113,7 +114,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; @@ -154,13 +155,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--] != '.'); @@ -199,8 +200,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/ImageLoaderPNG.cpp b/IO/src/ImageLoaderPNG.cpp index bfefedd..87bc0f2 100644 --- a/IO/src/ImageLoaderPNG.cpp +++ b/IO/src/ImageLoaderPNG.cpp @@ -107,14 +107,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++]; } @@ -131,14 +131,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++]; @@ -158,14 +158,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++]; @@ -182,14 +182,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 209f17e..ff361ce 100644 --- a/IO/src/ImageLoaderPNG.h +++ b/IO/src/ImageLoaderPNG.h @@ -11,7 +11,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 3b97442..49fb3d2 100644 --- a/IO/src/ImageWriterPNG.cpp +++ b/IO/src/ImageWriterPNG.cpp @@ -82,13 +82,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); } } @@ -98,7 +98,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 c5dda26..948f501 100644 --- a/IO/src/ImageWriterPNG.h +++ b/IO/src/ImageWriterPNG.h @@ -12,7 +12,7 @@ class ImageWriterPNG : public ImageWriter { virtual bool WriteImage(); private: - uint32 m_StreamPosition; + uint64 m_StreamPosition; uint32 m_TotalBytesWritten; friend class PNGStreamWriter; }; From 876182122030ecdd7ad3b622d8bb31fa88cdf9c9 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Wed, 7 Nov 2012 18:01:02 -0500 Subject: [PATCH 10/21] More compiler fixes. --- BPTCEncoder/src/BC7Compressor.cpp | 2 +- CLTool/src/clwin32.cpp | 182 +++++++++++++++++++++++++++++- Core/include/Thread.h | 9 +- Core/src/StopWatchWin32.cpp | 2 + Core/src/WorkerQueue.cpp | 6 +- 5 files changed, 194 insertions(+), 7 deletions(-) diff --git a/BPTCEncoder/src/BC7Compressor.cpp b/BPTCEncoder/src/BC7Compressor.cpp index bcfa8a4..ae9883a 100755 --- a/BPTCEncoder/src/BC7Compressor.cpp +++ b/BPTCEncoder/src/BC7Compressor.cpp @@ -2337,7 +2337,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/CLTool/src/clwin32.cpp b/CLTool/src/clwin32.cpp index 202de88..0fde80a 100644 --- a/CLTool/src/clwin32.cpp +++ b/CLTool/src/clwin32.cpp @@ -1,3 +1,183 @@ +#include +#include +#include +#include + +#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 main(int argc, char **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; +} \ No newline at end of file diff --git a/Core/include/Thread.h b/Core/include/Thread.h index b7435e1..b66ee63 100644 --- a/Core/include/Thread.h +++ b/Core/include/Thread.h @@ -3,6 +3,11 @@ #include "TexCompTypes.h" +//!HACK! Apparently MSVC has issues with Yield()...???? +#ifdef _MSC_VER +#undef Yield +#endif + //////////////////////////////////////////////////////////////////////////////// // // Base implementation @@ -68,9 +73,9 @@ class TCThread : public TCThreadBase { public: TCThread(TCCallable &); - - void Join(); + static void Yield(); + void Join(); }; //////////////////////////////////////////////////////////////////////////////// diff --git a/Core/src/StopWatchWin32.cpp b/Core/src/StopWatchWin32.cpp index c51965b..e711ff9 100755 --- a/Core/src/StopWatchWin32.cpp +++ b/Core/src/StopWatchWin32.cpp @@ -39,6 +39,8 @@ public: } }; +StopWatch::StopWatch() : impl(new StopWatchImpl) { } + StopWatch::StopWatch(const StopWatch &other) { impl = new StopWatchImpl(); memcpy(impl, other.impl, sizeof(StopWatchImpl)); diff --git a/Core/src/WorkerQueue.cpp b/Core/src/WorkerQueue.cpp index 113fa09..f41d13e 100644 --- a/Core/src/WorkerQueue.cpp +++ b/Core/src/WorkerQueue.cpp @@ -231,7 +231,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; @@ -240,7 +240,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; @@ -249,7 +249,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]; } From cb126c40ceb17845f4607324c34977d2864af26e Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Wed, 7 Nov 2012 18:22:12 -0500 Subject: [PATCH 11/21] Add the correct hooks to compile as a win32 console app. --- CLTool/src/clwin32.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CLTool/src/clwin32.cpp b/CLTool/src/clwin32.cpp index 0fde80a..40c2826 100644 --- a/CLTool/src/clwin32.cpp +++ b/CLTool/src/clwin32.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include "BlockStats.h" @@ -26,9 +27,9 @@ void ExtractBasename(const char *filename, char *buf, uint32 bufSz) { } } } - -int main(int argc, char **argv) { - + +int _tmain(int argc, _TCHAR* argv[]) +{ int fileArg = 1; if(fileArg == argc) { PrintUsage(); From 42c350878e56495056e74bdfb3e610b091c1667d Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Sat, 26 Jan 2013 14:11:37 -0500 Subject: [PATCH 12/21] Fix property variable. --- Core/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/CMakeLists.txt b/Core/CMakeLists.txt index 9ad6d03..a585901 100644 --- a/Core/CMakeLists.txt +++ b/Core/CMakeLists.txt @@ -70,7 +70,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" ) From 37d8cc797ce709bae7bc3919e9bd0f5fbde8344d Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Sat, 26 Jan 2013 14:12:19 -0500 Subject: [PATCH 13/21] Add in a small hack to add the boost library directory to the linker command line in order to be able to compile. --- CLTool/CMakeLists.txt | 6 ++++++ CMakeLists.txt | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/CLTool/CMakeLists.txt b/CLTool/CMakeLists.txt index 22278ff..223d39b 100644 --- a/CLTool/CMakeLists.txt +++ b/CLTool/CMakeLists.txt @@ -13,6 +13,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/CMakeLists.txt b/CMakeLists.txt index 6ae33ad..a3c64aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,28 @@ 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.... + SET(MSVC_ARCHITECTURE_STRING x64) + + 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) From f1e502c8f55ddd689de4f3bd4d31f77e93c0cf29 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Sat, 26 Jan 2013 18:03:48 -0500 Subject: [PATCH 14/21] Remove hack for adding a libpath flag in visual studio by requiring extra libraries from boost. --- CLTool/CMakeLists.txt | 6 +++--- Core/CMakeLists.txt | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CLTool/CMakeLists.txt b/CLTool/CMakeLists.txt index 223d39b..2d2145c 100644 --- a/CLTool/CMakeLists.txt +++ b/CLTool/CMakeLists.txt @@ -15,9 +15,9 @@ ADD_EXECUTABLE( # 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() +#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 ) diff --git a/Core/CMakeLists.txt b/Core/CMakeLists.txt index a585901..54f0bbe 100644 --- a/Core/CMakeLists.txt +++ b/Core/CMakeLists.txt @@ -39,7 +39,8 @@ INCLUDE_DIRECTORIES( ${TexC_SOURCE_DIR}/Core/include ) SET( THREAD_API ) SET( THREAD_APIS_AVAILABLE "None" ) -FIND_PACKAGE( Boost COMPONENTS thread system ) +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} ) From 6d85bc9467c166bf33228a71573a750f6826f6bd Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Sat, 26 Jan 2013 18:04:43 -0500 Subject: [PATCH 15/21] Determine what architecture the compiler is for msvc by how large our void pointers are. --- CMakeLists.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a3c64aa..e710cd9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,11 +16,14 @@ IF(MSVC) ENDIF() # !FIXME! Actually detect compiler architecture version.... - SET(MSVC_ARCHITECTURE_STRING x64) + 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) From f4629fa35a791c2a764cf13d05748b6d3836d22d Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Sun, 27 Jan 2013 10:33:41 -0500 Subject: [PATCH 16/21] Add boost libraries for windows. --- Core/CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Core/CMakeLists.txt b/Core/CMakeLists.txt index 54f0bbe..68681dd 100644 --- a/Core/CMakeLists.txt +++ b/Core/CMakeLists.txt @@ -39,6 +39,13 @@ INCLUDE_DIRECTORIES( ${TexC_SOURCE_DIR}/Core/include ) SET( THREAD_API ) SET( THREAD_APIS_AVAILABLE "None" ) +###### 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 ) @@ -50,6 +57,8 @@ IF( Boost_FOUND ) ENDIF() +###### Find PThreads.... + FIND_PACKAGE( Threads ) IF( CMAKE_USE_PTHREADS_INIT ) From 61a8d4e2c7b4bdc4a9a966c34f58ec1575593e83 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Sun, 27 Jan 2013 12:14:55 -0500 Subject: [PATCH 17/21] Add submodule to keep track of windows include files and libraries --- .gitmodules | 3 +++ Windows | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 Windows 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/Windows b/Windows new file mode 160000 index 0000000..e0834a7 --- /dev/null +++ b/Windows @@ -0,0 +1 @@ +Subproject commit e0834a7e7bd33a96c068f86b9dfa5b409eb00b41 From 7049dc3077fd6d1723b2cb708689428cbb2de6a3 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Sun, 27 Jan 2013 13:35:10 -0500 Subject: [PATCH 18/21] Update windows module to contain all necessary libs... --- Windows | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Windows b/Windows index e0834a7..1fad7ec 160000 --- a/Windows +++ b/Windows @@ -1 +1 @@ -Subproject commit e0834a7e7bd33a96c068f86b9dfa5b409eb00b41 +Subproject commit 1fad7ec01fd8b3cc88d5346231b5c6a92cfd0325 From 40a09476494cac4d9beb25c335d3d29db26bb196 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Sun, 27 Jan 2013 14:02:39 -0500 Subject: [PATCH 19/21] Fix small bug where we enter an infinite loop after we finish reading a file. --- IO/src/ImageFile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IO/src/ImageFile.cpp b/IO/src/ImageFile.cpp index bbb0576..bb9e852 100644 --- a/IO/src/ImageFile.cpp +++ b/IO/src/ImageFile.cpp @@ -204,7 +204,7 @@ unsigned char *ImageFile::ReadFileData(const CHAR *filename) { uint64 totalBytesLeft = fileSize; uint32 bytesToRead = uint32(std::min(totalBytesLeft, uint64(1 << 31))); int32 bytesRead; - while((bytesRead = fstr.Read(rawData, uint32(fileSize))) >= 0) { + while((bytesRead = fstr.Read(rawData, uint32(fileSize))) > 0) { totalBytesRead += bytesRead; totalBytesLeft -= bytesRead; } From 45e926536a5b835dd346ee13efa7004daec80b5d Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Sun, 27 Jan 2013 14:36:19 -0500 Subject: [PATCH 20/21] Move Thread.h out of the include directory, and update the BlockStatManager to compensate. --- Core/CMakeLists.txt | 2 +- Core/include/BlockStats.h | 22 +++++++++++++++-- Core/src/BlockStats.cpp | 44 ++++++++++++++++++++++++++++++++-- Core/{include => src}/Thread.h | 0 4 files changed, 63 insertions(+), 5 deletions(-) rename Core/{include => src}/Thread.h (100%) diff --git a/Core/CMakeLists.txt b/Core/CMakeLists.txt index 68681dd..61b0045 100644 --- a/Core/CMakeLists.txt +++ b/Core/CMakeLists.txt @@ -94,7 +94,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 19a4ddd..97c6d9b 100644 --- a/Core/include/BlockStats.h +++ b/Core/include/BlockStats.h @@ -3,7 +3,19 @@ #include "TexCompTypes.h" #include "ReferenceCounter.h" -#include "Thread.h" + +/////////////////////////////////////////////////////////////////////////////// +// +// Forward declarations +// +/////////////////////////////////////////////////////////////////////////////// +class TCMutex; + +/////////////////////////////////////////////////////////////////////////////// +// +// class BlockStat +// +/////////////////////////////////////////////////////////////////////////////// struct BlockStat { friend class BlockStatManager; @@ -36,6 +48,8 @@ class BlockStatManager { public: BlockStatManager(int nBlocks); + BlockStatManager(const BlockStatManager &); + BlockStatManager &operator=(const BlockStatManager &); ~BlockStatManager(); uint32 BeginBlock(); @@ -55,6 +69,7 @@ class BlockStatManager { private: BlockStatList(const BlockStat &stat); + BlockStatList(const BlockStatList &other); BlockStat m_Stat; BlockStatList *m_Tail; @@ -63,9 +78,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/src/BlockStats.cpp b/Core/src/BlockStats.cpp index b9f2fdb..f097a59 100644 --- a/Core/src/BlockStats.cpp +++ b/Core/src/BlockStats.cpp @@ -6,6 +6,7 @@ #include #include "FileStream.h" +#include "Thread.h" template static T max(const T &a, const T &b) { @@ -79,9 +80,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) { @@ -95,6 +123,12 @@ BlockStatManager::~BlockStatManager() { if(m_Counter.GetRefCount() == 0) { delete [] m_BlockStatList; } + + if(m_Mutex) + { + delete m_Mutex; + m_Mutex = 0; + } } uint32 BlockStatManager::BeginBlock() { @@ -104,7 +138,7 @@ uint32 BlockStatManager::BeginBlock() { return m_NextBlock-1; } - TCLock lock (m_Mutex); + TCLock lock (*m_Mutex); return m_NextBlock++; } @@ -115,7 +149,7 @@ void BlockStatManager::AddStat(uint32 blockIdx, const BlockStat &stat) { return; } - TCLock lock (m_Mutex); + TCLock lock (*m_Mutex); m_BlockStatList[blockIdx].AddStat(stat); } @@ -168,8 +202,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/include/Thread.h b/Core/src/Thread.h similarity index 100% rename from Core/include/Thread.h rename to Core/src/Thread.h From deac1e7fad4960640b313deff3b1b70ac23fe9b8 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Mon, 28 Jan 2013 11:44:14 -0500 Subject: [PATCH 21/21] Fix some compiler errors... --- Core/include/BlockStats.h | 2 +- Core/src/BlockStats.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/include/BlockStats.h b/Core/include/BlockStats.h index 97c6d9b..ed8ce2a 100644 --- a/Core/include/BlockStats.h +++ b/Core/include/BlockStats.h @@ -61,6 +61,7 @@ class BlockStatManager { class BlockStatList { public: BlockStatList(); + BlockStatList(const BlockStatList &other); ~BlockStatList(); void AddStat(const BlockStat &stat); @@ -69,7 +70,6 @@ class BlockStatManager { private: BlockStatList(const BlockStat &stat); - BlockStatList(const BlockStatList &other); BlockStat m_Stat; BlockStatList *m_Tail; diff --git a/Core/src/BlockStats.cpp b/Core/src/BlockStats.cpp index f097a59..5a18f5b 100644 --- a/Core/src/BlockStats.cpp +++ b/Core/src/BlockStats.cpp @@ -86,7 +86,7 @@ void BlockStatManager::Copy(const BlockStatManager &other) { // 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_BlockStatList = new BlockStatList(*other.m_BlockStatList); m_BlockStatListSz = other.m_BlockStatListSz; m_NextBlock = other.m_NextBlock;