aboutsummaryrefslogtreecommitdiffstats
path: root/debayer.c
diff options
context:
space:
mode:
authorPatrick Roth <roth@stettbacher.ch>2019-10-04 11:51:48 +0200
committerPatrick Roth <roth@stettbacher.ch>2019-10-04 11:51:48 +0200
commita0f501fa5650d0b6062cc8f26b34bce11137643d (patch)
tree8e31c5ac3409d4ce48887d88d4530b88a02c2660 /debayer.c
downloado3000-color-pipe-a0f501fa5650d0b6062cc8f26b34bce11137643d.tar.gz
o3000-color-pipe-a0f501fa5650d0b6062cc8f26b34bce11137643d.zip
initial commit
import from github
Diffstat (limited to 'debayer.c')
-rw-r--r--debayer.c243
1 files changed, 243 insertions, 0 deletions
diff --git a/debayer.c b/debayer.c
new file mode 100644
index 0000000..1733496
--- /dev/null
+++ b/debayer.c
@@ -0,0 +1,243 @@
+/**
+* @file debayer.c
+* @brief demosaicing algorithms
+* @author Patrick Roth - roth@stettbacher.ch
+* @version 1.0
+* @date 2015-08-20
+* @copyright 2012-2016 Stettbacher Signal Processing AG
+*
+* @remarks
+*
+* <PRE>
+* This library 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.1 of the License, or (at your option) any later version.
+*
+* This library 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 library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+* </PRE>
+*
+*/
+
+#include <stdio.h>
+#include "color_pipe_private.h"
+
+
+/**
+ * Return bayer pattern type of next line.
+ *
+ * @param pattern current pattern type
+ * @param offset_height height offset in number of lines
+ * @param offset_width width offset in numbers of rows
+ * @return pattern type of next line
+ */
+static inline enum enumBayerPattern_t getBayerType(enum enumBayerPattern_t pattern, int offset_height, int offset_width) {
+
+ int offset_y = offset_height%2;
+ int offset_x = offset_width%2;
+
+ if(offset_y == 0 && offset_x == 0) {
+ // do nothing
+ }
+ else if(offset_y == 0 && offset_x == 1) {
+ if(pattern == BP_GR) {
+ pattern = BP_RG;
+ }
+ else if(pattern == BP_RG) {
+ pattern = BP_GR;
+ }
+ else if(pattern == BP_BG) {
+ pattern = BP_GB;
+ }
+ else if(pattern == BP_GB) {
+ pattern = BP_BG;
+ }
+ }
+ else if(offset_y == 1 && offset_x == 0) {
+ if(pattern == BP_GR) {
+ pattern = BP_BG;
+ }
+ else if(pattern == BP_RG) {
+ pattern = BP_GB;
+ }
+ else if(pattern == BP_BG) {
+ pattern = BP_GR;
+ }
+ else if(pattern == BP_GB) {
+ pattern = BP_RG;
+ }
+ }
+ else if(offset_y == 1 && offset_x == 1) {
+ if(pattern == BP_GR) {
+ pattern = BP_GB;
+ }
+ else if(pattern == BP_RG) {
+ pattern = BP_BG;
+ }
+ else if(pattern == BP_BG) {
+ pattern = BP_RG;
+ }
+ else if(pattern == BP_GB) {
+ pattern = BP_GR;
+ }
+ }
+ return pattern;
+}
+
+
+/**
+ * Calculate RGB value depening on 9 pixel value from bayer pattern.
+ *
+ * @param p11 upper left pixel
+ * @param p12 upper center pixel
+ * @param p13 upper right pixel
+ * @param p21 center left pixel
+ * @param p22 center center pixel
+ * @param p23 center right pixel
+ * @param p31 lower left pixel
+ * @param p32 lower center pixel
+ * @param p33 lower right pixel
+ * @param pattern current bayer pattern type, this value is adjusted to next expected type after return
+ * @param red On return: red pixel value
+ * @param green On return: green pixel value
+ * @param blue On return: blue pixel value
+ */
+static inline void calc_bilinear(int p11, int p12, int p13,
+ int p21, int p22, int p23,
+ int p31, int p32, int p33,
+ enum enumBayerPattern_t *pattern,
+ int *red, int *green, int *blue) {
+
+ switch(*pattern) {
+ case BP_GR: // green-red-green-red-...
+ *red = (p21 + p23) >> 1;
+ *green = (p11 + p13 + p22*4 + p31 + p33) >> 3;
+ *blue = (p12 + p32) >> 1;
+ *pattern = BP_RG;
+ break;
+
+ case BP_RG: // red-green-red-green-...
+ *red = p22;
+ *green = (p12 + p21 + p23 + p32) >> 2;
+ *blue = (p11 + p13 + p31 + p33) >> 2;
+ *pattern = BP_GR;
+ break;
+
+ case BP_BG: // blue-green-blue-green-...
+ *red = (p11 + p13 + p31 + p33) >> 2;
+ *green = (p12 + p21 + p23 + p32) >> 2;
+ *blue = p22;
+ *pattern = BP_GB;
+ break;
+
+ case BP_GB: // green-blue-green-blue-...
+ *red = (p12 + p32) >> 1;
+ *green = (p11 + p13 + p22*4 + p31 + p33) >> 3;
+ *blue = (p21 + p23) >> 1;
+ *pattern = BP_BG;
+ break;
+ }
+}
+
+
+/**
+ * Bilinear demosaicing algorithm for RGB image (16 bit per color channel).
+ *
+ * @param img_rgb On return: RGB image in R-G-B order
+ * @param img_bayer bayer image
+ * @param height image height in number of pixels
+ * @param width image width in number of pixels
+ * @param bayer_pattern first pixel starts with this pixel
+ * @return 0 on success otherwise -1
+ */
+static void bilinear16(uint16_t *img_rgb, const uint16_t *img_bayer, const int height, const int width, const enum enumBayerPattern_t bayer_pattern)
+#include "alg_debayer_bilinear.h"
+
+
+/**
+ * Bilinear demosaicing algorithm for RGB image (8 bit per color channel).
+ *
+ * @param img_rgb On return: RGB image in R-G-B order
+ * @param img_bayer bayer image
+ * @param height image height in number of pixels
+ * @param width image width in number of pixels
+ * @param bayer_pattern first pixel starts with this pixel
+ * @return 0 on success otherwise -1
+ */
+static void bilinear8(uint8_t *img_rgb, const uint8_t *img_bayer, const int height, const int width, const enum enumBayerPattern_t bayer_pattern)
+#include "alg_debayer_bilinear.h"
+
+
+/**
+ * Bilinear demosaicing wrapper function used to select pixel-bit-depth dependet algrotihm.
+ *
+ * @param img_rgb On return: RGB image in R-G-B order
+ * @param img_bayer bayer image
+ * @param height image height in number of pixels
+ * @param width image width in number of pixels
+ * @param data_format image data format
+ * @param bayer_pattern first pixel starts with this pixel
+ * @return 0 on success otherwise -1
+ */
+static int bilinear_wrapper(void *img_rgb, const void *img_bayer, const int height, const int width,
+ const enum enumDataFormat_t data_format, const enum enumBayerPattern_t bayer_pattern) {
+ if(data_format == DF_RAW_BAYER_8) {
+ bilinear8(img_rgb, img_bayer, height, width, bayer_pattern);
+ }
+ else if(data_format == DF_RAW_BAYER_12 || data_format == DF_HDR_BAYER_20_COMP) {
+ bilinear16(img_rgb, img_bayer, height, width, bayer_pattern);
+ }
+ else {
+ printf("%s: image data format %d unknown\n", __func__, data_format);
+ return -1;
+ }
+ return 0;
+}
+
+
+/**
+ * Bayer to RGB image conversion algrithm (demosaicing)
+ *
+ * @param debayer_data required data for debayering
+ * @return 0 on success otherwise -1
+ */
+int debayer(struct debayer_data_t *debayer_data) {
+
+ void *img_rgb, *img_raw;
+ int ret, height, width;
+ enum enumDataFormat_t data_format;
+ enum enumBayerPattern_t bayer_pattern;
+ enum bayer_alg_t alg;
+
+ ret = 0;
+ img_rgb = debayer_data->img_rgb;
+ img_raw = debayer_data->img_raw;
+ height = debayer_data->height;
+ width = debayer_data->width;
+ data_format = debayer_data->format;
+ bayer_pattern = debayer_data->start_pattern;
+ alg = debayer_data->alg;
+
+ if(data_format == DF_RAW_MONO_8 || data_format == DF_RAW_MONO_12 || data_format == DF_HDR_MONO_20_COMP) {
+ printf("%s: No debayering is done on monochrome image (image data format %d)\n", __func__, data_format);
+ return -1;
+ }
+
+ switch(alg) {
+ case BAYER_ALG_BILINEAR:
+ ret = bilinear_wrapper(img_rgb, img_raw, height, width, data_format, bayer_pattern);
+ break;
+
+ default:
+ printf("%s: Debayer algorithm %d not implemented yet\n", __func__, alg);
+ ret = -1;
+ }
+ return ret;
+} \ No newline at end of file