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
51static const uint16_t kRed5     = 0x001f;
52static const uint16_t kGreen6   = 0x07e0;
53static const uint16_t kBlue5    = 0xf800;
54#else   // !HOST_WORDS_BIGENDIAN
55static const uint16_t kRed5     = 0xf800;
56static const uint16_t kGreen6   = 0x07e0;
57static const uint16_t kBlue5    = 0x001f;
58#endif  // !HOST_WORDS_BIGENDIAN
59
60/*
61 * RGB32 color masks
62 */
63
64#ifndef HOST_WORDS_BIGENDIAN
65static const uint32_t kRed8     = 0x000000ff;
66static const uint32_t kGreen8   = 0x0000ff00;
67static const uint32_t kBlue8    = 0x00ff0000;
68#else   // !HOST_WORDS_BIGENDIAN
69static const uint32_t kRed8     = 0x00ff0000;
70static const uint32_t kGreen8   = 0x0000ff00;
71static 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 */
127typedef 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 */
140static __inline__ int
141clamp(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. */
160static __inline__ void
161R8G8B8ToYUV(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. */
169static __inline__ void
170RGB565ToYUV(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. */
176static __inline__ void
177RGB32ToYUV(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. */
210static __inline__ uint16_t
211YUVToRGB565(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. */
222static __inline__ uint32_t
223YUVToRGB32(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. */
235static __inline__ void
236YUVToRGBPix(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/* Computes a luminance value after taking the exposure compensation.
246 * value into account.
247 *
248 * Param:
249 * inputY - The input luminance value.
250 * Return:
251 * The luminance value after adjusting the exposure compensation.
252 */
253static __inline__ uint8_t
254_change_exposure(uint8_t inputY, float exp_comp)
255{
256    return (uint8_t)clamp((float)inputY * exp_comp);
257}
258
259/* Adjusts an RGB pixel for the given exposure compensation. */
260static __inline__ void
261_change_exposure_RGB(uint8_t* r, uint8_t* g, uint8_t* b, float exp_comp)
262{
263    uint8_t y, u, v;
264    R8G8B8ToYUV(*r, *g, *b, &y, &u, &v);
265    YUVToRGBPix(_change_exposure(y, exp_comp), u, v, r, g, b);
266}
267
268/* Adjusts an RGB pixel for the given exposure compensation. */
269static __inline__ void
270_change_exposure_RGB_i(int* r, int* g, int* b, float exp_comp)
271{
272    uint8_t y, u, v;
273    R8G8B8ToYUV(*r, *g, *b, &y, &u, &v);
274    y = _change_exposure(y, exp_comp);
275    *r = YUV2RO(y,u,v);
276    *g = YUV2GO(y,u,v);
277    *b = YUV2BO(y,u,v);
278}
279
280/* Computes the pixel value after adjusting the white balance to the current
281 * one. The input the y, u, v channel of the pixel and the adjusted value will
282 * be stored in place. The adjustment is done in RGB space.
283 */
284static __inline__ void
285_change_white_balance_YUV(uint8_t* y,
286                          uint8_t* u,
287                          uint8_t* v,
288                          float r_scale,
289                          float g_scale,
290                          float b_scale)
291{
292    int r = (float)(YUV2R((int)*y, (int)*u, (int)*v)) / r_scale;
293    int g = (float)(YUV2G((int)*y, (int)*u, (int)*v)) / g_scale;
294    int b = (float)(YUV2B((int)*y, (int)*u, (int)*v)) / b_scale;
295
296    *y = RGB2Y(r, g, b);
297    *u = RGB2U(r, g, b);
298    *v = RGB2V(r, g, b);
299}
300
301/* Computes the pixel value after adjusting the white balance to the current
302 * one. The input the r, and b channels of the pixel and the adjusted value will
303 * be stored in place.
304 */
305static __inline__ void
306_change_white_balance_RGB(int* r,
307                          int* g,
308                          int* b,
309                          float r_scale,
310                          float g_scale,
311                          float b_scale)
312{
313    *r = (float)*r / r_scale;
314    *g = (float)*g / g_scale;
315    *b = (float)*b / b_scale;
316}
317
318/* Computes the pixel value after adjusting the white balance to the current
319 * one. The input the r, and b channels of the pixel and the adjusted value will
320 * be stored in place.
321 */
322static __inline__ void
323_change_white_balance_RGB_b(uint8_t* r,
324                            uint8_t* g,
325                            uint8_t* b,
326                            float r_scale,
327                            float g_scale,
328                            float b_scale)
329{
330    *r = (float)*r / r_scale;
331    *g = (float)*g / g_scale;
332    *b = (float)*b / b_scale;
333}
334
335/********************************************************************************
336 * Generic converters between YUV and RGB formats
337 *******************************************************************************/
338
339/*
340 * The converters go line by line, convering one frame format to another.
341 * It's pretty much straight forward for RGB/BRG, where all colors are
342 * grouped next to each other in memory. The only two things that differ one RGB
343 * format from another are:
344 * - Is it an RGB, or BRG (i.e. color ordering)
345 * - Is it 16, 24, or 32 bits format.
346 * All these differences are addressed by load_rgb / save_rgb routines, provided
347 * for each format in the RGB descriptor to load / save RGB color bytes from / to
348 * the buffer. As far as moving from one RGB pixel to the next, there
349 * are two question to consider:
350 * - How many bytes it takes to encode one RGB pixel (could be 2, 3, or 4)
351 * - How many bytes it takes to encode a line (i.e. line alignment issue, which
352 *   makes sence only for 24-bit formats, since 16, and 32 bit formats provide
353 *   automatic word alignment.)
354 * The first question is answered with the 'rgb_inc' field of the RGB descriptor,
355 * and the second one is done by aligning rgb pointer up to the nearest 16 bit
356 * boundaries at the end of each line.
357 * YUV format has much greater complexity for conversion. in YUV color encoding
358 * is divided into three separate panes that can be mixed together in any way
359 * imaginable. Fortunately, there are still some consistent patterns in different
360
361 * YUV formats that can be abstracted through a descriptor:
362 * - At the line-by-line level, colors are always groupped aroud pairs of pixels,
363 *   where each pixel in the pair has its own Y value, and each pair of pixels
364 *   share thesame U, and V values.
365 * - Position of Y, U, and V is the same for each pair, so the distance between
366 *   Ys, and U/V for adjacent pairs is the same.
367 * - Inside the pair, the distance between two Ys is always the same.
368
369 * Moving between the lines in YUV can also be easily formalized. Essentially,
370 * there are three ways how color panes are arranged:
371 * 1. All interleaved, where all three Y, U, and V values are encoded together in
372 *    one block:
373 *               1,2  3,4  5,6      n,n+1
374 *              YUVY YUVY YUVY .... YUVY
375 *
376 *    This type is used to encode YUV 4:2:2 formats.
377 *
378 * 2. One separate block of memory for Y pane, and one separate block of memory
379 *    containing interleaved U, and V panes.
380 *
381 *      YY | YY | YY | YY
382 *      YY | YY | YY | YY
383 *      -----------------
384 *      UV | UV | UV | UV
385 *      -----------------
386 *
387 *    This type is used to encode 4:2:0 formats.
388 *
389 * 3. Three separate blocks of memory for each pane.
390 *
391 *      YY | YY | YY | YY
392 *      YY | YY | YY | YY
393 *      -----------------
394 *      U  | U  | U  | U
395 *      V  | V  | V  | V
396 *      -----------------
397 *
398 *    This type is also used to encode 4:2:0 formats.
399 *
400 * Note that in cases 2, and 3 each pair of U and V is shared among four pixels,
401 * grouped together as they are groupped in the framebeffer: divide the frame's
402 * rectangle into 2x2 pixels squares, starting from 0,0 corner - and each square
403 * represents the group of pixels that share same pair of UV values. So, each
404 * line in the U/V panes table is shared between two adjacent lines in Y pane,
405 * which provides a pattern on how to move between U/V lines as we move between
406 * Y lines.
407 *
408 * So, all these patterns can be coded in a YUV format descriptor, so there can
409 * just one generic way of walking YUV frame.
410 *
411 * BAYER format.
412 * We don't use BAYER inside the guest system, so there is no need to have a
413 * converter to the BAYER formats, only from it. The color approximation  used in
414 * the BAYER format converters implemented here simply averages corresponded
415 * color values found in pixels sorrounding the one for which RGB colors are
416 * calculated.
417 *
418 * Performance considerations:
419 * Since converters implemented here are intended to work as part of the camera
420 * emulation, making the code super performant is not a priority at all. There
421 * will be enough loses in other parts of the emultion to overlook any slight
422 * inefficiences in the conversion algorithm as neglectable.
423 */
424
425typedef struct RGBDesc RGBDesc;
426typedef struct YUVDesc YUVDesc;
427typedef struct BayerDesc BayerDesc;
428
429/* Prototype for a routine that loads RGB colors from an RGB/BRG stream.
430 * Param:
431 *  rgb - Pointer to a pixel inside the stream where to load colors from.
432 *  r, g, b - Upon return will contain red, green, and blue colors for the pixel
433 *      addressed by 'rgb' pointer.
434 * Return:
435 *  Pointer to the next pixel in the stream.
436 */
437typedef const void* (*load_rgb_func)(const void* rgb,
438                                     uint8_t* r,
439                                     uint8_t* g,
440                                     uint8_t* b);
441
442/* Prototype for a routine that saves RGB colors to an RGB/BRG stream.
443 * Param:
444 *  rgb - Pointer to a pixel inside the stream where to save colors.
445 *  r, g, b - Red, green, and blue colors to save to the pixel addressed by
446 *      'rgb' pointer.
447 * Return:
448 *  Pointer to the next pixel in the stream.
449 */
450typedef void* (*save_rgb_func)(void* rgb, uint8_t r, uint8_t g, uint8_t b);
451
452/* Prototype for a routine that calculates an offset of the first U value for the
453 * given line in a YUV framebuffer.
454 * Param:
455 *  desc - Descriptor for the YUV frame for which the offset is being calculated.
456 *  line - Zero-based line number for which to calculate the offset.
457 *  width, height - Frame dimensions.
458 * Return:
459 *  Offset of the first U value for the given frame line. The offset returned
460 *  here is relative to the beginning of the YUV framebuffer.
461 */
462typedef int (*u_offset_func)(const YUVDesc* desc, int line, int width, int height);
463
464/* Prototype for a routine that calculates an offset of the first V value for the
465 * given line in a YUV framebuffer.
466 * Param:
467 *  desc - Descriptor for the YUV frame for which the offset is being calculated.
468 *  line - Zero-based line number for which to calculate the offset.
469 *  width, height - Frame dimensions.
470 * Return:
471 *  Offset of the first V value for the given frame line. The offset returned
472 *  here is relative to the beginning of the YUV framebuffer.
473 */
474typedef int (*v_offset_func)(const YUVDesc* desc, int line, int width, int height);
475
476/* RGB/BRG format descriptor. */
477struct RGBDesc {
478    /* Routine that loads RGB colors from a buffer. */
479    load_rgb_func   load_rgb;
480    /* Routine that saves RGB colors into a buffer. */
481    save_rgb_func   save_rgb;
482    /* Byte size of an encoded RGB pixel. */
483    int             rgb_inc;
484};
485
486/* YUV format descriptor. */
487struct YUVDesc {
488    /* Offset of the first Y value in a fully interleaved YUV framebuffer. */
489    int             Y_offset;
490    /* Distance between two Y values inside a pair of pixels in a fully
491     * interleaved YUV framebuffer. */
492    int             Y_inc;
493    /* Distance between first Y values of the adjacent pixel pairs in a fully
494     * interleaved YUV framebuffer. */
495    int             Y_next_pair;
496    /* Increment between adjacent U/V values in a YUV framebuffer. */
497    int             UV_inc;
498    /* Controls location of the first U value in YUV framebuffer. Depending on
499     * the actual YUV format can mean three things:
500     *  - For fully interleaved YUV formats contains offset of the first U value
501     *    in each line.
502     *  - For YUV format that use separate, but interleaved UV pane, this field
503     *    contains an offset of the first U value in the UV pane.
504     *  - For YUV format that use fully separated Y, U, and V panes this field
505     *    defines order of U and V panes in the framebuffer:
506     *      = 1 - U pane comes first, right after Y pane.
507     *      = 0 - U pane follows V pane that startes right after Y pane. */
508    int             U_offset;
509    /* Controls location of the first V value in YUV framebuffer.
510     * See comments to U_offset for more info. */
511    int             V_offset;
512    /* Routine that calculates an offset of the first U value for the given line
513     * in a YUV framebuffer. */
514    u_offset_func   u_offset;
515    /* Routine that calculates an offset of the first V value for the given line
516     * in a YUV framebuffer. */
517    v_offset_func   v_offset;
518};
519
520/* Bayer format descriptor. */
521struct BayerDesc {
522    /* Defines color ordering in the BAYER framebuffer. Can be one of the four:
523     *  - "GBRG" for GBGBGB / RGRGRG
524     *  - "GRBG" for GRGRGR / BGBGBG
525     *  - "RGGB" for RGRGRG / GBGBGB
526     *  - "BGGR" for BGBGBG / GRGRGR
527     */
528    const char* color_order;
529    /* Bitmask for valid bits in the pixel:
530     *  - 0xff  For a 8-bit BAYER format
531     *  - 0x3ff For a 10-bit BAYER format
532     *  - 0xfff For a 12-bit BAYER format
533     */
534    int         mask;
535};
536
537/********************************************************************************
538 * RGB/BRG load / save routines.
539 *******************************************************************************/
540
541/* Loads R, G, and B colors from a RGB32 framebuffer. */
542static const void*
543_load_RGB32(const void* rgb, uint8_t* r, uint8_t* g, uint8_t* b)
544{
545    const uint8_t* rgb_ptr = (const uint8_t*)rgb;
546    *r = rgb_ptr[0]; *g = rgb_ptr[1]; *b = rgb_ptr[2];
547    return rgb_ptr + 4;
548}
549
550/* Saves R, G, and B colors to a RGB32 framebuffer. */
551static void*
552_save_RGB32(void* rgb, uint8_t r, uint8_t g, uint8_t b)
553{
554    uint8_t* rgb_ptr = (uint8_t*)rgb;
555    rgb_ptr[0] = r; rgb_ptr[1] = g; rgb_ptr[2] = b;
556    return rgb_ptr + 4;
557}
558
559/* Loads R, G, and B colors from a BRG32 framebuffer. */
560static const void*
561_load_BRG32(const void* rgb, uint8_t* r, uint8_t* g, uint8_t* b)
562{
563    const uint8_t* rgb_ptr = (const uint8_t*)rgb;
564    *r = rgb_ptr[2]; *g = rgb_ptr[1]; *b = rgb_ptr[0];
565    return rgb_ptr + 4;
566}
567
568/* Saves R, G, and B colors to a BRG32 framebuffer. */
569static void*
570_save_BRG32(void* rgb, uint8_t r, uint8_t g, uint8_t b)
571{
572    uint8_t* rgb_ptr = (uint8_t*)rgb;
573    rgb_ptr[2] = r; rgb_ptr[1] = g; rgb_ptr[0] = b;
574    return rgb_ptr + 4;
575}
576
577/* Loads R, G, and B colors from a RGB24 framebuffer.
578 * Note that it's the caller's responsibility to ensure proper alignment of the
579 * returned pointer at the line's break. */
580static const void*
581_load_RGB24(const void* rgb, uint8_t* r, uint8_t* g, uint8_t* b)
582{
583    const uint8_t* rgb_ptr = (const uint8_t*)rgb;
584    *r = rgb_ptr[0]; *g = rgb_ptr[1]; *b = rgb_ptr[2];
585    return rgb_ptr + 3;
586}
587
588/* Saves R, G, and B colors to a RGB24 framebuffer.
589 * Note that it's the caller's responsibility to ensure proper alignment of the
590 * returned pointer at the line's break. */
591static void*
592_save_RGB24(void* rgb, uint8_t r, uint8_t g, uint8_t b)
593{
594    uint8_t* rgb_ptr = (uint8_t*)rgb;
595    rgb_ptr[0] = r; rgb_ptr[1] = g; rgb_ptr[2] = b;
596    return rgb_ptr + 3;
597}
598
599/* Loads R, G, and B colors from a BRG32 framebuffer.
600 * Note that it's the caller's responsibility to ensure proper alignment of the
601 * returned pointer at the line's break. */
602static const void*
603_load_BRG24(const void* rgb, uint8_t* r, uint8_t* g, uint8_t* b)
604{
605    const uint8_t* rgb_ptr = (const uint8_t*)rgb;
606    *r = rgb_ptr[2]; *g = rgb_ptr[1]; *b = rgb_ptr[0];
607    return rgb_ptr + 3;
608}
609
610/* Saves R, G, and B colors to a BRG24 framebuffer.
611 * Note that it's the caller's responsibility to ensure proper alignment of the
612 * returned pointer at the line's break. */
613static void*
614_save_BRG24(void* rgb, uint8_t r, uint8_t g, uint8_t b)
615{
616    uint8_t* rgb_ptr = (uint8_t*)rgb;
617    rgb_ptr[2] = r; rgb_ptr[1] = g; rgb_ptr[0] = b;
618    return rgb_ptr + 3;
619}
620
621/* Loads R, G, and B colors from a RGB565 framebuffer. */
622static const void*
623_load_RGB16(const void* rgb, uint8_t* r, uint8_t* g, uint8_t* b)
624{
625    const uint16_t rgb16 = *(const uint16_t*)rgb;
626    *r = R16(rgb16); *g = G16(rgb16); *b = B16(rgb16);
627    return (const uint8_t*)rgb + 2;
628}
629
630/* Saves R, G, and B colors to a RGB565 framebuffer. */
631static void*
632_save_RGB16(void* rgb, uint8_t r, uint8_t g, uint8_t b)
633{
634    *(uint16_t*)rgb = RGB565(r & 0x1f, g & 0x3f, b & 0x1f);
635    return (uint8_t*)rgb + 2;
636}
637
638/* Loads R, G, and B colors from a BRG565 framebuffer. */
639static const void*
640_load_BRG16(const void* rgb, uint8_t* r, uint8_t* g, uint8_t* b)
641{
642    const uint16_t rgb16 = *(const uint16_t*)rgb;
643    *r = B16(rgb16); *g = G16(rgb16); *b = R16(rgb16);
644    return (const uint8_t*)rgb + 2;
645}
646
647/* Saves R, G, and B colors to a BRG565 framebuffer. */
648static void*
649_save_BRG16(void* rgb, uint8_t r, uint8_t g, uint8_t b)
650{
651    *(uint16_t*)rgb = RGB565(b & 0x1f, g & 0x3f, r & 0x1f);
652    return (uint8_t*)rgb + 2;
653}
654
655/********************************************************************************
656 * YUV's U/V offset calculation routines.
657 *******************************************************************************/
658
659/* U offset in a fully interleaved YUV 4:2:2 */
660static int
661_UOffIntrlYUV(const YUVDesc* desc, int line, int width, int height)
662{
663    /* In interleaved YUV 4:2:2 each pair of pixels is encoded with 4 consecutive
664     * bytes (or 2 bytes per pixel). So line size in a fully interleaved YUV 4:2:2
665     * is twice its width. */
666    return line * width * 2 + desc->U_offset;
667}
668
669/* V offset in a fully interleaved YUV 4:2:2 */
670static int
671_VOffIntrlYUV(const YUVDesc* desc, int line, int width, int height)
672{
673    /* See _UOffIntrlYUV comments. */
674    return line * width * 2 + desc->V_offset;
675}
676
677/* U offset in an interleaved UV pane of YUV 4:2:0 */
678static int
679_UOffIntrlUV(const YUVDesc* desc, int line, int width, int height)
680{
681    /* UV pane starts right after the Y pane, that occupies 'height * width'
682     * bytes. Eacht line in UV pane contains width / 2 'UV' pairs, which makes UV
683     * lane to contain as many bytes, as the width is.
684     * Each line in the UV pane is shared between two Y lines. So, final formula
685     * for the beggining of the UV pane's line for the given line in YUV
686     * framebuffer is:
687     *
688     *    height * width + (line / 2) * width = (height + line / 2) * width
689     */
690    return (height + line / 2) * width + desc->U_offset;
691}
692
693/* V offset in an interleaved UV pane of YUV 4:2:0 */
694static int
695_VOffIntrlUV(const YUVDesc* desc, int line, int width, int height)
696{
697    /* See comments in _UOffIntrlUV. */
698    return (height + line / 2) * width + desc->V_offset;
699}
700
701/* U offset in a 3-pane YUV 4:2:0 */
702static int
703_UOffSepYUV(const YUVDesc* desc, int line, int width, int height)
704{
705    /* U, or V pane starts right after the Y pane, that occupies 'height * width'
706     * bytes. Eacht line in each of U and V panes contains width / 2 elements.
707     * Also, each line in each of U and V panes is shared between two Y lines.
708     * So, final formula for the beggining of a line in the U/V pane is:
709     *
710     *    <Y pane size> + (line / 2) * width / 2
711     *
712     * for the pane that follows right after the Y pane, or
713     *
714     *    <Y pane size> + <Y pane size> / 4 + (line / 2) * width / 2
715     *
716     * for the second pane.
717     */
718    const int y_pane_size = height * width;
719    if (desc->U_offset) {
720        /* U pane comes right after the Y pane. */
721        return y_pane_size + (line / 2) * width / 2;
722    } else {
723        /* U pane follows V pane. */
724        return y_pane_size + y_pane_size / 4 + (line / 2) * width / 2;
725    }
726}
727
728/* V offset in a 3-pane YUV 4:2:0 */
729static int
730_VOffSepYUV(const YUVDesc* desc, int line, int width, int height)
731{
732    /* See comment for _UOffSepYUV. */
733    const int y_pane_size = height * width;
734    if (desc->V_offset) {
735        /* V pane comes right after the Y pane. */
736        return y_pane_size + (line / 2) * width / 2;
737    } else {
738        /* V pane follows U pane. */
739        return y_pane_size + y_pane_size / 4 + (line / 2) * width / 2;
740    }
741}
742
743/********************************************************************************
744 * Bayer routines.
745 *******************************************************************************/
746
747/* Gets a color value for the given pixel in a bayer framebuffer.
748 * Param:
749 *  desc - Bayer framebuffer descriptor.
750 *  buf - Beginning of the framebuffer.
751 *  x, y - Coordinates of the pixel inside the framebuffer to get the color for.
752 *  width - Number of pixel in a line inside the framebuffer.
753 * Return:
754 *  Given pixel color.
755 */
756static __inline__ int
757_get_bayer_color(const BayerDesc* desc, const void* buf, int x, int y, int width)
758{
759    if (desc->mask == kBayer8) {
760        /* Each pixel is represented with one byte. */
761        return *((const uint8_t*)buf + y * width + x);
762    } else {
763#ifndef HOST_WORDS_BIGENDIAN
764        return *((const int16_t*)buf + y * width + x) & desc->mask;
765#else
766        const uint8_t* pixel = (const uint8_t*)buf + (y * width + x) * 2;
767        return (((uint16_t)pixel[1] << 8) | pixel[0]) & desc->mask;
768#endif  /* !HOST_WORDS_BIGENDIAN */
769    }
770}
771
772/* Gets an average value of colors that are horisontally adjacent to a pixel in
773 * a bayer framebuffer.
774 * Param:
775 *  desc - Bayer framebuffer descriptor.
776 *  buf - Beginning of the framebuffer.
777 *  x, y - Coordinates of the pixel inside the framebuffer that is the center for
778 *      the calculation.
779 *  width, height - Framebuffer dimensions.
780 * Return:
781 *  Average color for horisontally adjacent pixels.
782 */
783static int
784_get_bayer_ave_hor(const BayerDesc* desc,
785                   const void* buf,
786                   int x,
787                   int y,
788                   int width,
789                   int height)
790{
791    if (x == 0) {
792        return _get_bayer_color(desc, buf, x + 1, y, width);
793    } else if (x == (width - 1)) {
794        return _get_bayer_color(desc, buf, x - 1, y, width);
795    } else {
796        return (_get_bayer_color(desc, buf, x - 1, y, width) +
797                _get_bayer_color(desc, buf, x + 1, y, width)) / 2;
798    }
799}
800
801/* Gets an average value of colors that are vertically adjacent to a pixel in
802 * a bayer framebuffer.
803 * Param:
804 *  desc - Bayer framebuffer descriptor.
805 *  buf - Beginning of the framebuffer.
806 *  x, y - Coordinates of the pixel inside the framebuffer that is the center for
807 *      the calculation.
808 *  width, height - Framebuffer dimensions.
809 * Return:
810 *  Average color for vertically adjacent pixels.
811 */
812static int
813_get_bayer_ave_vert(const BayerDesc* desc,
814                    const void* buf,
815                    int x,
816                    int y,
817                    int width,
818                    int height)
819{
820    if (y == 0) {
821        return _get_bayer_color(desc, buf, x, y + 1, width);
822    } else if (y == (height - 1)) {
823        return _get_bayer_color(desc, buf, x, y - 1, width);
824    } else {
825        return (_get_bayer_color(desc, buf, x, y - 1, width) +
826                _get_bayer_color(desc, buf, x, y + 1, width)) / 2;
827    }
828}
829
830/* Gets an average value of colors that are horisontally and vertically adjacent
831 * to a pixel in a bayer framebuffer.
832 * Param:
833 *  desc - Bayer framebuffer descriptor.
834 *  buf - Beginning of the framebuffer.
835 *  x, y - Coordinates of the pixel inside the framebuffer that is the center for
836 *      the calculation.
837 *  width, height - Framebuffer dimensions.
838 * Return:
839 *  Average color for horisontally and vertically adjacent pixels.
840 */
841static int
842_get_bayer_ave_cross(const BayerDesc* desc,
843                     const void* buf,
844                     int x,
845                     int y,
846                     int width,
847                     int height)
848{
849    if (x > 0 && x < (width - 1) && y > 0 && y < (height - 1)) {
850        /* Most of the time the code will take this path. So it makes sence to
851         * special case it for performance reasons. */
852        return (_get_bayer_color(desc, buf, x - 1, y, width) +
853                _get_bayer_color(desc, buf, x + 1, y, width) +
854                _get_bayer_color(desc, buf, x, y - 1, width) +
855                _get_bayer_color(desc, buf, x, y + 1, width)) / 4;
856    } else {
857        int sum = 0;
858        int num = 0;
859
860        /* Horisontal sum */
861        if (x == 0) {
862            sum += _get_bayer_color(desc, buf, x + 1, y, width);
863            num++;
864        } else if (x == (width - 1)) {
865            sum += _get_bayer_color(desc, buf, x - 1, y, width);
866            num++;
867        } else {
868            sum += _get_bayer_color(desc, buf, x - 1, y, width) +
869                   _get_bayer_color(desc, buf, x + 1, y, width);
870            num += 2;
871        }
872
873        /* Vertical sum */
874        if (y == 0) {
875            sum += _get_bayer_color(desc, buf, x, y + 1, width);
876            num++;
877        } else if (y == (height - 1)) {
878            sum += _get_bayer_color(desc, buf, x, y - 1, width);
879            num++;
880        } else {
881            sum += _get_bayer_color(desc, buf, x, y - 1, width) +
882                   _get_bayer_color(desc, buf, x, y + 1, width);
883            num += 2;
884        }
885
886        return sum / num;
887    }
888}
889
890/* Gets an average value of colors that are diagonally adjacent to a pixel in a
891 * bayer framebuffer.
892 * Param:
893 *  desc - Bayer framebuffer descriptor.
894 *  buf - Beginning of the framebuffer.
895 *  x, y - Coordinates of the pixel inside the framebuffer that is the center for
896 *      the calculation.
897 *  width, height - Framebuffer dimensions.
898 * Return:
899 *  Average color for diagonally adjacent pixels.
900 */
901static int
902_get_bayer_ave_diag(const BayerDesc* desc,
903                    const void* buf,
904                    int x,
905                    int y,
906                    int width,
907                    int height)
908{
909    if (x > 0 && x < (width - 1) && y > 0 && y < (height - 1)) {
910        /* Most of the time the code will take this path. So it makes sence to
911         * special case it for performance reasons. */
912        return (_get_bayer_color(desc, buf, x - 1, y - 1, width) +
913                _get_bayer_color(desc, buf, x + 1, y - 1, width) +
914                _get_bayer_color(desc, buf, x - 1, y + 1, width) +
915                _get_bayer_color(desc, buf, x + 1, y + 1, width)) / 4;
916    } else {
917        int sum = 0;
918        int num = 0;
919        int xx, yy;
920        for (xx = x - 1; xx < (x + 2); xx += 2) {
921            for (yy = y - 1; yy < (y + 2); yy += 2) {
922                if (xx >= 0 && yy >= 0 && xx < width && yy < height) {
923                    sum += _get_bayer_color(desc, buf, xx, yy, width);
924                    num++;
925                }
926            }
927        }
928        return sum / num;
929    }
930}
931
932/* Gets pixel color selector for the given pixel in a bayer framebuffer.
933 * Param:
934 *  desc - Bayer framebuffer descriptor.
935 *  x, y - Coordinates of the pixel inside the framebuffer to get the color
936 *      selector for.
937 * Return:
938 *  Pixel color selector:
939 *      - 'R' - pixel is red.
940 *      - 'G' - pixel is green.
941 *      - 'B' - pixel is blue.
942 */
943static __inline__ char
944_get_bayer_color_sel(const BayerDesc* desc, int x, int y)
945{
946    return desc->color_order[((y & 1) << 1) | (x & 1)];
947}
948
949/* Calculates RGB colors for a pixel in a bayer framebuffer.
950 * Param:
951 *  desc - Bayer framebuffer descriptor.
952 *  buf - Beginning of the framebuffer.
953 *  x, y - Coordinates of the pixel inside the framebuffer to get the colors for.
954 *  width, height - Framebuffer dimensions.
955 *  red, green bluu - Upon return will contain RGB colors calculated for the pixel.
956 */
957static void
958_get_bayerRGB(const BayerDesc* desc,
959              const void* buf,
960              int x,
961              int y,
962              int width,
963              int height,
964              int* red,
965              int* green,
966              int* blue)
967{
968    const char pixel_color = _get_bayer_color_sel(desc, x, y);
969
970    if (pixel_color == 'G') {
971        /* This is a green pixel. */
972        const char next_pixel_color = _get_bayer_color_sel(desc, x + 1, y);
973        *green = _get_bayer_color(desc, buf, x, y, width);
974        if (next_pixel_color == 'R') {
975            *red = _get_bayer_ave_hor(desc, buf, x, y, width, height);
976            *blue = _get_bayer_ave_vert(desc, buf, x, y, width, height);
977        } else {
978            *red = _get_bayer_ave_vert(desc, buf, x, y, width, height);
979            *blue = _get_bayer_ave_hor(desc, buf, x, y, width, height);
980        }
981    } else if (pixel_color == 'R') {
982        /* This is a red pixel. */
983        *red = _get_bayer_color(desc, buf, x, y, width);
984        *green = _get_bayer_ave_cross(desc, buf, x, y, width, height);
985        *blue = _get_bayer_ave_diag(desc, buf, x, y, width, height);
986    } else {
987        /* This is a blue pixel. */
988        *blue = _get_bayer_color(desc, buf, x, y, width);
989        *green = _get_bayer_ave_cross(desc, buf, x, y, width, height);
990        *red = _get_bayer_ave_diag(desc, buf, x, y, width, height);
991    }
992}
993
994/********************************************************************************
995 * Generic YUV/RGB/BAYER converters
996 *******************************************************************************/
997
998/* Generic converter from an RGB/BRG format to a YUV format. */
999static void
1000RGBToYUV(const RGBDesc* rgb_fmt,
1001         const YUVDesc* yuv_fmt,
1002         const void* rgb,
1003         void* yuv,
1004         int width,
1005         int height,
1006         float r_scale,
1007         float g_scale,
1008         float b_scale,
1009         float exp_comp)
1010{
1011    int y, x;
1012    const int Y_Inc = yuv_fmt->Y_inc;
1013    const int UV_inc = yuv_fmt->UV_inc;
1014    const int Y_next_pair = yuv_fmt->Y_next_pair;
1015    uint8_t* pY = (uint8_t*)yuv + yuv_fmt->Y_offset;
1016    for (y = 0; y < height; y++) {
1017        uint8_t* pU =
1018            (uint8_t*)yuv + yuv_fmt->u_offset(yuv_fmt, y, width, height);
1019        uint8_t* pV =
1020            (uint8_t*)yuv + yuv_fmt->v_offset(yuv_fmt, y, width, height);
1021        for (x = 0; x < width; x += 2,
1022                               pY += Y_next_pair, pU += UV_inc, pV += UV_inc) {
1023            uint8_t r, g, b;
1024            rgb = rgb_fmt->load_rgb(rgb, &r, &g, &b);
1025            _change_white_balance_RGB_b(&r, &g, &b, r_scale, g_scale, b_scale);
1026            _change_exposure_RGB(&r, &g, &b, exp_comp);
1027            R8G8B8ToYUV(r, g, b, pY, pU, pV);
1028            rgb = rgb_fmt->load_rgb(rgb, &r, &g, &b);
1029            _change_white_balance_RGB_b(&r, &g, &b, r_scale, g_scale, b_scale);
1030            _change_exposure_RGB(&r, &g, &b, exp_comp);
1031            pY[Y_Inc] = RGB2Y((int)r, (int)g, (int)b);
1032        }
1033        /* Aling rgb_ptr to 16 bit */
1034        if (((uintptr_t)rgb & 1) != 0) rgb = (const uint8_t*)rgb + 1;
1035    }
1036}
1037
1038/* Generic converter from one RGB/BRG format to another RGB/BRG format. */
1039static void
1040RGBToRGB(const RGBDesc* src_rgb_fmt,
1041         const RGBDesc* dst_rgb_fmt,
1042         const void* src_rgb,
1043         void* dst_rgb,
1044         int width,
1045         int height,
1046         float r_scale,
1047         float g_scale,
1048         float b_scale,
1049         float exp_comp)
1050{
1051    int x, y;
1052    for (y = 0; y < height; y++) {
1053        for (x = 0; x < width; x++) {
1054            uint8_t r, g, b;
1055            src_rgb = src_rgb_fmt->load_rgb(src_rgb, &r, &g, &b);
1056            _change_white_balance_RGB_b(&r, &g, &b, r_scale, g_scale, b_scale);
1057            _change_exposure_RGB(&r, &g, &b, exp_comp);
1058            dst_rgb = dst_rgb_fmt->save_rgb(dst_rgb, r, g, b);
1059        }
1060        /* Aling rgb pinters to 16 bit */
1061        if (((uintptr_t)src_rgb & 1) != 0) src_rgb = (uint8_t*)src_rgb + 1;
1062        if (((uintptr_t)dst_rgb & 1) != 0) dst_rgb = (uint8_t*)dst_rgb + 1;
1063    }
1064}
1065
1066/* Generic converter from a YUV format to an RGB/BRG format. */
1067static void
1068YUVToRGB(const YUVDesc* yuv_fmt,
1069         const RGBDesc* rgb_fmt,
1070         const void* yuv,
1071         void* rgb,
1072         int width,
1073         int height,
1074         float r_scale,
1075         float g_scale,
1076         float b_scale,
1077         float exp_comp)
1078{
1079    int y, x;
1080    const int Y_Inc = yuv_fmt->Y_inc;
1081    const int UV_inc = yuv_fmt->UV_inc;
1082    const int Y_next_pair = yuv_fmt->Y_next_pair;
1083    const uint8_t* pY = (const uint8_t*)yuv + yuv_fmt->Y_offset;
1084    for (y = 0; y < height; y++) {
1085        const uint8_t* pU =
1086            (const uint8_t*)yuv + yuv_fmt->u_offset(yuv_fmt, y, width, height);
1087        const uint8_t* pV =
1088            (const uint8_t*)yuv + yuv_fmt->v_offset(yuv_fmt, y, width, height);
1089        for (x = 0; x < width; x += 2,
1090                               pY += Y_next_pair, pU += UV_inc, pV += UV_inc) {
1091            uint8_t r, g, b;
1092            const uint8_t U = *pU;
1093            const uint8_t V = *pV;
1094            YUVToRGBPix(*pY, U, V, &r, &g, &b);
1095            _change_white_balance_RGB_b(&r, &g, &b, r_scale, g_scale, b_scale);
1096            _change_exposure_RGB(&r, &g, &b, exp_comp);
1097            rgb = rgb_fmt->save_rgb(rgb, r, g, b);
1098            YUVToRGBPix(pY[Y_Inc], U, V, &r, &g, &b);
1099            _change_white_balance_RGB_b(&r, &g, &b, r_scale, g_scale, b_scale);
1100            _change_exposure_RGB(&r, &g, &b, exp_comp);
1101            rgb = rgb_fmt->save_rgb(rgb, r, g, b);
1102        }
1103        /* Aling rgb_ptr to 16 bit */
1104        if (((uintptr_t)rgb & 1) != 0) rgb = (uint8_t*)rgb + 1;
1105    }
1106}
1107
1108/* Generic converter from one YUV format to another YUV format. */
1109static void
1110YUVToYUV(const YUVDesc* src_fmt,
1111         const YUVDesc* dst_fmt,
1112         const void* src,
1113         void* dst,
1114         int width,
1115         int height,
1116         float r_scale,
1117         float g_scale,
1118         float b_scale,
1119         float exp_comp)
1120{
1121    int y, x;
1122    const int Y_Inc_src = src_fmt->Y_inc;
1123    const int UV_inc_src = src_fmt->UV_inc;
1124    const int Y_next_pair_src = src_fmt->Y_next_pair;
1125    const int Y_Inc_dst = dst_fmt->Y_inc;
1126    const int UV_inc_dst = dst_fmt->UV_inc;
1127    const int Y_next_pair_dst = dst_fmt->Y_next_pair;
1128    const uint8_t* pYsrc = (const uint8_t*)src + src_fmt->Y_offset;
1129    uint8_t* pYdst = (uint8_t*)dst + dst_fmt->Y_offset;
1130    for (y = 0; y < height; y++) {
1131        const uint8_t* pUsrc =
1132            (const uint8_t*)src + src_fmt->u_offset(src_fmt, y, width, height);
1133        const uint8_t* pVsrc =
1134            (const uint8_t*)src + src_fmt->v_offset(src_fmt, y, width, height);
1135        uint8_t* pUdst =
1136            (uint8_t*)dst + dst_fmt->u_offset(dst_fmt, y, width, height);
1137        uint8_t* pVdst =
1138            (uint8_t*)dst + dst_fmt->v_offset(dst_fmt, y, width, height);
1139        for (x = 0; x < width; x += 2, pYsrc += Y_next_pair_src,
1140                                       pUsrc += UV_inc_src,
1141                                       pVsrc += UV_inc_src,
1142                                       pYdst += Y_next_pair_dst,
1143                                       pUdst += UV_inc_dst,
1144                                       pVdst += UV_inc_dst) {
1145            *pYdst = *pYsrc; *pUdst = *pUsrc; *pVdst = *pVsrc;
1146            _change_white_balance_YUV(pYdst, pUdst, pVdst, r_scale, g_scale, b_scale);
1147            *pYdst = _change_exposure(*pYdst, exp_comp);
1148            pYdst[Y_Inc_dst] = _change_exposure(pYsrc[Y_Inc_src], exp_comp);
1149        }
1150    }
1151}
1152
1153/* Generic converter from a BAYER format to an RGB/BRG format. */
1154static void
1155BAYERToRGB(const BayerDesc* bayer_fmt,
1156           const RGBDesc* rgb_fmt,
1157           const void* bayer,
1158           void* rgb,
1159           int width,
1160           int height,
1161           float r_scale,
1162           float g_scale,
1163           float b_scale,
1164           float exp_comp)
1165{
1166    int y, x;
1167    for (y = 0; y < height; y++) {
1168        for (x = 0; x < width; x++) {
1169            int r, g, b;
1170            _get_bayerRGB(bayer_fmt, bayer, x, y, width, height, &r, &g, &b);
1171            if (bayer_fmt->mask == kBayer10) {
1172                r >>= 2; g >>= 2; b >>= 2;
1173            } else if (bayer_fmt->mask == kBayer12) {
1174                r >>= 4; g >>= 4; b >>= 4;
1175            }
1176            _change_white_balance_RGB(&r, &g, &b, r_scale, g_scale, b_scale);
1177            _change_exposure_RGB_i(&r, &g, &b, exp_comp);
1178            rgb = rgb_fmt->save_rgb(rgb, r, g, b);
1179        }
1180        /* Aling rgb_ptr to 16 bit */
1181        if (((uintptr_t)rgb & 1) != 0) rgb = (uint8_t*)rgb + 1;
1182    }
1183}
1184
1185/* Generic converter from a BAYER format to a YUV format. */
1186static void
1187BAYERToYUV(const BayerDesc* bayer_fmt,
1188           const YUVDesc* yuv_fmt,
1189           const void* bayer,
1190           void* yuv,
1191           int width,
1192           int height,
1193           float r_scale,
1194           float g_scale,
1195           float b_scale,
1196           float exp_comp)
1197{
1198    int y, x;
1199    const int Y_Inc = yuv_fmt->Y_inc;
1200    const int UV_inc = yuv_fmt->UV_inc;
1201    const int Y_next_pair = yuv_fmt->Y_next_pair;
1202    uint8_t* pY = (uint8_t*)yuv + yuv_fmt->Y_offset;
1203    for (y = 0; y < height; y++) {
1204        uint8_t* pU =
1205            (uint8_t*)yuv + yuv_fmt->u_offset(yuv_fmt, y, width, height);
1206        uint8_t* pV =
1207            (uint8_t*)yuv + yuv_fmt->v_offset(yuv_fmt, y, width, height);
1208        for (x = 0; x < width; x += 2,
1209                               pY += Y_next_pair, pU += UV_inc, pV += UV_inc) {
1210            int r, g, b;
1211            _get_bayerRGB(bayer_fmt, bayer, x, y, width, height, &r, &g, &b);
1212            _change_white_balance_RGB(&r, &g, &b, r_scale, g_scale, b_scale);
1213            _change_exposure_RGB_i(&r, &g, &b, exp_comp);
1214            R8G8B8ToYUV(r, g, b, pY, pU, pV);
1215            _get_bayerRGB(bayer_fmt, bayer, x + 1, y, width, height, &r, &g, &b);
1216            _change_white_balance_RGB(&r, &g, &b, r_scale, g_scale, b_scale);
1217            _change_exposure_RGB_i(&r, &g, &b, exp_comp);
1218            pY[Y_Inc] = RGB2Y(r, g, b);
1219        }
1220    }
1221}
1222
1223/********************************************************************************
1224 * RGB format descriptors.
1225 */
1226
1227/* Describes RGB32 format. */
1228static const RGBDesc _RGB32 =
1229{
1230    .load_rgb   = _load_RGB32,
1231    .save_rgb   = _save_RGB32,
1232    .rgb_inc    = 4
1233};
1234
1235/* Describes BRG32 format. */
1236static const RGBDesc _BRG32 =
1237{
1238    .load_rgb   = _load_BRG32,
1239    .save_rgb   = _save_BRG32,
1240    .rgb_inc    = 4
1241};
1242
1243/* Describes RGB24 format. */
1244static const RGBDesc _RGB24 =
1245{
1246    .load_rgb   = _load_RGB24,
1247    .save_rgb   = _save_RGB24,
1248    .rgb_inc    = 3
1249};
1250
1251/* Describes BRG24 format. */
1252static const RGBDesc _BRG24 =
1253{
1254    .load_rgb   = _load_BRG24,
1255    .save_rgb   = _save_BRG24,
1256    .rgb_inc    = 3
1257};
1258
1259/* Describes RGB16 format. */
1260static const RGBDesc _RGB16 =
1261{
1262    .load_rgb   = _load_RGB16,
1263    .save_rgb   = _save_RGB16,
1264    .rgb_inc    = 2
1265};
1266
1267/* Describes BRG16 format. */
1268static const RGBDesc _BRG16 =
1269{
1270    .load_rgb   = _load_BRG16,
1271    .save_rgb   = _save_BRG16,
1272    .rgb_inc    = 2
1273};
1274
1275/********************************************************************************
1276 * YUV 4:2:2 format descriptors.
1277 */
1278
1279/* YUYV: 4:2:2, YUV are interleaved. */
1280static const YUVDesc _YUYV =
1281{
1282    .Y_offset       = 0,
1283    .Y_inc          = 2,
1284    .Y_next_pair    = 4,
1285    .UV_inc         = 4,
1286    .U_offset       = 1,
1287    .V_offset       = 3,
1288    .u_offset       = &_UOffIntrlYUV,
1289    .v_offset       = &_VOffIntrlYUV
1290};
1291
1292/* UYVY: 4:2:2, YUV are interleaved. */
1293static const YUVDesc _UYVY =
1294{
1295    .Y_offset       = 1,
1296    .Y_inc          = 2,
1297    .Y_next_pair    = 4,
1298    .UV_inc         = 4,
1299    .U_offset       = 0,
1300    .V_offset       = 2,
1301    .u_offset       = &_UOffIntrlYUV,
1302    .v_offset       = &_VOffIntrlYUV
1303};
1304
1305/* YVYU: 4:2:2, YUV are interleaved. */
1306static const YUVDesc _YVYU =
1307{
1308    .Y_offset       = 0,
1309    .Y_inc          = 2,
1310    .Y_next_pair    = 4,
1311    .UV_inc         = 4,
1312    .U_offset       = 3,
1313    .V_offset       = 1,
1314    .u_offset       = &_UOffIntrlYUV,
1315    .v_offset       = &_VOffIntrlYUV
1316};
1317
1318/* VYUY: 4:2:2, YUV are interleaved. */
1319static const YUVDesc _VYUY =
1320{
1321    .Y_offset       = 1,
1322    .Y_inc          = 2,
1323    .Y_next_pair    = 4,
1324    .UV_inc         = 4,
1325    .U_offset       = 2,
1326    .V_offset       = 0,
1327    .u_offset       = &_UOffIntrlYUV,
1328    .v_offset       = &_VOffIntrlYUV
1329};
1330
1331/* YYUV (also YUY2, YUNV, V422) : 4:2:2, YUV are interleaved. */
1332static const YUVDesc _YYUV =
1333{
1334    .Y_offset       = 0,
1335    .Y_inc          = 1,
1336    .Y_next_pair    = 4,
1337    .UV_inc         = 4,
1338    .U_offset       = 2,
1339    .V_offset       = 3,
1340    .u_offset       = &_UOffIntrlYUV,
1341    .v_offset       = &_VOffIntrlYUV
1342};
1343
1344/* YYVU: 4:2:2, YUV are interleaved. */
1345static const YUVDesc _YYVU =
1346{
1347    .Y_offset       = 0,
1348    .Y_inc          = 1,
1349    .Y_next_pair    = 4,
1350    .UV_inc         = 4,
1351    .U_offset       = 3,
1352    .V_offset       = 2,
1353    .u_offset       = &_UOffIntrlYUV,
1354    .v_offset       = &_VOffIntrlYUV
1355};
1356
1357/********************************************************************************
1358 * YUV 4:2:0 descriptors.
1359 */
1360
1361/* YV12: 4:2:0, YUV are fully separated, U pane follows V pane */
1362static const YUVDesc _YV12 =
1363{
1364    .Y_offset       = 0,
1365    .Y_inc          = 1,
1366    .Y_next_pair    = 2,
1367    .UV_inc         = 1,
1368    .U_offset       = 0,
1369    .V_offset       = 1,
1370    .u_offset       = &_UOffSepYUV,
1371    .v_offset       = &_VOffSepYUV
1372};
1373
1374/* YU12: 4:2:0, YUV are fully separated, V pane follows U pane */
1375static const YUVDesc _YU12 =
1376{
1377    .Y_offset       = 0,
1378    .Y_inc          = 1,
1379    .Y_next_pair    = 2,
1380    .UV_inc         = 1,
1381    .U_offset       = 1,
1382    .V_offset       = 0,
1383    .u_offset       = &_UOffSepYUV,
1384    .v_offset       = &_VOffSepYUV
1385};
1386
1387/* NV12: 4:2:0, UV are interleaved, V follows U in UV pane */
1388static const YUVDesc _NV12 =
1389{
1390    .Y_offset       = 0,
1391    .Y_inc          = 1,
1392    .Y_next_pair    = 2,
1393    .UV_inc         = 2,
1394    .U_offset       = 0,
1395    .V_offset       = 1,
1396    .u_offset       = &_UOffIntrlUV,
1397    .v_offset       = &_VOffIntrlUV
1398};
1399
1400/* NV21: 4:2:0, UV are interleaved, U follows V in UV pane */
1401static const YUVDesc _NV21 =
1402{
1403    .Y_offset       = 0,
1404    .Y_inc          = 1,
1405    .Y_next_pair    = 2,
1406    .UV_inc         = 2,
1407    .U_offset       = 1,
1408    .V_offset       = 0,
1409    .u_offset       = &_UOffIntrlUV,
1410    .v_offset       = &_VOffIntrlUV
1411};
1412
1413/********************************************************************************
1414 * RGB bayer format descriptors.
1415 */
1416
1417/* Descriptor for a 8-bit GBGB / RGRG format. */
1418static const BayerDesc _GB8 =
1419{
1420    .mask           = kBayer8,
1421    .color_order    = "GBRG"
1422};
1423
1424/* Descriptor for a 8-bit GRGR / BGBG format. */
1425static const BayerDesc _GR8 =
1426{
1427    .mask           = kBayer8,
1428    .color_order    = "GRBG"
1429};
1430
1431/* Descriptor for a 8-bit BGBG / GRGR format. */
1432static const BayerDesc _BG8 =
1433{
1434    .mask           = kBayer8,
1435    .color_order    = "BGGR"
1436};
1437
1438/* Descriptor for a 8-bit RGRG / GBGB format. */
1439static const BayerDesc _RG8 =
1440{
1441    .mask           = kBayer8,
1442    .color_order    = "RGGB"
1443};
1444
1445/* Descriptor for a 10-bit GBGB / RGRG format. */
1446static const BayerDesc _GB10 =
1447{
1448    .mask           = kBayer10,
1449    .color_order    = "GBRG"
1450};
1451
1452/* Descriptor for a 10-bit GRGR / BGBG format. */
1453static const BayerDesc _GR10 =
1454{
1455    .mask           = kBayer10,
1456    .color_order    = "GRBG"
1457};
1458
1459/* Descriptor for a 10-bit BGBG / GRGR format. */
1460static const BayerDesc _BG10 =
1461{
1462    .mask           = kBayer10,
1463    .color_order    = "BGGR"
1464};
1465
1466/* Descriptor for a 10-bit RGRG / GBGB format. */
1467static const BayerDesc _RG10 =
1468{
1469    .mask           = kBayer10,
1470    .color_order    = "RGGB"
1471};
1472
1473/* Descriptor for a 12-bit GBGB / RGRG format. */
1474static const BayerDesc _GB12 =
1475{
1476    .mask           = kBayer12,
1477    .color_order    = "GBRG"
1478};
1479
1480/* Descriptor for a 12-bit GRGR / BGBG format. */
1481static const BayerDesc _GR12 =
1482{
1483    .mask           = kBayer12,
1484    .color_order    = "GRBG"
1485};
1486
1487/* Descriptor for a 12-bit BGBG / GRGR format. */
1488static const BayerDesc _BG12 =
1489{
1490    .mask           = kBayer12,
1491    .color_order    = "BGGR"
1492};
1493
1494/* Descriptor for a 12-bit RGRG / GBGB format. */
1495static const BayerDesc _RG12 =
1496{
1497    .mask           = kBayer12,
1498    .color_order    = "RGGB"
1499};
1500
1501
1502/********************************************************************************
1503 * List of descriptors for supported formats.
1504 *******************************************************************************/
1505
1506/* Enumerates pixel formats supported by converters. */
1507typedef enum PIXFormatSel {
1508    /* Pixel format is RGB/BGR */
1509    PIX_FMT_RGB,
1510    /* Pixel format is YUV */
1511    PIX_FMT_YUV,
1512    /* Pixel format is BAYER */
1513    PIX_FMT_BAYER
1514} PIXFormatSel;
1515
1516/* Formats entry in the list of descriptors for supported formats. */
1517typedef struct PIXFormat {
1518    /* "FOURCC" (V4L2_PIX_FMT_XXX) format type. */
1519    uint32_t        fourcc_type;
1520    /* RGB/YUV/BAYER format selector */
1521    PIXFormatSel    format_sel;
1522    union {
1523        /* References RGB format descriptor for that format. */
1524        const RGBDesc*      rgb_desc;
1525        /* References YUV format descriptor for that format. */
1526        const YUVDesc*      yuv_desc;
1527        /* References BAYER format descriptor for that format. */
1528        const BayerDesc*    bayer_desc;
1529    } desc;
1530} PIXFormat;
1531
1532/* Array of supported pixel format descriptors. */
1533static const PIXFormat _PIXFormats[] = {
1534    /* RGB/BRG formats. */
1535    { V4L2_PIX_FMT_RGB32,   PIX_FMT_RGB,    .desc.rgb_desc = &_RGB32  },
1536    { V4L2_PIX_FMT_BGR32,   PIX_FMT_RGB,    .desc.rgb_desc = &_BRG32  },
1537    { V4L2_PIX_FMT_RGB565,  PIX_FMT_RGB,    .desc.rgb_desc = &_RGB16  },
1538    { V4L2_PIX_FMT_RGB24,   PIX_FMT_RGB,    .desc.rgb_desc = &_RGB24  },
1539    { V4L2_PIX_FMT_BGR24,   PIX_FMT_RGB,    .desc.rgb_desc = &_BRG24  },
1540
1541    /* YUV 4:2:0 formats. */
1542    { V4L2_PIX_FMT_YVU420,  PIX_FMT_YUV,    .desc.yuv_desc = &_YV12   },
1543    { V4L2_PIX_FMT_YUV420,  PIX_FMT_YUV,    .desc.yuv_desc = &_YU12   },
1544    { V4L2_PIX_FMT_NV12,    PIX_FMT_YUV,    .desc.yuv_desc = &_NV12   },
1545    { V4L2_PIX_FMT_NV21,    PIX_FMT_YUV,    .desc.yuv_desc = &_NV21   },
1546
1547    /* YUV 4:2:2 formats. */
1548    { V4L2_PIX_FMT_YUYV,    PIX_FMT_YUV,    .desc.yuv_desc = &_YUYV   },
1549    { V4L2_PIX_FMT_YYUV,    PIX_FMT_YUV,    .desc.yuv_desc = &_YYUV   },
1550    { V4L2_PIX_FMT_YVYU,    PIX_FMT_YUV,    .desc.yuv_desc = &_YVYU   },
1551    { V4L2_PIX_FMT_UYVY,    PIX_FMT_YUV,    .desc.yuv_desc = &_UYVY   },
1552    { V4L2_PIX_FMT_VYUY,    PIX_FMT_YUV,    .desc.yuv_desc = &_VYUY   },
1553    { V4L2_PIX_FMT_YVYU,    PIX_FMT_YUV,    .desc.yuv_desc = &_YVYU   },
1554    { V4L2_PIX_FMT_VYUY,    PIX_FMT_YUV,    .desc.yuv_desc = &_VYUY   },
1555    { V4L2_PIX_FMT_YYVU,    PIX_FMT_YUV,    .desc.yuv_desc = &_YYVU   },
1556    { V4L2_PIX_FMT_YUY2,    PIX_FMT_YUV,    .desc.yuv_desc = &_YUYV   },
1557    { V4L2_PIX_FMT_YUNV,    PIX_FMT_YUV,    .desc.yuv_desc = &_YUYV   },
1558    { V4L2_PIX_FMT_V422,    PIX_FMT_YUV,    .desc.yuv_desc = &_YUYV   },
1559
1560    /* BAYER formats. */
1561    { V4L2_PIX_FMT_SBGGR8,  PIX_FMT_BAYER,  .desc.bayer_desc = &_BG8  },
1562    { V4L2_PIX_FMT_SGBRG8,  PIX_FMT_BAYER,  .desc.bayer_desc = &_GB8  },
1563    { V4L2_PIX_FMT_SGRBG8,  PIX_FMT_BAYER,  .desc.bayer_desc = &_GR8  },
1564    { V4L2_PIX_FMT_SRGGB8,  PIX_FMT_BAYER,  .desc.bayer_desc = &_RG8  },
1565    { V4L2_PIX_FMT_SBGGR10, PIX_FMT_BAYER,  .desc.bayer_desc = &_BG10 },
1566    { V4L2_PIX_FMT_SGBRG10, PIX_FMT_BAYER,  .desc.bayer_desc = &_GB10 },
1567    { V4L2_PIX_FMT_SGRBG10, PIX_FMT_BAYER,  .desc.bayer_desc = &_GR10 },
1568    { V4L2_PIX_FMT_SRGGB10, PIX_FMT_BAYER,  .desc.bayer_desc = &_RG10 },
1569    { V4L2_PIX_FMT_SBGGR12, PIX_FMT_BAYER,  .desc.bayer_desc = &_BG12 },
1570    { V4L2_PIX_FMT_SGBRG12, PIX_FMT_BAYER,  .desc.bayer_desc = &_GB12 },
1571    { V4L2_PIX_FMT_SGRBG12, PIX_FMT_BAYER,  .desc.bayer_desc = &_GR12 },
1572    { V4L2_PIX_FMT_SRGGB12, PIX_FMT_BAYER,  .desc.bayer_desc = &_RG12 },
1573};
1574static const int _PIXFormats_num = sizeof(_PIXFormats) / sizeof(*_PIXFormats);
1575
1576/* Get an entry in the array of supported pixel format descriptors.
1577 * Param:
1578 *  pixel_format - "fourcc" pixel format to lookup an entry for.
1579 * Return"
1580 *  Pointer to the found entry, or NULL if no entry exists for the given pixel
1581 *  format.
1582 */
1583static const PIXFormat*
1584_get_pixel_format_descriptor(uint32_t pixel_format)
1585{
1586    int f;
1587    for (f = 0; f < _PIXFormats_num; f++) {
1588        if (_PIXFormats[f].fourcc_type == pixel_format) {
1589            return &_PIXFormats[f];
1590        }
1591    }
1592    W("%s: Pixel format %.4s is unknown",
1593      __FUNCTION__, (const char*)&pixel_format);
1594    return NULL;
1595}
1596
1597/********************************************************************************
1598 * Public API
1599 *******************************************************************************/
1600
1601int
1602has_converter(uint32_t from, uint32_t to)
1603{
1604    if (from == to) {
1605        /* Same format: converter esists. */
1606        return 1;
1607    }
1608    return _get_pixel_format_descriptor(from) != NULL &&
1609           _get_pixel_format_descriptor(to) != NULL;
1610}
1611
1612int
1613convert_frame(const void* frame,
1614              uint32_t pixel_format,
1615              size_t framebuffer_size,
1616              int width,
1617              int height,
1618              ClientFrameBuffer* framebuffers,
1619              int fbs_num,
1620              float r_scale,
1621              float g_scale,
1622              float b_scale,
1623              float exp_comp)
1624{
1625    int n;
1626    const PIXFormat* src_desc = _get_pixel_format_descriptor(pixel_format);
1627    if (src_desc == NULL) {
1628        E("%s: Source pixel format %.4s is unknown",
1629          __FUNCTION__, (const char*)&pixel_format);
1630        return -1;
1631    }
1632
1633    for (n = 0; n < fbs_num; n++) {
1634        /* Note that we need to apply white balance, exposure compensation, etc.
1635         * when we transfer the captured frame to the user framebuffer. So, even
1636         * if source and destination formats are the same, we will have to go
1637         * thrugh the converters to apply these things. */
1638        const PIXFormat* dst_desc =
1639            _get_pixel_format_descriptor(framebuffers[n].pixel_format);
1640        if (dst_desc == NULL) {
1641            E("%s: Destination pixel format %.4s is unknown",
1642              __FUNCTION__, (const char*)&framebuffers[n].pixel_format);
1643            return -1;
1644        }
1645        switch (src_desc->format_sel) {
1646            case PIX_FMT_RGB:
1647                if (dst_desc->format_sel == PIX_FMT_RGB) {
1648                    RGBToRGB(src_desc->desc.rgb_desc, dst_desc->desc.rgb_desc,
1649                             frame, framebuffers[n].framebuffer, width, height,
1650                             r_scale, g_scale, b_scale, exp_comp);
1651                } else if (dst_desc->format_sel == PIX_FMT_YUV) {
1652                    RGBToYUV(src_desc->desc.rgb_desc, dst_desc->desc.yuv_desc,
1653                             frame, framebuffers[n].framebuffer, width, height,
1654                             r_scale, g_scale, b_scale, exp_comp);
1655                } else {
1656                    E("%s: Unexpected destination pixel format %d",
1657                      __FUNCTION__, dst_desc->format_sel);
1658                    return -1;
1659                }
1660                break;
1661            case PIX_FMT_YUV:
1662                if (dst_desc->format_sel == PIX_FMT_RGB) {
1663                    YUVToRGB(src_desc->desc.yuv_desc, dst_desc->desc.rgb_desc,
1664                             frame, framebuffers[n].framebuffer, width, height,
1665                             r_scale, g_scale, b_scale, exp_comp);
1666                } else if (dst_desc->format_sel == PIX_FMT_YUV) {
1667                    YUVToYUV(src_desc->desc.yuv_desc, dst_desc->desc.yuv_desc,
1668                             frame, framebuffers[n].framebuffer, width, height,
1669                             r_scale, g_scale, b_scale, exp_comp);
1670                } else {
1671                    E("%s: Unexpected destination pixel format %d",
1672                      __FUNCTION__, dst_desc->format_sel);
1673                    return -1;
1674                }
1675                break;
1676            case PIX_FMT_BAYER:
1677                if (dst_desc->format_sel == PIX_FMT_RGB) {
1678                    BAYERToRGB(src_desc->desc.bayer_desc, dst_desc->desc.rgb_desc,
1679                              frame, framebuffers[n].framebuffer, width, height,
1680                              r_scale, g_scale, b_scale, exp_comp);
1681                } else if (dst_desc->format_sel == PIX_FMT_YUV) {
1682                    BAYERToYUV(src_desc->desc.bayer_desc, dst_desc->desc.yuv_desc,
1683                               frame, framebuffers[n].framebuffer, width, height,
1684                               r_scale, g_scale, b_scale, exp_comp);
1685                } else {
1686                    E("%s: Unexpected destination pixel format %d",
1687                      __FUNCTION__, dst_desc->format_sel);
1688                    return -1;
1689                }
1690                break;
1691            default:
1692                E("%s: Unexpected source pixel format %d",
1693                  __FUNCTION__, dst_desc->format_sel);
1694                return -1;
1695        }
1696    }
1697
1698    return 0;
1699}
1700