Add ability to edit game name from UI
[jpcrr.git] / streamtools / rescalers / linear-separable.cpp
blobde05e9e794e244ae0373d0b16eb6988471bc8295
1 #include "rescalers/linear-separable.hpp"
3 #define MAXCOEFFICIENTS 256
5 void rescaler_linear_separable::operator()(uint8_t* target, uint32_t twidth, uint32_t theight,
6 const uint8_t* source, uint32_t swidth, uint32_t sheight)
8 float coeffs[MAXCOEFFICIENTS];
9 unsigned count;
10 unsigned base;
11 float* interm;
13 interm = new float[4 * twidth * sheight];
15 for(unsigned x = 0; x < twidth; x++) {
16 count = 0xDEADBEEF;
17 base = 0xDEADBEEF;
18 compute_coeffs(coeffs, (position_t)x * swidth, twidth, swidth, twidth, count, base);
19 /* Normalize the coefficients. */
20 float sum = 0;
21 for(unsigned i = 0; i < count; i++)
22 sum += coeffs[i];
23 for(unsigned i = 0; i < count; i++)
24 coeffs[i] /= sum;
25 for(unsigned y = 0; y < sheight; y++) {
26 float vr = 0, vg = 0, vb = 0, va = 0;
27 for(unsigned k = 0; k < count; k++) {
28 uint32_t sampleaddr = 4 * y * swidth + 4 * (k + base);
29 vr += coeffs[k] * source[sampleaddr + 0];
30 vg += coeffs[k] * source[sampleaddr + 1];
31 vb += coeffs[k] * source[sampleaddr + 2];
32 va += coeffs[k] * source[sampleaddr + 3];
34 interm[y * 4 * twidth + 4 * x + 0] = vr;
35 interm[y * 4 * twidth + 4 * x + 1] = vg;
36 interm[y * 4 * twidth + 4 * x + 2] = vb;
37 interm[y * 4 * twidth + 4 * x + 3] = va;
41 for(unsigned y = 0; y < theight; y++) {
42 count = 0;
43 base = 0;
44 compute_coeffs(coeffs, (position_t)y * sheight, theight, sheight, theight, count, base);
45 /* Normalize the coefficients. */
46 float sum = 0;
47 for(unsigned i = 0; i < count; i++)
48 sum += coeffs[i];
49 for(unsigned i = 0; i < count; i++)
50 coeffs[i] /= sum;
51 for(unsigned x = 0; x < twidth; x++) {
52 float vr = 0, vg = 0, vb = 0, va = 0;
53 for(unsigned k = 0; k < count; k++) {
54 vr += coeffs[k] * interm[(base + k) * 4 * twidth + x * 4 + 0];
55 vg += coeffs[k] * interm[(base + k) * 4 * twidth + x * 4 + 1];
56 vb += coeffs[k] * interm[(base + k) * 4 * twidth + x * 4 + 2];
57 va += coeffs[k] * interm[(base + k) * 4 * twidth + x * 4 + 3];
59 int wr = (int)vr;
60 int wg = (int)vg;
61 int wb = (int)vb;
62 int wa = (int)va;
63 wr = (wr < 0) ? 0 : ((wr > 255) ? 255 : wr);
64 wg = (wg < 0) ? 0 : ((wg > 255) ? 255 : wg);
65 wb = (wb < 0) ? 0 : ((wb > 255) ? 255 : wb);
66 wa = (wa < 0) ? 0 : ((wa > 255) ? 255 : wa);
68 target[y * 4 * twidth + 4 * x] = (unsigned char)wr;
69 target[y * 4 * twidth + 4 * x + 1] = (unsigned char)wg;
70 target[y * 4 * twidth + 4 * x + 2] = (unsigned char)wb;
71 target[y * 4 * twidth + 4 * x + 3] = (unsigned char)wa;
74 delete[] interm;
78 namespace
80 class simple_rescaler_linear_separable_c : public rescaler_linear_separable
82 public:
83 simple_rescaler_linear_separable_c(bound_coeff_function_t _coeffs_fn)
85 coeffs_fn = _coeffs_fn;
88 void compute_coeffs(float* coeffs, position_t num, position_t denum, position_t osize,
89 position_t nsize, unsigned& base, unsigned& coeffcount)
91 coeffs_fn(coeffs, num, denum, osize, nsize, base, coeffcount);
94 private:
95 bound_coeff_function_t coeffs_fn;
99 simple_rescaler_linear_separable::simple_rescaler_linear_separable(const std::string& type,
100 bound_coeff_function_t _coeffs_fn)
101 : rescaler_factory(type)
103 coeffs_fn = _coeffs_fn;
106 rescaler& simple_rescaler_linear_separable::make(const std::string& type)
108 return *new simple_rescaler_linear_separable_c(coeffs_fn);