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