//========================================================================= //#define PROGRAMMER "BAHN, William" //#define PROG_CODE "bahw" //#define COURSE "ECE-1021" //#define YEAR (2003) //#define TERM "Fall" //#define SECTION (0) //#define ASSIGNMENT "Project" //#define REVISION (0) //#define TITLE "Single Image Random Dot Stereogram Generator" //#define SUBTITLE "Header File" //#define EMAIL "wbahn@eas.uccs.edu" //#define FILENAME "SIRDS04.h" //========================================================================= #ifndef SIRDSdotH //== INCLUDE FILES ======================================================== #include "DirtyD.h" #include "bmp.h" #include // printf(), scanf(), sprintf() #include // sqrt(), sin(), floor() #include // isdigit(), toupper() #include // rand(), abs() #include // strlen() #include // clrscr(), gotoxy(), getch() //========================================================================= // SIRDS Related Type Definitions //========================================================================= typedef struct SIRDS SIRDS; typedef struct SIRDSDATA SIRDSDATA; typedef struct SIRDSIMAGE SIRDSIMAGE; typedef struct SIRDSGEN SIRDSGEN; typedef struct ZDATA ZDATA; //========================================================================= // SIRDS_DATA Structure Definition //========================================================================= struct SIRDS { SIRDSDATA *sd; SIRDSIMAGE *si; SIRDSGEN *sg; FILE *fp_rep; int dataloaded; int imagecreated; BMP *bmp; IMAGE *image; }; #define DATALOADED (0) #define IMAGECREATED (1) //------------------------------------------------------------------------- // SIRDS_DATA Structure function prototypes - primitives //------------------------------------------------------------------------- SIRDS *CreateSIRDS(void); SIRDSDATA *GetSIRDS_SIRDSDATA(SIRDS *s); SIRDSDATA *SetSIRDS_SIRDSDATA(SIRDS *s, SIRDSDATA *p); SIRDSIMAGE *GetSIRDS_SIRDSIMAGE(SIRDS *s); SIRDSIMAGE *SetSIRDS_SIRDSIMAGE(SIRDS *s, SIRDSIMAGE *p); SIRDSGEN *GetSIRDS_SIRDSGEN(SIRDS *s); SIRDSGEN *SetSIRDS_SIRDSGEN(SIRDS *s, SIRDSGEN *p); FILE *GetSIRDS_fprep(SIRDS *s); FILE *SetSIRDS_fprep(SIRDS *s, FILE *fp); BMP *GetSIRDS_BMP(SIRDS *s); BMP *SetSIRDS_BMP(SIRDS *s, BMP *bmp); IMAGE *GetSIRDS_IMAGE(SIRDS *s); IMAGE *SetSIRDS_IMAGE(SIRDS *s, IMAGE *image); int GetSIRDS_FLAG(SIRDS *s, int flag); int SetSIRDS_FLAG(SIRDS *s, int flag, int value); //------------------------------------------------------------------------- // SIRDS_DATA Structure function prototypes - manipulatives //------------------------------------------------------------------------- SIRDS *NewSIRDS(void); struct SIRDSDATA { char *filename; int PointsX; int PointsY; double Aspect; double SizeX; double SizeY; ZDATA *data; }; struct SIRDSIMAGE { char *filename; int Depth; int Color; int PixelsX; int PixelsY; double Aspect; double SizeX; double SizeY; }; struct SIRDSGEN { double eye_cxi; double eye_cyi; double eye_cxd; double eye_cyd; double distance; double eye_sep; double depth; double relief; int null_ht; }; struct ZDATA { int rows; int cols; UBYTE **data; }; //== MACRO DEFINITIONS ==================================================== #define ALL_LINES (-1) #define ERASE (0) #define DRAW (1) //== TOP LEVEL SUPPORT FUNCTION PROTOTYPES ================================ SIRDS *CreateSIRDS(void); SIRDSDATA *ChangeSIRDSDATA(SIRDS *s, int cmd); SIRDSIMAGE *ChangeSIRDSIMAGE(SIRDS *s, int cmd); SIRDSGEN *ChangeSIRDSGEN(SIRDS *s, int cmd); int ImportSIRDS_DATA(SIRDS *s); int GenerateSIRDS(SIRDS *s); int MakeDataBMP(SIRDS *s); int GenGRD(char *filename); //== SUPPORT FUNCTIONS ==================================================== //== LOWER LEVEL FUNCTION PROTOTYPES ====================================== SIRDSIMAGE *CreateSIRDSIMAGE(void); SIRDSDATA *CreateSIRDSDATA(void); SIRDSGEN *CreateSIRDSGEN(void); SIRDSDATA *IniSIRDSDATA(SIRDSDATA *s); SIRDSIMAGE *IniSIRDSIMAGE(SIRDSIMAGE *s); SIRDSGEN *IniSIRDSGEN(SIRDSGEN *s); //== TOP LEVEL SUPPORT FUNCTION DEFINITIONS =============================== //========================================================================= // SIRDS Structure functions //========================================================================= // struct SIRDS // { // SIRDSDATA *sd; // SIRDSIMAGE *si; // SIRDSGEN *sg; // FILE *fp_rep; // int dataloaded; // int imagecreated; // BMP *bmp; // IMAGE *image; // }; //------------------------------------------------------------------------- // SIRDS Structure functions - primitives //------------------------------------------------------------------------- SIRDS *CreateSIRDS(void) { SIRDS *s; s = malloc(sizeof(SIRDS)); return(s); } SIRDSDATA *GetSIRDS_SIRDSDATA(SIRDS *s) { if(NULL != s) return(s->sd); return(NULL); } SIRDSDATA *SetSIRDS_SIRDSDATA(SIRDS *s, SIRDSDATA *p) { if(NULL != s) s->sd = p; return(GetSIRDS_SIRDSDATA(s)); } SIRDSIMAGE *GetSIRDS_SIRDSIMAGE(SIRDS *s) { if(NULL != s) return(s->si); return(NULL); } SIRDSIMAGE *SetSIRDS_SIRDSIMAGE(SIRDS *s, SIRDSIMAGE *p) { if(NULL != s) s->si = p; return(GetSIRDS_SIRDSIMAGE(s)); } SIRDSGEN *GetSIRDS_SIRDSGEN(SIRDS *s) { if(NULL != s) return(s->sg); return(NULL); } SIRDSGEN *SetSIRDS_SIRDSGEN(SIRDS *s, SIRDSGEN *p) { if(NULL != s) s->sg = p; return(GetSIRDS_SIRDSGEN(s)); } FILE *GetSIRDS_REPORTFILE(SIRDS *s) { if(NULL != s) return(s->fp_rep); return(NULL); } FILE *SetSIRDS_REPORTFILE(SIRDS *s, FILE *fp) { if(NULL != s) s->fp_rep = fp; return(GetSIRDS_REPORTFILE(s)); } BMP *GetSIRDS_BMP(SIRDS *s) { if(NULL != s) return(s->bmp); return(NULL); } BMP *SetSIRDS_BMP(SIRDS *s, BMP *p) { if(NULL != s) s->bmp = p; return(GetSIRDS_BMP(s)); } IMAGE *GetSIRDS_IMAGE(SIRDS *s) { if(NULL != s) return(s->image); return(NULL); } IMAGE *SetSIRDS_IMAGE(SIRDS *s, IMAGE *image) { if(NULL != s) s->image = image; return(GetSIRDS_IMAGE(s)); } int GetSIRDS_FLAG(SIRDS *s, int flag) { if(NULL != s) switch(flag) { case DATALOADED: return(s->dataloaded); case IMAGECREATED: return(s->imagecreated); } return(-1); } int SetSIRDS_FLAG(SIRDS *s, int flag, int value) { if(NULL != s) switch(flag) { case DATALOADED: s->dataloaded = value; case IMAGECREATED: s->imagecreated = value; } return(GetSIRDS_FLAG(s, flag)); } //------------------------------------------------------------------------- // SIRDS Structure functions - manipulatives //------------------------------------------------------------------------- SIRDS *NewSIRDS(void) { SIRDS *s; s = CreateSIRDS(); IniSIRDSDATA ( SetSIRDS_SIRDSDATA ( s, CreateSIRDSDATA() ) ); IniSIRDSIMAGE( SetSIRDS_SIRDSIMAGE( s, CreateSIRDSIMAGE() ) ); IniSIRDSGEN ( SetSIRDS_SIRDSGEN ( s, CreateSIRDSGEN() ) ); SetSIRDS_REPORTFILE(s, NULL); SetSIRDS_FLAG(s, DATALOADED, FALSE); SetSIRDS_FLAG(s, IMAGECREATED, FALSE); s->dataloaded = FALSE; s->imagecreated = FALSE; SetSIRDS_BMP(s, NULL); SetSIRDS_IMAGE(s, NULL); return(s); } //========================================================================= // SIRDS_DATA Structure functions //========================================================================= //------------------------------------------------------------------------- // SIRDS_DATA Structure functions - primitives //------------------------------------------------------------------------- //------------------------------------------------------------------------- // SIRDS_DATA Structure functions - manipulatives //------------------------------------------------------------------------- //========================================================================= // SIRDS_IMAGE Structure functions //========================================================================= //------------------------------------------------------------------------- // SIRDS_IMAGE Structure functions - primitives //------------------------------------------------------------------------- //------------------------------------------------------------------------- // SIRDS_IMAGE Structure functions - manipulatives //------------------------------------------------------------------------- //========================================================================= // SIRDS_GEN Structure functions //========================================================================= //------------------------------------------------------------------------- // SIRDS_GE Structure functions - primitives //------------------------------------------------------------------------- //------------------------------------------------------------------------- // SIRDS_GE Structure functions - manipulatives //------------------------------------------------------------------------- SIRDSIMAGE *CreateSIRDSIMAGE(void) { SIRDSIMAGE *s; s = malloc(sizeof(SIRDSIMAGE)); return(s); } SIRDSDATA *CreateSIRDSDATA(void) { SIRDSDATA *s; s = malloc(sizeof(SIRDSDATA)); return(s); } SIRDSGEN *CreateSIRDSGEN(void) { SIRDSGEN *s; s = malloc(sizeof(SIRDSGEN)); return(s); } SIRDSDATA *IniSIRDSDATA(SIRDSDATA *s) { s->filename = NULL; s->PointsX = 0; s->PointsY = 0; s->Aspect = 1.0; s->SizeX = 25.0; s->SizeY = 0.0; return(s); } SIRDSIMAGE *IniSIRDSIMAGE(SIRDSIMAGE *s) { s->filename = NULL; s->Depth = 24; s->Color = FALSE; s->PixelsX = 640; s->PixelsY = 480; s->Aspect = 1.0; s->SizeX = 24.0; s->SizeY = 18.0; return(s); } SIRDSGEN *IniSIRDSGEN(SIRDSGEN *s) { s->eye_cxi = 0.0; s->eye_cyi = 0.0; s->eye_cxd = 0.0; s->eye_cyd = 0.0; s->distance = 25.0; s->eye_sep = 5.0; s->depth = 1.0; s->relief = 0.33; s->null_ht = 0; return(s); } #define SIRDS_DISPLAY_ROW (8) #define SIRDS_DISPLAY_DATA_LABELS ( 2) #define SIRDS_DISPLAY_IMAGE_LABELS (32) #define SIRDS_DISPLAY_GEN_LABELS (57) #define SIRDS_DISPLAY_DATA_OFFSET (25) #define SIRDS_DISPLAY_IMAGE_OFFSET (20) #define SIRDS_DISPLAY_GEN_OFFSET (19) #define SIRDS_DL (SIRDS_DISPLAY_DATA_LABELS) #define SIRDS_IL (SIRDS_DISPLAY_IMAGE_LABELS) #define SIRDS_GL (SIRDS_DISPLAY_GEN_LABELS) #define SIRDS_DO (SIRDS_DISPLAY_DATA_LABELS+SIRDS_DISPLAY_DATA_OFFSET) #define SIRDS_IO (SIRDS_DISPLAY_IMAGE_LABELS+SIRDS_DISPLAY_IMAGE_OFFSET) #define SIRDS_GO (SIRDS_DISPLAY_GEN_LABELS+SIRDS_DISPLAY_GEN_OFFSET) int GetZ(ZDATA *data, int row, int col, int def) { if( !InBounds(0, row, data->rows) ) return(def); if( !InBounds(0, col, data->cols) ) return(def); return(data->data[row][col]); } int GenerateSIRDS(SIRDS *s) { IMAGE *image; SIRDSDATA *sd; SIRDSIMAGE *si; SIRDSGEN *sg; int drow, dcol; int irow, icol; int irows, icols; int lPix, rPix; int dColMin, dColMax; int dRowMin, dRowMax; int pix, rpt; int *l_eye, *r_eye, *strip; int dataZ; int display; double base, height, dl, dr; double dppcmx, dppcmy; double ippcmx, ippcmy; double dist; double dcenterx, dcentery; double icenterx, icentery; UBYTE gray; COLORTRIPLET *c; image = s->image; sd = s->sd; si = s->si; sg = s->sg; icols = si->PixelsX; irows = si->PixelsY; dppcmx = sd->PointsX/sd->SizeX; dppcmy = sd->PointsY/sd->SizeY; ippcmx = si->PixelsX/si->SizeX; ippcmy = si->PixelsY/si->SizeY; gotoxy(50, 1); printf("PROGRESS MAP - ESC to turn"); display = 0; gotoxy(65, 1); if(display) printf("ESC to turn OFF"); else printf("ESC to turn ON "); gotoxy(1, 2); printf("Physical Scaling Factors\n"); printf("------------------------\n"); printf(" Horz Data Points per cm: %g\n", dppcmx); printf(" Vert Data Points per cm: %g\n", dppcmy); printf(" Horz Image Pixels per cm: %g\n", ippcmx); printf(" Vert Image Pixels per cm: %g\n", ippcmy); printf("\n"); // Determine picture coordinates directly below eye center (cm) dcenterx = (sd->SizeX)*(0.5-sg->eye_cxd); dcentery = (sd->SizeY)*(0.5-sg->eye_cyd); icenterx = (si->SizeX)*(0.5-sg->eye_cxi); icentery = (si->SizeY)*(0.5-sg->eye_cyi); dcol = (int) (dcenterx*dppcmx); drow = (int) (dcentery*dppcmy); icol = (int) (icenterx*ippcmx); irow = (int) (icentery*ippcmy); printf("Eye Center information\n"); printf("----------------------\n"); printf(" Center over Data at\n"); printf(" (%g, %g) cm <%i,%i> pixels\n", dcenterx, dcentery, dcol, drow); printf(" Center over Image at\n"); printf(" (%g, %g) cm <%i,%i> pixels\n", icenterx, icentery, icol, irow); printf("\n"); // Extreme Left Data Position visible by Right Eye dist = (0.0 - (icenterx+0.5*sg->eye_sep)); // r eye to image edge dist *= (1.0 + sg->depth); // r eye to data edge dist += 0.5*sg->eye_sep; // eye center to data edge dColMin = (int) ((dist + dcenterx)*dppcmx); // Convert to Col Index // Extreme Right Data Position visible by Left Eye dist = (si->SizeX - (icenterx-0.5*sg->eye_sep)); // l eye to image edge dist *= (1.0 + sg->depth); // l eye to data edge dist += -0.5*sg->eye_sep; // eye center to data edge dColMax = (int) ((dist + dcenterx)*dppcmx); // Convert to Col Index // Extreme Lower Data Position visible dist = (0.0 - icentery); // eye to image edge dist *= (1.0 + sg->depth); // eye to data edge dRowMin = (int) ((dist + dcentery)*dppcmy); // Convert to Row Index // Extreme Upper Data Position visible dist = (si->SizeY - icentery); // eye to image edge dist *= (1.0 + sg->depth); // eye to data edge dRowMax = (int) ((dist + dcentery)*dppcmy); // Convert to Row Index printf("Viewable Data Space extents\n"); printf("----------------------------\n"); printf(" Extreme left Data: %i\n", dColMin); printf(" Extreme right Data: %i\n", dColMax); printf(" Extreme lower Data: %i\n", dRowMin); printf(" Extreme upper Data: %i\n", dRowMax); printf("\n"); FillIMAGE(image, 0, 0, 0); l_eye = malloc(si->PixelsX*sizeof(int)); r_eye = malloc(si->PixelsX*sizeof(int)); strip = malloc(si->PixelsX*sizeof(int)); c = malloc(si->PixelsX*sizeof(COLORTRIPLET)); for(irow=0; irowdepth); // eye to data row drow = (int) ((dist + dcentery)*dppcmy); // Convert to Row Index gotoxy(2,24); printf("Starting Row: %3i (Sees Data Row: %3i)\n", irow, drow); // Initialize an array for each eye to all -1 indicating empty. // Initializing Strip for(icol = 0; icol < si->PixelsX; icol++) { strip[icol] = l_eye[icol] = r_eye[icol] = -1; } // Starting at left edge of data, determine which image pixel is in // line with each data point and store in array l_eye. // Calculating Constraints for(dcol = dColMin; dcol < dColMax; dcol++) { dataZ = GetZ(sd->data, drow, dcol, sg->null_ht); // Plot Progress Map // Check to see if display is to be toggled if(kbhit()) { if(27 == getch()) // ESC key hit { display = (display+1)%2; gotoxy(65, 1); if(display) printf("ESC to turn OFF"); else printf("ESC to turn ON "); } } if(display) { gotoxy( 40 + (int)( (39L*(dcol-dColMin))/(dColMax-dColMin) ), 23 - (int)( (20L*(drow-dRowMin))/(dRowMax-dRowMin) ) ); switch((int)(dataZ/50)) { case 0: putch('.'); break; case 1: putch('~'); break; case 2: putch('+'); break; case 3: putch('x'); break; case 4: putch('X'); break; case 5: putch('#'); break; } } // Calculate base of Triange for left eye (in pixels) base = (si->PixelsX)*(0.5+sg->eye_cxi) - (sg->eye_sep*si->PixelsX/si->SizeX/2.0) - dcol; // Calculate height of small triangle (below image plane) height = sg->distance*sg->depth*(255 - dataZ*sg->relief)/255; // Calculate image intersection points dl = base * height / (sg->distance + height); dr = (base + sg->eye_sep*si->PixelsX/si->SizeX) * (height / (sg->distance + height)); // Image Pixels that dcol is viewed through for each eye lPix = (int) (dcol + dl); rPix = (int) (dcol + dr); // Record pixel locations if higher than existing points. if(InBounds(0, lPix, si->PixelsX)) { // Check if this is the initial data visible at this pixel. if(0 > l_eye[lPix]) l_eye[lPix] = dcol; // Check if this is higher than previous data at this pixel. if( dataZ > GetZ(sd->data, drow, l_eye[lPix], sg->null_ht) ) l_eye[lPix] = dcol; } if(InBounds(0, rPix, si->PixelsX)) { // Check if this is the initial data visible at this pixel. if(0 > r_eye[rPix]) r_eye[rPix] = dcol; // Check if this is higher than previous data at this pixel. if( dataZ > GetZ(sd->data, drow, r_eye[rPix], sg->null_ht) ) r_eye[rPix] = dcol; } } // Applying Constraints for(icol = 0; icol < icols; icol++) { if(0 > strip[icol]) // Pixel has not been colored previously { strip[icol] = (UBYTE) rand_int(0,255); SetCTr(&c[icol], (UBYTE) rand_int(0, 255) ) ; SetCTg(&c[icol], (UBYTE) rand_int(0, 255) ) ; SetCTb(&c[icol], (UBYTE) rand_int(0, 255) ) ; } pix = l_eye[icol]; if(!(0>pix)) // Pixel has a left eye target { rpt = icol; while(rpt < si->PixelsX) { while( (rpt < si->PixelsX) && (r_eye[rpt] != pix) ) rpt++; if(rpt < si->PixelsX) { strip[rpt] = strip[icol]; c[rpt] = c[icol]; } rpt++; } } } // Updating Image for(icol=0; icolColor) SetCT(GetIMAGE_Pixel(image, irow, icol), GetCTr(&c[icol]), GetCTg(&c[icol]), GetCTb(&c[icol])); else SetCT(GetIMAGE_Pixel(image, irow, icol), gray, gray, gray); } } // Add Fusion Aids icol = (int) (icenterx*ippcmx); dcol = ippcmx*(((sg->eye_sep)/(1 + 1.0/sg->depth))/2); for(irow = 0; irow < irows; irow++) { SetCT(GetIMAGE_Pixel(image, irow, icol+dcol), 0, 0, 0); SetCT(GetIMAGE_Pixel(image, irow, icol-dcol), 0, 0, 0); } free(l_eye); free(r_eye); free(strip); free(c); return(TRUE); } int MakeDataBMP(SIRDS *s) { IMAGE *image; BMP *bmp; int row, col; int rows, cols; UBYTE gray; rows = s->sd->PointsY; cols = s->sd->PointsX; image = NewIMAGE(rows, cols, 24); for(row = 0; row < rows; row++) for(col = 0; col < cols; col++) { gray = GetZ(s->sd->data, row, col, s->sg->null_ht); SetCT(GetIMAGE_Pixel(image, row, col), gray, gray, gray); } bmp = GenerateBMPfromIMAGE(NULL, image); ExportBMP(bmp, "DataDump.BMP"); FreeIMAGE(image); FreeBMP(bmp); return(0); } #define SIRDSdotH #endif