-
-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add preliminary support for loading HDR images
The Netflix HDR sample images are loading correctly. Currently the HDR support is limited to SMPTE ST 2084 (BT.2100 PQ). It is unclear how the HDR support should work with premultiplied alpha images. I filed an issue in the av1-avif repository for clarification on that: AOMediaCodec/av1-avif#197
- Loading branch information
1 parent
2cdb582
commit 21e4fb5
Showing
14 changed files
with
951 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
/* | ||
* This file is part of avif-format, an AV1 Image (AVIF) file format | ||
* plug-in for Adobe Photoshop(R). | ||
* | ||
* Copyright (c) 2021, 2022 Nicholas Hayes | ||
* | ||
* avif-format is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU Lesser General Public License as | ||
* published by the Free Software Foundation, either version 3 of | ||
* the License, or (at your option) any later version. | ||
* | ||
* avif-format is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public License | ||
* along with avif-format. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#include "ColorTransfer.h" | ||
#include <stdexcept> | ||
|
||
namespace | ||
{ | ||
// The sRGB reference viewing environment has a maximum luminance level of 80 nits | ||
// See the 'Screen luminance level' value in the sRGB reference viewing environment table | ||
// https://en.wikipedia.org/wiki/SRGB#Viewing_environment | ||
constexpr float srgbMaxLuminanceLevel = 80.0f; | ||
// PQ (SMPTE ST 2084) has a maximum luminance level of 10000 nits | ||
// https://en.wikipedia.org/wiki/Perceptual_quantizer | ||
constexpr float pqMaxLuminanceLevel = 10000; | ||
|
||
inline float LinearToPQ(float normalizedLinearValue) | ||
{ | ||
// These constant values are taken from the Perceptual quantizer article on Wikipedia | ||
// https://en.wikipedia.org/wiki/Perceptual_quantizer | ||
constexpr float m1 = 2610.0f / 16384.0f; | ||
constexpr float m2 = 2523.0f / 4096.0f * 128.0f; | ||
constexpr float c1 = 3424.0f / 4096.0f; // c3 - c2 + 1 | ||
constexpr float c2 = 2413.0f / 4096.0f * 32.0f; | ||
constexpr float c3 = 2392.0f / 4096.0f * 32.0f; | ||
|
||
if (normalizedLinearValue < 0.0f) | ||
{ | ||
return 0.0f; | ||
} | ||
|
||
const float x = powf(normalizedLinearValue, m1); | ||
const float pq = powf((c1 + c2 * x) / (1.0f + c3 * x), m2); | ||
|
||
return pq; | ||
} | ||
|
||
inline float PQToLinear(float value) | ||
{ | ||
// These constant values are taken from the Perceptual quantizer article on Wikipedia | ||
// https://en.wikipedia.org/wiki/Perceptual_quantizer | ||
constexpr float m1 = 2610.0f / 16384.0f; | ||
constexpr float m2 = 2523.0f / 4096.0f * 128.0f; | ||
constexpr float c1 = 3424.0f / 4096.0f; // c3 - c2 + 1 | ||
constexpr float c2 = 2413.0f / 4096.0f * 32.0f; | ||
constexpr float c3 = 2392.0f / 4096.0f * 32.0f; | ||
|
||
if (value < 0.0f) | ||
{ | ||
return 0.0f; | ||
} | ||
|
||
const float x = powf(value, 1.0f / m2); | ||
const float normalizedLinear = powf(std::max(x - c1, 0.0f) / (c2 - c3 * x), 1.0f / m1); | ||
|
||
// We have to adjust for the difference in the maximum luminance level between | ||
// PQ and sRGB, otherwise the image is too dark. | ||
return normalizedLinear * (pqMaxLuminanceLevel / srgbMaxLuminanceLevel); | ||
} | ||
} | ||
|
||
float TransferCurveToLinear(float value, ColorTransferCurveType curveType) | ||
{ | ||
switch (curveType) | ||
{ | ||
case ColorTransferCurveType::PQ: | ||
return PQToLinear(value); | ||
default: | ||
throw std::runtime_error("Unsupported color transfer curve type."); | ||
} | ||
} | ||
|
||
float LinearToTransferCurve(float value, ColorTransferCurveType curveType) | ||
{ | ||
switch (curveType) | ||
{ | ||
case ColorTransferCurveType::PQ: | ||
return LinearToPQ(value); | ||
default: | ||
throw std::runtime_error("Unsupported color transfer curve type."); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* | ||
* This file is part of avif-format, an AV1 Image (AVIF) file format | ||
* plug-in for Adobe Photoshop(R). | ||
* | ||
* Copyright (c) 2021, 2022 Nicholas Hayes | ||
* | ||
* avif-format is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU Lesser General Public License as | ||
* published by the Free Software Foundation, either version 3 of | ||
* the License, or (at your option) any later version. | ||
* | ||
* avif-format is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public License | ||
* along with avif-format. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#ifndef COLORTRANSFER_H | ||
#define COLORTRANSFER_H | ||
|
||
#include <algorithm> | ||
#include <math.h> | ||
|
||
enum class ColorTransferCurveType | ||
{ | ||
PQ | ||
}; | ||
|
||
float TransferCurveToLinear(float value, ColorTransferCurveType curveType); | ||
|
||
float LinearToTransferCurve(float value, ColorTransferCurveType curveType); | ||
|
||
#endif // !COLORTRANSFER_H |
Oops, something went wrong.