2011년 6월 21일 화요일

Convert Bayer with BGRG pattern to RGB24

********************************** 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
*/
}

댓글 없음:

댓글 쓰기