diff options
author | Keith Whitwell <keith@tungstengraphics.com> | 2003-05-20 08:50:02 +0000 |
---|---|---|
committer | Keith Whitwell <keith@tungstengraphics.com> | 2003-05-20 08:50:02 +0000 |
commit | eea72ff722975d91bc2293a403bb43d69e5858d0 (patch) | |
tree | 35fa3770e7e23e0612612d34aafe5c6734d719b5 | |
parent | 0421ce4b46a3bfe43d06e31cfc6cc62060004657 (diff) |
Test programs for ycbcr extension
-rw-r--r-- | progs/tests/yuvrect.c | 233 | ||||
-rw-r--r-- | progs/tests/yuvsquare.c | 290 |
2 files changed, 523 insertions, 0 deletions
diff --git a/progs/tests/yuvrect.c b/progs/tests/yuvrect.c new file mode 100644 index 00000000000..22ee91cae97 --- /dev/null +++ b/progs/tests/yuvrect.c @@ -0,0 +1,233 @@ +/* + * Test the GL_NV_texture_rectangle and GL_MESA_ycrcb_texture extensions. + * + * Brian Paul 13 September 2002 + */ + +#include <assert.h> +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#define GL_GLEXT_PROTOTYPES +#include <GL/glut.h> + +#include "../util/readtex.c" /* I know, this is a hack. */ + +#define TEXTURE_FILE "../images/girl.rgb" + +static GLfloat Xrot = 0, Yrot = 0, Zrot = 0; +static GLint ImgWidth, ImgHeight; +static GLenum ImgFormat; +static GLubyte *Image = NULL; +static GLushort *ImageYUV = NULL; + + +static void DrawObject(void) +{ + glBegin(GL_QUADS); + + glTexCoord2f(0, 0); + glVertex2f(-1.0, -1.0); + + glTexCoord2f(ImgWidth, 0); + glVertex2f(1.0, -1.0); + + glTexCoord2f(ImgWidth, ImgHeight); + glVertex2f(1.0, 1.0); + + glTexCoord2f(0, ImgHeight); + glVertex2f(-1.0, 1.0); + + glEnd(); +} + + +static void Display( void ) +{ + glClear( GL_COLOR_BUFFER_BIT ); + + glPushMatrix(); + glRotatef(Xrot, 1.0, 0.0, 0.0); + glRotatef(Yrot, 0.0, 1.0, 0.0); + glRotatef(Zrot, 0.0, 0.0, 1.0); + DrawObject(); + glPopMatrix(); + + glutSwapBuffers(); +} + + +static void Reshape( int width, int height ) +{ + glViewport( 0, 0, width, height ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glFrustum( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 ); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + glTranslatef( 0.0, 0.0, -15.0 ); +} + + +static void Key( unsigned char key, int x, int y ) +{ + (void) x; + (void) y; + switch (key) { + case 27: + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void SpecialKey( int key, int x, int y ) +{ + float step = 3.0; + (void) x; + (void) y; + + switch (key) { + case GLUT_KEY_UP: + Xrot += step; + break; + case GLUT_KEY_DOWN: + Xrot -= step; + break; + case GLUT_KEY_LEFT: + Yrot += step; + break; + case GLUT_KEY_RIGHT: + Yrot -= step; + break; + } + glutPostRedisplay(); +} + + +#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) ) + +static void ConvertRGBtoYUV(GLint w, GLint h, const GLubyte *src, + GLushort *dest) +{ + GLint i, j; + + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + const GLfloat r = (*src++) / 255.0; + const GLfloat g = (*src++) / 255.0; + const GLfloat b = (*src++) / 255.0; + GLfloat y, cr, cb; + GLint iy, icr, icb; + + y = r * 65.481 + g * 128.553 + b * 24.966 + 16; + cb = r * -37.797 + g * -74.203 + b * 112.0 + 128; + cr = r * 112.0 + g * -93.786 + b * -18.214 + 128; + /*printf("%f %f %f -> %f %f %f\n", r, g, b, y, cb, cr);*/ + iy = (GLint) CLAMP(y, 0, 254); + icb = (GLint) CLAMP(cb, 0, 254); + icr = (GLint) CLAMP(cr, 0, 254); + + if (j & 1) { + /* odd */ + *dest = (iy << 8) | icr; + } + else { + /* even */ + *dest = (iy << 8) | icb; + } + dest++; + } + } +} + + +static void Init( int argc, char *argv[] ) +{ + GLuint texObj = 100; + const char *file; + + if (!glutExtensionSupported("GL_NV_texture_rectangle")) { + printf("Sorry, GL_NV_texture_rectangle is required\n"); + exit(0); + } + + if (!glutExtensionSupported("GL_MESA_ycbcr_texture")) { + printf("Sorry, GL_MESA_ycbcr_texture is required\n"); + exit(0); + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glBindTexture(GL_TEXTURE_RECTANGLE_NV, texObj); +#ifdef LINEAR_FILTER + /* linear filtering looks much nicer but is much slower for Mesa */ + glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +#else + glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST); +#endif + + if (argc > 1) + file = argv[1]; + else + file = TEXTURE_FILE; + + Image = LoadRGBImage(file, &ImgWidth, &ImgHeight, &ImgFormat); + if (!Image) { + printf("Couldn't read %s\n", TEXTURE_FILE); + exit(0); + } + + printf("Image: %dx%d\n", ImgWidth, ImgHeight); + + ImageYUV = (GLushort *) malloc(ImgWidth * ImgHeight * sizeof(GLushort)); + ConvertRGBtoYUV(ImgWidth, ImgHeight, Image, ImageYUV); + glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, + GL_YCBCR_MESA, ImgWidth, ImgHeight, 0, + GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, ImageYUV); + + assert(glGetError() == GL_NO_ERROR); + glTexSubImage2D(GL_TEXTURE_RECTANGLE_NV, 0, + 0, 0, ImgWidth, ImgHeight, + GL_YCBCR_MESA, GL_UNSIGNED_SHORT_8_8_MESA, ImageYUV); + + assert(glGetError() == GL_NO_ERROR); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + glEnable(GL_TEXTURE_RECTANGLE_NV); + + glShadeModel(GL_FLAT); + glClearColor(0.3, 0.3, 0.4, 1.0); + + if (argc > 1 && strcmp(argv[1], "-info")==0) { + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); + printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); + } +} + + +int main( int argc, char *argv[] ) +{ + glutInit( &argc, argv ); + glutInitWindowSize( 300, 300 ); + glutInitWindowPosition( 0, 0 ); + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); + glutCreateWindow(argv[0] ); + + Init( argc, argv ); + + glutReshapeFunc( Reshape ); + glutKeyboardFunc( Key ); + glutSpecialFunc( SpecialKey ); + glutDisplayFunc( Display ); + + glutMainLoop(); + return 0; +} diff --git a/progs/tests/yuvsquare.c b/progs/tests/yuvsquare.c new file mode 100644 index 00000000000..1d2ce135fe9 --- /dev/null +++ b/progs/tests/yuvsquare.c @@ -0,0 +1,290 @@ +/* + * Test the GL_NV_texture_rectangle and GL_MESA_ycrcb_texture extensions. + * + * Brian Paul 13 September 2002 + */ + + +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#define GL_GLEXT_PROTOTYPES +#include <GL/glut.h> + +#include "../util/readtex.c" /* I know, this is a hack. */ + +#define TEXTURE_FILE "../images/tile.rgb" + +static GLfloat Xrot = 0, Yrot = 0, Zrot = 0; +static GLint ImgWidth, ImgHeight; +static GLenum ImgFormat; +static GLushort *ImageYUV = NULL; + + +static void DrawObject(void) +{ + glBegin(GL_QUADS); + + glTexCoord2f(0, 0); + glVertex2f(-1.0, -1.0); + + glTexCoord2f(1, 0); + glVertex2f(1.0, -1.0); + + glTexCoord2f(1, 1); + glVertex2f(1.0, 1.0); + + glTexCoord2f(0, 1); + glVertex2f(-1.0, 1.0); + + glEnd(); +} + + +static void Display( void ) +{ + glClear( GL_COLOR_BUFFER_BIT ); + + glPushMatrix(); + glRotatef(Xrot, 1.0, 0.0, 0.0); + glRotatef(Yrot, 0.0, 1.0, 0.0); + glRotatef(Zrot, 0.0, 0.0, 1.0); + DrawObject(); + glPopMatrix(); + + glutSwapBuffers(); +} + + +static void Reshape( int width, int height ) +{ + glViewport( 0, 0, width, height ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glFrustum( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 ); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + glTranslatef( 0.0, 0.0, -15.0 ); +} + + +static void Key( unsigned char key, int x, int y ) +{ + (void) x; + (void) y; + switch (key) { + case 27: + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void SpecialKey( int key, int x, int y ) +{ + float step = 3.0; + (void) x; + (void) y; + + switch (key) { + case GLUT_KEY_UP: + Xrot += step; + break; + case GLUT_KEY_DOWN: + Xrot -= step; + break; + case GLUT_KEY_LEFT: + Yrot += step; + break; + case GLUT_KEY_RIGHT: + Yrot -= step; + break; + } + glutPostRedisplay(); +} + + +#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) ) + +static void ConvertRGBtoYUV(GLint w, GLint h, GLint texel_bytes, + const GLubyte *src, + GLushort *dest) +{ + GLint i, j; + + for (i = 0; i < h; i++) { + for (j = 0; j < w; j++) { + const GLfloat r = (src[0]) / 255.0; + const GLfloat g = (src[1]) / 255.0; + const GLfloat b = (src[2]) / 255.0; + GLfloat y, cr, cb; + GLint iy, icr, icb; + + y = r * 65.481 + g * 128.553 + b * 24.966 + 16; + cb = r * -37.797 + g * -74.203 + b * 112.0 + 128; + cr = r * 112.0 + g * -93.786 + b * -18.214 + 128; + /*printf("%f %f %f -> %f %f %f\n", r, g, b, y, cb, cr);*/ + iy = (GLint) CLAMP(y, 0, 254); + icb = (GLint) CLAMP(cb, 0, 254); + icr = (GLint) CLAMP(cr, 0, 254); + + if (j & 1) { + /* odd */ + *dest = (iy << 8) | icr; + } + else { + /* even */ + *dest = (iy << 8) | icb; + } + dest++; + src += texel_bytes; + } + } +} + + +/* + * Load an SGI .rgb file and return a pointer to the image data. + * Input: imageFile - name of .rgb to read + * Output: width - width of image + * height - height of image + * format - format of image (GL_RGB or GL_RGBA) + * Return: pointer to image data or NULL if error + */ +GLushort *LoadYUVImage( const char *imageFile, GLint *width, GLint *height, + GLenum *format ) +{ + TK_RGBImageRec *image; + GLint bytes; + GLushort *buffer; + + image = tkRGBImageLoad( imageFile ); + if (!image) { + return NULL; + } + + if (image->components==3) { + *format = GL_RGB; + } + else if (image->components==4) { + *format = GL_RGBA; + } + else { + /* not implemented */ + fprintf(stderr, + "Error in LoadYUVImage %d-component images not implemented\n", + image->components ); + return NULL; + } + + *width = image->sizeX; + *height = image->sizeY; + + buffer = (GLushort *) malloc( image->sizeX * image->sizeY * 2 ); + + if (buffer) + ConvertRGBtoYUV( image->sizeX, + image->sizeY, + image->components, + image->data, + buffer ); + + + FreeImage(image); + return buffer; +} + + + +/* #define LINEAR_FILTER */ + +static void Init( int argc, char *argv[] ) +{ + GLuint texObj = 100; + const char *file; + int error; + + if (!glutExtensionSupported("GL_MESA_ycbcr_texture")) { + printf("Sorry, GL_MESA_ycbcr_texture is required\n"); + exit(0); + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glBindTexture(GL_TEXTURE_2D, texObj); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + if (argc > 1) + file = argv[1]; + else + file = TEXTURE_FILE; + + ImageYUV = LoadYUVImage(file, &ImgWidth, &ImgHeight, &ImgFormat); + if (!ImageYUV) { + printf("Couldn't read %s\n", TEXTURE_FILE); + exit(0); + } + + printf("Image: %dx%d\n", ImgWidth, ImgHeight); + +/* error = gluBuild2DMipmaps( GL_TEXTURE_2D, */ +/* GL_YCBCR_MESA, */ +/* ImgWidth, ImgHeight, */ +/* GL_YCBCR_MESA, */ +/* GL_UNSIGNED_SHORT_8_8_MESA, */ +/* ImageYUV ); */ + + + +#if 0 + glTexImage2D(GL_TEXTURE_2D, 0, + GL_RGB, + ImgWidth, ImgHeight, 0, + GL_RGB, + GL_UNSIGNED_SHORT_5_6_5, ImageYUV); +#else + glTexImage2D(GL_TEXTURE_2D, 0, + GL_YCBCR_MESA, + ImgWidth, ImgHeight, 0, + GL_YCBCR_MESA, + GL_UNSIGNED_SHORT_8_8_MESA, ImageYUV); +#endif + + glEnable(GL_TEXTURE_2D); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + + glShadeModel(GL_FLAT); + glClearColor(0.3, 0.3, 0.4, 1.0); + + if (argc > 1 && strcmp(argv[1], "-info")==0) { + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); + printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); + printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); + printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); + } +} + + +int main( int argc, char *argv[] ) +{ + glutInit( &argc, argv ); + glutInitWindowSize( 300, 300 ); + glutInitWindowPosition( 0, 0 ); + glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); + glutCreateWindow(argv[0] ); + + Init( argc, argv ); + + glutReshapeFunc( Reshape ); + glutKeyboardFunc( Key ); + glutSpecialFunc( SpecialKey ); + glutDisplayFunc( Display ); + + glutMainLoop(); + return 0; +} |