KirillSamokhin

Cursed_work

Dec 19th, 2021 (edited)
248
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 20.28 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <math.h>
  5. #include <ctype.h>
  6. #include <getopt.h>
  7.  
  8. void printHelp(){
  9.     printf("\tThe program processes the V3 version of BMP files.\n");
  10.     printf("-n --name - filename to open (necessarily)\n");
  11.     printf("-o --outpname - filename to save\n");
  12.     printf("-h --help - option to call a list of available commands\n");
  13.     printf("-i --info - option to print information about the processed file\n");
  14.     printf("\tTo draw a rectangle\n");
  15.     printf("-r --rectangle - option sets the coordinates of the rectangle - upper left and lower right corners in format /x_1 y_1 x_2 y_2/\n");
  16.     printf("-w --width - boundary line width in format /w/\n");
  17.     printf("-L --linecolor - color of boundary line in format /R G B/\n");
  18.     printf("-f --fill - fill color in format /R G B/\n");
  19.     printf("\tTo draw a hexagon\n");
  20.     printf("-S --sqarehex - to draw a hexagon, using square: upper left and lower right corners in format /x_1 y_1 x_2 y_2/\n");
  21.     printf("-C --circlehex - to draw hexagon, using circle: circle center coordinates and radius in format /x_c y_c r/\n");
  22.     printf("-w --width - boundary line width in format /w/\n");
  23.     printf("-L --linecolor - color of boundary line in format /R G B/\n");
  24.     printf("-f --fill - fill color in format /R G B/\n");
  25.     printf("\tTo copy part of an image\n");
  26.     printf("-c --copy - coordinates of the source area and the coordinate of the upper left corner of the destination area\n");
  27. }
  28.  
  29. struct Configs{
  30.     int cfg_error_flag;
  31.     int infoFlag;
  32.     int rectangleFlag;
  33.     int squarehexFlag;
  34.     int circlehexFlag;
  35.     int copyFlag;
  36.     int fillFlag;
  37.     char* name;
  38.     char* output_name;
  39.     int rectangle[4];
  40.     int width;
  41.     int linecolor[3];
  42.     int fill[3];
  43.     int square_hexagon[4];
  44.     int circle_hexagon[3];
  45.     int copy[6];
  46. };
  47.  
  48. void optsProcess(int argc, char* argv[], struct Configs *config){
  49.     char* opts = "hin:o:r:w:L:f:S:C:c:";
  50.     struct option longOpts[]={
  51.             {"help", no_argument, NULL, 'h'},
  52.             {"info", no_argument, NULL, 'i'},
  53.             {"name", required_argument, 0, 'n'},
  54.             {"outpname", required_argument, 0, 'o'},
  55.             {"rectangle", required_argument, 0, 'r'},
  56.             {"width", required_argument, 0, 'w'},
  57.             {"linecolor", required_argument, 0, 'L'},
  58.             {"fill", required_argument, 0, 'f'},
  59.             {"squarehex", required_argument, 0, 'S'},
  60.             {"circlehex", required_argument, 0, 'C'},
  61.             {"copy", required_argument, 0, 'c'},
  62.             {0, 0, 0, 0}
  63.     };
  64.     int opt;
  65.     int longIngex;
  66.     opt = getopt_long(argc, argv, opts, longOpts, &longIngex);
  67.     while(opt != -1){
  68.         switch(opt){
  69.             case 'h':
  70.                 printHelp();
  71.                 break;
  72.             case 'i':
  73.                 config->infoFlag = 1;
  74.                 break;
  75.             case 'n':
  76.                 config->name = optarg;
  77.                 break;
  78.             case 'o':
  79.                 config->output_name = optarg;
  80.             case 'r':
  81.                 longIngex = optind - 1;
  82.                 config->rectangleFlag = 1;
  83.                 int counter = 0;
  84.                 while(longIngex < argc){
  85.                     char *next = strdup(argv[longIngex]);
  86.                     longIngex++;
  87.                     if(strstr(next, "-") == NULL){
  88.                         if(counter < 4){
  89.                             config->rectangle[counter++] = atoi(next);
  90.                         }
  91.                     }
  92.                     else{
  93.                         if(counter<4){
  94.                             config->cfg_error_flag = 1;
  95.                         }
  96.                         break;
  97.                     }
  98.                 }
  99.                 if(counter<4){
  100.                     config->cfg_error_flag = 1;
  101.                 }
  102.                 break;
  103.             case 'w':
  104.                 config->width = atoi(optarg);
  105.                 break;
  106.             case 'L':
  107.                 longIngex = optind - 1;
  108.                 counter = 0;
  109.                 while(longIngex < argc) {
  110.                     char *next = strdup(argv[longIngex]);
  111.                     longIngex++;
  112.                     if(strstr(next, "-") == NULL){
  113.                         if(counter < 3){
  114.                             config->linecolor[counter++] = atoi(next);
  115.                         }
  116.                     }
  117.                     else{
  118.                         if(counter<3){
  119.                             config->cfg_error_flag = 1;
  120.                         }
  121.                         break;
  122.                     }
  123.                 }
  124.                 if(counter<3){
  125.                     config->cfg_error_flag = 1;
  126.                 }
  127.                 break;
  128.             case 'f':
  129.                 config->fillFlag = 1;
  130.                 longIngex = optind - 1;
  131.                 counter = 0;
  132.                 while(longIngex < argc) {
  133.                     char *next = strdup(argv[longIngex]);
  134.                     longIngex++;
  135.                     if(strstr(next, "-") == NULL){
  136.                         if(counter < 3){
  137.                             config->fill[counter++] = atoi(next);
  138.                         }
  139.                     }
  140.                     else{
  141.                         if(counter<3){
  142.                             config->cfg_error_flag = 1;
  143.                         }
  144.                         break;
  145.                     }
  146.                 }
  147.                 if(counter<3){
  148.                     config->cfg_error_flag = 1;
  149.                 }
  150.                 break;
  151.             case 'S':
  152.                 longIngex = optind - 1;
  153.                 config->squarehexFlag = 1;
  154.                 counter = 0;
  155.                 while(longIngex < argc) {
  156.                     char *next = strdup(argv[longIngex]);
  157.                     longIngex++;
  158.                     if(strstr(next, "-") == NULL){
  159.                         if(counter < 4){
  160.                             config->square_hexagon[counter++] = atoi(next);
  161.                         }
  162.                     }
  163.                     else{
  164.                         if(counter<4){
  165.                             config->cfg_error_flag = 1;
  166.                         }
  167.                         break;
  168.                     }
  169.                 }
  170.                 if(counter<4){
  171.                     config->cfg_error_flag = 1;
  172.                 }
  173.                 break;
  174.             case 'C':
  175.                 longIngex = optind - 1;
  176.                 config->circlehexFlag = 1;
  177.                 counter = 0;
  178.                 while(longIngex < argc) {
  179.                     char *next = strdup(argv[longIngex]);
  180.                     longIngex++;
  181.                     if(strstr(next, "-") == NULL){
  182.                         if(counter < 3){
  183.                             config->circle_hexagon[counter++] = atoi(next);
  184.                         }
  185.                     }
  186.                     else{
  187.                         if(counter<3){
  188.                             config->cfg_error_flag = 1;
  189.                         }
  190.                         break;
  191.                     }
  192.                 }
  193.                 if(counter<3){
  194.                     config->cfg_error_flag = 1;
  195.                 }
  196.                 break;
  197.             case 'c':
  198.                 longIngex = optind - 1;
  199.                 config->copyFlag = 1;
  200.                 counter = 0;
  201.                 while(longIngex < argc) {
  202.                     char *next = strdup(argv[longIngex]);
  203.                     longIngex++;
  204.                     if(strstr(next, "-") == NULL){
  205.                         if(counter < 6){
  206.                             config->copy[counter++] = atoi(next);
  207.                         }
  208.                     }
  209.                     else{
  210.                         if(counter<6){
  211.                             config->cfg_error_flag = 1;
  212.                         }
  213.                         break;
  214.                     }
  215.                 }
  216.                 if(counter<6){
  217.                     config->cfg_error_flag = 1;
  218.                 }
  219.                 break;
  220.             default:
  221.                 printHelp();
  222.                 config->cfg_error_flag = 1;
  223.                 return;
  224.         }
  225.         opt = getopt_long(argc, argv, opts, longOpts, &longIngex);
  226.     }
  227.     argc -= optind;
  228.     argv += optind;
  229. }
  230.  
  231. #pragma pack (push, 1)
  232.  
  233. typedef struct
  234. {
  235.     unsigned short signature;
  236.     unsigned int filesize;
  237.     unsigned short reserved1;
  238.     unsigned short reserved2;
  239.     unsigned int pixelArrOffset;
  240. } BitmapFileHeader;
  241.  
  242. typedef struct
  243. {
  244.     unsigned int headerSize;
  245.     unsigned int width;
  246.     unsigned int height;
  247.     unsigned short planes;
  248.     unsigned short bitsPerPixel;
  249.     unsigned int compression;
  250.     unsigned int imageSize;
  251.     unsigned int xPixelsPerMeter;
  252.     unsigned int yPixelsPerMeter;
  253.     unsigned int colorsInColorTable;
  254.     unsigned int importantColorCount;
  255. } BitmapInfoHeader;
  256.  
  257. typedef struct
  258. {
  259.     unsigned char b;
  260.     unsigned char g;
  261.     unsigned char r;
  262. } Rgb;
  263.  
  264. #pragma pack(pop)
  265.  
  266. void printFileHeader(BitmapFileHeader header){
  267.     printf("signature:\t%x (%hu)\n", header.signature, header.signature);
  268.     printf("filesize:\t%x (%u)\n", header.filesize, header.filesize);
  269.     printf("reserved1:\t%x (%hu)\n", header.reserved1, header.reserved1);
  270.     printf("reserved2:\t%x (%hu)\n", header.reserved2, header.reserved2);
  271.     printf("pixelArrOffset:\t%x (%u)\n", header.pixelArrOffset, header.pixelArrOffset);
  272. }
  273.  
  274. void printInfoHeader(BitmapInfoHeader header){
  275.     printf("headerSize:\t%x (%u)\n", header.headerSize, header.headerSize);
  276.     printf("width:     \t%x (%u)\n", header.width, header.width);
  277.     printf("height:    \t%x (%u)\n", header.height, header.height);
  278.     printf("planes:    \t%x (%hu)\n", header.planes, header.planes);
  279.     printf("bitsPerPixel:\t%x (%hu)\n", header.bitsPerPixel, header.bitsPerPixel);
  280.     printf("compression:\t%x (%u)\n", header.compression, header.compression);
  281.     printf("imageSize:\t%x (%u)\n", header.imageSize, header.imageSize);
  282.     printf("xPixelsPerMeter:\t%x (%u)\n", header.xPixelsPerMeter, header.xPixelsPerMeter);
  283.     printf("yPixelsPerMeter:\t%x (%u)\n", header.yPixelsPerMeter, header.yPixelsPerMeter);
  284.     printf("colorsInColorTable:\t%x (%u)\n", header.colorsInColorTable, header.colorsInColorTable);
  285.     printf("importantColorCount:\t%x (%u)\n", header.importantColorCount, header.importantColorCount);
  286. }
  287.  
  288. void drawPixel(Rgb** arr, BitmapInfoHeader bih, int x, int y, int color_r, int color_g, int color_b){
  289.     if(x>=0 && y>=0 && x<bih.width && y<bih.height){
  290.         arr[y][x].r = color_r;
  291.         arr[y][x].g = color_g;
  292.         arr[y][x].b = color_b;
  293.     }
  294. }
  295.  
  296.     /* Drawing a line using Bresenham's algorithm */
  297.  
  298. void drawLine(Rgb** arr, BitmapInfoHeader bih, int x_st, int y_st, int x_end, int y_end, int color_r, int color_g, int color_b){
  299.     int dx =  abs(x_end - x_st), sx = x_st < x_end ? 1 : -1;
  300.     int dy = -abs(y_end - y_st), sy = y_st < y_end ? 1 : -1;
  301.     int err = dx + dy, e2; /* error value e_xy */
  302.  
  303.     for (;;){
  304.         drawPixel(arr, bih, x_st, y_st, color_r, color_g, color_b);
  305.         if(x_st == x_end && y_st == y_end){
  306.             break;
  307.         }
  308.         e2 = 2 * err;
  309.         if(e2 >= dy){
  310.             err += dy; x_st += sx;  /* e_xy+e_x > 0 */
  311.         }
  312.         if(e2 <= dx){
  313.             err += dx; y_st += sy;  /* e_xy+e_y < 0 */
  314.         }
  315.     }
  316. }
  317.  
  318.     /* Recursive fill function */
  319.  
  320. void shapeFill(Rgb** arr, BitmapInfoHeader bih, int x, int y, int fill_r, int fill_g, int fill_b, int line_r, int line_g, int line_b){
  321.     if(x>=0 && x<bih.width && y>=0 && y<bih.height && (arr[y][x].r != line_r || arr[y][x].g != line_g || arr[y][x].b != line_b) && (arr[y][x].r != fill_r || arr[y][x].g != fill_g || arr[y][x].b != fill_b)){
  322.         drawPixel(arr, bih, x, y,fill_r, fill_g, fill_b);
  323.         shapeFill(arr, bih, x+1, y, fill_r, fill_g, fill_b, line_r, line_g, line_b);
  324.         shapeFill(arr, bih, x-1, y, fill_r, fill_g, fill_b, line_r, line_g, line_b);
  325.         shapeFill(arr, bih, x, y+1, fill_r, fill_g, fill_b, line_r, line_g, line_b);
  326.         shapeFill(arr, bih, x, y-1, fill_r, fill_g, fill_b, line_r, line_g, line_b);
  327.     }
  328. }
  329.  
  330.  
  331.  
  332. void drawRectangle(Rgb** arr, BitmapInfoHeader bih, struct Configs cfg){
  333.     int x_st = cfg.rectangle[0];
  334.     int y_st = bih.height - cfg.rectangle[1] - 1;
  335.     int x_end = cfg.rectangle[2];
  336.     int y_end = bih.height - cfg.rectangle[3] - 1;
  337.     int color_r = cfg.linecolor[0];
  338.     int color_g = cfg.linecolor[1];
  339.     int color_b = cfg.linecolor[2];
  340.     int fill_r = cfg.fill[0];
  341.     int fill_g = cfg.fill[1];
  342.     int fill_b = cfg.fill[2];
  343.    
  344.     /* Validity check of entered coordinates and colours */
  345.  
  346.     if(x_st < 0 || x_st >= bih.width || y_st < 0 || y_st >= bih.height || x_end < 0 || x_end >= bih.width || y_end < 0 || y_end >= bih.height){
  347.         printf("Rectangle drawing error\n");
  348.         printf("Coordinates of rectangle are out of bounds!\n");
  349.         return;
  350.     }
  351.     if(x_st >= x_end || y_st <= y_end){
  352.         printf("Invalid input format!\n");
  353.         return;
  354.     }
  355.     if(color_r < 0 || color_r > 255 || color_g < 0 || color_g > 255 || color_b < 0 || color_b > 255 || fill_r < 0 || fill_r > 255 || fill_g < 0 || fill_g > 255|| fill_b < 0 || fill_b > 255){
  356.         printf("Invalid color value!\n");
  357.         return;
  358.     }
  359.  
  360.     /* Rectangle drawing */
  361.  
  362.     for(int w = 0; w < cfg.width; w++){
  363.         drawLine(arr, bih, x_st+w, y_st, x_st+w, y_end, color_r, color_g, color_b);
  364.         drawLine(arr, bih, x_st, y_st-w, x_end, y_st-w, color_r, color_g, color_b);
  365.         drawLine(arr, bih, x_end-w, y_st, x_end-w, y_end, color_r, color_g, color_b);
  366.         drawLine(arr, bih, x_st, y_end+w, x_end, y_end+w, color_r, color_g, color_b);
  367.     }
  368.  
  369.     /* Rectangle fill */
  370.  
  371.     if(cfg.fillFlag == 1){
  372.         shapeFill(arr, bih, (x_st+x_end)/2, (y_st+y_end)/2, fill_r, fill_g, fill_b, color_r, color_g, color_b);
  373.     }
  374. }
  375.  
  376. void drawHexagon(Rgb** arr, BitmapInfoHeader bih, struct Configs cfg){
  377.     int x_c, y_c, R;
  378.     int color_r = cfg.linecolor[0];
  379.     int color_g = cfg.linecolor[1];
  380.     int color_b = cfg.linecolor[2];
  381.     int fillFlag = cfg.fillFlag;
  382.     int fill_r = cfg.fill[0];
  383.     int fill_g = cfg.fill[1];
  384.     int fill_b = cfg.fill[2];
  385.  
  386.     /* Getting the coordinates of the center of a hexagon */
  387.  
  388.     if(cfg.squarehexFlag == 1){
  389.         int a = cfg.square_hexagon[2] - cfg.square_hexagon[0];
  390.         int b = cfg.square_hexagon[3] - cfg.square_hexagon[1];
  391.         if(a < 0 || b < 0){
  392.             printf("Invalid input format!\n");
  393.             return;
  394.         }
  395.         if(a != b) {
  396.             printf("Please enter square coordinates for option -S/--squarehex\n");
  397.             return;
  398.         }
  399.         R = a/2;
  400.         x_c = (cfg.square_hexagon[2] + cfg.square_hexagon[0])/2;
  401.         y_c = (2*bih.height - cfg.square_hexagon[1] - cfg.square_hexagon[3] - 2)/2;
  402.     }
  403.     else if(cfg.circlehexFlag == 1){
  404.         x_c = cfg.circle_hexagon[0];
  405.         y_c = bih.height - cfg.circle_hexagon[1] - 1;
  406.         R = cfg.circle_hexagon[2];
  407.     }
  408.     if(x_c < 0 || x_c >= bih.width || y_c < 0 || y_c >= bih.height){
  409.         printf("Hexagon drawing error\n");
  410.         printf("Coordinates of hexagon center are out of bounds!\n");
  411.         return;
  412.     }
  413.     if(color_r < 0 || color_r > 255 || color_g < 0 || color_g > 255 || color_b < 0 || color_b > 255 || fill_r < 0 || fill_r > 255 || fill_g < 0 || fill_g > 255|| fill_b < 0 || fill_b > 255){
  414.         printf("Invalid color value!\n");
  415.         return;
  416.     }
  417.  
  418.     /* Hexagon drawing */
  419.  
  420.     float Pi = 3.141593;
  421.     int dx = R * sin(Pi / 6);
  422.     int dy = R * cos(Pi / 6);
  423.     for (int w = 0; w < cfg.width; w++){
  424.         drawLine(arr, bih, x_c + R - w, y_c, x_c + dx - w, y_c + dy, color_r, color_g, color_b);
  425.         drawLine(arr, bih, x_c + dx, y_c + dy - w, x_c - dx, y_c + dy - w, color_r, color_g, color_b);
  426.         drawLine(arr, bih, x_c - dx + w, y_c + dy, x_c - R + w, y_c, color_r, color_g, color_b);
  427.         drawLine(arr, bih, x_c - R + w, y_c, x_c - dx + w, y_c - dy, color_r, color_g, color_b);
  428.         drawLine(arr, bih, x_c - dx, y_c - dy + w, x_c + dx, y_c - dy + w, color_r, color_g, color_b);
  429.         drawLine(arr, bih, x_c + dx - w, y_c - dy, x_c + R - w, y_c, color_r, color_g, color_b);
  430.     }
  431.  
  432.     /* Hexagon fill */
  433.  
  434.     if(fillFlag == 1){
  435.         shapeFill(arr, bih, x_c, y_c, fill_r, fill_g, fill_b, color_r, color_g, color_b);
  436.     }
  437. }
  438.  
  439. void copy(Rgb** arr, BitmapInfoHeader bih, struct Configs cfg){
  440.     int x_st = cfg.copy[0], y_st = bih.height - cfg.copy[1] - 1, x_end = cfg.copy[2], y_end = bih.height - cfg.copy[3] - 1, x_c = cfg.copy[4], y_c = bih.height - cfg.copy[5] - 1;
  441.  
  442.     /* Validity check of entered coordinates */
  443.  
  444.     if(x_st < 0 || x_st >= bih.width || y_st < 0 || y_st >= bih.height || x_end < 0 || x_end >= bih.width || y_end < 0 || y_end >= bih.height || x_c < 0 || x_c >= bih.width || y_c < 0 || y_c >= bih.height){
  445.         printf("Error in option -c/--copy\n");
  446.         printf("Coordinates are out of bounds!\n");
  447.         return;
  448.     }
  449.     int dx = x_end - x_st + 1;
  450.     int dy = y_st - y_end + 1;
  451.     if(x_c+dx-1 < 0 || x_c+dx-1 >= bih.width || y_c-dx-1 < 0 || y_c-dx-1 >= bih.height){
  452.         printf("Area copying error\n");
  453.         printf("Coordinates are out of bounds!\n");
  454.         return;
  455.     }
  456.  
  457.     /* Creating a buffer array of pixels */
  458.  
  459.     Rgb** buf_arr = malloc(dy*sizeof(Rgb*));
  460.     for(int i = 0; i<dy; i++) {
  461.         buf_arr[i] = malloc(dx * sizeof(Rgb));
  462.         for(int j = 0; j<dx; j++){
  463.             buf_arr[i][j].r = arr[y_st - i][x_st + j].r;
  464.             buf_arr[i][j].g = arr[y_st - i][x_st + j].g;
  465.             buf_arr[i][j].b = arr[y_st - i][x_st + j].b;
  466.         }
  467.     }
  468.  
  469.     /* Place the copied area in the resulting location */
  470.  
  471.     for(int i = 0; i<dy; i++){
  472.         for(int j = 0; j<dx; j++){
  473.             arr[y_c - i][x_c + j].r = buf_arr[i][j].r;
  474.             arr[y_c - i][x_c + j].g = buf_arr[i][j].g;
  475.             arr[y_c - i][x_c + j].b = buf_arr[i][j].b;
  476.         }
  477.     }
  478.     for(int u = 0; u<dy; u++){
  479.         free(buf_arr[u]);
  480.     }
  481.     free(buf_arr);
  482. }
  483.  
  484. int main(int argc, char* argv[]) {
  485.     struct Configs opts = {0, 0, 0, 0, 0, 0, 0, "", "output.bmp", 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  486.     optsProcess(argc, argv, &opts);
  487.     if (!strcmp(opts.name, "")) {
  488.         puts("No file on input!\nPlease enter -h for more information");
  489.         return 0;
  490.     }
  491.     if(opts.cfg_error_flag == 1){
  492.         puts("Invalid input format!");
  493.         return 0;
  494.     }
  495.  
  496.     /* Validation of the file type being processed */
  497.  
  498.     if(strstr(opts.name, ".bmp") == NULL){
  499.         puts("Invalid file format");
  500.         return 0;
  501.     }
  502.     FILE *f = fopen(opts.name, "rb");
  503.     if(f == NULL){
  504.         puts("No such file!");
  505.         return 0;
  506.     }
  507.     BitmapFileHeader bfh;
  508.     BitmapInfoHeader bih;
  509.  
  510.     /* Reading file headers and pixel map */
  511.  
  512.     fread(&bfh, 1, sizeof(BitmapFileHeader), f);
  513.     fread(&bih, 1, sizeof(BitmapInfoHeader), f);
  514.     if(bih.headerSize != 40 || bih.bitsPerPixel != 24){
  515.         puts("Invalid file version! Please use V3 version");
  516.         return 0;
  517.     }
  518.     unsigned int H = bih.height;
  519.     unsigned int W = bih.width;
  520.     Rgb **arr = malloc(H * sizeof(Rgb *));
  521.     int offset = (W * sizeof(Rgb)) % 4;
  522.     offset = offset ? 4 - offset : 0;
  523.     for (int i = 0; i < H; i++) {
  524.         arr[i] = malloc(W * sizeof(Rgb) + offset);
  525.         fread(arr[i], 1, W * sizeof(Rgb) + offset, f);
  526.     }
  527.  
  528.     /* Opening the resulting file */
  529.  
  530.     FILE *ff = fopen(opts.output_name, "wb");
  531.  
  532.     /* Calling functions by option flags */
  533.  
  534.     if(opts.infoFlag == 1){
  535.         printFileHeader(bfh);
  536.         printInfoHeader(bih);
  537.     }
  538.     if(opts.rectangleFlag == 1){
  539.         drawRectangle(arr, bih, opts);
  540.     }
  541.     if(opts.squarehexFlag == 1 || opts.circlehexFlag == 1){
  542.         drawHexagon(arr, bih, opts);
  543.     }
  544.     if(opts.copyFlag == 1){
  545.         copy(arr, bih, opts);
  546.     }
  547.  
  548.     /* Writing headers and pixel maps to the resulting file */
  549.  
  550.     fwrite(&bfh, 1, sizeof(BitmapFileHeader), ff);
  551.     fwrite(&bih, 1, sizeof(BitmapInfoHeader), ff);
  552.     unsigned int w = (W) * sizeof(Rgb) + offset;
  553.     for (int i = 0; i < H; i++) {
  554.         fwrite(arr[i], 1, w, ff);
  555.     }
  556.     for (int i = 0; i < H; i++) {
  557.         free(arr[i]);
  558.     }
  559.     free(arr);
  560.     fclose(ff);
  561.     fclose(f);
  562.     return 0;
  563. }
Add Comment
Please, Sign In to add comment