1a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// Copyright 2010 Google Inc. All Rights Reserved.
29aea642eefa7a641ab8b89d953251939221d2719Eric Hassold//
30406ce1417f76f2034833414dcecc9f56253640cVikas Arora// Use of this source code is governed by a BSD-style license
40406ce1417f76f2034833414dcecc9f56253640cVikas Arora// that can be found in the COPYING file in the root of the source
50406ce1417f76f2034833414dcecc9f56253640cVikas Arora// tree. An additional intellectual property rights grant can be found
60406ce1417f76f2034833414dcecc9f56253640cVikas Arora// in the file PATENTS. All contributing project authors may
70406ce1417f76f2034833414dcecc9f56253640cVikas Arora// be found in the AUTHORS file in the root of the source tree.
89aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// -----------------------------------------------------------------------------
99aea642eefa7a641ab8b89d953251939221d2719Eric Hassold//
10a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// inline YUV<->RGB conversion function
119aea642eefa7a641ab8b89d953251939221d2719Eric Hassold//
121e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora// The exact naming is Y'CbCr, following the ITU-R BT.601 standard.
131e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora// More information at: http://en.wikipedia.org/wiki/YCbCr
141e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora// Y = 0.2569 * R + 0.5044 * G + 0.0979 * B + 16
151e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora// U = -0.1483 * R - 0.2911 * G + 0.4394 * B + 128
161e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora// V = 0.4394 * R - 0.3679 * G - 0.0715 * B + 128
178b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora// We use 16bit fixed point operations for RGB->YUV conversion (YUV_FIX).
181e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora//
191e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora// For the Y'CbCr to RGB conversion, the BT.601 specification reads:
201e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora//   R = 1.164 * (Y-16) + 1.596 * (V-128)
211e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora//   G = 1.164 * (Y-16) - 0.813 * (V-128) - 0.391 * (U-128)
221e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora//   B = 1.164 * (Y-16)                   + 2.018 * (U-128)
231e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora// where Y is in the [16,235] range, and U/V in the [16,240] range.
241e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora//
257c8da7ce66017295a65ec028084b90800be377f8James Zern// The fixed-point implementation used here is:
267c8da7ce66017295a65ec028084b90800be377f8James Zern//  R = (19077 . y             + 26149 . v - 14234) >> 6
277c8da7ce66017295a65ec028084b90800be377f8James Zern//  G = (19077 . y -  6419 . u - 13320 . v +  8708) >> 6
287c8da7ce66017295a65ec028084b90800be377f8James Zern//  B = (19077 . y + 33050 . u             - 17685) >> 6
297c8da7ce66017295a65ec028084b90800be377f8James Zern// where the '.' operator is the mulhi_epu16 variant:
307c8da7ce66017295a65ec028084b90800be377f8James Zern//   a . b = ((a << 8) * b) >> 16
317c8da7ce66017295a65ec028084b90800be377f8James Zern// that preserves 8 bits of fractional precision before final descaling.
327c8da7ce66017295a65ec028084b90800be377f8James Zern
339aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// Author: Skal (pascal.massimino@gmail.com)
349aea642eefa7a641ab8b89d953251939221d2719Eric Hassold
35a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#ifndef WEBP_DSP_YUV_H_
36a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#define WEBP_DSP_YUV_H_
379aea642eefa7a641ab8b89d953251939221d2719Eric Hassold
388b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora#include "./dsp.h"
39fa39824bb690c5806358871f46940d0450973d8aJames Zern#include "../dec/vp8_dec.h"
409aea642eefa7a641ab8b89d953251939221d2719Eric Hassold
411e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora#if defined(WEBP_EXPERIMENTAL_FEATURES)
421e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora// Do NOT activate this feature for real compression. This is only experimental!
431e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora// This flag is for comparison purpose against JPEG's "YUVj" natural colorspace.
441e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora// This colorspace is close to Rec.601's Y'CbCr model with the notable
451e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora// difference of allowing larger range for luma/chroma.
461e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora// See http://en.wikipedia.org/wiki/YCbCr#JPEG_conversion paragraph, and its
471e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora// difference with http://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.601_conversion
481e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora// #define USE_YUVj
491e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora#endif
5088fe2b83c4b9232cd08729556fd0485d6a6a92cdVikas Arora
51a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------
52a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// YUV -> RGB conversion
53a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
548b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora#ifdef __cplusplus
559aea642eefa7a641ab8b89d953251939221d2719Eric Hassoldextern "C" {
569aea642eefa7a641ab8b89d953251939221d2719Eric Hassold#endif
579aea642eefa7a641ab8b89d953251939221d2719Eric Hassold
588b720228d581a84fd173b6dcb2fa295b59db489aVikas Aroraenum {
598b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  YUV_FIX = 16,                    // fixed-point precision for RGB->YUV
608b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  YUV_HALF = 1 << (YUV_FIX - 1),
618b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  YUV_MASK = (256 << YUV_FIX) - 1,
628b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  YUV_RANGE_MIN = -227,            // min value of r/g/b output
638b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  YUV_RANGE_MAX = 256 + 226,       // max value of r/g/b output
648b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora
657c8da7ce66017295a65ec028084b90800be377f8James Zern  YUV_FIX2 = 6,                   // fixed-point precision for YUV->RGB
667c8da7ce66017295a65ec028084b90800be377f8James Zern  YUV_HALF2 = 1 << YUV_FIX2 >> 1,
678b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  YUV_MASK2 = (256 << YUV_FIX2) - 1
689aea642eefa7a641ab8b89d953251939221d2719Eric Hassold};
690406ce1417f76f2034833414dcecc9f56253640cVikas Arora
708b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora//------------------------------------------------------------------------------
717c8da7ce66017295a65ec028084b90800be377f8James Zern// slower on x86 by ~7-8%, but bit-exact with the SSE2/NEON version
728b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora
737c8da7ce66017295a65ec028084b90800be377f8James Zernstatic WEBP_INLINE int MultHi(int v, int coeff) {   // _mm_mulhi_epu16 emulation
747c8da7ce66017295a65ec028084b90800be377f8James Zern  return (v * coeff) >> 8;
757c8da7ce66017295a65ec028084b90800be377f8James Zern}
768b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora
778b720228d581a84fd173b6dcb2fa295b59db489aVikas Arorastatic WEBP_INLINE int VP8Clip8(int v) {
788b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  return ((v & ~YUV_MASK2) == 0) ? (v >> YUV_FIX2) : (v < 0) ? 0 : 255;
798b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora}
808b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora
818b720228d581a84fd173b6dcb2fa295b59db489aVikas Arorastatic WEBP_INLINE int VP8YUVToR(int y, int v) {
827c8da7ce66017295a65ec028084b90800be377f8James Zern  return VP8Clip8(MultHi(y, 19077) + MultHi(v, 26149) - 14234);
838b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora}
848b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora
858b720228d581a84fd173b6dcb2fa295b59db489aVikas Arorastatic WEBP_INLINE int VP8YUVToG(int y, int u, int v) {
867c8da7ce66017295a65ec028084b90800be377f8James Zern  return VP8Clip8(MultHi(y, 19077) - MultHi(u, 6419) - MultHi(v, 13320) + 8708);
878b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora}
888b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora
898b720228d581a84fd173b6dcb2fa295b59db489aVikas Arorastatic WEBP_INLINE int VP8YUVToB(int y, int u) {
907c8da7ce66017295a65ec028084b90800be377f8James Zern  return VP8Clip8(MultHi(y, 19077) + MultHi(u, 33050) - 17685);
918b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora}
929aea642eefa7a641ab8b89d953251939221d2719Eric Hassold
938b720228d581a84fd173b6dcb2fa295b59db489aVikas Arorastatic WEBP_INLINE void VP8YuvToRgb(int y, int u, int v,
94a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora                                    uint8_t* const rgb) {
958b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  rgb[0] = VP8YUVToR(y, v);
968b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  rgb[1] = VP8YUVToG(y, u, v);
978b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  rgb[2] = VP8YUVToB(y, u);
989aea642eefa7a641ab8b89d953251939221d2719Eric Hassold}
999aea642eefa7a641ab8b89d953251939221d2719Eric Hassold
1008b720228d581a84fd173b6dcb2fa295b59db489aVikas Arorastatic WEBP_INLINE void VP8YuvToBgr(int y, int u, int v,
1010406ce1417f76f2034833414dcecc9f56253640cVikas Arora                                    uint8_t* const bgr) {
1028b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  bgr[0] = VP8YUVToB(y, u);
1038b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  bgr[1] = VP8YUVToG(y, u, v);
1048b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  bgr[2] = VP8YUVToR(y, v);
1050406ce1417f76f2034833414dcecc9f56253640cVikas Arora}
1060406ce1417f76f2034833414dcecc9f56253640cVikas Arora
1078b720228d581a84fd173b6dcb2fa295b59db489aVikas Arorastatic WEBP_INLINE void VP8YuvToRgb565(int y, int u, int v,
108a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora                                       uint8_t* const rgb) {
1098b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  const int r = VP8YUVToR(y, v);      // 5 usable bits
1108b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  const int g = VP8YUVToG(y, u, v);   // 6 usable bits
1118b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  const int b = VP8YUVToB(y, u);      // 5 usable bits
1128b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  const int rg = (r & 0xf8) | (g >> 5);
1138b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  const int gb = ((g << 3) & 0xe0) | (b >> 3);
1141e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora#ifdef WEBP_SWAP_16BIT_CSP
1151e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  rgb[0] = gb;
1161e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  rgb[1] = rg;
11788fe2b83c4b9232cd08729556fd0485d6a6a92cdVikas Arora#else
1181e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  rgb[0] = rg;
1191e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  rgb[1] = gb;
12088fe2b83c4b9232cd08729556fd0485d6a6a92cdVikas Arora#endif
121466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora}
122466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora
1238b720228d581a84fd173b6dcb2fa295b59db489aVikas Arorastatic WEBP_INLINE void VP8YuvToRgba4444(int y, int u, int v,
124466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora                                         uint8_t* const argb) {
1258b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  const int r = VP8YUVToR(y, v);        // 4 usable bits
1268b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  const int g = VP8YUVToG(y, u, v);     // 4 usable bits
1278b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  const int b = VP8YUVToB(y, u);        // 4 usable bits
1288b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  const int rg = (r & 0xf0) | (g >> 4);
1298b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  const int ba = (b & 0xf0) | 0x0f;     // overwrite the lower 4 bits
1301e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora#ifdef WEBP_SWAP_16BIT_CSP
1311e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  argb[0] = ba;
1321e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  argb[1] = rg;
13388fe2b83c4b9232cd08729556fd0485d6a6a92cdVikas Arora#else
1341e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  argb[0] = rg;
1351e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  argb[1] = ba;
13688fe2b83c4b9232cd08729556fd0485d6a6a92cdVikas Arora#endif
1379aea642eefa7a641ab8b89d953251939221d2719Eric Hassold}
1389aea642eefa7a641ab8b89d953251939221d2719Eric Hassold
1398b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora//-----------------------------------------------------------------------------
1408b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora// Alpha handling variants
1418b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora
1420406ce1417f76f2034833414dcecc9f56253640cVikas Arorastatic WEBP_INLINE void VP8YuvToArgb(uint8_t y, uint8_t u, uint8_t v,
1430406ce1417f76f2034833414dcecc9f56253640cVikas Arora                                     uint8_t* const argb) {
1440406ce1417f76f2034833414dcecc9f56253640cVikas Arora  argb[0] = 0xff;
1450406ce1417f76f2034833414dcecc9f56253640cVikas Arora  VP8YuvToRgb(y, u, v, argb + 1);
1469aea642eefa7a641ab8b89d953251939221d2719Eric Hassold}
1479aea642eefa7a641ab8b89d953251939221d2719Eric Hassold
148a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arorastatic WEBP_INLINE void VP8YuvToBgra(uint8_t y, uint8_t u, uint8_t v,
149a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora                                     uint8_t* const bgra) {
1509aea642eefa7a641ab8b89d953251939221d2719Eric Hassold  VP8YuvToBgr(y, u, v, bgra);
1519aea642eefa7a641ab8b89d953251939221d2719Eric Hassold  bgra[3] = 0xff;
1529aea642eefa7a641ab8b89d953251939221d2719Eric Hassold}
1539aea642eefa7a641ab8b89d953251939221d2719Eric Hassold
154a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arorastatic WEBP_INLINE void VP8YuvToRgba(uint8_t y, uint8_t u, uint8_t v,
155a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora                                     uint8_t* const rgba) {
156466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora  VP8YuvToRgb(y, u, v, rgba);
157466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora  rgba[3] = 0xff;
158466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora}
159466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora
1609aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// Must be called before everything, to initialize the tables.
16103d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Aroravoid VP8YUVInit(void);
1629aea642eefa7a641ab8b89d953251939221d2719Eric Hassold
1638b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora//-----------------------------------------------------------------------------
1648b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora// SSE2 extra functions (mostly for upsampling_sse2.c)
1658b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora
1668b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora#if defined(WEBP_USE_SSE2)
1678b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora
1687c8da7ce66017295a65ec028084b90800be377f8James Zern// Process 32 pixels and store the result (16b, 24b or 32b per pixel) in *dst.
1698b720228d581a84fd173b6dcb2fa295b59db489aVikas Aroravoid VP8YuvToRgba32(const uint8_t* y, const uint8_t* u, const uint8_t* v,
1708b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora                    uint8_t* dst);
1718b720228d581a84fd173b6dcb2fa295b59db489aVikas Aroravoid VP8YuvToRgb32(const uint8_t* y, const uint8_t* u, const uint8_t* v,
1728b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora                   uint8_t* dst);
1738b720228d581a84fd173b6dcb2fa295b59db489aVikas Aroravoid VP8YuvToBgra32(const uint8_t* y, const uint8_t* u, const uint8_t* v,
1748b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora                    uint8_t* dst);
1758b720228d581a84fd173b6dcb2fa295b59db489aVikas Aroravoid VP8YuvToBgr32(const uint8_t* y, const uint8_t* u, const uint8_t* v,
1768b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora                   uint8_t* dst);
1777c8da7ce66017295a65ec028084b90800be377f8James Zernvoid VP8YuvToArgb32(const uint8_t* y, const uint8_t* u, const uint8_t* v,
1787c8da7ce66017295a65ec028084b90800be377f8James Zern                    uint8_t* dst);
1797c8da7ce66017295a65ec028084b90800be377f8James Zernvoid VP8YuvToRgba444432(const uint8_t* y, const uint8_t* u, const uint8_t* v,
1807c8da7ce66017295a65ec028084b90800be377f8James Zern                        uint8_t* dst);
1817c8da7ce66017295a65ec028084b90800be377f8James Zernvoid VP8YuvToRgb56532(const uint8_t* y, const uint8_t* u, const uint8_t* v,
1827c8da7ce66017295a65ec028084b90800be377f8James Zern                      uint8_t* dst);
1838b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora
1848b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora#endif    // WEBP_USE_SSE2
1858b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora
186a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora//------------------------------------------------------------------------------
187a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora// RGB -> YUV conversion
188a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
1898b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora// Stub functions that can be called with various rounding values:
1908b720228d581a84fd173b6dcb2fa295b59db489aVikas Arorastatic WEBP_INLINE int VP8ClipUV(int uv, int rounding) {
1918b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  uv = (uv + rounding + (128 << (YUV_FIX + 2))) >> (YUV_FIX + 2);
1928b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  return ((uv & ~0xff) == 0) ? uv : (uv < 0) ? 0 : 255;
193a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
194a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
1951e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora#ifndef USE_YUVj
1961e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora
1978b720228d581a84fd173b6dcb2fa295b59db489aVikas Arorastatic WEBP_INLINE int VP8RGBToY(int r, int g, int b, int rounding) {
198a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora  const int luma = 16839 * r + 33059 * g + 6420 * b;
1998b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  return (luma + rounding + (16 << YUV_FIX)) >> YUV_FIX;  // no need to clip
200a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
201a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
2028b720228d581a84fd173b6dcb2fa295b59db489aVikas Arorastatic WEBP_INLINE int VP8RGBToU(int r, int g, int b, int rounding) {
2031e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  const int u = -9719 * r - 19081 * g + 28800 * b;
2048b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  return VP8ClipUV(u, rounding);
2051e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora}
2061e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora
2078b720228d581a84fd173b6dcb2fa295b59db489aVikas Arorastatic WEBP_INLINE int VP8RGBToV(int r, int g, int b, int rounding) {
2081e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  const int v = +28800 * r - 24116 * g - 4684 * b;
2098b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  return VP8ClipUV(v, rounding);
2101e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora}
2111e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora
2121e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora#else
2131e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora
2141e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora// This JPEG-YUV colorspace, only for comparison!
2158b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora// These are also 16bit precision coefficients from Rec.601, but with full
2161e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora// [0..255] output range.
2178b720228d581a84fd173b6dcb2fa295b59db489aVikas Arorastatic WEBP_INLINE int VP8RGBToY(int r, int g, int b, int rounding) {
2181e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  const int luma = 19595 * r + 38470 * g + 7471 * b;
2198b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  return (luma + rounding) >> YUV_FIX;  // no need to clip
2201e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora}
2211e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora
22233f74dabbc7920a65ed435d7417987589febdc16Vikas Arorastatic WEBP_INLINE int VP8RGBToU(int r, int g, int b, int rounding) {
2231e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  const int u = -11058 * r - 21710 * g + 32768 * b;
2248b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  return VP8ClipUV(u, rounding);
225a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
226a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
22733f74dabbc7920a65ed435d7417987589febdc16Vikas Arorastatic WEBP_INLINE int VP8RGBToV(int r, int g, int b, int rounding) {
2281e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora  const int v = 32768 * r - 27439 * g - 5329 * b;
2298b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora  return VP8ClipUV(v, rounding);
230a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora}
231a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora
2321e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora#endif    // USE_YUVj
2331e7bf8805bd030c19924a5306837ecd72c295751Vikas Arora
2348b720228d581a84fd173b6dcb2fa295b59db489aVikas Arora#ifdef __cplusplus
2359aea642eefa7a641ab8b89d953251939221d2719Eric Hassold}    // extern "C"
2369aea642eefa7a641ab8b89d953251939221d2719Eric Hassold#endif
2379aea642eefa7a641ab8b89d953251939221d2719Eric Hassold
238a2415724fb3466168b2af5b08bd94ba732c0e753Vikas Arora#endif  /* WEBP_DSP_YUV_H_ */
239