Coverage Report

Created: 2025-06-16 07:00

/src/libwebp/sharpyuv/sharpyuv_csp.c
Line
Count
Source (jump to first uncovered line)
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
0
static int ToFixed16(float f) { return (int)floor(f * (1 << 16) + 0.5f); }
21
22
void SharpYuvComputeConversionMatrix(const SharpYuvColorSpace* yuv_color_space,
23
0
                                     SharpYuvConversionMatrix* matrix) {
24
0
  const float kr = yuv_color_space->kr;
25
0
  const float kb = yuv_color_space->kb;
26
0
  const float kg = 1.0f - kr - kb;
27
0
  const float cb = 0.5f / (1.0f - kb);
28
0
  const float cr = 0.5f / (1.0f - kr);
29
30
0
  const int shift = yuv_color_space->bit_depth - 8;
31
32
0
  const float denom = (float)((1 << yuv_color_space->bit_depth) - 1);
33
0
  float scale_y = 1.0f;
34
0
  float add_y = 0.0f;
35
0
  float scale_u = cb;
36
0
  float scale_v = cr;
37
0
  float add_uv = (float)(128 << shift);
38
0
  assert(yuv_color_space->bit_depth >= 8);
39
40
0
  if (yuv_color_space->range == kSharpYuvRangeLimited) {
41
0
    scale_y *= (219 << shift) / denom;
42
0
    scale_u *= (224 << shift) / denom;
43
0
    scale_v *= (224 << shift) / denom;
44
0
    add_y = (float)(16 << shift);
45
0
  }
46
47
0
  matrix->rgb_to_y[0] = ToFixed16(kr * scale_y);
48
0
  matrix->rgb_to_y[1] = ToFixed16(kg * scale_y);
49
0
  matrix->rgb_to_y[2] = ToFixed16(kb * scale_y);
50
0
  matrix->rgb_to_y[3] = ToFixed16(add_y);
51
52
0
  matrix->rgb_to_u[0] = ToFixed16(-kr * scale_u);
53
0
  matrix->rgb_to_u[1] = ToFixed16(-kg * scale_u);
54
0
  matrix->rgb_to_u[2] = ToFixed16((1 - kb) * scale_u);
55
0
  matrix->rgb_to_u[3] = ToFixed16(add_uv);
56
57
0
  matrix->rgb_to_v[0] = ToFixed16((1 - kr) * scale_v);
58
0
  matrix->rgb_to_v[1] = ToFixed16(-kg * scale_v);
59
0
  matrix->rgb_to_v[2] = ToFixed16(-kb * scale_v);
60
0
  matrix->rgb_to_v[3] = ToFixed16(add_uv);
61
0
}
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
0
    SharpYuvMatrixType matrix_type) {
101
0
  switch (matrix_type) {
102
0
    case kSharpYuvMatrixWebp:
103
0
      return &kWebpMatrix;
104
0
    case kSharpYuvMatrixRec601Limited:
105
0
      return &kRec601LimitedMatrix;
106
0
    case kSharpYuvMatrixRec601Full:
107
0
      return &kRec601FullMatrix;
108
0
    case kSharpYuvMatrixRec709Limited:
109
0
      return &kRec709LimitedMatrix;
110
0
    case kSharpYuvMatrixRec709Full:
111
0
      return &kRec709FullMatrix;
112
0
    case kSharpYuvMatrixNum:
113
0
      return NULL;
114
0
  }
115
0
  return NULL;
116
0
}