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 <glad/glad.h>
49 #include "glut_wrap.h"
50 #include <assert.h>
51 #include <stdio.h>
52 #include <stdlib.h>
53 
54 
bswap(GLuint x)55 static 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 
73 static GLubyte *
readImage(const char * filename,GLsizei * width,GLsizei * height)74 readImage( 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 
116 GLubyte  *pixels;
117 GLsizei   width, height;
118 
119 GLfloat  horizontal[3][3] = {
120     { 0, -1, 0 },
121     { 0,  1, 0 },
122     { 0,  0, 0 }
123 };
124 
125 GLfloat  vertical[3][3] = {
126     {  0, 0, 0 },
127     { -1, 1, 0 },
128     {  0, 0, 0 }
129 };
130 
131 GLfloat  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 
init(void)138 static 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 
display(void)154 static 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 
reshape(int w,int h)162 static 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 
keyboard(unsigned char key,int x,int y)171 static 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  */
main(int argc,char ** argv)202 int 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    gladLoadGL();
212    init();
213    glutReshapeFunc(reshape);
214    glutKeyboardFunc(keyboard);
215    glutDisplayFunc(display);
216    glutMainLoop();
217    return 0;
218 }
219