• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2010 Google Inc.
2 //
3 // This code is licensed under the same terms as WebM:
4 //  Software License Agreement:  http://www.webmproject.org/license/software/
5 //  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
6 // -----------------------------------------------------------------------------
7 //
8 // inline YUV->RGB conversion function
9 //
10 // Author: Skal (pascal.massimino@gmail.com)
11 
12 #ifndef WEBP_DEC_YUV_H_
13 #define WEBP_DEC_YUV_H_
14 
15 #include "webp/decode_vp8.h"
16 
17 /*
18  * Define ANDROID_WEBP_RGB to enable specific optimizations for Android
19  * RGBA_4444 & RGB_565 color support.
20  *
21  */
22 
23 #define ANDROID_WEBP_RGB
24 
25 #if defined(__cplusplus) || defined(c_plusplus)
26 extern "C" {
27 #endif
28 
29 enum { YUV_FIX = 16,                // fixed-point precision
30        YUV_RANGE_MIN = -227,        // min value of r/g/b output
31        YUV_RANGE_MAX = 256 + 226    // max value of r/g/b output
32 };
33 extern int16_t VP8kVToR[256], VP8kUToB[256];
34 extern int32_t VP8kVToG[256], VP8kUToG[256];
35 extern uint8_t VP8kClip[YUV_RANGE_MAX - YUV_RANGE_MIN];
36 extern uint8_t VP8kClip4Bits[YUV_RANGE_MAX - YUV_RANGE_MIN];
37 
VP8YuvToRgb(uint8_t y,uint8_t u,uint8_t v,uint8_t * const rgb)38 static inline void VP8YuvToRgb(uint8_t y, uint8_t u, uint8_t v,
39                                uint8_t* const rgb) {
40   const int r_off = VP8kVToR[v];
41   const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX;
42   const int b_off = VP8kUToB[u];
43   rgb[0] = VP8kClip[y + r_off - YUV_RANGE_MIN];
44   rgb[1] = VP8kClip[y + g_off - YUV_RANGE_MIN];
45   rgb[2] = VP8kClip[y + b_off - YUV_RANGE_MIN];
46 }
47 
VP8YuvToRgb565(uint8_t y,uint8_t u,uint8_t v,uint8_t * const rgb)48 static inline void VP8YuvToRgb565(uint8_t y, uint8_t u, uint8_t v,
49                                   uint8_t* const rgb) {
50   const int r_off = VP8kVToR[v];
51   const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX;
52   const int b_off = VP8kUToB[u];
53 #ifdef ANDROID_WEBP_RGB
54   rgb[1] = ((VP8kClip[y + r_off - YUV_RANGE_MIN] & 0xf8) |
55             (VP8kClip[y + g_off - YUV_RANGE_MIN] >> 5));
56   rgb[0] = (((VP8kClip[y + g_off - YUV_RANGE_MIN] << 3) & 0xe0) |
57             (VP8kClip[y + b_off - YUV_RANGE_MIN] >> 3));
58 #else
59   rgb[0] = ((VP8kClip[y + r_off - YUV_RANGE_MIN] & 0xf8) |
60             (VP8kClip[y + g_off - YUV_RANGE_MIN] >> 5));
61   rgb[1] = (((VP8kClip[y + g_off - YUV_RANGE_MIN] << 3) & 0xe0) |
62             (VP8kClip[y + b_off - YUV_RANGE_MIN] >> 3));
63 #endif
64 }
65 
VP8YuvToArgbKeepA(uint8_t y,uint8_t u,uint8_t v,uint8_t * const argb)66 static inline void VP8YuvToArgbKeepA(uint8_t y, uint8_t u, uint8_t v,
67                                      uint8_t* const argb) {
68   // Don't update Aplha (argb[0])
69   VP8YuvToRgb(y, u, v, argb + 1);
70 }
71 
VP8YuvToArgb(uint8_t y,uint8_t u,uint8_t v,uint8_t * const argb)72 static inline void VP8YuvToArgb(uint8_t y, uint8_t u, uint8_t v,
73                                 uint8_t* const argb) {
74   argb[0] = 0xff;
75   VP8YuvToArgbKeepA(y, u, v, argb);
76 }
77 
VP8YuvToRgba4444KeepA(uint8_t y,uint8_t u,uint8_t v,uint8_t * const argb)78 static inline void VP8YuvToRgba4444KeepA(uint8_t y, uint8_t u, uint8_t v,
79                                          uint8_t* const argb) {
80   const int r_off = VP8kVToR[v];
81   const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX;
82   const int b_off = VP8kUToB[u];
83 #ifdef ANDROID_WEBP_RGB
84   argb[1] = ((VP8kClip4Bits[y + r_off - YUV_RANGE_MIN] << 4) |
85              VP8kClip4Bits[y + g_off - YUV_RANGE_MIN]);
86   argb[0] = (argb[0] & 0x0f) | (VP8kClip4Bits[y + b_off - YUV_RANGE_MIN] << 4);
87 #else
88   argb[0] = ((VP8kClip4Bits[y + r_off - YUV_RANGE_MIN] << 4) |
89              VP8kClip4Bits[y + g_off - YUV_RANGE_MIN]);
90   argb[1] = (argb[1] & 0x0f) | (VP8kClip4Bits[y + b_off - YUV_RANGE_MIN] << 4);
91 #endif
92 }
93 
VP8YuvToRgba4444(uint8_t y,uint8_t u,uint8_t v,uint8_t * const argb)94 static inline void VP8YuvToRgba4444(uint8_t y, uint8_t u, uint8_t v,
95                                     uint8_t* const argb) {
96 #ifdef ANDROID_WEBP_RGB
97   argb[0] = 0x0f;
98 #else
99   argb[1] = 0x0f;
100 #endif
101   VP8YuvToRgba4444KeepA(y, u, v, argb);
102 }
103 
VP8YuvToBgr(uint8_t y,uint8_t u,uint8_t v,uint8_t * const bgr)104 static inline void VP8YuvToBgr(uint8_t y, uint8_t u, uint8_t v,
105                                uint8_t* const bgr) {
106   const int r_off = VP8kVToR[v];
107   const int g_off = (VP8kVToG[v] + VP8kUToG[u]) >> YUV_FIX;
108   const int b_off = VP8kUToB[u];
109   bgr[0] = VP8kClip[y + b_off - YUV_RANGE_MIN];
110   bgr[1] = VP8kClip[y + g_off - YUV_RANGE_MIN];
111   bgr[2] = VP8kClip[y + r_off - YUV_RANGE_MIN];
112 }
113 
VP8YuvToBgra(uint8_t y,uint8_t u,uint8_t v,uint8_t * const bgra)114 static inline void VP8YuvToBgra(uint8_t y, uint8_t u, uint8_t v,
115                                 uint8_t* const bgra) {
116   VP8YuvToBgr(y, u, v, bgra);
117   bgra[3] = 0xff;
118 }
119 
VP8YuvToRgba(uint8_t y,uint8_t u,uint8_t v,uint8_t * const rgba)120 static inline void VP8YuvToRgba(uint8_t y, uint8_t u, uint8_t v,
121                                 uint8_t* const rgba) {
122   VP8YuvToRgb(y, u, v, rgba);
123   rgba[3] = 0xff;
124 }
125 
126 // Must be called before everything, to initialize the tables.
127 void VP8YUVInit(void);
128 
129 #if defined(__cplusplus) || defined(c_plusplus)
130 }    // extern "C"
131 #endif
132 
133 #endif  // WEBP_DEC_YUV_H_
134