Guest User

Untitled

a guest
Mar 8th, 2020
346
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.86 KB | None | 0 0
  1. #include<iostream>
  2. #include <fstream>
  3. #include <vector>
  4. #include <array>
  5. #include<cmath>
  6. #include<cstdlib>
  7.  
  8. #if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
  9. #pragma warning(disable:4996)
  10. #endif
  11.  
  12. using namespace std;
  13. constexpr double pi = 3.1415926535897932384626433832;
  14.  
  15. constexpr int block_size = 8;
  16. constexpr int qualtiy = 20;
  17.  
  18.  
  19.  
  20.  
  21. #define _DO_QUANTIZATION
  22. //#define _USE_YCBCR
  23.  
  24.  
  25.  
  26. const uint8_t ZigZagInv[8 * 8] = { 0, 1, 8,16, 9, 2, 3,10,
  27.  
  28.         17,24,32,25,18,11, 4, 5,
  29.                   12,19,26,33,40,48,41,34,
  30.                    27,20,13, 6, 7,14,21,28,
  31.                    35,42,49,56,57,50,43,36,
  32.                  29,22,15,23,30,37,44,51,
  33.                    58,59,52,45,38,31,39,46,
  34.                 53,60,61,54,47,55,62,63 };
  35. typedef  vector<vector< long long int>> map;
  36.  
  37. void readppm(const char* filename, int* height, int* width, map& r1, map& g1, map& b1, bool* vaild = nullptr)
  38. {
  39.     *vaild = false;
  40.     FILE* fd;
  41.     int  k;
  42.     char c;
  43.     long int i, j;
  44.     char b[100];
  45.     int red, green, blue;
  46.  
  47.     int n;
  48.     int m;
  49.     int bm;
  50.     // map a1, b1, c1;
  51.  
  52.     fd = fopen(filename, "rb");
  53.     if (fd == NULL)
  54.     {
  55.         printf("Could not open %s\n", filename);
  56.         return;
  57.     }
  58.     else {
  59.         *vaild = true;
  60.     }
  61.     c = getc(fd);
  62.     if (c == 'P' || c == 'p')
  63.         c = getc(fd);
  64.  
  65.     if (c == '3')
  66.     {
  67.         printf("%s is a PPM file (plain text version)\n", filename);
  68.  
  69.         // NOTE: This is not very good PPM code! Comments are not allowed
  70.         // except immediately after the magic number.
  71.         c = getc(fd);
  72.         if (c == '\n' || c == '\r') // Skip any line break and comments
  73.         {
  74.             c = getc(fd);
  75.             while (c == '#')
  76.             {
  77.                 fscanf(fd, "%[^\n\r] ", b);
  78.                 //   printf("%s\n", b);
  79.                 c = getc(fd);
  80.             }
  81.             ungetc(c, fd);
  82.         }
  83.         fscanf(fd, "%d %d %d", &m, &n, &k);
  84.         bm = fmaxf(n, m);
  85.         //   r1.resize(bm);
  86.       // /    g1.resize(bm);
  87.        //    b1.resize(bm);
  88.  
  89.         map a1(bm, vector<long long>(bm));
  90.         map t1(bm, vector<long long>(bm));
  91.         map c1(bm, vector<long long>(bm));
  92.  
  93.         //   cout << a1.size() << endl;
  94.            //  printf("%d rows  %d columns  max value= %d\n", n, m, k);
  95.  
  96.  
  97.  
  98.          ///  cout << m << " " << n << endl;
  99.  
  100.         for (i = 0; i < n; i++) {
  101.             for (j = 0; j < m; j++) // Important bug fix here!
  102.             { // i = row, j = column
  103.                 fscanf(fd, "%d %d %d", &red, &green, &blue);
  104.  
  105.                 //   a1[j].resize(bm);
  106.                   // g1[j].resize(bm);
  107.                 //   b1[j].resize(bm);
  108.  
  109.                 a1[i][j] = (double(red) * 255.0 / double(k));
  110.                 t1[i][j] = (double(green) * 255.0 / double(k));
  111.                 c1[i][j] = (double(blue) * 255.0 / double(k));
  112.             }
  113.         }
  114.         r1 = a1;
  115.         g1 = t1;
  116.         b1 = c1;
  117.     }
  118.     else
  119.         if (c == '6')
  120.         {
  121.             printf("%s is a PPM file (raw version)!\n", filename);
  122.  
  123.             c = getc(fd);
  124.             if (c == '\n' || c == '\r') // Skip any line break and comments
  125.             {
  126.                 c = getc(fd);
  127.                 while (c == '#')
  128.                 {
  129.                     fscanf(fd, "%[^\n\r] ", b);
  130.                     printf("%s\n", b);
  131.                     c = getc(fd);
  132.                 }
  133.                 ungetc(c, fd);
  134.             }
  135.             fscanf(fd, "%d %d %d", &m, &n, &k);
  136.             bm = fmaxf(n, m);
  137.  
  138.             map a1(bm, vector<long long>(bm));
  139.             map t1(bm, vector<long long>(bm));
  140.             map c1(bm, vector<long long>(bm));
  141.  
  142.             //     printf("%d rows  %d columns  max value= %d\n", m, n, k);
  143.             c = getc(fd); // Skip the last whitespace
  144.  
  145.  
  146.             // Read and re-order as necessary
  147.             for (i = 0; i < n; i++) {
  148.                 for (j = 0; j < m; j++) // Important bug fix here!
  149.                 {
  150.  
  151.                     /// r1[j].resize(n);
  152.                   //   g1[j].resize(n);
  153.                    //  b1[j].resize(n);
  154.  
  155.  
  156.                     a1[i][j] = double(getc(fd));
  157.                     t1[i][j] = double(getc(fd));
  158.                     c1[i][j] = double(getc(fd));
  159.                 }
  160.             }
  161.             r1 = a1;
  162.             g1 = t1;
  163.             b1 = c1;
  164.         }
  165.         else
  166.         {
  167.             printf("%s is not a PPM file!\n", filename);
  168.             return;
  169.         }
  170.  
  171.     // printf("read image\n");
  172.  
  173.     *height = m;
  174.     *width = n;
  175.     //   return image;
  176. }
  177.  
  178. void writeppm(string fileOut, int height, int width, map red, map green, map blue)
  179. {
  180.  
  181.     ofstream out(fileOut);
  182.  
  183.     out << "P3" << endl;
  184.  
  185.     out << width << " " << height << endl;
  186.  
  187.     out << 255 << endl;
  188.  
  189.     for (int i = 0; i < height; ++i)
  190.     {
  191.         for (int j = 0; j < width; ++j)
  192.         {
  193.             out << abs(red[i][j]) << " " << abs(green[i][j]) << " " << abs(blue[i][j]) << endl;
  194.         }
  195.     }
  196.  
  197.     out.close();
  198. }
  199.  
  200. array<array<double, block_size>, block_size> Compute8x8Dct(array<array<double, block_size>, block_size> in)
  201. {
  202.     int i, j, u, v;
  203.     double s;
  204.  
  205.     array<array<double, block_size>, block_size> out;
  206.  
  207.     double cof5 = sqrt(2.0 * double(block_size));
  208.  
  209.     for (i = 0; i < block_size; i++)
  210.         for (j = 0; j < block_size; j++)
  211.         {
  212.             s = 0;
  213.  
  214.             for (u = 0; u < block_size; u++)
  215.                 for (v = 0; v < block_size; v++)
  216.                     s += in[u][v] * cos((2.0 * (double)u + 1.0) * (double)i * pi / ((double)block_size * 2.0)) *
  217.                     cos((2.0 * (double)v + 1.0) * (double)j * pi / ((double)block_size * 2.0)) *
  218.                     ((i == 0) ? 1.0 / sqrt(2) : 1.0) *
  219.                     ((j == 0) ? 1.0 / sqrt(2) : 1.0);
  220.             s = s / cof5;
  221.  
  222.             out[i][j] = s;
  223.             //  cout << s / 4 << " " << out[i][j] << endl;
  224.         }
  225.     return out;
  226. }
  227.  
  228. array<array<double, block_size>, block_size> Compute8x8Idct(array<array<double, block_size>, block_size> in)
  229. {
  230.     int i, j, u, v;
  231.     double s;
  232.     array<array<double, block_size>, block_size> out;
  233.     double cof5 = sqrt(2.0 * double(block_size));
  234.  
  235.     for (i = 0; i < block_size; i++)
  236.         for (j = 0; j < block_size; j++)
  237.         {
  238.             s = 0;
  239.  
  240.             for (u = 0; u < block_size; u++)
  241.                 for (v = 0; v < block_size; v++)
  242.                     s += in[u][v] * cos((2.0 * (double)i + 1.0) * (double)u * pi / (double(block_size) * 2.0)) *
  243.                     cos((2.0 * (double)j + 1.0) * (double)v * pi / (double(block_size) * 2.0)) *
  244.                     ((u == 0) ? 1.0 / sqrtf(2) : 1.0) *
  245.                     ((v == 0) ? 1.0 / sqrtf(2) : 1.0);
  246.  
  247.             s = s / cof5;
  248.  
  249.             if (s > 255)
  250.             {
  251.                 s = 255;
  252.             }
  253.  
  254.             out[i][j] = s;
  255.  
  256.  
  257.         }
  258.  
  259.     return out;
  260. }
  261.  
  262.  
  263. array<array<double, block_size>, block_size> qu(array<array<double, block_size>, block_size> a, vector<double> quantization)
  264.  
  265. {
  266.     ///std::vector<double> quantization = { 16 , 11 , 10 , 16 , 24 , 40 , 51 , 61 , 12 , 12 , 14 , 19 , 26 , 58 , 60 , 55 , 14 , 13 , 16 , 24 , 40 , 57 , 69 , 56 , 14 , 17 , 22 , 29 , 51 , 87 , 80 , 62 , 18 , 22 , 37 , 56 , 68 , 109 , 103 , 77 , 24 , 35 , 55 , 64 , 81 , 104 , 113 , 92 , 49 , 64 , 78 , 87 , 103 , 121 , 120 , 101 , 72 , 92 , 95 , 98 , 112 , 100 , 103 , 99 };
  267.  
  268.     for (int i = 0; i < block_size * block_size; ++i)
  269.     {
  270.         int col = i % block_size;
  271.         int row = int(i / block_size);
  272.         double olda = a[row][col];
  273.  
  274.         a[row][col] = round((a[row][col]) / (quantization[i]));
  275.  
  276.     }
  277.  
  278.  
  279.     return a;
  280. }
  281.  
  282.  
  283.  
  284. array<array<double, block_size>, block_size> qu2(array<array<double, block_size>, block_size> a, vector<double> quantization)
  285.  
  286. {
  287.  
  288.     for (int i = 0; i < block_size * block_size; ++i)
  289.     {
  290.         int col = i % block_size;
  291.         int row = int(i / block_size);
  292.  
  293.         a[row][col] = ((a[row][col]) * (quantization[i]));
  294.  
  295.  
  296.     }
  297.     return a;
  298. }
  299.  
  300. map jpg(map r, int height, int width, vector<double> quantization)
  301. {
  302.     vector<array<array<double, block_size>, block_size>> block = vector<array<array<double, block_size>, block_size>>();
  303.  
  304.  
  305.     int wth = ((width * height) / (block_size * block_size));
  306.  
  307.  
  308.     for (int i = 0; i < ((width * height) / (block_size * block_size)); ++i)
  309.     {
  310.         block.push_back(array<array<double, block_size>, block_size>());
  311.     }
  312.  
  313.     // cout << " h\n";
  314.  
  315.     for (int i = 0; i < height / block_size; i++)
  316.     {
  317.         for (int j = 0; j < width / block_size; j++)
  318.         {
  319.             for (int k = i * block_size, l = 0; k < (i * block_size) + block_size; k++, l++)
  320.             {
  321.                 for (int m = j * block_size, n = 0; m < (j * block_size) + block_size; m++, n++)
  322.                 {
  323.                     block[(i * (width / block_size)) + j][n][l] = r[m][k];
  324.                 }
  325.  
  326.             }
  327.         }
  328.     }
  329.  
  330.     int bidx = block.size();
  331.  
  332.  
  333.     for (int i = 0; i < bidx; ++i)
  334.     {
  335.         block[i] = Compute8x8Dct(block[i]);
  336.  
  337.     }
  338. #ifdef _DO_QUANTIZATION
  339.     for (int i = 0; i < bidx; ++i)
  340.     {
  341.         block[i] = qu(block[i], quantization);
  342.     }
  343. #endif
  344.  
  345.     for (int i = 0; i < bidx; ++i)
  346.     {
  347.         for (int j = 0; j < block_size * block_size; ++j)
  348.         {
  349.             //  int de = ZigZagInv[j];
  350.               //block[bidx][(int)de / 8][de % 8] = block[bidx][(int)j / 8][j % 8];
  351.         }
  352.  
  353.     }
  354.  
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361.  
  362.     for (int i = 0; i < height / block_size; i++)
  363.     {
  364.         for (int j = 0; j < width / block_size; j++)
  365.         {
  366.             for (int k = i * block_size, l = 0; k < (i * block_size) + block_size; k++, l++)
  367.             {
  368.                 for (int m = j * block_size, n = 0; m < (j * block_size) + block_size; m++, n++)
  369.                 {
  370.                     r[m][k] = ((block[(i * (width / block_size)) + j][n][l]));
  371.                 }
  372.             }
  373.         }
  374.     }
  375.  
  376.  
  377.     cout << "done" << endl;
  378.  
  379.     return r;
  380. }
  381.  
  382.  
  383.  
  384.  
  385. map jpgde(map r, int height, int width, vector<double> quantization)
  386. {
  387.  
  388.     //read
  389.  
  390.     vector<array<array<double, block_size>, block_size>> block = vector<array<array<double, block_size>, block_size>>();
  391.     /// block.push_back(array<array<double, 8>, 8>());
  392.     // block.resize(width * height / 64);
  393.  
  394.  
  395.     int wth = ((width * height) / (block_size * block_size));
  396.  
  397.  
  398.     for (int i = 0; i < wth; ++i)
  399.     {
  400.         block.push_back(array<array<double, block_size>, block_size>());
  401.     }
  402.  
  403.     // cout << " h\n";
  404.  
  405.     for (int i = 0; i < height / block_size; i++)
  406.     {
  407.         for (int j = 0; j < width / block_size; j++)
  408.         {
  409.             for (int k = i * block_size, l = 0; k < (i * block_size) + block_size; k++, l++)
  410.             {
  411.                 for (int m = j * block_size, n = 0; m < (j * block_size) + block_size; m++, n++)
  412.                 {
  413.                     block[(i * (width / block_size)) + j][n][l] = r[m][k];
  414.                 }
  415.             }
  416.         }
  417.     }
  418.  
  419.     int bidx = block.size();
  420.  
  421.  
  422.  
  423. #ifdef _DO_QUANTIZATION
  424.     for (int i = 0; i < bidx; ++i)
  425.     {
  426.         block[i] = qu2(block[i], quantization);
  427.     }
  428. #endif // _DO_QUANTIZATION
  429.  
  430.     for (int i = 0; i < bidx; ++i)
  431.     {
  432.         block[i] = Compute8x8Idct(block[i]);
  433.     }
  434.  
  435.     for (int i = 0; i < bidx; ++i)
  436.     {
  437.         for (int j = 0; j < 64; ++j)
  438.         {
  439.             //int de = ZigZagInv[j];
  440.              //block[bidx][(int)de / 8][de % 8] = block[bidx][(int)j / 8][j % 8];
  441.         }
  442.  
  443.     }
  444.  
  445.     for (int i = 0; i < bidx; ++i)
  446.     {
  447.         for (int j = 0; j < 64; ++j)
  448.         {
  449.             //  int de = ZigZagInv[j];
  450.        ///s       block[bidx][(int)j / 8][j % 8] = block[bidx][(int)de / 8][de % 8];
  451.         }
  452.  
  453.     }
  454.  
  455.     double val_scale = 1.0 / (double(block_size) / 8.0);
  456.  
  457.     for (int i = 0; i < height / block_size; i++)
  458.     {
  459.         for (int j = 0; j < width / block_size; j++)
  460.         {
  461.             for (int k = i * block_size, l = 0; k < (i * block_size) + block_size; k++, l++)
  462.             {
  463.                 for (int m = j * block_size, n = 0; m < (j * block_size) + block_size; m++, n++)
  464.                 {
  465.                     r[m][k] = ((block[(i * (width / block_size)) + j][n][l])) * val_scale;
  466.                 }
  467.             }
  468.         }
  469.     }
  470.  
  471.  
  472.     bool deb = 0;
  473.  
  474.     int bidx2 = 0;
  475.  
  476.  
  477.     return r;
  478. }
  479.  
  480.  
  481.  
  482.  
  483.  
  484. //void rgb2ycbr
  485.  
  486. void rgb2ycbcr(int width, int height, map& r, map& g, map& b)
  487. {
  488.     map r1 = r;
  489.     map g1 = g;
  490.     map b1 = b;
  491.  
  492.     for (int i = 0; i < height; ++i)
  493.     {
  494.         for (int j = 0; j < width; ++j)
  495.         {
  496.             r1[i][j] = 0.0 + (0.299 * r[i][j]) + (0.587 * g[i][j]) + (0.114 * b[i][j]);
  497.             g1[i][j] = 128.0 - (0.168736 * r[i][j]) - (0.331264 * g[i][j]) + (0.5 * b[i][j]);
  498.             b1[i][j] = 128.0 + (0.5 * r[i][j]) - (0.418688 * g[i][j]) - (0.081312 * b[i][j]);
  499.         }
  500.     }
  501.     r = r1;
  502.     g = g1;
  503.     b = b1;
  504.     //   Y = 0.257R´ + 0.504G´ + 0.098B´ + 16
  505.  
  506.    //Cb = -0.148R´ - 0.291G´ + 0.439B´ + 128
  507.  
  508.    //Cr = 0.439R´ - 0.368G´ - 0.071B´ + 128
  509. }
  510.  
  511. void ycbcr2rgb(int width, int height, map& y, map& cb, map& cr)
  512. {
  513.     map r = y;
  514.     map g = cb;
  515.     map b = cr;
  516.  
  517.     for (int i = 0; i < height; ++i)
  518.     {
  519.         for (int j = 0; j < width; ++j)
  520.         {
  521.             r[i][j] = (y[i][j]) + 1.402 * (cr[i][j] - 128);
  522.             g[i][j] = (y[i][j]) - 0.344136 * (cb[i][j] - 128) - 0.714136 * (cr[i][j] - 128);
  523.             b[i][j] = (y[i][j]) + 1.772 * (cb[i][j] - 128);
  524.         }
  525.     }
  526.     y = r;
  527.     cb = g;
  528.     cr = b;
  529.     // R´ = 1.164(Y - 16) + 1.596(Cr - 128)
  530.  
  531.       //   G´ = 1.164(Y - 16) - 0.813(Cr - 128) - 0.392(Cb - 128)
  532.  
  533.         // B´ = 1.164(Y - 16) + 2.017(Cb - 128)
  534. }
  535.  
  536.  
  537.  
  538. int main()
  539. {
  540.     map r;
  541.     map g;
  542.     map b;
  543.  
  544.     int width = 0;
  545.  
  546.     int height = 0;
  547.     bool vaild = false;
  548.     double S = 0;
  549.     vector<double> tb = { 16, 11, 10, 16,24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55,
  550.         14 ,13, 16, 24, 40, 57, 69, 56, 14, 17, 22, 29, 51, 87, 80, 62,
  551.         18,22 ,37, 56, 68, 109, 103, 77, 24, 35, 55, 64, 81, 104, 113, 92,
  552.         49 ,64, 78 ,87 ,103 ,121, 120, 101, 72, 92 ,95, 98 ,112, 100, 103, 99 };
  553.  
  554.     ///  %// Determine S
  555.     if (qualtiy < 50)
  556.         S = 5000 / qualtiy;
  557.     else
  558.         S = 200 - 2 * qualtiy;
  559.     //end
  560.  
  561.     for (int i = 0; i < 64; ++i)
  562.     {
  563.         tb[i] = floor((S * tb[i] + 50.0) / 100.0);
  564.         if (tb[i] == 0)
  565.         {
  566.             tb[i] = 1;
  567.         }
  568.     }
  569.     // Ts = floor((S * Tb + 50) / 100);
  570.  
  571.  
  572. // Ts(Ts == 0) = 1;
  573.  
  574.  //read image
  575.     readppm("test3.ppm", &width, &height, r, g, b, &vaild);
  576.     map c = r;
  577.     if (!vaild)
  578.     {
  579.         return EXIT_FAILURE;
  580.  
  581.     }
  582.  
  583.     //do stuff here
  584.  
  585.  
  586.  
  587.  
  588.  
  589.  
  590.  
  591.  
  592. #ifdef _USE_YCBCR
  593.     rgb2ycbcr(width, height, r, g, b);
  594. #endif // _USE_YCBCR
  595.  
  596.     //write to output image
  597.  
  598.     r = jpg(r, width, height, tb);
  599.     r = jpgde(r, width, height, tb);
  600.  
  601.     g = jpg(g, width, height, tb);
  602.     g = jpgde(g, width, height, tb);
  603.  
  604.     b = jpg(b, width, height, tb);
  605.     b = jpgde(b, width, height, tb);
  606.  
  607. #ifdef _USE_YCBCR
  608.     ycbcr2rgb(width, height, r, g, b);
  609. #endif // _USE_YCBCR
  610.  
  611.  
  612.     writeppm("output.ppm", height, width, r, g, b);
  613.  
  614.  
  615.  
  616.  
  617.     cout << width << "  " << height << endl;
  618.  
  619.  
  620.  
  621.  
  622.  
  623. }
Advertisement
Add Comment
Please, Sign In to add comment