/*---------------------------------------------------------------------------*/ /* Program: move_image. */ /* */ /* Purpose: This program supports the translation, rotation and scaling */ /* of KUIM format images. */ /* */ /* Author: John Gauch, Edu Metz */ /* */ /* Date: October 26, 1994 */ /* */ /* Note: Copyright (C) The University of Kansas, 1994 */ /*---------------------------------------------------------------------------*/ #include #include char Name1[50]; char Name2[50]; IM_TYPE *Image1; IM_TYPE *Image2; int PixType, Xdim, Ydim, Zdim, DimCnt; /* Program variables */ float Angle = 0.0; float Xscale = 1.0; float Yscale = 1.0; float Xtrans = 0.0; float Ytrans = 0.0; float SinAngle, CosAngle, X, Y; float w1, w2, w3, w4; int x, y, Xhalf, Yhalf; int Debug = FALSE; /*---------------------------------------------------------------------------*/ /* Purpose: Translate, rotate and scale Grey images */ /*---------------------------------------------------------------------------*/ void MoveGreyImage() { FLOAT_TYPE **Data1; FLOAT_TYPE **Data2; float v1, v2, v3, v4; Data1 = (FLOAT_TYPE **) im_alloc2D(Image1, FLOAT); im_read(Image1, FLOAT, (char *) &(Data1[0][0])); /* Create output image */ Image2 = im_create(Name2, FLOAT, Xdim, Ydim, Zdim); Data2 = (FLOAT_TYPE **) im_alloc2D(Image2, FLOAT); /* Precalculate rotation angles and scale factor */ Angle = M_PI * Angle / 180; SinAngle = (float) sin((double) Angle); CosAngle = (float) cos((double) Angle); if (Debug == TRUE) printf("angle %f sin %f cos %f\n", Angle, SinAngle, CosAngle); if (Xscale != 0.0) Xscale = 1.0 / Xscale; if (Yscale != 0.0) Yscale = 1.0 / Yscale; /* Perform translation, rotation and scaling */ Yhalf = Ydim / 2; Xhalf = Xdim / 2; for (y = 0; y < Ydim; y++) for (x = 0; x < Xdim; x++) { X = Xscale * ((x - Xhalf) * CosAngle - (y - Yhalf) * SinAngle) + Xhalf - Xtrans; Y = Yscale * ((y - Yhalf) * CosAngle + (x - Xhalf) * SinAngle) + Yhalf - Ytrans; if (Debug == TRUE) printf("X,Y %f %f\n", X, Y); if ((X < 0) || (X >= Xdim) || (Y < 0) || (Y >= Ydim)) Data2[y][x] = 0.0; else { v1 = v2 = v3 = v4 = Data1[(int) Y][(int) X]; if (X + 1 < Xdim) v2 = Data1[(int) Y][(int) X + 1]; if (Y + 1 < Ydim) v3 = Data1[(int) Y + 1][(int) X]; if ((X + 1 < Xdim) && (Y + 1 < Ydim)) v4 = Data1[(int) Y + 1][(int) X + 1]; w4 = (X - (int) X) * (Y - (int) Y); w3 = (1 - X + (int) X) * (Y - (int) Y); w2 = (X - (int) X) * (1 - Y + (int) Y); w1 = (1 - X + (int) X) * (1 - Y + (int) Y); Data2[y][x] = w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4; } } /* Write information to output image */ im_write(Image2, FLOAT, (char *) &(Data2[0][0])); im_free2D((char **) Data1); im_free2D((char **) Data2); } /*---------------------------------------------------------------------------*/ /* Purpose: Translate, rotate and scale Color images */ /*---------------------------------------------------------------------------*/ void MoveColorImage() { COLOR_TYPE **Data1; COLOR_TYPE **Data2; float v1Red, v1Green, v1Blue, v2Red, v2Green, v2Blue; float v3Red, v3Green, v3Blue, v4Red, v4Green, v4Blue; Data1 = (COLOR_TYPE **) im_alloc2D(Image1, COLOR); im_read(Image1, COLOR, (char *) &(Data1[0][0])); /* Create output image */ Image2 = im_create(Name2, COLOR, Xdim, Ydim, Zdim); Data2 = (COLOR_TYPE **) im_alloc2D(Image2, COLOR); /* Precalculate rotation angles and scale factor */ Angle = M_PI * Angle / 180; SinAngle = (float) sin((double) Angle); CosAngle = (float) cos((double) Angle); if (Debug == TRUE) printf("angle %f sin %f cos %f\n", Angle, SinAngle, CosAngle); if (Xscale != 0.0) Xscale = 1.0 / Xscale; if (Yscale != 0.0) Yscale = 1.0 / Yscale; /* Perform translation, rotation and scaling */ Yhalf = Ydim / 2; Xhalf = Xdim / 2; for (y = 0; y < Ydim; y++) for (x = 0; x < Xdim; x++) { X = Xscale * ((x - Xhalf) * CosAngle - (y - Yhalf) * SinAngle) + Xhalf - Xtrans; Y = Yscale * ((y - Yhalf) * CosAngle + (x - Xhalf) * SinAngle) + Yhalf - Ytrans; if (Debug == TRUE) printf("X,Y %f %f\n", X, Y); if ((X < 0) || (X >= Xdim) || (Y < 0) || (Y >= Ydim)) Data2[y][x].r = Data2[y][x].g = Data2[y][x].b = 0; else { v1Red = v2Red = v3Red = v4Red = Data1[(int) Y][(int) X].r; v1Green = v2Green = v3Green = v4Green = Data1[(int) Y][(int) X].g; v1Blue = v2Blue = v3Blue = v4Blue = Data1[(int) Y][(int) X].b; if (X + 1 < Xdim) { v2Red = Data1[(int) Y][(int) X + 1].r; v2Green = Data1[(int) Y][(int) X + 1].g; v2Blue = Data1[(int) Y][(int) X + 1].b; } if (Y + 1 < Ydim) { v3Red = Data1[(int) Y + 1][(int) X].r; v3Green = Data1[(int) Y + 1][(int) X].g; v3Blue = Data1[(int) Y + 1][(int) X].b; } if ((X + 1 < Xdim) && (Y + 1 < Ydim)) { v4Red = Data1[(int) Y + 1][(int) X + 1].r; v4Green = Data1[(int) Y + 1][(int) X + 1].g; v4Blue = Data1[(int) Y + 1][(int) X + 1].b; } w4 = (X - (int) X) * (Y - (int) Y); w3 = (1 - X + (int) X) * (Y - (int) Y); w2 = (X - (int) X) * (1 - Y + (int) Y); w1 = (1 - X + (int) X) * (1 - Y + (int) Y); Data2[y][x].r = (unsigned char) (w1 * v1Red + w2 * v2Red + w3 * v3Red + w4 * v4Red); Data2[y][x].g = (unsigned char) (w1 * v1Green + w2 * v2Green + w3 * v3Green + w4 * v4Green); Data2[y][x].b = (unsigned char) (w1 * v1Blue + w2 * v2Blue + w3 * v3Blue + w4 * v4Blue); } } /* Write information to output image */ im_write(Image2, COLOR, (char *) &(Data2[0][0])); im_free2D((char **) Data1); im_free2D((char **) Data2); } /*---------------------------------------------------------------------------*/ /* Purpose: This is the main program. */ /*---------------------------------------------------------------------------*/ int main(int argc, char *argv[]) { /* Image variables */ int i = 0; /* Interpret program options */ printf("MOVE_IMAGE Program - KUIM Version 2.0\n\n"); while ((++i < argc) && (argv[i][0] == '-')) switch (argv[i][1]) { case 's': if (sscanf(argv[++i], "%f", &Xscale) == 0) Error("Can not get scale factor"); if (sscanf(argv[++i], "%f", &Yscale) == 0) Error("Can not get scale factor"); break; case 'R': if (sscanf(argv[++i], "%f", &Angle) == 0) Error("Can not get rotation angle"); Angle += (float) (rand() % 360); printf("angle %f\n", Angle); break; case 'r': if (sscanf(argv[++i], "%f", &Angle) == 0) Error("Can not get rotation angle"); break; case 't': if (sscanf(argv[++i], "%f", &Xtrans) == 0) Error("Can not get X translation factor"); if (sscanf(argv[++i], "%f", &Ytrans) == 0) Error("Can not get Y translation factor"); break; case 'd': Debug = TRUE; break; default: Error("Invalid option encountered"); break; } /* Check number of file names */ if (argc - i != 2) { fprintf(stderr, "Usage: move_image [options] infile outfile\n"); fprintf(stderr, " [-d] Print debugging information\n"); fprintf(stderr, " [-r #] Rotation angle\n"); fprintf(stderr, " [-s # #] Scaling factor in X and Y\n"); fprintf(stderr, " [-t # #] Translation factors in X and Y\n"); exit(1); } /* Get image file names from argument list */ if (sscanf(argv[i++], "%s", Name1) == 0) Error("Could not get input file name"); if (sscanf(argv[i++], "%s", Name2) == 0) Error("Could not get output file name"); /* Read input image */ Image1 = im_open(Name1, &PixType, &Xdim, &Ydim, &Zdim, &DimCnt); if (DimCnt != 2) Error("Can not process 1D or 3D images"); if (PixType == COLOR || PixType == PSEUDO || PixType == JPEG_RGB) MoveColorImage(); else MoveGreyImage(); return (0); }