Added HDR readers and writes and Evaluate function
This commit is contained in:
parent
b0d443f526
commit
04143d621c
@ -31,6 +31,8 @@
|
||||
#include <d3d11_1.h>
|
||||
#endif
|
||||
|
||||
#include <directxmath.h>
|
||||
|
||||
#include <ocidl.h>
|
||||
|
||||
#define DIRECTX_TEX_VERSION 140
|
||||
@ -209,6 +211,11 @@ namespace DirectX
|
||||
HRESULT __cdecl GetMetadataFromDDSFile( _In_z_ const wchar_t* szFile, _In_ DWORD flags,
|
||||
_Out_ TexMetadata& metadata );
|
||||
|
||||
HRESULT __cdecl GetMetadataFromHDRMemory( _In_reads_bytes_(size) const void* pSource, _In_ size_t size,
|
||||
_Out_ TexMetadata& metadata );
|
||||
HRESULT __cdecl GetMetadataFromHDRFile( _In_z_ const wchar_t* szFile,
|
||||
_Out_ TexMetadata& metadata );
|
||||
|
||||
HRESULT __cdecl GetMetadataFromTGAMemory( _In_reads_bytes_(size) const void* pSource, _In_ size_t size,
|
||||
_Out_ TexMetadata& metadata );
|
||||
HRESULT __cdecl GetMetadataFromTGAFile( _In_z_ const wchar_t* szFile,
|
||||
@ -304,6 +311,8 @@ namespace DirectX
|
||||
void *__cdecl GetBufferPointer() const { return m_buffer; }
|
||||
size_t __cdecl GetBufferSize() const { return m_size; }
|
||||
|
||||
HRESULT __cdecl Trim(size_t size);
|
||||
|
||||
private:
|
||||
void* m_buffer;
|
||||
size_t m_size;
|
||||
@ -326,6 +335,15 @@ namespace DirectX
|
||||
HRESULT __cdecl SaveToDDSFile( _In_ const Image& image, _In_ DWORD flags, _In_z_ const wchar_t* szFile );
|
||||
HRESULT __cdecl SaveToDDSFile( _In_reads_(nimages) const Image* images, _In_ size_t nimages, _In_ const TexMetadata& metadata, _In_ DWORD flags, _In_z_ const wchar_t* szFile );
|
||||
|
||||
// HDR operations
|
||||
HRESULT __cdecl LoadFromHDRMemory( _In_reads_bytes_(size) const void* pSource, _In_ size_t size,
|
||||
_Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image );
|
||||
HRESULT __cdecl LoadFromHDRFile( _In_z_ const wchar_t* szFile,
|
||||
_Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image );
|
||||
|
||||
HRESULT __cdecl SaveToHDRMemory( _In_ const Image& image, _Out_ Blob& blob );
|
||||
HRESULT __cdecl SaveToHDRFile( _In_ const Image& image, _In_z_ const wchar_t* szFile );
|
||||
|
||||
// TGA operations
|
||||
HRESULT __cdecl LoadFromTGAMemory( _In_reads_bytes_(size) const void* pSource, _In_ size_t size,
|
||||
_Out_opt_ TexMetadata* metadata, _Out_ ScratchImage& image );
|
||||
@ -590,6 +608,9 @@ namespace DirectX
|
||||
|
||||
HRESULT __cdecl ComputeMSE( _In_ const Image& image1, _In_ const Image& image2, _Out_ float& mse, _Out_writes_opt_(4) float* mseV, _In_ DWORD flags = 0 );
|
||||
|
||||
HRESULT __cdecl Evaluate( _In_ const Image& image,
|
||||
_In_ std::function<void __cdecl(_In_reads_(width) const XMVECTOR* pixels, size_t width, size_t y)> pixelFunc );
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// WIC utility code
|
||||
|
||||
|
979
DirectXTex/DirectXTexHDR.cpp
Normal file
979
DirectXTex/DirectXTexHDR.cpp
Normal file
@ -0,0 +1,979 @@
|
||||
//-------------------------------------------------------------------------------------
|
||||
// DirectXTexHDR.cpp
|
||||
//
|
||||
// DirectX Texture Library - Radiance HDR (RGBE) file format reader/writer
|
||||
//
|
||||
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
||||
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
||||
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
||||
// PARTICULAR PURPOSE.
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// http://go.microsoft.com/fwlink/?LinkId=248926
|
||||
//-------------------------------------------------------------------------------------
|
||||
|
||||
#include "directxtexp.h"
|
||||
|
||||
//
|
||||
// In theory HDR (RGBE) Radiance files can have any of the following data orientations
|
||||
//
|
||||
// +X width +Y height
|
||||
// +X width -Y height
|
||||
// -X width +Y height
|
||||
// -X width -Y height
|
||||
// +Y height +X width
|
||||
// -Y height +X width
|
||||
// +Y height -X width
|
||||
// -Y height -X width
|
||||
//
|
||||
// All HDR files we've encountered are always written as "-Y height +X width", so
|
||||
// we support only that one as that's what other Radiance parsing code does as well.
|
||||
//
|
||||
|
||||
//#define DISABLE_COMPRESS
|
||||
|
||||
using namespace DirectX;
|
||||
|
||||
namespace
|
||||
{
|
||||
const char g_Signature[] = "#?RADIANCE";
|
||||
const char g_Format[] = "FORMAT=";
|
||||
const char g_Exposure[] = "EXPOSURE=";
|
||||
|
||||
const char g_sRGBE[] = "32-bit_rle_rgbe";
|
||||
const char g_sXYZE[] = "32-bit_rle_xyze";
|
||||
|
||||
const char g_Header[] =
|
||||
"#?RADIANCE\n"\
|
||||
"FORMAT=32-bit_rle_rgbe\n"\
|
||||
"\n"\
|
||||
"-Y %u +X %u\n";
|
||||
|
||||
inline size_t FindEOL(const char* str, size_t maxlen)
|
||||
{
|
||||
size_t pos = 0;
|
||||
|
||||
while (pos < maxlen)
|
||||
{
|
||||
if (str[pos] == '\n')
|
||||
return pos;
|
||||
else if (str[pos] == '\0')
|
||||
return size_t(-1);
|
||||
++pos;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Decodes HDR header
|
||||
//-------------------------------------------------------------------------------------
|
||||
HRESULT DecodeHDRHeader(
|
||||
_In_reads_bytes_(size) const void* pSource,
|
||||
size_t size,
|
||||
_Out_ TexMetadata& metadata,
|
||||
size_t& offset,
|
||||
float& exposure)
|
||||
{
|
||||
if (!pSource)
|
||||
return E_INVALIDARG;
|
||||
|
||||
memset(&metadata, 0, sizeof(TexMetadata));
|
||||
|
||||
exposure = 1.f;
|
||||
|
||||
if (size < sizeof(g_Signature))
|
||||
{
|
||||
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
||||
}
|
||||
|
||||
// Verify magic signature
|
||||
if (memcmp(pSource, g_Signature, sizeof(g_Signature) - 1) != 0)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Process first part of header
|
||||
bool formatFound = false;
|
||||
const char* info = reinterpret_cast<const char*>(pSource);
|
||||
while (size > 0)
|
||||
{
|
||||
if (*info == '\n')
|
||||
{
|
||||
++info;
|
||||
--size;
|
||||
break;
|
||||
}
|
||||
|
||||
const size_t formatLen = sizeof(g_Format) - 1;
|
||||
const size_t exposureLen = sizeof(g_Exposure) - 1;
|
||||
if ((size > formatLen) && memcmp(info, g_Format, formatLen) == 0)
|
||||
{
|
||||
info += formatLen;
|
||||
size -= formatLen;
|
||||
|
||||
// Trim whitespace
|
||||
while (*info == ' ' || *info == '\t')
|
||||
{
|
||||
if (--size == 0)
|
||||
return E_FAIL;
|
||||
++info;
|
||||
}
|
||||
|
||||
static_assert(sizeof(g_sRGBE) == sizeof(g_sXYZE), "Format strings length mismatch");
|
||||
|
||||
const size_t encodingLen = sizeof(g_sRGBE) - 1;
|
||||
|
||||
if (size < encodingLen)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if (memcmp(info, g_sRGBE, encodingLen) != 0 && memcmp(info, g_sXYZE, encodingLen) != 0)
|
||||
{
|
||||
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
formatFound = true;
|
||||
|
||||
size_t len = FindEOL(info, size);
|
||||
if (len == size_t(-1))
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
info += len + 1;
|
||||
size -= len + 1;
|
||||
}
|
||||
else if ((size > exposureLen) && memcmp(info, g_Exposure, exposureLen) == 0)
|
||||
{
|
||||
info += exposureLen;
|
||||
size -= exposureLen;
|
||||
|
||||
// Trim whitespace
|
||||
while (*info == ' ' || *info == '\t')
|
||||
{
|
||||
if (--size == 0)
|
||||
return E_FAIL;
|
||||
++info;
|
||||
}
|
||||
|
||||
size_t len = FindEOL(info, size);
|
||||
if (len == size_t(-1)
|
||||
|| len < 1)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
char buff[32] = {};
|
||||
strncpy_s(buff, info, std::min<size_t>(31, len));
|
||||
|
||||
float newExposure = static_cast<float>(atof(buff));
|
||||
if ((newExposure >= 1e-12) && (newExposure <= 1e12))
|
||||
{
|
||||
// Note that we ignore strange exposure values (like EXPOSURE=0)
|
||||
exposure *= newExposure;
|
||||
}
|
||||
|
||||
info += len + 1;
|
||||
size -= len + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t len = FindEOL(info, size);
|
||||
if (len == size_t(-1))
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
info += len + 1;
|
||||
size -= len + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!formatFound)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Get orientation
|
||||
char orient[256] = {};
|
||||
|
||||
size_t len = FindEOL(info, std::min<size_t>(sizeof(orient), size - 1));
|
||||
if (len == size_t(-1)
|
||||
|| len <= 2)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
strncpy_s(orient, info, len);
|
||||
|
||||
if (orient[0] != '-' && orient[1] != 'Y')
|
||||
{
|
||||
// We only support the -Y +X orientation (see top of file)
|
||||
return HRESULT_FROM_WIN32(
|
||||
((orient[0] == '+' || orient[0] == '-') && (orient[1] == 'X' || orient[1] == 'Y'))
|
||||
? ERROR_NOT_SUPPORTED : ERROR_INVALID_DATA
|
||||
);
|
||||
}
|
||||
|
||||
uint32_t height = 0;
|
||||
if (sscanf_s(orient + 2, "%u", &height) != 1)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
const char* ptr = orient + 2;
|
||||
while (*ptr != 0 && *ptr != '-' && *ptr != '+')
|
||||
++ptr;
|
||||
|
||||
if (*ptr == 0)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
else if (*ptr != '+')
|
||||
{
|
||||
// We only support the -Y +X orientation (see top of file)
|
||||
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
++ptr;
|
||||
if (*ptr == 0 || (*ptr != 'X' && *ptr != 'Y'))
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
else if (*ptr != 'X')
|
||||
{
|
||||
// We only support the -Y +X orientation (see top of file)
|
||||
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
++ptr;
|
||||
uint32_t width;
|
||||
if (sscanf_s(ptr, "%u", &width) != 1)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
info += len + 1;
|
||||
size -= len + 1;
|
||||
|
||||
if (!width || !height)
|
||||
{
|
||||
return HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
offset = info - reinterpret_cast<const char*>(pSource);
|
||||
|
||||
metadata.width = width;
|
||||
metadata.height = height;
|
||||
metadata.depth = metadata.arraySize = metadata.mipLevels = 1;
|
||||
metadata.format = DXGI_FORMAT_R32G32B32A32_FLOAT;
|
||||
metadata.dimension = TEX_DIMENSION_TEXTURE2D;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// FloatToRGBE
|
||||
//-------------------------------------------------------------------------------------
|
||||
inline void FloatToRGBE(_Out_writes_(width*4) uint8_t* pDestination, _In_reads_(width*bpp) const float* pSource, size_t width, int bpp)
|
||||
{
|
||||
for (size_t j = 0; j < width; ++j)
|
||||
{
|
||||
float r = pSource[0] >= 0.f ? pSource[0] : 0.f;
|
||||
float g = pSource[1] >= 0.f ? pSource[1] : 0.f;
|
||||
float b = pSource[2] >= 0.f ? pSource[2] : 0.f;
|
||||
pSource += bpp;
|
||||
|
||||
const float max_xy = (r > g) ? r : g;
|
||||
float max_xyz = (max_xy > b) ? max_xy : b;
|
||||
|
||||
if (max_xyz > 1e-32)
|
||||
{
|
||||
int e;
|
||||
max_xyz = frexpf(max_xyz, &e) * 256.f / max_xyz;
|
||||
e += 128;
|
||||
|
||||
uint8_t red = uint8_t(r * max_xyz);
|
||||
uint8_t green = uint8_t(g * max_xyz);
|
||||
uint8_t blue = uint8_t(b * max_xyz);
|
||||
|
||||
pDestination[0] = red;
|
||||
pDestination[1] = green;
|
||||
pDestination[2] = blue;
|
||||
pDestination[3] = (red || green || blue) ? uint8_t(e & 0xff) : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pDestination[0] = pDestination[1] = pDestination[2] = pDestination[3] = 0;
|
||||
}
|
||||
|
||||
pDestination += 4;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Encode using Adapative RLE
|
||||
//-------------------------------------------------------------------------------------
|
||||
_Success_(return > 0)
|
||||
size_t EncodeRLE(_Out_writes_(width*4) uint8_t* enc, _In_reads_(width*4) uint8_t* rgbe, size_t rowPitch, size_t width)
|
||||
{
|
||||
if (width < 8 || width > 32767)
|
||||
{
|
||||
// Don't try to compress too narrow or too wide scan-lines
|
||||
return 0;
|
||||
}
|
||||
|
||||
enc[0] = 2;
|
||||
enc[1] = 2;
|
||||
enc[2] = uint8_t(width >> 8);
|
||||
enc[3] = uint8_t(width & 0xff);
|
||||
enc += 4;
|
||||
size_t encSize = 4;
|
||||
|
||||
uint8_t scan[128] = {};
|
||||
|
||||
for (int channel = 0; channel < 4; ++channel)
|
||||
{
|
||||
uint8_t* spanPtr = rgbe + channel;
|
||||
for (size_t pixelCount = 0; pixelCount < width;)
|
||||
{
|
||||
uint8_t spanLen = 1;
|
||||
while (pixelCount + spanLen < width && spanLen < 127)
|
||||
{
|
||||
if (spanPtr[spanLen * 4] == *spanPtr)
|
||||
{
|
||||
++spanLen;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (spanLen > 1)
|
||||
{
|
||||
if (encSize + 2 > rowPitch)
|
||||
return 0;
|
||||
|
||||
enc[0] = 128 + spanLen;
|
||||
enc[1] = *spanPtr;
|
||||
enc += 2;
|
||||
encSize += 2;
|
||||
spanPtr += spanLen * 4;
|
||||
pixelCount += spanLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t runLen = 1;
|
||||
scan[0] = *spanPtr;
|
||||
while (pixelCount + runLen < width && runLen < 127)
|
||||
{
|
||||
if (spanPtr[(runLen - 1) * 4] != spanPtr[runLen * 4])
|
||||
{
|
||||
scan[runLen++] = spanPtr[runLen * 4];
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (encSize + runLen + 1 > rowPitch)
|
||||
return 0;
|
||||
|
||||
*enc++ = runLen;
|
||||
memcpy(enc, scan, runLen);
|
||||
enc += runLen;
|
||||
encSize += runLen + 1;
|
||||
spanPtr += runLen * 4;
|
||||
pixelCount += runLen;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return encSize;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=====================================================================================
|
||||
// Entry-points
|
||||
//=====================================================================================
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Obtain metadata from HDR file in memory/on disk
|
||||
//-------------------------------------------------------------------------------------
|
||||
_Use_decl_annotations_
|
||||
HRESULT DirectX::GetMetadataFromHDRMemory(const void* pSource, size_t size, TexMetadata& metadata)
|
||||
{
|
||||
if (!pSource || size == 0)
|
||||
return E_INVALIDARG;
|
||||
|
||||
size_t offset;
|
||||
float exposure;
|
||||
return DecodeHDRHeader(pSource, size, metadata, offset, exposure);
|
||||
}
|
||||
|
||||
_Use_decl_annotations_
|
||||
HRESULT DirectX::GetMetadataFromHDRFile(const wchar_t* szFile, TexMetadata& metadata)
|
||||
{
|
||||
if (!szFile)
|
||||
return E_INVALIDARG;
|
||||
|
||||
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
|
||||
ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr)));
|
||||
#else
|
||||
ScopedHandle hFile(safe_handle(CreateFileW(szFile, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
|
||||
FILE_FLAG_SEQUENTIAL_SCAN, nullptr)));
|
||||
#endif
|
||||
if (!hFile)
|
||||
{
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
// Get the file size
|
||||
FILE_STANDARD_INFO fileInfo;
|
||||
if (!GetFileInformationByHandleEx(hFile.get(), FileStandardInfo, &fileInfo, sizeof(fileInfo)))
|
||||
{
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
// File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid HDR file)
|
||||
if (fileInfo.EndOfFile.HighPart > 0)
|
||||
{
|
||||
return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE);
|
||||
}
|
||||
|
||||
// Need at least enough data to fill the standard header to be a valid HDR
|
||||
if (fileInfo.EndOfFile.LowPart < sizeof(g_Signature))
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Read the first part of the file to find the header
|
||||
uint8_t header[8192];
|
||||
DWORD bytesRead = 0;
|
||||
if (!ReadFile(hFile.get(), header, std::min<DWORD>(sizeof(header), fileInfo.EndOfFile.LowPart), &bytesRead, nullptr))
|
||||
{
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
size_t offset;
|
||||
float exposure;
|
||||
return DecodeHDRHeader(header, bytesRead, metadata, offset, exposure);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Load a HDR file in memory
|
||||
//-------------------------------------------------------------------------------------
|
||||
_Use_decl_annotations_
|
||||
HRESULT DirectX::LoadFromHDRMemory(const void* pSource, size_t size, TexMetadata* metadata, ScratchImage& image)
|
||||
{
|
||||
if (!pSource || size == 0)
|
||||
return E_INVALIDARG;
|
||||
|
||||
image.Release();
|
||||
|
||||
size_t offset;
|
||||
float exposure;
|
||||
TexMetadata mdata;
|
||||
HRESULT hr = DecodeHDRHeader(pSource, size, mdata, offset, exposure);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
if (offset > size)
|
||||
return E_FAIL;
|
||||
|
||||
size_t remaining = size - offset;
|
||||
if (remaining == 0)
|
||||
return E_FAIL;
|
||||
|
||||
hr = image.Initialize2D(mdata.format, mdata.width, mdata.height, 1, 1);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
// Copy pixels
|
||||
auto sourcePtr = reinterpret_cast<const uint8_t*>(pSource) + offset;
|
||||
|
||||
size_t pixelLen = remaining;
|
||||
|
||||
const Image* img = image.GetImage(0, 0, 0);
|
||||
|
||||
auto destPtr = img->pixels;
|
||||
|
||||
#ifdef _DEBUG
|
||||
memset(img->pixels, 0xFF, img->rowPitch * img->height);
|
||||
#endif
|
||||
|
||||
for (size_t scan = 0; scan < mdata.height; ++scan)
|
||||
{
|
||||
if (pixelLen < 4)
|
||||
{
|
||||
image.Release();
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
uint8_t inColor[4];
|
||||
memcpy(inColor, sourcePtr, 4);
|
||||
sourcePtr += 4;
|
||||
pixelLen -= 4;
|
||||
|
||||
auto scanLine = reinterpret_cast<float*>(destPtr);
|
||||
|
||||
if (inColor[0] == 2 && inColor[1] == 2 && inColor[2] < 128)
|
||||
{
|
||||
// Adaptive Run Length Encoding (RLE)
|
||||
if (size_t((inColor[2] << 8) + inColor[3]) != mdata.width)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
for (int channel = 0; channel < 4; ++channel)
|
||||
{
|
||||
auto pixelLoc = scanLine + channel;
|
||||
for(size_t pixelCount = 0; pixelCount < mdata.width;)
|
||||
{
|
||||
if (pixelLen < 2)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
assert(sourcePtr < (reinterpret_cast<const uint8_t*>(pSource) + size));
|
||||
|
||||
uint8_t runLen = *sourcePtr;
|
||||
if (runLen > 128)
|
||||
{
|
||||
runLen &= 127;
|
||||
if (pixelCount + runLen > mdata.width)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
float val = static_cast<float>(sourcePtr[1]);
|
||||
for (uint8_t j = 0; j < runLen; ++j)
|
||||
{
|
||||
*pixelLoc = val;
|
||||
pixelLoc += 4;
|
||||
}
|
||||
pixelCount += runLen;
|
||||
sourcePtr += 2;
|
||||
pixelLen -= 2;
|
||||
}
|
||||
else if ((size < size_t(runLen + 1)) || ((pixelCount + runLen) > mdata.width))
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
++sourcePtr;
|
||||
for (uint8_t j = 0; j < runLen; ++j)
|
||||
{
|
||||
float val = static_cast<float>(*sourcePtr++);
|
||||
*pixelLoc = val;
|
||||
pixelLoc += 4;
|
||||
}
|
||||
pixelCount += runLen;
|
||||
pixelLen -= runLen + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto pixelLoc = scanLine;
|
||||
|
||||
float prevColor[4];
|
||||
prevColor[0] = inColor[0];
|
||||
prevColor[1] = inColor[1];
|
||||
prevColor[2] = inColor[2];
|
||||
prevColor[3] = inColor[3];
|
||||
|
||||
int bitShift = 0;
|
||||
for (size_t pixelCount = 0; pixelCount < mdata.width;)
|
||||
{
|
||||
if (inColor[0] == 1 && inColor[1] == 1 && inColor[2] == 1)
|
||||
{
|
||||
// "Standard" Run Length Encoding
|
||||
size_t spanLen = inColor[3] << bitShift;
|
||||
if (spanLen + pixelCount > mdata.width)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
for (size_t j = 0; j < spanLen; ++j)
|
||||
{
|
||||
pixelLoc[0] = prevColor[0];
|
||||
pixelLoc[1] = prevColor[1];
|
||||
pixelLoc[2] = prevColor[2];
|
||||
pixelLoc[3] = prevColor[3];
|
||||
pixelLoc += 4;
|
||||
}
|
||||
pixelCount += spanLen;
|
||||
bitShift += 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Uncompressed
|
||||
pixelLoc[0] = prevColor[0] = inColor[0];
|
||||
pixelLoc[1] = prevColor[1] = inColor[1];
|
||||
pixelLoc[2] = prevColor[2] = inColor[2];
|
||||
pixelLoc[3] = prevColor[3] = inColor[3];
|
||||
bitShift = 0;
|
||||
++pixelCount;
|
||||
pixelLoc += 4;
|
||||
}
|
||||
|
||||
if (pixelCount >= mdata.width)
|
||||
break;
|
||||
|
||||
if (pixelLen < 4)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
memcpy(inColor, sourcePtr, 4);
|
||||
sourcePtr += 4;
|
||||
pixelLen -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
destPtr += img->rowPitch;
|
||||
}
|
||||
|
||||
// Transform values
|
||||
{
|
||||
auto fdata = reinterpret_cast<float*>(image.GetPixels());
|
||||
|
||||
for (size_t j = 0; j < image.GetPixelsSize(); j += 16)
|
||||
{
|
||||
int exponent = static_cast<int>(fdata[3]);
|
||||
fdata[0] = 1.0f / exposure*ldexpf((fdata[0] + 0.5f), exponent - (128 + 8));
|
||||
fdata[1] = 1.0f / exposure*ldexpf((fdata[1] + 0.5f), exponent - (128 + 8));
|
||||
fdata[2] = 1.0f / exposure*ldexpf((fdata[2] + 0.5f), exponent - (128 + 8));
|
||||
fdata[3] = 1.f;
|
||||
|
||||
fdata += 4;
|
||||
}
|
||||
}
|
||||
|
||||
if (metadata)
|
||||
memcpy(metadata, &mdata, sizeof(TexMetadata));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Load a HDR file from disk
|
||||
//-------------------------------------------------------------------------------------
|
||||
_Use_decl_annotations_
|
||||
HRESULT DirectX::LoadFromHDRFile(const wchar_t* szFile, TexMetadata* metadata, ScratchImage& image)
|
||||
{
|
||||
if (!szFile)
|
||||
return E_INVALIDARG;
|
||||
|
||||
image.Release();
|
||||
|
||||
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
|
||||
ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr)));
|
||||
#else
|
||||
ScopedHandle hFile(safe_handle(CreateFileW(szFile, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
|
||||
FILE_FLAG_SEQUENTIAL_SCAN, nullptr)));
|
||||
#endif
|
||||
if (!hFile)
|
||||
{
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
// Get the file size
|
||||
FILE_STANDARD_INFO fileInfo;
|
||||
if (!GetFileInformationByHandleEx(hFile.get(), FileStandardInfo, &fileInfo, sizeof(fileInfo)))
|
||||
{
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
// File is too big for 32-bit allocation, so reject read (4 GB should be plenty large enough for a valid HDR file)
|
||||
if (fileInfo.EndOfFile.HighPart > 0)
|
||||
{
|
||||
return HRESULT_FROM_WIN32(ERROR_FILE_TOO_LARGE);
|
||||
}
|
||||
|
||||
// Need at least enough data to fill the header to be a valid HDR
|
||||
if (fileInfo.EndOfFile.LowPart < sizeof(g_Signature))
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Read file
|
||||
std::unique_ptr<uint8_t[]> temp(new (std::nothrow) uint8_t[fileInfo.EndOfFile.LowPart]);
|
||||
if (!temp)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
DWORD bytesRead = 0;
|
||||
if (!ReadFile(hFile.get(), temp.get(), fileInfo.EndOfFile.LowPart, &bytesRead, nullptr))
|
||||
{
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
if (bytesRead != fileInfo.EndOfFile.LowPart)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return LoadFromHDRMemory(temp.get(), fileInfo.EndOfFile.LowPart, metadata, image);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Save a HDR file to memory
|
||||
//-------------------------------------------------------------------------------------
|
||||
_Use_decl_annotations_
|
||||
HRESULT DirectX::SaveToHDRMemory(const Image& image, Blob& blob)
|
||||
{
|
||||
if (!image.pixels)
|
||||
return E_POINTER;
|
||||
|
||||
if (image.width > 32767 || image.height > 32767)
|
||||
{
|
||||
// Images larger than this can't be RLE encoded. They are technically allowed as
|
||||
// uncompresssed, but we just don't support them.
|
||||
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
int bpp;
|
||||
switch (image.format)
|
||||
{
|
||||
case DXGI_FORMAT_R32G32B32A32_FLOAT:
|
||||
bpp = 4;
|
||||
break;
|
||||
|
||||
case DXGI_FORMAT_R32G32B32_FLOAT:
|
||||
bpp = 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
blob.Release();
|
||||
|
||||
char header[256] = {};
|
||||
sprintf_s(header, g_Header, image.height, image.width);
|
||||
|
||||
auto headerLen = static_cast<DWORD>(strlen(header));
|
||||
|
||||
size_t rowPitch = image.width * 4;
|
||||
size_t slicePitch = image.height * rowPitch;
|
||||
|
||||
HRESULT hr = blob.Initialize(headerLen + slicePitch);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
// Copy header
|
||||
auto dPtr = reinterpret_cast<uint8_t*>(blob.GetBufferPointer());
|
||||
assert(dPtr != 0);
|
||||
memcpy_s(dPtr, blob.GetBufferSize(), header, headerLen);
|
||||
dPtr += headerLen;
|
||||
|
||||
#ifdef DISABLE_COMPRESS
|
||||
// Uncompressed write
|
||||
auto sPtr = reinterpret_cast<const uint8_t*>(image.pixels);
|
||||
for (size_t scan = 0; scan < image.height; ++scan)
|
||||
{
|
||||
FloatToRGBE(dPtr, reinterpret_cast<const float*>(sPtr), image.width, bpp);
|
||||
dPtr += rowPitch;
|
||||
sPtr += image.rowPitch;
|
||||
}
|
||||
#else
|
||||
std::unique_ptr<uint8_t[]> temp(new (std::nothrow) uint8_t[rowPitch * 2]);
|
||||
if (!temp)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
auto rgbe = temp.get();
|
||||
auto enc = temp.get() + rowPitch;
|
||||
|
||||
auto sPtr = reinterpret_cast<const uint8_t*>(image.pixels);
|
||||
for (size_t scan = 0; scan < image.height; ++scan)
|
||||
{
|
||||
FloatToRGBE(rgbe, reinterpret_cast<const float*>(sPtr), image.width, bpp);
|
||||
sPtr += image.rowPitch;
|
||||
|
||||
size_t encSize = EncodeRLE(enc, rgbe, rowPitch, image.width);
|
||||
if (encSize > 0)
|
||||
{
|
||||
memcpy(dPtr, enc, encSize);
|
||||
dPtr += encSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(dPtr, rgbe, rowPitch);
|
||||
dPtr += rowPitch;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
hr = blob.Trim(dPtr - reinterpret_cast<uint8_t*>(blob.GetBufferPointer()));
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Save a HDR file to disk
|
||||
//-------------------------------------------------------------------------------------
|
||||
_Use_decl_annotations_
|
||||
HRESULT DirectX::SaveToHDRFile(const Image& image, const wchar_t* szFile)
|
||||
{
|
||||
if (!szFile)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!image.pixels)
|
||||
return E_POINTER;
|
||||
|
||||
if (image.width > 32767 || image.height > 32767)
|
||||
{
|
||||
// Images larger than this can't be RLE encoded. They are technically allowed as
|
||||
// uncompresssed, but we just don't support them.
|
||||
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
int bpp;
|
||||
switch (image.format)
|
||||
{
|
||||
case DXGI_FORMAT_R32G32B32A32_FLOAT:
|
||||
bpp = 4;
|
||||
break;
|
||||
|
||||
case DXGI_FORMAT_R32G32B32_FLOAT:
|
||||
bpp = 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
// Create file and write header
|
||||
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
|
||||
ScopedHandle hFile(safe_handle(CreateFile2(szFile, GENERIC_WRITE, 0, CREATE_ALWAYS, nullptr)));
|
||||
#else
|
||||
ScopedHandle hFile(safe_handle(CreateFileW(szFile, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, nullptr)));
|
||||
#endif
|
||||
if (!hFile)
|
||||
{
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
auto_delete_file delonfail(hFile.get());
|
||||
|
||||
size_t rowPitch = image.width * 4;
|
||||
size_t slicePitch = image.height * rowPitch;
|
||||
|
||||
if (slicePitch < 65535)
|
||||
{
|
||||
// For small images, it is better to create an in-memory file and write it out
|
||||
Blob blob;
|
||||
|
||||
HRESULT hr = SaveToHDRMemory(image, blob);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
// Write blob
|
||||
const DWORD bytesToWrite = static_cast<DWORD>(blob.GetBufferSize());
|
||||
DWORD bytesWritten;
|
||||
if (!WriteFile(hFile.get(), blob.GetBufferPointer(), bytesToWrite, &bytesWritten, nullptr))
|
||||
{
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
if (bytesWritten != bytesToWrite)
|
||||
{
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, write the image one scanline at a time...
|
||||
std::unique_ptr<uint8_t[]> temp(new (std::nothrow) uint8_t[rowPitch * 2]);
|
||||
if (!temp)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
auto rgbe = temp.get();
|
||||
|
||||
// Write header
|
||||
char header[256] = {};
|
||||
sprintf_s(header, g_Header, image.height, image.width);
|
||||
|
||||
auto headerLen = static_cast<DWORD>(strlen(header));
|
||||
|
||||
DWORD bytesWritten;
|
||||
if (!WriteFile(hFile.get(), header, headerLen, &bytesWritten, nullptr))
|
||||
{
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
if (bytesWritten != headerLen)
|
||||
return E_FAIL;
|
||||
|
||||
#ifdef DISABLE_COMPRESS
|
||||
// Uncompressed write
|
||||
auto sPtr = reinterpret_cast<const uint8_t*>(image.pixels);
|
||||
for (size_t scan = 0; scan < image.height; ++scan)
|
||||
{
|
||||
FloatToRGBE(rgbe, reinterpret_cast<const float*>(sPtr), image.width, bpp);
|
||||
sPtr += image.rowPitch;
|
||||
|
||||
if (!WriteFile(hFile.get(), rgbe, static_cast<DWORD>(rowPitch), &bytesWritten, nullptr))
|
||||
{
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
if (bytesWritten != rowPitch)
|
||||
return E_FAIL;
|
||||
}
|
||||
#else
|
||||
auto enc = temp.get() + rowPitch;
|
||||
|
||||
auto sPtr = reinterpret_cast<const uint8_t*>(image.pixels);
|
||||
for (size_t scan = 0; scan < image.height; ++scan)
|
||||
{
|
||||
FloatToRGBE(rgbe, reinterpret_cast<const float*>(sPtr), image.width, bpp);
|
||||
sPtr += image.rowPitch;
|
||||
|
||||
size_t encSize = EncodeRLE(enc, rgbe, rowPitch, image.width);
|
||||
if (encSize > 0)
|
||||
{
|
||||
if (!WriteFile(hFile.get(), enc, static_cast<DWORD>(encSize), &bytesWritten, nullptr))
|
||||
{
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
if (bytesWritten != encSize)
|
||||
return E_FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!WriteFile(hFile.get(), rgbe, static_cast<DWORD>(rowPitch), &bytesWritten, nullptr))
|
||||
{
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
if (bytesWritten != rowPitch)
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
delonfail.clear();
|
||||
|
||||
return S_OK;
|
||||
}
|
@ -166,6 +166,41 @@ namespace
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
HRESULT Evaluate_(
|
||||
const Image& image,
|
||||
std::function<void __cdecl(_In_reads_(width) const XMVECTOR* pixels, size_t width, size_t y)> pixelFunc)
|
||||
{
|
||||
if (!pixelFunc)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!image.pixels)
|
||||
return E_POINTER;
|
||||
|
||||
assert(!IsCompressed(image.format));
|
||||
|
||||
const size_t width = image.width;
|
||||
|
||||
ScopedAlignedArrayXMVECTOR scanline(reinterpret_cast<XMVECTOR*>(_aligned_malloc((sizeof(XMVECTOR)*width), 16)));
|
||||
if (!scanline)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
const uint8_t *pSrc = image.pixels;
|
||||
const size_t rowPitch = image.rowPitch;
|
||||
|
||||
for (size_t h = 0; h < image.height; ++h)
|
||||
{
|
||||
if (!_LoadScanline(scanline.get(), width, pSrc, rowPitch, image.format))
|
||||
return E_FAIL;
|
||||
|
||||
pixelFunc(scanline.get(), width, h);
|
||||
|
||||
pSrc += rowPitch;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -367,3 +402,40 @@ HRESULT DirectX::ComputeMSE(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------
|
||||
// Evaluates a user-supplied function for all the pixels in the image
|
||||
//-------------------------------------------------------------------------------------
|
||||
_Use_decl_annotations_
|
||||
HRESULT DirectX::Evaluate(
|
||||
const Image& image,
|
||||
std::function<void __cdecl(_In_reads_(width) const XMVECTOR* pixels, size_t width, size_t y)> pixelFunc)
|
||||
{
|
||||
if (image.width > UINT32_MAX
|
||||
|| image.height > UINT32_MAX)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (IsPlanar(image.format) || IsPalettized(image.format))
|
||||
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
|
||||
|
||||
if (IsCompressed(image.format))
|
||||
{
|
||||
ScratchImage temp;
|
||||
HRESULT hr = Decompress(image, DXGI_FORMAT_R32G32B32A32_FLOAT, temp);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
const Image* img = temp.GetImage(0, 0, 0);
|
||||
if (!img)
|
||||
return E_POINTER;
|
||||
|
||||
return Evaluate_(*img, pixelFunc);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Evaluate_(image, pixelFunc);
|
||||
}
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
@ -1442,3 +1442,19 @@ HRESULT Blob::Initialize(size_t size)
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT Blob::Trim(size_t size)
|
||||
{
|
||||
if (!size)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (!m_buffer)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (size > m_size)
|
||||
return E_INVALIDARG;
|
||||
|
||||
m_size = size;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -406,6 +406,7 @@
|
||||
<ClCompile Include="DirectXTexD3D11.cpp" />
|
||||
<ClCompile Include="DirectXTexDDS.cpp" />
|
||||
<ClCompile Include="DirectXTexFlipRotate.cpp" />
|
||||
<ClCompile Include="DirectXTexHDR.cpp" />
|
||||
<ClCompile Include="DirectXTexImage.cpp" />
|
||||
<ClCompile Include="DirectXTexMipMaps.cpp" />
|
||||
<ClCompile Include="DirectXTexMisc.cpp" />
|
||||
|
@ -95,6 +95,9 @@
|
||||
<ClCompile Include="DirectXTexWIC.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DirectXTexHDR.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CLInclude Include="BC.h">
|
||||
|
@ -397,6 +397,7 @@
|
||||
<ClCompile Include="DirectXTexD3D11.cpp" />
|
||||
<ClCompile Include="DirectXTexDDS.cpp" />
|
||||
<ClCompile Include="DirectXTexFlipRotate.cpp" />
|
||||
<ClCompile Include="DirectXTexHDR.cpp" />
|
||||
<ClCompile Include="DirectXTexImage.cpp" />
|
||||
<ClCompile Include="DirectXTexMipMaps.cpp" />
|
||||
<ClCompile Include="DirectXTexMisc.cpp" />
|
||||
|
@ -95,6 +95,9 @@
|
||||
<ClCompile Include="DirectXTexWIC.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DirectXTexHDR.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CLInclude Include="BC.h">
|
||||
|
@ -406,6 +406,7 @@
|
||||
<ClCompile Include="DirectXTexD3D11.cpp" />
|
||||
<ClCompile Include="DirectXTexDDS.cpp" />
|
||||
<ClCompile Include="DirectXTexFlipRotate.cpp" />
|
||||
<ClCompile Include="DirectXTexHDR.cpp" />
|
||||
<ClCompile Include="DirectXTexImage.cpp" />
|
||||
<ClCompile Include="DirectXTexMipMaps.cpp" />
|
||||
<ClCompile Include="DirectXTexMisc.cpp" />
|
||||
|
@ -95,6 +95,9 @@
|
||||
<ClCompile Include="DirectXTexWIC.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DirectXTexHDR.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CLInclude Include="BC.h">
|
||||
|
@ -37,6 +37,7 @@
|
||||
<ClCompile Include="DirectXTexD3D11.cpp" />
|
||||
<ClCompile Include="DirectXTexDDS.cpp" />
|
||||
<ClCompile Include="DirectXTexFlipRotate.cpp" />
|
||||
<ClCompile Include="DirectXTexHDR.cpp" />
|
||||
<ClCompile Include="DirectXTexImage.cpp" />
|
||||
<ClCompile Include="DirectXTexMipmaps.cpp" />
|
||||
<ClCompile Include="DirectXTexMisc.cpp" />
|
||||
|
@ -58,6 +58,9 @@
|
||||
<ClCompile Include="DirectXTexWIC.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DirectXTexHDR.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="DirectXTex.h">
|
||||
|
@ -615,6 +615,7 @@
|
||||
<ClCompile Include="DirectXTexD3D11.cpp" />
|
||||
<ClCompile Include="DirectXTexDDS.cpp" />
|
||||
<ClCompile Include="DirectXTexFlipRotate.cpp" />
|
||||
<ClCompile Include="DirectXTexHDR.cpp" />
|
||||
<ClCompile Include="DirectXTexImage.cpp" />
|
||||
<ClCompile Include="DirectXTexMipMaps.cpp" />
|
||||
<ClCompile Include="DirectXTexMisc.cpp" />
|
||||
|
@ -1,10 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns:atg="http://atg.xbox.com" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{8e114980-c1a3-4ada-ad7c-83caadf5daeb}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{c99f7f80-93a7-4692-8567-779ebabe625b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
@ -48,6 +44,9 @@
|
||||
<ClCompile Include="BC4BC5.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DirectXTexHDR.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="BC.cpp">
|
||||
|
@ -166,6 +166,7 @@
|
||||
<ClCompile Include="DirectXTexD3D11.cpp" />
|
||||
<ClCompile Include="DirectXTexDDS.cpp" />
|
||||
<ClCompile Include="DirectXTexFlipRotate.cpp" />
|
||||
<ClCompile Include="DirectXTexHDR.cpp" />
|
||||
<ClCompile Include="DirectXTexImage.cpp" />
|
||||
<ClCompile Include="DirectXTexMipMaps.cpp" />
|
||||
<ClCompile Include="DirectXTexMisc.cpp" />
|
||||
|
@ -58,6 +58,9 @@
|
||||
<ClCompile Include="DirectXTexWIC.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DirectXTexHDR.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CLInclude Include="DirectXTex.h">
|
||||
|
@ -45,6 +45,7 @@
|
||||
<ClCompile Include="DirectXTexD3D11.cpp" />
|
||||
<ClCompile Include="DirectXTexDDS.cpp" />
|
||||
<ClCompile Include="DirectXTexFlipRotate.cpp" />
|
||||
<ClCompile Include="DirectXTexHDR.cpp" />
|
||||
<ClCompile Include="DirectXTexImage.cpp" />
|
||||
<ClCompile Include="DirectXTexMipmaps.cpp" />
|
||||
<ClCompile Include="DirectXTexMisc.cpp" />
|
||||
|
@ -132,5 +132,8 @@
|
||||
<ClCompile Include="DirectXTexWIC.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DirectXTexHDR.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -1,13 +1,22 @@
|
||||
//--------------------------------------------------------------------------------------
|
||||
// File: Texassemble.cpp
|
||||
//
|
||||
// DirectX 11 Texture assembler for cube maps, volume maps, and arrays
|
||||
// DirectX Texture assembler for cube maps, volume maps, and arrays
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4005)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define NOMINMAX
|
||||
#define NODRAWTEXT
|
||||
#define NOGDI
|
||||
#define NOBITMAP
|
||||
#define NOMCX
|
||||
#define NOSERVICE
|
||||
#define NOHELP
|
||||
#pragma warning(pop)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -275,7 +284,7 @@ void PrintList(size_t cch, SValue *pValue)
|
||||
|
||||
void PrintLogo()
|
||||
{
|
||||
wprintf( L"Microsoft (R) DirectX 11 Texture Assembler (DirectXTex version)\n");
|
||||
wprintf( L"Microsoft (R) DirectX Texture Assembler (DirectXTex version)\n");
|
||||
wprintf( L"Copyright (C) Microsoft Corp. All rights reserved.\n");
|
||||
wprintf( L"\n");
|
||||
}
|
||||
@ -517,6 +526,15 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if ( _wcsicmp( ext, L".hdr" ) == 0 )
|
||||
{
|
||||
hr = LoadFromHDRFile( pConv->szSrc, &info, *image.get() );
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
wprintf( L" FAILED (%x)\n", hr);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// WIC shares the same filter values for mode and dither
|
||||
|
@ -1,13 +1,22 @@
|
||||
//--------------------------------------------------------------------------------------
|
||||
// File: TexConv.cpp
|
||||
//
|
||||
// DirectX 11 Texture Converter
|
||||
// DirectX Texture Converter
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4005)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define NOMINMAX
|
||||
#define NODRAWTEXT
|
||||
#define NOGDI
|
||||
#define NOBITMAP
|
||||
#define NOMCX
|
||||
#define NOSERVICE
|
||||
#define NOHELP
|
||||
#pragma warning(pop)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -293,6 +302,7 @@ SValue g_pFilters[] =
|
||||
#define CODEC_TGA 0xFFFF0002
|
||||
#define CODEC_HDP 0xFFFF0003
|
||||
#define CODEC_JXR 0xFFFF0004
|
||||
#define CODEC_HDR 0xFFFF0005
|
||||
|
||||
SValue g_pSaveFileTypes[] = // valid formats to write to
|
||||
{
|
||||
@ -302,6 +312,7 @@ SValue g_pSaveFileTypes[] = // valid formats to write to
|
||||
{ L"PNG", WIC_CODEC_PNG },
|
||||
{ L"DDS", CODEC_DDS },
|
||||
{ L"TGA", CODEC_TGA },
|
||||
{ L"HDR", CODEC_HDR },
|
||||
{ L"TIF", WIC_CODEC_TIFF },
|
||||
{ L"TIFF", WIC_CODEC_TIFF },
|
||||
{ L"WDP", WIC_CODEC_WMP },
|
||||
@ -451,7 +462,7 @@ void PrintList(size_t cch, SValue *pValue)
|
||||
|
||||
void PrintLogo()
|
||||
{
|
||||
wprintf( L"Microsoft (R) DirectX 11 Texture Converter (DirectXTex version)\n");
|
||||
wprintf( L"Microsoft (R) DirectX Texture Converter (DirectXTex version)\n");
|
||||
wprintf( L"Copyright (C) Microsoft Corp. All rights reserved.\n");
|
||||
#ifdef _DEBUG
|
||||
wprintf( L"*** Debug build ***\n");
|
||||
@ -1204,6 +1215,15 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if ( _wcsicmp( ext, L".hdr" ) == 0 )
|
||||
{
|
||||
hr = LoadFromHDRFile( pConv->szSrc, &info, *image );
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
wprintf( L" FAILED (%x)\n", hr);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// WIC shares the same filter values for mode and dither
|
||||
@ -1890,6 +1910,10 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
||||
hr = SaveToTGAFile( img[0], pConv->szDest );
|
||||
break;
|
||||
|
||||
case CODEC_HDR:
|
||||
hr = SaveToHDRFile( img[0], pConv->szDest );
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
WICCodecs codec = (FileType == CODEC_HDP || FileType == CODEC_JXR) ? WIC_CODEC_WMP : static_cast<WICCodecs>(FileType);
|
||||
|
Loading…
Reference in New Issue
Block a user