53 #define MAX(x,y) ((x < y) ? (y) : (x))
54 #define MIN(x,y) ((x > y) ? (y) : (x))
55 #define CLAMP(x) MAX(MIN(x,0xff),0)
61 int dRGB(
int i1,
int i2,
unsigned char *RGB);
63 int do_rb_ctr_row(
unsigned char *image_h,
unsigned char *image_v,
int w,
64 int h,
int y,
int *pos_code);
67 unsigned char *image_v,
int w,
int h,
int y,
int *pos_code);
69 int get_diffs_row2(
unsigned char * hom_buffer_h,
unsigned char *hom_buffer_v,
70 unsigned char * buffer_h,
unsigned char *buffer_v,
int w);
72 #define AD(x, y, w) ((y)*(w)*3+3*(x))
80 int dRGB(
int i1,
int i2,
unsigned char *RGB) {
82 dR=RGB[i1+
RED]-RGB[i2+
RED];
85 return dR*dR+dG*dG+dB*dB;
97 int do_rb_ctr_row(
unsigned char *image_h,
unsigned char *image_v,
int w,
98 int h,
int y,
int *pos_code)
101 int value,value2,div,color;
119 for (x = 0; x < w; x++)
121 bayer = (x&1?0:1) + (y&1?0:2);
122 for (color=0; color < 3; color+=2) {
123 if ((color==
RED && bayer == pos_code[3])
125 && bayer == pos_code[0])) {
127 if (x > 0 && y > 0) {
128 value += image_h[
AD(x-1,0,w)+color]
130 value2+= image_v[
AD(x-1,0,w)+color]
134 if (x > 0 && y < h-1) {
135 value += image_h[
AD(x-1,2,w)+color]
137 value2+= image_v[
AD(x-1,2,w)+color]
141 if (x < w-1 && y > 0) {
142 value += image_h[
AD(x+1,0,w)+color]
144 value2+= image_v[
AD(x+1,0,w)+color]
148 if (x < w-1 && y < h-1) {
149 value += image_h[
AD(x+1,2,w)+color]
151 value2+= image_v[
AD(x+1,2,w)+color]
155 image_h[
AD(x,1,w)+color]=
159 image_v[
AD(x,1,w)+color]=
162 }
else if ((color==
RED && bayer == pos_code[2])
164 && bayer == pos_code[1])) {
167 value += image_h[
AD(x,0,w)+color]
169 value2+= image_v[
AD(x,0,w)+color]
174 value += image_h[
AD(x,2,w)+color]
176 value2+= image_v[
AD(x,2,w)+color]
180 image_h[
AD(x,1,w)+color]=
184 image_v[
AD(x,1,w)+color]=
188 }
else if ((color==
RED && bayer == pos_code[1])
190 && bayer == pos_code[2])) {
193 value += image_h[
AD(x-1,1,w)+color]
195 value2+= image_v[
AD(x-1,1,w)+color]
200 value += image_h[
AD(x+1,1,w)+color]
202 value2+= image_v[
AD(x+1,1,w)+color]
206 image_h[
AD(x,1,w)+color]=
210 image_v[
AD(x,1,w)+color]=
234 unsigned char *image_v,
int w,
int h,
int y,
int *pos_code)
244 for (x = 0; x < w; x++) {
245 bayer = (x&1?0:1) + (y&1?0:2);
248 if ( bayer == pos_code[0] || bayer == pos_code[3]) {
250 if (bayer==pos_code[0])
251 value += 2*image[
AD(x,y,w)+
RED];
253 value += 2*image[
AD(x,y,w)+
BLUE];
256 value += 2*image[
AD(x+1,y,w)+
GREEN];
260 if (bayer==pos_code[0])
261 value -= image[
AD(x+2,y,w)+
RED];
263 value -= image[
AD(x+2,y,w)+
BLUE];
267 value += 2*image[
AD(x-1,y,w)+
GREEN];
271 if (bayer==pos_code[0])
272 value -= image[
AD(x-2,y,w)+
RED];
274 value -= image[
AD(x-2,y,w)+
BLUE];
283 if (bayer==pos_code[0])
284 value += 2*image[
AD(x,y,w)+
RED];
286 value += 2*image[
AD(x,y,w)+
BLUE];
289 value += 2*image[
AD(x,y+1,w)+
GREEN];
293 if (bayer==pos_code[0])
294 value -= image[
AD(x,y+2,w)+
RED];
296 value -= image[
AD(x,y+2,w)+
BLUE];
300 value += 2*image[
AD(x,y-1,w)+
GREEN];
304 if (bayer==pos_code[0])
305 value -= image[
AD(x,y-2,w)+
RED];
307 value -= image[
AD(x,y-2,w)+
BLUE];
328 unsigned char * buffer_h,
unsigned char *buffer_v,
int w)
332 unsigned char Usize_h, Usize_v;
334 for (j = 1; j < w-1; j++) {
359 if (
dRGB(i,i-3,buffer_h) <= RGBeps)
361 if (
dRGB(i,i-3,buffer_v) <= RGBeps)
363 if (
dRGB(i,i+3,buffer_h) <= RGBeps)
365 if (
dRGB(i,i+3,buffer_v) <= RGBeps)
367 if (
dRGB(i,i-3*w,buffer_h)<= RGBeps)
369 if (
dRGB(i,i-3*w,buffer_v) <= RGBeps)
371 if (
dRGB(i,i+3*w,buffer_h) <= RGBeps)
373 if (
dRGB(i,i+3*w,buffer_v) <= RGBeps)
375 hom_buffer_h[j+2*w]=Usize_h;
376 hom_buffer_v[j+2*w]=Usize_v;
423 unsigned char *window_h, *window_v, *cur_window_h, *cur_window_v;
424 unsigned char *homo_h, *homo_v;
425 unsigned char *homo_ch, *homo_cv;
427 window_h = calloc (w * 18, 1);
428 window_v = calloc (w * 18, 1);
429 homo_h = calloc (w*3, 1);
430 homo_v = calloc (w*3, 1);
431 homo_ch = calloc (w, 1);
432 homo_cv = calloc (w, 1);
433 if (!window_h || !window_v || !homo_h || !homo_v || !homo_ch || !homo_cv) {
440 GP_LOG_E (
"Out of memory");
447 p[0] = 0; p[1] = 1; p[2] = 2; p[3] = 3;
451 p[0] = 1; p[1] = 0; p[2] = 3; p[3] = 2;
455 p[0] = 3; p[1] = 2; p[2] = 1; p[3] = 0;
459 p[0] = 2; p[1] = 3; p[2] = 0; p[3] = 1;
500 cur_window_h = window_h+9*w;
501 cur_window_v = window_v+9*w;
506 memcpy (window_h+12*w, image, 6*w);
507 memcpy (window_v+12*w, image, 6*w);
525 memmove(window_h, window_h+3*w,15*w);
526 memmove(window_v, window_v+3*w,15*w);
527 memcpy (window_h+15*w, image+6*w, 3*w);
528 memcpy (window_v+15*w, image+6*w, 3*w);
537 memmove (window_h, window_h+3*w, 15*w);
538 memmove(window_v, window_v+3*w,15*w);
549 for (y = 0; y < h; y++) {
551 memcpy (window_v+15*w,image+3*y*w+9*w, 3*w);
552 memcpy (window_h+15*w,image+3*y*w+9*w, 3*w);
554 memset(window_v+15*w, 0, 3*w);
555 memset(window_h+15*w, 0, 3*w);
559 cur_window_v+3*w, w, h, y+3, p);
572 memset(homo_ch, 0, w);
573 memset(homo_cv, 0, w);
580 for (x=0; x < w; x++) {
581 for (i=-1; i < 2;i++) {
582 for (k=0; k < 3;k++) {
584 if ((j >= 0) && ( j < w*3)) {
585 homo_ch[x]+=homo_h[j];
586 homo_cv[x]+=homo_v[j];
590 for (color=0; color < 3; color++) {
591 if (homo_ch[x] > homo_cv[x])
592 image[3*y*w+3*x+color]
593 = window_h[3*x+6*w+color];
594 else if (homo_ch[x] < homo_cv[x])
595 image[3*y*w+3*x+color]
596 = window_v[3*x+6*w+color];
598 image[3*y*w+3*x+color]
599 = (window_v[3*x+6*w+color]+
600 window_h[3*x+6*w+color])/2;
604 memmove(window_v, window_v+3*w, 15*w);
605 memmove(window_h, window_h+3*w, 15*w);
606 memmove (homo_h,homo_h+w,2*w);
607 memmove (homo_v,homo_v+w,2*w);
int gp_ahd_decode(unsigned char *input, int w, int h, unsigned char *output, BayerTile tile)
Convert a bayer raster style image to a RGB raster.
static int dRGB(int i1, int i2, unsigned char *RGB)
This function computes distance^2 between two sets of pixel data.
static int get_diffs_row2(unsigned char *hom_buffer_h, unsigned char *hom_buffer_v, unsigned char *buffer_h, unsigned char *buffer_v, int w)
Differences are assigned scores across row 2 of buffer_v, buffer_h.
static int do_rb_ctr_row(unsigned char *image_h, unsigned char *image_v, int w, int h, int y, int *pos_code)
Missing reds and/or blues are reconstructed on a single row.
int gp_ahd_interpolate(unsigned char *image, int w, int h, BayerTile tile)
Interpolate a expanded bayer array into an RGB image.
static int do_green_ctr_row(unsigned char *image, unsigned char *image_h, unsigned char *image_v, int w, int h, int y, int *pos_code)
Missing greens are reconstructed on a single row.
int gp_bayer_expand(unsigned char *input, int w, int h, unsigned char *output, BayerTile tile)
Expand a bayer raster style image to a RGB raster.
BayerTile
how the bayer CCD array is laid out
@ BAYER_TILE_GBRG_INTERLACED
scanline order: G1,B1,G2,B2,...,R1,G1,R2,G2,...
@ BAYER_TILE_GBRG
raster is RG,GB
@ BAYER_TILE_RGGB_INTERLACED
scanline order: R1,G1,R2,G2,...,G1,B1,G2,B2,...
@ BAYER_TILE_BGGR_INTERLACED
scanline order: B1,G1,R2,G2,...,G1,R1,G2,R2,...
@ BAYER_TILE_BGGR
raster is BG,GR
@ BAYER_TILE_RGGB
raster is RG,GN
@ BAYER_TILE_GRBG
raster is GR,BG
@ BAYER_TILE_GRBG_INTERLACED
scanline order: G1,R1,R2,G2,...,B1,G1,B2,G2,...
#define GP_ERROR_NO_MEMORY
Out of memory.
#define GP_OK
Everything is OK.