[vlc] Request for SBGGR8->x colorspace conversions
Luca Risolia
luca.risolia at studio.unibo.it
Mon Nov 15 05:05:32 CET 2004
Hello,
could you integrate the SBGGR8 pixel format in VLC, which is defined by
the V4L2 API (in videodev2.h)? This way I could write and test a simple v4l2
input module for webcams (and video capture devices in general) in 1 day.
The functions below that I wrote for xawtv might help. I think they are
already clear enough to be mostly copied and placed in the right place
without any problems. The code is released under GPL.
Thanks.
#define RED 0
#define GREEN 1
#define BLUE 2
#define avg2(x,y) ((((int)(x)) + ((int)(y))) / 2)
#define avg3(x,y,z) ((((int)(x)) + ((int)(y)) + ((int)(z))) / 3)
#define avg4(w,x,y,z) ((((int)(w)) + ((int)(x)) + ((int)(y)) + ((int)(z))) /
4)
/* ------------------------------------------------------------------- */
/* bayer bgbg...grgr...to rgb24 */
/*
bgbgbg
grgrgr
bgbgbg
grgrgr
*/
static void
sbggr8_to_rgb24(void *h, struct ng_video_buf *out, struct ng_video_buf *in)
{
unsigned char *restrict s, *restrict d;
unsigned long x, y, i, j;
d = out->data;
s = in->data;
x = in->fmt.width;
y = in->fmt.height;
/* upper left corner */
d[0 + RED] = s[x + 1];
d[0 + BLUE] = s[0];
d[0 + GREEN] = ((int)s[1] + (int)s[x]) / 2;
/* top line (minus corners) */
i = 1;
while (i < x - 2) {
d[i * 3 + RED] = s[x + i];
d[i * 3 + GREEN] = s[i];
d[i * 3 + BLUE] = avg2(s[i - 1], s[i + 1]);
i++;
d[i * 3 + RED] = avg2(s[x + i - 1], s[x + i + 1]);
d[i * 3 + GREEN] = avg3(s[i - 1], s[i + 1], s[x + 1]);
d[i * 3 + BLUE] = s[i];
i++;
}
/* upper right corner */
d[i * 3 + RED] = s[x + i];
d[i * 3 + GREEN] = s[i];
d[i * 3 + BLUE] = s[i - 1];
/* middle lines */
j = 1;
while (j < y - 2) {
d[j * x * 3 + RED] = s[j * x + 1];
d[j * x * 3 + GREEN] = s[j * x];
d[j * x * 3 + BLUE] = avg2(s[(j - 1) * x], s[(j + 1) * x]);
i = 1;
while (i < x - 2) {
d[(j * x + i) * 3 + RED] = s[j * x + i];
d[(j * x + i) * 3 + GREEN] = avg4(s[(j - 1) * x + i],
s[j * x + i - 1],
s[j * x + i + 1],
s[(j + 1) * x + i]);
d[(j * x + i) * 3 + BLUE] = avg4(s[(j - 1) * x + i - 1],
s[(j - 1) * x + i + 1],
s[(j + 1) * x + i - 1],
s[(j + 1) * x + i + 1]);
i++;
d[(j * x + i) * 3 + RED] = avg2(s[j * x + i - 1],
s[j * x + i + 1]);
d[(j * x + i) * 3 + GREEN] = s[j * x + i];
d[(j * x + i) * 3 + BLUE] = avg2(s[(j - 1) * x + i],
s[(j + 1) * x + i]);
i++;
}
d[(j * x + i) * 3 + RED] = s[j * x + i];
d[(j * x + i) * 3 + BLUE] = avg2(s[(j - 1) * x + i - 1],
s[(j + 1) * x + i - 1]);
d[(j * x + i) * 3 + GREEN] = avg2(s[(j - 1) * x + i],
s[(j + 1) * x + i]);
j++;
d[(j * x + i) * 3 + RED] = avg2(s[(j - 1) * x + i + 1],
s[(j + 1) * x + i + 1]);
d[(j * x + i) * 3 + BLUE] = s[j * x + i];
d[(j * x + i) * 3 + GREEN] = avg3(s[(j - 1) * x + i],
s[j * x + i + 1],
s[(j + 1) * x + i]);
i = 1;
while (i < x - 2) {
d[(j * x + i) * 3 + RED] = avg2(s[(j - 1) * x + i],
s[(j + 1) * x + i]);
d[(j * x + i) * 3 + GREEN] = s[j * x + i];
d[(j * x + i) * 3 + BLUE] = avg2(s[j * x + i - 1],
s[j * x + i + 1]);
i++;
d[(j * x + i) * 3 + RED] = avg4(s[(j - 1) * x + i - 1],
s[(j - 1) * x + i + 1],
s[(j + 1) * x + i - 1],
s[(j + 1) * x + i + 1]);
d[(j * x + i) * 3 + GREEN] = avg4(s[(j - 1) * x + i],
s[j * x + i - 1],
s[j * x + i + 1],
s[(j + 1) * x + i]);
d[(j * x + i) * 3 + BLUE] = s[j * x + i];
i++;
}
j++;
}
/* lower left corner */
d[(j * x) * 3 + RED] = s[j * x + 1];
d[(j * x) * 3 + GREEN] = s[j * x];
d[(j * x) * 3 + BLUE] = s[(j - 1) * x];
/* bottom line */
i = 1;
while (i < x - 2) {
d[(j * x + i) * 3 + RED] = s[j * x + i];
d[(j * x + i) * 3 + GREEN] = avg2(s[j * x + i - 1], s[j * x + i + 1]);
d[(j * x + i) * 3 + BLUE] = avg2(s[(j - 1) * x + i - 1],
s[(j - 1) * x + i + 1]);
i++;
d[(j * x + i) * 3 + RED] = avg2(s[j * x + i - 1], s[j * x + i + 1]);
d[(j * x + i) * 3 + GREEN] = s[j * x + i];
d[(j * x + i) * 3 + BLUE] = s[(j - 1) * x + i];
i++;
}
/* lower right corner */
d[(j * x + i) * 3 + RED] = s[j * x + i];
d[(j * x + i) * 3 + GREEN] = avg2(s[(j - 1) * x + i], s[j * x + i - 1]);
d[(j * x + i) * 3 + BLUE] = s[(j - 1) * x + i - 1];
}
/* ------------------------------------------------------------------- */
/* bayer bgbg...grgr...to rgb16 */
static void
sbggr8_to_rgb16(void *p, struct ng_video_buf *out, struct ng_video_buf *in)
{
unsigned char *restrict s;
uint16_t *d1, *d2;
unsigned long i, j, x, y, w, h;
unsigned char r, g1, g2, b, g;
s = in->data;
w = in->fmt.width;
h = in->fmt.height;
d1 = (uint16_t *)out->data;
d2 = d1 + w;
i = 0;
j = w;
for (y = 0; y < h; y += 2, i += w * 2, j += w * 2, d1 += w, d2 += w) {
for (x = 0; x < w; x += 2) {
b = s[i + x] ;
g1 = s[i + 1 + x];
g2 = s[j + x];
r = s[j + 1 + x];
g = (g1 >> 1) + (g2 >> 1);
*d1++ = (((b) & 0xF8) >> 3 |
(((g1) & 0xFC) << 3) |
(((r) & 0xF8) << 8)) ;
*d1++ = (((b) & 0xF8) >> 3 |
(((g) & 0xFC) << 3) |
(((r) & 0xF8) << 8)) ;
*d2++ = (((b) & 0xF8) >> 3 |
(((g) & 0xFC) << 3) |
(((r) & 0xF8) << 8)) ;
*d2++ = (((b) & 0xF8) >> 3 |
(((g2) & 0xFC) << 3) |
(((r) & 0xF8) << 8)) ;
}
}
}
static void
sbggr8_to_rgb32(void *p, struct ng_video_buf *out, struct ng_video_buf *in)
{
unsigned char *restrict s;
unsigned char *d1, *d2;
unsigned long i, j, x, y, w, h;
unsigned char r, g1, g2, b, g;
s = in->data;
w = in->fmt.width;
h = in->fmt.height;
d1 = out->data;
d2 = d1 + 4*w;
i = 0;
j = w;
for (y = 0; y < h; y += 2, i += w * 2, j += w * 2, d1 += 4*w, d2 += 4*w) {
for (x = 0; x < w; x += 2) {
b = s[i + x] ;
g1 = s[i + 1 + x];
g2 = s[j + x];
r = s[j + 1 + x];
g = (g1 >> 1) + (g2 >> 1);
d1[0] = (r);
d1[1] = (g1);
d1[2] = (b);
d1 += 4;
d1[0] = (r);
d1[1] = (g);
d1[2] = (b);
d1 += 4;
d2[0] = (r);
d2[1] = (g);
d2[2] = (b);
d2 += 4;
d2[0] = (r);
d2[1] = (g2);
d2[2] = (b);
d2 += 4;
}
}
}
static void
sbggr8_to_yuv420p(void *p, struct ng_video_buf *out, struct ng_video_buf *in)
{
unsigned char *restrict s;
unsigned char *d1, *d2, *U, *V;
unsigned long i, j, x, y, w, h;
unsigned char tr, tb, r, g1, g2, b, g, y1, y2, y3, y4;
int u, v;
#define CLIP(color) ((color > 0xff) ? 0xff : ((color < 0) ? 0 : color))
s = in->data;
w = in->fmt.width;
h = in->fmt.height;
d1 = out->data;
d2 = d1 + w;
i = 0;
j = w;
U = d1 + w*h;
V = U + ((w*h) >> 2);
for (y = 0; y < h; y += 2, i += w * 2, j += w * 2, d1 += w, d2 += w) {
for (x = 0; x < w; x += 2) {
tb = s[i + x] ;
g1 = s[i + 1 + x];
g2 = s[j + x];
tr = s[j + 1 + x];
g = (g1 >> 1) + (g2 >> 1);
r = ((tr << 8) - (tr << 4) - (tr << 3)) >> 10;
b = ((tb << 7) >> 10);
g1 = ((g1 << 9) + (g1 << 7) + (g1 << 5)) >> 10;
g2 = ((g2 << 9) + (g2 << 7) + (g2 << 5)) >> 10;
g = ((g << 9) + (g << 7) + (g << 5)) >> 10;
y1 = CLIP((r + g1 + b));
y2 = CLIP((r + g + b));
y3 = CLIP((r + g + b));
y4 = CLIP((r + g2 + b));
*d1++ = y1;
*d1++ = y2;
*d2++ = y3;
*d2++ = y4;
v = tr - ((y1 + y2 + y3 + y4) >> 2);
u = ((v << 9) + (v << 7) + (v << 5)) >> 10;
v = (tb - ((y1 + y2 + y3 + y4) >> 2)) >> 1;
*U++ = 128 + v;
*V++ = 128 + u;
}
}
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/vlc/attachments/20041115/ec919fe0/attachment.html>
More information about the vlc
mailing list