Advertisement
mullerdaniil

lab14inf

Dec 25th, 2020
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.18 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <limits.h>
  4. #include <stdlib.h>
  5.  
  6. #define UNKNOWN_COMMAND 0
  7. #define INPUT_COMMAND 1
  8. #define OUTPUT_COMMAND 2
  9. #define MAX_ITER_COMMAND 3
  10. #define DUMP_FREQ_COMMAND 4
  11.  
  12. #define STRING_LENGTH 400
  13.  
  14. char INPUT_FILE_NAME[STRING_LENGTH];
  15. char DIR_NAME[STRING_LENGTH];
  16. //int MAX_ITER = INT_MAX;
  17. int MAX_ITER = 500;
  18. int DUMP_FREQ = 1;
  19. int INPUT_FLAG = 0;
  20. int OUTPUT_FLAG = 0;
  21.  
  22. unsigned int HEIGHT;
  23. unsigned int WIDTH;
  24. unsigned char header[54];
  25. char **generation;
  26.  
  27.  
  28.  
  29. void printError(char *errorMessage) {
  30. printf("Error: %s!", errorMessage);
  31. exit(1);
  32. }
  33.  
  34.  
  35. int checkCommand(char *command) {
  36. if (strcmp(command, "--input") == 0)
  37. return INPUT_COMMAND;
  38. if (strcmp(command, "--output") == 0)
  39. return OUTPUT_COMMAND;
  40. if (strcmp(command, "--max_iter") == 0)
  41. return MAX_ITER_COMMAND;
  42. if (strcmp(command, "--dump_freq") == 0)
  43. return DUMP_FREQ_COMMAND;
  44. return 0;
  45. }
  46.  
  47.  
  48. void parseCommand(int argc, char **argv) {
  49. if (argc < 5 || argc % 2 == 0)
  50. printError("Incorrect number of arguments");
  51.  
  52. int commandType;
  53. for (int i = 1; i < argc - 1; i += 2) {
  54. commandType = checkCommand(argv[i]);
  55.  
  56. if (commandType == 0)
  57. printError("Incorrect command");
  58.  
  59. switch (commandType) {
  60. case INPUT_COMMAND:
  61. INPUT_FLAG = 1;
  62. strcpy(INPUT_FILE_NAME, argv[i + 1]);
  63. break;
  64. case OUTPUT_COMMAND:
  65. OUTPUT_FLAG = 1;
  66. strcpy(DIR_NAME, argv[i + 1]);
  67. break;
  68. case MAX_ITER_COMMAND:
  69. MAX_ITER = atoi(argv[i + 1]);
  70. break;
  71. case DUMP_FREQ_COMMAND:
  72. DUMP_FREQ = atoi(argv[i + 1]);
  73. break;
  74. }
  75. }
  76.  
  77. if (INPUT_FLAG == 0 || OUTPUT_FLAG == 0)
  78. printError("No input or output were provided");
  79. }
  80.  
  81.  
  82. char newCell(int x, int y) {
  83. char cell = generation[x][y];
  84. char nbrCount =
  85. generation[x - 1][y - 1]
  86. + generation[x][y - 1]
  87. + generation[x + 1][y - 1]
  88. + generation[x - 1][y]
  89. + generation[x + 1][y]
  90. + generation[x - 1][y + 1]
  91. + generation[x][y + 1]
  92. + generation[x + 1][y + 1];
  93.  
  94. return cell && (nbrCount == 2 || nbrCount == 3) || !cell && nbrCount == 3;
  95. }
  96.  
  97.  
  98. void freeGeneration(char **generation, unsigned int height) {
  99. for (int i = 0; i < height; i++)
  100. free(generation[i]);
  101. generation = NULL;
  102. }
  103.  
  104.  
  105. void enlargeBy2Generation() {
  106. HEIGHT += 4;
  107. WIDTH += 4;
  108.  
  109. char **enlargedGeneration = (char **) malloc(HEIGHT * sizeof(char *));
  110. for (int i = 0; i < HEIGHT; i++)
  111. enlargedGeneration[i] = (char *) calloc(WIDTH, sizeof(char));
  112.  
  113. for (int row = 2; row < HEIGHT - 2; row++)
  114. for (int col = 2; col < WIDTH - 2; col++)
  115. enlargedGeneration[row][col] = generation[row - 2][col - 2];
  116.  
  117. freeGeneration(generation, HEIGHT - 4);
  118.  
  119. generation = enlargedGeneration;
  120. }
  121.  
  122.  
  123. void calculateNewGeneration() {
  124. char **newGeneration = (char **) malloc(HEIGHT * sizeof(char *));
  125. for (int i = 0; i < HEIGHT; i++)
  126. newGeneration[i] = (char *) calloc(WIDTH, sizeof(char));
  127.  
  128. for (int row = 1; row < HEIGHT - 1; row++)
  129. for (int col = 1; col < WIDTH - 1; col++)
  130. newGeneration[row][col] = newCell(row, col);
  131.  
  132. freeGeneration(generation, HEIGHT);
  133. generation = newGeneration;
  134. }
  135.  
  136.  
  137. void cutEdges() {
  138. int top = 2, right = WIDTH - 2, bottom = HEIGHT - 2, left = 2;
  139.  
  140. // top check
  141. for (int col = 1; col < WIDTH - 1; col++)
  142. if (generation[1][col]) {
  143. top--;
  144. break;
  145. }
  146. // right check
  147. for (int row = 1; row < HEIGHT - 1; row++)
  148. if (generation[row][WIDTH - 2]) {
  149. right++;
  150. break;
  151. }
  152. // bottom check
  153. for (int col = 1; col < WIDTH - 1; col++)
  154. if (generation[HEIGHT - 2][col]) {
  155. bottom++;
  156. break;
  157. }
  158. // left check
  159. for (int row = 1; row < HEIGHT - 1; row++)
  160. if (generation[row][1]) {
  161. left--;
  162. break;
  163. }
  164.  
  165. int newHeight = bottom - top;
  166. int newWidth = right - left;
  167. char **newGeneration = (char **) malloc(newHeight * sizeof(char *));
  168. for (int i = 0; i < newHeight; i++)
  169. newGeneration[i] = (char *) calloc(newWidth, sizeof(char));
  170.  
  171. for (int row = 0; row < newHeight; row++)
  172. for (int col = 0; col < newWidth; col++)
  173. newGeneration[row][col] = generation[row + top][col + left];
  174.  
  175. freeGeneration(generation, HEIGHT);
  176. HEIGHT = newHeight;
  177. WIDTH = newWidth;
  178. generation = newGeneration;
  179. }
  180.  
  181.  
  182. void newGeneration() {
  183. enlargeBy2Generation();
  184. calculateNewGeneration();
  185. cutEdges();
  186. }
  187.  
  188. void updateHeader() {
  189. unsigned int width = WIDTH;
  190. unsigned int height = HEIGHT;
  191. for (int byte = 18; byte < 22; byte++) {
  192. header[byte] = width % 256;
  193. header[byte + 4] = height % 256;
  194. width >>= 8;
  195. height >>= 8;
  196. }
  197.  
  198. unsigned int size = HEIGHT * (WIDTH * 3 + (WIDTH * 3) % 4) + 54;
  199. for (int byte = 2; byte < 6; byte++) {
  200. header[byte] = size % 256;
  201. size >>= 8;
  202. }
  203.  
  204. size = HEIGHT * (WIDTH * 3 + (WIDTH * 3) % 4);
  205. for (int byte = 34; byte < 38; byte++) {
  206. header[byte] = size % 256;
  207. size >>= 8;
  208. }
  209. }
  210.  
  211.  
  212. void saveGeneration(int iteration) {
  213. char outputFileName[STRING_LENGTH];
  214. char iterationName[STRING_LENGTH];
  215. strcpy(outputFileName, DIR_NAME);
  216. strcat(outputFileName, "/");
  217. strncat(outputFileName, INPUT_FILE_NAME, strlen(INPUT_FILE_NAME) - 4);
  218. strcat(outputFileName, "_");
  219. strcat(outputFileName, itoa(iteration, iterationName, 10));
  220. strcat(outputFileName, ".bmp");
  221. FILE *outputFile = fopen(outputFileName, "wb");
  222. updateHeader();
  223. fseek(outputFile, 0, SEEK_SET);
  224. fwrite(header, 1, 54, outputFile);
  225.  
  226. char currentPixel;
  227. unsigned char currentRGB[3];
  228. for (int row = HEIGHT - 1; row >= 0; row--) {
  229. for (int col = 0; col < WIDTH; col++) {
  230. currentPixel = generation[row][col];
  231. if (currentPixel) {
  232. currentRGB[0] = 0x00;
  233. currentRGB[1] = 0x00;
  234. currentRGB[2] = 0x00;
  235. } else {
  236. currentRGB[0] = 0xFF;
  237. currentRGB[1] = 0xFF;
  238. currentRGB[2] = 0xFF;
  239. }
  240. fwrite(currentRGB, 1, 3, outputFile);
  241. }
  242. while (ftell(outputFile) % 4 != 2)
  243. fputc(0x80, outputFile);
  244. }
  245.  
  246. fclose(outputFile);
  247. }
  248.  
  249.  
  250.  
  251. int main(int argc, char **argv) {
  252. parseCommand(argc, argv);
  253.  
  254. FILE *file = NULL;
  255. file = fopen(INPUT_FILE_NAME, "rb");
  256. if (file == NULL)
  257. printError("File not found");
  258.  
  259.  
  260. // reading the header
  261. fseek(file, 0, SEEK_SET);
  262. fread(header, 1, 54, file);
  263. WIDTH = header[18] + 256 * header[19] + 256 * 256 * header[20] + 256 * 256 * 256 * header[21];
  264. HEIGHT = header[22] + 256 * header[23] + 256 * 256 * header[24] + 256 * 256 * 256 * header[25];
  265.  
  266.  
  267. // initial generation (initialization)
  268. generation = (char **) malloc(HEIGHT * sizeof(char *));
  269. for (int i = 0; i < HEIGHT; i++)
  270. generation[i] = (char *) malloc(WIDTH * sizeof(char));
  271.  
  272.  
  273. // initial generation (filling)
  274. unsigned char currentRGB[3];
  275. for (int row = HEIGHT - 1; row >= 0; row--) {
  276. for (int col = 0; col < WIDTH; col++) {
  277. fread(currentRGB, 1, 3, file);
  278. if (currentRGB[0] == 0xFF && currentRGB[1] == 0xFF && currentRGB[2] == 0xFF)
  279. generation[row][col] = 0;
  280. else
  281. generation[row][col] = 1;
  282. }
  283. while (ftell(file) % 4 != 2)
  284. fgetc(file);
  285. }
  286. fclose(file);
  287.  
  288.  
  289. // calculating and saving generations
  290. mkdir(DIR_NAME);
  291. for (int iter = 1; iter <= MAX_ITER; iter++) {
  292. newGeneration();
  293. if (iter % DUMP_FREQ == 0)
  294. saveGeneration(iter);
  295. }
  296.  
  297.  
  298. freeGeneration(generation, HEIGHT);
  299. printf("DONE!\n");
  300.  
  301. return 0;
  302. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement