Advertisement
Guest User

ppmtrans.c

a guest
Oct 20th, 2019
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.77 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4.  
  5. #include "assert.h"
  6. #include "a2methods.h"
  7. #include "a2plain.h"
  8. #include "a2blocked.h"
  9. #include "pnm.h"
  10. #include "mem.h"
  11.  
  12. void rotate_90(int i, int j, A2Methods_Array2 array2, A2Methods_Object *ptr, void *cl);
  13. void rotate_180(int i, int j, A2Methods_Array2 array2, A2Methods_Object *ptr, void *cl);
  14. void flip_horizontal(int i, int j, A2Methods_Array2 array2, A2Methods_Object *ptr, void *cl);
  15. void flip_vertical(int i, int j, A2Methods_Array2 array2, A2Methods_Object *ptr, void *cl);
  16. void transposition(int i, int j, A2Methods_Array2 array2, A2Methods_Object *ptr, void *cl);
  17. void A2_blocked_print(A2Methods_Array2 array2);
  18. void A2_plain_print(A2Methods_Array2 array2);
  19.  
  20. int const HORIZONTAL = 5;
  21. int const VERTICAL = 6;
  22.  
  23. int main(int argc, char *argv[])
  24. {
  25.  
  26. int rotation = 0;
  27. int flip = 0;
  28. int transpose = 0;
  29.  
  30. // A2Methods_T methods = array2_methods_plain; // default to UArray2 methods
  31. A2Methods_T methods = array2_methods_blocked; // default to UArray2 methods
  32.  
  33. assert(methods);
  34. A2Methods_mapfun *map = methods->map_default; // default to best map
  35. assert(map);
  36. #define SET_METHODS(METHODS, MAP, WHAT) do { \
  37. methods = (METHODS); \
  38. assert(methods); \
  39. map = methods->MAP; \
  40. if (!map) { \
  41. fprintf(stderr, "%s does not support " WHAT "mapping\n", argv[0]); \
  42. exit(1); \
  43. } \
  44. } while(0)
  45.  
  46. int i;
  47. for (i = 1; i < argc; i++) {
  48. if (!strcmp(argv[i], "-row-major")) {
  49. SET_METHODS(array2_methods_plain, map_row_major, "row-major");
  50. } else if (!strcmp(argv[i], "-col-major")) {
  51. SET_METHODS(array2_methods_plain, map_col_major, "column-major");
  52. } else if (!strcmp(argv[i], "-block-major")) {
  53. SET_METHODS(array2_methods_blocked, map_block_major, "block-major");
  54. } else if (!strcmp(argv[i], "-rotate")) {
  55. assert(i + 1 < argc);
  56. char *endptr;
  57. rotation = strtol(argv[++i], &endptr, 10);
  58. assert(*endptr == '\0'); // parsed all correctly
  59. assert(rotation == 0 || rotation == 90
  60. || rotation == 180 || rotation == 270);
  61. } else if (!strcmp(argv[i], "-flip")) {
  62. printf("\nReached flip\n");
  63. assert(i + 1 < argc);
  64. if (!strcmp(argv[i+1], "horizontal")) flip = HORIZONTAL;
  65. else if (!strcmp(argv[i+1], "vertical")) flip = VERTICAL;
  66. else {
  67. fprintf(stderr, "%s: unknown flip option '%s'\n", argv[0], argv[i+1]);
  68. fprintf(stderr, "Usage: %s [-rotate <angle> or -flip <horizontal,vertical>] "
  69. "[-{row,col,block}-major] [filename]\n", argv[0]);
  70. exit(1);
  71. }
  72. } else if (!strcmp(argv[i], "-transpose")) {
  73. transpose = 1;
  74. } else if (*argv[i] == '-') {
  75. fprintf(stderr, "%s: unknown option '%s'\n", argv[0], argv[i]);
  76. exit(1);
  77. } else if (argc - i > 3) {
  78. fprintf(stderr, "Usage: %s [-rotate <angle> or -flip <horizontal,vertical>] "
  79. "[-{row,col,block}-major] [filename]\n", argv[0]);
  80. exit(1);
  81. } else {
  82. break;
  83. }
  84. }
  85.  
  86. //open file to read original_pixmap
  87. FILE *fp = fopen(argv[argc-1], "r");
  88. //open file to read rotated_pixmap copy
  89. FILE *copy = fopen(argv[argc-1], "r");
  90. //open file to write transformed ppm image
  91. FILE *write = fopen("transformation_result.ppm", "w");
  92.  
  93. //read the ppm image into both Pnm_ppm objects
  94. Pnm_ppm pixmap_original = Pnm_ppmread(fp, methods);
  95. Pnm_ppm pixmap_transformed = Pnm_ppmread(copy, methods);
  96.  
  97. //close files now that they have been stored in pixmaps
  98. fclose(fp);
  99. fclose(copy);
  100.  
  101. printf("\nWidth: %d\n", pixmap_original->methods->width(pixmap_original->pixels));
  102. printf("\nHeight: %d\n", pixmap_original->methods->height(pixmap_original->pixels));
  103. printf("\nBlocksize: %d\n", pixmap_original->methods->blocksize(pixmap_original->pixels));
  104.  
  105. // A2_plain_print(pixmap_original->pixels);
  106.  
  107. //Perform rotation transformations
  108. if(rotation == 90) pixmap_original->methods->map_default(pixmap_original->pixels, rotate_90, &pixmap_transformed->pixels);
  109. if(rotation == 180) pixmap_original->methods->map_default(pixmap_original->pixels, rotate_180, &pixmap_transformed->pixels);
  110. if(rotation == 270)
  111. {
  112. //Read into another Pnm_ppm object that will be used to perform the 180 degree rotation
  113. FILE *copy_180 = fopen(argv[argc-1], "r");
  114. Pnm_ppm pixmap_180 = Pnm_ppmread(copy_180, methods);
  115. //Preform a 180 degree rotation on pixmap_180
  116. pixmap_original->methods->map_default(pixmap_original->pixels, rotate_180, &pixmap_180->pixels);
  117. //Perform 90 degree rotation on pixmap_180
  118. pixmap_original->methods->map_default(pixmap_180->pixels, rotate_90, &pixmap_transformed->pixels);
  119. fclose(copy_180);
  120.  
  121. }
  122. if(flip == HORIZONTAL) pixmap_original->methods->map_default(pixmap_original->pixels, flip_horizontal, &pixmap_transformed->pixels);
  123. if(flip == VERTICAL) pixmap_original->methods->map_default(pixmap_original->pixels, flip_vertical, &pixmap_transformed->pixels);
  124. if(transpose) pixmap_original->methods->map_default(pixmap_original->pixels, transposition, &pixmap_transformed->pixels);
  125.  
  126. // printf("\nOriginal: \n");
  127. // A2_blocked_print(pixmap_original->pixels);
  128. // printf("\nRotated: \n");
  129. // A2_blocked_print(pixmap_90->pixels);
  130. // A2_blocked_print(pixmap_transformed->pixels);
  131.  
  132. //If none of the transformation conditionals were flipped previously, -rotate 0 has been provided
  133. //therefore pixmap_transformed remains unchanged. Otherwise, transformed image written to file.
  134. Pnm_ppmwrite(write, pixmap_original);
  135. // Pnm_ppmwrite(write, pixmap_transformed);
  136.  
  137. //close file containing transformed image
  138. fclose(write);
  139. exit(0);
  140. }
  141.  
  142. void rotate_180(int i, int j, A2Methods_Array2 array2, A2Methods_Object *ptr, void *cl)
  143. {
  144.  
  145. //quiet the compiler
  146. cl = cl;
  147.  
  148. int height = array2_methods_blocked->height(array2);
  149. int width = array2_methods_blocked->width(array2);
  150. int blocksize = array2_methods_blocked->blocksize(array2);
  151. int height_overflow = width % blocksize;
  152. int width_overflow = height % blocksize;
  153.  
  154.  
  155. //if there is block overflow and the dimensions are unequal, dimension will be non-zero and trigger conditional
  156. int dimension_offset = (height_overflow < width_overflow) ? (width_overflow - height_overflow) : height_overflow - width_overflow;
  157.  
  158. //define new i and j positions of the pixel post rotation
  159. int new_i_pos = width - i - 1;
  160. int new_j_pos = height - j - 1;
  161.  
  162. // if the dimensions are unequal, adjust new_i/j positions accordingly
  163. if(dimension_offset)
  164. {
  165. if(height_overflow > width_overflow)
  166. {
  167. new_i_pos += dimension_offset;
  168. new_j_pos -= dimension_offset;
  169. }
  170. else
  171. {
  172. new_i_pos -= dimension_offset;
  173. new_j_pos += dimension_offset;
  174. }
  175. }
  176.  
  177. //retrieve the value of the pixel from array2b (Array2b_T prior to rotation)
  178. Pnm_rgb new_rgb = array2_methods_blocked->at(array2, new_i_pos, new_j_pos);
  179.  
  180. //Define the A2_Methods_object ptr to be of type Pnm_rgb to allow for reassignment
  181. Pnm_rgb original_rgb = ptr;
  182.  
  183. //store the new rgb values within the Pnm_rgb struct being pointed to
  184. original_rgb->red = new_rgb->red;
  185. original_rgb->blue = new_rgb->blue;
  186. original_rgb->green = new_rgb->green;
  187.  
  188. }
  189.  
  190.  
  191. void rotate_90(int i, int j, A2Methods_Array2 array2, A2Methods_Object *ptr, void *cl)
  192. {
  193.  
  194. //quiet the compiler
  195. cl = cl;
  196.  
  197. //define new i and j positions of the pixel post rotation
  198. int new_i_pos = array2_methods_blocked->height(array2) - j - 1;
  199. int new_j_pos = i;
  200.  
  201. //retrieve the value of the pixel from array2b (Array2b_T prior to rotation)
  202. Pnm_rgb new_rgb = array2_methods_blocked->at(array2, new_i_pos, new_j_pos);
  203.  
  204. //Define the A2_Methods_object ptr to be of type Pnm_rgb to allow for reassignment
  205. Pnm_rgb original_rgb = ptr;
  206.  
  207. //store the new rgb values within the Pnm_rgb struct being pointed to
  208. original_rgb->red = new_rgb->red;
  209. original_rgb->blue = new_rgb->blue;
  210. original_rgb->green = new_rgb->green;
  211. }
  212.  
  213. void flip_horizontal(int i, int j, A2Methods_Array2 array2, A2Methods_Object *ptr, void *cl)
  214. {
  215. //quiet the compiler
  216. cl = cl;
  217.  
  218. //define new i and j positions of the pixel post rotation
  219. int new_i_pos = i;
  220. int new_j_pos = array2_methods_blocked->width(array2) - j - 1;
  221.  
  222. //retrieve the value of the pixel from array2b (Array2b_T prior to rotation)
  223. Pnm_rgb new_rgb = array2_methods_blocked->at(array2, new_i_pos, new_j_pos);
  224.  
  225. //Define the A2_Methods_object ptr to be of type Pnm_rgb to allow for reassignment
  226. Pnm_rgb original_rgb = ptr;
  227.  
  228. //store the new rgb values within the Pnm_rgb struct being pointed to
  229. original_rgb->red = new_rgb->red;
  230. original_rgb->blue = new_rgb->blue;
  231. original_rgb->green = new_rgb->green;
  232. }
  233.  
  234. void flip_vertical(int i, int j, A2Methods_Array2 array2, A2Methods_Object *ptr, void *cl)
  235. {
  236. //quiet the compiler
  237. cl = cl;
  238.  
  239. //define new i and j positions of the pixel post rotation
  240. int new_i_pos = array2_methods_blocked->width(array2) - i - 1;
  241. int new_j_pos = j;
  242.  
  243. //retrieve the value of the pixel from array2b (Array2b_T prior to rotation)
  244. Pnm_rgb new_rgb = array2_methods_blocked->at(array2, new_i_pos, new_j_pos);
  245.  
  246. //Define the A2_Methods_object ptr to be of type Pnm_rgb to allow for reassignment
  247. Pnm_rgb original_rgb = ptr;
  248.  
  249. //store the new rgb values within the Pnm_rgb struct being pointed to
  250. original_rgb->red = new_rgb->red;
  251. original_rgb->blue = new_rgb->blue;
  252. original_rgb->green = new_rgb->green;
  253. }
  254.  
  255. void transposition(int i, int j, A2Methods_Array2 array2, A2Methods_Object *ptr, void *cl)
  256. {
  257. //quiet the compiler
  258. cl = cl;
  259.  
  260. //define new i and j positions of the pixel post rotation
  261. int new_i_pos = j;
  262. int new_j_pos = i;
  263.  
  264. //retrieve the value of the pixel from array2b (Array2b_T prior to rotation)
  265. Pnm_rgb new_rgb = array2_methods_blocked->at(array2, new_i_pos, new_j_pos);
  266.  
  267. //Define the A2_Methods_object ptr to be of type Pnm_rgb to allow for reassignment
  268. Pnm_rgb original_rgb = ptr;
  269.  
  270. //store the new rgb values within the Pnm_rgb struct being pointed to
  271. original_rgb->red = new_rgb->red;
  272. original_rgb->blue = new_rgb->blue;
  273. original_rgb->green = new_rgb->green;
  274. }
  275.  
  276.  
  277. void A2_plain_print(A2Methods_Array2 array2)
  278. {
  279. int cols = array2_methods_plain->width(array2);
  280. int rows = array2_methods_plain->height(array2);
  281.  
  282. printf("\n");
  283. for(int i = 0; i < rows; i++)
  284. {
  285. for(int j = 0; j < cols; j++)
  286. {
  287. if(j > 0) printf(" ");
  288.  
  289. Pnm_rgb rgb = array2_methods_plain->at(array2, i, j);
  290. printf(" %d %d %d", rgb->red, rgb->green, rgb->blue);
  291. }
  292. printf("\n");
  293. }
  294. printf("\n");
  295. }
  296.  
  297. void A2_blocked_print(A2Methods_Array2 array2)
  298. {
  299. int height = array2_methods_blocked->height(array2);
  300. int width = array2_methods_blocked->width(array2);
  301. int blocksize = array2_methods_blocked->blocksize(array2);
  302.  
  303.  
  304. printf("\n");
  305. for(int i = 0; i < height; i++)
  306. {
  307. //Print the column indices
  308. if(i == 0)
  309. {
  310. for(int k = 0; k < width; k++)
  311. {
  312. if(k == 0) printf(" ");
  313. if(k % blocksize == 0 && k != 0) printf(" %d ", k);
  314. else printf("%d ", k);
  315. }
  316. }
  317. //separate blocks by a new lines
  318. if (i % blocksize == 0)
  319. {
  320. printf("\n\n%d| ", i);
  321. }
  322. //print the current row index
  323. if (i != 0 && i % blocksize != 0)
  324. {
  325. printf("\n%d| ", i);
  326. }
  327. //print each of the blocks and their cells
  328. for(int j = 0 ; j < width; j++)
  329. {
  330. //get the current cell
  331. // void *cell = array2_methods_blocked->at(array2, i, j);
  332.  
  333. Pnm_rgb rgb = array2_methods_blocked->at(array2, i, j);
  334. // printf(" %d %d %d", rgb->red, rgb->green, rgb->blue);
  335. //print whitespace to seperate blocks
  336. if(j % blocksize == 0 && j > 0)
  337. {
  338. printf(" %d %d %d", rgb->red, rgb->green, rgb->blue);
  339.  
  340. // printf(" %d ", *(int*)cell);
  341. }
  342. else
  343. {
  344. //account for single digit cell index spacing
  345. if(rgb->blue > 10) printf("%d %d %d ", rgb->red, rgb->green, rgb->blue);
  346. else if(rgb->red > 10) printf("%d %d %d ", rgb->red, rgb->green, rgb->blue);
  347. else printf("%d %d %d ", rgb->red, rgb->green, rgb->blue);
  348. }
  349. }
  350. }
  351. printf("\n");
  352. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement