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