Guest User

code

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