Add target witdth to parameters for linear separable resizers
[jpcrr.git] / streamtools / resize-linear-separable.cpp
blob98effbc0c7766a4cac09ed6c36c6b08f3ae00308
1 #include "resize-linear-separable.hpp"
3 #define MAXCOEFFICIENTS 256
5 void resizer_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[3 * 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;
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];
33 interm[y * 3 * twidth + 3 * x + 0] = vr;
34 interm[y * 3 * twidth + 3 * x + 1] = vg;
35 interm[y * 3 * twidth + 3 * x + 2] = vb;
39 for(unsigned y = 0; y < theight; y++) {
40 count = 0;
41 base = 0;
42 compute_coeffs(coeffs, (position_t)y * sheight, theight, sheight, theight, count, base);
43 /* Normalize the coefficients. */
44 float sum = 0;
45 for(unsigned i = 0; i < count; i++)
46 sum += coeffs[i];
47 for(unsigned i = 0; i < count; i++)
48 coeffs[i] /= sum;
49 for(unsigned x = 0; x < twidth; x++) {
50 float vr = 0, vg = 0, vb = 0;
51 for(unsigned k = 0; k < count; k++) {
52 vr += coeffs[k] * interm[(base + k) * 3 * twidth + x * 3 + 0];
53 vg += coeffs[k] * interm[(base + k) * 3 * twidth + x * 3 + 1];
54 vb += coeffs[k] * interm[(base + k) * 3 * twidth + x * 3 + 2];
56 int wr = (int)vr;
57 int wg = (int)vg;
58 int wb = (int)vb;
59 wr = (wr < 0) ? 0 : ((wr > 255) ? 255 : wr);
60 wg = (wg < 0) ? 0 : ((wg > 255) ? 255 : wg);
61 wb = (wb < 0) ? 0 : ((wb > 255) ? 255 : wb);
63 target[y * 4 * twidth + 4 * x] = (unsigned char)wr;
64 target[y * 4 * twidth + 4 * x + 1] = (unsigned char)wg;
65 target[y * 4 * twidth + 4 * x + 2] = (unsigned char)wb;
66 target[y * 4 * twidth + 4 * x + 3] = 0;
69 delete[] interm;
73 namespace
75 class simple_resizer_linear_separable_c : public resizer_linear_separable
77 public:
78 simple_resizer_linear_separable_c(void(*_coeffs_fn)(float* coeffs, position_t num,
79 position_t denum, position_t osize, position_t nsize, unsigned& base, unsigned& coeffcount))
81 coeffs_fn = _coeffs_fn;
84 void compute_coeffs(float* coeffs, position_t num, position_t denum, position_t osize,
85 position_t nsize, unsigned& base, unsigned& coeffcount)
87 coeffs_fn(coeffs, num, denum, osize, nsize, base, coeffcount);
90 private:
91 void(*coeffs_fn)(float* coeffs, position_t num, position_t denum, position_t osize,
92 position_t nsize, unsigned& base, unsigned& coeffcount);
95 class simple_resizer_linear_separable_c2 : public resizer_linear_separable
97 public:
98 simple_resizer_linear_separable_c2(void(*_coeffs_fn)(float* coeffs, position_t num,
99 position_t denum, position_t osize, position_t nsize, unsigned& base, unsigned& coeffcount,
100 int algo), int _algo)
102 coeffs_fn = _coeffs_fn;
103 algo = _algo;
106 void compute_coeffs(float* coeffs, position_t num, position_t denum, position_t osize,
107 position_t nsize, unsigned& base, unsigned& coeffcount)
109 coeffs_fn(coeffs, num, denum, osize, nsize, base, coeffcount, algo);
112 private:
113 void(*coeffs_fn)(float* coeffs, position_t num, position_t denum, position_t osize,
114 position_t nsize, unsigned& base, unsigned& coeffcount, int algo);
115 int algo;
119 simple_resizer_linear_separable::simple_resizer_linear_separable(const std::string& type,
120 void(*_coeffs_fn)(float* coeffs, position_t num, position_t denum, position_t osize,
121 position_t nsize, unsigned& base, unsigned& coeffcount))
122 : resizer_factory(type)
124 coeffs_fn = _coeffs_fn;
125 coeffs_fn2 = NULL;
126 algo = 0;
129 simple_resizer_linear_separable::simple_resizer_linear_separable(const std::string& type,
130 void(*_coeffs_fn)(float* coeffs, position_t num, position_t denum, position_t osize,
131 position_t nsize, unsigned& base, unsigned& coeffcount, int algo), int _algo)
132 : resizer_factory(type)
134 coeffs_fn = NULL;
135 coeffs_fn2 = _coeffs_fn;
136 algo = _algo;
139 resizer& simple_resizer_linear_separable::make(const std::string& type)
141 if(coeffs_fn)
142 return *new simple_resizer_linear_separable_c(coeffs_fn);
143 else
144 return *new simple_resizer_linear_separable_c2(coeffs_fn2, algo);