mirror of
https://github.com/microsoft/DirectXTex.git
synced 2025-07-14 14:10:13 +02:00
PFM half16 variant and cope with comments
This commit is contained in:
parent
0539287324
commit
5999f34c11
@ -3,9 +3,6 @@
|
|||||||
//
|
//
|
||||||
// Utilities for reading & writing Portable PixMap files (PPM/PFM)
|
// Utilities for reading & writing Portable PixMap files (PPM/PFM)
|
||||||
//
|
//
|
||||||
// http://paulbourke.net/dataformats/ppm/
|
|
||||||
// http://paulbourke.net/dataformats/pbmhdr/
|
|
||||||
//
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
// Licensed under the MIT License.
|
// Licensed under the MIT License.
|
||||||
//
|
//
|
||||||
@ -138,7 +135,8 @@ namespace
|
|||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
// PPM
|
// PPM (Portable PixMap)
|
||||||
|
// http://paulbourke.net/dataformats/ppm/
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
HRESULT __cdecl LoadFromPortablePixMap(
|
HRESULT __cdecl LoadFromPortablePixMap(
|
||||||
@ -402,7 +400,9 @@ HRESULT __cdecl SaveToPortablePixMap(
|
|||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
// PFM
|
// PFM (Portable Float Map)
|
||||||
|
// http://paulbourke.net/dataformats/pbmhdr/
|
||||||
|
// https://oyranos.org/2015/03/portable-float-map-with-16-bit-half/index.html
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
HRESULT __cdecl LoadFromPortablePixMapHDR(
|
HRESULT __cdecl LoadFromPortablePixMapHDR(
|
||||||
@ -419,18 +419,44 @@ HRESULT __cdecl LoadFromPortablePixMapHDR(
|
|||||||
if (pfmSize < 3)
|
if (pfmSize < 3)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
if (pfmData[0] != 'P' || (pfmData[1] != 'f' && pfmData[1] != 'F') || pfmData[2] != '\n')
|
if (pfmData[0] != 'P' || pfmData[2] != '\n')
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
bool monochrome = pfmData[1] == 'f';
|
DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
|
||||||
|
bool monochrome = false;
|
||||||
|
bool half16 = false;
|
||||||
|
switch (pfmData[1])
|
||||||
|
{
|
||||||
|
case 'f': format = DXGI_FORMAT_R32_FLOAT; monochrome = true; break;
|
||||||
|
case 'F': format = DXGI_FORMAT_R32G32B32A32_FLOAT; break;
|
||||||
|
case 'h': format = DXGI_FORMAT_R16_FLOAT; monochrome = true; half16 = true; break;
|
||||||
|
case 'H': format = DXGI_FORMAT_R16G16B16A16_FLOAT; half16 = true; break;
|
||||||
|
default:
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
auto pData = reinterpret_cast<const char*>(pfmData.get()) + 3;
|
auto pData = reinterpret_cast<const char*>(pfmData.get()) + 3;
|
||||||
pfmSize -= 3;
|
pfmSize -= 3;
|
||||||
|
if (!pfmSize)
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
size_t len = FindEOL(pData, 256);
|
// Ignore any comment lines (some tools add them)
|
||||||
|
size_t len = 0;
|
||||||
|
while (pfmSize > 0)
|
||||||
|
{
|
||||||
|
len = FindEOL(pData, 256);
|
||||||
if (!len)
|
if (!len)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
|
if (*pData != '#')
|
||||||
|
break;
|
||||||
|
|
||||||
|
pData += len + 1;
|
||||||
|
pfmSize -= len + 1;
|
||||||
|
if (!pfmSize)
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
char dataStr[256] = {};
|
char dataStr[256] = {};
|
||||||
char junkStr[256] = {};
|
char junkStr[256] = {};
|
||||||
strncpy_s(dataStr, pData, len + 1);
|
strncpy_s(dataStr, pData, len + 1);
|
||||||
@ -444,10 +470,23 @@ HRESULT __cdecl LoadFromPortablePixMapHDR(
|
|||||||
if (!pfmSize)
|
if (!pfmSize)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
|
// Ignore any comment lines (some tools add them)
|
||||||
|
len = 0;
|
||||||
|
while (pfmSize > 0)
|
||||||
|
{
|
||||||
len = FindEOL(pData, 256);
|
len = FindEOL(pData, 256);
|
||||||
if (!len)
|
if (!len)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
|
if (*pData != '#')
|
||||||
|
break;
|
||||||
|
|
||||||
|
pData += len + 1;
|
||||||
|
pfmSize -= len + 1;
|
||||||
|
if (!pfmSize)
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
strncpy_s(dataStr, pData, len + 1);
|
strncpy_s(dataStr, pData, len + 1);
|
||||||
|
|
||||||
float aspectRatio = 0.f;
|
float aspectRatio = 0.f;
|
||||||
@ -461,7 +500,7 @@ HRESULT __cdecl LoadFromPortablePixMapHDR(
|
|||||||
if (!pfmSize)
|
if (!pfmSize)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
size_t scanline = width * sizeof(float) * (monochrome ? 1 : 3);
|
size_t scanline = width * (half16 ? sizeof(uint16_t) : sizeof(float)) * (monochrome ? 1 : 3);
|
||||||
if (pfmSize < scanline * height)
|
if (pfmSize < scanline * height)
|
||||||
return HRESULT_FROM_WIN32(ERROR_HANDLE_EOF);
|
return HRESULT_FROM_WIN32(ERROR_HANDLE_EOF);
|
||||||
|
|
||||||
@ -471,17 +510,62 @@ HRESULT __cdecl LoadFromPortablePixMapHDR(
|
|||||||
metadata->width = width;
|
metadata->width = width;
|
||||||
metadata->height = height;
|
metadata->height = height;
|
||||||
metadata->depth = metadata->arraySize = metadata->mipLevels = 1;
|
metadata->depth = metadata->arraySize = metadata->mipLevels = 1;
|
||||||
metadata->format = monochrome ? DXGI_FORMAT_R32_FLOAT : DXGI_FORMAT_R32G32B32A32_FLOAT;
|
metadata->format = format;
|
||||||
metadata->dimension = TEX_DIMENSION_TEXTURE2D;
|
metadata->dimension = TEX_DIMENSION_TEXTURE2D;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = image.Initialize2D(monochrome ? DXGI_FORMAT_R32_FLOAT : DXGI_FORMAT_R32G32B32A32_FLOAT,
|
hr = image.Initialize2D(format, width, height, 1, 1);
|
||||||
width, height, 1, 1);
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
auto img = image.GetImage(0, 0, 0);
|
auto img = image.GetImage(0, 0, 0);
|
||||||
|
|
||||||
|
|
||||||
|
if (half16)
|
||||||
|
{
|
||||||
|
auto sptr = reinterpret_cast<const uint16_t*>(pData);
|
||||||
|
if (monochrome)
|
||||||
|
{
|
||||||
|
for (size_t y = 0; y < height; ++y)
|
||||||
|
{
|
||||||
|
auto dptr = reinterpret_cast<uint16_t*>(img->pixels + (height - y - 1) * img->rowPitch);
|
||||||
|
|
||||||
|
for (size_t x = 0; x < width; ++x)
|
||||||
|
{
|
||||||
|
*dptr++ = (bigendian) ? _byteswap_ushort(*sptr++) : *sptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (size_t y = 0; y < height; ++y)
|
||||||
|
{
|
||||||
|
auto dptr = reinterpret_cast<uint16_t*>(img->pixels + (height - y - 1) * img->rowPitch);
|
||||||
|
|
||||||
|
for (size_t x = 0; x < width; ++x)
|
||||||
|
{
|
||||||
|
if (bigendian)
|
||||||
|
{
|
||||||
|
dptr[0] = _byteswap_ushort(sptr[0]);
|
||||||
|
dptr[1] = _byteswap_ushort(sptr[1]);
|
||||||
|
dptr[2] = _byteswap_ushort(sptr[2]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dptr[0] = sptr[0];
|
||||||
|
dptr[1] = sptr[1];
|
||||||
|
dptr[2] = sptr[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
dptr[3] = 0x3c00; // 1.f
|
||||||
|
sptr += 3;
|
||||||
|
dptr += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
auto sptr = reinterpret_cast<const uint32_t*>(pData);
|
auto sptr = reinterpret_cast<const uint32_t*>(pData);
|
||||||
|
|
||||||
if (monochrome)
|
if (monochrome)
|
||||||
@ -523,11 +607,13 @@ HRESULT __cdecl LoadFromPortablePixMapHDR(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// We always save as PF or Pf as that's the most common PFM implementation.
|
||||||
HRESULT __cdecl SaveToPortablePixMapHDR(
|
HRESULT __cdecl SaveToPortablePixMapHDR(
|
||||||
_In_ const Image& image,
|
_In_ const Image& image,
|
||||||
_In_z_ const wchar_t* szFile) noexcept
|
_In_z_ const wchar_t* szFile) noexcept
|
||||||
|
Loading…
x
Reference in New Issue
Block a user