Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <string.h>
- #include <limits.h>
- #include <stdlib.h>
- #define UNKNOWN_COMMAND 0
- #define INPUT_COMMAND 1
- #define OUTPUT_COMMAND 2
- #define MAX_ITER_COMMAND 3
- #define DUMP_FREQ_COMMAND 4
- #define STRING_LENGTH 400
- char INPUT_FILE_NAME[STRING_LENGTH];
- char DIR_NAME[STRING_LENGTH];
- //int MAX_ITER = INT_MAX;
- int MAX_ITER = 500;
- int DUMP_FREQ = 1;
- int INPUT_FLAG = 0;
- int OUTPUT_FLAG = 0;
- unsigned int HEIGHT;
- unsigned int WIDTH;
- unsigned char header[54];
- char **generation;
- void printError(char *errorMessage) {
- printf("Error: %s!", errorMessage);
- exit(1);
- }
- int checkCommand(char *command) {
- if (strcmp(command, "--input") == 0)
- return INPUT_COMMAND;
- if (strcmp(command, "--output") == 0)
- return OUTPUT_COMMAND;
- if (strcmp(command, "--max_iter") == 0)
- return MAX_ITER_COMMAND;
- if (strcmp(command, "--dump_freq") == 0)
- return DUMP_FREQ_COMMAND;
- return 0;
- }
- void parseCommand(int argc, char **argv) {
- if (argc < 5 || argc % 2 == 0)
- printError("Incorrect number of arguments");
- int commandType;
- for (int i = 1; i < argc - 1; i += 2) {
- commandType = checkCommand(argv[i]);
- if (commandType == 0)
- printError("Incorrect command");
- switch (commandType) {
- case INPUT_COMMAND:
- INPUT_FLAG = 1;
- strcpy(INPUT_FILE_NAME, argv[i + 1]);
- break;
- case OUTPUT_COMMAND:
- OUTPUT_FLAG = 1;
- strcpy(DIR_NAME, argv[i + 1]);
- break;
- case MAX_ITER_COMMAND:
- MAX_ITER = atoi(argv[i + 1]);
- break;
- case DUMP_FREQ_COMMAND:
- DUMP_FREQ = atoi(argv[i + 1]);
- break;
- }
- }
- if (INPUT_FLAG == 0 || OUTPUT_FLAG == 0)
- printError("No input or output were provided");
- }
- char newCell(int x, int y) {
- char cell = generation[x][y];
- char nbrCount =
- generation[x - 1][y - 1]
- + generation[x][y - 1]
- + generation[x + 1][y - 1]
- + generation[x - 1][y]
- + generation[x + 1][y]
- + generation[x - 1][y + 1]
- + generation[x][y + 1]
- + generation[x + 1][y + 1];
- return cell && (nbrCount == 2 || nbrCount == 3) || !cell && nbrCount == 3;
- }
- void freeGeneration(char **generation, unsigned int height) {
- for (int i = 0; i < height; i++)
- free(generation[i]);
- generation = NULL;
- }
- void enlargeBy2Generation() {
- HEIGHT += 4;
- WIDTH += 4;
- char **enlargedGeneration = (char **) malloc(HEIGHT * sizeof(char *));
- for (int i = 0; i < HEIGHT; i++)
- enlargedGeneration[i] = (char *) calloc(WIDTH, sizeof(char));
- for (int row = 2; row < HEIGHT - 2; row++)
- for (int col = 2; col < WIDTH - 2; col++)
- enlargedGeneration[row][col] = generation[row - 2][col - 2];
- freeGeneration(generation, HEIGHT - 4);
- generation = enlargedGeneration;
- }
- void calculateNewGeneration() {
- char **newGeneration = (char **) malloc(HEIGHT * sizeof(char *));
- for (int i = 0; i < HEIGHT; i++)
- newGeneration[i] = (char *) calloc(WIDTH, sizeof(char));
- for (int row = 1; row < HEIGHT - 1; row++)
- for (int col = 1; col < WIDTH - 1; col++)
- newGeneration[row][col] = newCell(row, col);
- freeGeneration(generation, HEIGHT);
- generation = newGeneration;
- }
- void cutEdges() {
- int top = 2, right = WIDTH - 2, bottom = HEIGHT - 2, left = 2;
- // top check
- for (int col = 1; col < WIDTH - 1; col++)
- if (generation[1][col]) {
- top--;
- break;
- }
- // right check
- for (int row = 1; row < HEIGHT - 1; row++)
- if (generation[row][WIDTH - 2]) {
- right++;
- break;
- }
- // bottom check
- for (int col = 1; col < WIDTH - 1; col++)
- if (generation[HEIGHT - 2][col]) {
- bottom++;
- break;
- }
- // left check
- for (int row = 1; row < HEIGHT - 1; row++)
- if (generation[row][1]) {
- left--;
- break;
- }
- int newHeight = bottom - top;
- int newWidth = right - left;
- char **newGeneration = (char **) malloc(newHeight * sizeof(char *));
- for (int i = 0; i < newHeight; i++)
- newGeneration[i] = (char *) calloc(newWidth, sizeof(char));
- for (int row = 0; row < newHeight; row++)
- for (int col = 0; col < newWidth; col++)
- newGeneration[row][col] = generation[row + top][col + left];
- freeGeneration(generation, HEIGHT);
- HEIGHT = newHeight;
- WIDTH = newWidth;
- generation = newGeneration;
- }
- void newGeneration() {
- enlargeBy2Generation();
- calculateNewGeneration();
- cutEdges();
- }
- void updateHeader() {
- unsigned int width = WIDTH;
- unsigned int height = HEIGHT;
- for (int byte = 18; byte < 22; byte++) {
- header[byte] = width % 256;
- header[byte + 4] = height % 256;
- width >>= 8;
- height >>= 8;
- }
- unsigned int size = HEIGHT * (WIDTH * 3 + (WIDTH * 3) % 4) + 54;
- for (int byte = 2; byte < 6; byte++) {
- header[byte] = size % 256;
- size >>= 8;
- }
- size = HEIGHT * (WIDTH * 3 + (WIDTH * 3) % 4);
- for (int byte = 34; byte < 38; byte++) {
- header[byte] = size % 256;
- size >>= 8;
- }
- }
- void saveGeneration(int iteration) {
- char outputFileName[STRING_LENGTH];
- char iterationName[STRING_LENGTH];
- strcpy(outputFileName, DIR_NAME);
- strcat(outputFileName, "/");
- strncat(outputFileName, INPUT_FILE_NAME, strlen(INPUT_FILE_NAME) - 4);
- strcat(outputFileName, "_");
- strcat(outputFileName, itoa(iteration, iterationName, 10));
- strcat(outputFileName, ".bmp");
- FILE *outputFile = fopen(outputFileName, "wb");
- updateHeader();
- fseek(outputFile, 0, SEEK_SET);
- fwrite(header, 1, 54, outputFile);
- char currentPixel;
- unsigned char currentRGB[3];
- for (int row = HEIGHT - 1; row >= 0; row--) {
- for (int col = 0; col < WIDTH; col++) {
- currentPixel = generation[row][col];
- if (currentPixel) {
- currentRGB[0] = 0x00;
- currentRGB[1] = 0x00;
- currentRGB[2] = 0x00;
- } else {
- currentRGB[0] = 0xFF;
- currentRGB[1] = 0xFF;
- currentRGB[2] = 0xFF;
- }
- fwrite(currentRGB, 1, 3, outputFile);
- }
- while (ftell(outputFile) % 4 != 2)
- fputc(0x80, outputFile);
- }
- fclose(outputFile);
- }
- int main(int argc, char **argv) {
- parseCommand(argc, argv);
- FILE *file = NULL;
- file = fopen(INPUT_FILE_NAME, "rb");
- if (file == NULL)
- printError("File not found");
- // reading the header
- fseek(file, 0, SEEK_SET);
- fread(header, 1, 54, file);
- WIDTH = header[18] + 256 * header[19] + 256 * 256 * header[20] + 256 * 256 * 256 * header[21];
- HEIGHT = header[22] + 256 * header[23] + 256 * 256 * header[24] + 256 * 256 * 256 * header[25];
- // initial generation (initialization)
- generation = (char **) malloc(HEIGHT * sizeof(char *));
- for (int i = 0; i < HEIGHT; i++)
- generation[i] = (char *) malloc(WIDTH * sizeof(char));
- // initial generation (filling)
- unsigned char currentRGB[3];
- for (int row = HEIGHT - 1; row >= 0; row--) {
- for (int col = 0; col < WIDTH; col++) {
- fread(currentRGB, 1, 3, file);
- if (currentRGB[0] == 0xFF && currentRGB[1] == 0xFF && currentRGB[2] == 0xFF)
- generation[row][col] = 0;
- else
- generation[row][col] = 1;
- }
- while (ftell(file) % 4 != 2)
- fgetc(file);
- }
- fclose(file);
- // calculating and saving generations
- mkdir(DIR_NAME);
- for (int iter = 1; iter <= MAX_ITER; iter++) {
- newGeneration();
- if (iter % DUMP_FREQ == 0)
- saveGeneration(iter);
- }
- freeGeneration(generation, HEIGHT);
- printf("DONE!\n");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement