********************************** bayer.h *************************************
/* bayer2rgb
Copyright 2011 Hoyoung Yi.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, please visit www.gnu.org.
*/
#ifndef __BAYER_H__
#define __BAYER_H__
#ifdef __cplusplus
extern "C" {
#endif
/*
typedef enum {
BAYER_BGGR,
BAYER_GBRG,
BAYER_GRBG
} bayer_t;
void bayer2rgb24(unsigned char *rgb, unsigned char *bayer, int sx, int sy, bayer_t tile);
*/
void bayer2rgb24(unsigned char *rgb, unsigned char *bayer, int width, int height);
#ifdef __cplusplus
}
#endif
#endif /* __BAYER_H__ */
********************************** bayer.c *************************************
/* bayer2rgb
Copyright 2011 Hoyoung Yi.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, please visit www.gnu.org.
*/
#include "bayer.h"
// BGRG pattern
void bayer2rgb24(unsigned char *rgb, unsigned char *raw, int width, int height)
{
int i, j;
int raw_pitch = 2*width;
int rgb_pitch = 3*width;
#undef RED
#define RED(x, y) rgb[(y)*rgb_pitch+(x)*3+2]
#undef GREEN
#define GREEN(x, y) rgb[(y)*rgb_pitch+(x)*3+1]
#undef BLUE
#define BLUE(x, y) rgb[(y)*rgb_pitch+(x)*3+0]
#define RAW_LOW(x, y) ((int)raw[(y)*raw_pitch+(x)*2+0])
#define RAW_HIGH(x, y) ((int)raw[(y)*raw_pitch+(x)*2+1])
for (i = 0; i < height-1; ) {
// odd line
j = 0;
BLUE(j, i) = (RAW_LOW(j, i)+RAW_LOW(j, i+1))>>1;
GREEN(j, i) = (RAW_HIGH(j, i)+RAW_HIGH(j+1, i)+RAW_HIGH(j, i+1))/3;
RED(j, i) = (RAW_LOW(j+1, i)+RAW_LOW(j+1, i+1))>>1;
/*
rgb[i*rgb_pitch+j*3+0] = ((int)raw[i*raw_pitch+j*2+0]
+(int)raw[(i+1)*raw_pitch+j*2+0]+1)>>1; // blue;
rgb[i*rgb_pitch+j*3+1] = ((int)raw[i*raw_pitch+j*2+1]+(int)raw[i*raw_pitch+(j+1)*2+1]
+(int)raw[(i+1)*raw_pitch+j*2+1]+1)/3; // green;
rgb[i*rgb_pitch+j*3+2] = ((int)raw[i*raw_pitch+(j+1)*2+0]
+(int)raw[(i+1)*raw_pitch+(j+1)*2+0]+1)>>1; // red;
*/
j++;
while (j < width-1) {
BLUE(j, i) = (RAW_LOW(j-1, i)+RAW_LOW(j+1, i))>>1;
GREEN(j, i) = (RAW_HIGH(j, i)+RAW_HIGH(j, i+1))>>1;
RED(j, i) = (RAW_LOW(j, i)+RAW_LOW(j, i+1))>>1;
/*
rgb[i*rgb_pitch+j*3+0] = ((int)raw[i*raw_pitch+(j-1)*2+0]+(int)raw[i*raw_pitch+(j+1)*2+0]+1)>>1; // blue;
rgb[i*rgb_pitch+j*3+1] = ((int)raw[i*raw_pitch+j*2+1]
+(int)raw[(i+1)*raw_pitch+j*2+1]+1)>>1; // green
rgb[i*rgb_pitch+j*3+2] = ((int)raw[i*raw_pitch+j*2+0]
+(int)raw[(i+1)*raw_pitch+j*2+0]+1)>>1; // red
*/
j++;
BLUE(j, i) = (RAW_LOW(j, i)+RAW_LOW(j, i+1))>>1;
GREEN(j, i) = (RAW_HIGH(j-1, i)+RAW_HIGH(j, i)+RAW_HIGH(j+1, i)+RAW_HIGH(j, i+1))>>2;
RED(j, i) = (RAW_LOW(j-1, i)+RAW_LOW(j+1, i)+RAW_LOW(j-1, i+1)+RAW_LOW(j+1, i+1))>>2;
/*
rgb[i*rgb_pitch+j*3+0] = ((int)raw[i*raw_pitch+j*2+0]
+(int)raw[(i+1)*raw_pitch+j*2+0]+1)>>1; // blue;
rgb[i*rgb_pitch+j*3+1] = ((int)raw[i*raw_pitch+(j-1)*2+1]+(int)raw[i*raw_pitch+j*2+1]+(int)raw[i*raw_pitch+(j+1)*2+1]
+(int)raw[(i+1)*raw_pitch+j*2+1]+1)>>2; // green
rgb[i*rgb_pitch+j*3+2] = ((int)raw[i*raw_pitch+(j-1)*2+0]+(int)raw[i*raw_pitch+(j+1)*2+0]
+(int)raw[(i+1)*raw_pitch+(j-1)*2+0]+(int)raw[(i+1)*raw_pitch+(j+1)*2+0]+1)>>2; // red
*/
j++;
}
BLUE(j, i) = RAW_LOW(j-1, i);
GREEN(j, i) = (RAW_HIGH(j, i)+RAW_HIGH(j, i+1))>>1;
RED(j, i) = (RAW_LOW(j, i)+RAW_LOW(j, i+1))>>1;
/*
rgb[i*rgb_pitchj*3+0] = raw[i*raw_pitch+(j-1)*2+0]; // blue;
rgb[i*rgb_pitchj*3+1] = ((int)raw[i*raw_pitch+j*2+1]
+(int)raw[(i+1)*raw_pitch+j*2+1]+1)>>1; // green
rgb[i*rgb_pitchj*3+2] = ((int)raw[i*raw_pitch+j*2+0]
+(int)raw[(i+1)*raw_pitch+j*2+0]+1)>>1; // red
*/
i++;
// even line
j = 0;
BLUE(j, i) = (RAW_LOW(j, i)+RAW_LOW(j, i+1))>>1;
GREEN(j, i) = (RAW_HIGH(j, i)+RAW_HIGH(j, i+1))>>1;
RED(j, i) = RAW_LOW(j+1, i);
/*
rgb[i*rgb_pitch+j*3+0] = ((int)raw[i*raw_pitch+j*2+0]
+(int)raw[(i+1)*raw_pitch+j*2+0]+1)>>1; // blue
rgb[i*rgb_pitch+j*3+1] = ((int)raw[i*raw_pitch+j*2+1]
+(int)raw[(i+1)*raw_pitch+j*2+1]+1)>>1; // green
rgb[i*rgb_pitch+j*3+2] = raw[i*raw_pitch+(j+1)*2+0]; // red
*/
j++;
while (j < width-1) {
BLUE(j, i) = (RAW_LOW(j-1, i)+RAW_LOW(j+1, i)+RAW_LOW(j-1, i+1)+RAW_LOW(j+1, i+1))>>2;
GREEN(j, i) = (RAW_HIGH(j-1, i)+RAW_HIGH(j, i)+RAW_HIGH(j+1, i)+RAW_HIGH(j, i+1))>>2;
RED(j, i) = (RAW_LOW(j, i)+RAW_LOW(j, i+1))>>1;
/*
rgb[i*rgb_pitch+j*3+0] = ((int)raw[i*raw_pitch+(j-1)*2+0]+(int)raw[i*raw_pitch+(j+1)*2+0]
+(int)raw[(i+1)*raw_pitch+(j-1)*2+0]+(int)raw[(i+1)*raw_pitch+(j+1)*2+0]+1)>>2; // blue
rgb[i*rgb_pitch+j*3+1] = ((int)raw[i*raw_pitch+(j-1)*2+1]+(int)raw[i*raw_pitch+j*2+1]+(int)raw[i*raw_pitch+(j+1)*2+1]
+(int)raw[(i+1)*raw_pitch+j*2+1]+1)>>2; // green
rgb[i*rgb_pitch+j*3+2] = ((int)raw[i*raw_pitch+j*2+0]
+(int)raw[(i+1)*raw_pitch+j*2+0]+1)>>1; // red
*/
j++;
BLUE(j, i) = (RAW_LOW(j, i)+RAW_LOW(j, i+1))>>1;
GREEN(j, i) = (RAW_HIGH(j, i)+RAW_HIGH(j, i+1))>>1;
RED(j, i) = (RAW_LOW(j-1, i)+RAW_LOW(j+1, i))>>1;
/*
rgb[i*rgb_pitch+j*3+0] = ((int)raw[i*raw_pitch+j*2+0]
+(int)raw[(i+1)*raw_pitch+j*2+0]+1)>>1; // blue
rgb[i*rgb_pitch+j*3+1] = ((int)raw[i*raw_pitch+j*2+1]
+(int)raw[(i+1)*raw_pitch+j*2+1]+1)>>1; // green
rgb[i*rgb_pitch+j*3+2] = ((int)raw[i*raw_pitch+(j-1)*2+0]+(int)raw[i*raw_pitch+(j+1)*2+0]+1)>>1; // red
*/
j++;
}
BLUE(j, i) = (RAW_LOW(j-1, i)+RAW_LOW(j-1, i+1))>>1;
GREEN(j, i) = (RAW_HIGH(j-1, i)+RAW_HIGH(j, i)+RAW_HIGH(j, i+1))/3;
RED(j, i) = (RAW_LOW(j, i)+RAW_LOW(j, i+1))>>1;
/*
rgb[i*rgb_pitch+j*3+0] = ((int)raw[i*raw_pitch+(j-1)*2+0]
+(int)raw[(i+1)*raw_pitch+(j-1)*2+0]+1)>>1; // blue
rgb[i*rgb_pitch+j*3+1] = ((int)raw[i*raw_pitch+(j-1)*2+1]+(int)raw[i*raw_pitch+j*2+1]
+(int)raw[(i+1)*raw_pitch+j*2+1]+1)/3; // green
rgb[i*rgb_pitch+j*3+2] = ((int)raw[i*raw_pitch+j*2+0]
+(int)raw[(i+1)*raw_pitch+j*2+0]+1)>>1; // red
*/
i++;
// third line
j = 0;
BLUE(j, i) = (RAW_LOW(j, i)+RAW_LOW(j, i+1))>>1;
GREEN(j, i) = (RAW_HIGH(j, i)+RAW_HIGH(j+1, i)+RAW_HIGH(j, i+1))/3;
RED(j, i) = (RAW_LOW(j+1, i)+RAW_LOW(j+1, i+1))>>1;
/*
rgb[i*rgb_pitch+j*3+0] = ((int)raw[i*raw_pitch+j*2+0]
+(int)raw[(i+1)*raw_pitch+j*2+0]+1)>>1; // blue;
rgb[i*rgb_pitch+j*3+1] = ((int)raw[i*raw_pitch+j*2+1]+(int)raw[i*raw_pitch+(j+1)*2+1]
+(int)raw[(i+1)*raw_pitch+j*2+1]+1)/3; // green;
rgb[i*rgb_pitch+j*3+2] = ((int)raw[i*raw_pitch+(j+1)*2+0]
+(int)raw[(i+1)*raw_pitch+(j+1)*2+0]+1)>>1; // red;
*/
j++;
while (j < width-1) {
BLUE(j, i) = (RAW_LOW(j-1, i)+RAW_LOW(j+1, i))>>1;
GREEN(j, i) = (RAW_HIGH(j, i)+RAW_HIGH(j, i+1))>>1;
RED(j, i) = (RAW_LOW(j, i)+RAW_LOW(j, i+1))>>1;
/*
rgb[i*rgb_pitch+j*3+0] = ((int)raw[i*raw_pitch+(j-1)*2+0]+(int)raw[i*raw_pitch+(j+1)*2+0]+1)>>1; // blue;
rgb[i*rgb_pitch+j*3+1] = ((int)raw[i*raw_pitch+j*2+1]
+(int)raw[(i+1)*raw_pitch+j*2+1]+1)>>1; // green
rgb[i*rgb_pitch+j*3+2] = ((int)raw[i*raw_pitch+j*2+0]
+(int)raw[(i+1)*raw_pitch+j*2+0]+1)>>1; // red
*/
j++;
BLUE(j, i) = (RAW_LOW(j, i)+RAW_LOW(j, i+1))>>1;
GREEN(j, i) = (RAW_HIGH(j-1, i)+RAW_HIGH(j, i)+RAW_HIGH(j+1, i)+RAW_HIGH(j, i+1))>>2;
RED(j, i) = (RAW_LOW(j-1, i)+RAW_LOW(j+1, i)+RAW_LOW(j-1, i+1)+RAW_LOW(j+1, i+1))>>2;
/*
rgb[i*rgb_pitch+j*3+0] = ((int)raw[i*raw_pitch+j*2+0]
+(int)raw[(i+1)*raw_pitch+j*2+0]+1)>>1; // blue;
rgb[i*rgb_pitch+j*3+1] = ((int)raw[i*raw_pitch+(j-1)*2+1]+(int)raw[i*raw_pitch+j*2+1]+(int)raw[i*raw_pitch+(j+1)*2+1]
+(int)raw[(i+1)*raw_pitch+j*2+1]+1)>>2; // green
rgb[i*rgb_pitch+j*3+2] = ((int)raw[i*raw_pitch+(j-1)*2+0]+(int)raw[i*raw_pitch+(j+1)*2+0]
+(int)raw[(i+1)*raw_pitch+(j-1)*2+0]+(int)raw[(i+1)*raw_pitch+(j+1)*2+0]+1)>>2; // red
*/
j++;
}
BLUE(j, i) = RAW_LOW(j-1, i);
GREEN(j, i) = (RAW_HIGH(j, i)+RAW_HIGH(j, i+1))>>1;
RED(j, i) = (RAW_LOW(j, i)+RAW_LOW(j, i+1))>>1;
/*
rgb[i*rgb_pitchj*3+0] = raw[i*raw_pitch+(j-1)*2+0]; // blue;
rgb[i*rgb_pitchj*3+1] = ((int)raw[i*raw_pitch+j*2+1]
+(int)raw[(i+1)*raw_pitch+j*2+1]+1)>>1; // green
rgb[i*rgb_pitchj*3+2] = ((int)raw[i*raw_pitch+j*2+0]
+(int)raw[(i+1)*raw_pitch+j*2+0]+1)>>1; // red
*/
i++;
}
j = 0;
BLUE(j, i) = RAW_LOW(j, i);
GREEN(j, i) = RAW_HIGH(j, i);
RED(j, i) = RAW_LOW(j+1, i);
/*
rgb[i*rgb_pitch+j*3+0] = raw[i*raw_pitch+j*2+0]; // blue
rgb[i*rgb_pitch+j*3+1] = raw[i*raw_pitch+j*2+1]; // green
rgb[i*rgb_pitch+j*3+2] = raw[i*raw_pitch+(j+1)*2+0]; // red
*/
j++;
while (j < width-1) {
BLUE(j, i) = (RAW_LOW(j-1, i)+RAW_LOW(j+1, i))>>1;
GREEN(j, i) = (RAW_HIGH(j-1, i)+RAW_HIGH(j, i)+RAW_HIGH(j+1, i))/3;
RED(j, i) = RAW_LOW(j, i);
/*
rgb[i*rgb_pitch+j*3+0] = ((int)raw[i*raw_pitch+(j-1)*2+0]+(int)raw[i*raw_pitch+(j+1)*2+0]+1)>>1; // blue
rgb[i*rgb_pitch+j*3+1] = ((int)raw[i*raw_pitch+(j-1)*2+1]+(int)raw[i*raw_pitch+j*2+1]+(int)raw[i*raw_pitch+(j+1)*2+1]+1)/3; // green
rgb[i*rgb_pitch+j*3+2] = raw[i*raw_pitch+j*2+0]; // red
*/
j++;
BLUE(j, i) = RAW_LOW(j, i);
GREEN(j, i) = RAW_HIGH(j, i);
RED(j, i) = (RAW_LOW(j-1, i)+RAW_LOW(j+1, i))>>1;
/*
rgb[i*rgb_pitch+j*3+0] = raw[i*raw_pitch+j*2+0]; // blue
rgb[i*rgb_pitch+j*3+1] = raw[i*raw_pitch+j*2+1]; // green
rgb[i*rgb_pitch+j*3+2] = ((int)raw[i*raw_pitch+(j-1)*2+0]+(int)raw[i*raw_pitch+(j+1)*2+0]+1)>>1; // red
*/
j++;
}
BLUE(j, i) = RAW_LOW(j-1, i);
GREEN(j, i) = (RAW_HIGH(j-1, i)+RAW_HIGH(j, i))>>1;
RED(j, i) = RAW_LOW(j, i);
/*
rgb[i*rgb_pitch+j*3+0] = raw[i*raw_pitch+(j-1)*2+0]; // blue
rgb[i*rgb_pitch+j*3+1] = ((int)raw[i*raw_pitch+(j-1)*2+1]+(int)raw[i*raw_pitch+j*2+1]+1)>>1; // green
rgb[i*rgb_pitch+j*3+2] = raw[i*raw_pitch+j*2+0]; // red
*/
}
댓글 없음:
댓글 쓰기