| 609 | } |
| 610 | |
| 611 | void DebayerRGB(int frame_width, int frame_height, const uint8_t* inBayer, uint8_t* outBuffer, bool inBGR) |
| 612 | { |
| 613 | // PSMove output is in the following Bayer format (GRBG): |
| 614 | // |
| 615 | // G R G R G R |
| 616 | // B G B G B G |
| 617 | // G R G R G R |
| 618 | // B G B G B G |
| 619 | // |
| 620 | // This is the normal Bayer pattern shifted left one place. |
| 621 | |
| 622 | int num_output_channels = 3; |
| 623 | int source_stride = frame_width; |
| 624 | const uint8_t* source_row = inBayer; // Start at first bayer pixel |
| 625 | int dest_stride = frame_width * num_output_channels; |
| 626 | uint8_t* dest_row = outBuffer + dest_stride + num_output_channels + 1; // We start outputting at the second pixel of the second row's G component |
| 627 | int swap_br = inBGR ? 1 : -1; |
| 628 | |
| 629 | // Fill rows 1 to height-1 of the destination buffer. First and last row are filled separately (they are copied from the second row and second-to-last rows respectively) |
| 630 | for (int y = 0; y < frame_height-1; source_row += source_stride, dest_row += dest_stride, ++y) |
| 631 | { |
| 632 | const uint8_t* source = source_row; |
| 633 | const uint8_t* source_end = source + (source_stride-2); // -2 to deal with the fact that we're starting at the second pixel of the row and should end at the second-to-last pixel of the row (first and last are filled separately) |
| 634 | uint8_t* dest = dest_row; |
| 635 | |
| 636 | // Row starting with Green |
| 637 | if (y % 2 == 0) |
| 638 | { |
| 639 | // Fill first pixel (green) |
| 640 | dest[-1*swap_br] = (source[source_stride] + source[source_stride + 2] + 1) >> 1; |
| 641 | dest[0] = source[source_stride + 1]; |
| 642 | dest[1*swap_br] = (source[1] + source[source_stride * 2 + 1] + 1) >> 1; |
| 643 | |
| 644 | source++; |
| 645 | dest += num_output_channels; |
| 646 | |
| 647 | // Fill remaining pixel |
| 648 | for (; source <= source_end - 2; source += 2, dest += num_output_channels * 2) |
| 649 | { |
| 650 | // Blue pixel |
| 651 | uint8_t* cur_pixel = dest; |
| 652 | cur_pixel[-1*swap_br] = source[source_stride + 1]; |
| 653 | cur_pixel[0] = (source[1] + source[source_stride] + source[source_stride + 2] + source[source_stride * 2 + 1] + 2) >> 2; |
| 654 | cur_pixel[1*swap_br] = (source[0] + source[2] + source[source_stride * 2] + source[source_stride * 2 + 2] + 2) >> 2; |
| 655 | |
| 656 | // Green pixel |
| 657 | uint8_t* next_pixel = cur_pixel+num_output_channels; |
| 658 | next_pixel[-1*swap_br] = (source[source_stride + 1] + source[source_stride + 3] + 1) >> 1; |
| 659 | next_pixel[0] = source[source_stride + 2]; |
| 660 | next_pixel[1*swap_br] = (source[2] + source[source_stride * 2 + 2] + 1) >> 1; |
| 661 | } |
| 662 | } |
| 663 | else |
| 664 | { |
| 665 | for (; source <= source_end - 2; source += 2, dest += num_output_channels * 2) |
| 666 | { |
| 667 | // Red pixel |
| 668 | uint8_t* cur_pixel = dest; |
nothing calls this directly
no outgoing calls
no test coverage detected