Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include "assert.h"
- #include "a2methods.h"
- #include "a2plain.h"
- #include "a2blocked.h"
- #include "pnm.h"
- #include "mem.h"
- void rotate_90(int i, int j, A2Methods_Array2 array2, A2Methods_Object *ptr, void *cl);
- void rotate_180(int i, int j, A2Methods_Array2 array2, A2Methods_Object *ptr, void *cl);
- void flip_horizontal(int i, int j, A2Methods_Array2 array2, A2Methods_Object *ptr, void *cl);
- void flip_vertical(int i, int j, A2Methods_Array2 array2, A2Methods_Object *ptr, void *cl);
- void transposition(int i, int j, A2Methods_Array2 array2, A2Methods_Object *ptr, void *cl);
- void A2_blocked_print(A2Methods_Array2 array2);
- void A2_plain_print(A2Methods_Array2 array2);
- int const HORIZONTAL = 5;
- int const VERTICAL = 6;
- int main(int argc, char *argv[])
- {
- int rotation = 0;
- int flip = 0;
- int transpose = 0;
- // A2Methods_T methods = array2_methods_plain; // default to UArray2 methods
- A2Methods_T methods = array2_methods_blocked; // default to UArray2 methods
- assert(methods);
- A2Methods_mapfun *map = methods->map_default; // default to best map
- assert(map);
- #define SET_METHODS(METHODS, MAP, WHAT) do { \
- methods = (METHODS); \
- assert(methods); \
- map = methods->MAP; \
- if (!map) { \
- fprintf(stderr, "%s does not support " WHAT "mapping\n", argv[0]); \
- exit(1); \
- } \
- } while(0)
- int i;
- for (i = 1; i < argc; i++) {
- if (!strcmp(argv[i], "-row-major")) {
- SET_METHODS(array2_methods_plain, map_row_major, "row-major");
- } else if (!strcmp(argv[i], "-col-major")) {
- SET_METHODS(array2_methods_plain, map_col_major, "column-major");
- } else if (!strcmp(argv[i], "-block-major")) {
- SET_METHODS(array2_methods_blocked, map_block_major, "block-major");
- } else if (!strcmp(argv[i], "-rotate")) {
- assert(i + 1 < argc);
- char *endptr;
- rotation = strtol(argv[++i], &endptr, 10);
- assert(*endptr == '\0'); // parsed all correctly
- assert(rotation == 0 || rotation == 90
- || rotation == 180 || rotation == 270);
- } else if (!strcmp(argv[i], "-flip")) {
- printf("\nReached flip\n");
- assert(i + 1 < argc);
- if (!strcmp(argv[i+1], "horizontal")) flip = HORIZONTAL;
- else if (!strcmp(argv[i+1], "vertical")) flip = VERTICAL;
- else {
- fprintf(stderr, "%s: unknown flip option '%s'\n", argv[0], argv[i+1]);
- fprintf(stderr, "Usage: %s [-rotate <angle> or -flip <horizontal,vertical>] "
- "[-{row,col,block}-major] [filename]\n", argv[0]);
- exit(1);
- }
- } else if (!strcmp(argv[i], "-transpose")) {
- transpose = 1;
- } else if (*argv[i] == '-') {
- fprintf(stderr, "%s: unknown option '%s'\n", argv[0], argv[i]);
- exit(1);
- } else if (argc - i > 3) {
- fprintf(stderr, "Usage: %s [-rotate <angle> or -flip <horizontal,vertical>] "
- "[-{row,col,block}-major] [filename]\n", argv[0]);
- exit(1);
- } else {
- break;
- }
- }
- //open file to read original_pixmap
- FILE *fp = fopen(argv[argc-1], "r");
- //open file to read rotated_pixmap copy
- FILE *copy = fopen(argv[argc-1], "r");
- //open file to write transformed ppm image
- FILE *write = fopen("transformation_result.ppm", "w");
- //read the ppm image into both Pnm_ppm objects
- Pnm_ppm pixmap_original = Pnm_ppmread(fp, methods);
- Pnm_ppm pixmap_transformed = Pnm_ppmread(copy, methods);
- //close files now that they have been stored in pixmaps
- fclose(fp);
- fclose(copy);
- printf("\nWidth: %d\n", pixmap_original->methods->width(pixmap_original->pixels));
- printf("\nHeight: %d\n", pixmap_original->methods->height(pixmap_original->pixels));
- printf("\nBlocksize: %d\n", pixmap_original->methods->blocksize(pixmap_original->pixels));
- // A2_plain_print(pixmap_original->pixels);
- //Perform rotation transformations
- if(rotation == 90) pixmap_original->methods->map_default(pixmap_original->pixels, rotate_90, &pixmap_transformed->pixels);
- if(rotation == 180) pixmap_original->methods->map_default(pixmap_original->pixels, rotate_180, &pixmap_transformed->pixels);
- if(rotation == 270)
- {
- //Read into another Pnm_ppm object that will be used to perform the 180 degree rotation
- FILE *copy_180 = fopen(argv[argc-1], "r");
- Pnm_ppm pixmap_180 = Pnm_ppmread(copy_180, methods);
- //Preform a 180 degree rotation on pixmap_180
- pixmap_original->methods->map_default(pixmap_original->pixels, rotate_180, &pixmap_180->pixels);
- //Perform 90 degree rotation on pixmap_180
- pixmap_original->methods->map_default(pixmap_180->pixels, rotate_90, &pixmap_transformed->pixels);
- fclose(copy_180);
- }
- if(flip == HORIZONTAL) pixmap_original->methods->map_default(pixmap_original->pixels, flip_horizontal, &pixmap_transformed->pixels);
- if(flip == VERTICAL) pixmap_original->methods->map_default(pixmap_original->pixels, flip_vertical, &pixmap_transformed->pixels);
- if(transpose) pixmap_original->methods->map_default(pixmap_original->pixels, transposition, &pixmap_transformed->pixels);
- // printf("\nOriginal: \n");
- // A2_blocked_print(pixmap_original->pixels);
- // printf("\nRotated: \n");
- // A2_blocked_print(pixmap_90->pixels);
- // A2_blocked_print(pixmap_transformed->pixels);
- //If none of the transformation conditionals were flipped previously, -rotate 0 has been provided
- //therefore pixmap_transformed remains unchanged. Otherwise, transformed image written to file.
- Pnm_ppmwrite(write, pixmap_original);
- // Pnm_ppmwrite(write, pixmap_transformed);
- //close file containing transformed image
- fclose(write);
- exit(0);
- }
- void rotate_180(int i, int j, A2Methods_Array2 array2, A2Methods_Object *ptr, void *cl)
- {
- //quiet the compiler
- cl = cl;
- int height = array2_methods_blocked->height(array2);
- int width = array2_methods_blocked->width(array2);
- int blocksize = array2_methods_blocked->blocksize(array2);
- int height_overflow = width % blocksize;
- int width_overflow = height % blocksize;
- //if there is block overflow and the dimensions are unequal, dimension will be non-zero and trigger conditional
- int dimension_offset = (height_overflow < width_overflow) ? (width_overflow - height_overflow) : height_overflow - width_overflow;
- //define new i and j positions of the pixel post rotation
- int new_i_pos = width - i - 1;
- int new_j_pos = height - j - 1;
- // if the dimensions are unequal, adjust new_i/j positions accordingly
- if(dimension_offset)
- {
- if(height_overflow > width_overflow)
- {
- new_i_pos += dimension_offset;
- new_j_pos -= dimension_offset;
- }
- else
- {
- new_i_pos -= dimension_offset;
- new_j_pos += dimension_offset;
- }
- }
- //retrieve the value of the pixel from array2b (Array2b_T prior to rotation)
- Pnm_rgb new_rgb = array2_methods_blocked->at(array2, new_i_pos, new_j_pos);
- //Define the A2_Methods_object ptr to be of type Pnm_rgb to allow for reassignment
- Pnm_rgb original_rgb = ptr;
- //store the new rgb values within the Pnm_rgb struct being pointed to
- original_rgb->red = new_rgb->red;
- original_rgb->blue = new_rgb->blue;
- original_rgb->green = new_rgb->green;
- }
- void rotate_90(int i, int j, A2Methods_Array2 array2, A2Methods_Object *ptr, void *cl)
- {
- //quiet the compiler
- cl = cl;
- //define new i and j positions of the pixel post rotation
- int new_i_pos = array2_methods_blocked->height(array2) - j - 1;
- int new_j_pos = i;
- //retrieve the value of the pixel from array2b (Array2b_T prior to rotation)
- Pnm_rgb new_rgb = array2_methods_blocked->at(array2, new_i_pos, new_j_pos);
- //Define the A2_Methods_object ptr to be of type Pnm_rgb to allow for reassignment
- Pnm_rgb original_rgb = ptr;
- //store the new rgb values within the Pnm_rgb struct being pointed to
- original_rgb->red = new_rgb->red;
- original_rgb->blue = new_rgb->blue;
- original_rgb->green = new_rgb->green;
- }
- void flip_horizontal(int i, int j, A2Methods_Array2 array2, A2Methods_Object *ptr, void *cl)
- {
- //quiet the compiler
- cl = cl;
- //define new i and j positions of the pixel post rotation
- int new_i_pos = i;
- int new_j_pos = array2_methods_blocked->width(array2) - j - 1;
- //retrieve the value of the pixel from array2b (Array2b_T prior to rotation)
- Pnm_rgb new_rgb = array2_methods_blocked->at(array2, new_i_pos, new_j_pos);
- //Define the A2_Methods_object ptr to be of type Pnm_rgb to allow for reassignment
- Pnm_rgb original_rgb = ptr;
- //store the new rgb values within the Pnm_rgb struct being pointed to
- original_rgb->red = new_rgb->red;
- original_rgb->blue = new_rgb->blue;
- original_rgb->green = new_rgb->green;
- }
- void flip_vertical(int i, int j, A2Methods_Array2 array2, A2Methods_Object *ptr, void *cl)
- {
- //quiet the compiler
- cl = cl;
- //define new i and j positions of the pixel post rotation
- int new_i_pos = array2_methods_blocked->width(array2) - i - 1;
- int new_j_pos = j;
- //retrieve the value of the pixel from array2b (Array2b_T prior to rotation)
- Pnm_rgb new_rgb = array2_methods_blocked->at(array2, new_i_pos, new_j_pos);
- //Define the A2_Methods_object ptr to be of type Pnm_rgb to allow for reassignment
- Pnm_rgb original_rgb = ptr;
- //store the new rgb values within the Pnm_rgb struct being pointed to
- original_rgb->red = new_rgb->red;
- original_rgb->blue = new_rgb->blue;
- original_rgb->green = new_rgb->green;
- }
- void transposition(int i, int j, A2Methods_Array2 array2, A2Methods_Object *ptr, void *cl)
- {
- //quiet the compiler
- cl = cl;
- //define new i and j positions of the pixel post rotation
- int new_i_pos = j;
- int new_j_pos = i;
- //retrieve the value of the pixel from array2b (Array2b_T prior to rotation)
- Pnm_rgb new_rgb = array2_methods_blocked->at(array2, new_i_pos, new_j_pos);
- //Define the A2_Methods_object ptr to be of type Pnm_rgb to allow for reassignment
- Pnm_rgb original_rgb = ptr;
- //store the new rgb values within the Pnm_rgb struct being pointed to
- original_rgb->red = new_rgb->red;
- original_rgb->blue = new_rgb->blue;
- original_rgb->green = new_rgb->green;
- }
- void A2_plain_print(A2Methods_Array2 array2)
- {
- int cols = array2_methods_plain->width(array2);
- int rows = array2_methods_plain->height(array2);
- printf("\n");
- for(int i = 0; i < rows; i++)
- {
- for(int j = 0; j < cols; j++)
- {
- if(j > 0) printf(" ");
- Pnm_rgb rgb = array2_methods_plain->at(array2, i, j);
- printf(" %d %d %d", rgb->red, rgb->green, rgb->blue);
- }
- printf("\n");
- }
- printf("\n");
- }
- void A2_blocked_print(A2Methods_Array2 array2)
- {
- int height = array2_methods_blocked->height(array2);
- int width = array2_methods_blocked->width(array2);
- int blocksize = array2_methods_blocked->blocksize(array2);
- printf("\n");
- for(int i = 0; i < height; i++)
- {
- //Print the column indices
- if(i == 0)
- {
- for(int k = 0; k < width; k++)
- {
- if(k == 0) printf(" ");
- if(k % blocksize == 0 && k != 0) printf(" %d ", k);
- else printf("%d ", k);
- }
- }
- //separate blocks by a new lines
- if (i % blocksize == 0)
- {
- printf("\n\n%d| ", i);
- }
- //print the current row index
- if (i != 0 && i % blocksize != 0)
- {
- printf("\n%d| ", i);
- }
- //print each of the blocks and their cells
- for(int j = 0 ; j < width; j++)
- {
- //get the current cell
- // void *cell = array2_methods_blocked->at(array2, i, j);
- Pnm_rgb rgb = array2_methods_blocked->at(array2, i, j);
- // printf(" %d %d %d", rgb->red, rgb->green, rgb->blue);
- //print whitespace to seperate blocks
- if(j % blocksize == 0 && j > 0)
- {
- printf(" %d %d %d", rgb->red, rgb->green, rgb->blue);
- // printf(" %d ", *(int*)cell);
- }
- else
- {
- //account for single digit cell index spacing
- if(rgb->blue > 10) printf("%d %d %d ", rgb->red, rgb->green, rgb->blue);
- else if(rgb->red > 10) printf("%d %d %d ", rgb->red, rgb->green, rgb->blue);
- else printf("%d %d %d ", rgb->red, rgb->green, rgb->blue);
- }
- }
- }
- printf("\n");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement