/* image_toys.c * a few little routines for the manipulation of images, like * rotation, inversion, etc. * * miantained by g.winter * * 8th nov 2001 * * in this instance, to keep things clear, i have defined a three byte * rgb pixel as a triple - this will make matters simpler with all of the * manipulations. this should be extended to the jpeg writing functions * so this heralds a likely change in mosflm_jpeg.c */ #include #include typedef struct triple{ char r; char g; char b; } triple; /* declarations so that things don't complain */ int flip_image_v_axis( triple *image, int x, int y ); int flip_image_h_axis( triple *image, int x, int y ); int flip_image_d1_axis( triple *image, int x, int y ); int flip_image_d2_axis( triple *image, int x, int y ); /* this could be depricated in favour of flip_image_v_axis ... */ int image_swap_x( triple *image, int x, int y ) { int i, j; triple temp; for(i = 0; i < y; i++) { for(j = 0; j < x; j++) { temp = image[i * x + j]; image[i * x + j] = image[i * x + x - j - 1]; image[i * x + x - j - 1] = temp; } } return 0; } int image_swap_y( triple *image, int x, int y ) { int i, j; triple temp; for(i = 0; i < y; i++) { for(j = 0; j < x; j++) { temp = image[i * x + j]; image[i * x + j] = image[(x - i - 1) * x + j]; image[(x - i - 1) * x + j] = temp; } } return 0; } int image_rotate_acw( triple *image, int x, int y, int theta ) { int i, j, xlim, ylim; triple temp; if(theta == 0) { return 0; } if(x == y) { /* we have a nice square image */ if((x % 2) == 0) { xlim = x / 2; } else { xlim = (x + 1) / 2; } if((y % 2) == 0) { ylim = y / 2; } else { ylim = (y - 1) / 2; } if(theta == 90) { for(i = 0; i < ylim; i++) { for(j = 0; j < xlim; j++) { temp = image[i * x + j]; image[i * x + j] = image[j * x + (y - i - 1)]; image[j * x + (y - i - 1)] = image[(y - i - 1) * x + (x - j - 1)]; image[(y - i - 1) * x + (x - j - 1)] = image[(x - j - 1) * x + i]; image[(x - j - 1) * x + i] = temp; } } } else if(theta == 180){ for(i = 0; i < ylim; i++) { for(j = 0; j < xlim; j++) { temp = image[i * x + j]; image[i * x + j] = image[(x - j - 1) * x + i]; image[(x - j - 1) * x + i] = temp; temp = image[(y - i - 1) * x + (x - j - 1)]; image[(y - i - 1) * x + (x - j - 1)] = image[j * x + (y - i - 1)]; image[j * x + (y - i - 1)] = temp; } } } else if(theta == 270) { for(i = 0; i < ylim; i++) { for(j = 0; j < xlim; j++) { temp = image[i * x + j]; image[i * x + j] = image[(x - j - 1) * x + i]; image[(x - j - 1) * x + i] = image[(y - i - 1) * x + (x - j - 1)]; image[(y - i - 1) * x + (x - j - 1)] = image[j * x + (y - i - 1)]; image[j * x + (y - i - 1)] = temp; } } } else { return -1; } } else { /* matters are a little more complicated, as the image isn't square */ /* fortunately this won't be needed frequently, so no worries */ /* in particular, as these are a little more complicated I'll construct them from reflections (elementary group theory) */ if(theta == 180) { flip_image_v_axis(image, x, y); flip_image_h_axis(image, y, x); } else if(theta == 90) { flip_image_v_axis(image, x, y); flip_image_d1_axis(image, x, y); } else if(theta == 270) { flip_image_d1_axis(image, x, y); flip_image_v_axis(image, x, y); } else { return -1; } } return 0; } /* flips - these are to construct rotations from reflections... original flip_v flip_h 012 210 678 345 543 345 678 876 012 flip_d1 flip_d2 036 852 147 741 258 630 where the original data is stored in a linear array 012345678 for square arrays these are all performed without working memory, for others working memory is required for the flips (i think...) */ int flip_image_v_axis( triple *image, int x, int y ) { int i, j; triple temp; for(i = 0; i < y; i++) { for(j = 0; j < x; j++) { temp = image[i * x + j]; image[i * x + j] = image[i * x + (x - j - 1)]; image[i * x + (x - j - 1)] = temp; } } return 0; } int flip_image_h_axis( triple *image, int x, int y ) { int i, j; triple temp; for(i = 0; i < y; i++) { for(j = 0; j < x; j++) { temp = image[i * x + j]; image[i * x + j] = image[(y - i - 1) * x + j]; image[(y - i - 1) * x + j] = temp; } } return 0; } int flip_image_d1_axis( triple *image, int x, int y ) { int i, j; triple *working; triple temp; if(x == y) { /* just have a square image to transpose */ for(i = 0; i < y; i++) { for(j = 0; j < i; j++) { temp = image[i * x + j]; image[i * x + j] = image[j * y + x]; image[j * y + x] = temp; } } } else { working = (triple *) malloc (sizeof(triple) * x * y); memcpy(working, image, sizeof(triple) * x * y); for(i = 0; i < y; i++) { for(j = 0; j < x; j++) { image[i * x + j] = working[j * y + i]; } } free(working); } return 0; } int flip_image_d2_axis( triple *image, int x, int y ) { int i, j; triple *working; triple temp; if(x == y) { /* just have a square image to transpose */ for(i = 0; i < y; i++) { for(j = 0; j < (y - i - 1); j++) { temp = image[i * x + j]; image[i * x + j] = image[(x * y - 1) - (j * y + i)]; image[(x * y - 1) - (j * y + i)] = temp; } } } else { working = (triple *) malloc (sizeof(triple) * x * y); memcpy(working, image, sizeof(triple) * x * y); for(i = 0; i < y; i++) { for(j = 0; j < x; j++) { image[i * x + j] = working[(x * y - 1) - (j * y + i)]; } } free(working); } return 0; }