tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

alpha.cc (3933B)


      1 // Copyright (c) the JPEG XL Project Authors. All rights reserved.
      2 //
      3 // Use of this source code is governed by a BSD-style
      4 // license that can be found in the LICENSE file.
      5 
      6 #include "lib/jxl/alpha.h"
      7 
      8 #include <string.h>
      9 
     10 #include <algorithm>
     11 
     12 namespace jxl {
     13 
     14 static float Clamp(float x) { return std::max(std::min(1.0f, x), 0.0f); }
     15 
     16 void PerformAlphaBlending(const AlphaBlendingInputLayer& bg,
     17                          const AlphaBlendingInputLayer& fg,
     18                          const AlphaBlendingOutput& out, size_t num_pixels,
     19                          bool alpha_is_premultiplied, bool clamp) {
     20  if (alpha_is_premultiplied) {
     21    for (size_t x = 0; x < num_pixels; ++x) {
     22      float fga = clamp ? Clamp(fg.a[x]) : fg.a[x];
     23      out.r[x] = (fg.r[x] + bg.r[x] * (1.f - fga));
     24      out.g[x] = (fg.g[x] + bg.g[x] * (1.f - fga));
     25      out.b[x] = (fg.b[x] + bg.b[x] * (1.f - fga));
     26      out.a[x] = (1.f - (1.f - fga) * (1.f - bg.a[x]));
     27    }
     28  } else {
     29    for (size_t x = 0; x < num_pixels; ++x) {
     30      float fga = clamp ? Clamp(fg.a[x]) : fg.a[x];
     31      const float new_a = 1.f - (1.f - fga) * (1.f - bg.a[x]);
     32      const float rnew_a = (new_a > 0 ? 1.f / new_a : 0.f);
     33      out.r[x] = (fg.r[x] * fga + bg.r[x] * bg.a[x] * (1.f - fga)) * rnew_a;
     34      out.g[x] = (fg.g[x] * fga + bg.g[x] * bg.a[x] * (1.f - fga)) * rnew_a;
     35      out.b[x] = (fg.b[x] * fga + bg.b[x] * bg.a[x] * (1.f - fga)) * rnew_a;
     36      out.a[x] = new_a;
     37    }
     38  }
     39 }
     40 void PerformAlphaBlending(const float* bg, const float* bga, const float* fg,
     41                          const float* fga, float* out, size_t num_pixels,
     42                          bool alpha_is_premultiplied, bool clamp) {
     43  if (bg == bga && fg == fga) {
     44    for (size_t x = 0; x < num_pixels; ++x) {
     45      float fa = clamp ? fga[x] : Clamp(fga[x]);
     46      out[x] = (1.f - (1.f - fa) * (1.f - bga[x]));
     47    }
     48  } else {
     49    if (alpha_is_premultiplied) {
     50      for (size_t x = 0; x < num_pixels; ++x) {
     51        float fa = clamp ? fga[x] : Clamp(fga[x]);
     52        out[x] = (fg[x] + bg[x] * (1.f - fa));
     53      }
     54    } else {
     55      for (size_t x = 0; x < num_pixels; ++x) {
     56        float fa = clamp ? fga[x] : Clamp(fga[x]);
     57        const float new_a = 1.f - (1.f - fa) * (1.f - bga[x]);
     58        const float rnew_a = (new_a > 0 ? 1.f / new_a : 0.f);
     59        out[x] = (fg[x] * fa + bg[x] * bga[x] * (1.f - fa)) * rnew_a;
     60      }
     61    }
     62  }
     63 }
     64 
     65 void PerformAlphaWeightedAdd(const float* bg, const float* fg, const float* fga,
     66                             float* out, size_t num_pixels, bool clamp) {
     67  if (fg == fga) {
     68    memcpy(out, bg, num_pixels * sizeof(*out));
     69  } else if (clamp) {
     70    for (size_t x = 0; x < num_pixels; ++x) {
     71      out[x] = bg[x] + fg[x] * Clamp(fga[x]);
     72    }
     73  } else {
     74    for (size_t x = 0; x < num_pixels; ++x) {
     75      out[x] = bg[x] + fg[x] * fga[x];
     76    }
     77  }
     78 }
     79 
     80 void PerformMulBlending(const float* bg, const float* fg, float* out,
     81                        size_t num_pixels, bool clamp) {
     82  if (clamp) {
     83    for (size_t x = 0; x < num_pixels; ++x) {
     84      out[x] = bg[x] * Clamp(fg[x]);
     85    }
     86  } else {
     87    for (size_t x = 0; x < num_pixels; ++x) {
     88      out[x] = bg[x] * fg[x];
     89    }
     90  }
     91 }
     92 
     93 void PremultiplyAlpha(float* JXL_RESTRICT r, float* JXL_RESTRICT g,
     94                      float* JXL_RESTRICT b, const float* JXL_RESTRICT a,
     95                      size_t num_pixels) {
     96  for (size_t x = 0; x < num_pixels; ++x) {
     97    const float multiplier = std::max(kSmallAlpha, a[x]);
     98    r[x] *= multiplier;
     99    g[x] *= multiplier;
    100    b[x] *= multiplier;
    101  }
    102 }
    103 
    104 void UnpremultiplyAlpha(float* JXL_RESTRICT r, float* JXL_RESTRICT g,
    105                        float* JXL_RESTRICT b, const float* JXL_RESTRICT a,
    106                        size_t num_pixels) {
    107  for (size_t x = 0; x < num_pixels; ++x) {
    108    const float multiplier = 1.f / std::max(kSmallAlpha, a[x]);
    109    r[x] *= multiplier;
    110    g[x] *= multiplier;
    111    b[x] *= multiplier;
    112  }
    113 }
    114 
    115 }  // namespace jxl