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