/* Camicro - Microscope camera viewer. * * Copyright (C) 2019 Nicolas Schodet * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Contact : * Web: http://ni.fr.eu.org/ * Email: */ #include "image.h" #include void image_bayer2argb(const uint8_t *bayer, uint32_t *rgb, int width, int height, int stride) { /* * Compute missing value using an average of its neighbours. * Input pattern: * G R G R G R * B G B G B G * G R G R G R * B G B G B G */ const int in_stride = width; const int out_stride = stride; /* Skip first line and column. */ const uint8_t *in = bayer + in_stride + 1; uint8_t *out = (uint8_t *) rgb + out_stride + 4; /* Loop over lines. */ for (int i = 1; i < height - 1; i += 2) { /* Even lines. */ const uint8_t *in_stop = in + (width - 2); while (in != in_stop) { *out++ = (in[-1] + in[+1] + 1) >> 1; /* B */ *out++ = in[0]; /* G */ *out++ = (in[-in_stride] + in[+in_stride] + 1) >> 1; /* R */ *out++ = 255; /* A */ in++; *out++ = in[0]; /* B */ *out++ = (in[-in_stride] + in[+in_stride] /* G */ + in[-1] + in[+1] + 2) >> 2; *out++ = (in[-in_stride - 1] + in[-in_stride + 1] /* R */ + in[+in_stride - 1] + in[+in_stride + 1] + 2) >> 2; *out++ = 255; /* A */ in++; } /* Fill first and last pixels. */ out[-(width - 1) * 4 + 0] = out[-(width - 2) * 4 + 0]; out[-(width - 1) * 4 + 1] = out[-(width - 2) * 4 + 1]; out[-(width - 1) * 4 + 2] = out[-(width - 2) * 4 + 2]; out[-(width - 1) * 4 + 3] = out[-(width - 2) * 4 + 3]; out[0] = out[-4]; out[1] = out[-3]; out[2] = out[-2]; out[3] = out[-1]; out += out_stride - (width - 2) * 4; in += in_stride - (width - 2); /* Odd lines. */ in_stop = in + (width - 2); while (in != in_stop) { *out++ = (in[-in_stride - 1] + in[-in_stride + 1] /* B */ + in[+in_stride - 1] + in[+in_stride + 1] + 2) >> 2; *out++ = (in[-in_stride] + in[+in_stride] /* G */ + in[-1] + in[+1] + 2) >> 2; *out++ = in[0]; /* R */ *out++ = 255; /* A */ in++; *out++ = (in[-in_stride] + in[+in_stride] + 1) >> 1; /* B */ *out++ = in[0]; /* G */ *out++ = (in[-1] + in[+1] + 1) >> 1; /* R */ *out++ = 255; /* A */ in++; } /* Fill first and last pixels. */ out[-(width - 1) * 4 + 0] = out[-(width - 2) * 4 + 0]; out[-(width - 1) * 4 + 1] = out[-(width - 2) * 4 + 1]; out[-(width - 1) * 4 + 2] = out[-(width - 2) * 4 + 2]; out[-(width - 1) * 4 + 3] = out[-(width - 2) * 4 + 3]; out[0] = out[-4]; out[1] = out[-3]; out[2] = out[-2]; out[3] = out[-1]; out += out_stride - (width - 2) * 4; in += in_stride - (width - 2); } /* Last line. */ out -= 4; memcpy(out, out - out_stride, width * 4); /* First line. */ out -= (height - 1) * out_stride; memcpy(out, out + out_stride, width * 4); }