// Copyright (c) the JPEG XL Project Authors. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file.
// color is linear, but blending happens in gamma-compressed space using // (gamma-compressed) grayscale background color, alpha image represents // weights of the sRGB colors in the [0 .. (1 << bit_depth) - 1] interval, // output image is in linear space. void AlphaBlend(const Image3F& in, const size_t c, float background_linear, const ImageF& alpha, Image3F* out) { constfloat background = LinearToSrgb8Direct(background_linear);
for (size_t y = 0; y < out->ysize(); ++y) { constfloat* JXL_RESTRICT row_a = alpha.ConstRow(y); constfloat* JXL_RESTRICT row_i = in.ConstPlaneRow(c, y); float* JXL_RESTRICT row_o = out->PlaneRow(c, y); for (size_t x = 0; x < out->xsize(); ++x) { constfloat a = row_a[x]; if (a <= 0.f) {
row_o[x] = background_linear;
} elseif (a >= 1.f) {
row_o[x] = row_i[x];
} else { constfloat w_fg = a; constfloat w_bg = 1.0f - w_fg; constfloat fg = w_fg * LinearToSrgb8Direct(row_i[x]); constfloat bg = w_bg * background;
row_o[x] = Srgb8ToLinearDirect(fg + bg);
}
}
}
}
void AlphaBlend(float background_linear, ImageBundle* io_linear_srgb) { // No alpha => all opaque. if (!io_linear_srgb->HasAlpha()) return;
for (size_t c = 0; c < 3; ++c) {
AlphaBlend(*io_linear_srgb->color(), c, background_linear,
*io_linear_srgb->alpha(), io_linear_srgb->color());
}
}
Status ComputeScore(const ImageBundle& rgb0, const ImageBundle& rgb1,
Comparator* comparator, const JxlCmsInterface& cms, float* score, ImageF* diffmap, ThreadPool* pool, bool ignore_alpha) {
JxlMemoryManager* memory_manager = rgb0.memory_manager(); // Convert to linear sRGB (unless already in that space)
ImageMetadata metadata0 = *rgb0.metadata();
ImageBundle store0(memory_manager, &metadata0); const ImageBundle* linear_srgb0;
JXL_RETURN_IF_ERROR(
TransformIfNeeded(rgb0, ColorEncoding::LinearSRGB(rgb0.IsGray()), cms,
pool, &store0, &linear_srgb0));
ImageMetadata metadata1 = *rgb1.metadata();
ImageBundle store1(memory_manager, &metadata1); const ImageBundle* linear_srgb1;
JXL_RETURN_IF_ERROR(
TransformIfNeeded(rgb1, ColorEncoding::LinearSRGB(rgb1.IsGray()), cms,
pool, &store1, &linear_srgb1));
// No alpha: skip blending, only need a single call to Butteraugli. if (ignore_alpha || (!rgb0.HasAlpha() && !rgb1.HasAlpha())) {
JXL_RETURN_IF_ERROR(ComputeScoreImpl(*linear_srgb0, *linear_srgb1,
comparator, diffmap, *score)); returntrue;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.