diff options
author | David Schleef <ds@schleef.org> | 2007-12-27 00:52:23 +0000 |
---|---|---|
committer | David Schleef <ds@schleef.org> | 2007-12-27 00:52:23 +0000 |
commit | 3b15f24af01272a011b9e8d9df500a7c62eb496d (patch) | |
tree | 91291cff718e109a715332794c0f575786555121 /sys/glsink/color_matrix.c | |
parent | 28eec0700150e32a4f257985a53c22ab22cf562f (diff) | |
download | gst-plugins-bad-3b15f24af01272a011b9e8d9df500a7c62eb496d.tar.gz gst-plugins-bad-3b15f24af01272a011b9e8d9df500a7c62eb496d.tar.bz2 gst-plugins-bad-3b15f24af01272a011b9e8d9df500a7c62eb496d.zip |
sys/glsink/: Remove code that handles non-texture buffers. Add a
Original commit message from CVS:
* sys/glsink/BUGS:
* sys/glsink/Makefile.am:
* sys/glsink/gstglbuffer.c:
* sys/glsink/gstglbuffer.h:
* sys/glsink/gstglconvert.c:
* sys/glsink/gstgldisplay.c:
* sys/glsink/gstglfilter.c:
* sys/glsink/gstglfilter.h:
* sys/glsink/gstglfilterexample.c:
* sys/glsink/gstgltestsrc.c:
* sys/glsink/gstglupload.c:
* sys/glsink/gstopengl.c:
Remove code that handles non-texture buffers. Add a
GstGLBufferFormat type that corresponds to how to use the
texture, not the original video format. Convert gstflfilter.c
into a base class, add glfilterexample and glconvert elements.
* sys/glsink/color_matrix.c:
Minor ramblings about color conversion matrices.
Diffstat (limited to 'sys/glsink/color_matrix.c')
-rw-r--r-- | sys/glsink/color_matrix.c | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/sys/glsink/color_matrix.c b/sys/glsink/color_matrix.c new file mode 100644 index 00000000..255184f7 --- /dev/null +++ b/sys/glsink/color_matrix.c @@ -0,0 +1,243 @@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include <stdio.h> +#include <string.h> + +typedef struct +{ + double comp[3]; +} Color; + +typedef struct +{ + Color pre_offset; + double matrix[3][3]; + Color post_offset; +} ColorMatrix; + + +/* convert uint8 RGB values to float */ +ColorMatrix rgb255_to_rgb = { + {{0, 0, 0}}, + {{(1 / 255.0), 0, 0}, + {0, (1 / 255.0), 0}, + {0, 0, (1 / 255.0)}}, + {{0, 0, 0}} +}; +ColorMatrix rgb_to_rgb255; + +/* convert uint8 YUV values to float as per ITU-R.601 + * technically, Y, Cr, Cb to E_Y, E_C_B, E_C_R */ +ColorMatrix ycbcr601_to_yuv = { + {{-16, -128, -128}}, + {{(1 / 219.0), 0, 0}, + {0, (1 / 224.0), 0}, + {0, 0, (1 / 224.0)}}, + {{0, 0, 0}} +}; +ColorMatrix yuv_to_ycbcr601; + +/* convert RGB to YUV as per ITU-R.601 + * technically, E_R, E_G, E_B to E_Y, E_C_B, E_C_R */ +ColorMatrix rgb_to_yuv = { + {{0, 0, 0}}, + {{0.299, 0.587, 0.114}, + {0.500, -0.419, -0.081}, + {-0.169, -0.331, 0.500}}, + {{0, 0, 0}} +}; +ColorMatrix yuv_to_rgb; + +ColorMatrix compress = { + {{0, 0, 0}}, + {{0.50, 0, 0}, + {0, 0.5, 0}, + {0, 0, 0.500}}, + {{0.25, 0.25, 0.25}} +}; + +/* red mask */ +ColorMatrix red_mask = { + {{0, 0, 0}}, + {{1, 1, 1}, + {0, 0, 0}, + {0, 0, 0}}, + {{0, 0, 0}} +}; + +double colors[][3] = { + {0, 0, 0}, + {255, 0, 0}, + {0, 255, 0}, + {0, 0, 255} +}; + + +void +color_dump (const double *a) +{ + printf (" %g, %g, %g\n", a[0], a[1], a[2]); +} + +void +color_matrix_dump (ColorMatrix * m) +{ + printf ("pre: %g, %g, %g\n", + m->pre_offset.comp[0], m->pre_offset.comp[1], m->pre_offset.comp[2]); + printf (" %g, %g, %g\n", m->matrix[0][0], m->matrix[0][1], m->matrix[0][2]); + printf (" %g, %g, %g\n", m->matrix[1][0], m->matrix[1][1], m->matrix[1][2]); + printf (" %g, %g, %g\n", m->matrix[2][0], m->matrix[2][1], m->matrix[2][2]); + printf ("post: %g, %g, %g\n", + m->post_offset.comp[0], m->post_offset.comp[1], m->post_offset.comp[2]); +} + +void +color_matrix_apply_color (Color * a, const ColorMatrix * b) +{ + Color d; + int i; + + a->comp[0] += b->pre_offset.comp[0]; + a->comp[1] += b->pre_offset.comp[1]; + a->comp[2] += b->pre_offset.comp[2]; + + for (i = 0; i < 3; i++) { + d.comp[i] = a->comp[0] * b->matrix[i][0]; + d.comp[i] += a->comp[1] * b->matrix[i][1]; + d.comp[i] += a->comp[2] * b->matrix[i][2]; + } + + d.comp[0] += b->post_offset.comp[0]; + d.comp[1] += b->post_offset.comp[1]; + d.comp[2] += b->post_offset.comp[2]; + + *a = d; +} + +void +color_matrix_init (ColorMatrix * a) +{ + memset (a, 0, sizeof (*a)); + a->matrix[0][0] = 1.0; + a->matrix[1][1] = 1.0; + a->matrix[2][2] = 1.0; +} + +void +color_matrix_apply (ColorMatrix * a, ColorMatrix * b) +{ + ColorMatrix d; + int i, j; + + d.pre_offset = a->pre_offset; + + d.post_offset = a->post_offset; + color_matrix_apply_color (&d.post_offset, b); + + for (j = 0; j < 3; j++) { + for (i = 0; i < 3; i++) { + d.matrix[i][j] = + a->matrix[i][0] * b->matrix[0][j] + + a->matrix[i][1] * b->matrix[1][j] + a->matrix[i][2] * b->matrix[2][j]; + } + } + + *a = d; +} + +void +color_matrix_invert (ColorMatrix * a, ColorMatrix * b) +{ + int i, j; + double det; + + a->post_offset.comp[0] = -b->pre_offset.comp[0]; + a->post_offset.comp[1] = -b->pre_offset.comp[1]; + a->post_offset.comp[2] = -b->pre_offset.comp[2]; + + for (j = 0; j < 3; j++) { + for (i = 0; i < 3; i++) { + a->matrix[j][i] = + b->matrix[(i + 1) % 3][(j + 1) % 3] * b->matrix[(i + 2) % 3][(j + + 2) % 3] - b->matrix[(i + 1) % 3][(j + 2) % 3] * b->matrix[(i + + 2) % 3][(j + 1) % 3]; + } + } + + det = a->matrix[0][0] * b->matrix[0][0]; + det += a->matrix[0][1] * b->matrix[1][0]; + det += a->matrix[0][2] * b->matrix[2][0]; + + for (j = 0; j < 3; j++) { + for (i = 0; i < 3; i++) { + a->matrix[j][i] /= det; + } + } + + a->pre_offset.comp[0] = -b->post_offset.comp[0]; + a->pre_offset.comp[1] = -b->post_offset.comp[1]; + a->pre_offset.comp[2] = -b->post_offset.comp[2]; +} + +void +init (void) +{ + color_matrix_invert (&yuv_to_rgb, &rgb_to_yuv); + color_matrix_invert (&yuv_to_ycbcr601, &ycbcr601_to_yuv); + color_matrix_invert (&rgb_to_rgb255, &rgb255_to_rgb); +#if 0 + color_matrix_dump (&yuv_to_rgb); + color_matrix_dump (&yuv_to_ycbcr601); + color_matrix_dump (&rgb_to_rgb255); +#endif +} + +int +main (int argc, char *argv[]) +{ + ColorMatrix want; + ColorMatrix actual; + ColorMatrix actual_inv; + ColorMatrix a; + + init (); + +#if 0 + int i; + + for (i = 0; i < 4; i++) { + double color[3]; + + printf ("%d:\n", i); + + color_copy (color, colors[i]); + color_matrix_apply_color (color, &rgb255_to_rgb); + color_matrix_apply_color (color, &rgb_to_yuv); + color_dump (color); + } +#endif + + color_matrix_init (&want); + color_matrix_apply (&want, &ycbcr601_to_yuv); + color_matrix_apply (&want, &yuv_to_rgb); + color_matrix_apply (&want, &compress); + color_matrix_apply (&want, &compress); + //color_matrix_apply (&want, &compress); + + color_matrix_init (&actual); + color_matrix_apply (&actual, &rgb255_to_rgb); + + /* calc X such that actual * X = want */ + + color_matrix_invert (&actual_inv, &actual); + + a = actual_inv; + color_matrix_apply (&a, &want); + + color_matrix_dump (&a); + + + return 0; +} |