Path: blob/master/thirdparty/libwebp/sharpyuv/sharpyuv_csp.c
21253 views
// Copyright 2022 Google Inc. All Rights Reserved.1//2// Use of this source code is governed by a BSD-style license3// that can be found in the COPYING file in the root of the source4// tree. An additional intellectual property rights grant can be found5// in the file PATENTS. All contributing project authors may6// be found in the AUTHORS file in the root of the source tree.7// -----------------------------------------------------------------------------8//9// Colorspace utilities.1011#include "sharpyuv/sharpyuv_csp.h"1213#include <assert.h>14#include <math.h>15#include <stddef.h>1617#include "sharpyuv/sharpyuv.h"1819static int ToFixed16(float f) { return (int)floor(f * (1 << 16) + 0.5f); }2021void SharpYuvComputeConversionMatrix(const SharpYuvColorSpace* yuv_color_space,22SharpYuvConversionMatrix* matrix) {23const float kr = yuv_color_space->kr;24const float kb = yuv_color_space->kb;25const float kg = 1.0f - kr - kb;26const float cb = 0.5f / (1.0f - kb);27const float cr = 0.5f / (1.0f - kr);2829const int shift = yuv_color_space->bit_depth - 8;3031const float denom = (float)((1 << yuv_color_space->bit_depth) - 1);32float scale_y = 1.0f;33float add_y = 0.0f;34float scale_u = cb;35float scale_v = cr;36float add_uv = (float)(128 << shift);37assert(yuv_color_space->bit_depth >= 8);3839if (yuv_color_space->range == kSharpYuvRangeLimited) {40scale_y *= (219 << shift) / denom;41scale_u *= (224 << shift) / denom;42scale_v *= (224 << shift) / denom;43add_y = (float)(16 << shift);44}4546matrix->rgb_to_y[0] = ToFixed16(kr * scale_y);47matrix->rgb_to_y[1] = ToFixed16(kg * scale_y);48matrix->rgb_to_y[2] = ToFixed16(kb * scale_y);49matrix->rgb_to_y[3] = ToFixed16(add_y);5051matrix->rgb_to_u[0] = ToFixed16(-kr * scale_u);52matrix->rgb_to_u[1] = ToFixed16(-kg * scale_u);53matrix->rgb_to_u[2] = ToFixed16((1 - kb) * scale_u);54matrix->rgb_to_u[3] = ToFixed16(add_uv);5556matrix->rgb_to_v[0] = ToFixed16((1 - kr) * scale_v);57matrix->rgb_to_v[1] = ToFixed16(-kg * scale_v);58matrix->rgb_to_v[2] = ToFixed16(-kb * scale_v);59matrix->rgb_to_v[3] = ToFixed16(add_uv);60}6162// Matrices are in YUV_FIX fixed point precision.63// WebP's matrix, similar but not identical to kRec601LimitedMatrix64// Derived using the following formulas:65// Y = 0.2569 * R + 0.5044 * G + 0.0979 * B + 1666// U = -0.1483 * R - 0.2911 * G + 0.4394 * B + 12867// V = 0.4394 * R - 0.3679 * G - 0.0715 * B + 12868static const SharpYuvConversionMatrix kWebpMatrix = {69{16839, 33059, 6420, 16 << 16},70{-9719, -19081, 28800, 128 << 16},71{28800, -24116, -4684, 128 << 16},72};73// Kr=0.2990f Kb=0.1140f bit_depth=8 range=kSharpYuvRangeLimited74static const SharpYuvConversionMatrix kRec601LimitedMatrix = {75{16829, 33039, 6416, 16 << 16},76{-9714, -19071, 28784, 128 << 16},77{28784, -24103, -4681, 128 << 16},78};79// Kr=0.2990f Kb=0.1140f bit_depth=8 range=kSharpYuvRangeFull80static const SharpYuvConversionMatrix kRec601FullMatrix = {81{19595, 38470, 7471, 0},82{-11058, -21710, 32768, 128 << 16},83{32768, -27439, -5329, 128 << 16},84};85// Kr=0.2126f Kb=0.0722f bit_depth=8 range=kSharpYuvRangeLimited86static const SharpYuvConversionMatrix kRec709LimitedMatrix = {87{11966, 40254, 4064, 16 << 16},88{-6596, -22189, 28784, 128 << 16},89{28784, -26145, -2639, 128 << 16},90};91// Kr=0.2126f Kb=0.0722f bit_depth=8 range=kSharpYuvRangeFull92static const SharpYuvConversionMatrix kRec709FullMatrix = {93{13933, 46871, 4732, 0},94{-7509, -25259, 32768, 128 << 16},95{32768, -29763, -3005, 128 << 16},96};9798const SharpYuvConversionMatrix* SharpYuvGetConversionMatrix(99SharpYuvMatrixType matrix_type) {100switch (matrix_type) {101case kSharpYuvMatrixWebp:102return &kWebpMatrix;103case kSharpYuvMatrixRec601Limited:104return &kRec601LimitedMatrix;105case kSharpYuvMatrixRec601Full:106return &kRec601FullMatrix;107case kSharpYuvMatrixRec709Limited:108return &kRec709LimitedMatrix;109case kSharpYuvMatrixRec709Full:110return &kRec709FullMatrix;111case kSharpYuvMatrixNum:112return NULL;113}114return NULL;115}116117118