Guest User

Untitled

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