1:  #include < GL/glut.h >
2:  #include < stdlib.h >
3:  #include < stdio.h >
4:  #include < string.h >
5:  #include < math.h >
6:  #include < pthread.h >
7:  
8:  #define Round(v) ((int)(v+0.5))
9:  #define MAX 800
10:  #define MAX_FILE_LENGTH 256
11:    
12:  #define LOW_VALUE 0 
13:  #define HIGH_VALUE 255
14:  
15:  #define TRUE 1
16:  #define FALSE 0  
17:  
18:  #define RESTART 1
19:  #define CAMERA_CORRECTION 2
20:  #define X2_C_CORR 3
21:  
22:  /*cartesian coordinate type*/
23:  typedef struct {int x;
24:                  int y;}coord;  
25:  
26:  /*RGB color struct*/ 
27:  typedef struct {float red;
28:                  float green;
29:                  float blue;
30:                 }RGB;
31:  
32:  /*RGB color struct*/  
33:  typedef struct {int red;
34:                  int green;
35:                  int blue;
36:                 }RGB_INT;
37:  
38:  struct PGMstructure 
39:  {
40:    int maxVal;
41:    int width;
42:    int height;
43:    RGB_INT data[MAX][MAX];
44:  };
45:  
46:  typedef struct PGMstructure PGMImage;
47:  
48:  /*Evil globals, but not do-able otherwise.*/
49:  static PGMImage *img_cur;
50:  static PGMImage *img0; /*original*/
51:  static PGMImage *img1; /*current*/
52:  static PGMImage *img2; /*current*/
53:  static int HSIZE;
54:  static int VSIZE;
55:  
56:  /**************Drawing funcitions************************************/
57:  /********************************************************************/
58:  
59:  void setCPixel(int ix, int iy, RGB color)
60:  /*Same as setIPixel except that the last parameter is an RGB color*/
61:  {
62:    float x = (ix*2.0)/HSIZE - 1.0;
63:    float y = (iy*2.0)/VSIZE - 1.0;
64:    glColor3f(color.red, color.green, color.blue);
65:    glBegin(GL_POINTS); 
66:      glVertex2f (x, y);
67:    glEnd();
68:  }
69:  
70:  
71:  /**********************File I/O functions*******************************/
72:  /***********************************************************************/
73:  
74:  /*Gets an ascii color pgm image file (type P3).*/
75:  void getPGMfile (char filename[], PGMImage *img)
76:  {
77:    FILE *in_file;
78:    char ch;
79:    int row, col;
80:  
81:    in_file = fopen(filename, "r");
82:    if (in_file == NULL)
83:    {
84:      fprintf(stderr, "Error: Unable to open file %s\n\n", filename);
85:      exit(8);
86:    }
87:  
88:    printf("\nReading image file: %s", filename);
89:    
90:    do                                        /* skip header identifier */
91:      ch = getc(in_file);
92:    while (ch != '\n');
93:  
94:    do                                        /* skip comments lines    */
95:    {
96:      while (ch != '\n') ch = getc(in_file);  /*  flush to end of line  */
97:      ch = getc(in_file);
98:    } while (ch == '#');
99:   
100:    fseek(in_file, -1, SEEK_CUR);             /* backup one character   */
101:  
102:    fscanf(in_file,"%d", &((*img).width));
103:    fscanf(in_file,"%d", &((*img).height));
104:    fscanf(in_file,"%d", &((*img).maxVal));
105:  
106:    printf("\n width  = %d",(*img).width);
107:    printf("\n height = %d",(*img).height);
108:    printf("\n maxVal = %d",(*img).maxVal);
109:    printf("\n");
110:   
111:    if (((*img).width  > MAX) || ((*img).height  > MAX))
112:    {
113:      printf("\n\n***ERROR - image too big for current image structure***\n\n");
114:      exit(0);
115:    }
116:  
117:    for (row=(*img).height-1; row >=0; row--)
118:      for (col=0; col< (*img).width; col++)
119:      {
120:        fscanf(in_file,"%d", &((*img).data[row][col].red) );
121:        fscanf(in_file,"%d", &((*img).data[row][col].green));
122:        fscanf(in_file,"%d", &((*img).data[row][col].blue));
123:      }
124:    fclose(in_file);
125:    printf("\nDone reading file.\n");
126:  }
127:  
128:  
129:  void save(PGMImage *img)
130:  {
131:     int i, j, nr, nc, k;
132:     int red, green, blue;
133:     FILE *iop;
134:  
135:     nr = img- >height;
136:     nc = img- >width;
137:      
138:     iop = fopen("image1.pgm", "w");
139:     fprintf(iop, "P3\n");
140:     fprintf(iop, "%d %d\n", nc, nr);
141:     fprintf(iop, "255\n");
142:      
143:     k = 1;
144:     for(i = nr - 1; i  >= 0; i--)
145:     {
146:        for(j = 0; j <  nc; j++)
147:        {
148:           red = img- >data[i][j].red;
149:           green = img- >data[i][j].green;
150:           blue = img- >data[i][j].blue;
151:           if(red <  0)
152:           {
153:              printf("IMG_WRITE: Found value %d at row %d col %d\n", red, i, j);
154:              printf("           Setting red to zero\n");
155:              red = 0;
156:           }
157:           if(green <  0)   
158:           {
159:              printf("IMG_WRITE: Found value %d at row %d col %d\n", green,i, j);
160:              printf("           Setting green to zero\n");
161:              green = 0;
162:           }
163:           if(blue <  0)   
164:           {
165:              printf("IMG_WRITE: Found value %d at row %d col %d\n", blue, i, j);
166:              printf("           Setting green to zero\n");
167:              blue = 0;
168:           }
169:           if(red  > 255) 
170:           {   
171:              printf("IMG_WRITE: Found value %d at row %d col %d\n", red, i, j);
172:              printf("           Setting red to 255\n");
173:              red = 255;
174:           }
175:           if(green  > 255)
176:           {
177:              printf("IMG_WRITE: Found value %d at row %d col %d\n", green,i, j);
178:              printf("           Setting green to 255\n");
179:              green = 255;
180:           }
181:           if(blue  > 255)
182:           {
183:              printf("IMG_WRITE: Found value %d at row %d col %d\n", blue, i, j);
184:              printf("           Setting blue to 255\n");
185:              blue = 255;
186:           }
187:  
188:           if(k % 10)
189:           {
190:              fprintf(iop, "%d ", red);
191:              fprintf(iop, "%d ", green);
192:              fprintf(iop, "%d ", blue);
193:           }
194:           else /*for newline*/
195:           {
196:              fprintf(iop, "%d\n", red);
197:              fprintf(iop, "%d\n", green);
198:              fprintf(iop, "%d\n", blue);
199:           }
200:           k++;
201:        }
202:     }
203:     fprintf(iop, "\n");
204:     fclose(iop);
205:  }
206:  
207:  
208:  /****Calculation & drawing functions of the image translations**********
209:  ***********************************************************************/
210:              
211:            
212:  void showColor (PGMImage *img)
213:  {
214:     int row, col; /*y, x*/
215:     RGB pixel_color; /*valid between 0 and 1?*/
216:     for (row=(*img).height-1; row >=0; row--)
217:        for (col=0; col< (*img).width; col++)
218:        {
219:  	 pixel_color.red =
220:  	    (float)(*img).data[row][col].red/(float)(*img).maxVal;
221:  	 pixel_color.green =
222:  	    (float)(*img).data[row][col].green/(float)(*img).maxVal;
223:  	 pixel_color.blue =
224:  	    (float)(*img).data[row][col].blue/(float)(*img).maxVal;
225:  	 setCPixel(col, row, pixel_color);
226:        }
227:     glFlush ();
228:  }
229:  
230:  void camera_correction(PGMImage* new_img, PGMImage* org_img)
231:  {
232:     int row, col, img_row, img_col; /*loop counting*/
233:  
234:     /*camera parameters*/
235:     float height = 30; /*height of camera in cm*/
236:     float gamma = 0, theta = .698; /*camera angles = 40 degrees in rad*/
237:     float aperture = 1.1968, alpha = .598; /*aperature = 2 * alpha*/
238:     
239:     /*temporary varaibles*/
240:     float angular_height_corr;
241:     float angular_side_corr;
242:     int x_coord, y_coord;
243:  
244:     memset(new_img, 0, sizeof(PGMImage));
245:     (*new_img).height = (*org_img).height;
246:     (*new_img).width = (*org_img).width;
247:     (*new_img).maxVal = (*org_img).maxVal;
248:  
249:     for (row=(*org_img).height-1; row >=0; row--)
250:        for (col=0; col< (*org_img).width; col++)
251:        {
252:  	/*img_row -= (*org_img).height / 2;
253:  	  img_col = col - (*org_img).width / 2;*/
254:  
255:  	 angular_height_corr = 
256:     (theta - alpha) + col * (aperture / ((float)((*org_img).width) - 1));
257:  	 angular_side_corr =
258:     (gamma - alpha) + row * (aperture / ((float)((*org_img).height) - 1));
259:  
260:  	 /*angular_height_corr *= 2;*/
261:  	 /*   angular_side_corr *= 3;*/
262:           /*height *= 2;*/
263:  	 height = 100;
264:  
265:  	 x_coord =
266:  	   height * (1 / tan(angular_height_corr)) * cos(angular_side_corr);
267:  	 y_coord =
268:  	   height * (1 / tan(angular_height_corr)) * sin(angular_side_corr);
269:  
270:  	 x_coord += (*org_img).width / 2;
271:  	 y_coord += (*org_img).height / 2;
272:  
273:  	 /*printf("org: (%d, %d)  new: (%d, %d)\n\n", row, col, y_coord, x_coord);*/
274:  
275:  	 /*make sure values are within bounds*/
276:           if(x_coord  > 0 && x_coord <  (*new_img).width
277:  	    && y_coord  > 0 && y_coord <  (*new_img).height)
278:  	 {
279:  	    (*new_img).data[y_coord][x_coord].red =
280:  	       (*org_img).data[row][col].red;
281:  	    (*new_img).data[y_coord][x_coord].green =
282:  	       (*org_img).data[row][col].green;
283:  	    (*new_img).data[y_coord][x_coord].blue =
284:  	       (*org_img).data[row][col].blue;
285:  	 }
286:        }
287:  }
288:  
289:  /* =================================================================
290:   * Callback functions.
291:   *
292:   * color = displayed graphics in window
293:   * menu = menu event handling
294:   * keyboard = deyboard event handling
295:   * ----------------------------------------------------------------- */
296:  void color(void)
297:  {
298:    /*glClear (GL_COLOR_BUFFER_BIT);*/
299:     
300:     /*  printf("\nDrawing Original image...\n");*/
301:    showColor(img_cur);
302:     
303:    /*glFlush();*/
304:  }
305:  
306:  void menu(int selection)
307:  {
308:     if(selection == RESTART)   
309:     {
310:        memcpy(img1, img0, sizeof(PGMImage));
311:        img_cur = img0;
312:      }
313:     if(selection == CAMERA_CORRECTION)
314:     {
315:        printf("Starting camera correction\n");
316:        camera_correction(img1, img0);
317:        img_cur = img1;
318:      }
319:     if(selection == X2_C_CORR)
320:     {
321:        printf("Starting camera correction\n");
322:        camera_correction(img1, img0);
323:        camera_correction(img2, img1);
324:        img_cur = img2;
325:      }
326:     glClear (GL_COLOR_BUFFER_BIT);
327:     showColor(img_cur);
328:     glutPostRedisplay();
329:  }
330:  
331:  void keyboard(unsigned char key, int x, int y)
332:  { 
333:     switch (key)
334:     {
335:        case 27: 
336:           exit(0);
337:           break;
338:     }
339:  }
340:    
341:  /* =================================================================
342:   * init - initializes graphics viewport
343:   *
344:   * You should not have to change this function for the first few
345:   * projects we have. It will become more important when we move to
346:   * 3D graphics.
347:   * ----------------------------------------------------------------- */
348:  void init (void)
349:  {
350:    
351:  /*
352:   * select clearing color - white
353:   */
354:     glClearColor (1.0, 1.0, 1.0, 0.0);
355:  
356:  /*
357:   * initialize viewport values
358:   */
359:     glMatrixMode(GL_PROJECTION);
360:     glLoadIdentity();
361:     glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
362:  
363:     /*add menus*/
364:     glutCreateMenu(menu);
365:     glutAddMenuEntry("Restart", RESTART);
366:     glutAddMenuEntry("Camera Correction", CAMERA_CORRECTION);
367:     glutAddMenuEntry("2x C. Corr.", X2_C_CORR);
368:     glutAttachMenu(GLUT_RIGHT_BUTTON);
369:  }
370:   
371:  int main(int argc, char** argv)
372:  {
373:     char PGMfileName[MAX_FILE_LENGTH];
374:     
375:     int WindowID;
376:  
377:     int i;  /*looping variable*/
378:      
379:     /*parse the command line*/  
380:     if(argc == 1)
381:     {
382:        printf("To few parameters.\n");
383:        printf("Usage: research < file.pgm >\n");
384:        exit(1);
385:     }
386:     else if(argc == 2)
387:        strcpy(PGMfileName, argv[1]);
388:     else
389:     {
390:        printf("To many parameters.\n");
391:        printf("Usage: research < file.pgm >\n");
392:        exit(1);
393:     }
394:  /*
395:   * Read in image file. - note: sets our global values, too.
396:   * ----------------------------------------------------------------- */
397:               
398:     img0 = (PGMImage*) malloc(sizeof(PGMImage));
399:     getPGMfile(PGMfileName, img0);
400:     HSIZE = (*img0).width;
401:     VSIZE = (*img0).height;
402:  
403:     img_cur = img0; /*VERY IMPORTANT to set this*/
404:              
405:     /*allocate memory for second image*/
406:     img1 = (PGMImage*) malloc(sizeof(PGMImage));
407:     memcpy(img1, img0, sizeof(PGMImage));
408:     /*(*img1).width = HSIZE;
409:     (*img1).height = VSIZE;
410:     (*img1).maxVal = 255;*/
411:               
412:     img2 = (PGMImage*) malloc(sizeof(PGMImage));
413:     memcpy(img2, img0, sizeof(PGMImage));
414:              
415:  /*
416:   * Initialize the glut package.
417:   * ----------------------------------------------------------------- */
418:     glutInit(&argc, argv);
419:     glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
420:  /*           
421:   * Define a new window (its size, position and title).
422:   * ----------------------------------------------------------------- */
423:        glutInitWindowSize (HSIZE, VSIZE);  /*size*/
424:        glutInitWindowPosition (10, 10);    /*position*/
425:        WindowID = glutCreateWindow (PGMfileName); /*title*/
426:        glutSetWindow(WindowID);
427:        glutDisplayFunc(color);
428:        
429:  /*  
430:   * Call our init function to define viewing parameters.
431:   * ----------------------------------------------------------------- */
432:     init ();
433:        
434:     glutKeyboardFunc(keyboard); 
435:     glutMainLoop();
436:  
437:  /*  
438:   * When we reach here, we've left the event loop and are ready to
439:   * exit.
440:   * ----------------------------------------------------------------- */
441:     return 0;
442:  }
443:  
444:  
445:  
446:  
447:  
448:  
449:  
450:  
451:  
452:  
453:  
454:  
455: