Skip to content

Commit

Permalink
fix alpha detection
Browse files Browse the repository at this point in the history
  • Loading branch information
awxkee committed Oct 9, 2023
1 parent e76d25f commit c50ee40
Show file tree
Hide file tree
Showing 20 changed files with 681 additions and 162 deletions.
2 changes: 1 addition & 1 deletion Sources/avifc/AVIFImageXForm.mm
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ - (_Nullable CGImageRef)formCGImage:(nonnull avifDecoder*)decoder scale:(CGFloat
avifRGBImage rgbImage;
avifRGBImageSetDefaults(&rgbImage, decoder->image);

auto imageUsesAlpha = decoder->image->imageOwnsAlphaPlane;
auto imageUsesAlpha = decoder->image->imageOwnsAlphaPlane || decoder->image->alphaPlane != nullptr;

int components = imageUsesAlpha ? 4 : 3;

Expand Down
112 changes: 0 additions & 112 deletions Sources/avifc/Colorspace.h
Original file line number Diff line number Diff line change
Expand Up @@ -328,48 +328,6 @@ inline vector<float> Colorspace_Gamut_Conversion_DCIP3_to_709(const vector<float
return mul(convert_matrix_DCIP3_to_709, rgb);
}

static const std::vector<vector<float>> aces_input_matrix =
{
{0.59719f, 0.35458f, 0.04823f},
{0.07600f, 0.90834f, 0.01566f},
{0.02840f, 0.13383f, 0.83777f}
};

static const std::vector<vector<float>> aces_output_matrix =
{
{ 1.60475f, -0.53108f, -0.07367f},
{-0.10208f, 1.10813f, -0.00605f},
{-0.00327f, -0.07276f, 1.07602f}
};

vector<float> rtt_and_odt_fit(vector<float> v)
{
vector<float> a = add(mul(v, add(v, 0.0245786f)), - 0.000090537f);
vector<float> b = mul(mul(v, add(mul(v, 0.983729f), 0.4329510f)), 0.238081f);
return div(a, b);
}

vector<float> aces_approx(const vector<float>& v)
{
vector<float> r = mul(v, 0.6f);
float a = 2.51f;
float b = 0.03f;
float c = 2.43f;
float d = 0.59f;
float e = 0.14f;
auto num = mul(r,add(mul(r,a),b));
auto den = add(mul(r, add(mul(r, c), d)), e);
auto ret = clamp(div(num, den), 0.0f, 1.0f);
return ret;
}

vector<float> aces_fitted(vector<float>& v)
{
v = mul(aces_input_matrix, v);
v = rtt_and_odt_fit(v);
return mul(aces_output_matrix, v);
}

std::vector<float> acesFilmicToneMapping(const std::vector<float>& rgb) {
std::vector<float> result(3);
for (int i = 0; i < 3; ++i) {
Expand Down Expand Up @@ -419,33 +377,10 @@ std::vector<float> filmicUncharted3ToneMapping(const std::vector<float>& rgb) {
return result;
}

std::vector<float> reinhard(const std::vector<float>& rgb) {
return div(rgb, add(rgb, 1.0f));
}

float reinhard(const float v) {
return v / (1.0f + v);
}

inline float Luma(const vector<float>& v, const float* primaries) {
return v[0] * primaries[0] + v[1] * primaries[1] + v[2] * primaries[2];
}

vector<float> change_luminance(const vector<float>& c_in, float l_out, const float* primaries)
{
float l_in = Luma(c_in, primaries);
const float scale = l_out / l_in;
return { c_in[0]*scale, c_in[1]*scale, c_in[2]*scale };
}

vector<float> reinhard_extended_luminance(const vector<float>& v, float max_white_l, const float* primaries)
{
float l_old = Luma(v, primaries);
float numerator = l_old * (1.0f + (l_old / (max_white_l * max_white_l)));
float l_new = numerator / (1.0f + l_old);
return change_luminance(v, l_new, primaries);
}

template <typename T>
T lerp(const T& a, const T& b, float t) {
return a + t * (b - a);
Expand All @@ -458,51 +393,4 @@ vector<float> reinhard_jodie(const vector<float>& v, const float* primaries)
vector<float> res = { lerp(v[0] / (1.0f + l), tv[0], tv[0]), lerp(v[1] / (1.0f + l), tv[1], tv[1]), lerp(v[2] / (1.0f + l), tv[2], tv[2]) };
return res;
}

float uncharted2_tonemap_partial(float x)
{
float A = 0.15f;
float B = 0.50f;
float C = 0.10f;
float D = 0.20f;
float E = 0.02f;
float F = 0.30f;
return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;
}

float uncharted2_filmic(float v)
{
float exposure_bias = 2.0f;
float curr = uncharted2_tonemap_partial(v * exposure_bias);

float W = 11.2f;
float white_scale = 1.0f / uncharted2_tonemap_partial(W);
return curr * white_scale;
}


// Apply the Hable tone mapping operator to a single HDR pixel
inline float hableToneMapping(float x) {
const float A = 0.15f; // Shoulder Strength
const float B = 0.50f; // Linear Strength
const float C = 0.10f; // Linear Angle
const float D = 0.20f; // Toe Strength
const float E = 0.02f; // Toe Numerator
const float F = 0.30f; // Toe Denominator
return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;
}

inline float hable(float x)
{
const float A = 0.15, B = 0.50, C = 0.10, D = 0.20, E = 0.02, F = 0.30;

return ((x * (A * x + (C * B)) + (D * E)) / (x * (A * x + B) + (D * F))) - E / F;
}

inline float ToneMappingHable(const float rgb)
{
static const float HABLE_DIV = hable(4.8);
return hable(rgb) / HABLE_DIV;
}

#endif /* Colorspace_h */
11 changes: 10 additions & 1 deletion Sources/avifc/NEMath.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
#if __arm64__

#include <arm_neon.h>
#include <vector>
#include <array>

/* Logarithm polynomial coefficients */
const std::array<float32x4_t, 8> log_tab =
static const std::array<float32x4_t, 8> log_tab =
{
{
vdupq_n_f32(-2.29561495781f),
Expand Down Expand Up @@ -141,6 +143,13 @@ static inline float32x4_t vlogq_f32(float32x4_t x)
return poly;
}

static inline float32x4_t vlog10q_f32(float32x4_t x)
{
static const float32x4_t CONST_LN10 = vdupq_n_f32(2.30258509299); // ln(2)
const float32x4_t v = vlogq_f32(x);
return vdivq_f32(v, CONST_LN10);
}

__attribute__((always_inline))
static inline float32x4_t vpowq_f32(float32x4_t val, float32x4_t n)
{
Expand Down
40 changes: 15 additions & 25 deletions Sources/avifc/PerceptualQuantinizer.mm
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
#import "NEMath.h"

#import "Colorspace.h"
#import "Rec2408ToneMapper.hpp"
#import "ToneMap/Rec2408ToneMapper.hpp"
#import "half.hpp"

using namespace std;
Expand Down Expand Up @@ -96,10 +96,6 @@ inline TriStim ClipToWhite(TriStim* c, const float* primaries) {
return *c;
}

float Luma(float r, float g, float b, const float* primaries) {
return r * primaries[0] + g * primaries[1] + b * primaries[2];
}

float clampf(float value, float min, float max) {
return fmin(fmax(value, min), max);
}
Expand Down Expand Up @@ -128,7 +124,7 @@ inline half loadHalf(uint16_t t) {
return f;
}

void TransferROW_U16HFloats(uint16_t *data, PQGammaCorrection gammaCorrection, const float* primaries, Rec2408ToneMapper* toneMapper) {
void TransferROW_U16HFloats(uint16_t *data, PQGammaCorrection gammaCorrection, const float* primaries, ToneMapper* toneMapper) {
auto r = (float) loadHalf(data[0]);
auto g = (float) loadHalf(data[1]);
auto b = (float) loadHalf(data[2]);
Expand All @@ -138,7 +134,7 @@ void TransferROW_U16HFloats(uint16_t *data, PQGammaCorrection gammaCorrection, c
g = smpte.g;
b = smpte.b;

toneMapper->toneMap(r, g, b);
toneMapper->Execute(r, g, b);

if (gammaCorrection == Rec2020) {
data[0] = half(clamp(LinearRec2020ToRec2020(r), 0.0f, 1.0f)).data_;
Expand Down Expand Up @@ -209,7 +205,7 @@ inline float32x4_t GetPixelsRGBU8(const float32x4_t rgb, const float32x4_t maxCo
inline float32x4x4_t Transfer(float32x4_t rChan, float32x4_t gChan,
float32x4_t bChan,
PQGammaCorrection gammaCorrection,
Rec2408ToneMapper* toneMapper) {
ToneMapper* toneMapper) {
float32x4_t pqR = ToLinearPQ(rChan);
float32x4_t pqG = ToLinearPQ(gChan);
float32x4_t pqB = ToLinearPQ(bChan);
Expand All @@ -219,7 +215,7 @@ inline float32x4x4_t Transfer(float32x4_t rChan, float32x4_t gChan,
};
m = MatTransponseQF32(m);

float32x4x4_t r = toneMapper->toneMap(m);
float32x4x4_t r = toneMapper->Execute(m);

if (gammaCorrection == Rec2020) {
r.val[0] = vclampq_n_f32(LinearRec2020ToRec2020(r.val[0]), 0.0f, 1.0f);
Expand Down Expand Up @@ -256,7 +252,7 @@ void TransferROW_U16(uint16_t *data, float maxColors, PQGammaCorrection gammaCor
// data[2] = float_to_half((float) smpte.b * scale);
}

void TransferROW_U8(uint8_t *data, float maxColors, PQGammaCorrection gammaCorrection, Rec2408ToneMapper* toneMapper) {
void TransferROW_U8(uint8_t *data, float maxColors, PQGammaCorrection gammaCorrection, ToneMapper* toneMapper) {
auto r = (float) data[0] / (float) maxColors;
auto g = (float) data[1] / (float) maxColors;
auto b = (float) data[2] / (float) maxColors;
Expand All @@ -266,7 +262,7 @@ void TransferROW_U8(uint8_t *data, float maxColors, PQGammaCorrection gammaCorre
g = smpte.g;
b = smpte.b;

toneMapper->toneMap(r, g, b);
toneMapper->Execute(r, g, b);

if (gammaCorrection == Rec2020) {
r = LinearRec2020ToRec2020(r);
Expand All @@ -288,11 +284,9 @@ @implementation PerceptualQuantinizer : NSObject
#if __arm64__

+(void)transferNEONF16:(nonnull uint8_t*)data stride:(int)stride width:(int)width height:(int)height depth:(int)depth primaries:(float*)primaries
space:(PQGammaCorrection)space components:(int)components {
space:(PQGammaCorrection)space components:(int)components toneMapper:(ToneMapper*)toneMapper {
auto ptr = reinterpret_cast<uint8_t *>(data);

Rec2408ToneMapper* toneMapper = new Rec2408ToneMapper(1000.0f, 1.0f, sdrReferencePoint);

dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply(height, concurrentQueue, ^(size_t y) {

Expand Down Expand Up @@ -368,13 +362,12 @@ +(void)transferNEONF16:(nonnull uint8_t*)data stride:(int)stride width:(int)widt
ptr16 += components;
}
});

delete toneMapper;
}

+(void)transferNEONU8:(nonnull uint8_t*)data
stride:(int)stride width:(int)width height:(int)height depth:(int)depth
primaries:(float*)primaries space:(PQGammaCorrection)space components:(int)components {
primaries:(float*)primaries space:(PQGammaCorrection)space components:(int)components
toneMapper:(ToneMapper*)toneMapper {
auto ptr = reinterpret_cast<uint8_t *>(data);

const float32x4_t mask = {1.0f, 1.0f, 1.0f, 0.0};
Expand All @@ -386,8 +379,6 @@ +(void)transferNEONU8:(nonnull uint8_t*)data

const float32x4_t vMaxColors = vdupq_n_f32(maxColors);

Rec2408ToneMapper* toneMapper = new Rec2408ToneMapper(1000.0f, 1.0f, sdrReferencePoint);

dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply(height, concurrentQueue, ^(size_t y) {
auto ptr16 = reinterpret_cast<uint8_t *>(ptr + y * stride);
Expand Down Expand Up @@ -588,8 +579,6 @@ +(void)transferNEONU8:(nonnull uint8_t*)data
ptr16 += components;
}
});

delete toneMapper;
}
#endif

Expand Down Expand Up @@ -688,22 +677,23 @@ +(void)transfer:(nonnull uint8_t*)data stride:(int)stride width:(int)width heigh
U16:(bool)U16 depth:(int)depth half:(bool)half primaries:(float*)primaries
components:(int)components gammaCorrection:(PQGammaCorrection)gammaCorrection {
auto ptr = reinterpret_cast<uint8_t *>(data);
ToneMapper* toneMapper = new Rec2408ToneMapper(1000.0f, 1.0f, sdrReferencePoint);
#if __arm64__
if (U16 && half) {
[self transferNEONF16:reinterpret_cast<uint8_t*>(data) stride:stride width:width height:height
depth:depth primaries:primaries space:gammaCorrection components:components];
depth:depth primaries:primaries space:gammaCorrection components:components toneMapper:toneMapper];
delete toneMapper;
return;
}
if (!U16) {
[self transferNEONU8:reinterpret_cast<uint8_t*>(data) stride:stride width:width height:height
depth:depth primaries:primaries space:gammaCorrection components:components];
depth:depth primaries:primaries space:gammaCorrection components:components toneMapper:toneMapper];
delete toneMapper;
return;
}
#endif
auto maxColors = powf(2, (float) depth) - 1;

Rec2408ToneMapper* toneMapper = new Rec2408ToneMapper(1000.0f, 1.0f, sdrReferencePoint);

dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply(height, concurrentQueue, ^(size_t y) {
if (U16) {
Expand Down
Loading

0 comments on commit c50ee40

Please sign in to comment.