Skip to content

Instantly share code, notes, and snippets.

@skyleaworlder
Created December 10, 2020 16:24
Show Gist options
  • Save skyleaworlder/c5c0129cbd9fe49afc7d20fe58151c7d to your computer and use it in GitHub Desktop.
Save skyleaworlder/c5c0129cbd9fe49afc7d20fe58151c7d to your computer and use it in GitHub Desktop.
DCT-Quantum-Matrix-Generator-C++
#include "DCT_QMG.hpp"
// Quantitum Matrix: Q_{50}
// using Q_{50} as a standard to generate other Matrix
std::vector<double> DCT::Quant_matrix_50 = std::vector<double> {
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
};
/*
* the function comes from the highest reply post in:
* https://stackoverflow.com/questions/29215879/how-can-i-generalize-the-quantization-matrix-in-jpeg-compression
*
* through test(test_Q_gen),
* this function can generate Q Matrix(e.g. Q_{10} and Q_{90}).
*/
std::vector<double> DCT::Quant_matrix_gen(size_t target_Q) {
size_t S;
if (target_Q < 50)
S = 5000 / target_Q;
else
S = 200 - 2*target_Q;
std::vector<double> ret;
for (double elem : DCT::Quant_matrix_50) {
size_t input = floor((S*elem + 50) / 100);
ret.push_back(DCT::round(input));
}
return ret;
}
/*
* round function
* unsign is true:
* input is restricted in [0, 255]
* while unsign is false:
* round() is round() in mathematic.
*/
int DCT::round(double input, bool unsign) {
if (unsign) {
if (input > 255)
return 255;
else if (input < 0)
return 0;
else
return int(input + 0.5);
}
else {
if (input > 0)
return int(input + 0.5);
else
return int(input - 0.5);
}
}
#include <vector>
namespace DCT {
extern std::vector<double> Quant_matrix_50;
std::vector<double> Quant_matrix_gen(
size_t target_Q
);
int round(double input, bool unsign=1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment