Advertisement
LilChicha174

Untitled

Jun 6th, 2022
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 24.47 KB | None | 0 0
  1. #include <unistd.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <stdarg.h>
  5. #include <math.h>
  6. #include <png.h>
  7.  
  8. #define PNG_DEBUG 3
  9.  
  10. #include <string.h>
  11. #include <getopt.h>
  12.  
  13.  
  14. struct Png {
  15.     int width, height;
  16.     png_byte color_type;
  17.     png_byte bit_depth;
  18.  
  19.     png_structp png_ptr;
  20.     png_infop info_ptr;
  21.     int number_of_passes;
  22.     png_bytep *row_pointers;
  23. };
  24.  
  25. struct Configs {
  26.     int x1, y1;
  27.     int x2, y2;
  28.     int x3, y3;
  29.     int line_fat;
  30.     int line_color_r, line_color_g, line_color_b;
  31.     int paint_color_r, paint_color_g, paint_color_b;
  32.     int is_pour;
  33.     int xPhoto, yPhoto;
  34.     char *output;
  35. };
  36.  
  37.  
  38. void printHelp() {
  39.     printf("Это программа с CLI для редактирования png файлов\n");
  40.     printf("Формат ввода: [имя исходного файла] ./a.out  [функция] "
  41.            "-[ключ1]/--[полный ключ1] [аргумент1] ...\n\n");
  42.     printf("Функции/ключи:\n");
  43.     printf("triangle [имя файла] - рисование треугольника с возможностью его залить и "
  44.            "выбрать "
  45.            "цвет.\n");
  46.     printf("    -f/--first  [<x-координата>.<y-координата>] - первая вершина треугольника\n");
  47.     printf("    -s/--second  [<x-координата>.<y-координата>] - вторая вершина треугольника\n");
  48.     printf("    -t/--third [<x-координата>.<y-координата>] - третья вершина треугольника\n");
  49.     printf("    -l/--lineFat [<число>] - толщина сторон треугольника(в пикселях)\n");
  50.     printf("    -r/--range [<число>.<число>.<число>] - цвет сторон треугольника (RGB)\n");
  51.     printf("    -C/--color [<число>.<число>.<число>] - цвет заливки треугольника (RGB)\n");
  52.     printf("    -с/--cast - заливка треугольника (по умолчанию без заливки)\n");
  53.     printf("line [имя файла] - рисование прямой линии.\n");
  54.     printf("    -f/--first  [<x-координата>.<y-координата>] - начало линии\n");
  55.     printf("    -s/--second  [<x-координата>.<y-координата>] - конец линии\n");
  56.     printf("    -l/--lineFat [<число>] - толщина линии(в пикселях)\n");
  57.     printf("    -C/--color [<число>.<число>.<число>] - цвет линии (RGB)\n");
  58.     printf("collage [имя файла] - создается коллаж из изображения.\n");
  59.     printf("    -x/--xPhoto  [<число>] - количество изображений по оси X\n");
  60.     printf("    -y/--yPhoto  [<число>] - количество изображений по оси Y\n");
  61.     printf("rectangle [имя файла] - поиск самого большого прямоугольника заданного цвета и его "
  62.            "перекраска в заданный цвет.\n");
  63.     printf("    -C/--color [<число>.<число>.<число>] - цвет перекраски (RGB)\n");
  64.     printf("    -r/--range [<число>.<число>.<число>] - цвет искомого прямоугольника (RGB)\n");
  65.     printf("-h/--help - вывод справки о работе программы.\n");
  66.     printf("-o/--output [путь] - файл для вывода (по умолчанию исходный файл)\n");
  67. }
  68.  
  69. void information(struct Png *image) {
  70.     printf("info about input picture:\n");
  71.     printf("width:\t%d\n", image->width);
  72.     printf("height:\t%d\n", image->height);
  73.     printf("bit depth:\t%u\n", image->bit_depth);
  74.     printf("color type:\t%u\n", image->color_type);
  75.     printf("\ttypes:\n"
  76.            "\t0 - grayscale\n"
  77.            "\t2 - RGB\n"
  78.            "\t4 - grayscale with alpha\n"
  79.            "\t6 - RGBA\n");
  80.  
  81. }
  82.  
  83.  
  84. void read_png_file(char *file_name, struct Png *image) {
  85.     int x, y;
  86.     char header[8];    // 8 is the maximum size that can be checked
  87.  
  88.     /* open file and test for it being a png */
  89.     FILE *fp = fopen(file_name, "rb");
  90.     if (!fp) {
  91.         // Some error handling: file could not be opened
  92.         printf("Ошибка открытия файла на чтение!\n");
  93.     }
  94.  
  95.     fread(header, 1, 8, fp);
  96.     if (png_sig_cmp(header, 0, 8)) {
  97.         printf("Это не PNG файл!\n");
  98.         exit(-1);
  99.     }
  100.  
  101.     /* initialize stuff */
  102.     image->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  103.  
  104.     if (!image->png_ptr) {
  105.         printf("png_create_read_struct failed\n");
  106.         exit(-1);
  107.     }
  108.  
  109.     image->info_ptr = png_create_info_struct(image->png_ptr);
  110.     if (!image->info_ptr) {
  111.         printf("png_create_read_struct failed\n");
  112.         exit(-1);
  113.     }
  114.  
  115.     if (setjmp(png_jmpbuf(image->png_ptr))) {
  116.         printf("error during init_io\n");
  117.         exit(-1);
  118.     }
  119.  
  120.     png_init_io(image->png_ptr, fp);
  121.     png_set_sig_bytes(image->png_ptr, 8);
  122.  
  123.     png_read_info(image->png_ptr, image->info_ptr);
  124.  
  125.     image->width = png_get_image_width(image->png_ptr, image->info_ptr);
  126.     image->height = png_get_image_height(image->png_ptr, image->info_ptr);
  127.     image->color_type = png_get_color_type(image->png_ptr, image->info_ptr);
  128.     image->bit_depth = png_get_bit_depth(image->png_ptr, image->info_ptr);
  129.  
  130.     image->number_of_passes = png_set_interlace_handling(image->png_ptr);
  131.     png_read_update_info(image->png_ptr, image->info_ptr);
  132.  
  133.     /* read file */
  134.     if (setjmp(png_jmpbuf(image->png_ptr))) {
  135.         // Some error handling: error during read_image
  136.         printf("error during read_image\n");
  137.         exit(-1);
  138.     }
  139.  
  140.     image->row_pointers = (png_bytep *) malloc(sizeof(png_bytep) * image->height);
  141.     for (y = 0; y < image->height; y++)
  142.         image->row_pointers[y] = (png_byte *) malloc(
  143.                 png_get_rowbytes(image->png_ptr, image->info_ptr));
  144.  
  145.     png_read_image(image->png_ptr, image->row_pointers);
  146.  
  147.     fclose(fp);
  148. }
  149.  
  150.  
  151. void write_png_file(char *file_name, struct Png *image) {
  152.     int x, y;
  153.     FILE *fp = fopen(file_name, "wb");
  154.  
  155.     if (!fp) {
  156.         printf("Ошибка открытия результирующего файла!\n");
  157.         exit(-1);
  158.     }
  159.  
  160.     /* initialize stuff */
  161.     image->png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  162.  
  163.     if (!image->png_ptr) {
  164.         printf("png_create_write_struct failed\n");
  165.         exit(-1);
  166.     }
  167.  
  168.     image->info_ptr = png_create_info_struct(image->png_ptr);
  169.     if (!image->info_ptr) {
  170.         // Some error handling: png_create_info_struct failed
  171.         printf("png_create_info_struct failed\n");
  172.         exit(-1);
  173.     }
  174.  
  175.     if (setjmp(png_jmpbuf(image->png_ptr))) {
  176.         printf("error during init_io\n");
  177.         exit(-1);
  178.     }
  179.  
  180.     png_init_io(image->png_ptr, fp);
  181.  
  182.  
  183.     /* write header */
  184.     if (setjmp(png_jmpbuf(image->png_ptr))) {
  185.         // Some error handling: error during writing header
  186.         printf("error during writing header\n");
  187.         exit(-1);
  188.     }
  189.  
  190.     png_set_IHDR(image->png_ptr, image->info_ptr, image->width, image->height,
  191.                  image->bit_depth, image->color_type, PNG_INTERLACE_NONE,
  192.                  PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
  193.  
  194.     png_write_info(image->png_ptr, image->info_ptr);
  195.  
  196.  
  197.     /* write bytes */
  198.     if (setjmp(png_jmpbuf(image->png_ptr))) {
  199.         printf("Ошибка чтения байтов!\n");
  200.         exit(-1);
  201.     }
  202.  
  203.     png_write_image(image->png_ptr, image->row_pointers);
  204.  
  205.  
  206.     /* end write */
  207.     if (setjmp(png_jmpbuf(image->png_ptr))) {
  208.         printf("error during end of write\n");
  209.     }
  210.  
  211.     png_write_end(image->png_ptr, NULL);
  212.  
  213.     /* cleanup heap allocation */
  214.     for (y = 0; y < image->height; y++)
  215.         free(image->row_pointers[y]);
  216.     free(image->row_pointers);
  217.  
  218.     fclose(fp);
  219. }
  220.  
  221. void paint_pixel(struct Png *image, int x, int y, int width_pixel, int Red, int Green, int Blue) {
  222.     if (x < 0 || x >= image->width || y < 0 || y >= image->height)
  223.         return;
  224.     png_byte *row = image->row_pointers[y];
  225.     png_byte *ptr = &(row[x * width_pixel]);
  226.     ptr[0] = Red;
  227.     ptr[1] = Green;
  228.     ptr[2] = Blue;
  229. }
  230.  
  231. // Рисование круга(для толщины линии)
  232. void draw_Circle(struct Png *image, int x0, int y0, int line_fat, int width_pixel, int Red,
  233.                  int
  234.                  Green,
  235.                  int Blue) {
  236.     int x = 0;
  237.     int radius = line_fat / 2;
  238.     int y = radius;
  239.     int start = y0 - radius;
  240.     int end = y0 + radius;
  241.     int delta = 1 - 2 * radius;
  242.     int error;
  243.     while (y >= 0) {
  244.         paint_pixel(image, x0 + x, y0 + y, width_pixel, Red, Green, Blue);
  245.  
  246.         paint_pixel(image, x0 + x, y0 - y, width_pixel, Red, Green, Blue);
  247.  
  248.         paint_pixel(image, x0 - x, y0 + y, width_pixel, Red, Green, Blue);
  249.  
  250.         paint_pixel(image, x0 - x, y0 - y, width_pixel, Red, Green, Blue);
  251.  
  252.         error = 2 * (delta + y) - 1;
  253.         while (start <= y0) {
  254.             for (int i = abs(x - x0); i < (x + x0); i++) {
  255.                 paint_pixel(image, i, start, width_pixel, Red, Green, Blue);
  256.  
  257.                 paint_pixel(image, i, end, width_pixel, Red, Green, Blue);
  258.             }
  259.             if (error > 0) {
  260.                 start++;
  261.                 end--;
  262.             }
  263.             break;
  264.         }
  265.         if (delta < 0 && error <= 0) {
  266.             ++x;
  267.             delta += 2 * x + 1;
  268.             continue;
  269.         }
  270.         error = 2 * (delta - x) - 1;
  271.         if (delta > 0 && error > 0) {
  272.             --y;
  273.             delta += 1 - 2 * y;
  274.             continue;
  275.         }
  276.         ++x;
  277.         delta += 2 * (x - y);
  278.         --y;
  279.     }
  280. }
  281.  
  282. void paint_line(struct Png *image, int width_pixel, int x0, int y0, int x1, int y1, int line_fat,
  283.                 int Red, int Green, int Blue) {
  284.     int A, B, sign;
  285.     A = y1 - y0;
  286.     B = x0 - x1;
  287.     if (abs(A) > abs(B)) sign = 1;
  288.     else sign = -1;
  289.     int signa, signb;
  290.     if (A < 0) signa = -1;
  291.     else signa = 1;
  292.     if (B < 0) signb = -1;
  293.     else signb = 1;
  294.     int f = 0;
  295.  
  296.     paint_pixel(image, x0, y0, width_pixel, Red, Green, Blue);
  297.     draw_Circle(image, x0, y0, line_fat, width_pixel, Red, Green, Blue);
  298.     int x = x0, y = y0;
  299.     if (sign == -1) {
  300.         do {
  301.             f += A * signa;
  302.             if (f > 0) {
  303.                 f -= B * signb;
  304.                 y += signa;
  305.             }
  306.             x -= signb;
  307.             paint_pixel(image, x, y, width_pixel, Red, Green, Blue);
  308.             draw_Circle(image, x, y, line_fat, width_pixel, Red, Green, Blue);
  309.         } while (x != x1 || y != y1);
  310.     } else {
  311.         do {
  312.             f += B * signb;
  313.             if (f > 0) {
  314.                 f -= A * signa;
  315.                 x -= signb;
  316.             }
  317.             y += signa;
  318.             paint_pixel(image, x, y, width_pixel, Red, Green, Blue);
  319.             draw_Circle(image, x, y, line_fat, width_pixel, Red, Green, Blue);
  320.         } while (x != x1 || y != y1);
  321.     }
  322. }
  323.  
  324. // проверка, находится ли текущий пиксель внутри треугольника
  325. int is_inside(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
  326.     int one = (x1 - x0) * (y2 - y1) - (x2 - x1) * (y1 - y0);
  327.     int two = (x2 - x0) * (y3 - y2) - (x3 - x2) * (y2 - y0);
  328.     int three = (x3 - x0) * (y1 - y3) - (x1 - x3) * (y3 - y0);
  329.     if ((one < 0 && two < 0 && three < 0) || (one > 0 && two > 0 && three > 0)) {
  330.         return 1;
  331.     }
  332.     return 0;
  333. }
  334.  
  335. int check(struct Png *image, int x, int y) {
  336.     if (x < 0 || x >= image->width || y < 0 || y >= image->height)
  337.         return 0;
  338.     return 1;
  339. }
  340.  
  341. int is_not_painted_rect(struct Png *image, int width_pixel, int x, int y, int Red, int Green, int
  342. Blue) {
  343.     png_byte *row = image->row_pointers[y];
  344.     png_byte *ptr = &(row[x * width_pixel]);
  345.     if ((ptr[0] == Red) && (ptr[1] == Green) && (ptr[2] == Blue)) {
  346.         return 0;
  347.     }
  348.     return 1;
  349. }
  350.  
  351. //проверка, покрашен ли уже пиксель при заливке треугольника (внутри и на линии)
  352. int is_not_painted(struct Png *image, int width_pixel, int x, int y, int Red_p, int Green_p, int
  353. Blue_p, int Red_l, int Green_l, int Blue_l) {
  354.     if (!check(image, x, y))
  355.         return 0;
  356.     png_byte *row = image->row_pointers[y];
  357.     png_byte *ptr = &(row[x * width_pixel]);
  358.     int one = (ptr[0] == Red_p) && (ptr[1] == Green_p) && (ptr[2] == Blue_p);
  359.     int two = (ptr[0] == Red_l) && (ptr[1] == Green_l) && (ptr[2] == Blue_l);
  360.     if (one || two) {
  361.         return 0;
  362.     }
  363.     return 1;
  364. }
  365.  
  366. // рекурсивная заливка треугольника
  367. void pouring_triangle(struct Png *image, int width_pixel, int x_c, int y_c, int x1, int y1, int x2,
  368.                       int y2,
  369.                       int x3, int y3, int Red, int Green, int Blue, int Red_l, int Green_l,
  370.                       int Blue_l) {
  371.     if (is_inside(x_c, y_c, x1, y1, x2, y2, x3, y3) && is_not_painted(image, width_pixel, x_c,
  372.                                                                       y_c, Red, Green, Blue, Red_l,
  373.                                                                       Green_l, Blue_l)) {
  374.         paint_pixel(image, x_c, y_c, width_pixel, Red, Green, Blue);
  375.         pouring_triangle(image, width_pixel, x_c + 1, y_c, x1, y1, x2, y2, x3, y3, Red, Green, Blue,
  376.                          Red_l,
  377.                          Green_l, Blue_l);
  378.         pouring_triangle(image, width_pixel, x_c, y_c + 1, x1, y1, x2, y2, x3, y3, Red, Green, Blue,
  379.                          Red_l,
  380.                          Green_l, Blue_l);
  381.         pouring_triangle(image, width_pixel, x_c - 1, y_c, x1, y1, x2, y2, x3, y3, Red, Green, Blue,
  382.                          Red_l,
  383.                          Green_l, Blue_l);
  384.         pouring_triangle(image, width_pixel, x_c, y_c - 1, x1, y1, x2, y2, x3, y3, Red, Green, Blue,
  385.                          Red_l,
  386.                          Green_l, Blue_l);
  387.     }
  388. }
  389.  
  390.  
  391. void draw_triangle(struct Png *image, int width_pixel, int x1, int y1, int x2, int y2, int x3, int
  392. y3, int line_fat, int is_pour, int Red_l, int Green_l, int Blue_l, int Red_p, int Green_p,
  393.                    int Blue_p) {
  394.     paint_line(image, width_pixel, x1, y1, x2, y2, line_fat, Red_l, Green_l, Blue_l);
  395.     paint_line(image, width_pixel, x2, y2, x3, y3, line_fat, Red_l, Green_l, Blue_l);
  396.     paint_line(image, width_pixel, x3, y3, x1, y1, line_fat, Red_l, Green_l, Blue_l);
  397.     if (is_pour) {
  398.         int x_c = (x1 + x2 + x3) / 3;
  399.         int y_c = (y1 + y2 + y3) / 3;
  400.         pouring_triangle(image, width_pixel, x_c, y_c, x1, y1, x2, y2, x3, y3, Red_p, Green_p,
  401.                          Blue_p, Red_l,
  402.                          Green_l, Blue_l);
  403.     }
  404. }
  405.  
  406. // перенос пикселя при создании коллажа
  407. void replace(png_byte *new_pixel, png_byte *old_pixel, int width_pixel) {
  408.     for (int i = 0; i < width_pixel; i++) {
  409.         new_pixel[i] = old_pixel[i];
  410.     }
  411. }
  412.  
  413. void make_collage(struct Png *image, int width_pixel, int x_photos, int y_photos) {
  414.     int new_width = image->width * x_photos;
  415.     int new_height = image->height * y_photos;
  416.  
  417.     png_byte **new_mas = (png_byte **) malloc(sizeof(png_byte * ) * new_height);
  418.     for (int y = 0; y < new_height; y++)
  419.         new_mas[y] = (png_byte *) malloc(sizeof(png_byte) * new_width * width_pixel);
  420.     for (int y = 0; y < new_height; y++) {
  421.         int old_y = y % image->height;
  422.         png_byte *old_row = image->row_pointers[old_y];
  423.         png_byte *new_row = new_mas[y];
  424.         for (int x = 0; x < new_width; x++) {
  425.             int old_x = x % image->width;
  426.             png_byte *old_pixel = &(old_row[old_x * width_pixel]);
  427.             png_byte *new_pixel = &(new_row[x * width_pixel]);
  428.             replace(new_pixel, old_pixel, width_pixel);
  429.         }
  430.     }
  431.     for (int x = 0; x < image->height; x++) {
  432.         free(image->row_pointers[x]);
  433.     }
  434.     free(image->row_pointers);
  435.  
  436.     image->row_pointers = new_mas;
  437.     image->width = new_width;
  438.     image->height = new_height;
  439. }
  440.  
  441. int check_X_Y(struct Png *image, int x0, int y0, int *x1, int *y1, int *x2, int *y2, int *x3, int
  442. *y3, int *x4, int *y4, int width_pixel, int red0, int green0, int blue0) {
  443.     int x1t = 0, y1t = 0, x2t = 0, y2t = 0, x3t = 0, y3t = 0, x4t = 0, y4t = 0;
  444.     int flag = 0;
  445.     png_byte *row = image->row_pointers[y0];
  446.     for (int x = x0; x < image->width; x++) {
  447.         png_byte *ptr = &(row[x * width_pixel]);
  448.         if (ptr[0] == red0 && ptr[1] == green0 && ptr[2] == blue0) {
  449.             if (flag == 0) {
  450.                 x1t = x, y1t = y0;
  451.                 flag++;
  452.             }
  453.         } else {
  454.             if (x != (x0 + 1)) {
  455.                 x2t = x - 1, y2t = y0;
  456.                 flag++;
  457.                 break;
  458.             } else {
  459.                 return 0;
  460.             }
  461.         }
  462.     }
  463.     for (int y = y0; y < image->height; y++) {
  464.         png_byte *row = image->row_pointers[y];
  465.         png_byte *ptr = &(row[x0 * width_pixel]);
  466.         if (ptr[0] != red0 || ptr[1] != green0 || ptr[2] != blue0) {
  467.             if (y != (y0 + 1) && flag == 2) {
  468.                 y3t = y - 1, x3t = x0;
  469.                 flag++;
  470.             }
  471.         }
  472.     }
  473.     for (int y = y0; y < image->height; y++) {
  474.         png_byte *row = image->row_pointers[y];
  475.         png_byte *ptr = &(row[x1t * width_pixel]);
  476.         if (ptr[0] != red0 || ptr[1] != green0 || ptr[2] != blue0) {
  477.             if (y != (y0 + 1) && flag == 3) {
  478.                 y4t = y - 1, x4t = x2t;
  479.                 flag++;
  480.             }
  481.         }
  482.     }
  483.     if (y4t != y3t)
  484.         return 0;
  485.     row = image->row_pointers[y3t];
  486.  
  487.     for (int x = x3t; x < x4t; x++) {
  488.         png_byte *ptr = &(row[x * width_pixel]);
  489.         if (ptr[0] != red0 || ptr[1] != green0 || ptr[2] != blue0) {
  490.             return 0;
  491.         }
  492.     }
  493.     *x1 = x1t, *y1 = y1t;
  494.     *x2 = x2t, *y2 = y2t;
  495.     *x3 = x3t, *y3 = y3t;
  496.     *x4 = x4t, *y4 = y4t;
  497.     return 1;
  498.  
  499. }
  500.  
  501. //перекраска прямоугольника
  502. void pouring_rectangle(struct Png *image, int width_pixel, int x, int y, int Red, int Green, int
  503. Blue, int Red_l, int Green_l, int Blue_l) {
  504.     png_byte *row;
  505.     png_byte *ptr;
  506.     if (check(image, x, y)) {
  507.         row = image->row_pointers[y];
  508.         ptr = &(row[x * width_pixel]);
  509.         if ((ptr[0] == Red_l) && (ptr[1] == Green_l) && (ptr[2] == Blue_l)) {
  510.             return;
  511.         }
  512.     } else return;
  513.     if ((ptr[0] == Red) && (ptr[1] == Green) && (ptr[2] == Blue)) {
  514.         paint_pixel(image, x, y, width_pixel, Red_l, Green_l, Blue_l);
  515.         pouring_rectangle(image, width_pixel, x + 1, y, Red, Green, Blue, Red_l, Green_l, Blue_l);
  516.         pouring_rectangle(image, width_pixel, x - 1, y, Red, Green, Blue, Red_l, Green_l, Blue_l);
  517.         pouring_rectangle(image, width_pixel, x, y + 1, Red, Green, Blue, Red_l, Green_l, Blue_l);
  518.         pouring_rectangle(image, width_pixel, x, y - 1, Red, Green, Blue, Red_l, Green_l, Blue_l);
  519.     }
  520. }
  521.  
  522. // поиск прямоугольника макс площади
  523. int is_rectangle(struct Png *image, int width_pixel, int red0, int green0, int blue0, int red1, int
  524. green1, int blue1) {
  525.     int x1, y1, x2, y2, x3, y3, x4, y4;
  526.     int square, square_max = 0;
  527.     int x1_max, y1_max, x2_max, y2_max, x3_max, y3_max, x4_max, y4_max;
  528.     for (int y = 0; y < image->height; y++) {
  529.         png_byte *row = image->row_pointers[y];
  530.         for (int x = 0; x < image->width; x++) {
  531.             png_byte *ptr = &(row[x * width_pixel]);
  532.             if (ptr[0] == red0 && ptr[1] == green0 && ptr[2] == blue0) {
  533.                 if (check_X_Y(image, x, y, &x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4,
  534.                               width_pixel, red0, green0, blue0)) {
  535.                     int square = sqrt((x2 - x1) * (x2 - x1)) * sqrt((y3 - y1) * (y3 - y1));
  536.                     if (square > square_max) {
  537.                         square_max = square;
  538.                         x1_max = x1, y1_max = y1, x2_max = x2, y2_max = y2, x3_max = x3, y3_max =
  539.                                 y3, x4_max = x4, y4_max = y4;
  540.                     }
  541.                 }
  542.             }
  543.         }
  544.     }
  545.     pouring_rectangle(image, width_pixel, x1_max, y1_max, red0, green0, blue0, red1, green1, blue1);
  546.     return 0;
  547. }
  548.  
  549. // расстановка конфигураций, переданных через флаги в getopt
  550. void cfg(int **arr, int kl, char *opt) {
  551.     char *str1;
  552.     str1 = strtok(opt, ".");
  553.     *(arr[0]) = atoi(str1);
  554.     for (int i = 1; i < kl; i++) {
  555.         str1 = strtok(NULL, ".");
  556.         *(arr[i]) = atoi(str1);
  557.     }
  558. }
  559.  
  560.  
  561. void choice(struct Configs *config, int opt) {
  562.     char *str1;
  563.     int **arr = malloc(3 * sizeof(int *));
  564.     switch (opt) {
  565.         case 'r':
  566.             arr[0] = &(config->line_color_r), arr[1] = &(config->line_color_g), arr[2] = &
  567.                     (config->line_color_b);
  568.             cfg(arr, 3, optarg);
  569.             break;
  570.         case 'f':
  571.             arr[0] = &(config->x1), arr[1] = &(config->y1);
  572.             cfg(arr, 2, optarg);
  573.             break;
  574.         case 's':
  575.             arr[0] = &(config->x2), arr[1] = &(config->y2);
  576.             cfg(arr, 2, optarg);
  577.             break;
  578.         case 't':
  579.             arr[0] = &(config->x3), arr[1] = &(config->y3);
  580.             cfg(arr, 2, optarg);
  581.             break;
  582.         case 'l':
  583.             config->line_fat = atoi(optarg);
  584.             break;
  585.         case 'C':
  586.             arr[0] = &(config->paint_color_r), arr[1] = &(config->paint_color_g), arr[2] = &
  587.                     (config->paint_color_b);
  588.             cfg(arr, 3, optarg);
  589.             break;
  590.         case 'c':
  591.             config->is_pour = 1;
  592.             break;
  593.         case 'x':
  594.             config->xPhoto = atoi(optarg);
  595.             break;
  596.         case 'y':
  597.             config->yPhoto = atoi(optarg);
  598.             break;
  599.         case 'o':
  600.             config->output = optarg;
  601.             break;
  602.         case 'h':
  603.             printHelp();
  604.             exit(-1);
  605.             break;
  606.     }
  607. }
  608.  
  609. int main(int argc, char **argv) {
  610.  
  611.     char *opts = "f:s:t:l:C:cx:y:o:hr:";
  612.     char *output = argv[1];
  613.     struct Configs config = {0, 0, 0, 0, 0, 0, 0, 0, 0,
  614.                              0, 0, 0, 0, 0,
  615.                              0, 0, output};
  616.     struct Png image;
  617.     char *func = argv[2];
  618.     char *file = argv[1];
  619.     struct option longOpts[] = {
  620.             {"first",   required_argument, NULL, 'f'},
  621.             {"second",  required_argument, NULL, 's'},
  622.             {"third",   required_argument, NULL, 't'},
  623.             {"lineFat", required_argument, NULL, 'l'},
  624.             {"color",   required_argument, NULL, 'C'},
  625.             {"cast",    no_argument,       NULL, 'c'},
  626.             {"xPhoto",  required_argument, NULL, 'x'},
  627.             {"yPhoto",  required_argument, NULL, 'y'},
  628.             {"output",  required_argument, NULL, 'o'},
  629.             {"help",    no_argument,       NULL, 'h'},
  630.             {"range",   required_argument, NULL, 'r'},
  631.             {NULL,      no_argument,       NULL, 0}
  632.     };
  633.     int opt;
  634.     int longIndex;
  635.     opt = getopt_long(argc, argv, opts, longOpts, &longIndex);
  636.     while (opt != -1) {
  637.         choice(&config, opt);
  638.         opt = getopt_long(argc, argv, opts, longOpts, &longIndex);
  639.     }
  640.     read_png_file(file, &image);
  641.     information(&image);
  642.     if (!strcmp(func, "triangle")) {
  643.         draw_triangle(&image, 3, config.x1, config.y1, config.x2, config.y2, config.x3,
  644.                       config.y3, config.line_fat, config.is_pour, config.line_color_r,
  645.                       config.line_color_g,
  646.                       config.line_color_b, config.paint_color_r, config.paint_color_g,
  647.                       config.paint_color_b);
  648.     }
  649.     if (!strcmp(func, "line")) {
  650.         paint_line(&image, 3, config.x1, config.y1, config.x2, config.y2, config.line_fat,
  651.                    config.paint_color_r, config.paint_color_g, config.paint_color_b);
  652.     }
  653.     if (!strcmp(func, "collage")) {
  654.         make_collage(&image, 3, config.xPhoto, config.yPhoto);
  655.     }
  656.     if (!strcmp(func, "rectangle")) {
  657.         is_rectangle(&image, 3, config.line_color_r, config.line_color_g, config
  658.                 .line_color_b, config.paint_color_r, config.paint_color_g, config.paint_color_b);
  659.     }
  660.  
  661.  
  662.     write_png_file(config.output, &image);
  663.     return 0;
  664. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement