parent
59c59e557a
commit
032cbdc0cf
@ -0,0 +1,188 @@
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
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; ys++) {
|
||||
for (xs = 0, xd = 0; xs < src_w; xs++) {
|
||||
|
||||
/* read the pixel but only the lower 8bit */
|
||||
t = *(src++) & 0x00FF;
|
||||
|
||||
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 = 0; g = t; 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++) = b;
|
||||
*(dst++) = g;
|
||||
*(dst++) = r;
|
||||
xd++;
|
||||
}
|
||||
}
|
||||
|
||||
/* if the source image is too small ignore the other places */
|
||||
if (xd < dst_w)
|
||||
dst += 3 * (dst_w - xd);
|
||||
yd++;
|
||||
}
|
||||
}
|
||||
|
||||
// macros to make code better readable
|
||||
#define CE (*(src))
|
||||
#define UP (*(src-src_w))
|
||||
#define DN (*(src+src_w))
|
||||
#define LE (*(src-1))
|
||||
#define RI (*(src+1))
|
||||
#define UPLE (*(src-src_w-1))
|
||||
#define UPRI (*(src-src_w+11))
|
||||
#define DNLE (*(src+src_w-1))
|
||||
#define DNRI (*(src+src_w+11))
|
||||
#define STORE *(dst++) = r; *(dst++) = g; *(dst++) = b; src++;
|
||||
|
||||
|
||||
/*
|
||||
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) {
|
||||
|
||||
// GG RR GG RR
|
||||
// BB GG BB GG
|
||||
// GG RR GG RR
|
||||
// BB GG BB GG
|
||||
uint8_t r, g, b;
|
||||
int xs, ys;
|
||||
|
||||
// start with upper left pixel (green)
|
||||
r = RI;
|
||||
g = CE;
|
||||
b = DN;
|
||||
STORE;
|
||||
|
||||
// upper first line, starts with RR GG RR ...
|
||||
for (xs = 1; xs < src_w - 1; xs+=2) {
|
||||
// red pixel
|
||||
r = CE;
|
||||
g = (LE + RI + DN) / 3;
|
||||
b = (DNLE + DNRI) / 2;
|
||||
STORE;
|
||||
// green pixel
|
||||
r = (LE + RI) / 2;
|
||||
g = CE;
|
||||
b = DN;
|
||||
STORE;
|
||||
}
|
||||
|
||||
// upper right pixel (red)
|
||||
r = CE;
|
||||
g = (DN + LE) / 2;
|
||||
b = DNLE;
|
||||
STORE;
|
||||
|
||||
// got through the "body" of the image
|
||||
for (ys = 1; ys < src_h - 1; ys+=2) {
|
||||
|
||||
// every second line with BB GG BB GG (start at 2nd line)
|
||||
|
||||
// left hand pixel (blue)
|
||||
r = (UPRI + DNRI) / 2;
|
||||
g = (UP + DN + RI) / 3;
|
||||
b = CE;
|
||||
STORE;
|
||||
for (xs = 1; xs < src_w - 1; xs+=2) {
|
||||
// green pixel
|
||||
r = (UP + DN) / 2;
|
||||
g = CE;
|
||||
b = (LE + RI) / 2;
|
||||
STORE;
|
||||
// blue pixel
|
||||
r = (UPLE + UPRI + DNLE + DNRI) / 4;
|
||||
g = (LE + RI + UP + DN) / 4;
|
||||
b = CE;
|
||||
STORE;
|
||||
}
|
||||
// last pixel in line (green)
|
||||
r = (UP + DN) / 2;
|
||||
g = CE;
|
||||
b = LE;
|
||||
STORE;
|
||||
|
||||
// every second line with GG RR GG RR ... (start at 3rd line)
|
||||
|
||||
// left hand pixel (green)
|
||||
r = RI;
|
||||
g = CE;
|
||||
b = (UP + DN) / 2;
|
||||
STORE;
|
||||
for (xs = 1; xs < src_w - 1; xs+=2) {
|
||||
// red pixel
|
||||
r = CE;
|
||||
g = (LE + RI + UP + DN) / 4;
|
||||
b = (UPLE + UPRI + DNLE + DNRI) / 4;
|
||||
STORE;
|
||||
// green pixel
|
||||
r = (LE + RI) / 2;
|
||||
g = CE;
|
||||
b = (UP + DN) / 2;
|
||||
}
|
||||
// last pixel in line (red)
|
||||
r = CE;
|
||||
g = (UP + DN + LE) / 3;
|
||||
b = (UPLE + DNLE) / 2;
|
||||
STORE;
|
||||
}
|
||||
|
||||
// bottom left pixel
|
||||
r = UPRI;
|
||||
g = (UP + RI) / 2;
|
||||
b = CE;
|
||||
STORE;
|
||||
|
||||
// last line starting with GG BB GG ...
|
||||
for (xs = 1; xs < src_w - 1; xs+=2) {
|
||||
// green pixel
|
||||
r = UP;
|
||||
g = CE;
|
||||
b = (LE + RI) / 2;
|
||||
STORE;
|
||||
// blue pixel
|
||||
r = (UPLE + UPRI) / 2;
|
||||
g = (LE + UP + RI) / 2;
|
||||
b = CE;
|
||||
STORE;
|
||||
}
|
||||
|
||||
// bottom right pixel (green)
|
||||
r = UP;
|
||||
g = CE;
|
||||
b = LE;
|
||||
STORE;
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
#ifndef _DEBAYER_H_
|
||||
#define _DEBAYER_H_
|
||||
|
||||
void debayer_grbg16_simple (uint16_t * src, int src_w, int src_h,
|
||||
uint8_t * dst, int dst_w, int dst_h);
|
||||
|
||||
void debayer_grbg16_bilinear (uint16_t * src, int src_w, int src_h,
|
||||
uint8_t * dst, int dst_w, int dst_h);
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in new issue