diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2289371 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +# User files +*.suo +*.user +*.sln.docstates + +# Build folders + +workspace/ + +# Visual Studio Intermediate files +*.opendb +*.db + +# Temporary +*.tmp \ No newline at end of file diff --git a/Visual Studio 2010.bat b/Visual Studio 2010.bat new file mode 100644 index 0000000..8d90594 --- /dev/null +++ b/Visual Studio 2010.bat @@ -0,0 +1,3 @@ +@echo off +start /B /W premake/win/premake5 --file=ddspp.lua vs2010 +pause \ No newline at end of file diff --git a/ddspp.h b/ddspp.h index 72e72a0..fd98fc1 100644 --- a/ddspp.h +++ b/ddspp.h @@ -362,8 +362,8 @@ namespace ddspp unsigned int rowPitch; // Row pitch for mip 0 unsigned int depthPitch; // Size of mip 0 unsigned int bitsPerPixelOrBlock; // If compressed bits per block, else bits per pixel - unsigned int blockWidth; - unsigned int blockHeight; + unsigned int blockWidth; // Width of block in pixels (1 if uncompressed) + unsigned int blockHeight;// Height of block in pixels (1 if uncompressed) bool compressed; bool srgb; unsigned int headerSize; // Actual size of header, use this to get to image data @@ -599,13 +599,27 @@ namespace ddspp return; } + inline ddspp_constexpr unsigned int get_row_pitch(unsigned int width, unsigned int bitsPerPixelOrBlock, unsigned int blockWidth, unsigned int mip) + { + // Shift width by mipmap index, round to next block size and round to next byte (for the rare less than 1 byte per pixel formats) + // E.g. width = 119, mip = 3, BC1 compression + // ((((119 >> 2) + 4 - 1) / 4) * 64) / 8 = 64 bytes + return ((((width >> mip) + blockWidth - 1) / blockWidth) * bitsPerPixelOrBlock + 7) / 8; + } + + // Returns number of bytes for each row of a given mip. Valid range is [0, desc.numMips) + inline ddspp_constexpr unsigned int get_row_pitch(const Descriptor& desc, unsigned int mip) + { + return get_row_pitch(desc.width, desc.bitsPerPixelOrBlock, desc.blockWidth, mip); + } + inline Result decode_header(unsigned char* sourceData, Descriptor& desc) { unsigned int magic = *reinterpret_cast(sourceData); // First 4 bytes are the magic DDS number if (magic != DDS_MAGIC) { - return Result::Error; + return ddspp::Error; } const Header header = *reinterpret_cast(sourceData + sizeof(DDS_MAGIC)); @@ -859,7 +873,7 @@ namespace ddspp { if((header.caps2 & DDS_HEADER_CAPS2_CUBEMAP_ALLFACES) != DDS_HEADER_CAPS2_CUBEMAP_ALLFACES) { - return Result::Error; + return ddspp::Error; } desc.type = Cubemap; @@ -909,11 +923,11 @@ namespace ddspp desc.bitsPerPixelOrBlock = get_bits_per_pixel_or_block(desc.format); get_block_size(desc.format, desc.blockWidth, desc.blockHeight); - desc.rowPitch = desc.width * desc.bitsPerPixelOrBlock / (8 * desc.blockWidth); + desc.rowPitch = get_row_pitch(desc.width, desc.bitsPerPixelOrBlock, desc.blockWidth, 0); desc.depthPitch = desc.rowPitch * desc.height / desc.blockHeight; desc.headerSize = sizeof(DDS_MAGIC) + sizeof(Header) + (dxt10Extension ? sizeof(HeaderDXT10) : 0); - return Result::Success; + return ddspp::Success; } inline void encode_header(const DXGIFormat format, const unsigned int width, const unsigned int height, const unsigned int depth, diff --git a/ddspp.lua b/ddspp.lua new file mode 100644 index 0000000..f78de2f --- /dev/null +++ b/ddspp.lua @@ -0,0 +1,95 @@ +Workspace = "workspace/".._ACTION + +-- Compilers + +-- x86/x64 +PlatformMSVC64 = "MSVC 64" +PlatformOSX64 = "OSX 64" +PlatformLinux64_GCC = "Linux64_GCC" +PlatformLinux64_Clang = "Linux64_Clang" + +isMacBuild = _ACTION == "xcode4" +isLinuxBuild = _ACTION == "gmake2" +isWindowsBuild = not isMacBuild and not isLinuxBuild +supportsARMBuild = _ACTION == "vs2017" or _ACTION == "vs2019" or _ACTION == "vs2022" + +workspace("dds++") + configurations { "Debug", "Release" } + location (Workspace) + + flags + { + "multiprocessorcompile", -- /MP + } + + includedirs + { + includeDir, + } + + cppdialect("c++11") + + if(isMacBuild) then + + platforms { PlatformOSX64 } + toolset("clang") + architecture("x64") + buildoptions { "-std=c++11 -Wno-unused-variable" } + linkoptions { "-stdlib=libc++" } + + elseif(isLinuxBuild) then + + platforms { PlatformLinux64_GCC, PlatformLinux64_Clang } + architecture("x64") + buildoptions { "-std=c++11 -Wno-unused-variable" } + + filter { "platforms:"..PlatformLinux64_GCC } + toolset("gcc") + + filter { "platforms:"..PlatformLinux64_Clang } + toolset("clang") + + else + + platforms + { + PlatformMSVC64 + } + + local llvmToolset; + + if (_ACTION == "vs2015") then + llvmToolset = "msc-llvm-vs2014"; + elseif(_ACTION == "vs2017") then + llvmToolset = "msc-llvm"; + else + llvmToolset = "msc-clangcl"; + end + + startproject(UnitTestProject) + + filter { "platforms:"..PlatformMSVC64 } + toolset("msc") + architecture("x64") + + filter{} + end + + filter { "configurations:Debug" } + defines { "DEBUG" } + symbols ("full") + optimize("debug") + + filter { "configurations:Release" } + defines { "NDEBUG" } + inlining("auto") + optimize("speed") + +project ('dds++') + kind("consoleapp") + + files + { + "*.cpp", + "*.h", + } \ No newline at end of file diff --git a/ddspp.sln b/ddspp.sln deleted file mode 100644 index c734a98..0000000 --- a/ddspp.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ddspp", "ddspp.vcxproj", "{A91AD509-788F-491F-AF7D-1471530B1AC6}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {A91AD509-788F-491F-AF7D-1471530B1AC6}.Debug|Win32.ActiveCfg = Debug|Win32 - {A91AD509-788F-491F-AF7D-1471530B1AC6}.Debug|Win32.Build.0 = Debug|Win32 - {A91AD509-788F-491F-AF7D-1471530B1AC6}.Release|Win32.ActiveCfg = Release|Win32 - {A91AD509-788F-491F-AF7D-1471530B1AC6}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/ddspp.vcxproj b/ddspp.vcxproj deleted file mode 100644 index 1972714..0000000 --- a/ddspp.vcxproj +++ /dev/null @@ -1,71 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {A91AD509-788F-491F-AF7D-1471530B1AC6} - ddspp - - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - Level3 - Disabled - - - true - - - - - Level3 - MaxSpeed - true - true - - - true - true - true - - - - - - - - - - - - \ No newline at end of file diff --git a/ddspp.vcxproj.filters b/ddspp.vcxproj.filters deleted file mode 100644 index 8bf6e54..0000000 --- a/ddspp.vcxproj.filters +++ /dev/null @@ -1,27 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - - - Source Files - - - \ No newline at end of file diff --git a/main.cpp b/main.cpp index 699a94f..a41d1ee 100644 --- a/main.cpp +++ b/main.cpp @@ -19,11 +19,17 @@ int main() fread(data, sizeof(*data), ddsSize, fh); ddspp::Descriptor desc; - unsigned char* ddsData = ddspp::decode_header(data, desc); + ddspp::Result ddsResult = ddspp::decode_header(data, desc); - ddspp::Header h; + ddspp::Header header; ddspp::HeaderDXT10 h10; - ddspp::encode_header(desc.format, desc.width, desc.height, desc.depth, desc.type, desc.numMips, desc.arraySize, h, h10); + ddspp::encode_header(desc.format, desc.width, desc.height, desc.depth, desc.type, desc.numMips, desc.arraySize, header, h10); + + unsigned int rowPitch512 = ddspp::get_row_pitch(512, 64, 4, 0); + + unsigned int rowPitch = ddspp::get_row_pitch(29, 8, 1, 0); + + unsigned int rowPitchDesc = ddspp::get_row_pitch(desc, 0); unsigned int offset = ddspp::get_offset(desc, 4, 0); diff --git a/premake/linux/premake5 b/premake/linux/premake5 new file mode 100644 index 0000000..d0ad141 Binary files /dev/null and b/premake/linux/premake5 differ diff --git a/premake/osx/premake5 b/premake/osx/premake5 new file mode 100644 index 0000000..58fce3f Binary files /dev/null and b/premake/osx/premake5 differ diff --git a/premake/win/premake5.exe b/premake/win/premake5.exe new file mode 100644 index 0000000..1a637aa Binary files /dev/null and b/premake/win/premake5.exe differ