Advertisement
Elsas

aasaas

Apr 8th, 2020
209
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.14 KB | None | 0 0
  1. #pragma warning(disable : 4996)
  2. #include <cstdio>
  3. #include <cmath>
  4. #include <iostream>
  5.  
  6. int type, h, w, max;
  7. unsigned char *pixels;
  8.  
  9. //useful functions
  10. template <class T>
  11. void swap(T& a, T& b)
  12. {
  13.     T tmp = a;
  14.     a = b;
  15.     b = tmp;
  16. }
  17.  
  18. float CharTofloat(char *strnum)
  19. {
  20.     float num = 0;
  21.     int i, j;
  22.     for (i = 0; strnum[i] != '\0' && strnum[i] != '.'; i++)
  23.         num = num * 10 + strnum[i] - '0';
  24.     if (strnum[i] == '\0')
  25.         return num;
  26.  
  27.     for (j = 0; strnum[j + i + 1] != '\0'; j++)
  28.         num = num * 10 + strnum[j + i + 1] - '0';
  29.     for (int k = 0; k < j; k++)
  30.         num /= 10;
  31.  
  32.     return num;
  33. }
  34.  
  35. template <class T>
  36. T sign(T num) { return num < 0 ? -1 : num > 0 ? 1 : 0; }
  37.  
  38. bool OnPic(int coord_x, int coord_y) { return coord_x > 0 && coord_x < w && coord_y > 0 && coord_y < h; }
  39.  
  40. int Rounding(float num) { return (int)(sign(num) * (fabs(num) + 0.5)); }
  41.  
  42. //file check
  43. int ReadFile(char* filename)
  44. {
  45.     FILE *f;
  46.  
  47.     // file checking (closing file)
  48.     if ((f = fopen(filename, "rb")) == NULL)
  49.     {
  50.         printf("Put another filename!\n");
  51.         fclose(f);
  52.         return 0;
  53.     }
  54.  
  55.     if (fscanf(f, "P%i%i%i%i\n", &type, &w, &h, &max) == NULL)
  56.     {
  57.         printf("Can't read this file\n");
  58.         fclose(f);
  59.         return 0;
  60.     }
  61.  
  62.     // data checking (closing file)
  63.     if (h < 1 || w < 1)
  64.     {
  65.         printf("Wrong heigh or width\n");
  66.         fclose(f);
  67.         return 0;
  68.     }
  69.  
  70.     if (type != 5 && type != 6)
  71.     {
  72.         printf("Wrong filetype\n");
  73.         fclose(f);
  74.         return 0;
  75.     }
  76.  
  77.     if (max != 255)
  78.     {
  79.         printf("Wrong value of max color\n");
  80.         fclose(f);
  81.         return 0;
  82.     }
  83.     unsigned char check;
  84.     pixels = new unsigned char[w * h];
  85.  
  86.     //memory checking (closing file and deleting array)
  87.     if (pixels == nullptr)
  88.     {
  89.         printf("Not enoudh memory!\n");
  90.         delete[]pixels;
  91.         fclose(f);
  92.         return 0;
  93.     }
  94.  
  95.     //data checking (closing file and deleting array)
  96.     if (fread(pixels, 1, w * h, f) < w * h)
  97.     {
  98.         printf("Not enougth pixels\n");
  99.         delete[]pixels;
  100.         fclose(f);
  101.         return 0;
  102.     }
  103.  
  104.     if (fread(&check, 1, 1, f) == 1)
  105.     {
  106.         printf("Too much pixels\n");
  107.         delete[]pixels;
  108.         fclose(f);
  109.         return 0;
  110.     }
  111.  
  112.     fclose(f);
  113.     return 1;
  114. }
  115.  
  116. int WriteFile(char* filename)
  117. {
  118.     FILE* f;
  119.  
  120.     if ((f = fopen(filename, "wb")) == NULL)
  121.     {
  122.         printf("Can't open output file\n");
  123.         delete[] pixels;
  124.         return 0;
  125.     }
  126.  
  127.     fprintf(f, "P%i\n%i %i\n%i\n", type, w, h, max);
  128.     fwrite(pixels, 1, w * h, f);
  129.  
  130.     fclose(f);
  131.     return 1;
  132. }
  133.  
  134. //graphic fucntions
  135. float Correction(float color, float g) { return (g != 0) ? pow(color / max, 1 / g) * max : (color / max <= 0.0031308) ? 12.92 * color : (pow(1.055 * color / max, 1 / 2.4) - 0.055) * max; }
  136.  
  137. float ToNormal(float color, float g) { return (g != 0) ? pow(color / max, g) * max : (color / max <= 12.92 * 0.0031308) ? color / 12.92 : pow((color / max + 0.055), 2.4) / 1.055 * max; }
  138.  
  139. float TrueColor(float color) { return color < 0 ? 0 : color > max ? max : color; }
  140.  
  141. void PutPoint(float x, float y, float color, float g, float intensity)
  142. {
  143.     if (OnPic(x, y))
  144.         pixels[Rounding(y * w + x)] = (int)TrueColor(Correction(ToNormal(pixels[Rounding(y * w + x)], g) * (1 - intensity) + color * intensity, g));
  145. }
  146.  
  147. //easy line
  148. void VerticalLine(float x1, float y1, float x2, float y2, int color, float g, float thickness)
  149. {
  150.     if ((int)thickness % 2 != 0 && (int)thickness == 0)
  151.         for (int j = y1; j != y2; j += sign(y2 - y1))
  152.             for (int i = -thickness / 2; i <= thickness / 2; i++)
  153.                 PutPoint(x1 + i, j, color, g, (1.0 - fabs(i) / thickness * 2.0 / 3.0));
  154.     else
  155.         for (int j = y1; j != y2; j += sign(y2 - y1))
  156.             for (int i = -thickness / 2; i < thickness / 2; i++)
  157.                 PutPoint(x1 + i, j, color, g, (1.0 - fabs(i) / thickness * 2.0 / 3.0));
  158. }
  159.  
  160. void HorizontalLine(float x1, float y1, float x2, float y2, int color, float g, float thickness)
  161. {
  162.     if ((int)thickness % 2 != 0 && (int)thickness == 0)
  163.         for (int j = x1; j != x2; j += sign(x2 - x1))
  164.             for (int i = -thickness / 2; i <= thickness / 2; i++)
  165.                 PutPoint(j, y1 + i, color, g, (1.0 - fabs(i) / thickness * 2.0 / 3.0));
  166.     else
  167.         for (int j = x1; j != x2; j += sign(x2 - x1))
  168.             for (int i = -thickness / 2; i < thickness / 2; i++)
  169.                 PutPoint(j, y1 + i, color, g, (1.0 - fabs(i) / thickness * 2.0 / 3.0));
  170. }
  171.  
  172. void EasyLine(float x1, float y1, float x2, float y2, int color, float g, float thickness)
  173. {
  174.     float intensity = 0;
  175.     if (thickness < 1)
  176.         color *= thickness;
  177.  
  178.     thickness = Rounding(thickness);
  179.     if (y1 == y2)
  180.         HorizontalLine(x1, y1, x2, y2, color, g, thickness);
  181.     else
  182.         VerticalLine(x1, y1, x2, y2, color, g, thickness);
  183. }
  184.  
  185. //wu line
  186.  
  187. void WuLine(float x1, float y1, float x2, float y2, int color, float g, float thickness)
  188. {
  189.     bool is_swaped = false;
  190.  
  191.     if (abs(x1 - x2) < abs(y1 - y2))
  192.     {
  193.         is_swaped = true;
  194.         swap(x1, y1);
  195.         swap(x2, y2);
  196.     }
  197.  
  198.     if (x1 > x2)
  199.     {
  200.         swap(x1, x2);
  201.         swap(y1, y2);
  202.     }
  203.  
  204.     float k = (y2 - y1) / (x2 - x1);
  205. //  float thick_x = thickness * cos, thick_y;
  206.     float cur_y = y1 + k * (Rounding(x1) - x1);
  207.  
  208.     for (float i = x1; i <= x2; i += 1)
  209.     {
  210.         for (float j = y1 - thickness; j <= y1 + thickness; j++)
  211.         {
  212.             if (!is_swaped)
  213.             {
  214.                 PutPoint(i, (int)cur_y, color, g, TrueColor((thickness + 1.0) / 2.0 - fabs(cur_y - j) * cos(atan(k)) * max));
  215.                 PutPoint(i, (int)cur_y + 1, color, g, cur_y - (int)cur_y);
  216.             }
  217.             else
  218.             {
  219.                 PutPoint((int)cur_y, i, color, g, 1 - (cur_y - (int)cur_y));
  220.                 PutPoint((int)cur_y + 1, i, color, g, cur_y - (int)cur_y);
  221.             }
  222.             cur_y += k;
  223.         }
  224.     }
  225. }
  226.  
  227. //main functions
  228. void MakeLine(float x1, float y1, float x2, float y2, float g, int color, float thickness)
  229. {
  230.     if ((Rounding(x1 - x2) == 0) || (Rounding(y1 - y2) == 0))
  231.         EasyLine(x1, y1, x2, y2, color, g, thickness);
  232.     else
  233.         WuLine(x1, y1, x2, y2, color, g, thickness);
  234. }
  235.  
  236. int main(int argc, char **argv)
  237. {
  238.     if (argc < 9)
  239.     {
  240.         printf("Not enough data!\n");
  241.         return 0;
  242.     }
  243.  
  244.     if (!ReadFile(argv[1]))
  245.         return 0;
  246.  
  247.     int color = (int)CharTofloat(argv[3]);
  248.     float thickness = CharTofloat(argv[4]);
  249.     float x1 = CharTofloat(argv[5]), y1 = CharTofloat(argv[6]), x2 = CharTofloat(argv[7]), y2 = CharTofloat(argv[8]);
  250.     float g = argc < 10 ? 0 : CharTofloat(argv[9]);
  251.  
  252.     MakeLine(x1, y1, x2, y2, g, color, thickness);
  253.  
  254.     if (!WriteFile(argv[2]))
  255.         return 0;
  256.  
  257.     delete[] pixels;
  258.     system("pause");
  259.     return 0;
  260. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement