|
|
|
|
@ -1,3 +1,7 @@
|
|
|
|
|
|
|
|
|
|
#include "video.h"
|
|
|
|
|
#include "debayer.h"
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
@ -6,59 +10,6 @@
|
|
|
|
|
|
|
|
|
|
std::string toBits(unsigned int i, int maxbits);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
The function converts a 16bit GRBG 2x2 CFA coded image into an 8bit
|
|
|
|
|
RGB image by setting the missing RGB values to zero.
|
|
|
|
|
*/
|
|
|
|
|
void debayer_grbg16_simple (uint16_t * src, int src_w, int src_h,
|
|
|
|
|
uint8_t * dst, int dst_w, int dst_h) {
|
|
|
|
|
|
|
|
|
|
// GG RR
|
|
|
|
|
// BB GG
|
|
|
|
|
uint16_t t;
|
|
|
|
|
uint8_t r, g, b;
|
|
|
|
|
int ys, yd, xs, xd;
|
|
|
|
|
|
|
|
|
|
for (ys = 0, yd = 0; ys < src_h && yd < dst_h; ys++, yd++) {
|
|
|
|
|
for (xs = 0, xd = 0; xs < src_w; xs++) {
|
|
|
|
|
|
|
|
|
|
/* read the pixel but only the higher 8bit, assuming data is little endian */
|
|
|
|
|
t = (*(src++) >> 8) & 0xff;
|
|
|
|
|
|
|
|
|
|
if (xs & 1) {
|
|
|
|
|
if (ys & 1) {
|
|
|
|
|
// lower right green pixel
|
|
|
|
|
b = 0; g = t; r = 0;
|
|
|
|
|
} else {
|
|
|
|
|
// upper right red pixel
|
|
|
|
|
b = 0; g = 0; r = t;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (ys & 1) {
|
|
|
|
|
// lower left blue pixel
|
|
|
|
|
b = t; g = 0; r = 0;
|
|
|
|
|
} else {
|
|
|
|
|
// upper left green pixel
|
|
|
|
|
b = 0; g = t; r = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* only paint the image if the source is within the destination */
|
|
|
|
|
if (xd < dst_w) {
|
|
|
|
|
/* set the pixel */
|
|
|
|
|
*(dst++) = r;
|
|
|
|
|
*(dst++) = g;
|
|
|
|
|
*(dst++) = b;
|
|
|
|
|
xd++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* if the source image is too small ignore the other places */
|
|
|
|
|
if (xd < dst_w)
|
|
|
|
|
dst += 3 * (dst_w - xd);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// macros to make code better readable
|
|
|
|
|
#define CE (*(src))
|
|
|
|
|
#define UP (*(src-src_w))
|
|
|
|
|
@ -79,8 +30,8 @@ void debayer_grbg16_simple (uint16_t * src, int src_w, int src_h,
|
|
|
|
|
The function converts a 16bit GRBG 2x2 CFA coded image into an 8bit
|
|
|
|
|
RGB image by bilinear interpolation.
|
|
|
|
|
*/
|
|
|
|
|
void debayer_grbg16_bilinear (uint16_t * src, int src_w, int src_h,
|
|
|
|
|
uint8_t * dst, int dst_w, int dst_h) {
|
|
|
|
|
void debayer_grbg16 (uint16_t * src, int src_w, int src_h,
|
|
|
|
|
uint8_t * dst, int dst_w, int dst_h) {
|
|
|
|
|
|
|
|
|
|
// GG RR GG RR
|
|
|
|
|
// BB GG BB GG
|
|
|
|
|
@ -196,65 +147,19 @@ void debayer_grbg16_bilinear (uint16_t * src, int src_w, int src_h,
|
|
|
|
|
STORE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
The function converts a 8bit GRBG 2x2 CFA coded image into an 8bit
|
|
|
|
|
RGB image by setting the missing RGB values to zero.
|
|
|
|
|
*/
|
|
|
|
|
void debayer_grbg8_simple (uint8_t * src, int src_w, int src_h,
|
|
|
|
|
uint8_t * dst, int dst_w, int dst_h) {
|
|
|
|
|
|
|
|
|
|
// GG RR
|
|
|
|
|
// BB GG
|
|
|
|
|
uint8_t t;
|
|
|
|
|
uint16_t r, g, b;
|
|
|
|
|
int ys, yd, xs, xd;
|
|
|
|
|
|
|
|
|
|
for (ys = 0, yd = 0; ys < src_h && yd < dst_h; ys++, yd++) {
|
|
|
|
|
for (xs = 0, xd = 0; xs < src_w; xs++) {
|
|
|
|
|
|
|
|
|
|
/* read the pixel but only the higher 8bit, assuming data is little endian */
|
|
|
|
|
t = *(src++);
|
|
|
|
|
|
|
|
|
|
if (xs & 1) {
|
|
|
|
|
if (ys & 1) {
|
|
|
|
|
// lower right green pixel
|
|
|
|
|
b = 0; g = t; r = 0;
|
|
|
|
|
} else {
|
|
|
|
|
// upper right red pixel
|
|
|
|
|
b = 0; g = 0; r = t;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (ys & 1) {
|
|
|
|
|
// lower left blue pixel
|
|
|
|
|
b = t; g = 0; r = 0;
|
|
|
|
|
} else {
|
|
|
|
|
// upper left green pixel
|
|
|
|
|
b = 0; g = t; r = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* only paint the image if the source is within the destination */
|
|
|
|
|
if (xd < dst_w) {
|
|
|
|
|
/* set the pixel */
|
|
|
|
|
*(dst++) = r;
|
|
|
|
|
*(dst++) = g;
|
|
|
|
|
*(dst++) = b;
|
|
|
|
|
xd++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* if the source image is too small ignore the other places */
|
|
|
|
|
if (xd < dst_w)
|
|
|
|
|
dst += 3 * (dst_w - xd);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
The function converts a 8bit GRBG 2x2 CFA coded image into an 8bit
|
|
|
|
|
RGB image by bilinear interpolation.
|
|
|
|
|
*/
|
|
|
|
|
void debayer_grbg8_bilinear (uint8_t * src, int src_w, int src_h,
|
|
|
|
|
uint8_t * dst, int dst_w, int dst_h) {
|
|
|
|
|
void debayer_gbrg8 (uint8_t * src, int src_w, int src_h, uint8_t * dst, int dst_w, int dst_h) {
|
|
|
|
|
debayer_grbg8 (src, src_w, src_h, dst, dst_w, dst_h);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void debayer_rggb8 (uint8_t * src, int src_w, int src_h, uint8_t * dst, int dst_w, int dst_h) {
|
|
|
|
|
debayer_grbg8 (src, src_w, src_h, dst, dst_w, dst_h);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void debayer_grbg8 (uint8_t * src, int src_w, int src_h, uint8_t * dst, int dst_w, int dst_h) {
|
|
|
|
|
|
|
|
|
|
// GG RR GG RR
|
|
|
|
|
// BB GG BB GG
|
|
|
|
|
@ -379,8 +284,8 @@ int MAX(int a, int m) { if (a > m) return m; else return a; };
|
|
|
|
|
#define PRGGB10P_UR ((uint16_t)(*(psrc+2-src_w*2*10/8)))
|
|
|
|
|
#define PRGGB10P_DL ((uint16_t)(*(psrc-2-src_w*2*10/8)))
|
|
|
|
|
#define PRGGB10P_DR ((uint16_t)(*(psrc+2+src_w*2*10/8)))
|
|
|
|
|
void debayer_rggb10packet_simple (uint8_t * src, int src_w, int src_h,
|
|
|
|
|
uint8_t * dst, int dst_w, int dst_h) {
|
|
|
|
|
void debayer_rggb10packet (uint8_t * src, int src_w, int src_h,
|
|
|
|
|
uint8_t * dst, int dst_w, int dst_h) {
|
|
|
|
|
int s, d;
|
|
|
|
|
int xs, ys, xd, yd;
|
|
|
|
|
unsigned char r, g, b;
|
|
|
|
|
@ -463,13 +368,6 @@ std::string toBits(unsigned int i, int maxbits) {
|
|
|
|
|
return out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void debayer_rggb10packet_bilinear (uint8_t * src, int src_w, int src_h,
|
|
|
|
|
uint8_t * dst, int dst_w, int dst_h) {
|
|
|
|
|
|
|
|
|
|
debayer_rggb10packet_simple (src, src_w, src_h, dst, dst_w, dst_h);
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline int swap16(uint16_t i) {
|
|
|
|
|
uint16_t r;
|
|
|
|
|
@ -479,24 +377,89 @@ inline int swap16(uint16_t i) {
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define PRGGB10_U ((uint16_t)(*(psrc-src_w*2)))
|
|
|
|
|
#define PRGGB10_D ((uint16_t)(*(psrc+src_w*2)))
|
|
|
|
|
#define PRGGB10_L ((uint16_t)(*(psrc-2)))
|
|
|
|
|
#define PRGGB10_R ((uint16_t)(*(psrc+2)))
|
|
|
|
|
#define PRGGB10_UL ((uint16_t)(*(psrc-2-src_w*2)))
|
|
|
|
|
#define PRGGB10_UR ((uint16_t)(*(psrc+2-src_w*2)))
|
|
|
|
|
#define PRGGB10_DL ((uint16_t)(*(psrc-2-src_w*2)))
|
|
|
|
|
#define PRGGB10_DR ((uint16_t)(*(psrc+2+src_w*2)))
|
|
|
|
|
void debayer_rggb10_simple (uint8_t * src, int src_w, int src_h,
|
|
|
|
|
uint8_t * dst, int dst_w, int dst_h) {
|
|
|
|
|
|
|
|
|
|
#define PRGGB10_U (unsigned int)(*(psrc-src_w))
|
|
|
|
|
#define PRGGB10_D (unsigned int)(*(psrc+src_w))
|
|
|
|
|
#define PRGGB10_L (unsigned int)(*(psrc-1))
|
|
|
|
|
#define PRGGB10_R (unsigned int)(*(psrc+1))
|
|
|
|
|
#define PRGGB10_UL (unsigned int)(*(psrc-1-src_w))
|
|
|
|
|
#define PRGGB10_UR (unsigned int)(*(psrc+1-src_w))
|
|
|
|
|
#define PRGGB10_DL (unsigned int)(*(psrc-1+src_w))
|
|
|
|
|
#define PRGGB10_DR (unsigned int)(*(psrc+1+src_w))
|
|
|
|
|
void debayer_gbrg10 (uint8_t * src, int src_w, int src_h, uint8_t * dst, int dst_w, int dst_h) {
|
|
|
|
|
// GG BB GG BB
|
|
|
|
|
// RR GG RR GG
|
|
|
|
|
// GG BB GG BB
|
|
|
|
|
// RR GG RR GG
|
|
|
|
|
int xs, ys, xd, yd;
|
|
|
|
|
uint16_t r, g, b, data;
|
|
|
|
|
uint32_t r, g, b, data;
|
|
|
|
|
int max = dst_w * dst_h * 3;
|
|
|
|
|
unsigned char *pdst;
|
|
|
|
|
unsigned char *psrc;
|
|
|
|
|
uint8_t *pdst;
|
|
|
|
|
uint16_t *psrc;
|
|
|
|
|
int max_r = 0;
|
|
|
|
|
int max_g = 0;
|
|
|
|
|
int max_b = 0;
|
|
|
|
|
|
|
|
|
|
for (ys = 0, yd = 0, psrc = src, pdst = dst; ys < dst_h; ys++, yd++) {
|
|
|
|
|
for (ys = 0, yd = 0, psrc = (uint16_t*)src, pdst = dst; ys < dst_h; ys++, yd++) {
|
|
|
|
|
r = 0;
|
|
|
|
|
g = 0;
|
|
|
|
|
b = 0;
|
|
|
|
|
for (xs = 0, xd = 0; xd < dst_w; xs++, xd++) {
|
|
|
|
|
if (ys > 0 && ys < src_h-1 && xs > 0 && xs < src_w-1) {
|
|
|
|
|
r = 0; b = 0; g = 0;
|
|
|
|
|
if (ys&1) {
|
|
|
|
|
if (xs&1) {
|
|
|
|
|
b = (unsigned int)(PRGGB10_U + PRGGB10_D) >> 1;
|
|
|
|
|
g = *psrc;
|
|
|
|
|
r = (unsigned int)(PRGGB10_L + PRGGB10_R) >> 1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
b = (unsigned int)(PRGGB10_UL + PRGGB10_DL + PRGGB10_UR + PRGGB10_UL) >> 2;
|
|
|
|
|
g = (unsigned int)(PRGGB10_L + PRGGB10_R + PRGGB10_U + PRGGB10_D) >> 2;
|
|
|
|
|
r = *psrc;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (xs&1) {
|
|
|
|
|
b = *psrc;
|
|
|
|
|
g = (unsigned int)(PRGGB10_L + PRGGB10_R + PRGGB10_U + PRGGB10_D) >> 2;
|
|
|
|
|
r = (unsigned int)(PRGGB10_UL + PRGGB10_DL + PRGGB10_UR + PRGGB10_UL) >> 2;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
b = (unsigned int)(PRGGB10_L + PRGGB10_R) >> 1;
|
|
|
|
|
g = *psrc;
|
|
|
|
|
r = (unsigned int)(PRGGB10_U + PRGGB10_D) >> 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
pdst[0] = (r >> 2);
|
|
|
|
|
pdst[1] = (g >> 2);
|
|
|
|
|
pdst[2] = (b >> 2);
|
|
|
|
|
// if (yd < 100 && xd < 300) {
|
|
|
|
|
// pdst[0] = 0; if (xd < 100) pdst[0] = 255;
|
|
|
|
|
// pdst[1] = 0; if (xd > 100 && xd < 200) pdst[1] = 255;
|
|
|
|
|
// pdst[2] = 0; if (xd > 200 && xd < 300) pdst[2] = 255;
|
|
|
|
|
// }
|
|
|
|
|
pdst += 3;
|
|
|
|
|
psrc += 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void debayer_rggb10 (uint8_t *src, int src_w, int src_h, uint8_t * dst, int dst_w, int dst_h) {
|
|
|
|
|
// RR GG RR GG
|
|
|
|
|
// GG BB GG BB
|
|
|
|
|
// RR GG RR GG
|
|
|
|
|
// GG BB GG BB
|
|
|
|
|
int xs, ys, xd, yd;
|
|
|
|
|
uint32_t r, g, b, data;
|
|
|
|
|
int max = dst_w * dst_h * 3;
|
|
|
|
|
uint8_t *pdst;
|
|
|
|
|
uint16_t *psrc;
|
|
|
|
|
int max_r = 0;
|
|
|
|
|
int max_g = 0;
|
|
|
|
|
int max_b = 0;
|
|
|
|
|
|
|
|
|
|
for (ys = 0, yd = 0, psrc = (uint16_t*)src, pdst = dst; ys < dst_h; ys++, yd++) {
|
|
|
|
|
r = 0;
|
|
|
|
|
g = 0;
|
|
|
|
|
b = 0;
|
|
|
|
|
@ -506,45 +469,38 @@ void debayer_rggb10_simple (uint8_t * src, int src_w, int src_h,
|
|
|
|
|
if (ys&1) {
|
|
|
|
|
if (xs&1) {
|
|
|
|
|
b = *psrc;
|
|
|
|
|
g = (PRGGB10_L + PRGGB10_R + PRGGB10_U + PRGGB10_D)/4;
|
|
|
|
|
r = (PRGGB10_UL + PRGGB10_DL + PRGGB10_UR + PRGGB10_UL)/4;
|
|
|
|
|
g = (unsigned int)(PRGGB10_L + PRGGB10_R + PRGGB10_U + PRGGB10_D) >> 2;
|
|
|
|
|
r = (unsigned int)(PRGGB10_UL + PRGGB10_DL + PRGGB10_UR + PRGGB10_UL) >> 2;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
b = (PRGGB10_L + PRGGB10_R)/2;
|
|
|
|
|
b = (unsigned int)(PRGGB10_L + PRGGB10_R) >> 1;
|
|
|
|
|
g = *psrc;
|
|
|
|
|
r = (PRGGB10_U + PRGGB10_D)/2;
|
|
|
|
|
r = (unsigned int)(PRGGB10_U + PRGGB10_D) >> 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (xs&1) {
|
|
|
|
|
b = (PRGGB10_U + PRGGB10_D)/2;
|
|
|
|
|
b = (unsigned int)(PRGGB10_U + PRGGB10_D) >> 1;
|
|
|
|
|
g = *psrc;
|
|
|
|
|
r = (PRGGB10_L + PRGGB10_R)/2;
|
|
|
|
|
r = (unsigned int)(PRGGB10_L + PRGGB10_R) >> 1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
g = (PRGGB10_L + PRGGB10_R + PRGGB10_U + PRGGB10_D)/4;
|
|
|
|
|
b = (PRGGB10_UL + PRGGB10_DL + PRGGB10_UR + PRGGB10_UL)/4;
|
|
|
|
|
g = (unsigned int)(PRGGB10_L + PRGGB10_R + PRGGB10_U + PRGGB10_D) >> 2;
|
|
|
|
|
b = (unsigned int)(PRGGB10_UL + PRGGB10_DL + PRGGB10_UR + PRGGB10_UL) >> 2;
|
|
|
|
|
r = *psrc;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// if (pdst - dst > max) {
|
|
|
|
|
// printf ("debayer error. dpst out of bounds size:%dx%d pos:%dx%d \n", dst_w, dst_h, xd, yd);
|
|
|
|
|
pdst[0] = (r >> 2);
|
|
|
|
|
pdst[1] = (g >> 2);
|
|
|
|
|
pdst[2] = (b >> 2);
|
|
|
|
|
// if (yd < 100 && xd < 300) {
|
|
|
|
|
// pdst[0] = 0; if (xd < 100) pdst[0] = 255;
|
|
|
|
|
// pdst[1] = 0; if (xd > 100 && xd < 200) pdst[1] = 255;
|
|
|
|
|
// pdst[2] = 0; if (xd > 200 && xd < 300) pdst[2] = 255;
|
|
|
|
|
// }
|
|
|
|
|
// if ((ys == 10 || ys == 11) && xs < 10) printf ("%dx%d - %d, %d, %d\n", xs, ys, r, g, b);
|
|
|
|
|
pdst[0] = (r);
|
|
|
|
|
pdst[1] = (g);
|
|
|
|
|
pdst[2] = (b);
|
|
|
|
|
pdst += 3;
|
|
|
|
|
psrc += 2;
|
|
|
|
|
psrc += 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void debayer_rggb10_bilinear (uint8_t * src, int src_w, int src_h,
|
|
|
|
|
uint8_t * dst, int dst_w, int dst_h) {
|
|
|
|
|
debayer_rggb10_simple(src, src_w, src_h, dst, dst_w, dst_h);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|