1/*
2 * Copyright (c) 1993-2003, Silicon Graphics, Inc.
3 * All Rights Reserved
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose and without fee is hereby granted, provided that the above
7 * copyright notice appear in all copies and that both the copyright
8 * notice and this permission notice appear in supporting documentation,
9 * and that the name of Silicon Graphics, Inc. not be used in
10 * advertising or publicity pertaining to distribution of the software
11 * without specific, written prior permission.
12 *
13 * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND
14 * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
16 * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
17 * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
18 * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19 * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF
20 * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD
21 * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN ADVISED OF
22 * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF
23 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE
24 * OR PERFORMANCE OF THIS SOFTWARE.
25 *
26 * US Government Users Restricted Rights
27 * Use, duplication, or disclosure by the Government is subject to
28 * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
29 * (c)(1)(ii) of the Rights in Technical Data and Computer Software
30 * clause at DFARS 252.227-7013 and/or in similar or successor clauses
31 * in the FAR or the DOD or NASA FAR Supplement.  Unpublished - rights
32 * reserved under the copyright laws of the United States.
33 *
34 * Contractor/manufacturer is:
35 *	Silicon Graphics, Inc.
36 *	1500 Crittenden Lane
37 *	Mountain View, CA  94043
38 *	United State of America
39 *
40 * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
41 */
42
43/*
44 *  convolution.c
45 *  Use various 2D convolutions filters to find edges in an image.
46 *
47 */
48#include <GL/glew.h>
49#include "glut_wrap.h"
50#include <assert.h>
51#include <stdio.h>
52#include <stdlib.h>
53
54
55static GLuint bswap(GLuint x)
56{
57   const GLuint ui = 1;
58   const GLubyte *ubp = (const GLubyte *) &ui;
59   if (*ubp == 1) {
60      /* we're on little endiang so byteswap x */
61      GLsizei y =  ((x >> 24)
62                    | ((x >> 8) & 0xff00)
63                    | ((x << 8) & 0xff0000)
64                    | ((x << 24) & 0xff000000));
65      return y;
66   }
67   else {
68      return x;
69   }
70}
71
72
73static GLubyte *
74readImage( const char* filename, GLsizei* width, GLsizei *height )
75{
76    int       n;
77    GLubyte*  pixels;
78    size_t    num_read;
79
80    FILE* infile = fopen( filename, "rb" );
81
82    if ( !infile ) {
83	fprintf( stderr, "Unable to open file '%s'\n", filename );
84        exit(1);
85    }
86
87    num_read = fread( width, sizeof( GLsizei ), 1, infile );
88    assert(num_read == 1);
89    num_read = fread( height, sizeof( GLsizei ), 1, infile );
90    assert(num_read == 1);
91
92    *width = bswap(*width);
93    *height = bswap(*height);
94
95    assert(*width > 0);
96    assert(*height > 0);
97
98    n = 3 * (*width) * (*height);
99
100    pixels = (GLubyte *) malloc( n * sizeof( GLubyte ));
101    if ( !pixels ) {
102	fprintf( stderr, "Unable to malloc() bytes for pixels\n" );
103	fclose( infile );
104	return NULL;
105    }
106
107    num_read = fread( pixels, sizeof( GLubyte ), n, infile );
108    assert(num_read == n);
109
110    fclose( infile );
111
112    return pixels;
113}
114
115
116GLubyte  *pixels;
117GLsizei   width, height;
118
119GLfloat  horizontal[3][3] = {
120    { 0, -1, 0 },
121    { 0,  1, 0 },
122    { 0,  0, 0 }
123};
124
125GLfloat  vertical[3][3] = {
126    {  0, 0, 0 },
127    { -1, 1, 0 },
128    {  0, 0, 0 }
129};
130
131GLfloat  laplacian[3][3] = {
132    { -0.125, -0.125, -0.125 },
133    { -0.125,  1.0  , -0.125 },
134    { -0.125, -0.125, -0.125 },
135};
136
137
138static void init(void)
139{
140   if (!glutExtensionSupported("GL_ARB_imaging")) {
141      fprintf(stderr, "Sorry, this program requires GL_ARB_imaging.\n");
142      exit(1);
143   }
144
145   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
146   glClearColor(0.0, 0.0, 0.0, 0.0);
147
148   printf("Using the horizontal filter\n");
149   glConvolutionFilter2D(GL_CONVOLUTION_2D, GL_LUMINANCE,
150			 3, 3, GL_LUMINANCE, GL_FLOAT, horizontal);
151   glEnable(GL_CONVOLUTION_2D);
152}
153
154static void display(void)
155{
156   glClear(GL_COLOR_BUFFER_BIT);
157   glRasterPos2i( 1, 1);
158   glDrawPixels(width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels);
159   glFlush();
160}
161
162static void reshape(int w, int h)
163{
164   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
165   glMatrixMode(GL_PROJECTION);
166   glLoadIdentity();
167   glOrtho(0, w, 0, h, -1.0, 1.0);
168   glMatrixMode(GL_MODELVIEW);
169}
170
171static void keyboard(unsigned char key, int x, int y)
172{
173   switch (key) {
174       case 'h' :
175	   printf("Using a horizontal filter\n");
176	   glConvolutionFilter2D(GL_CONVOLUTION_2D, GL_LUMINANCE, 3, 3,
177				  GL_LUMINANCE, GL_FLOAT, horizontal);
178	   break;
179
180       case 'v' :
181	   printf("Using the vertical filter\n");
182	   glConvolutionFilter2D(GL_CONVOLUTION_2D, GL_LUMINANCE, 3, 3,
183				  GL_LUMINANCE, GL_FLOAT, vertical);
184	   break;
185
186       case 'l' :
187	   printf("Using the laplacian filter\n");
188	   glConvolutionFilter2D(GL_CONVOLUTION_2D, GL_LUMINANCE, 3, 3,
189				  GL_LUMINANCE, GL_FLOAT, laplacian);
190	   break;
191
192       case 27:
193         exit(0);
194   }
195   glutPostRedisplay();
196}
197
198/*  Main Loop
199 *  Open window with initial window size, title bar,
200 *  RGBA display mode, and handle input events.
201 */
202int main(int argc, char** argv)
203{
204   pixels = readImage("leeds.bin", &width, &height);
205
206   glutInit(&argc, argv);
207   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
208   glutInitWindowSize(width, height);
209   glutInitWindowPosition(100, 100);
210   glutCreateWindow(argv[0]);
211   glewInit();
212   init();
213   glutReshapeFunc(reshape);
214   glutKeyboardFunc(keyboard);
215   glutDisplayFunc(display);
216   glutMainLoop();
217   return 0;
218}
219