Refactor resizers and add bilinear resizer
[jpcrr.git] / streamtools / resizer-lanczos.cpp
bloba66300b17d4550155249e86868c58e7585a2b16d
1 #include "resize-linear-separable.hpp"
2 #include <stdint.h>
3 #include <cmath>
4 #include <stdexcept>
6 namespace
8 void compute_coefficients_lanczos(float* coeffs, position_t num, position_t denum, position_t width,
9 unsigned& count, unsigned& base, int a)
11 signed lowbound, highbound, scan;
13 if(num % denum == 0) {
14 coeffs[0] = 1;
15 count = 1;
16 base = num / denum;
17 return;
20 if(a == 0)
21 throw std::runtime_error("Parameter alpha must be positive in lanczos resizer");
23 if(2 * a + 1 <= a)
24 throw std::runtime_error("Parameter alpha way too large in lanczos resizer");
26 if(2 * a + 1 > MAXCOEFFICIENTS)
27 throw std::runtime_error("Parameter alpha value would require more coefficients than supported");
29 lowbound = num - a * denum;
30 highbound = num + a * denum;
31 if(lowbound < 0)
32 lowbound = 0;
33 if(highbound > width * denum)
34 highbound = width * denum - denum;
36 scan = lowbound + (denum - lowbound % denum) % denum;
37 base = scan / denum;
38 count = 0;
39 while(scan <= highbound) {
40 float difference = (float)(num - scan) / denum;
41 if(num == scan)
42 coeffs[count++] = 1;
43 else
44 coeffs[count++] = a * sin(M_PI*difference) * sin(M_PI*difference/2) /
45 (M_PI * M_PI * difference * difference);
47 scan = scan + denum;
51 void compute_coefficients_average(float* coeffs, position_t num, position_t denum, position_t width,
52 unsigned& count, unsigned& base)
54 signed lowbound, highbound, scan;
56 lowbound = num;
57 highbound = num + width;
58 scan = lowbound - lowbound % denum;
60 if((width + denum - 1) / denum > MAXCOEFFICIENTS)
61 throw std::runtime_error("Conversion would require more coefficients than supported");
63 base = scan / denum;
64 *coeffs = (scan + denum) - lowbound;
65 count = 1;
66 scan = scan + denum;
67 while(scan < highbound) {
68 if(scan + denum > highbound)
69 coeffs[count++] = highbound - scan;
70 else
71 coeffs[count++] = denum;
73 scan = scan + denum;
77 simple_resizer_linear_separable r_average("average", compute_coefficients_average);
78 simple_resizer_linear_separable r_lanczos1("lanczos1", compute_coefficients_lanczos, 1);
79 simple_resizer_linear_separable r_lanczos2("lanczos2", compute_coefficients_lanczos, 2);
80 simple_resizer_linear_separable r_lanczos3("lanczos3", compute_coefficients_lanczos, 3);
81 simple_resizer_linear_separable r_lanczos4("lanczos4", compute_coefficients_lanczos, 4);
82 simple_resizer_linear_separable r_lanczos5("lanczos5", compute_coefficients_lanczos, 5);