tor-browser

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

sharpyuv_csp.c (4083B)


      1 // Copyright 2022 Google Inc. All Rights Reserved.
      2 //
      3 // Use of this source code is governed by a BSD-style license
      4 // that can be found in the COPYING file in the root of the source
      5 // tree. An additional intellectual property rights grant can be found
      6 // in the file PATENTS. All contributing project authors may
      7 // be found in the AUTHORS file in the root of the source tree.
      8 // -----------------------------------------------------------------------------
      9 //
     10 // Colorspace utilities.
     11 
     12 #include "sharpyuv/sharpyuv_csp.h"
     13 
     14 #include <assert.h>
     15 #include <math.h>
     16 #include <stddef.h>
     17 
     18 #include "sharpyuv/sharpyuv.h"
     19 
     20 static int ToFixed16(float f) { return (int)floor(f * (1 << 16) + 0.5f); }
     21 
     22 void SharpYuvComputeConversionMatrix(const SharpYuvColorSpace* yuv_color_space,
     23                                     SharpYuvConversionMatrix* matrix) {
     24  const float kr = yuv_color_space->kr;
     25  const float kb = yuv_color_space->kb;
     26  const float kg = 1.0f - kr - kb;
     27  const float cb = 0.5f / (1.0f - kb);
     28  const float cr = 0.5f / (1.0f - kr);
     29 
     30  const int shift = yuv_color_space->bit_depth - 8;
     31 
     32  const float denom = (float)((1 << yuv_color_space->bit_depth) - 1);
     33  float scale_y = 1.0f;
     34  float add_y = 0.0f;
     35  float scale_u = cb;
     36  float scale_v = cr;
     37  float add_uv = (float)(128 << shift);
     38  assert(yuv_color_space->bit_depth >= 8);
     39 
     40  if (yuv_color_space->range == kSharpYuvRangeLimited) {
     41    scale_y *= (219 << shift) / denom;
     42    scale_u *= (224 << shift) / denom;
     43    scale_v *= (224 << shift) / denom;
     44    add_y = (float)(16 << shift);
     45  }
     46 
     47  matrix->rgb_to_y[0] = ToFixed16(kr * scale_y);
     48  matrix->rgb_to_y[1] = ToFixed16(kg * scale_y);
     49  matrix->rgb_to_y[2] = ToFixed16(kb * scale_y);
     50  matrix->rgb_to_y[3] = ToFixed16(add_y);
     51 
     52  matrix->rgb_to_u[0] = ToFixed16(-kr * scale_u);
     53  matrix->rgb_to_u[1] = ToFixed16(-kg * scale_u);
     54  matrix->rgb_to_u[2] = ToFixed16((1 - kb) * scale_u);
     55  matrix->rgb_to_u[3] = ToFixed16(add_uv);
     56 
     57  matrix->rgb_to_v[0] = ToFixed16((1 - kr) * scale_v);
     58  matrix->rgb_to_v[1] = ToFixed16(-kg * scale_v);
     59  matrix->rgb_to_v[2] = ToFixed16(-kb * scale_v);
     60  matrix->rgb_to_v[3] = ToFixed16(add_uv);
     61 }
     62 
     63 // Matrices are in YUV_FIX fixed point precision.
     64 // WebP's matrix, similar but not identical to kRec601LimitedMatrix
     65 // Derived using the following formulas:
     66 // Y = 0.2569 * R + 0.5044 * G + 0.0979 * B + 16
     67 // U = -0.1483 * R - 0.2911 * G + 0.4394 * B + 128
     68 // V = 0.4394 * R - 0.3679 * G - 0.0715 * B + 128
     69 static const SharpYuvConversionMatrix kWebpMatrix = {
     70  {16839, 33059, 6420, 16 << 16},
     71  {-9719, -19081, 28800, 128 << 16},
     72  {28800, -24116, -4684, 128 << 16},
     73 };
     74 // Kr=0.2990f Kb=0.1140f bit_depth=8 range=kSharpYuvRangeLimited
     75 static const SharpYuvConversionMatrix kRec601LimitedMatrix = {
     76  {16829, 33039, 6416, 16 << 16},
     77  {-9714, -19071, 28784, 128 << 16},
     78  {28784, -24103, -4681, 128 << 16},
     79 };
     80 // Kr=0.2990f Kb=0.1140f bit_depth=8 range=kSharpYuvRangeFull
     81 static const SharpYuvConversionMatrix kRec601FullMatrix = {
     82  {19595, 38470, 7471, 0},
     83  {-11058, -21710, 32768, 128 << 16},
     84  {32768, -27439, -5329, 128 << 16},
     85 };
     86 // Kr=0.2126f Kb=0.0722f bit_depth=8 range=kSharpYuvRangeLimited
     87 static const SharpYuvConversionMatrix kRec709LimitedMatrix = {
     88  {11966, 40254, 4064, 16 << 16},
     89  {-6596, -22189, 28784, 128 << 16},
     90  {28784, -26145, -2639, 128 << 16},
     91 };
     92 // Kr=0.2126f Kb=0.0722f bit_depth=8 range=kSharpYuvRangeFull
     93 static const SharpYuvConversionMatrix kRec709FullMatrix = {
     94  {13933, 46871, 4732, 0},
     95  {-7509, -25259, 32768, 128 << 16},
     96  {32768, -29763, -3005, 128 << 16},
     97 };
     98 
     99 const SharpYuvConversionMatrix* SharpYuvGetConversionMatrix(
    100    SharpYuvMatrixType matrix_type) {
    101  switch (matrix_type) {
    102    case kSharpYuvMatrixWebp:
    103      return &kWebpMatrix;
    104    case kSharpYuvMatrixRec601Limited:
    105      return &kRec601LimitedMatrix;
    106    case kSharpYuvMatrixRec601Full:
    107      return &kRec601FullMatrix;
    108    case kSharpYuvMatrixRec709Limited:
    109      return &kRec709LimitedMatrix;
    110    case kSharpYuvMatrixRec709Full:
    111      return &kRec709FullMatrix;
    112    case kSharpYuvMatrixNum:
    113      return NULL;
    114  }
    115  return NULL;
    116 }