Home | History | Annotate | Download | only in camera
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <stdint.h>
     18 #include <stdio.h>
     19 #include <stdlib.h>
     20 #ifdef _WIN32
     21 #elif _DARWIN_C_SOURCE
     22 #else
     23 #include <linux/videodev2.h>
     24 #endif
     25 #include "android/camera/camera-format-converters.h"
     26 
     27 #define  E(...)    derror(__VA_ARGS__)
     28 #define  W(...)    dwarning(__VA_ARGS__)
     29 #define  D(...)    VERBOSE_PRINT(camera,__VA_ARGS__)
     30 #define  D_ACTIVE  VERBOSE_CHECK(camera)
     31 
     32  /*
     33  * NOTE: RGB and big/little endian considerations. Wherewer in this code RGB
     34  * pixels are represented as WORD, or DWORD, the color order inside the
     35  * WORD / DWORD matches the one that would occur if that WORD / DWORD would have
     36  * been read from the typecasted framebuffer:
     37  *
     38  *      const uint32_t rgb = *reinterpret_cast<const uint32_t*>(framebuffer);
     39  *
     40  * So, if this code runs on the little endian CPU, red color in 'rgb' would be
     41  * masked as 0x000000ff, and blue color would be masked as 0x00ff0000, while if
     42  * the code runs on a big endian CPU, the red color in 'rgb' would be masked as
     43  * 0xff000000, and blue color would be masked as 0x0000ff00,
     44  */
     45 
     46 /*
     47  * RGB565 color masks
     48  */
     49 
     50 #ifndef HOST_WORDS_BIGENDIAN
     51 static const uint16_t kRed5     = 0x001f;
     52 static const uint16_t kGreen6   = 0x07e0;
     53 static const uint16_t kBlue5    = 0xf800;
     54 #else   // !HOST_WORDS_BIGENDIAN
     55 static const uint16_t kRed5     = 0xf800;
     56 static const uint16_t kGreen6   = 0x07e0;
     57 static const uint16_t kBlue5    = 0x001f;
     58 #endif  // !HOST_WORDS_BIGENDIAN
     59 
     60 /*
     61  * RGB32 color masks
     62  */
     63 
     64 #ifndef HOST_WORDS_BIGENDIAN
     65 static const uint32_t kRed8     = 0x000000ff;
     66 static const uint32_t kGreen8   = 0x0000ff00;
     67 static const uint32_t kBlue8    = 0x00ff0000;
     68 #else   // !HOST_WORDS_BIGENDIAN
     69 static const uint32_t kRed8     = 0x00ff0000;
     70 static const uint32_t kGreen8   = 0x0000ff00;
     71 static const uint32_t kBlue8    = 0x000000ff;
     72 #endif  // !HOST_WORDS_BIGENDIAN
     73 
     74 /*
     75  * Extracting, and saving color bytes from / to WORD / DWORD RGB.
     76  */
     77 
     78 #ifndef HOST_WORDS_BIGENDIAN
     79 /* Extract red, green, and blue bytes from RGB565 word. */
     80 #define R16(rgb)    (uint8_t)((rgb) & kRed5)
     81 #define G16(rgb)    (uint8_t)(((rgb) & kGreen6) >> 5)
     82 #define B16(rgb)    (uint8_t)(((rgb) & kBlue5) >> 11)
     83 /* Make 8 bits red, green, and blue, extracted from RGB565 word. */
     84 #define R16_32(rgb) (uint8_t)((((rgb) & kRed5) << 3) | (((rgb) & kRed5) >> 2))
     85 #define G16_32(rgb) (uint8_t)((((rgb) & kGreen6) >> 3) | (((rgb) & kGreen6) >> 9))
     86 #define B16_32(rgb) (uint8_t)((((rgb) & kBlue5) >> 8) | (((rgb) & kBlue5) >> 14))
     87 /* Extract red, green, and blue bytes from RGB32 dword. */
     88 #define R32(rgb)    (uint8_t)((rgb) & kRed8)
     89 #define G32(rgb)    (uint8_t)((((rgb) & kGreen8) >> 8) & 0xff)
     90 #define B32(rgb)    (uint8_t)((((rgb) & kBlue8) >> 16) & 0xff)
     91 /* Build RGB565 word from red, green, and blue bytes. */
     92 #define RGB565(r, g, b) (uint16_t)(((((uint16_t)(b) << 6) | (g)) << 5) | (r))
     93 /* Build RGB32 dword from red, green, and blue bytes. */
     94 #define RGB32(r, g, b) (uint32_t)(((((uint32_t)(b) << 8) | (g)) << 8) | (r))
     95 #else   // !HOST_WORDS_BIGENDIAN
     96 /* Extract red, green, and blue bytes from RGB565 word. */
     97 #define R16(rgb)    (uint8_t)(((rgb) & kRed5) >> 11)
     98 #define G16(rgb)    (uint8_t)(((rgb) & kGreen6) >> 5)
     99 #define B16(rgb)    (uint8_t)((rgb) & kBlue5)
    100 /* Make 8 bits red, green, and blue, extracted from RGB565 word. */
    101 #define R16_32(rgb) (uint8_t)((((rgb) & kRed5) >> 8) | (((rgb) & kRed5) >> 14))
    102 #define G16_32(rgb) (uint8_t)((((rgb) & kGreen6) >> 3) | (((rgb) & kGreen6) >> 9))
    103 #define B16_32(rgb) (uint8_t)((((rgb) & kBlue5) << 3) | (((rgb) & kBlue5) >> 2))
    104 /* Extract red, green, and blue bytes from RGB32 dword. */
    105 #define R32(rgb)    (uint8_t)(((rgb) & kRed8) >> 16)
    106 #define G32(rgb)    (uint8_t)(((rgb) & kGreen8) >> 8)
    107 #define B32(rgb)    (uint8_t)((rgb) & kBlue8)
    108 /* Build RGB565 word from red, green, and blue bytes. */
    109 #define RGB565(r, g, b) (uint16_t)(((((uint16_t)(r) << 6) | (g)) << 5) | (b))
    110 /* Build RGB32 dword from red, green, and blue bytes. */
    111 #define RGB32(r, g, b) (uint32_t)(((((uint32_t)(r) << 8) | (g)) << 8) | (b))
    112 #endif  // !HOST_WORDS_BIGENDIAN
    113 
    114 /*
    115  * BAYER bitmasks
    116  */
    117 
    118 /* Bitmask for 8-bits BAYER pixel. */
    119 #define kBayer8     0xff
    120 /* Bitmask for 10-bits BAYER pixel. */
    121 #define kBayer10    0x3ff
    122 /* Bitmask for 12-bits BAYER pixel. */
    123 #define kBayer12    0xfff
    124 
    125 /* An union that simplifies breaking 32 bit RGB into separate R, G, and B colors.
    126  */
    127 typedef union RGB32_t {
    128     uint32_t    color;
    129     struct {
    130 #ifndef HOST_WORDS_BIGENDIAN
    131         uint8_t r; uint8_t g; uint8_t b; uint8_t a;
    132 #else   // !HOST_WORDS_BIGENDIAN
    133         uint8_t a; uint8_t b; uint8_t g; uint8_t r;
    134 #endif  // HOST_WORDS_BIGENDIAN
    135     };
    136 } RGB32_t;
    137 
    138 /* Clips a value to the unsigned 0-255 range, treating negative values as zero.
    139  */
    140 static __inline__ int
    141 clamp(int x)
    142 {
    143     if (x > 255) return 255;
    144     if (x < 0)   return 0;
    145     return x;
    146 }
    147 
    148 /********************************************************************************
    149  * Basics of RGB -> YUV conversion
    150  *******************************************************************************/
    151 
    152 /*
    153  * RGB -> YUV conversion macros
    154  */
    155 #define RGB2Y(r, g, b) (uint8_t)(((66 * (r) + 129 * (g) +  25 * (b) + 128) >> 8) +  16)
    156 #define RGB2U(r, g, b) (uint8_t)(((-38 * (r) - 74 * (g) + 112 * (b) + 128) >> 8) + 128)
    157 #define RGB2V(r, g, b) (uint8_t)(((112 * (r) - 94 * (g) -  18 * (b) + 128) >> 8) + 128)
    158 
    159 /* Converts R8 G8 B8 color to YUV. */
    160 static __inline__ void
    161 R8G8B8ToYUV(uint8_t r, uint8_t g, uint8_t b, uint8_t* y, uint8_t* u, uint8_t* v)
    162 {
    163     *y = RGB2Y((int)r, (int)g, (int)b);
    164     *u = RGB2U((int)r, (int)g, (int)b);
    165     *v = RGB2V((int)r, (int)g, (int)b);
    166 }
    167 
    168 /* Converts RGB565 color to YUV. */
    169 static __inline__ void
    170 RGB565ToYUV(uint16_t rgb, uint8_t* y, uint8_t* u, uint8_t* v)
    171 {
    172     R8G8B8ToYUV(R16_32(rgb), G16_32(rgb), B16_32(rgb), y, u, v);
    173 }
    174 
    175 /* Converts RGB32 color to YUV. */
    176 static __inline__ void
    177 RGB32ToYUV(uint32_t rgb, uint8_t* y, uint8_t* u, uint8_t* v)
    178 {
    179     RGB32_t rgb_c;
    180     rgb_c.color = rgb;
    181     R8G8B8ToYUV(rgb_c.r, rgb_c.g, rgb_c.b, y, u, v);
    182 }
    183 
    184 /********************************************************************************
    185  * Basics of YUV -> RGB conversion.
    186  *******************************************************************************/
    187 
    188 /*
    189  * YUV -> RGB conversion macros
    190  */
    191 
    192 /* "Optimized" macros that take specialy prepared Y, U, and V values:
    193  *  C = Y - 16
    194  *  D = U - 128
    195  *  E = V - 128
    196  */
    197 #define YUV2RO(C, D, E) clamp((298 * (C) + 409 * (E) + 128) >> 8)
    198 #define YUV2GO(C, D, E) clamp((298 * (C) - 100 * (D) - 208 * (E) + 128) >> 8)
    199 #define YUV2BO(C, D, E) clamp((298 * (C) + 516 * (D) + 128) >> 8)
    200 
    201 /*
    202  *  Main macros that take the original Y, U, and V values
    203  */
    204 #define YUV2R(y, u, v) clamp((298 * ((y)-16) + 409 * ((v)-128) + 128) >> 8)
    205 #define YUV2G(y, u, v) clamp((298 * ((y)-16) - 100 * ((u)-128) - 208 * ((v)-128) + 128) >> 8)
    206 #define YUV2B(y, u, v) clamp((298 * ((y)-16) + 516 * ((u)-128) + 128) >> 8)
    207 
    208 
    209 /* Converts YUV color to RGB565. */
    210 static __inline__ uint16_t
    211 YUVToRGB565(int y, int u, int v)
    212 {
    213     /* Calculate C, D, and E values for the optimized macro. */
    214     y -= 16; u -= 128; v -= 128;
    215     const uint16_t r = YUV2RO(y,u,v) >> 3;
    216     const uint16_t g = YUV2GO(y,u,v) >> 2;
    217     const uint16_t b = YUV2BO(y,u,v) >> 3;
    218     return RGB565(r, g, b);
    219 }
    220 
    221 /* Converts YUV color to RGB32. */
    222 static __inline__ uint32_t
    223 YUVToRGB32(int y, int u, int v)
    224 {
    225     /* Calculate C, D, and E values for the optimized macro. */
    226     y -= 16; u -= 128; v -= 128;
    227     RGB32_t rgb;
    228     rgb.r = YUV2RO(y,u,v);
    229     rgb.g = YUV2GO(y,u,v);
    230     rgb.b = YUV2BO(y,u,v);
    231     return rgb.color;
    232 }
    233 
    234 /* Converts YUV color to separated RGB32 colors. */
    235 static __inline__ void
    236 YUVToRGBPix(int y, int u, int v, uint8_t* r, uint8_t* g, uint8_t* b)
    237 {
    238     /* Calculate C, D, and E values for the optimized macro. */
    239     y -= 16; u -= 128; v -= 128;
    240     *r = (uint8_t)YUV2RO(y,u,v);
    241     *g = (uint8_t)YUV2GO(y,u,v);
    242     *b = (uint8_t)YUV2BO(y,u,v);
    243 }
    244 
    245 /********************************************************************************
    246  * Generic converters between YUV and RGB formats
    247  *******************************************************************************/
    248 
    249 /*
    250  * The converters go line by line, convering one frame format to another.
    251  * It's pretty much straight forward for RGB/BRG, where all colors are
    252  * grouped next to each other in memory. The only two things that differ one RGB
    253  * format from another are:
    254  * - Is it an RGB, or BRG (i.e. color ordering)
    255  * - Is it 16, 24, or 32 bits format.
    256  * All these differences are addressed by load_rgb / save_rgb routines, provided
    257  * for each format in the RGB descriptor to load / save RGB color bytes from / to
    258  * the buffer. As far as moving from one RGB pixel to the next, there
    259  * are two question to consider:
    260  * - How many bytes it takes to encode one RGB pixel (could be 2, 3, or 4)
    261  * - How many bytes it takes to encode a line (i.e. line alignment issue, which
    262  *   makes sence only for 24-bit formats, since 16, and 32 bit formats provide
    263  *   automatic word alignment.)
    264  * The first question is answered with the 'rgb_inc' field of the RGB descriptor,
    265  * and the second one is done by aligning rgb pointer up to the nearest 16 bit
    266  * boundaries at the end of each line.
    267  * YUV format has much greater complexity for conversion. in YUV color encoding
    268  * is divided into three separate panes that can be mixed together in any way
    269  * imaginable. Fortunately, there are still some consistent patterns in different
    270 
    271  * YUV formats that can be abstracted through a descriptor:
    272  * - At the line-by-line level, colors are always groupped aroud pairs of pixels,
    273  *   where each pixel in the pair has its own Y value, and each pair of pixels
    274  *   share thesame U, and V values.
    275  * - Position of Y, U, and V is the same for each pair, so the distance between
    276  *   Ys, and U/V for adjacent pairs is the same.
    277  * - Inside the pair, the distance between two Ys is always the same.
    278 
    279  * Moving between the lines in YUV can also be easily formalized. Essentially,
    280  * there are three ways how color panes are arranged:
    281  * 1. All interleaved, where all three Y, U, and V values are encoded together in
    282  *    one block:
    283  *               1,2  3,4  5,6      n,n+1
    284  *              YUVY YUVY YUVY .... YUVY
    285  *
    286  *    This type is used to encode YUV 4:2:2 formats.
    287  *
    288  * 2. One separate block of memory for Y pane, and one separate block of memory
    289  *    containing interleaved U, and V panes.
    290  *
    291  *      YY | YY | YY | YY
    292  *      YY | YY | YY | YY
    293  *      -----------------
    294  *      UV | UV | UV | UV
    295  *      -----------------
    296  *
    297  *    This type is used to encode 4:2:0 formats.
    298  *
    299  * 3. Three separate blocks of memory for each pane.
    300  *
    301  *      YY | YY | YY | YY
    302  *      YY | YY | YY | YY
    303  *      -----------------
    304  *      U  | U  | U  | U
    305  *      V  | V  | V  | V
    306  *      -----------------
    307  *
    308  *    This type is also used to encode 4:2:0 formats.
    309  *
    310  * Note that in cases 2, and 3 each pair of U and V is shared among four pixels,
    311  * grouped together as they are groupped in the framebeffer: divide the frame's
    312  * rectangle into 2x2 pixels squares, starting from 0,0 corner - and each square
    313  * represents the group of pixels that share same pair of UV values. So, each
    314  * line in the U/V panes table is shared between two adjacent lines in Y pane,
    315  * which provides a pattern on how to move between U/V lines as we move between
    316  * Y lines.
    317  *
    318  * So, all these patterns can be coded in a YUV format descriptor, so there can
    319  * just one generic way of walking YUV frame.
    320  *
    321  * BAYER format.
    322  * We don't use BAYER inside the guest system, so there is no need to have a
    323  * converter to the BAYER formats, only from it. The color approximation  used in
    324  * the BAYER format converters implemented here simply averages corresponded
    325  * color values found in pixels sorrounding the one for which RGB colors are
    326  * calculated.
    327  *
    328  * Performance considerations:
    329  * Since converters implemented here are intended to work as part of the camera
    330  * emulation, making the code super performant is not a priority at all. There
    331  * will be enough loses in other parts of the emultion to overlook any slight
    332  * inefficiences in the conversion algorithm as neglectable.
    333  */
    334 
    335 typedef struct RGBDesc RGBDesc;
    336 typedef struct YUVDesc YUVDesc;
    337 typedef struct BayerDesc BayerDesc;
    338 
    339 /* Prototype for a routine that loads RGB colors from an RGB/BRG stream.
    340  * Param:
    341  *  rgb - Pointer to a pixel inside the stream where to load colors from.
    342  *  r, g, b - Upon return will contain red, green, and blue colors for the pixel
    343  *      addressed by 'rgb' pointer.
    344  * Return:
    345  *  Pointer to the next pixel in the stream.
    346  */
    347 typedef const void* (*load_rgb_func)(const void* rgb,
    348                                      uint8_t* r,
    349                                      uint8_t* g,
    350                                      uint8_t* b);
    351 
    352 /* Prototype for a routine that saves RGB colors to an RGB/BRG stream.
    353  * Param:
    354  *  rgb - Pointer to a pixel inside the stream where to save colors.
    355  *  r, g, b - Red, green, and blue colors to save to the pixel addressed by
    356  *      'rgb' pointer.
    357  * Return:
    358  *  Pointer to the next pixel in the stream.
    359  */
    360 typedef void* (*save_rgb_func)(void* rgb, uint8_t r, uint8_t g, uint8_t b);
    361 
    362 /* Prototype for a routine that calculates an offset of the first U value for the
    363  * given line in a YUV framebuffer.
    364  * Param:
    365  *  desc - Descriptor for the YUV frame for which the offset is being calculated.
    366  *  line - Zero-based line number for which to calculate the offset.
    367  *  width, height - Frame dimensions.
    368  * Return:
    369  *  Offset of the first U value for the given frame line. The offset returned
    370  *  here is relative to the beginning of the YUV framebuffer.
    371  */
    372 typedef int (*u_offset_func)(const YUVDesc* desc, int line, int width, int height);
    373 
    374 /* Prototype for a routine that calculates an offset of the first V value for the
    375  * given line in a YUV framebuffer.
    376  * Param:
    377  *  desc - Descriptor for the YUV frame for which the offset is being calculated.
    378  *  line - Zero-based line number for which to calculate the offset.
    379  *  width, height - Frame dimensions.
    380  * Return:
    381  *  Offset of the first V value for the given frame line. The offset returned
    382  *  here is relative to the beginning of the YUV framebuffer.
    383  */
    384 typedef int (*v_offset_func)(const YUVDesc* desc, int line, int width, int height);
    385 
    386 /* RGB/BRG format descriptor. */
    387 struct RGBDesc {
    388     /* Routine that loads RGB colors from a buffer. */
    389     load_rgb_func   load_rgb;
    390     /* Routine that saves RGB colors into a buffer. */
    391     save_rgb_func   save_rgb;
    392     /* Byte size of an encoded RGB pixel. */
    393     int             rgb_inc;
    394 };
    395 
    396 /* YUV format descriptor. */
    397 struct YUVDesc {
    398     /* Offset of the first Y value in a fully interleaved YUV framebuffer. */
    399     int             Y_offset;
    400     /* Distance between two Y values inside a pair of pixels in a fully
    401      * interleaved YUV framebuffer. */
    402     int             Y_inc;
    403     /* Distance between first Y values of the adjacent pixel pairs in a fully
    404      * interleaved YUV framebuffer. */
    405     int             Y_next_pair;
    406     /* Increment between adjacent U/V values in a YUV framebuffer. */
    407     int             UV_inc;
    408     /* Controls location of the first U value in YUV framebuffer. Depending on
    409      * the actual YUV format can mean three things:
    410      *  - For fully interleaved YUV formats contains offset of the first U value
    411      *    in each line.
    412      *  - For YUV format that use separate, but interleaved UV pane, this field
    413      *    contains an offset of the first U value in the UV pane.
    414      *  - For YUV format that use fully separated Y, U, and V panes this field
    415      *    defines order of U and V panes in the framebuffer:
    416      *      = 1 - U pane comes first, right after Y pane.
    417      *      = 0 - U pane follows V pane that startes right after Y pane. */
    418     int             U_offset;
    419     /* Controls location of the first V value in YUV framebuffer.
    420      * See comments to U_offset for more info. */
    421     int             V_offset;
    422     /* Routine that calculates an offset of the first U value for the given line
    423      * in a YUV framebuffer. */
    424     u_offset_func   u_offset;
    425     /* Routine that calculates an offset of the first V value for the given line
    426      * in a YUV framebuffer. */
    427     v_offset_func   v_offset;
    428 };
    429 
    430 /* Bayer format descriptor. */
    431 struct BayerDesc {
    432     /* Defines color ordering in the BAYER framebuffer. Can be one of the four:
    433      *  - "GBRG" for GBGBGB / RGRGRG
    434      *  - "GRBG" for GRGRGR / BGBGBG
    435      *  - "RGGB" for RGRGRG / GBGBGB
    436      *  - "BGGR" for BGBGBG / GRGRGR
    437      */
    438     const char* color_order;
    439     /* Bitmask for valid bits in the pixel:
    440      *  - 0xff  For a 8-bit BAYER format
    441      *  - 0x3ff For a 10-bit BAYER format
    442      *  - 0xfff For a 12-bit BAYER format
    443      */
    444     int         mask;
    445 };
    446 
    447 /********************************************************************************
    448  * RGB/BRG load / save routines.
    449  *******************************************************************************/
    450 
    451 /* Loads R, G, and B colors from a RGB32 framebuffer. */
    452 static const void*
    453 _load_RGB32(const void* rgb, uint8_t* r, uint8_t* g, uint8_t* b)
    454 {
    455     const uint8_t* rgb_ptr = (const uint8_t*)rgb;
    456     *r = rgb_ptr[0]; *g = rgb_ptr[1]; *b = rgb_ptr[2];
    457     return rgb_ptr + 4;
    458 }
    459 
    460 /* Saves R, G, and B colors to a RGB32 framebuffer. */
    461 static void*
    462 _save_RGB32(void* rgb, uint8_t r, uint8_t g, uint8_t b)
    463 {
    464     uint8_t* rgb_ptr = (uint8_t*)rgb;
    465     rgb_ptr[0] = r; rgb_ptr[1] = g; rgb_ptr[2] = b;
    466     return rgb_ptr + 4;
    467 }
    468 
    469 /* Loads R, G, and B colors from a BRG32 framebuffer. */
    470 static const void*
    471 _load_BRG32(const void* rgb, uint8_t* r, uint8_t* g, uint8_t* b)
    472 {
    473     const uint8_t* rgb_ptr = (const uint8_t*)rgb;
    474     *r = rgb_ptr[2]; *g = rgb_ptr[1]; *b = rgb_ptr[0];
    475     return rgb_ptr + 4;
    476 }
    477 
    478 /* Saves R, G, and B colors to a BRG32 framebuffer. */
    479 static void*
    480 _save_BRG32(void* rgb, uint8_t r, uint8_t g, uint8_t b)
    481 {
    482     uint8_t* rgb_ptr = (uint8_t*)rgb;
    483     rgb_ptr[2] = r; rgb_ptr[1] = g; rgb_ptr[0] = b;
    484     return rgb_ptr + 4;
    485 }
    486 
    487 /* Loads R, G, and B colors from a RGB24 framebuffer.
    488  * Note that it's the caller's responsibility to ensure proper alignment of the
    489  * returned pointer at the line's break. */
    490 static const void*
    491 _load_RGB24(const void* rgb, uint8_t* r, uint8_t* g, uint8_t* b)
    492 {
    493     const uint8_t* rgb_ptr = (const uint8_t*)rgb;
    494     *r = rgb_ptr[0]; *g = rgb_ptr[1]; *b = rgb_ptr[2];
    495     return rgb_ptr + 3;
    496 }
    497 
    498 /* Saves R, G, and B colors to a RGB24 framebuffer.
    499  * Note that it's the caller's responsibility to ensure proper alignment of the
    500  * returned pointer at the line's break. */
    501 static void*
    502 _save_RGB24(void* rgb, uint8_t r, uint8_t g, uint8_t b)
    503 {
    504     uint8_t* rgb_ptr = (uint8_t*)rgb;
    505     rgb_ptr[0] = r; rgb_ptr[1] = g; rgb_ptr[2] = b;
    506     return rgb_ptr + 3;
    507 }
    508 
    509 /* Loads R, G, and B colors from a BRG32 framebuffer.
    510  * Note that it's the caller's responsibility to ensure proper alignment of the
    511  * returned pointer at the line's break. */
    512 static const void*
    513 _load_BRG24(const void* rgb, uint8_t* r, uint8_t* g, uint8_t* b)
    514 {
    515     const uint8_t* rgb_ptr = (const uint8_t*)rgb;
    516     *r = rgb_ptr[2]; *g = rgb_ptr[1]; *b = rgb_ptr[0];
    517     return rgb_ptr + 3;
    518 }
    519 
    520 /* Saves R, G, and B colors to a BRG24 framebuffer.
    521  * Note that it's the caller's responsibility to ensure proper alignment of the
    522  * returned pointer at the line's break. */
    523 static void*
    524 _save_BRG24(void* rgb, uint8_t r, uint8_t g, uint8_t b)
    525 {
    526     uint8_t* rgb_ptr = (uint8_t*)rgb;
    527     rgb_ptr[2] = r; rgb_ptr[1] = g; rgb_ptr[0] = b;
    528     return rgb_ptr + 3;
    529 }
    530 
    531 /* Loads R, G, and B colors from a RGB565 framebuffer. */
    532 static const void*
    533 _load_RGB16(const void* rgb, uint8_t* r, uint8_t* g, uint8_t* b)
    534 {
    535     const uint16_t rgb16 = *(const uint16_t*)rgb;
    536     *r = R16(rgb16); *g = G16(rgb16); *b = B16(rgb16);
    537     return (const uint8_t*)rgb + 2;
    538 }
    539 
    540 /* Saves R, G, and B colors to a RGB565 framebuffer. */
    541 static void*
    542 _save_RGB16(void* rgb, uint8_t r, uint8_t g, uint8_t b)
    543 {
    544     *(uint16_t*)rgb = RGB565(r & 0x1f, g & 0x3f, b & 0x1f);
    545     return (uint8_t*)rgb + 2;
    546 }
    547 
    548 /* Loads R, G, and B colors from a BRG565 framebuffer. */
    549 static const void*
    550 _load_BRG16(const void* rgb, uint8_t* r, uint8_t* g, uint8_t* b)
    551 {
    552     const uint16_t rgb16 = *(const uint16_t*)rgb;
    553     *r = B16(rgb16); *g = G16(rgb16); *b = R16(rgb16);
    554     return (const uint8_t*)rgb + 2;
    555 }
    556 
    557 /* Saves R, G, and B colors to a BRG565 framebuffer. */
    558 static void*
    559 _save_BRG16(void* rgb, uint8_t r, uint8_t g, uint8_t b)
    560 {
    561     *(uint16_t*)rgb = RGB565(b & 0x1f, g & 0x3f, r & 0x1f);
    562     return (uint8_t*)rgb + 2;
    563 }
    564 
    565 /********************************************************************************
    566  * YUV's U/V offset calculation routines.
    567  *******************************************************************************/
    568 
    569 /* U offset in a fully interleaved YUV 4:2:2 */
    570 static int
    571 _UOffIntrlYUV(const YUVDesc* desc, int line, int width, int height)
    572 {
    573     /* In interleaved YUV 4:2:2 each pair of pixels is encoded with 4 consecutive
    574      * bytes (or 2 bytes per pixel). So line size in a fully interleaved YUV 4:2:2
    575      * is twice its width. */
    576     return line * width * 2 + desc->U_offset;
    577 }
    578 
    579 /* V offset in a fully interleaved YUV 4:2:2 */
    580 static int
    581 _VOffIntrlYUV(const YUVDesc* desc, int line, int width, int height)
    582 {
    583     /* See _UOffIntrlYUV comments. */
    584     return line * width * 2 + desc->V_offset;
    585 }
    586 
    587 /* U offset in an interleaved UV pane of YUV 4:2:0 */
    588 static int
    589 _UOffIntrlUV(const YUVDesc* desc, int line, int width, int height)
    590 {
    591     /* UV pane starts right after the Y pane, that occupies 'height * width'
    592      * bytes. Eacht line in UV pane contains width / 2 'UV' pairs, which makes UV
    593      * lane to contain as many bytes, as the width is.
    594      * Each line in the UV pane is shared between two Y lines. So, final formula
    595      * for the beggining of the UV pane's line for the given line in YUV
    596      * framebuffer is:
    597      *
    598      *    height * width + (line / 2) * width = (height + line / 2) * width
    599      */
    600     return (height + line / 2) * width + desc->U_offset;
    601 }
    602 
    603 /* V offset in an interleaved UV pane of YUV 4:2:0 */
    604 static int
    605 _VOffIntrlUV(const YUVDesc* desc, int line, int width, int height)
    606 {
    607     /* See comments in _UOffIntrlUV. */
    608     return (height + line / 2) * width + desc->V_offset;
    609 }
    610 
    611 /* U offset in a 3-pane YUV 4:2:0 */
    612 static int
    613 _UOffSepYUV(const YUVDesc* desc, int line, int width, int height)
    614 {
    615     /* U, or V pane starts right after the Y pane, that occupies 'height * width'
    616      * bytes. Eacht line in each of U and V panes contains width / 2 elements.
    617      * Also, each line in each of U and V panes is shared between two Y lines.
    618      * So, final formula for the beggining of a line in the U/V pane is:
    619      *
    620      *    <Y pane size> + (line / 2) * width / 2
    621      *
    622      * for the pane that follows right after the Y pane, or
    623      *
    624      *    <Y pane size> + <Y pane size> / 4 + (line / 2) * width / 2
    625      *
    626      * for the second pane.
    627      */
    628     const int y_pane_size = height * width;
    629     if (desc->U_offset) {
    630         /* U pane comes right after the Y pane. */
    631         return y_pane_size + (line / 2) * width / 2;
    632     } else {
    633         /* U pane follows V pane. */
    634         return y_pane_size + y_pane_size / 4 + (line / 2) * width / 2;
    635     }
    636 }
    637 
    638 /* V offset in a 3-pane YUV 4:2:0 */
    639 static int
    640 _VOffSepYUV(const YUVDesc* desc, int line, int width, int height)
    641 {
    642     /* See comment for _UOffSepYUV. */
    643     const int y_pane_size = height * width;
    644     if (desc->V_offset) {
    645         /* V pane comes right after the Y pane. */
    646         return y_pane_size + (line / 2) * width / 2;
    647     } else {
    648         /* V pane follows U pane. */
    649         return y_pane_size + y_pane_size / 4 + (line / 2) * width / 2;
    650     }
    651 }
    652 
    653 /********************************************************************************
    654  * Bayer routines.
    655  *******************************************************************************/
    656 
    657 /* Gets a color value for the given pixel in a bayer framebuffer.
    658  * Param:
    659  *  desc - Bayer framebuffer descriptor.
    660  *  buf - Beginning of the framebuffer.
    661  *  x, y - Coordinates of the pixel inside the framebuffer to get the color for.
    662  *  width - Number of pixel in a line inside the framebuffer.
    663  * Return:
    664  *  Given pixel color.
    665  */
    666 static __inline__ int
    667 _get_bayer_color(const BayerDesc* desc, const void* buf, int x, int y, int width)
    668 {
    669     if (desc->mask == kBayer8) {
    670         /* Each pixel is represented with one byte. */
    671         return *((const uint8_t*)buf + y * width + x);
    672     } else {
    673 #ifndef HOST_WORDS_BIGENDIAN
    674         return *((const int16_t*)buf + y * width + x) & desc->mask;
    675 #else
    676         const uint8_t* pixel = (const uint8_t*)buf + (y * width + x) * 2;
    677         return (((uint16_t)pixel[1] << 8) | pixel[0]) & desc->mask;
    678 #endif  /* !HOST_WORDS_BIGENDIAN */
    679     }
    680 }
    681 
    682 /* Gets an average value of colors that are horisontally adjacent to a pixel in
    683  * a bayer framebuffer.
    684  * Param:
    685  *  desc - Bayer framebuffer descriptor.
    686  *  buf - Beginning of the framebuffer.
    687  *  x, y - Coordinates of the pixel inside the framebuffer that is the center for
    688  *      the calculation.
    689  *  width, height - Framebuffer dimensions.
    690  * Return:
    691  *  Average color for horisontally adjacent pixels.
    692  */
    693 static int
    694 _get_bayer_ave_hor(const BayerDesc* desc,
    695                    const void* buf,
    696                    int x,
    697                    int y,
    698                    int width,
    699                    int height)
    700 {
    701     if (x == 0) {
    702         return _get_bayer_color(desc, buf, x + 1, y, width);
    703     } else if (x == (width - 1)) {
    704         return _get_bayer_color(desc, buf, x - 1, y, width);
    705     } else {
    706         return (_get_bayer_color(desc, buf, x - 1, y, width) +
    707                 _get_bayer_color(desc, buf, x + 1, y, width)) / 2;
    708     }
    709 }
    710 
    711 /* Gets an average value of colors that are vertically adjacent to a pixel in
    712  * a bayer framebuffer.
    713  * Param:
    714  *  desc - Bayer framebuffer descriptor.
    715  *  buf - Beginning of the framebuffer.
    716  *  x, y - Coordinates of the pixel inside the framebuffer that is the center for
    717  *      the calculation.
    718  *  width, height - Framebuffer dimensions.
    719  * Return:
    720  *  Average color for vertically adjacent pixels.
    721  */
    722 static int
    723 _get_bayer_ave_vert(const BayerDesc* desc,
    724                     const void* buf,
    725                     int x,
    726                     int y,
    727                     int width,
    728                     int height)
    729 {
    730     if (y == 0) {
    731         return _get_bayer_color(desc, buf, x, y + 1, width);
    732     } else if (y == (height - 1)) {
    733         return _get_bayer_color(desc, buf, x, y - 1, width);
    734     } else {
    735         return (_get_bayer_color(desc, buf, x, y - 1, width) +
    736                 _get_bayer_color(desc, buf, x, y + 1, width)) / 2;
    737     }
    738 }
    739 
    740 /* Gets an average value of colors that are horisontally and vertically adjacent
    741  * to a pixel in a bayer framebuffer.
    742  * Param:
    743  *  desc - Bayer framebuffer descriptor.
    744  *  buf - Beginning of the framebuffer.
    745  *  x, y - Coordinates of the pixel inside the framebuffer that is the center for
    746  *      the calculation.
    747  *  width, height - Framebuffer dimensions.
    748  * Return:
    749  *  Average color for horisontally and vertically adjacent pixels.
    750  */
    751 static int
    752 _get_bayer_ave_cross(const BayerDesc* desc,
    753                      const void* buf,
    754                      int x,
    755                      int y,
    756                      int width,
    757                      int height)
    758 {
    759     if (x > 0 && x < (width - 1) && y > 0 && y < (height - 1)) {
    760         /* Most of the time the code will take this path. So it makes sence to
    761          * special case it for performance reasons. */
    762         return (_get_bayer_color(desc, buf, x - 1, y, width) +
    763                 _get_bayer_color(desc, buf, x + 1, y, width) +
    764                 _get_bayer_color(desc, buf, x, y - 1, width) +
    765                 _get_bayer_color(desc, buf, x, y + 1, width)) / 4;
    766     } else {
    767         int sum = 0;
    768         int num = 0;
    769 
    770         /* Horisontal sum */
    771         if (x == 0) {
    772             sum += _get_bayer_color(desc, buf, x + 1, y, width);
    773             num++;
    774         } else if (x == (width - 1)) {
    775             sum += _get_bayer_color(desc, buf, x - 1, y, width);
    776             num++;
    777         } else {
    778             sum += _get_bayer_color(desc, buf, x - 1, y, width) +
    779                    _get_bayer_color(desc, buf, x + 1, y, width);
    780             num += 2;
    781         }
    782 
    783         /* Vertical sum */
    784         if (y == 0) {
    785             sum += _get_bayer_color(desc, buf, x, y + 1, width);
    786             num++;
    787         } else if (y == (height - 1)) {
    788             sum += _get_bayer_color(desc, buf, x, y - 1, width);
    789             num++;
    790         } else {
    791             sum += _get_bayer_color(desc, buf, x, y - 1, width) +
    792                    _get_bayer_color(desc, buf, x, y + 1, width);
    793             num += 2;
    794         }
    795 
    796         return sum / num;
    797     }
    798 }
    799 
    800 /* Gets an average value of colors that are diagonally adjacent to a pixel in a
    801  * bayer framebuffer.
    802  * Param:
    803  *  desc - Bayer framebuffer descriptor.
    804  *  buf - Beginning of the framebuffer.
    805  *  x, y - Coordinates of the pixel inside the framebuffer that is the center for
    806  *      the calculation.
    807  *  width, height - Framebuffer dimensions.
    808  * Return:
    809  *  Average color for diagonally adjacent pixels.
    810  */
    811 static int
    812 _get_bayer_ave_diag(const BayerDesc* desc,
    813                     const void* buf,
    814                     int x,
    815                     int y,
    816                     int width,
    817                     int height)
    818 {
    819     if (x > 0 && x < (width - 1) && y > 0 && y < (height - 1)) {
    820         /* Most of the time the code will take this path. So it makes sence to
    821          * special case it for performance reasons. */
    822         return (_get_bayer_color(desc, buf, x - 1, y - 1, width) +
    823                 _get_bayer_color(desc, buf, x + 1, y - 1, width) +
    824                 _get_bayer_color(desc, buf, x - 1, y + 1, width) +
    825                 _get_bayer_color(desc, buf, x + 1, y + 1, width)) / 4;
    826     } else {
    827         int sum = 0;
    828         int num = 0;
    829         int xx, yy;
    830         for (xx = x - 1; xx < (x + 2); xx += 2) {
    831             for (yy = y - 1; yy < (y + 2); yy += 2) {
    832                 if (xx >= 0 && yy >= 0 && xx < width && yy < height) {
    833                     sum += _get_bayer_color(desc, buf, xx, yy, width);
    834                     num++;
    835                 }
    836             }
    837         }
    838         return sum / num;
    839     }
    840 }
    841 
    842 /* Gets pixel color selector for the given pixel in a bayer framebuffer.
    843  * Param:
    844  *  desc - Bayer framebuffer descriptor.
    845  *  x, y - Coordinates of the pixel inside the framebuffer to get the color
    846  *      selector for.
    847  * Return:
    848  *  Pixel color selector:
    849  *      - 'R' - pixel is red.
    850  *      - 'G' - pixel is green.
    851  *      - 'B' - pixel is blue.
    852  */
    853 static __inline__ char
    854 _get_bayer_color_sel(const BayerDesc* desc, int x, int y)
    855 {
    856     return desc->color_order[((y & 1) << 1) | (x & 1)];
    857 }
    858 
    859 /* Calculates RGB colors for a pixel in a bayer framebuffer.
    860  * Param:
    861  *  desc - Bayer framebuffer descriptor.
    862  *  buf - Beginning of the framebuffer.
    863  *  x, y - Coordinates of the pixel inside the framebuffer to get the colors for.
    864  *  width, height - Framebuffer dimensions.
    865  *  red, green bluu - Upon return will contain RGB colors calculated for the pixel.
    866  */
    867 static void
    868 _get_bayerRGB(const BayerDesc* desc,
    869               const void* buf,
    870               int x,
    871               int y,
    872               int width,
    873               int height,
    874               int* red,
    875               int* green,
    876               int* blue)
    877 {
    878     const char pixel_color = _get_bayer_color_sel(desc, x, y);
    879 
    880     if (pixel_color == 'G') {
    881         /* This is a green pixel. */
    882         const char next_pixel_color = _get_bayer_color_sel(desc, x + 1, y);
    883         *green = _get_bayer_color(desc, buf, x, y, width);
    884         if (next_pixel_color == 'R') {
    885             *red = _get_bayer_ave_hor(desc, buf, x, y, width, height);
    886             *blue = _get_bayer_ave_vert(desc, buf, x, y, width, height);
    887         } else {
    888             *red = _get_bayer_ave_vert(desc, buf, x, y, width, height);
    889             *blue = _get_bayer_ave_hor(desc, buf, x, y, width, height);
    890         }
    891     } else if (pixel_color == 'R') {
    892         /* This is a red pixel. */
    893         *red = _get_bayer_color(desc, buf, x, y, width);
    894         *green = _get_bayer_ave_cross(desc, buf, x, y, width, height);
    895         *blue = _get_bayer_ave_diag(desc, buf, x, y, width, height);
    896     } else {
    897         /* This is a blue pixel. */
    898         *blue = _get_bayer_color(desc, buf, x, y, width);
    899         *green = _get_bayer_ave_cross(desc, buf, x, y, width, height);
    900         *red = _get_bayer_ave_diag(desc, buf, x, y, width, height);
    901     }
    902 }
    903 
    904 /********************************************************************************
    905  * Generic YUV/RGB/BAYER converters
    906  *******************************************************************************/
    907 
    908 /* Generic converter from an RGB/BRG format to a YUV format. */
    909 static void
    910 RGBToYUV(const RGBDesc* rgb_fmt,
    911          const YUVDesc* yuv_fmt,
    912          const void* rgb,
    913          void* yuv,
    914          int width,
    915          int height)
    916 {
    917     int y, x;
    918     const int Y_Inc = yuv_fmt->Y_inc;
    919     const int UV_inc = yuv_fmt->UV_inc;
    920     const int Y_next_pair = yuv_fmt->Y_next_pair;
    921     uint8_t* pY = (uint8_t*)yuv + yuv_fmt->Y_offset;
    922     for (y = 0; y < height; y++) {
    923         uint8_t* pU =
    924             (uint8_t*)yuv + yuv_fmt->u_offset(yuv_fmt, y, width, height);
    925         uint8_t* pV =
    926             (uint8_t*)yuv + yuv_fmt->v_offset(yuv_fmt, y, width, height);
    927         for (x = 0; x < width; x += 2,
    928                                pY += Y_next_pair, pU += UV_inc, pV += UV_inc) {
    929             uint8_t r, g, b;
    930             rgb = rgb_fmt->load_rgb(rgb, &r, &g, &b);
    931             R8G8B8ToYUV(r, g, b, pY, pU, pV);
    932             rgb = rgb_fmt->load_rgb(rgb, &r, &g, &b);
    933             pY[Y_Inc] = RGB2Y((int)r, (int)g, (int)b);
    934         }
    935         /* Aling rgb_ptr to 16 bit */
    936         if (((uintptr_t)rgb & 1) != 0) rgb = (const uint8_t*)rgb + 1;
    937     }
    938 }
    939 
    940 /* Generic converter from one RGB/BRG format to another RGB/BRG format. */
    941 static void
    942 RGBToRGB(const RGBDesc* src_rgb_fmt,
    943          const RGBDesc* dst_rgb_fmt,
    944          const void* src_rgb,
    945          void* dst_rgb,
    946          int width,
    947          int height)
    948 {
    949     int x, y;
    950     for (y = 0; y < height; y++) {
    951         for (x = 0; x < width; x++) {
    952             uint8_t r, g, b;
    953             src_rgb = src_rgb_fmt->load_rgb(src_rgb, &r, &g, &b);
    954             dst_rgb = dst_rgb_fmt->save_rgb(dst_rgb, r, g, b);
    955         }
    956         /* Aling rgb pinters to 16 bit */
    957         if (((uintptr_t)src_rgb & 1) != 0) src_rgb = (uint8_t*)src_rgb + 1;
    958         if (((uintptr_t)dst_rgb & 1) != 0) dst_rgb = (uint8_t*)dst_rgb + 1;
    959     }
    960 }
    961 
    962 /* Generic converter from a YUV format to an RGB/BRG format. */
    963 static void
    964 YUVToRGB(const YUVDesc* yuv_fmt,
    965          const RGBDesc* rgb_fmt,
    966          const void* yuv,
    967          void* rgb,
    968          int width,
    969          int height)
    970 {
    971     int y, x;
    972     const int Y_Inc = yuv_fmt->Y_inc;
    973     const int UV_inc = yuv_fmt->UV_inc;
    974     const int Y_next_pair = yuv_fmt->Y_next_pair;
    975     const uint8_t* pY = (const uint8_t*)yuv + yuv_fmt->Y_offset;
    976     for (y = 0; y < height; y++) {
    977         const uint8_t* pU =
    978             (const uint8_t*)yuv + yuv_fmt->u_offset(yuv_fmt, y, width, height);
    979         const uint8_t* pV =
    980             (const uint8_t*)yuv + yuv_fmt->v_offset(yuv_fmt, y, width, height);
    981         for (x = 0; x < width; x += 2,
    982                                pY += Y_next_pair, pU += UV_inc, pV += UV_inc) {
    983             uint8_t r, g, b;
    984             const uint8_t U = *pU;
    985             const uint8_t V = *pV;
    986             YUVToRGBPix(*pY, U, V, &r, &g, &b);
    987             rgb = rgb_fmt->save_rgb(rgb, r, g, b);
    988             YUVToRGBPix(pY[Y_Inc], U, V, &r, &g, &b);
    989             rgb = rgb_fmt->save_rgb(rgb, r, g, b);
    990         }
    991         /* Aling rgb_ptr to 16 bit */
    992         if (((uintptr_t)rgb & 1) != 0) rgb = (uint8_t*)rgb + 1;
    993     }
    994 }
    995 
    996 /* Generic converter from one YUV format to another YUV format. */
    997 static void
    998 YUVToYUV(const YUVDesc* src_fmt,
    999          const YUVDesc* dst_fmt,
   1000          const void* src,
   1001          void* dst,
   1002          int width,
   1003          int height)
   1004 {
   1005     int y, x;
   1006     const int Y_Inc_src = src_fmt->Y_inc;
   1007     const int UV_inc_src = src_fmt->UV_inc;
   1008     const int Y_next_pair_src = src_fmt->Y_next_pair;
   1009     const int Y_Inc_dst = dst_fmt->Y_inc;
   1010     const int UV_inc_dst = dst_fmt->UV_inc;
   1011     const int Y_next_pair_dst = dst_fmt->Y_next_pair;
   1012     const uint8_t* pYsrc = (const uint8_t*)src + src_fmt->Y_offset;
   1013     uint8_t* pYdst = (uint8_t*)dst + dst_fmt->Y_offset;
   1014     for (y = 0; y < height; y++) {
   1015         const uint8_t* pUsrc =
   1016             (const uint8_t*)src + src_fmt->u_offset(src_fmt, y, width, height);
   1017         const uint8_t* pVsrc =
   1018             (const uint8_t*)src + src_fmt->v_offset(src_fmt, y, width, height);
   1019         uint8_t* pUdst =
   1020             (uint8_t*)dst + dst_fmt->u_offset(dst_fmt, y, width, height);
   1021         uint8_t* pVdst =
   1022             (uint8_t*)dst + dst_fmt->v_offset(dst_fmt, y, width, height);
   1023         for (x = 0; x < width; x += 2, pYsrc += Y_next_pair_src,
   1024                                        pUsrc += UV_inc_src,
   1025                                        pVsrc += UV_inc_src,
   1026                                        pYdst += Y_next_pair_dst,
   1027                                        pUdst += UV_inc_dst,
   1028                                        pVdst += UV_inc_dst) {
   1029             *pYdst = *pYsrc; *pUdst = *pUsrc; *pVdst = *pVsrc;
   1030             pYdst[Y_Inc_dst] = pYsrc[Y_Inc_src];
   1031         }
   1032     }
   1033 }
   1034 
   1035 /* Generic converter from a BAYER format to an RGB/BRG format. */
   1036 static void
   1037 BAYERToRGB(const BayerDesc* bayer_fmt,
   1038            const RGBDesc* rgb_fmt,
   1039            const void* bayer,
   1040            void* rgb,
   1041            int width,
   1042            int height)
   1043 {
   1044     int y, x;
   1045     for (y = 0; y < height; y++) {
   1046         for (x = 0; x < width; x++) {
   1047             int r, g, b;
   1048             _get_bayerRGB(bayer_fmt, bayer, x, y, width, height, &r, &g, &b);
   1049             if (bayer_fmt->mask == kBayer10) {
   1050                 r >>= 2; g >>= 2; b >>= 2;
   1051             } else if (bayer_fmt->mask == kBayer12) {
   1052                 r >>= 4; g >>= 4; b >>= 4;
   1053             }
   1054             rgb = rgb_fmt->save_rgb(rgb, r, g, b);
   1055         }
   1056         /* Aling rgb_ptr to 16 bit */
   1057         if (((uintptr_t)rgb & 1) != 0) rgb = (uint8_t*)rgb + 1;
   1058     }
   1059 }
   1060 
   1061 /* Generic converter from a BAYER format to a YUV format. */
   1062 static void
   1063 BAYERToYUV(const BayerDesc* bayer_fmt,
   1064            const YUVDesc* yuv_fmt,
   1065            const void* bayer,
   1066            void* yuv,
   1067            int width,
   1068            int height)
   1069 {
   1070     int y, x;
   1071     const int Y_Inc = yuv_fmt->Y_inc;
   1072     const int UV_inc = yuv_fmt->UV_inc;
   1073     const int Y_next_pair = yuv_fmt->Y_next_pair;
   1074     uint8_t* pY = (uint8_t*)yuv + yuv_fmt->Y_offset;
   1075     for (y = 0; y < height; y++) {
   1076         uint8_t* pU =
   1077             (uint8_t*)yuv + yuv_fmt->u_offset(yuv_fmt, y, width, height);
   1078         uint8_t* pV =
   1079             (uint8_t*)yuv + yuv_fmt->v_offset(yuv_fmt, y, width, height);
   1080         for (x = 0; x < width; x += 2,
   1081                                pY += Y_next_pair, pU += UV_inc, pV += UV_inc) {
   1082             int r, g, b;
   1083             _get_bayerRGB(bayer_fmt, bayer, x, y, width, height, &r, &g, &b);
   1084             R8G8B8ToYUV(r, g, b, pY, pU, pV);
   1085             _get_bayerRGB(bayer_fmt, bayer, x + 1, y, width, height, &r, &g, &b);
   1086             pY[Y_Inc] = RGB2Y(r, g, b);
   1087         }
   1088     }
   1089 }
   1090 
   1091 /********************************************************************************
   1092  * RGB format descriptors.
   1093  */
   1094 
   1095 /* Describes RGB32 format. */
   1096 static const RGBDesc _RGB32 =
   1097 {
   1098     .load_rgb   = _load_RGB32,
   1099     .save_rgb   = _save_RGB32,
   1100     .rgb_inc    = 4
   1101 };
   1102 
   1103 /* Describes BRG32 format. */
   1104 static const RGBDesc _BRG32 =
   1105 {
   1106     .load_rgb   = _load_BRG32,
   1107     .save_rgb   = _save_BRG32,
   1108     .rgb_inc    = 4
   1109 };
   1110 
   1111 /* Describes RGB24 format. */
   1112 static const RGBDesc _RGB24 =
   1113 {
   1114     .load_rgb   = _load_RGB24,
   1115     .save_rgb   = _save_RGB24,
   1116     .rgb_inc    = 3
   1117 };
   1118 
   1119 /* Describes BRG24 format. */
   1120 static const RGBDesc _BRG24 =
   1121 {
   1122     .load_rgb   = _load_BRG24,
   1123     .save_rgb   = _save_BRG24,
   1124     .rgb_inc    = 3
   1125 };
   1126 
   1127 /* Describes RGB16 format. */
   1128 static const RGBDesc _RGB16 =
   1129 {
   1130     .load_rgb   = _load_RGB16,
   1131     .save_rgb   = _save_RGB16,
   1132     .rgb_inc    = 2
   1133 };
   1134 
   1135 /* Describes BRG16 format. */
   1136 static const RGBDesc _BRG16 =
   1137 {
   1138     .load_rgb   = _load_BRG16,
   1139     .save_rgb   = _save_BRG16,
   1140     .rgb_inc    = 2
   1141 };
   1142 
   1143 /********************************************************************************
   1144  * YUV 4:2:2 format descriptors.
   1145  */
   1146 
   1147 /* YUYV: 4:2:2, YUV are interleaved. */
   1148 static const YUVDesc _YUYV =
   1149 {
   1150     .Y_offset       = 0,
   1151     .Y_inc          = 2,
   1152     .Y_next_pair    = 4,
   1153     .UV_inc         = 4,
   1154     .U_offset       = 1,
   1155     .V_offset       = 3,
   1156     .u_offset       = &_UOffIntrlYUV,
   1157     .v_offset       = &_VOffIntrlYUV
   1158 };
   1159 
   1160 /* UYVY: 4:2:2, YUV are interleaved. */
   1161 static const YUVDesc _UYVY =
   1162 {
   1163     .Y_offset       = 1,
   1164     .Y_inc          = 2,
   1165     .Y_next_pair    = 4,
   1166     .UV_inc         = 4,
   1167     .U_offset       = 0,
   1168     .V_offset       = 2,
   1169     .u_offset       = &_UOffIntrlYUV,
   1170     .v_offset       = &_VOffIntrlYUV
   1171 };
   1172 
   1173 /* YVYU: 4:2:2, YUV are interleaved. */
   1174 static const YUVDesc _YVYU =
   1175 {
   1176     .Y_offset       = 0,
   1177     .Y_inc          = 2,
   1178     .Y_next_pair    = 4,
   1179     .UV_inc         = 4,
   1180     .U_offset       = 3,
   1181     .V_offset       = 1,
   1182     .u_offset       = &_UOffIntrlYUV,
   1183     .v_offset       = &_VOffIntrlYUV
   1184 };
   1185 
   1186 /* VYUY: 4:2:2, YUV are interleaved. */
   1187 static const YUVDesc _VYUY =
   1188 {
   1189     .Y_offset       = 1,
   1190     .Y_inc          = 2,
   1191     .Y_next_pair    = 4,
   1192     .UV_inc         = 4,
   1193     .U_offset       = 2,
   1194     .V_offset       = 0,
   1195     .u_offset       = &_UOffIntrlYUV,
   1196     .v_offset       = &_VOffIntrlYUV
   1197 };
   1198 
   1199 /* YYUV (also YUY2, YUNV, V422) : 4:2:2, YUV are interleaved. */
   1200 static const YUVDesc _YYUV =
   1201 {
   1202     .Y_offset       = 0,
   1203     .Y_inc          = 1,
   1204     .Y_next_pair    = 4,
   1205     .UV_inc         = 4,
   1206     .U_offset       = 2,
   1207     .V_offset       = 3,
   1208     .u_offset       = &_UOffIntrlYUV,
   1209     .v_offset       = &_VOffIntrlYUV
   1210 };
   1211 
   1212 /* YYVU: 4:2:2, YUV are interleaved. */
   1213 static const YUVDesc _YYVU =
   1214 {
   1215     .Y_offset       = 0,
   1216     .Y_inc          = 1,
   1217     .Y_next_pair    = 4,
   1218     .UV_inc         = 4,
   1219     .U_offset       = 3,
   1220     .V_offset       = 2,
   1221     .u_offset       = &_UOffIntrlYUV,
   1222     .v_offset       = &_VOffIntrlYUV
   1223 };
   1224 
   1225 /********************************************************************************
   1226  * YUV 4:2:0 descriptors.
   1227  */
   1228 
   1229 /* YV12: 4:2:0, YUV are fully separated, U pane follows V pane */
   1230 static const YUVDesc _YV12 =
   1231 {
   1232     .Y_offset       = 0,
   1233     .Y_inc          = 1,
   1234     .Y_next_pair    = 2,
   1235     .UV_inc         = 1,
   1236     .U_offset       = 0,
   1237     .V_offset       = 1,
   1238     .u_offset       = &_UOffSepYUV,
   1239     .v_offset       = &_VOffSepYUV
   1240 };
   1241 
   1242 /* YU12: 4:2:0, YUV are fully separated, V pane follows U pane */
   1243 static const YUVDesc _YU12 =
   1244 {
   1245     .Y_offset       = 0,
   1246     .Y_inc          = 1,
   1247     .Y_next_pair    = 2,
   1248     .UV_inc         = 1,
   1249     .U_offset       = 1,
   1250     .V_offset       = 0,
   1251     .u_offset       = &_UOffSepYUV,
   1252     .v_offset       = &_VOffSepYUV
   1253 };
   1254 
   1255 /* NV12: 4:2:0, UV are interleaved, V follows U in UV pane */
   1256 static const YUVDesc _NV12 =
   1257 {
   1258     .Y_offset       = 0,
   1259     .Y_inc          = 1,
   1260     .Y_next_pair    = 2,
   1261     .UV_inc         = 2,
   1262     .U_offset       = 0,
   1263     .V_offset       = 1,
   1264     .u_offset       = &_UOffIntrlUV,
   1265     .v_offset       = &_VOffIntrlUV
   1266 };
   1267 
   1268 /* NV21: 4:2:0, UV are interleaved, U follows V in UV pane */
   1269 static const YUVDesc _NV21 =
   1270 {
   1271     .Y_offset       = 0,
   1272     .Y_inc          = 1,
   1273     .Y_next_pair    = 2,
   1274     .UV_inc         = 2,
   1275     .U_offset       = 1,
   1276     .V_offset       = 0,
   1277     .u_offset       = &_UOffIntrlUV,
   1278     .v_offset       = &_VOffIntrlUV
   1279 };
   1280 
   1281 /********************************************************************************
   1282  * RGB bayer format descriptors.
   1283  */
   1284 
   1285 /* Descriptor for a 8-bit GBGB / RGRG format. */
   1286 static const BayerDesc _GB8 =
   1287 {
   1288     .mask           = kBayer8,
   1289     .color_order    = "GBRG"
   1290 };
   1291 
   1292 /* Descriptor for a 8-bit GRGR / BGBG format. */
   1293 static const BayerDesc _GR8 =
   1294 {
   1295     .mask           = kBayer8,
   1296     .color_order    = "GRBG"
   1297 };
   1298 
   1299 /* Descriptor for a 8-bit BGBG / GRGR format. */
   1300 static const BayerDesc _BG8 =
   1301 {
   1302     .mask           = kBayer8,
   1303     .color_order    = "BGGR"
   1304 };
   1305 
   1306 /* Descriptor for a 8-bit RGRG / GBGB format. */
   1307 static const BayerDesc _RG8 =
   1308 {
   1309     .mask           = kBayer8,
   1310     .color_order    = "RGGB"
   1311 };
   1312 
   1313 /* Descriptor for a 10-bit GBGB / RGRG format. */
   1314 static const BayerDesc _GB10 =
   1315 {
   1316     .mask           = kBayer10,
   1317     .color_order    = "GBRG"
   1318 };
   1319 
   1320 /* Descriptor for a 10-bit GRGR / BGBG format. */
   1321 static const BayerDesc _GR10 =
   1322 {
   1323     .mask           = kBayer10,
   1324     .color_order    = "GRBG"
   1325 };
   1326 
   1327 /* Descriptor for a 10-bit BGBG / GRGR format. */
   1328 static const BayerDesc _BG10 =
   1329 {
   1330     .mask           = kBayer10,
   1331     .color_order    = "BGGR"
   1332 };
   1333 
   1334 /* Descriptor for a 10-bit RGRG / GBGB format. */
   1335 static const BayerDesc _RG10 =
   1336 {
   1337     .mask           = kBayer10,
   1338     .color_order    = "RGGB"
   1339 };
   1340 
   1341 /* Descriptor for a 12-bit GBGB / RGRG format. */
   1342 static const BayerDesc _GB12 =
   1343 {
   1344     .mask           = kBayer12,
   1345     .color_order    = "GBRG"
   1346 };
   1347 
   1348 /* Descriptor for a 12-bit GRGR / BGBG format. */
   1349 static const BayerDesc _GR12 =
   1350 {
   1351     .mask           = kBayer12,
   1352     .color_order    = "GRBG"
   1353 };
   1354 
   1355 /* Descriptor for a 12-bit BGBG / GRGR format. */
   1356 static const BayerDesc _BG12 =
   1357 {
   1358     .mask           = kBayer12,
   1359     .color_order    = "BGGR"
   1360 };
   1361 
   1362 /* Descriptor for a 12-bit RGRG / GBGB format. */
   1363 static const BayerDesc _RG12 =
   1364 {
   1365     .mask           = kBayer12,
   1366     .color_order    = "RGGB"
   1367 };
   1368 
   1369 
   1370 /********************************************************************************
   1371  * List of descriptors for supported formats.
   1372  *******************************************************************************/
   1373 
   1374 /* Enumerates pixel formats supported by converters. */
   1375 typedef enum PIXFormatSel {
   1376     /* Pixel format is RGB/BGR */
   1377     PIX_FMT_RGB,
   1378     /* Pixel format is YUV */
   1379     PIX_FMT_YUV,
   1380     /* Pixel format is BAYER */
   1381     PIX_FMT_BAYER
   1382 } PIXFormatSel;
   1383 
   1384 /* Formats entry in the list of descriptors for supported formats. */
   1385 typedef struct PIXFormat {
   1386     /* "FOURCC" (V4L2_PIX_FMT_XXX) format type. */
   1387     uint32_t        fourcc_type;
   1388     /* RGB/YUV/BAYER format selector */
   1389     PIXFormatSel    format_sel;
   1390     union {
   1391         /* References RGB format descriptor for that format. */
   1392         const RGBDesc*      rgb_desc;
   1393         /* References YUV format descriptor for that format. */
   1394         const YUVDesc*      yuv_desc;
   1395         /* References BAYER format descriptor for that format. */
   1396         const BayerDesc*    bayer_desc;
   1397     } desc;
   1398 } PIXFormat;
   1399 
   1400 /* Array of supported pixel format descriptors. */
   1401 static const PIXFormat _PIXFormats[] = {
   1402     /* RGB/BRG formats. */
   1403     { V4L2_PIX_FMT_RGB32,   PIX_FMT_RGB,    .desc.rgb_desc = &_RGB32  },
   1404     { V4L2_PIX_FMT_BGR32,   PIX_FMT_RGB,    .desc.rgb_desc = &_BRG32  },
   1405     { V4L2_PIX_FMT_RGB565,  PIX_FMT_RGB,    .desc.rgb_desc = &_RGB16  },
   1406     { V4L2_PIX_FMT_RGB24,   PIX_FMT_RGB,    .desc.rgb_desc = &_RGB24  },
   1407     { V4L2_PIX_FMT_BGR24,   PIX_FMT_RGB,    .desc.rgb_desc = &_BRG24  },
   1408 
   1409     /* YUV 4:2:0 formats. */
   1410     { V4L2_PIX_FMT_YVU420,  PIX_FMT_YUV,    .desc.yuv_desc = &_YV12   },
   1411     { V4L2_PIX_FMT_YUV420,  PIX_FMT_YUV,    .desc.yuv_desc = &_YU12   },
   1412     { V4L2_PIX_FMT_NV12,    PIX_FMT_YUV,    .desc.yuv_desc = &_NV12   },
   1413     { V4L2_PIX_FMT_NV21,    PIX_FMT_YUV,    .desc.yuv_desc = &_NV21   },
   1414 
   1415     /* YUV 4:2:2 formats. */
   1416     { V4L2_PIX_FMT_YUYV,    PIX_FMT_YUV,    .desc.yuv_desc = &_YUYV   },
   1417     { V4L2_PIX_FMT_YYUV,    PIX_FMT_YUV,    .desc.yuv_desc = &_YYUV   },
   1418     { V4L2_PIX_FMT_YVYU,    PIX_FMT_YUV,    .desc.yuv_desc = &_YVYU   },
   1419     { V4L2_PIX_FMT_UYVY,    PIX_FMT_YUV,    .desc.yuv_desc = &_UYVY   },
   1420     { V4L2_PIX_FMT_VYUY,    PIX_FMT_YUV,    .desc.yuv_desc = &_VYUY   },
   1421     { V4L2_PIX_FMT_YVYU,    PIX_FMT_YUV,    .desc.yuv_desc = &_YVYU   },
   1422     { V4L2_PIX_FMT_VYUY,    PIX_FMT_YUV,    .desc.yuv_desc = &_VYUY   },
   1423     { V4L2_PIX_FMT_YYVU,    PIX_FMT_YUV,    .desc.yuv_desc = &_YYVU   },
   1424     { V4L2_PIX_FMT_YUY2,    PIX_FMT_YUV,    .desc.yuv_desc = &_YUYV   },
   1425     { V4L2_PIX_FMT_YUNV,    PIX_FMT_YUV,    .desc.yuv_desc = &_YUYV   },
   1426     { V4L2_PIX_FMT_V422,    PIX_FMT_YUV,    .desc.yuv_desc = &_YUYV   },
   1427 
   1428     /* BAYER formats. */
   1429     { V4L2_PIX_FMT_SBGGR8,  PIX_FMT_BAYER,  .desc.bayer_desc = &_BG8  },
   1430     { V4L2_PIX_FMT_SGBRG8,  PIX_FMT_BAYER,  .desc.bayer_desc = &_GB8  },
   1431     { V4L2_PIX_FMT_SGRBG8,  PIX_FMT_BAYER,  .desc.bayer_desc = &_GR8  },
   1432     { V4L2_PIX_FMT_SRGGB8,  PIX_FMT_BAYER,  .desc.bayer_desc = &_RG8  },
   1433     { V4L2_PIX_FMT_SBGGR10, PIX_FMT_BAYER,  .desc.bayer_desc = &_BG10 },
   1434     { V4L2_PIX_FMT_SGBRG10, PIX_FMT_BAYER,  .desc.bayer_desc = &_GB10 },
   1435     { V4L2_PIX_FMT_SGRBG10, PIX_FMT_BAYER,  .desc.bayer_desc = &_GR10 },
   1436     { V4L2_PIX_FMT_SRGGB10, PIX_FMT_BAYER,  .desc.bayer_desc = &_RG10 },
   1437     { V4L2_PIX_FMT_SBGGR12, PIX_FMT_BAYER,  .desc.bayer_desc = &_BG12 },
   1438     { V4L2_PIX_FMT_SGBRG12, PIX_FMT_BAYER,  .desc.bayer_desc = &_GB12 },
   1439     { V4L2_PIX_FMT_SGRBG12, PIX_FMT_BAYER,  .desc.bayer_desc = &_GR12 },
   1440     { V4L2_PIX_FMT_SRGGB12, PIX_FMT_BAYER,  .desc.bayer_desc = &_RG12 },
   1441 };
   1442 static const int _PIXFormats_num = sizeof(_PIXFormats) / sizeof(*_PIXFormats);
   1443 
   1444 /* Get an entry in the array of supported pixel format descriptors.
   1445  * Param:
   1446  *  pixel_format - "fourcc" pixel format to lookup an entry for.
   1447  * Return"
   1448  *  Pointer to the found entry, or NULL if no entry exists for the given pixel
   1449  *  format.
   1450  */
   1451 static const PIXFormat*
   1452 _get_pixel_format_descriptor(uint32_t pixel_format)
   1453 {
   1454     int f;
   1455     for (f = 0; f < _PIXFormats_num; f++) {
   1456         if (_PIXFormats[f].fourcc_type == pixel_format) {
   1457             return &_PIXFormats[f];
   1458         }
   1459     }
   1460     W("%s: Pixel format %.4s is unknown",
   1461       __FUNCTION__, (const char*)&pixel_format);
   1462     return NULL;
   1463 }
   1464 
   1465 /********************************************************************************
   1466  * Public API
   1467  *******************************************************************************/
   1468 
   1469 int
   1470 has_converter(uint32_t from, uint32_t to)
   1471 {
   1472     if (from == to) {
   1473         /* Same format: converter esists. */
   1474         return 1;
   1475     }
   1476     return _get_pixel_format_descriptor(from) != NULL &&
   1477            _get_pixel_format_descriptor(to) != NULL;
   1478 }
   1479 
   1480 int
   1481 convert_frame(const void* frame,
   1482               uint32_t pixel_format,
   1483               size_t framebuffer_size,
   1484               int width,
   1485               int height,
   1486               ClientFrameBuffer* framebuffers,
   1487               int fbs_num)
   1488 {
   1489     int n;
   1490     const PIXFormat* src_desc = _get_pixel_format_descriptor(pixel_format);
   1491     if (src_desc == NULL) {
   1492         E("%s: Source pixel format %.4s is unknown",
   1493           __FUNCTION__, (const char*)&pixel_format);
   1494         return -1;
   1495     }
   1496 
   1497     for (n = 0; n < fbs_num; n++) {
   1498         if (framebuffers[n].pixel_format == pixel_format) {
   1499             /* Same pixel format. No conversion needed: just make a copy. */
   1500             memcpy(framebuffers[n].framebuffer, frame, framebuffer_size);
   1501         } else {
   1502             const PIXFormat* dst_desc =
   1503                 _get_pixel_format_descriptor(framebuffers[n].pixel_format);
   1504             if (dst_desc == NULL) {
   1505                 E("%s: Destination pixel format %.4s is unknown",
   1506                   __FUNCTION__, (const char*)&framebuffers[n].pixel_format);
   1507                 return -1;
   1508             }
   1509             switch (src_desc->format_sel) {
   1510                 case PIX_FMT_RGB:
   1511                     if (dst_desc->format_sel == PIX_FMT_RGB) {
   1512                         RGBToRGB(src_desc->desc.rgb_desc, dst_desc->desc.rgb_desc,
   1513                                  frame, framebuffers[n].framebuffer, width, height);
   1514                     } else if (dst_desc->format_sel == PIX_FMT_YUV) {
   1515                         RGBToYUV(src_desc->desc.rgb_desc, dst_desc->desc.yuv_desc,
   1516                                  frame, framebuffers[n].framebuffer, width, height);
   1517                     } else {
   1518                         E("%s: Unexpected destination pixel format %d",
   1519                           __FUNCTION__, dst_desc->format_sel);
   1520                         return -1;
   1521                     }
   1522                     break;
   1523                 case PIX_FMT_YUV:
   1524                     if (dst_desc->format_sel == PIX_FMT_RGB) {
   1525                         YUVToRGB(src_desc->desc.yuv_desc, dst_desc->desc.rgb_desc,
   1526                                  frame, framebuffers[n].framebuffer, width, height);
   1527                     } else if (dst_desc->format_sel == PIX_FMT_YUV) {
   1528                         YUVToYUV(src_desc->desc.yuv_desc, dst_desc->desc.yuv_desc,
   1529                                  frame, framebuffers[n].framebuffer, width, height);
   1530                     } else {
   1531                         E("%s: Unexpected destination pixel format %d",
   1532                           __FUNCTION__, dst_desc->format_sel);
   1533                         return -1;
   1534                     }
   1535                     break;
   1536                 case PIX_FMT_BAYER:
   1537                     if (dst_desc->format_sel == PIX_FMT_RGB) {
   1538                         BAYERToRGB(src_desc->desc.bayer_desc, dst_desc->desc.rgb_desc,
   1539                                   frame, framebuffers[n].framebuffer, width, height);
   1540                     } else if (dst_desc->format_sel == PIX_FMT_YUV) {
   1541                         BAYERToYUV(src_desc->desc.bayer_desc, dst_desc->desc.yuv_desc,
   1542                                    frame, framebuffers[n].framebuffer, width, height);
   1543                     } else {
   1544                         E("%s: Unexpected destination pixel format %d",
   1545                           __FUNCTION__, dst_desc->format_sel);
   1546                         return -1;
   1547                     }
   1548                     break;
   1549                 default:
   1550                     E("%s: Unexpected source pixel format %d",
   1551                       __FUNCTION__, dst_desc->format_sel);
   1552                     return -1;
   1553             }
   1554         }
   1555     }
   1556 
   1557     return 0;
   1558 }
   1559