Add target witdth to parameters for linear separable resizers
[jpcrr.git] / streamtools / resizer-lanczos.cpp
blob9a57f50784a9ae86c9dc28aa801eb9ea56fcf4f1
1 #include "resize-linear-separable.hpp"
2 #include <stdint.h>
3 #include <cmath>
4 #include <stdexcept>
6 namespace
8 double pi = 3.1415926535897932384626;
10 //num / denum = x * swidth / twidth
11 // swidth = n * twidth => x * n
12 // twdith = n * swidth => x / n
14 void compute_coefficients_lanczos(float* coeffs, position_t num, position_t denum, position_t width,
15 position_t twidth, unsigned& count, unsigned& base, int a)
17 if(a == 0)
18 throw std::runtime_error("Parameter alpha must be positive in lanczos resizer");
20 if(2 * a + 1 <= a)
21 throw std::runtime_error("Parameter alpha way too large in lanczos resizer");
23 if(2 * a + 1 > MAXCOEFFICIENTS)
24 throw std::runtime_error("Parameter alpha value would require more coefficients than "
25 "supported");
27 count = 0;
28 base = 0;
29 bool base_set = false;
30 position_t centralpoint = num / denum;
31 for(int i = -a + 1; i <= a; i++) {
32 position_t point = centralpoint + i;
34 if(point < 0 || point >= width)
35 continue; //Out of range.
36 if(!base_set) {
37 base_set = true;
38 base = (unsigned)point;
40 if(num != centralpoint * denum) {
41 double x = (double)num / denum - centralpoint;
42 coeffs[count++] = a * sin(x * pi) * sin(x * pi / a) / ((x * pi) * (x * pi));
43 } else {
44 coeffs[count++] = 1;
49 void compute_coefficients_average(float* coeffs, position_t num, position_t denum, position_t width,
50 position_t twidth, unsigned& count, unsigned& base)
52 signed lowbound, highbound, scan;
54 lowbound = num;
55 highbound = num + width;
56 scan = lowbound - lowbound % denum;
58 if((width + denum - 1) / denum > MAXCOEFFICIENTS)
59 throw std::runtime_error("Conversion would require more coefficients than supported");
61 base = scan / denum;
62 *coeffs = (scan + denum) - lowbound;
63 count = 1;
64 scan = scan + denum;
65 while(scan < highbound) {
66 if(scan + denum > highbound)
67 coeffs[count++] = highbound - scan;
68 else
69 coeffs[count++] = denum;
71 scan = scan + denum;
75 simple_resizer_linear_separable r_average("average", compute_coefficients_average);
76 simple_resizer_linear_separable r_lanczos1("lanczos1", compute_coefficients_lanczos, 1);
77 simple_resizer_linear_separable r_lanczos2("lanczos2", compute_coefficients_lanczos, 2);
78 simple_resizer_linear_separable r_lanczos3("lanczos3", compute_coefficients_lanczos, 3);
79 simple_resizer_linear_separable r_lanczos4("lanczos4", compute_coefficients_lanczos, 4);
80 simple_resizer_linear_separable r_lanczos5("lanczos5", compute_coefficients_lanczos, 5);