132001f49Smrg/*
232001f49Smrg * Copyright (c) 1993-2003, Silicon Graphics, Inc.
332001f49Smrg * All Rights Reserved
432001f49Smrg *
532001f49Smrg * Permission to use, copy, modify, and distribute this software for any
632001f49Smrg * purpose and without fee is hereby granted, provided that the above
732001f49Smrg * copyright notice appear in all copies and that both the copyright
832001f49Smrg * notice and this permission notice appear in supporting documentation,
932001f49Smrg * and that the name of Silicon Graphics, Inc. not be used in
1032001f49Smrg * advertising or publicity pertaining to distribution of the software
1132001f49Smrg * without specific, written prior permission.
1232001f49Smrg *
1332001f49Smrg * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND
1432001f49Smrg * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
1532001f49Smrg * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
1632001f49Smrg * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
1732001f49Smrg * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
1832001f49Smrg * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
1932001f49Smrg * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF
2032001f49Smrg * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD
2132001f49Smrg * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN ADVISED OF
2232001f49Smrg * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF
2332001f49Smrg * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE
2432001f49Smrg * OR PERFORMANCE OF THIS SOFTWARE.
2532001f49Smrg *
2632001f49Smrg * US Government Users Restricted Rights
2732001f49Smrg * Use, duplication, or disclosure by the Government is subject to
2832001f49Smrg * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
2932001f49Smrg * (c)(1)(ii) of the Rights in Technical Data and Computer Software
3032001f49Smrg * clause at DFARS 252.227-7013 and/or in similar or successor clauses
3132001f49Smrg * in the FAR or the DOD or NASA FAR Supplement.  Unpublished - rights
3232001f49Smrg * reserved under the copyright laws of the United States.
3332001f49Smrg *
3432001f49Smrg * Contractor/manufacturer is:
3532001f49Smrg *	Silicon Graphics, Inc.
3632001f49Smrg *	1500 Crittenden Lane
3732001f49Smrg *	Mountain View, CA  94043
3832001f49Smrg *	United State of America
3932001f49Smrg *
4032001f49Smrg * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
4132001f49Smrg */
4232001f49Smrg
4332001f49Smrg/*
4432001f49Smrg *  convolution.c
4532001f49Smrg *  Use various 2D convolutions filters to find edges in an image.
4632001f49Smrg *
4732001f49Smrg */
4832001f49Smrg#include <GL/glew.h>
4932001f49Smrg#include "glut_wrap.h"
5032001f49Smrg#include <assert.h>
5132001f49Smrg#include <stdio.h>
5232001f49Smrg#include <stdlib.h>
5332001f49Smrg
5432001f49Smrg
5532001f49Smrgstatic GLuint bswap(GLuint x)
5632001f49Smrg{
5732001f49Smrg   const GLuint ui = 1;
5832001f49Smrg   const GLubyte *ubp = (const GLubyte *) &ui;
5932001f49Smrg   if (*ubp == 1) {
6032001f49Smrg      /* we're on little endiang so byteswap x */
6132001f49Smrg      GLsizei y =  ((x >> 24)
6232001f49Smrg                    | ((x >> 8) & 0xff00)
6332001f49Smrg                    | ((x << 8) & 0xff0000)
6432001f49Smrg                    | ((x << 24) & 0xff000000));
6532001f49Smrg      return y;
6632001f49Smrg   }
6732001f49Smrg   else {
6832001f49Smrg      return x;
6932001f49Smrg   }
7032001f49Smrg}
7132001f49Smrg
7232001f49Smrg
7332001f49Smrgstatic GLubyte *
7432001f49SmrgreadImage( const char* filename, GLsizei* width, GLsizei *height )
7532001f49Smrg{
7632001f49Smrg    int       n;
7732001f49Smrg    GLubyte*  pixels;
7832001f49Smrg    size_t    num_read;
7932001f49Smrg
8032001f49Smrg    FILE* infile = fopen( filename, "rb" );
8132001f49Smrg
8232001f49Smrg    if ( !infile ) {
8332001f49Smrg	fprintf( stderr, "Unable to open file '%s'\n", filename );
8432001f49Smrg        exit(1);
8532001f49Smrg    }
8632001f49Smrg
8732001f49Smrg    num_read = fread( width, sizeof( GLsizei ), 1, infile );
8832001f49Smrg    assert(num_read == 1);
8932001f49Smrg    num_read = fread( height, sizeof( GLsizei ), 1, infile );
9032001f49Smrg    assert(num_read == 1);
9132001f49Smrg
9232001f49Smrg    *width = bswap(*width);
9332001f49Smrg    *height = bswap(*height);
9432001f49Smrg
9532001f49Smrg    assert(*width > 0);
9632001f49Smrg    assert(*height > 0);
9732001f49Smrg
9832001f49Smrg    n = 3 * (*width) * (*height);
9932001f49Smrg
10032001f49Smrg    pixels = (GLubyte *) malloc( n * sizeof( GLubyte ));
10132001f49Smrg    if ( !pixels ) {
10232001f49Smrg	fprintf( stderr, "Unable to malloc() bytes for pixels\n" );
10332001f49Smrg	fclose( infile );
10432001f49Smrg	return NULL;
10532001f49Smrg    }
10632001f49Smrg
10732001f49Smrg    num_read = fread( pixels, sizeof( GLubyte ), n, infile );
10832001f49Smrg    assert(num_read == n);
10932001f49Smrg
11032001f49Smrg    fclose( infile );
11132001f49Smrg
11232001f49Smrg    return pixels;
11332001f49Smrg}
11432001f49Smrg
11532001f49Smrg
11632001f49SmrgGLubyte  *pixels;
11732001f49SmrgGLsizei   width, height;
11832001f49Smrg
11932001f49SmrgGLfloat  horizontal[3][3] = {
12032001f49Smrg    { 0, -1, 0 },
12132001f49Smrg    { 0,  1, 0 },
12232001f49Smrg    { 0,  0, 0 }
12332001f49Smrg};
12432001f49Smrg
12532001f49SmrgGLfloat  vertical[3][3] = {
12632001f49Smrg    {  0, 0, 0 },
12732001f49Smrg    { -1, 1, 0 },
12832001f49Smrg    {  0, 0, 0 }
12932001f49Smrg};
13032001f49Smrg
13132001f49SmrgGLfloat  laplacian[3][3] = {
13232001f49Smrg    { -0.125, -0.125, -0.125 },
13332001f49Smrg    { -0.125,  1.0  , -0.125 },
13432001f49Smrg    { -0.125, -0.125, -0.125 },
13532001f49Smrg};
13632001f49Smrg
13732001f49Smrg
13832001f49Smrgstatic void init(void)
13932001f49Smrg{
14032001f49Smrg   if (!glutExtensionSupported("GL_ARB_imaging")) {
14132001f49Smrg      fprintf(stderr, "Sorry, this program requires GL_ARB_imaging.\n");
14232001f49Smrg      exit(1);
14332001f49Smrg   }
14432001f49Smrg
14532001f49Smrg   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
14632001f49Smrg   glClearColor(0.0, 0.0, 0.0, 0.0);
14732001f49Smrg
14832001f49Smrg   printf("Using the horizontal filter\n");
14932001f49Smrg   glConvolutionFilter2D(GL_CONVOLUTION_2D, GL_LUMINANCE,
15032001f49Smrg			 3, 3, GL_LUMINANCE, GL_FLOAT, horizontal);
15132001f49Smrg   glEnable(GL_CONVOLUTION_2D);
15232001f49Smrg}
15332001f49Smrg
15432001f49Smrgstatic void display(void)
15532001f49Smrg{
15632001f49Smrg   glClear(GL_COLOR_BUFFER_BIT);
15732001f49Smrg   glRasterPos2i( 1, 1);
15832001f49Smrg   glDrawPixels(width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels);
15932001f49Smrg   glFlush();
16032001f49Smrg}
16132001f49Smrg
16232001f49Smrgstatic void reshape(int w, int h)
16332001f49Smrg{
16432001f49Smrg   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
16532001f49Smrg   glMatrixMode(GL_PROJECTION);
16632001f49Smrg   glLoadIdentity();
16732001f49Smrg   glOrtho(0, w, 0, h, -1.0, 1.0);
16832001f49Smrg   glMatrixMode(GL_MODELVIEW);
16932001f49Smrg}
17032001f49Smrg
17132001f49Smrgstatic void keyboard(unsigned char key, int x, int y)
17232001f49Smrg{
17332001f49Smrg   switch (key) {
17432001f49Smrg       case 'h' :
17532001f49Smrg	   printf("Using a horizontal filter\n");
17632001f49Smrg	   glConvolutionFilter2D(GL_CONVOLUTION_2D, GL_LUMINANCE, 3, 3,
17732001f49Smrg				  GL_LUMINANCE, GL_FLOAT, horizontal);
17832001f49Smrg	   break;
17932001f49Smrg
18032001f49Smrg       case 'v' :
18132001f49Smrg	   printf("Using the vertical filter\n");
18232001f49Smrg	   glConvolutionFilter2D(GL_CONVOLUTION_2D, GL_LUMINANCE, 3, 3,
18332001f49Smrg				  GL_LUMINANCE, GL_FLOAT, vertical);
18432001f49Smrg	   break;
18532001f49Smrg
18632001f49Smrg       case 'l' :
18732001f49Smrg	   printf("Using the laplacian filter\n");
18832001f49Smrg	   glConvolutionFilter2D(GL_CONVOLUTION_2D, GL_LUMINANCE, 3, 3,
18932001f49Smrg				  GL_LUMINANCE, GL_FLOAT, laplacian);
19032001f49Smrg	   break;
19132001f49Smrg
19232001f49Smrg       case 27:
19332001f49Smrg         exit(0);
19432001f49Smrg   }
19532001f49Smrg   glutPostRedisplay();
19632001f49Smrg}
19732001f49Smrg
19832001f49Smrg/*  Main Loop
19932001f49Smrg *  Open window with initial window size, title bar,
20032001f49Smrg *  RGBA display mode, and handle input events.
20132001f49Smrg */
20232001f49Smrgint main(int argc, char** argv)
20332001f49Smrg{
20432001f49Smrg   pixels = readImage("leeds.bin", &width, &height);
20532001f49Smrg
20632001f49Smrg   glutInit(&argc, argv);
20732001f49Smrg   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
20832001f49Smrg   glutInitWindowSize(width, height);
20932001f49Smrg   glutInitWindowPosition(100, 100);
21032001f49Smrg   glutCreateWindow(argv[0]);
21132001f49Smrg   glewInit();
21232001f49Smrg   init();
21332001f49Smrg   glutReshapeFunc(reshape);
21432001f49Smrg   glutKeyboardFunc(keyboard);
21532001f49Smrg   glutDisplayFunc(display);
21632001f49Smrg   glutMainLoop();
21732001f49Smrg   return 0;
21832001f49Smrg}
219