/*************************************************************************** * Func: affine * * * * Desc: performs an affine transformation on a PPM or PGM image in memory * * and writes out an output file * * Params: buffer - pointer to image in memory * * cols - number of columns in image * * rows - number of rows in image * * fileout - name of output file * * u0, v0, u1, v1, u2, v2 - control points of source * * x0, y0, x1, y1, x2, y2 - control points of destination * ***************************************************************************/ void affine(void *buffer, int cols, int h, int type, char *fileout, double u0, double u1, double u2, double v0, double v1, double v2, double x0, double x1, double x2, double y0, double y1, double y2) { double delx1, dely1, delx2; /* deltas */ double dely2, delx3, dely3; /* deltas */ double a11, a12, a13; /* intermediate coefficients */ double a21, a22, a23; /* intermediate coefficients */ double a31, a32; /* intermediate coefficients (a33 = 1.0) */ int u, v; /* indices into source image */ int i, j; /* loop variables */ float x, y; /* normalized indices */ double floatu, floatv; /* floating point equivalents of u and v */ double detU, detT; /* U and T determinates */ image_ptr line_buff; /* line buffer for PGM file */ pixel_ptr pixel_buff; /* line buffer for PPM file */ image_ptr source; /* pointer to PGM file in memory */ pixel_ptr pixel_source; /* pointer to PPM file in memory */ unsigned long sourcebase; /* index into source image */ FILE *fp; /* file pointer to output file */ /* image specific (gray vs. color) customizations */ switch(type) { case 5: source = (image_ptr) buffer; line_buff = (image_ptr) malloc(cols); break; case 6: pixel_source = (pixel_ptr) buffer; pixel_buff = (pixel_ptr) malloc(cols * sizeof(pixel_ptr)); break; default: printf("Bad type value\n"); exit(1); break; } /* open output file */ if((fp=fopen(fileout, "wb")) == NULL) { printf("Unable to open %s for output\n", fileout); exit(1); } /* write out header */ fprintf(fp, "P%d\n%d %d\n255\n", type, cols, h); /* compute coefficients */ detU = u0 * (v1-v2) - v0 * (u1-u2) + (u1*v2 - u2*v1); a11 = detU * ((v1-v2)*x0 + (v2-v0)*x1 + (v0-v1)*x2); a21 = detU * ((u2-u1)*x0 + (u0-u2)*x1 + (u1-u0)*x2); a31 = detU * ((u1*v2-u2*v1)*x0 + (u2*v0-u0*v2)*x1 + (u2*v1-u1*v0)*x2); a12 = detU * ((v1-v2)*y0 + (v2-v0)*y1 + (v0-v1)*y2); a22 = detU * ((u2-u1)*y0 + (u0-u2)*y1 + (u1-u0)*y2); a32 = detU * ((u1*v2-u2*v1)*y0 + (u2*v0-u0*v2)*y1 + (u2*v1-u1*v0)*y2); detT = 1.0 / (a11*a22 - a21*a12); for(i=0; i=cols) u=cols-1; if(u<0) u=0; if(v>=h) v=h-1; if(v<0) v=0; /* compute source address */ sourcebase = (unsigned long)cols * v + u; if(type == 6) { pixel_buff[j].r = pixel_source[sourcebase].r; pixel_buff[j].g = pixel_source[sourcebase].g; pixel_buff[j].b = pixel_source[sourcebase].b; } else line_buff[j] = source[sourcebase]; } if(type == 6) fwrite(pixel_buff, sizeof(pixel), cols, fp); else fwrite(line_buff, 1, cols, fp); } fclose(fp); }