24 #include <fvutils/color/bayer.h> 25 #include <fvutils/color/colorspaces.h> 26 #include <fvutils/color/yuv.h> 27 #include <fvutils/color/rgbyuv.h> 38 #define assign(y, u, v, y1, u1, v1, y2, u2, v2) { \ 41 *u++ = ((u1 + u2) >> 1); \ 42 *v++ = ((v1 + v2) >> 1); } 46 bayerGBRG_to_yuv422planar_nearest_neighbour(
const unsigned char *bayer,
unsigned char *yuv,
47 unsigned int width,
unsigned int height)
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) {
60 for (
unsigned int w = 0; w < width; w += 2) {
63 RGB2YUV(t1, *b, t2, y1, u1, v1);
68 RGB2YUV(t1, t2, *b, y2, u2, v2);
71 assign(y, u, v, y1, u1, v1, y2, u2, v2);
75 for (
unsigned int w = 0; w < width; w += 2) {
78 RGB2YUV(*b, t1, t2, y1, u1, v1);
83 RGB2YUV(t1, *b, t2, y2, u2, v2);
86 assign(y, u, v, y1, u1, v1, y2, u2, v2);
94 bayerGBRG_to_yuv422planar_bilinear(
const unsigned char *bayer,
unsigned char *yuv,
95 unsigned int width,
unsigned int height)
97 unsigned char *y = yuv;
98 unsigned char *u = YUV422_PLANAR_U_PLANE(yuv, width, height);
99 unsigned char *v = YUV422_PLANAR_V_PLANE(yuv, width, height);
100 const unsigned char *bf = bayer;
102 int y1, u1, v1, y2, u2, v2;
108 RGB2YUV(bf[width], *bf, bf[1], y1, u1, v1);
111 r = (bf[width - 1] + bf[width + 1]) >> 1;
115 g = (bf[-1] + bf[1]) >> 1;
116 RGB2YUV(r, g, *bf, y2, u2, v2);
119 assign(y, u, v, y1, u1, v1, y2, u2, v2);
122 for (
unsigned int w = 2; w < width - 2; w += 2) {
123 b = (bf[-1] + bf[1]) >> 1;
124 RGB2YUV(bf[width], *bf, b, y1, u1, v1);
127 r = (bf[width - 1] + bf[width + 1]) >> 1;
131 g = (bf[-1] + bf[1]) >> 1;
132 RGB2YUV(r, g, *bf, y2, u2, v2);
135 assign(y, u, v, y1, u1, v1, y2, u2, v2);
139 b = (bf[-1] + bf[1]) >> 1;
140 RGB2YUV(bf[width], *bf, b, y1, u1, v1);
143 g = (bf[-1] + bf[width]) >> 1;
144 RGB2YUV(bf[width - 1], g, *bf, y2, u2, v2);
147 assign(y, u, v, y1, u1, v1, y2, u2, v2);
149 for (
unsigned int h = 1; h < height - 1; h += 2) {
154 g = (bf[-width] + bf[1]) >> 1;
155 b = (bf[width-1] + bf[width+1]) >> 1;
156 RGB2YUV(*bf, g, b, y1, u1, v1);
159 r = (bf[-1] + bf[1]) >> 1;
160 b = (bf[-width] + bf[width]) >> 1;
161 RGB2YUV(r, *bf, b, y2, u2, v2);
164 assign(y, u, v, y1, u1, v1, y2, u2, v2);
166 for (
unsigned int w = 2; w < width - 2; w += 2) {
167 g = (bf[-width] + bf[1] + bf[width] + bf[-1]) >> 2;
168 b = (bf[-width-1] + bf[-width+1] + bf[width-1] + bf[width+1]) >> 2;
169 RGB2YUV(*bf, g, b, y1, u1, v1);
172 r = (bf[-1] + bf[1]) >> 1;
173 b = (bf[-width] + bf[width]) >> 1;
174 RGB2YUV(r, *bf, b, y2, u2, v2);
177 assign(y, u, v, y1, u1, v1, y2, u2, v2);
180 g = (bf[-width] + bf[1] + bf[width] + bf[-1]) >> 2;
181 b = (bf[-width-1] + bf[-width+1] + bf[width-1] + bf[width+1]) >> 2;
182 RGB2YUV(*bf, g, b, y1, u1, v1);
185 b = (bf[-width] + bf[width]) >> 1;
186 RGB2YUV(bf[-1], *bf, g, y2, u2, v2);
189 assign(y, u, v, y1, u1, v1, y2, u2, v2);
194 r = (bf[width] + bf[-width]) >> 1;
195 RGB2YUV(r, *bf, bf[1], y1, u1, v1);
198 r = (bf[-width-1] + bf[-width+1] + bf[width - 1] + bf[width + 1]) >> 2;
199 g = (bf[-width] + bf[1] + bf[width] + bf[-1]) >> 2;
200 RGB2YUV(r, g, *bf, y2, u2, v2);
203 assign(y, u, v, y1, u1, v1, y2, u2, v2);
205 for (
unsigned int w = 2; w < width - 2; w += 2) {
206 r = (bf[width] + bf[-width]) >> 1;
207 b = (bf[-1] + bf[1]) >> 1;
208 RGB2YUV(r, *bf, b, y1, u1, v1);
211 r = (bf[-width-1] + bf[-width+1] + bf[width-1] + bf[width+1]) >> 2;
212 g = (bf[-width] + bf[1] + bf[width] + bf[-1]) >> 2;
213 RGB2YUV(r, g, *bf, y2, u2, v2);
216 assign(y, u, v, y1, u1, v1, y2, u2, v2);
219 r = (bf[width] + bf[-width]) >> 1;
220 b = (bf[-1] + bf[1]) >> 1;
221 RGB2YUV(r, *bf, b, y1, u1, v1);
224 r = (bf[-width-1] + bf[width-1]) >> 1;
227 g = (bf[-width] + bf[-1]) >> 1;
228 RGB2YUV(r, g, *bf, y2, u2, v2);
231 assign(y, u, v, y1, u1, v1, y2, u2, v2);
237 g = (bf[-width] + bf[1]) >> 1;
239 RGB2YUV(*bf, g, b, y1, u1, v1);
242 r = (bf[-1] + bf[1]) >> 1;
244 RGB2YUV(r, g, *bf, y2, u2, v2);
247 assign(y, u, v, y1, u1, v1, y2, u2, v2);
249 for (
unsigned int w = 2; w < width - 2; w += 2) {
252 g = (bf[-width] + bf[-1]) >> 1;
253 b = (bf[-width-1] + bf[-width+1]) >> 1;
254 RGB2YUV(*bf, g, b, y1, u1, v1);
257 r = (bf[-1] + bf[1]) >> 1;
259 RGB2YUV(r, *bf, b, y2, u2, v2);
262 assign(y, u, v, y1, u1, v1, y2, u2, v2);
267 g = (bf[-width] + bf[-1]) >> 1;
268 b = (bf[-width-1] + bf[-width+1]) >> 1;
269 RGB2YUV(*bf, g, b, y1, u1, v1);
273 RGB2YUV(bf[-1], *bf, b, y2, u2, v2);
276 assign(y, u, v, y1, u1, v1, y2, u2, v2);
282 bayerGBRG_to_yuv422planar_bilinear2(
const unsigned char *bayer,
unsigned char *yuv,
283 unsigned int width,
unsigned int height)
285 unsigned char *y = yuv;
286 unsigned char *u = YUV422_PLANAR_U_PLANE(yuv, width, height);
287 unsigned char *v = YUV422_PLANAR_V_PLANE(yuv, width, height);
288 const unsigned char *bf = bayer;
290 int y1, u1, v1, y2, u2, v2;
299 for (
unsigned int h = 1; h < height - 1; h += 2) {
307 for (
unsigned int w = 2; w < width - 2; w += 2) {
308 g = (bf[1] + bf[-1]) >> 1;
309 b = (bf[width-1] + bf[width+1]) >> 1;
310 RGB2YUV(*bf, g, b, y1, u1, v1);
313 r = (bf[-1] + bf[1]) >> 1;
314 b = (bf[-width] + bf[width]) >> 1;
315 RGB2YUV(r, *bf, b, y2, u2, v2);
318 assign(y, u, v, y1, u1, v1, y2, u2, v2);
332 for (
unsigned int w = 2; w < width - 2; w += 2) {
333 r = (bf[width] + bf[-width]) >> 1;
334 b = (bf[-1] + bf[1]) >> 1;
335 RGB2YUV(r, *bf, b, y1, u1, v1);
338 r = (bf[width-1] + bf[width+1]) >> 1;
339 g = (bf[1] + bf[width]) >> 1;
340 RGB2YUV(r, g, *bf, y2, u2, v2);
343 assign(y, u, v, y1, u1, v1, y2, u2, v2);
546 bayerGRBG_to_yuv422planar_nearest_neighbour(
const unsigned char *bayer,
551 unsigned char *y = yuv;
552 unsigned char *u = YUV422_PLANAR_U_PLANE(yuv, width, height);
553 unsigned char *v = YUV422_PLANAR_V_PLANE(yuv, width, height);
554 const unsigned char *b = bayer;
556 int y1, u1, v1, y2, u2, v2;
558 for (
unsigned int h = 0; h < height; h += 2) {
561 for (
unsigned int w = 0; w < width; w += 2) {
562 RGB2YUV(b[1], b[width], *b, y1, u1, v1);
565 RGB2YUV(*b, b[-1], b[width - 1], y2, u2, v2);
568 assign(y, u, v, y1, u1, v1, y2, u2, v2);
572 for (
unsigned int w = 0; w < width; w += 2) {
573 RGB2YUV(*(b-width+1), b[1], *b, y1, u1, v1);
576 RGB2YUV(*(b-width), *b, b[-1], y2, u2, v2);
579 assign(y, u, v, y1, u1, v1, y2, u2, v2);
586 bayerRGGB_to_yuv422planar_nearest_neighbour(
const unsigned char *bayer,
591 unsigned char *y = yuv;
592 unsigned char *u = YUV422_PLANAR_U_PLANE(yuv, width, height);
593 unsigned char *v = YUV422_PLANAR_V_PLANE(yuv, width, height);
594 const unsigned char *b = bayer;
596 int y1, u1, v1, y2, u2, v2;
598 for (
unsigned int h = 0; h < height; h += 2) {
601 for (
unsigned int w = 0; w < width; w += 2) {
602 RGB2YUV(*b, b[1], b[width+1], y1, u1, v1);
605 RGB2YUV(b[-1], *b, b[width], y2, u2, v2);
608 assign(y, u, v, y1, u1, v1, y2, u2, v2);
612 for (
unsigned int w = 0; w < width; w += 2) {
613 RGB2YUV(*(b-width), *b, b[1], y1, u1, v1);
616 RGB2YUV(*(b-width-1), b[-1], *b, y2, u2, v2);
619 assign(y, u, v, y1, u1, v1, y2, u2, v2);
625 bayerGRBG_to_yuv422planar_bilinear(
const unsigned char *bayer,
unsigned char *yuv,
626 unsigned int width,
unsigned int height)
628 unsigned char *y = yuv;
629 unsigned char *u = YUV422_PLANAR_U_PLANE(yuv, width, height);
630 unsigned char *v = YUV422_PLANAR_V_PLANE(yuv, width, height);
631 const unsigned char *bf = bayer;
633 int y1, u1, v1, y2, u2, v2;
639 RGB2YUV(bf[1], *bf, bf[width], y1, u1, v1);
642 b = (bf[width - 1] + bf[width + 1]) >> 1;
646 g = (bf[-1] + bf[1]) >> 1;
647 RGB2YUV(*bf, g, b, y2, u2, v2);
650 assign(y, u, v, y1, u1, v1, y2, u2, v2);
653 for (
unsigned int w = 2; w < width - 2; w += 2) {
654 r = (bf[-1] + bf[1]) >> 1;
655 RGB2YUV(r, *bf, bf[width], y1, u1, v1);
658 b = (bf[width - 1] + bf[width + 1]) >> 1;
662 g = (bf[-1] + bf[1]) >> 1;
663 RGB2YUV(*bf, g, b, y2, u2, v2);
666 assign(y, u, v, y1, u1, v1, y2, u2, v2);
670 r = (bf[-1] + bf[1]) >> 1;
671 RGB2YUV(r, *bf, bf[width], y1, u1, v1);
674 g = (bf[-1] + bf[width]) >> 1;
675 RGB2YUV(*bf, g, bf[width - 1], y2, u2, v2);
678 assign(y, u, v, y1, u1, v1, y2, u2, v2);
680 for (
unsigned int h = 1; h < height - 1; h += 2) {
685 g = (*(bf-width) + bf[1]) >> 1;
686 r = (*(bf-width+1) + bf[width+1]) >> 1;
687 RGB2YUV(r, g, *bf, y1, u1, v1);
690 b = (bf[-1] + bf[1]) >> 1;
691 r = (*(bf-width) + bf[width]) >> 1;
692 RGB2YUV(r, *bf, g, y2, u2, v2);
695 assign(y, u, v, y1, u1, v1, y2, u2, v2);
697 for (
unsigned int w = 2; w < width - 2; w += 2) {
698 g = (*(bf-width) + bf[1] + bf[width] + bf[-1]) >> 2;
699 r = (*(bf-width-1) + *(bf-width+1) + bf[width-1] + bf[width+1]) >> 2;
700 RGB2YUV(r, g, *bf, y1, u1, v1);
703 b = (bf[-1] + bf[1]) >> 1;
704 r = ( *(bf-width) + bf[width]) >> 1;
705 RGB2YUV(r, *bf, b, y2, u2, v2);
708 assign(y, u, v, y1, u1, v1, y2, u2, v2);
711 g = (*(bf-width) + bf[1] + bf[width] + bf[-1]) >> 2;
712 r = (*(bf-width-1) + *(bf-width+1) + bf[width-1] + bf[width+1]) >> 2;
713 RGB2YUV(r, g, *bf, y1, u1, v1);
716 r = (*(bf-width) + bf[width]) >> 1;
717 RGB2YUV(r, *bf, bf[-1], y2, u2, v2);
720 assign(y, u, v, y1, u1, v1, y2, u2, v2);
724 b = (bf[width] + *(bf-width)) >> 1;
725 RGB2YUV(bf[1], *bf, b, y1, u1, v1);
728 b = (*(bf-width-1) + *(bf-width+1) + bf[width - 1] + bf[width + 1]) >> 2;
729 g = (*(bf-width) + bf[1] + bf[width] + bf[-1]) >> 2;
730 RGB2YUV(*bf, g, b, y2, u2, v2);
733 assign(y, u, v, y1, u1, v1, y2, u2, v2);
735 for (
unsigned int w = 2; w < width - 2; w += 2) {
736 b = (bf[width] + *(bf-width)) >> 1;
737 r = (bf[-1] + bf[1]) >> 1;
738 RGB2YUV(r, *bf, b, y1, u1, v1);
741 b = (*(bf-width-1) + *(bf-width+1) + bf[width-1] + bf[width+1]) >> 2;
742 g = (*(bf-width) + bf[1] + bf[width] + bf[-1]) >> 2;
743 RGB2YUV(*bf, g, b, y2, u2, v2);
746 assign(y, u, v, y1, u1, v1, y2, u2, v2);
749 b = (bf[width] + *(bf-width)) >> 1;
750 r = (bf[-1] + bf[1]) >> 1;
751 RGB2YUV(r, *bf, b, y1, u1, v1);
754 b = (*(bf-width-1) + bf[width-1]) >> 1;
757 g = (*(bf-width) + bf[-1]) >> 1;
758 RGB2YUV(*bf, g, r, y2, u2, v2);
761 assign(y, u, v, y1, u1, v1, y2, u2, v2);
767 g = (*(bf-width) + bf[1]) >> 1;
769 RGB2YUV(r, g, *bf, y1, u1, v1);
772 b = (bf[-1] + bf[1]) >> 1;
774 RGB2YUV(r, *bf, b, y2, u2, v2);
777 assign(y, u, v, y1, u1, v1, y2, u2, v2);
779 for (
unsigned int w = 2; w < width - 2; w += 2) {
782 g = (*(bf-width) + bf[-1]) >> 1;
783 r = (*(bf-width-1) + *(bf-width+1)) >> 1;
784 RGB2YUV(r, g, *bf, y1, u1, v1);
787 b = (bf[-1] + bf[1]) >> 1;
789 RGB2YUV(r, *bf, b, y2, u2, v2);
792 assign(y, u, v, y1, u1, v1, y2, u2, v2);
797 g = (*(bf-width) + bf[-1]) >> 1;
798 r = (*(bf-width-1) + *(bf-width+1)) >> 1;
799 RGB2YUV(r, g, *bf, y1, u1, v1);
803 RGB2YUV(r, *bf, bf[-1], y2, u2, v2);
806 assign(y, u, v, y1, u1, v1, y2, u2, v2);
812 bayerGRBG_to_rgb_nearest_neighbour(
const unsigned char *bayer,
unsigned char *rgb,
813 unsigned int width,
unsigned int height)
815 for (
unsigned int h = 0; h < height; h += 2) {
817 for (
unsigned int w = 0; w < width; w += 2) {
819 *rgb++ = bayer[width];
825 *rgb++ = bayer[width - 1];
830 for (
unsigned int w = 0; w < width; w += 2) {
831 *rgb++ = *(bayer-width+1);
836 *rgb++ = *(bayer-width);
846 bayerGRBG_to_rgb_bilinear(
const unsigned char *bayer,
unsigned char *rgb,
847 unsigned int width,
unsigned int height)
854 *rgb++ = bayer[width];
861 *rgb++ = (bayer[-1] + bayer[1]) >> 1;
862 *rgb++ = (bayer[width - 1] + bayer[width + 1]) >> 1;
866 for (
unsigned int w = 2; w < width - 2; w += 2) {
867 *rgb++ = (bayer[-1] + bayer[1]) >> 1;
869 *rgb++ = bayer[width];
876 *rgb++ = (bayer[-1] + bayer[1]) >> 1;
877 *rgb++ = (bayer[width - 1] + bayer[width + 1]) >> 1;
882 *rgb++ = (bayer[-1] + bayer[1]) >> 1;
884 *rgb++ = bayer[width];
888 *rgb++ = (bayer[-1] + bayer[width]) >> 1;
889 *rgb++ = bayer[width - 1];
892 for (
unsigned int h = 1; h < height - 1; h += 2) {
896 *rgb++ = (*(bayer-width+1) + bayer[width+1]) >> 1;
897 *rgb++ = (*(bayer-width) + bayer[1]) >> 1;
901 *rgb++ = (*(bayer-width) + bayer[width]) >> 1;
903 *rgb++ = (bayer[-1] + bayer[1]) >> 1;
906 for (
unsigned int w = 2; w < width - 2; w += 2) {
907 *rgb++ = (*(bayer-width-1) + *(bayer-width+1) + bayer[width-1] + bayer[width+1]) >> 2;
908 *rgb++ = (*(bayer-width) + bayer[1] + bayer[width] + bayer[-1]) >> 2;
912 *rgb++ = (*(bayer-width) + bayer[width]) >> 1;
914 *rgb++ = (bayer[-1] + bayer[1]) >> 1;
918 *rgb++ = (*(bayer-width-1) + *(bayer-width+1) + bayer[width-1] + bayer[width+1]) >> 2;
919 *rgb++ = (*(bayer-width) + bayer[1] + bayer[width] + bayer[-1]) >> 2;
923 *rgb++ = (*(bayer-width) + bayer[width]) >> 1;
932 *rgb++ = (bayer[width] + *(bayer-width)) >> 1;
936 *rgb++ = (*(bayer-width) + bayer[1] + bayer[width] + bayer[-1]) >> 2;
937 *rgb++ = (*(bayer-width-1) + *(bayer-width+1) + bayer[width - 1] + bayer[width + 1]) >> 2;
940 for (
unsigned int w = 2; w < width - 2; w += 2) {
941 *rgb++ = (bayer[-1] + bayer[1]) >> 1;
943 *rgb++ = (bayer[width] + *(bayer-width)) >> 1;
947 *rgb++ = (*(bayer-width) + bayer[1] + bayer[width] + bayer[-1]) >> 2;
948 *rgb++ = (*(bayer-width-1) + *(bayer-width+1) + bayer[width-1] + bayer[width+1]) >> 2;
952 *rgb++ = (bayer[-1] + bayer[1]) >> 1;
954 *rgb++ = (bayer[width] + *(bayer-width)) >> 1;
960 *rgb++ = (*(bayer-width) + bayer[-1]) >> 1;
961 *rgb++ = (*(bayer-width-1) + bayer[width-1]) >> 1;
968 *rgb++ = *(bayer-width+1);
969 *rgb++ = (*(bayer-width) + bayer[1]) >> 1;
973 *rgb++ = *(bayer-width);
975 *rgb++ = (bayer[-1] + bayer[1]) >> 1;
978 for (
unsigned int w = 2; w < width - 2; w += 2) {
981 *rgb++ = (*(bayer-width-1) + *(bayer-width+1)) >> 1;
982 *rgb++ = (*(bayer-width) + bayer[-1]) >> 1;
986 *rgb++ = *(bayer-width);
988 *rgb++ = (bayer[-1] + bayer[1]) >> 1;
994 *rgb++ = (*(bayer-width-1) + *(bayer-width+1)) >> 1;
995 *rgb++ = (*(bayer-width) + bayer[-1]) >> 1;
999 *rgb++ = *(bayer-width);