24#include <fvutils/color/bayer.h>
25#include <fvutils/color/colorspaces.h>
26#include <fvutils/color/rgbyuv.h>
27#include <fvutils/color/yuv.h>
35#define assign(y, u, v, y1, u1, v1, y2, u2, v2) \
39 *u++ = ((u1 + u2) >> 1); \
40 *v++ = ((v1 + v2) >> 1); \
44bayerGBRG_to_yuv422planar_nearest_neighbour(
const unsigned char *bayer,
49 unsigned char * y = yuv;
50 unsigned char * u = YUV422_PLANAR_U_PLANE(yuv, width, height);
51 unsigned char * v = YUV422_PLANAR_V_PLANE(yuv, width, height);
52 const unsigned char *b = bayer;
54 int y1, u1, v1, y2, u2, v2;
57 for (
unsigned int h = 0; h < height; h += 2) {
59 for (
unsigned int w = 0; w < width; w += 2) {
62 RGB2YUV(t1, *b, t2, y1, u1, v1);
67 RGB2YUV(t1, t2, *b, y2, u2, v2);
70 assign(y, u, v, y1, u1, v1, y2, u2, v2);
74 for (
unsigned int w = 0; w < width; w += 2) {
77 RGB2YUV(*b, t1, t2, y1, u1, v1);
82 RGB2YUV(t1, *b, t2, y2, u2, v2);
85 assign(y, u, v, y1, u1, v1, y2, u2, v2);
91bayerGBRG_to_yuv422planar_bilinear(
const unsigned char *bayer,
96 unsigned char * y = yuv;
97 unsigned char * u = YUV422_PLANAR_U_PLANE(yuv, width, height);
98 unsigned char * v = YUV422_PLANAR_V_PLANE(yuv, width, height);
99 const unsigned char *bf = bayer;
101 int y1, u1, v1, y2, u2, v2;
107 RGB2YUV(bf[width], *bf, bf[1], y1, u1, v1);
110 r = (bf[width - 1] + bf[width + 1]) >> 1;
114 g = (bf[-1] + bf[1]) >> 1;
115 RGB2YUV(r, g, *bf, y2, u2, v2);
118 assign(y, u, v, y1, u1, v1, y2, u2, v2);
121 for (
unsigned int w = 2; w < width - 2; w += 2) {
122 b = (bf[-1] + bf[1]) >> 1;
123 RGB2YUV(bf[width], *bf, b, y1, u1, v1);
126 r = (bf[width - 1] + bf[width + 1]) >> 1;
130 g = (bf[-1] + bf[1]) >> 1;
131 RGB2YUV(r, g, *bf, y2, u2, v2);
134 assign(y, u, v, y1, u1, v1, y2, u2, v2);
138 b = (bf[-1] + bf[1]) >> 1;
139 RGB2YUV(bf[width], *bf, b, y1, u1, v1);
142 g = (bf[-1] + bf[width]) >> 1;
143 RGB2YUV(bf[width - 1], g, *bf, y2, u2, v2);
146 assign(y, u, v, y1, u1, v1, y2, u2, v2);
148 for (
unsigned int h = 1; h < height - 1; h += 2) {
152 g = (bf[-width] + bf[1]) >> 1;
153 b = (bf[width - 1] + bf[width + 1]) >> 1;
154 RGB2YUV(*bf, g, b, y1, u1, v1);
157 r = (bf[-1] + bf[1]) >> 1;
158 b = (bf[-width] + bf[width]) >> 1;
159 RGB2YUV(r, *bf, b, y2, u2, v2);
162 assign(y, u, v, y1, u1, v1, y2, u2, v2);
164 for (
unsigned int w = 2; w < width - 2; w += 2) {
165 g = (bf[-width] + bf[1] + bf[width] + bf[-1]) >> 2;
166 b = (bf[-width - 1] + bf[-width + 1] + bf[width - 1] + bf[width + 1]) >> 2;
167 RGB2YUV(*bf, g, b, y1, u1, v1);
170 r = (bf[-1] + bf[1]) >> 1;
171 b = (bf[-width] + bf[width]) >> 1;
172 RGB2YUV(r, *bf, b, y2, u2, v2);
175 assign(y, u, v, y1, u1, v1, y2, u2, v2);
178 g = (bf[-width] + bf[1] + bf[width] + bf[-1]) >> 2;
179 b = (bf[-width - 1] + bf[-width + 1] + bf[width - 1] + bf[width + 1]) >> 2;
180 RGB2YUV(*bf, g, b, y1, u1, v1);
183 b = (bf[-width] + bf[width]) >> 1;
184 RGB2YUV(bf[-1], *bf, g, y2, u2, v2);
187 assign(y, u, v, y1, u1, v1, y2, u2, v2);
190 r = (bf[width] + bf[-width]) >> 1;
191 RGB2YUV(r, *bf, bf[1], y1, u1, v1);
194 r = (bf[-width - 1] + bf[-width + 1] + bf[width - 1] + bf[width + 1]) >> 2;
195 g = (bf[-width] + bf[1] + bf[width] + bf[-1]) >> 2;
196 RGB2YUV(r, g, *bf, y2, u2, v2);
199 assign(y, u, v, y1, u1, v1, y2, u2, v2);
201 for (
unsigned int w = 2; w < width - 2; w += 2) {
202 r = (bf[width] + bf[-width]) >> 1;
203 b = (bf[-1] + bf[1]) >> 1;
204 RGB2YUV(r, *bf, b, y1, u1, v1);
207 r = (bf[-width - 1] + bf[-width + 1] + bf[width - 1] + bf[width + 1]) >> 2;
208 g = (bf[-width] + bf[1] + bf[width] + bf[-1]) >> 2;
209 RGB2YUV(r, g, *bf, y2, u2, v2);
212 assign(y, u, v, y1, u1, v1, y2, u2, v2);
215 r = (bf[width] + bf[-width]) >> 1;
216 b = (bf[-1] + bf[1]) >> 1;
217 RGB2YUV(r, *bf, b, y1, u1, v1);
220 r = (bf[-width - 1] + bf[width - 1]) >> 1;
223 g = (bf[-width] + bf[-1]) >> 1;
224 RGB2YUV(r, g, *bf, y2, u2, v2);
227 assign(y, u, v, y1, u1, v1, y2, u2, v2);
233 g = (bf[-width] + bf[1]) >> 1;
235 RGB2YUV(*bf, g, b, y1, u1, v1);
238 r = (bf[-1] + bf[1]) >> 1;
240 RGB2YUV(r, g, *bf, y2, u2, v2);
243 assign(y, u, v, y1, u1, v1, y2, u2, v2);
245 for (
unsigned int w = 2; w < width - 2; w += 2) {
248 g = (bf[-width] + bf[-1]) >> 1;
249 b = (bf[-width - 1] + bf[-width + 1]) >> 1;
250 RGB2YUV(*bf, g, b, y1, u1, v1);
253 r = (bf[-1] + bf[1]) >> 1;
255 RGB2YUV(r, *bf, b, y2, u2, v2);
258 assign(y, u, v, y1, u1, v1, y2, u2, v2);
263 g = (bf[-width] + bf[-1]) >> 1;
264 b = (bf[-width - 1] + bf[-width + 1]) >> 1;
265 RGB2YUV(*bf, g, b, y1, u1, v1);
269 RGB2YUV(bf[-1], *bf, b, y2, u2, v2);
272 assign(y, u, v, y1, u1, v1, y2, u2, v2);
276bayerGBRG_to_yuv422planar_bilinear2(
const unsigned char *bayer,
281 unsigned char * y = yuv;
282 unsigned char * u = YUV422_PLANAR_U_PLANE(yuv, width, height);
283 unsigned char * v = YUV422_PLANAR_V_PLANE(yuv, width, height);
284 const unsigned char *bf = bayer;
286 int y1, u1, v1, y2, u2, v2;
295 for (
unsigned int h = 1; h < height - 1; h += 2) {
305 for (
unsigned int w = 2; w < width - 2; w += 2) {
306 g = (bf[1] + bf[-1]) >> 1;
307 b = (bf[width - 1] + bf[width + 1]) >> 1;
308 RGB2YUV(*bf, g, b, y1, u1, v1);
311 r = (bf[-1] + bf[1]) >> 1;
312 b = (bf[-width] + bf[width]) >> 1;
313 RGB2YUV(r, *bf, b, y2, u2, v2);
316 assign(y, u, v, y1, u1, v1, y2, u2, v2);
336 for (
unsigned int w = 2; w < width - 2; w += 2) {
337 r = (bf[width] + bf[-width]) >> 1;
338 b = (bf[-1] + bf[1]) >> 1;
339 RGB2YUV(r, *bf, b, y1, u1, v1);
342 r = (bf[width - 1] + bf[width + 1]) >> 1;
343 g = (bf[1] + bf[width]) >> 1;
344 RGB2YUV(r, g, *bf, y2, u2, v2);
347 assign(y, u, v, y1, u1, v1, y2, u2, v2);
552bayerGRBG_to_yuv422planar_nearest_neighbour(
const unsigned char *bayer,
557 unsigned char * y = yuv;
558 unsigned char * u = YUV422_PLANAR_U_PLANE(yuv, width, height);
559 unsigned char * v = YUV422_PLANAR_V_PLANE(yuv, width, height);
560 const unsigned char *b = bayer;
562 int y1, u1, v1, y2, u2, v2;
564 for (
unsigned int h = 0; h < height; h += 2) {
566 for (
unsigned int w = 0; w < width; w += 2) {
567 RGB2YUV(b[1], b[width], *b, y1, u1, v1);
570 RGB2YUV(*b, b[-1], b[width - 1], y2, u2, v2);
573 assign(y, u, v, y1, u1, v1, y2, u2, v2);
577 for (
unsigned int w = 0; w < width; w += 2) {
578 RGB2YUV(*(b - width + 1), b[1], *b, y1, u1, v1);
581 RGB2YUV(*(b - width), *b, b[-1], y2, u2, v2);
584 assign(y, u, v, y1, u1, v1, y2, u2, v2);
590bayerRGGB_to_yuv422planar_nearest_neighbour(
const unsigned char *bayer,
595 unsigned char * y = yuv;
596 unsigned char * u = YUV422_PLANAR_U_PLANE(yuv, width, height);
597 unsigned char * v = YUV422_PLANAR_V_PLANE(yuv, width, height);
598 const unsigned char *b = bayer;
600 int y1, u1, v1, y2, u2, v2;
602 for (
unsigned int h = 0; h < height; h += 2) {
604 for (
unsigned int w = 0; w < width; w += 2) {
605 RGB2YUV(*b, b[1], b[width + 1], y1, u1, v1);
608 RGB2YUV(b[-1], *b, b[width], y2, u2, v2);
611 assign(y, u, v, y1, u1, v1, y2, u2, v2);
615 for (
unsigned int w = 0; w < width; w += 2) {
616 RGB2YUV(*(b - width), *b, b[1], y1, u1, v1);
619 RGB2YUV(*(b - width - 1), b[-1], *b, y2, u2, v2);
622 assign(y, u, v, y1, u1, v1, y2, u2, v2);
628bayerGRBG_to_yuv422planar_bilinear(
const unsigned char *bayer,
633 unsigned char * y = yuv;
634 unsigned char * u = YUV422_PLANAR_U_PLANE(yuv, width, height);
635 unsigned char * v = YUV422_PLANAR_V_PLANE(yuv, width, height);
636 const unsigned char *bf = bayer;
638 int y1, u1, v1, y2, u2, v2;
644 RGB2YUV(bf[1], *bf, bf[width], y1, u1, v1);
647 b = (bf[width - 1] + bf[width + 1]) >> 1;
651 g = (bf[-1] + bf[1]) >> 1;
652 RGB2YUV(*bf, g, b, y2, u2, v2);
655 assign(y, u, v, y1, u1, v1, y2, u2, v2);
658 for (
unsigned int w = 2; w < width - 2; w += 2) {
659 r = (bf[-1] + bf[1]) >> 1;
660 RGB2YUV(r, *bf, bf[width], y1, u1, v1);
663 b = (bf[width - 1] + bf[width + 1]) >> 1;
667 g = (bf[-1] + bf[1]) >> 1;
668 RGB2YUV(*bf, g, b, y2, u2, v2);
671 assign(y, u, v, y1, u1, v1, y2, u2, v2);
675 r = (bf[-1] + bf[1]) >> 1;
676 RGB2YUV(r, *bf, bf[width], y1, u1, v1);
679 g = (bf[-1] + bf[width]) >> 1;
680 RGB2YUV(*bf, g, bf[width - 1], y2, u2, v2);
683 assign(y, u, v, y1, u1, v1, y2, u2, v2);
685 for (
unsigned int h = 1; h < height - 1; h += 2) {
689 g = (*(bf - width) + bf[1]) >> 1;
690 r = (*(bf - width + 1) + bf[width + 1]) >> 1;
691 RGB2YUV(r, g, *bf, y1, u1, v1);
694 b = (bf[-1] + bf[1]) >> 1;
695 r = (*(bf - width) + bf[width]) >> 1;
696 RGB2YUV(r, *bf, g, y2, u2, v2);
699 assign(y, u, v, y1, u1, v1, y2, u2, v2);
701 for (
unsigned int w = 2; w < width - 2; w += 2) {
702 g = (*(bf - width) + bf[1] + bf[width] + bf[-1]) >> 2;
703 r = (*(bf - width - 1) + *(bf - width + 1) + bf[width - 1] + bf[width + 1]) >> 2;
704 RGB2YUV(r, g, *bf, y1, u1, v1);
707 b = (bf[-1] + bf[1]) >> 1;
708 r = (*(bf - width) + bf[width]) >> 1;
709 RGB2YUV(r, *bf, b, y2, u2, v2);
712 assign(y, u, v, y1, u1, v1, y2, u2, v2);
715 g = (*(bf - width) + bf[1] + bf[width] + bf[-1]) >> 2;
716 r = (*(bf - width - 1) + *(bf - width + 1) + bf[width - 1] + bf[width + 1]) >> 2;
717 RGB2YUV(r, g, *bf, y1, u1, v1);
720 r = (*(bf - width) + bf[width]) >> 1;
721 RGB2YUV(r, *bf, bf[-1], y2, u2, v2);
724 assign(y, u, v, y1, u1, v1, y2, u2, v2);
727 b = (bf[width] + *(bf - width)) >> 1;
728 RGB2YUV(bf[1], *bf, b, y1, u1, v1);
731 b = (*(bf - width - 1) + *(bf - width + 1) + bf[width - 1] + bf[width + 1]) >> 2;
732 g = (*(bf - width) + bf[1] + bf[width] + bf[-1]) >> 2;
733 RGB2YUV(*bf, g, b, y2, u2, v2);
736 assign(y, u, v, y1, u1, v1, y2, u2, v2);
738 for (
unsigned int w = 2; w < width - 2; w += 2) {
739 b = (bf[width] + *(bf - width)) >> 1;
740 r = (bf[-1] + bf[1]) >> 1;
741 RGB2YUV(r, *bf, b, y1, u1, v1);
744 b = (*(bf - width - 1) + *(bf - width + 1) + bf[width - 1] + bf[width + 1]) >> 2;
745 g = (*(bf - width) + bf[1] + bf[width] + bf[-1]) >> 2;
746 RGB2YUV(*bf, g, b, y2, u2, v2);
749 assign(y, u, v, y1, u1, v1, y2, u2, v2);
752 b = (bf[width] + *(bf - width)) >> 1;
753 r = (bf[-1] + bf[1]) >> 1;
754 RGB2YUV(r, *bf, b, y1, u1, v1);
757 b = (*(bf - width - 1) + bf[width - 1]) >> 1;
760 g = (*(bf - width) + bf[-1]) >> 1;
761 RGB2YUV(*bf, g, r, y2, u2, v2);
764 assign(y, u, v, y1, u1, v1, y2, u2, v2);
770 g = (*(bf - width) + bf[1]) >> 1;
771 r = *(bf - width + 1);
772 RGB2YUV(r, g, *bf, y1, u1, v1);
775 b = (bf[-1] + bf[1]) >> 1;
777 RGB2YUV(r, *bf, b, y2, u2, v2);
780 assign(y, u, v, y1, u1, v1, y2, u2, v2);
782 for (
unsigned int w = 2; w < width - 2; w += 2) {
785 g = (*(bf - width) + bf[-1]) >> 1;
786 r = (*(bf - width - 1) + *(bf - width + 1)) >> 1;
787 RGB2YUV(r, g, *bf, y1, u1, v1);
790 b = (bf[-1] + bf[1]) >> 1;
792 RGB2YUV(r, *bf, b, y2, u2, v2);
795 assign(y, u, v, y1, u1, v1, y2, u2, v2);
800 g = (*(bf - width) + bf[-1]) >> 1;
801 r = (*(bf - width - 1) + *(bf - width + 1)) >> 1;
802 RGB2YUV(r, g, *bf, y1, u1, v1);
806 RGB2YUV(r, *bf, bf[-1], y2, u2, v2);
809 assign(y, u, v, y1, u1, v1, y2, u2, v2);
813bayerGRBG_to_rgb_nearest_neighbour(
const unsigned char *bayer,
818 for (
unsigned int h = 0; h < height; h += 2) {
820 for (
unsigned int w = 0; w < width; w += 2) {
822 *rgb++ = bayer[width];
828 *rgb++ = bayer[width - 1];
833 for (
unsigned int w = 0; w < width; w += 2) {
834 *rgb++ = *(bayer - width + 1);
839 *rgb++ = *(bayer - width);
848bayerGRBG_to_rgb_bilinear(
const unsigned char *bayer,
858 *rgb++ = bayer[width];
865 *rgb++ = (bayer[-1] + bayer[1]) >> 1;
866 *rgb++ = (bayer[width - 1] + bayer[width + 1]) >> 1;
870 for (
unsigned int w = 2; w < width - 2; w += 2) {
871 *rgb++ = (bayer[-1] + bayer[1]) >> 1;
873 *rgb++ = bayer[width];
880 *rgb++ = (bayer[-1] + bayer[1]) >> 1;
881 *rgb++ = (bayer[width - 1] + bayer[width + 1]) >> 1;
886 *rgb++ = (bayer[-1] + bayer[1]) >> 1;
888 *rgb++ = bayer[width];
892 *rgb++ = (bayer[-1] + bayer[width]) >> 1;
893 *rgb++ = bayer[width - 1];
896 for (
unsigned int h = 1; h < height - 1; h += 2) {
900 *rgb++ = (*(bayer - width + 1) + bayer[width + 1]) >> 1;
901 *rgb++ = (*(bayer - width) + bayer[1]) >> 1;
905 *rgb++ = (*(bayer - width) + bayer[width]) >> 1;
907 *rgb++ = (bayer[-1] + bayer[1]) >> 1;
910 for (
unsigned int w = 2; w < width - 2; w += 2) {
912 (*(bayer - width - 1) + *(bayer - width + 1) + bayer[width - 1] + bayer[width + 1]) >> 2;
913 *rgb++ = (*(bayer - width) + bayer[1] + bayer[width] + bayer[-1]) >> 2;
917 *rgb++ = (*(bayer - width) + bayer[width]) >> 1;
919 *rgb++ = (bayer[-1] + bayer[1]) >> 1;
924 (*(bayer - width - 1) + *(bayer - width + 1) + bayer[width - 1] + bayer[width + 1]) >> 2;
925 *rgb++ = (*(bayer - width) + bayer[1] + bayer[width] + bayer[-1]) >> 2;
929 *rgb++ = (*(bayer - width) + bayer[width]) >> 1;
937 *rgb++ = (bayer[width] + *(bayer - width)) >> 1;
941 *rgb++ = (*(bayer - width) + bayer[1] + bayer[width] + bayer[-1]) >> 2;
943 (*(bayer - width - 1) + *(bayer - width + 1) + bayer[width - 1] + bayer[width + 1]) >> 2;
946 for (
unsigned int w = 2; w < width - 2; w += 2) {
947 *rgb++ = (bayer[-1] + bayer[1]) >> 1;
949 *rgb++ = (bayer[width] + *(bayer - width)) >> 1;
953 *rgb++ = (*(bayer - width) + bayer[1] + bayer[width] + bayer[-1]) >> 2;
955 (*(bayer - width - 1) + *(bayer - width + 1) + bayer[width - 1] + bayer[width + 1]) >> 2;
959 *rgb++ = (bayer[-1] + bayer[1]) >> 1;
961 *rgb++ = (bayer[width] + *(bayer - width)) >> 1;
967 *rgb++ = (*(bayer - width) + bayer[-1]) >> 1;
968 *rgb++ = (*(bayer - width - 1) + bayer[width - 1]) >> 1;
975 *rgb++ = *(bayer - width + 1);
976 *rgb++ = (*(bayer - width) + bayer[1]) >> 1;
980 *rgb++ = *(bayer - width);
982 *rgb++ = (bayer[-1] + bayer[1]) >> 1;
985 for (
unsigned int w = 2; w < width - 2; w += 2) {
988 *rgb++ = (*(bayer - width - 1) + *(bayer - width + 1)) >> 1;
989 *rgb++ = (*(bayer - width) + bayer[-1]) >> 1;
993 *rgb++ = *(bayer - width);
995 *rgb++ = (bayer[-1] + bayer[1]) >> 1;
1001 *rgb++ = (*(bayer - width - 1) + *(bayer - width + 1)) >> 1;
1002 *rgb++ = (*(bayer - width) + bayer[-1]) >> 1;
1006 *rgb++ = *(bayer - width);