Home | History | Annotate | Download | only in util
      1 /**************************************************************************
      2  *
      3  * Copyright 2010 VMware, Inc.
      4  * All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the
      8  * "Software"), to deal in the Software without restriction, including
      9  * without limitation the rights to use, copy, modify, merge, publish,
     10  * distribute, sub license, and/or sell copies of the Software, and to
     11  * permit persons to whom the Software is furnished to do so, subject to
     12  * the following conditions:
     13  *
     14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
     17  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
     18  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     19  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     20  * USE OR OTHER DEALINGS IN THE SOFTWARE.
     21  *
     22  * The above copyright notice and this permission notice (including the
     23  * next paragraph) shall be included in all copies or substantial portions
     24  * of the Software.
     25  *
     26  **************************************************************************/
     27 
     28 
     29 /**
     30  * @file
     31  * YUV colorspace conversion.
     32  *
     33  * @author Brian Paul <brianp (at) vmware.com>
     34  * @author Michal Krol <michal (at) vmware.com>
     35  * @author Jose Fonseca <jfonseca (at) vmware.com>
     36  *
     37  * See also:
     38  * - http://www.fourcc.org/fccyvrgb.php
     39  * - http://msdn.microsoft.com/en-us/library/ms893078
     40  * - http://en.wikipedia.org/wiki/YUV
     41  */
     42 
     43 
     44 #ifndef U_FORMAT_YUV_H_
     45 #define U_FORMAT_YUV_H_
     46 
     47 
     48 #include "pipe/p_compiler.h"
     49 #include "u_math.h"
     50 
     51 
     52 /*
     53  * TODO: Ensure we use consistent and right floating formulas, with enough
     54  * precision in the coefficients.
     55  */
     56 
     57 static inline void
     58 util_format_rgb_float_to_yuv(float r, float g, float b,
     59                              uint8_t *y, uint8_t *u, uint8_t *v)
     60 {
     61    const float _r = CLAMP(r, 0.0f, 1.0f);
     62    const float _g = CLAMP(g, 0.0f, 1.0f);
     63    const float _b = CLAMP(b, 0.0f, 1.0f);
     64 
     65    const float scale = 255.0f;
     66 
     67    const int _y = scale * ( (0.257f * _r) + (0.504f * _g) + (0.098f * _b));
     68    const int _u = scale * (-(0.148f * _r) - (0.291f * _g) + (0.439f * _b));
     69    const int _v = scale * ( (0.439f * _r) - (0.368f * _g) - (0.071f * _b));
     70 
     71    *y = _y + 16;
     72    *u = _u + 128;
     73    *v = _v + 128;
     74 }
     75 
     76 
     77 static inline void
     78 util_format_yuv_to_rgb_float(uint8_t y, uint8_t u, uint8_t v,
     79                              float *r, float *g, float *b)
     80 {
     81    const int _y = y - 16;
     82    const int _u = u - 128;
     83    const int _v = v - 128;
     84 
     85    const float y_factor = 255.0f / 219.0f;
     86 
     87    const float scale = 1.0f / 255.0f;
     88 
     89    *r = scale * (y_factor * _y               + 1.596f * _v);
     90    *g = scale * (y_factor * _y - 0.391f * _u - 0.813f * _v);
     91    *b = scale * (y_factor * _y + 2.018f * _u              );
     92 }
     93 
     94 
     95 static inline void
     96 util_format_rgb_8unorm_to_yuv(uint8_t r, uint8_t g, uint8_t b,
     97                 	      uint8_t *y, uint8_t *u, uint8_t *v)
     98 {
     99    *y = ((  66 * r + 129 * g +  25 * b + 128) >> 8) +  16;
    100    *u = (( -38 * r -  74 * g + 112 * b + 128) >> 8) + 128;
    101    *v = (( 112 * r -  94 * g -  18 * b + 128) >> 8) + 128;
    102 }
    103 
    104 
    105 static inline void
    106 util_format_yuv_to_rgb_8unorm(uint8_t y, uint8_t u, uint8_t v,
    107                               uint8_t *r, uint8_t *g, uint8_t *b)
    108 {
    109    const int _y = y - 16;
    110    const int _u = u - 128;
    111    const int _v = v - 128;
    112 
    113    const int _r = (298 * _y            + 409 * _v + 128) >> 8;
    114    const int _g = (298 * _y - 100 * _u - 208 * _v + 128) >> 8;
    115    const int _b = (298 * _y + 516 * _u            + 128) >> 8;
    116 
    117    *r = CLAMP(_r, 0, 255);
    118    *g = CLAMP(_g, 0, 255);
    119    *b = CLAMP(_b, 0, 255);
    120 }
    121 
    122 
    123 
    124 void
    125 util_format_uyvy_unpack_rgba_float(float *dst_row, unsigned dst_stride,
    126                               const uint8_t *src_row, unsigned src_stride,
    127                               unsigned width, unsigned height);
    128 
    129 void
    130 util_format_uyvy_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    131                                const uint8_t *src_row, unsigned src_stride,
    132                                unsigned width, unsigned height);
    133 
    134 void
    135 util_format_uyvy_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
    136                             const float *src_row, unsigned src_stride,
    137                             unsigned width, unsigned height);
    138 
    139 void
    140 util_format_uyvy_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    141                              const uint8_t *src_row, unsigned src_stride,
    142                              unsigned width, unsigned height);
    143 
    144 void
    145 util_format_uyvy_fetch_rgba_float(float *dst, const uint8_t *src,
    146                              unsigned i, unsigned j);
    147 
    148 void
    149 util_format_yuyv_unpack_rgba_float(float *dst_row, unsigned dst_stride,
    150                               const uint8_t *src_row, unsigned src_stride,
    151                               unsigned width, unsigned height);
    152 
    153 void
    154 util_format_yuyv_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    155                                const uint8_t *src_row, unsigned src_stride,
    156                                unsigned width, unsigned height);
    157 
    158 void
    159 util_format_yuyv_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
    160                             const float *src_row, unsigned src_stride,
    161                             unsigned width, unsigned height);
    162 
    163 void
    164 util_format_yuyv_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    165                              const uint8_t *src_row, unsigned src_stride,
    166                              unsigned width, unsigned height);
    167 
    168 void
    169 util_format_yuyv_fetch_rgba_float(float *dst, const uint8_t *src,
    170                              unsigned i, unsigned j);
    171 
    172 /* XXX: Stubbed for now */
    173 void
    174 util_format_yv12_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    175                              const uint8_t *src_row, unsigned src_stride,
    176                              unsigned width, unsigned height);
    177 void
    178 util_format_yv12_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    179                              const uint8_t *src_row, unsigned src_stride,
    180                              unsigned width, unsigned height);
    181 void
    182 util_format_yv12_unpack_rgba_float(float *dst_row, unsigned dst_stride,
    183                              const uint8_t *src_row, unsigned src_stride,
    184                              unsigned width, unsigned height);
    185 void
    186 util_format_yv12_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
    187                              const float *src_row, unsigned src_stride,
    188                              unsigned width, unsigned height);
    189 void
    190 util_format_yv12_fetch_rgba_float(float *dst, const uint8_t *src,
    191                              unsigned i, unsigned j);
    192 void
    193 util_format_yv16_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    194                              const uint8_t *src_row, unsigned src_stride,
    195                              unsigned width, unsigned height);
    196 void
    197 util_format_yv16_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    198                              const uint8_t *src_row, unsigned src_stride,
    199                              unsigned width, unsigned height);
    200 void
    201 util_format_yv16_unpack_rgba_float(float *dst_row, unsigned dst_stride,
    202                              const uint8_t *src_row, unsigned src_stride,
    203                              unsigned width, unsigned height);
    204 void
    205 util_format_yv16_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
    206                              const float *src_row, unsigned src_stride,
    207                              unsigned width, unsigned height);
    208 void
    209 util_format_yv16_fetch_rgba_float(float *dst, const uint8_t *src,
    210                              unsigned i, unsigned j);
    211 void
    212 util_format_iyuv_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    213                              const uint8_t *src_row, unsigned src_stride,
    214                              unsigned width, unsigned height);
    215 void
    216 util_format_iyuv_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    217                              const uint8_t *src_row, unsigned src_stride,
    218                              unsigned width, unsigned height);
    219 void
    220 util_format_iyuv_unpack_rgba_float(float *dst_row, unsigned dst_stride,
    221                              const uint8_t *src_row, unsigned src_stride,
    222                              unsigned width, unsigned height);
    223 void
    224 util_format_iyuv_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
    225                              const float *src_row, unsigned src_stride,
    226                              unsigned width, unsigned height);
    227 void
    228 util_format_iyuv_fetch_rgba_float(float *dst, const uint8_t *src,
    229                              unsigned i, unsigned j);
    230 void
    231 util_format_nv12_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    232                              const uint8_t *src_row, unsigned src_stride,
    233                              unsigned width, unsigned height);
    234 void
    235 util_format_nv12_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    236                              const uint8_t *src_row, unsigned src_stride,
    237                              unsigned width, unsigned height);
    238 void
    239 util_format_nv12_unpack_rgba_float(float *dst_row, unsigned dst_stride,
    240                              const uint8_t *src_row, unsigned src_stride,
    241                              unsigned width, unsigned height);
    242 void
    243 util_format_nv12_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
    244                              const float *src_row, unsigned src_stride,
    245                              unsigned width, unsigned height);
    246 void
    247 util_format_nv12_fetch_rgba_float(float *dst, const uint8_t *src,
    248                              unsigned i, unsigned j);
    249 void
    250 util_format_nv21_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    251                              const uint8_t *src_row, unsigned src_stride,
    252                              unsigned width, unsigned height);
    253 void
    254 util_format_nv21_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    255                              const uint8_t *src_row, unsigned src_stride,
    256                              unsigned width, unsigned height);
    257 void
    258 util_format_nv21_unpack_rgba_float(float *dst_row, unsigned dst_stride,
    259                              const uint8_t *src_row, unsigned src_stride,
    260                              unsigned width, unsigned height);
    261 void
    262 util_format_nv21_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
    263                              const float *src_row, unsigned src_stride,
    264                              unsigned width, unsigned height);
    265 void
    266 util_format_nv21_fetch_rgba_float(float *dst, const uint8_t *src,
    267                              unsigned i, unsigned j);
    268 void
    269 util_format_r8g8_b8g8_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride,
    270                                          const uint8_t *src_row, unsigned src_stride,
    271                                          unsigned width, unsigned height);
    272 
    273 void
    274 util_format_r8g8_b8g8_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    275                                           const uint8_t *src_row, unsigned src_stride,
    276                                           unsigned width, unsigned height);
    277 
    278 void
    279 util_format_r8g8_b8g8_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
    280                                        const float *src_row, unsigned src_stride,
    281                                        unsigned width, unsigned height);
    282 
    283 void
    284 util_format_r8g8_b8g8_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    285                                         const uint8_t *src_row, unsigned src_stride,
    286                                         unsigned width, unsigned height);
    287 
    288 void
    289 util_format_r8g8_b8g8_unorm_fetch_rgba_float(float *dst, const uint8_t *src,
    290                                         unsigned i, unsigned j);
    291 
    292 void
    293 util_format_g8r8_g8b8_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride,
    294                                          const uint8_t *src_row, unsigned src_stride,
    295                                          unsigned width, unsigned height);
    296 
    297 void
    298 util_format_g8r8_g8b8_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    299                                           const uint8_t *src_row, unsigned src_stride,
    300                                           unsigned width, unsigned height);
    301 
    302 void
    303 util_format_g8r8_g8b8_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
    304                                        const float *src_row, unsigned src_stride,
    305                                        unsigned width, unsigned height);
    306 
    307 void
    308 util_format_g8r8_g8b8_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    309                                         const uint8_t *src_row, unsigned src_stride,
    310                                         unsigned width, unsigned height);
    311 
    312 void
    313 util_format_g8r8_g8b8_unorm_fetch_rgba_float(float *dst, const uint8_t *src,
    314                                         unsigned i, unsigned j);
    315 
    316 void
    317 util_format_r8g8_r8b8_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride,
    318                                          const uint8_t *src_row, unsigned src_stride,
    319                                          unsigned width, unsigned height);
    320 
    321 void
    322 util_format_r8g8_r8b8_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    323                                           const uint8_t *src_row, unsigned src_stride,
    324                                           unsigned width, unsigned height);
    325 
    326 void
    327 util_format_r8g8_r8b8_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
    328                                        const float *src_row, unsigned src_stride,
    329                                        unsigned width, unsigned height);
    330 
    331 void
    332 util_format_r8g8_r8b8_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    333                                         const uint8_t *src_row, unsigned src_stride,
    334                                         unsigned width, unsigned height);
    335 
    336 void
    337 util_format_r8g8_r8b8_unorm_fetch_rgba_float(float *dst, const uint8_t *src,
    338                                         unsigned i, unsigned j);
    339 
    340 void
    341 util_format_g8r8_b8r8_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride,
    342                                          const uint8_t *src_row, unsigned src_stride,
    343                                          unsigned width, unsigned height);
    344 
    345 void
    346 util_format_g8r8_b8r8_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    347                                           const uint8_t *src_row, unsigned src_stride,
    348                                           unsigned width, unsigned height);
    349 
    350 void
    351 util_format_g8r8_b8r8_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
    352                                        const float *src_row, unsigned src_stride,
    353                                        unsigned width, unsigned height);
    354 
    355 void
    356 util_format_g8r8_b8r8_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
    357                                         const uint8_t *src_row, unsigned src_stride,
    358                                         unsigned width, unsigned height);
    359 
    360 void
    361 util_format_g8r8_b8r8_unorm_fetch_rgba_float(float *dst, const uint8_t *src,
    362                                         unsigned i, unsigned j);
    363 
    364 #endif /* U_FORMAT_YUV_H_ */
    365