Advertisement
LilChicha174

Untitled

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