Skip to content

Commit 9708883

Browse files
committed
PngToExr
1 parent 2399617 commit 9708883

15 files changed

+375
-2
lines changed

Common/MLConverter.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,14 @@ Yuv10ToRgb10(
198198
// ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
199199
// ガンマカーブ
200200

201+
static float
202+
SRGBtoLinear(float v)
203+
{
204+
// Approximately pow(color, 2.2)
205+
v = v < 0.04045f ? v / 12.92f : pow(abs(v + 0.055f) / 1.055f, 2.4f);
206+
return v;
207+
}
208+
201209
static const float pq_m1 = 0.1593017578125f; // ( 2610.0 / 4096.0 ) / 4.0;
202210
static const float pq_m2 = 78.84375f; // ( 2523.0 / 4096.0 ) * 128.0;
203211
static const float pq_c1 = 0.8359375f; // 3424.0 / 4096.0 or pq_c3 - pq_c2 + 1.0;
@@ -864,6 +872,74 @@ MLConverter::R16G16B16A16ToR210(const uint16_t* pFrom, uint32_t* pTo, const int
864872
}
865873
}
866874

875+
876+
void
877+
MLConverter::R16G16B16A16ToExrHalfFloat(const uint16_t* pFrom, uint16_t* pTo, const int width, const int height)
878+
{
879+
#pragma omp parallel for
880+
for (int y = 0; y < height; ++y) {
881+
for (int x = 0; x < width; ++x) {
882+
const int pos = 4 * (x + y * width);
883+
884+
const float rF = ST2084toExrLinear(pFrom[pos + 0] / 65535.0f);
885+
const float gF = ST2084toExrLinear(pFrom[pos + 1] / 65535.0f);
886+
const float bF = ST2084toExrLinear(pFrom[pos + 2] / 65535.0f);
887+
const float aF = pFrom[pos + 3] / 65535.0f; //< アルファチャンネルは別の計算式。
888+
889+
const half& rH = rF;
890+
const half& gH = gF;
891+
const half& bH = bF;
892+
const half& aH = aF;
893+
894+
pTo[pos + 0] = rH.bits();
895+
pTo[pos + 1] = gH.bits();
896+
pTo[pos + 2] = bH.bits();
897+
pTo[pos + 3] = aH.bits();
898+
}
899+
}
900+
}
901+
902+
903+
void
904+
MLConverter::R8G8B8A8ToExrHalfFloat(
905+
const uint8_t* pFrom, uint16_t* pTo, const int width, const int height, QuantizationRange qr)
906+
{
907+
#pragma omp parallel for
908+
for (int y = 0; y < height; ++y) {
909+
for (int x = 0; x < width; ++x) {
910+
const int pos = 4 * (x + y * width);
911+
912+
uint8_t r = pFrom[pos + 0];
913+
uint8_t g = pFrom[pos + 1];
914+
uint8_t b = pFrom[pos + 2];
915+
uint8_t a = pFrom[pos + 3];
916+
917+
if (qr == QR_Limited) {
918+
r = (uint8_t)((r - 16) * 255 / 219);
919+
g = (uint8_t)((g - 16) * 255 / 219);
920+
b = (uint8_t)((b - 16) * 255 / 219);
921+
}
922+
923+
// Quantization range == full
924+
const float rF = SRGBtoLinear(r / 255.0f);
925+
const float gF = SRGBtoLinear(g / 255.0f);
926+
const float bF = SRGBtoLinear(b / 255.0f);
927+
const float aF = a / 255.0f; //< アルファチャンネルは別の計算式。
928+
929+
const half& rH = rF;
930+
const half& gH = gF;
931+
const half& bH = bF;
932+
const half& aH = aF;
933+
934+
pTo[pos + 0] = rH.bits();
935+
pTo[pos + 1] = gH.bits();
936+
pTo[pos + 2] = bH.bits();
937+
pTo[pos + 3] = aH.bits();
938+
}
939+
}
940+
}
941+
942+
867943
/// <summary>
868944
/// bmdFormat12BitRGB → DXGI_FORMAT_R8G8B8A8_UNORM
869945
/// </summary>

Common/MLConverter.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ class MLConverter {
1414
CS_Rec2020,
1515
};
1616

