Advertisement
jcdkiki

Untitled

Apr 30th, 2024
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 18.22 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <getopt.h>
  4. #include <string.h>
  5. #include <limits.h>
  6.  
  7. #pragma pack(push, 1)
  8.  
  9. #define CW_OK 0
  10. #define CW_ERROR 40
  11.  
  12. enum {
  13.     EXCHANGE_UNKNOWN = -1,
  14.     EXCHANGE_CLOCKWISE = 0,
  15.     EXCHANGE_COUNTERCLOCKWISE,
  16.     EXCHANGE_DIAGONALS
  17. };
  18.  
  19. typedef struct {
  20.     unsigned short signature;
  21.     unsigned int filesize;
  22.     unsigned short reserved1;
  23.     unsigned short reserved2;
  24.     unsigned int data_offset;
  25. } bmpfile_header_t;
  26.  
  27. typedef struct {
  28.     unsigned int header_size;
  29.     unsigned int width;
  30.     unsigned int height;
  31.     unsigned short planes;
  32.     unsigned short bits_per_pixel;
  33.     unsigned int compression;
  34.     unsigned int image_size;
  35.     unsigned int xresolution;
  36.     unsigned int yresolution;
  37.     unsigned int n_colors;
  38.     unsigned int n_important_colors;
  39. } bmpfile_info_t;
  40.  
  41. typedef struct {
  42.     unsigned char b;
  43.     unsigned char g;
  44.     unsigned char r;
  45. } rgb_t;
  46.  
  47. #pragma pack(pop)
  48.  
  49. typedef struct {
  50.     int x, y;
  51. } point_t;
  52.  
  53. typedef struct {
  54.     bmpfile_header_t header;
  55.     bmpfile_info_t   info;
  56.     rgb_t**          data;
  57. } bmp_t;
  58.  
  59. int load_bmp(bmp_t *bmp, char *filename)
  60. {
  61.     FILE *fp = fopen(filename, "rb");
  62.     if (fp == NULL) {
  63.         fputs("Cannot open input file\n", stderr);
  64.         return CW_ERROR;
  65.     }
  66.  
  67.     fread(&bmp->header, 1, sizeof(bmpfile_header_t), fp);
  68.     fread(&bmp->info, 1, sizeof(bmpfile_info_t), fp);
  69.  
  70.     if (bmp->header.signature!= 0x4D42) {
  71.         fputs("Invalid file signature\n", stderr);
  72.         fclose(fp);
  73.         return CW_ERROR;
  74.     }
  75.  
  76.     if (bmp->info.bits_per_pixel != 24 || bmp->info.compression != 0 || bmp->info.planes != 1) {
  77.         fputs("Unsupported BMP format\n", stderr);
  78.         fclose(fp);
  79.         return CW_ERROR;
  80.     }
  81.  
  82.     bmp->data = (rgb_t**)malloc(bmp->info.height * sizeof(rgb_t*));
  83.     if (bmp->data == NULL) {
  84.         fputs("Memory allocation error\n", stderr);
  85.         fclose(fp);
  86.         return CW_ERROR;
  87.     }
  88.  
  89.     size_t padding = (4 - (sizeof(rgb_t) * bmp->info.width) % 4) % 4;
  90.    
  91.     for (int i = bmp->info.height - 1; i >= 0; i--) {
  92.         bmp->data[i] = (rgb_t*)malloc(bmp->info.width * sizeof(rgb_t) + padding);
  93.         if (bmp->data[i] == NULL) {
  94.             fputs("Memory allocation error\n", stderr);
  95.             fclose(fp);
  96.  
  97.             for (int j = bmp->info.height - 1; j > i; j--)
  98.                 free(bmp->data[j]);
  99.             free(bmp->data);
  100.             return CW_ERROR;
  101.         }
  102.  
  103.         fread(bmp->data[i], 1, bmp->info.width * sizeof(rgb_t) + padding, fp);
  104.     }
  105.  
  106.     fclose(fp);
  107.     return CW_OK;
  108. }
  109.  
  110. int save_bmp(bmp_t *bmp, char *filename)
  111. {
  112.     FILE *fp = fopen(filename, "wb");
  113.     if (fp == NULL) {
  114.         fputs("Cannot open output file\n", stderr);
  115.         return CW_ERROR;
  116.     }
  117.  
  118.     fwrite(&bmp->header, 1, sizeof(bmpfile_header_t), fp);
  119.     fwrite(&bmp->info, 1, sizeof(bmpfile_info_t), fp);
  120.     fseek(fp, bmp->header.data_offset, SEEK_SET);
  121.  
  122.     int padding = (4 - (sizeof(rgb_t) * bmp->info.width) % 4) % 4;
  123.     for (int i = bmp->info.height - 1; i >= 0; i--) {
  124.         fwrite(bmp->data[i], 1, bmp->info.width * sizeof(rgb_t) + padding, fp);
  125.     }
  126.  
  127.     fclose(fp);
  128.     return CW_OK;
  129. }
  130.  
  131. void free_bmp(bmp_t *bmp)
  132. {
  133.     for (size_t i = 0; i < bmp->info.height; i++) {
  134.         free(bmp->data[i]);
  135.     }
  136.     free(bmp->data);
  137. }
  138.  
  139. const char shortopts[] = "hil:s:t:c:fF:r:x:I:O:";
  140.  
  141. enum {
  142.     FUNCTION_SQUARE = 1,
  143.     FUNCTION_EXCHANGE,
  144.     FUNCTION_FREQ_COLOR
  145. };
  146.  
  147. struct option longopts[] = {
  148.     { "help", 0, NULL, 'h' },
  149.     { "info", 0, NULL, 'i' },
  150.     { "square", 0, NULL, FUNCTION_SQUARE },
  151.     { "exchange", 0, NULL, FUNCTION_EXCHANGE },
  152.     { "freq_color", 0, NULL, FUNCTION_FREQ_COLOR },
  153.  
  154.     { "left_up", 1, NULL, 'l' },
  155.     { "side_size", 1, NULL,'s' },
  156.     { "thickness", 1, NULL, 't' },
  157.     { "color", 1, NULL, 'c'},
  158.     { "fill", 0, NULL, 'f' },
  159.     { "fill_color", 1, NULL, 'F' },
  160.  
  161.     { "right_down", 1, NULL, 'r' },
  162.     { "exchange_type", 1, NULL, 'x' },
  163.  
  164.     { "input", 1, NULL, 'I' },
  165.     { "output", 1, NULL, 'O' },
  166.  
  167.     { NULL, 0, NULL, 0 }
  168. };
  169.  
  170. typedef struct {
  171.     point_t left_up;
  172.     int side_size;
  173.     int thickness;
  174.     rgb_t color;
  175.     char is_color_set;
  176.     char fill;
  177.     rgb_t fill_color;
  178.     char is_fill_color_set;
  179.     point_t right_down;
  180.     int exchange_type;
  181.     char *input;
  182.     char *output;
  183. } args_t;
  184.  
  185. void init_args(args_t *args)
  186. {
  187.     args->left_up = (point_t) { INT_MAX, INT_MAX };
  188.     args->side_size = INT_MAX;
  189.     args->thickness = INT_MAX;
  190.     args->color = (rgb_t) { 0, 0, 0 };
  191.     args->is_color_set = 0;
  192.     args->fill = 0;
  193.     args->right_down = (point_t) { INT_MAX, INT_MAX };
  194.     args->exchange_type = EXCHANGE_UNKNOWN;
  195.     args->input = NULL;
  196.     args->output = "out.bmp";
  197. }
  198.  
  199. int read_color(rgb_t *rgb, char *str)
  200. {
  201.     int r, g, b;
  202.     int n = sscanf(str, "%d.%d.%d", &r, &g, &b);
  203.  
  204.     if (n != 3) {
  205.         fputs("Invalid color format\n", stderr);
  206.         return CW_ERROR;
  207.     }
  208.  
  209.     if (r < 0 || g < 0 || b < 0 || r > 255 || g > 255 || b > 255) {
  210.         fputs("Invalid color value\n", stderr);
  211.         return CW_ERROR;
  212.     }
  213.  
  214.     rgb->r = r;
  215.     rgb->g = g;
  216.     rgb->b = b;
  217.     return CW_OK;
  218. }
  219.  
  220. int read_int(int *val, char *str)
  221. {
  222.     int n = sscanf(str, "%d", val);
  223.  
  224.     if (n != 1) {
  225.         fputs("Invalid integer\n", stderr);
  226.         return CW_ERROR;
  227.     }
  228.  
  229.     return CW_OK;
  230. }
  231.  
  232. int read_point(point_t *pt, char *str)
  233. {
  234.     int n = sscanf(str, "%d.%d", &pt->x, &pt->y);
  235.    
  236.     if (n!= 2) {
  237.         fputs("Invalid point format\n", stderr);
  238.         return CW_ERROR;
  239.     }
  240.  
  241.     return CW_OK;
  242. }
  243.  
  244. int read_exchange_type(int *exchange_type, char *str)
  245. {
  246.     if (strcmp(str, "clockwise") == 0) {
  247.         *exchange_type = EXCHANGE_CLOCKWISE;
  248.         return CW_OK;
  249.     }
  250.     if (strcmp(str, "counterclockwise") == 0) {
  251.         *exchange_type = EXCHANGE_COUNTERCLOCKWISE;
  252.         return CW_OK;
  253.     }
  254.     if (strcmp(str, "diagonals") == 0) {
  255.         *exchange_type = EXCHANGE_DIAGONALS;
  256.         return CW_OK;
  257.     }
  258.  
  259.     fputs("Invalid exchange type\n", stderr);
  260.     return CW_ERROR;  
  261. }
  262.  
  263. void print_help()
  264. {
  265.     puts(
  266.         "./cw <function> [options]\n"
  267.         "Functions:\n"
  268.         " -h, --help\n"
  269.         " -i, --info     print info about image\n"
  270.         " --square       draw square\n"
  271.         " --exchange     exchange four pieces of the image\n"
  272.         " --freq_color   replace most frequent color\n"
  273.         "Options:\n"
  274.         " -I, --input <file>\n"
  275.         " -O, --output <file>\n"
  276.         "Options for square:\n"
  277.         " -l, --left_up X.Y\n"
  278.         " -s, --side_size X\n"
  279.         " -t, --thickness X\n"
  280.         " -c, --color R.G.B\n"
  281.         " -f, --fill (flag to fill the square)\n"
  282.         " -F, --fill_color R.G.B\n"
  283.         "Options for exchange:\n"
  284.         "  -x, --exchange_type (clockwise, counterclockwise, diagonals)\n"
  285.         "  -l, --left_up X.Y\n"
  286.         "  -r, --right_down X.Y\n"
  287.         "Options for freq_color:\n"
  288.         "  -c, --color R.G.B"
  289.     );
  290. }
  291.  
  292. rgb_t get_pixel(bmp_t *bmp, int x, int y)
  293. {
  294.     if (x < 0 || y < 0 || x >= (int)bmp->info.width || y >= (int)bmp->info.height) {
  295.         return (rgb_t) { 0, 0, 0 };
  296.     }
  297.     return bmp->data[y][x];
  298. }
  299.  
  300. void set_pixel(bmp_t *bmp, int x, int y, rgb_t rgb)
  301. {
  302.     if (x < 0 || y < 0 || x >= (int)bmp->info.width || y >= (int)bmp->info.height)
  303.         return;
  304.     bmp->data[y][x] = rgb;
  305. }
  306.  
  307. int print_image_info_option(bmp_t *bmp)
  308. {
  309.     printf("Width: %d\n", (int)bmp->info.width);
  310.     printf("Height: %d\n", (int)bmp->info.height);
  311.     printf("Planes: %d\n", (int)bmp->info.planes);
  312.     printf("Bits per pixel: %d\n", (int)bmp->info.bits_per_pixel);
  313.     printf("Compression: %d\n", (int)bmp->info.compression);
  314.     printf("Image size: %d\n", (int)bmp->info.image_size);
  315.     printf("X resolution: %d\n", (int)bmp->info.xresolution);
  316.     printf("Y resolution: %d\n", (int)bmp->info.yresolution);
  317.     printf("Number of colors: %d\n", (int)bmp->info.n_colors);
  318.     printf("Number of important colors: %d\n", (int)bmp->info.n_important_colors);
  319.  
  320.     return CW_OK;
  321. }
  322.  
  323. int draw_square_option(bmp_t *bmp, args_t *args)
  324. {
  325.     if (args->left_up.x == INT_MAX && args->left_up.y == INT_MAX) {
  326.         fputs("Left up corner not specified\n", stderr);
  327.         return CW_ERROR;
  328.     }
  329.     if (args->side_size == INT_MAX) {
  330.         fputs("Side size not specified\n", stderr);
  331.         return CW_ERROR;
  332.     }
  333.     if (args->thickness == INT_MAX) {
  334.         fputs("Thickness not specified\n", stderr);
  335.         return CW_ERROR;
  336.     }
  337.     if (args->is_color_set == 0) {
  338.         fputs("Color not specified\n", stderr);
  339.         return CW_ERROR;
  340.     }
  341.     if (args->fill == 1 && args->is_fill_color_set == 0) {
  342.         fputs("Fill color not specified\n", stderr);
  343.         return CW_ERROR;
  344.     }
  345.  
  346.     int x0 = args->left_up.x;
  347.     int y0 = args->left_up.y;
  348.     int x1 = args->left_up.x + args->side_size;
  349.     int y1 = args->left_up.y + args->side_size;
  350.  
  351.     args->thickness = (args->thickness + 1) / 2;
  352.  
  353.     if (args->fill) {
  354.         int fx0 = (x0 < 0) ? 0 : x0;
  355.         int fy0 = (y0 < 0) ? 0 : y0;
  356.         int fx1 = (x1 > (int)bmp->info.width) ? (int)bmp->info.width : x1;
  357.         int fy1 = (y1 > (int)bmp->info.height) ? (int)bmp->info.height : y1;
  358.  
  359.         for (int x = fx0; x < fx1; x++) {
  360.             for (int y = fy0; y < fy1; y++) {
  361.                 set_pixel(bmp, x, y, args->fill_color);
  362.             }
  363.         }
  364.     }
  365.  
  366.     for (int s = -args->thickness+1; s < args->side_size + args->thickness; s++) {
  367.         for (int t = 0; t < args->thickness; t++) {
  368.             set_pixel(bmp, x0 + s, y0 + t, args->color);
  369.             set_pixel(bmp, x0 + s, y0 - t, args->color);
  370.             set_pixel(bmp, x0 + t, y0 + s, args->color);
  371.             set_pixel(bmp, x0 - t, y0 + s, args->color);
  372.             set_pixel(bmp, x0 + s, y1 + t, args->color);
  373.             set_pixel(bmp, x0 + s, y1 - t, args->color);
  374.             set_pixel(bmp, x1 + t, y0 + s, args->color);
  375.             set_pixel(bmp, x1 - t, y0 + s, args->color);
  376.         }
  377.     }
  378.  
  379.     return CW_OK;
  380. }
  381.  
  382. void swap_regions(bmp_t *bmp, int x0, int y0, int x1, int y1, int dx, int dy)
  383. {
  384.     for (int x = 0; x < dx; x++) {
  385.         for (int y = 0; y < dy; y++) {
  386.             rgb_t tmp = get_pixel(bmp, x0 + x, y0 + y);
  387.             set_pixel(bmp, x0 + x, y0 + y, get_pixel(bmp, x1 + x, y1 + y));
  388.             set_pixel(bmp, x1 + x, y1 + y, tmp);
  389.         }
  390.     }
  391. }
  392.  
  393. int exchange_opion(bmp_t *bmp, args_t *args)
  394. {
  395.     if (args->exchange_type == EXCHANGE_UNKNOWN) {
  396.         fputs("Exchange type is not specified\n", stderr);
  397.         return CW_ERROR;
  398.     }
  399.     if (args->left_up.x == INT_MAX && args->left_up.y == INT_MAX) {
  400.         fputs("Left up point is not specified\n", stderr);
  401.         return CW_ERROR;
  402.     }
  403.     if (args->right_down.x == INT_MAX && args->right_down.y == INT_MAX) {
  404.         fputs("Right down point is not specified\n", stderr);
  405.         return CW_ERROR;
  406.     }
  407.  
  408.     int x0 = args->left_up.x;
  409.     int y0 = args->left_up.y;
  410.     int x1 = args->right_down.x;
  411.     int y1 = args->right_down.y;
  412.     int dx = (x1 - x0) / 2;
  413.     int dy = (y1 - y0) / 2;
  414.  
  415.     if (args->exchange_type == EXCHANGE_DIAGONALS) {
  416.         swap_regions(bmp, x0, y0, x0 + dx, y0 + dy, dx, dy);
  417.         swap_regions(bmp, x0 + dx, y0, x0, y0 + dy, dx, dy);    
  418.     }
  419.     else if (args->exchange_type == EXCHANGE_CLOCKWISE) {
  420.         swap_regions(bmp, x0, y0, x0, y0 + dy, dx, dy);
  421.         swap_regions(bmp, x0 + dx, y0, x0, y0 + dy, dx, dy);
  422.         swap_regions(bmp, x0 + dx, y0 + dy, x0, y0 + dy, dx, dy);
  423.     }
  424.     else {
  425.         swap_regions(bmp, x0, y0, x0 + dx, y0, dx, dy);
  426.         swap_regions(bmp, x0 + dx, y0, x0 + dx, y0 + dy, dx, dy);
  427.         swap_regions(bmp, x0 + dx, y0 + dy, x0, y0 + dy, dx, dy);
  428.     }
  429.  
  430.     return CW_OK;
  431. }
  432.  
  433. typedef struct {
  434.     rgb_t color;
  435.     size_t freq;
  436. } colorinfo_t;
  437.  
  438. #define BASE_SIZE 256
  439. #define MAX_SEARCH 10
  440.  
  441. int find_color(colorinfo_t *colors, size_t size, rgb_t color)
  442. {
  443.     for (size_t i = 0; i < size; i++) {
  444.         if (colors[i].color.r == color.r &&
  445.             colors[i].color.g == color.g &&
  446.             colors[i].color.b == color.b) {
  447.             return i;
  448.         }
  449.     }
  450.     return -1;
  451. }
  452.  
  453. int cantor_pairing(int a, int b)
  454. {
  455.    return (a + b + 1) * (a + b) / 2 + b;
  456. }
  457.  
  458. int hash_color(rgb_t color)
  459. {
  460.    return cantor_pairing(color.r, cantor_pairing(color.g, color.b));
  461. }
  462.  
  463. int colors_equal(rgb_t a, rgb_t b)
  464. {
  465.     return a.r == b.r && a.g == b.g && a.b == b.b;
  466. }
  467.  
  468. int increment_color(colorinfo_t *colors, size_t size, rgb_t color, int amount)
  469. {
  470.     int start_index = hash_color(color) % size;
  471.  
  472.     for (int i = 0; i < MAX_SEARCH; i++) {
  473.         int index = (start_index + i) % size;
  474.  
  475.         if (colors[index].freq > 0 && colors_equal(colors[index].color, color)) {
  476.             colors[index].freq += amount;
  477.             return 1;
  478.         }
  479.     }
  480.  
  481.     // try to insert
  482.     for (int i = 0; i < MAX_SEARCH; i++) {
  483.         int index = (start_index + i) % size;
  484.  
  485.         if (colors[index].freq == 0) {
  486.             colors[index].freq = 1;
  487.             colors[index].color = color;
  488.             return 1;
  489.         }
  490.     }
  491.    
  492.     return 0;
  493. }
  494.  
  495. colorinfo_t *grow_colors(colorinfo_t *old_colors, size_t old_size, size_t new_size, size_t *out_size)
  496. {
  497.     colorinfo_t *new_colors = (colorinfo_t*)malloc(sizeof(colorinfo_t) * new_size);
  498.     if (new_colors == NULL) {
  499.         fputs("Memory allocation failed\n", stderr);
  500.         free(old_colors);
  501.         return NULL;
  502.     }
  503.  
  504.     memset(new_colors, 0, sizeof(colorinfo_t) * new_size);
  505.  
  506.     for (size_t i = 0; i < old_size; i++) {
  507.         if (old_colors[i].freq > 0) {
  508.             if (!increment_color(new_colors, new_size, old_colors[i].color, old_colors[i].freq)) {
  509.                 free(new_colors);
  510.                 return grow_colors(old_colors, old_size, new_size * 2, out_size);
  511.             }
  512.         }
  513.     }
  514.  
  515.     *out_size = new_size;
  516.     free(old_colors);
  517.     return new_colors;
  518. }
  519.  
  520. int freq_color_option(bmp_t *bmp, args_t *args)
  521. {
  522.     if (!args->is_color_set) {
  523.         fputs("Color is not specified\n", stderr);
  524.         return CW_ERROR;
  525.     }
  526.  
  527.     colorinfo_t *colors = malloc(sizeof(colorinfo_t) * BASE_SIZE);
  528.  
  529.     if (colors == NULL) {
  530.         fputs("Memory allocation failed\n", stderr);
  531.         return CW_ERROR;
  532.     }
  533.  
  534.     size_t size = BASE_SIZE;
  535.     memset(colors, 0, sizeof(colorinfo_t) * BASE_SIZE);
  536.    
  537.     for (int y = 0; y < (int)bmp->info.height; y++) {
  538.         for (int x = 0; x < (int)bmp->info.width; x++) {
  539.             int ret = increment_color(colors, size, get_pixel(bmp, x, y), 1);
  540.             while (!ret) {
  541.                 size_t new_size;
  542.                 colors = grow_colors(colors, size, size * 2, &new_size);
  543.                 if (colors == NULL)
  544.                     return CW_ERROR;
  545.  
  546.                 size = new_size;
  547.                 ret = increment_color(colors, size, get_pixel(bmp, x, y), 1);
  548.             }
  549.         }
  550.     }
  551.  
  552.     int best_i = 0;
  553.     for (size_t i = 0; i < size; i++) {
  554.         if (colors[i].freq > colors[best_i].freq)
  555.             best_i = i;
  556.     }
  557.  
  558.     rgb_t color = colors[best_i].color;
  559.     for (int y = 0; y < (int)bmp->info.height; y++) {
  560.         for (int x = 0; x < (int)bmp->info.width; x++) {
  561.             if (bmp->data[y][x].r == color.r &&
  562.                 bmp->data[y][x].g == color.g &&
  563.                 bmp->data[y][x].b == color.b) {
  564.                 bmp->data[y][x] = args->color;
  565.             }
  566.         }
  567.     }
  568.  
  569.     free(colors);
  570.     return CW_OK;
  571. }
  572.  
  573. int main(int argc, char **argv)
  574. {
  575.     puts("Course work for option 4.4, created by Kulach Daniil");
  576.  
  577.     args_t args;
  578.     int function = '\0';
  579.  
  580.     init_args(&args);
  581.  
  582.     int opt = getopt_long(argc, argv, shortopts, longopts, NULL);
  583.     while (opt!= -1) {
  584.         if (opt == '?') {
  585.             fputs("Invalid option\n", stderr);
  586.             return CW_ERROR;
  587.         }
  588.  
  589.         int ret = CW_OK;
  590.         switch (opt) {
  591.             case 'h':
  592.                 print_help();
  593.                 return CW_OK;
  594.             case 'i':
  595.             case FUNCTION_SQUARE:
  596.             case FUNCTION_EXCHANGE:
  597.             case FUNCTION_FREQ_COLOR:
  598.                 function = opt;
  599.                 break;
  600.             case 'l':
  601.                 ret = read_point(&args.left_up, optarg);
  602.                 break;
  603.             case 's':
  604.                 ret = read_int(&args.side_size, optarg);
  605.                 break;
  606.             case 't':
  607.                 ret = read_int(&args.thickness, optarg);
  608.                 break;
  609.             case 'c':
  610.                 ret = read_color(&args.color, optarg);
  611.                 args.is_color_set = 1;
  612.                 break;
  613.             case 'f':
  614.                 args.fill = 1;
  615.                 break;
  616.             case 'F':
  617.                 ret = read_color(&args.fill_color, optarg);
  618.                 args.is_fill_color_set = 1;
  619.             case 'r':
  620.                 ret = read_point(&args.right_down, optarg);
  621.                 break;
  622.             case 'x':
  623.                 ret = read_exchange_type(&args.exchange_type, optarg);
  624.                 break;
  625.             case 'I':
  626.                 args.input = optarg;
  627.                 break;
  628.             case 'O':
  629.                 args.output = optarg;
  630.                 break;
  631.         }
  632.  
  633.         if (ret != CW_OK) {
  634.             return CW_ERROR;
  635.         }
  636.  
  637.         opt = getopt_long(argc, argv, shortopts, longopts, NULL);
  638.     }
  639.  
  640.     if (function == '\0') {
  641.         fputs("No function specified\n", stderr);
  642.         return CW_ERROR;
  643.     }
  644.  
  645.     if (args.input == NULL) {
  646.         if (optind >= argc) {
  647.             fputs("No image specified\n", stderr);
  648.             return CW_ERROR;
  649.         }
  650.         args.input = argv[optind];
  651.     }
  652.  
  653.     bmp_t bmp;
  654.     if (load_bmp(&bmp, args.input) != CW_OK) {
  655.         return CW_ERROR;
  656.     }
  657.  
  658.     int ret = CW_OK;
  659.     switch (function) {
  660.         case 'i':
  661.             ret = print_image_info_option(&bmp);
  662.             break;
  663.         case FUNCTION_SQUARE:
  664.             ret = draw_square_option(&bmp, &args);
  665.             break;
  666.         case FUNCTION_EXCHANGE:
  667.             ret = exchange_opion(&bmp, &args);
  668.             break;
  669.         case FUNCTION_FREQ_COLOR:
  670.             ret = freq_color_option(&bmp, &args);
  671.             break;
  672.     }
  673.  
  674.     if (ret != CW_OK) {
  675.         free_bmp(&bmp);
  676.         return CW_ERROR;
  677.     }
  678.  
  679.     if (function != 'i') {
  680.         int ret = save_bmp(&bmp, args.output);
  681.         if (ret != CW_OK) {
  682.             return CW_ERROR;
  683.         }
  684.     }
  685.  
  686.     free_bmp(&bmp);
  687. }
  688.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement