yuv.h revision 466727975bcc57c0c5597bcd0747a2fe4777b303
19aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// Copyright 2010 Google Inc.
29aea642eefa7a641ab8b89d953251939221d2719Eric Hassold//
39aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// This code is licensed under the same terms as WebM:
49aea642eefa7a641ab8b89d953251939221d2719Eric Hassold//  Software License Agreement:  http://www.webmproject.org/license/software/
59aea642eefa7a641ab8b89d953251939221d2719Eric Hassold//  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
69aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// -----------------------------------------------------------------------------
79aea642eefa7a641ab8b89d953251939221d2719Eric Hassold//
89aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// inline YUV->RGB conversion function
99aea642eefa7a641ab8b89d953251939221d2719Eric Hassold//
109aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// Author: Skal (pascal.massimino@gmail.com)
119aea642eefa7a641ab8b89d953251939221d2719Eric Hassold
1203d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora#ifndef WEBP_DEC_YUV_H_
1303d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora#define WEBP_DEC_YUV_H_
149aea642eefa7a641ab8b89d953251939221d2719Eric Hassold
159aea642eefa7a641ab8b89d953251939221d2719Eric Hassold#include "webp/decode_vp8.h"
169aea642eefa7a641ab8b89d953251939221d2719Eric Hassold
179aea642eefa7a641ab8b89d953251939221d2719Eric Hassold#if defined(__cplusplus) || defined(c_plusplus)
189aea642eefa7a641ab8b89d953251939221d2719Eric Hassoldextern "C" {
199aea642eefa7a641ab8b89d953251939221d2719Eric Hassold#endif
209aea642eefa7a641ab8b89d953251939221d2719Eric Hassold
219aea642eefa7a641ab8b89d953251939221d2719Eric Hassoldenum { YUV_FIX = 16,                // fixed-point precision
229aea642eefa7a641ab8b89d953251939221d2719Eric Hassold       YUV_RANGE_MIN = -227,        // min value of r/g/b output
239aea642eefa7a641ab8b89d953251939221d2719Eric Hassold       YUV_RANGE_MAX = 256 + 226    // max value of r/g/b output
249aea642eefa7a641ab8b89d953251939221d2719Eric Hassold};
259aea642eefa7a641ab8b89d953251939221d2719Eric Hassoldextern int16_t VP8kVToR[256], VP8kUToB[256];
269aea642eefa7a641ab8b89d953251939221d2719Eric Hassoldextern int32_t VP8kVToG[256], VP8kUToG[256];
279aea642eefa7a641ab8b89d953251939221d2719Eric Hassoldextern uint8_t VP8kClip[YUV_RANGE_MAX - YUV_RANGE_MIN];
28466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Aroraextern uint8_t VP8kClip4Bits[YUV_RANGE_MAX - YUV_RANGE_MIN];
299aea642eefa7a641ab8b89d953251939221d2719Eric Hassold
30466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arorastatic inline void VP8YuvToRgb(uint8_t y, uint8_t u, uint8_t v,
319aea642eefa7a641ab8b89d953251939221d2719Eric Hassold                               uint8_t* const rgb) {
329aea642eefa7a641ab8b89d953251939221d2719Eric Hassold  const int r_off = VP8kVToR[v];
339aea642eefa7a641ab8b89d953251939221d2719Eric Hassold  const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX;
349aea642eefa7a641ab8b89d953251939221d2719Eric Hassold  const int b_off = VP8kUToB[u];
359aea642eefa7a641ab8b89d953251939221d2719Eric Hassold  rgb[0] = VP8kClip[y + r_off - YUV_RANGE_MIN];
369aea642eefa7a641ab8b89d953251939221d2719Eric Hassold  rgb[1] = VP8kClip[y + g_off - YUV_RANGE_MIN];
379aea642eefa7a641ab8b89d953251939221d2719Eric Hassold  rgb[2] = VP8kClip[y + b_off - YUV_RANGE_MIN];
389aea642eefa7a641ab8b89d953251939221d2719Eric Hassold}
399aea642eefa7a641ab8b89d953251939221d2719Eric Hassold
40466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arorastatic inline void VP8YuvToRgb565(uint8_t y, uint8_t u, uint8_t v,
41466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora                                  uint8_t* const rgb) {
42466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora  const int r_off = VP8kVToR[v];
43466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora  const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX;
44466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora  const int b_off = VP8kUToB[u];
45466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora  rgb[0] = ((VP8kClip[y + r_off - YUV_RANGE_MIN] & 0xf8) |
46466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora            (VP8kClip[y + g_off - YUV_RANGE_MIN] >> 5));
47466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora  rgb[1] = (((VP8kClip[y + g_off - YUV_RANGE_MIN] << 3) & 0xe0) |
48466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora            (VP8kClip[y + b_off - YUV_RANGE_MIN] >> 3));
49466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora}
50466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora
51466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arorastatic inline void VP8YuvToArgbKeepA(uint8_t y, uint8_t u, uint8_t v,
52466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora                                     uint8_t* const argb) {
53466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora  // Don't update Aplha (argb[0])
54466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora  VP8YuvToRgb(y, u, v, argb + 1);
55466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora}
56466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora
57466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arorastatic inline void VP8YuvToArgb(uint8_t y, uint8_t u, uint8_t v,
58466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora                                uint8_t* const argb) {
59466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora  argb[0] = 0xff;
60466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora  VP8YuvToArgbKeepA(y, u, v, argb);
61466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora}
62466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora
63466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arorastatic inline void VP8YuvToRgba4444KeepA(uint8_t y, uint8_t u, uint8_t v,
64466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora                                         uint8_t* const argb) {
65466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora  const int r_off = VP8kVToR[v];
66466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora  const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX;
67466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora  const int b_off = VP8kUToB[u];
68466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora  // Don't update Aplha (last 4 bits of argb[1])
69466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora  argb[0] = ((VP8kClip4Bits[y + r_off - YUV_RANGE_MIN] << 4) |
70466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora             VP8kClip4Bits[y + g_off - YUV_RANGE_MIN]);
71466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora  argb[1] = (argb[1] & 0x0f) | (VP8kClip4Bits[y + b_off - YUV_RANGE_MIN] << 4);
72466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora}
73466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora
74466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arorastatic inline void VP8YuvToRgba4444(uint8_t y, uint8_t u, uint8_t v,
75466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora                                    uint8_t* const argb) {
76466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora  argb[1] = 0x0f;
77466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora  VP8YuvToRgba4444KeepA(y, u, v, argb);
789aea642eefa7a641ab8b89d953251939221d2719Eric Hassold}
799aea642eefa7a641ab8b89d953251939221d2719Eric Hassold
80466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arorastatic inline void VP8YuvToBgr(uint8_t y, uint8_t u, uint8_t v,
819aea642eefa7a641ab8b89d953251939221d2719Eric Hassold                               uint8_t* const bgr) {
829aea642eefa7a641ab8b89d953251939221d2719Eric Hassold  const int r_off = VP8kVToR[v];
839aea642eefa7a641ab8b89d953251939221d2719Eric Hassold  const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX;
849aea642eefa7a641ab8b89d953251939221d2719Eric Hassold  const int b_off = VP8kUToB[u];
859aea642eefa7a641ab8b89d953251939221d2719Eric Hassold  bgr[0] = VP8kClip[y + b_off - YUV_RANGE_MIN];
869aea642eefa7a641ab8b89d953251939221d2719Eric Hassold  bgr[1] = VP8kClip[y + g_off - YUV_RANGE_MIN];
879aea642eefa7a641ab8b89d953251939221d2719Eric Hassold  bgr[2] = VP8kClip[y + r_off - YUV_RANGE_MIN];
889aea642eefa7a641ab8b89d953251939221d2719Eric Hassold}
899aea642eefa7a641ab8b89d953251939221d2719Eric Hassold
90466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arorastatic inline void VP8YuvToBgra(uint8_t y, uint8_t u, uint8_t v,
91466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora                                uint8_t* const bgra) {
929aea642eefa7a641ab8b89d953251939221d2719Eric Hassold  VP8YuvToBgr(y, u, v, bgra);
939aea642eefa7a641ab8b89d953251939221d2719Eric Hassold  bgra[3] = 0xff;
949aea642eefa7a641ab8b89d953251939221d2719Eric Hassold}
959aea642eefa7a641ab8b89d953251939221d2719Eric Hassold
96466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arorastatic inline void VP8YuvToRgba(uint8_t y, uint8_t u, uint8_t v,
97466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora                                uint8_t* const rgba) {
98466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora  VP8YuvToRgb(y, u, v, rgba);
99466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora  rgba[3] = 0xff;
100466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora}
101466727975bcc57c0c5597bcd0747a2fe4777b303Vikas Arora
1029aea642eefa7a641ab8b89d953251939221d2719Eric Hassold// Must be called before everything, to initialize the tables.
10303d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Aroravoid VP8YUVInit(void);
1049aea642eefa7a641ab8b89d953251939221d2719Eric Hassold
1059aea642eefa7a641ab8b89d953251939221d2719Eric Hassold#if defined(__cplusplus) || defined(c_plusplus)
1069aea642eefa7a641ab8b89d953251939221d2719Eric Hassold}    // extern "C"
1079aea642eefa7a641ab8b89d953251939221d2719Eric Hassold#endif
1089aea642eefa7a641ab8b89d953251939221d2719Eric Hassold
10903d5e34c70f174c16282b0efdc6bb9473df5f8f1Vikas Arora#endif  // WEBP_DEC_YUV_H_
110