17+
enum QuantizationRange {
18+
QR_Full,
19+
QR_Limited,
20+
};
21+
1722
/// <summary>
1823
/// R8G8B8A8 to B8G8R8 for BMP save
1924
/// </summary>
@@ -93,6 +98,10 @@ class MLConverter {
9398
/// </summary>
9499
static void R16G16B16A16ToR210(const uint16_t* pFrom, uint32_t* pTo, const int width, const int height);
95100

101+
static void R16G16B16A16ToExrHalfFloat(const uint16_t* pFrom, uint16_t* pTo, const int width, const int height);
102+
static void R8G8B8A8ToExrHalfFloat(
103+
const uint8_t* pFrom, uint16_t* pTo, const int width, const int height, QuantizationRange qr);
104+
96105
void BMRawYuvV210ToRGBA(uint32_t* pFrom, uint32_t* pTo, const int width, const int height, const uint8_t alpha);
97106

98107
static void YuvV210ToYuvA(uint32_t* pFrom, uint32_t* pTo, const int width, const int height, const uint8_t alpha);

Common/MLExrWriter.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ MLExrWriter::Write(const char* exrFilePath, const MLImage2& img)
4444
buff = new uint8_t[buffBytes];
4545
memcpy(buff, img.data, buffBytes);
4646
break;
47+
case MLImage2::BFT_UIntR16G16B16A16:
48+
buff = new uint8_t[buffBytes];
49+
mConv.R16G16B16A16ToExrHalfFloat((uint16_t*)img.data, (uint16_t*)buff, img.width, img.height);
50+
break;
51+
case MLImage2::BFT_UIntR8G8B8A8:
52+
buff = new uint8_t[buffBytes];
53+
mConv.R8G8B8A8ToExrHalfFloat((uint8_t*)img.data, (uint16_t*)buff, img.width, img.height, (MLConverter::QuantizationRange)img.quantizationRange);
54+
break;
4755
default:
4856
// 作ってない。
4957
return E_NOTIMPL;

Common/MLImage2.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@ struct MLImage2 {
2929
MLG_HLG,
3030
};
3131

32+
/// <summary>
33+
/// MLConverter::QuantizationRangeと同じ。
34+
/// </summary>
35+
enum QuantizationRange {
36+
QR_Full,
37+
QR_Limited,
38+
};
39+
3240
/// <summary>
3341
/// new[]で確保して下さい。
3442
/// </summary>
@@ -41,6 +49,7 @@ struct MLImage2 {
4149
BitFormatType bitFormat = BFT_None;
4250
MLColorGamutType colorGamut = ML_CG_Rec709;
4351
GammaType gamma = MLG_G22;
52+
QuantizationRange quantizationRange = QR_Full;
4453

4554
/// <summary>
4655
/// ビットデプス。8bit, 10bit等。

HDR10Capture2019/HDR10Capture.sln

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MLDX12VideoCapture", "..\ML
1717
EndProject
1818
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MLDecklinkCapture", "..\MLDecklinkCapture\MLDecklinkCapture.vcxproj", "{9B2A14DC-4F72-4EB7-8DEB-B10D7BE0610C}"
1919
EndProject
20+
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PngToExr", "..\PngToExr\PngToExr.vcxproj", "{4C49B532-4946-47C3-AD29-90DDDAB2F45A}"
21+
EndProject
2022
Global
2123
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2224
Debug|x64 = Debug|x64
@@ -51,6 +53,10 @@ Global
5153
{9B2A14DC-4F72-4EB7-8DEB-B10D7BE0610C}.Debug|x64.Build.0 = Debug|x64
5254
{9B2A14DC-4F72-4EB7-8DEB-B10D7BE0610C}.Release|x64.ActiveCfg = Release|x64
5355
{9B2A14DC-4F72-4EB7-8DEB-B10D7BE0610C}.Release|x64.Build.0 = Release|x64
56+
{4C49B532-4946-47C3-AD29-90DDDAB2F45A}.Debug|x64.ActiveCfg = Debug|x64
57+
{4C49B532-4946-47C3-AD29-90DDDAB2F45A}.Debug|x64.Build.0 = Debug|x64
58+
{4C49B532-4946-47C3-AD29-90DDDAB2F45A}.Release|x64.ActiveCfg = Release|x64
59+
{4C49B532-4946-47C3-AD29-90DDDAB2F45A}.Release|x64.Build.0 = Release|x64
5460
EndGlobalSection
5561
GlobalSection(SolutionProperties) = preSolution
5662
HideSolutionNode = FALSE

HDR10Capture2019/HDR10Capture.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
<ClInclude Include="..\Common\MLVideoCapUser.h" />
3232
<ClInclude Include="..\Common\MLWinApp.h" />
3333
<ClInclude Include="MainApp.h" />
34+
<ClInclude Include="MLColorConvShaderConstants.h" />
3435
<ClInclude Include="resource.h" />
3536
</ItemGroup>
3637
<ItemGroup>

HDR10Capture2019/HDR10Capture.vcxproj.filters

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@
147147
<ClInclude Include="..\Common\MLWinApp.h">
148148
<Filter>Common</Filter>
149149
</ClInclude>
150+
<ClInclude Include="MLColorConvShaderConstants.h">
151+
<Filter>Sources</Filter>
152+
</ClInclude>
150153
</ItemGroup>
151154
<ItemGroup>
152155
<CustomBuild Include="shaderColorConvPS.hlsl">

Common/MLColorConvShaderConstants.h renamed to HDR10Capture2019/MLColorConvShaderConstants.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ struct MLColorConvShaderConstants {
88
DirectX::XMMATRIX colorConvMat;
99
DirectX::XMFLOAT4 outOfRangeColor;
1010
int imgGammaType; //< MLImage2::GammaType
11-
int flags; //< FlagsType
11+
int flags; //< FlagsType. 1=HighlightOutOfRange, 2=SwapRedBlue, 4=Limited Range
1212
float outOfRangeNits;
1313
float scale;
1414

1515
enum FlagsType {
1616
FLAG_OutOfRangeColor = 1,
1717
FLAG_SwapRedBlue = 2,
18+
FLAG_LimitedRange = 4,
1819
};
1920
};
2021

HDR10Capture2019/MainApp.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1417,6 +1417,18 @@ MainApp::ShowSettingsWindow(void) {
14171417
}
14181418
}
14191419

1420+
if (ImGui::TreeNodeEx("Image Quantization Range (Set Full for HDR)", ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_CollapsingHeader)) {
1421+
int cg = 0 != (mShaderConsts.flags & MLColorConvShaderConstants::FLAG_LimitedRange);
1422+
ImGui::RadioButton("Full ##ICG", &cg, 0);
1423+
ImGui::RadioButton("Limited ##ICG", &cg, 1);
1424+
1425+
if (cg) {
1426+
mShaderConsts.flags |= MLColorConvShaderConstants::FLAG_LimitedRange;
1427+
} else {
1428+
mShaderConsts.flags = mShaderConsts.flags & (~MLColorConvShaderConstants::FLAG_LimitedRange);
1429+
}
1430+
}
1431+
14201432
if (ImGui::TreeNodeEx("Image Color Gamut", ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_CollapsingHeader)) {
14211433
//ImGui::Text("Color Gamut is %s", MLColorGamutToStr(img.colorGamut));
14221434

HDR10Capture2019/shaderColorConvPS.hlsl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,17 @@ float3 ST2084_to_scRGB_Linear(float3 rgb) {
100100
return L * pq_C * (1.0f / 80.0f);
101101
}
102102

103+
float3 ProcessQuantizationRange(float3 v)
104+
{
105+
if ((c_flags & 4) != 0)
106+
{
107+
// Limited to Full
108+
v = (v - 16.0f/255.0f) * 255.0f / 219.0f;
109+
}
110+
111+
return v;
112+
}
113+
103114
float3 ApplyGamma(float3 rgb) {
104115
if (c_gammaType == 0) {
105116
// MLG_Linear : 100nits == 1.0
@@ -144,6 +155,8 @@ float4 PSMain(PSInput input) : SV_TARGET
144155

145156
rgba = SwapRedBlue(rgba);
146157

158+
rgba.rgb = ProcessQuantizationRange(rgba.rgb);
159+
147160
rgba.rgb = ApplyGamma(rgba.rgb);
148161

149162
rgba = mul(rgba, c_mat);

0 commit comments

Comments
 (0)