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