diff --git a/.gitignore b/.gitignore index 4100db6..36146ac 100755 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ Debug/ ipch/ *.sdf .vs/ +.idea/ *Debug/ *Release/ *debug*/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a6392b..8ff64bf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,18 +12,42 @@ # See the License for the specific language governing permissions and # limitations under the License. -cmake_minimum_required(VERSION 2.8.9) -project(EtcTest) - -set (CMAKE_CXX_STANDARD 11) -IF (APPLE) - set (CMAKE_CXX_FLAGS "-I/usr/include/i386-linux-gnu/c++/4.8 -I/usr/include/c++/4.8 -std=c++11 -g3 -Wall -O3") -ELSE () - IF (WIN32) - set (CMAKE_CXX_FLAGS "-I/usr/include/i386-linux-gnu/c++/4.8 -I/usr/include/c++/4.8 -W4 /EHsc") - ELSE() - set (CMAKE_CXX_FLAGS "-I/usr/include/i386-linux-gnu/c++/4.8 -I/usr/include/c++/4.8 -std=c++11 -pthread -g3 -Wall -O2") - ENDIF() -ENDIF () -ADD_SUBDIRECTORY(EtcLib) -ADD_SUBDIRECTORY(EtcTool) +cmake_minimum_required(VERSION 3.1) + +if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) + message(FATAL_ERROR "Please create a separate build directory and call cmake from there.") +endif() + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build. Supported options are: Debug, Release" FORCE) + message("CMAKE_BUILD_TYPE was not specified. Defaulting to ${CMAKE_BUILD_TYPE}") +endif() + +project(Etc2Comp) + +set(CMAKE_CXX_STANDARD 11) +set(CXX_STANDARD_REQUIRED ON) + +if(CMAKE_COMPILER_IS_GNUCC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -Wall") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g3") + + if(APPLE) + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2") + else() + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") + endif() + + if(MINGW) + # Including c and c++ runtime libs in the exe to reduce clutter. + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") + # Strip release executable to make it smaller. + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s") + endif() + +elseif(MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -W4 /EHsc") +endif() + +add_subdirectory(EtcLib) +add_subdirectory(EtcTool) diff --git a/EtcLib/CMakeLists.txt b/EtcLib/CMakeLists.txt index b584b88..12073e9 100644 --- a/EtcLib/CMakeLists.txt +++ b/EtcLib/CMakeLists.txt @@ -21,4 +21,4 @@ file(GLOB SOURCES ${PROJECT_SOURCE_DIR}/EtcCodec/*.h ${PROJECT_SOURCE_DIR}/Etc/*.cpp ${PROJECT_SOURCE_DIR}/EtcCodec/*.cpp) -ADD_LIBRARY(EtcLib ${SOURCES}) +add_library(EtcLib ${SOURCES}) diff --git a/EtcLib/Etc/Etc.cpp b/EtcLib/Etc/Etc.cpp index 0fe4961..89b0448 100644 --- a/EtcLib/Etc/Etc.cpp +++ b/EtcLib/Etc/Etc.cpp @@ -70,12 +70,12 @@ namespace Etc auto mipWidth = a_uiSourceWidth; auto mipHeight = a_uiSourceHeight; int totalEncodingTime = 0; - for(unsigned int mip = 0; mip < a_uiMaxMipmaps && mipWidth >= 1 && mipHeight >= 1; mip++) + for (unsigned int mip = 0; mip < a_uiMaxMipmaps; mip++) { float* pImageData = nullptr; float* pMipImage = nullptr; - if(mip == 0) + if (mip == 0) { pImageData = a_pafSourceRGBA; } @@ -88,23 +88,23 @@ namespace Etc } } - if ( pImageData ) + if (pImageData) { Image image(pImageData, mipWidth, mipHeight, a_eErrMetric); - image.m_bVerboseOutput = a_bVerboseOutput; - image.Encode(a_format, a_eErrMetric, a_fEffort, a_uiJobs, a_uiMaxJobs); + image.m_bVerboseOutput = a_bVerboseOutput; + image.Encode(a_format, a_eErrMetric, a_fEffort, a_uiJobs, a_uiMaxJobs); - a_pMipmapImages[mip].paucEncodingBits = std::shared_ptr(image.GetEncodingBits(), [](unsigned char *p) { delete[] p; }); - a_pMipmapImages[mip].uiEncodingBitsBytes = image.GetEncodingBitsBytes(); - a_pMipmapImages[mip].uiExtendedWidth = image.GetExtendedWidth(); - a_pMipmapImages[mip].uiExtendedHeight = image.GetExtendedHeight(); + a_pMipmapImages[mip].paucEncodingBits = std::shared_ptr(image.GetEncodingBits(), [](unsigned char *p) { delete[] p; }); + a_pMipmapImages[mip].uiEncodingBitsBytes = image.GetEncodingBitsBytes(); + a_pMipmapImages[mip].uiExtendedWidth = image.GetExtendedWidth(); + a_pMipmapImages[mip].uiExtendedHeight = image.GetExtendedHeight(); - totalEncodingTime += image.GetEncodingTimeMs(); + totalEncodingTime += image.GetEncodingTimeMs(); } - if(pMipImage) + if (pMipImage) { delete[] pMipImage; } @@ -114,8 +114,20 @@ namespace Etc break; } - mipWidth >>= 1; - mipHeight >>= 1; + if (mipWidth == 1 && mipHeight == 1) + { + break; + } + + if (mipWidth > 1) + { + mipWidth >>= 1; + } + + if (mipHeight > 1) + { + mipHeight >>= 1; + } } *a_piEncodingTime_ms = totalEncodingTime; diff --git a/EtcTool/CMakeLists.txt b/EtcTool/CMakeLists.txt index ef79cb0..f01c569 100644 --- a/EtcTool/CMakeLists.txt +++ b/EtcTool/CMakeLists.txt @@ -24,5 +24,9 @@ file(GLOB SOURCES ../third_party/lodepng/*.cpp) add_executable(EtcTool ${SOURCES}) -target_link_libraries (EtcTool EtcLib) +set(LIBRARIES EtcTool EtcLib) +if(WIN32) + set(LIBRARIES ${LIBRARIES} psapi) +endif() +target_link_libraries(${LIBRARIES}) diff --git a/EtcTool/EtcTool.cpp b/EtcTool/EtcTool.cpp index 1b52778..55c2215 100644 --- a/EtcTool/EtcTool.cpp +++ b/EtcTool/EtcTool.cpp @@ -51,10 +51,13 @@ using namespace Etc; #if ETC_WINDOWS const char *ETC_MKDIR_COMMAND = "mkdir"; +#ifndef __MINGW32__ int strcasecmp(const char *s1, const char *s2) { return _stricmp(s1, s2); } +#endif + #else const char *ETC_MKDIR_COMMAND = "mkdir -p"; #endif @@ -162,7 +165,7 @@ int main(int argc, const char * argv[]) // Calculate the maximum number of possible mipmaps { - int dim = (uiSourceWidth < uiSourceHeight)?uiSourceWidth:uiSourceHeight; + int dim = (uiSourceWidth > uiSourceHeight)?uiSourceWidth:uiSourceHeight; int maxMips = 0; while(dim >= 1) { @@ -441,7 +444,7 @@ bool Commands::ProcessCommandLineArguments(int a_iArgs, const char *a_apstrArgs[ if (iArg >= (a_iArgs)) { - printf("Error: missing comprison_image parameter for -compare\n"); + printf("Error: missing comparison_image parameter for -compare\n"); return true; } else @@ -651,7 +654,7 @@ bool Commands::ProcessCommandLineArguments(int a_iArgs, const char *a_apstrArgs[ if (pstrOutputFilename[c] == ETC_PATH_SLASH) { c++; - ptrOutputDir = new char[c]; + ptrOutputDir = new char[c + 1]; strncpy(ptrOutputDir, pstrOutputFilename, c); ptrOutputDir[c] = '\0'; CreateNewDir(ptrOutputDir); @@ -659,11 +662,6 @@ bool Commands::ProcessCommandLineArguments(int a_iArgs, const char *a_apstrArgs[ } } - if (ptrOutputDir == nullptr) - { - printf("couldnt find a place to put converted images\n"); - exit(1); - } } } else if (strcmp(a_apstrArgs[iArg], "-verbose") == 0 || @@ -802,7 +800,7 @@ void Commands::PrintUsageMessage(void) printf(" -normalizexyz normalize RGB to have a length of 1\n"); printf(" -verbose or -v shows status information during the encoding\n"); printf(" process\n"); - printf(" -mipmaps or -m sets the maximum number of mipaps to generate (default=1)\n"); + printf(" -mipmaps or -m sets the maximum number of mipmaps to generate (default=1)\n"); printf(" -mipwrap or -w sets the mipmap filter wrap mode (default=clamp)\n"); printf("\n"); @@ -816,7 +814,7 @@ void Commands::PrintUsageMessage(void) char strCommand[300]; #if ETC_WINDOWS - sprintf_s(strCommand, "if not exist %s %s %s", path, ETC_MKDIR_COMMAND, path); + sprintf(strCommand, "if not exist %s %s %s", path, ETC_MKDIR_COMMAND, path); #else sprintf(strCommand, "%s %s", ETC_MKDIR_COMMAND, path); #endif diff --git a/EtcTool/EtcTool.h b/EtcTool/EtcTool.h index 67cfccd..8006365 100644 --- a/EtcTool/EtcTool.h +++ b/EtcTool/EtcTool.h @@ -25,7 +25,10 @@ extern const char *ETC_MKDIR_COMMAND; extern const char *ETC_IF_DIR_NOT_EXIST_COMMAND; +#ifndef __MINGW32__ int strcasecmp(const char *s1, const char *s2); +#endif + #else const char ETC_PATH_SLASH = '/'; const char ETC_BAD_PATH_SLASH = '\\'; diff --git a/README.md b/README.md index 1c70ae9..64d87b2 100644 --- a/README.md +++ b/README.md @@ -42,14 +42,14 @@ To build the Etc2Comp binary: 1. Run `mkdir build_xcode` 1. Run `cd build_xcode` 1. Run `cmake -G Xcode ../` - 1. Open *Xcode* and import the `build_xcode/EtcTest.xcodeproj` file. + 1. Open *Xcode* and import the `build_xcode/Etc2Comp.xcodeproj` file. 1. Open the Product menu and choose Build For -> Running. 1. Once the build succeeds the binary located at `build_xcode/EtcTool/Debug/EtcTool` can be executed. Optional Xcode EtcTool ‘Run’ preferences -note: if the build_xcode/EtcTest.xcodeproj is manually deleted then some Xcode preferences +note: if the build_xcode/Etc2Comp.xcodeproj is manually deleted then some Xcode preferences will need to be set by hand after cmake is run (these prefs are retained across cmake updates if the .xcodeproj is not deleted/removed) @@ -68,7 +68,7 @@ Add this launch argument: ‘-argfile ../../EtcTool/args.txt’ For VS 2013 : `cmake -G "Visual Studio 12 2013 Win64" ../` For VS 2015 : `cmake -G "Visual Studio 14 2015 Win64" ../` NOTE: To see what supported Visual Studio outputs there are, run `cmake -G` -1. open the 'EtcTest' solution +1. open the 'Etc2Comp' solution 1. make the 'EtcTool' project the start up project 1. (optional) in the project properties, under 'Debugging ->command arguments' add the argfile textfile thats included in the EtcTool directory. @@ -120,23 +120,25 @@ Options: -normalizexyz normalize RGB to have a length of 1 -verbose or -v shows status information during the encoding process - -mipmaps or -m sets the maximum number of mipaps to generate (default=1) - -mipwrap or -w sets the mipmap filter wrap mode (default=clamp) + -mipmaps or -m sets the maximum number of mipmaps to generate (default=1) + -mipwrap or -w sets the mipmap filter wrap mode (default=clamp) * -analyze will run an analysis of the encoding and place it in folder "analysis_folder" (e.g. ../analysis/kodim05). within the analysis_folder, a folder will be created with a name of the current date/time (e.g. 20151204_153306). this date/time folder is used to compare encodings of the same texture over time. within the date/time folder is a text file with several encoding stats and a 2x png -image showing the encoding mode for each 4x4 block. +image showing the encoding mode for each 4x4 block. Analyze only works if generating +mipmaps is disabled. * -argfile allows additional command line arguments to be placed in a text file * -blockAtHV selects the 4x4 pixel subset of the source image at position (H,V). This is mainly used for debugging -* -compare compares the source image to the created encoded image. The encoding -will dictate what error analysis is used in the comparison. +* -compare compares the image given as the parameter to the newly created encoded image. +The encoding will dictate what error analysis is used in the comparison. Currently only +supports .ktx as the file format. * -effort uses an "amount" between 0 and 100 to determine how much additional effort to apply during the encoding.