5 #define MIN(a,b) ((a) < (b) ? (a) : (b))
6 #define MAX(a,b) ((a) > (b) ? (a) : (b))
7 #define CLAMP(a,min,max) MIN(MAX((a),(min)),(max))
14 void print1(float *in, int x)
16 for (int i = 0; i < x; i++)
20 void print2(void *_data, int x, int y)
22 float (*data)[x] = _data;
23 for (int yi=0; yi < y; yi++)
29 * y ,+---+---+---+---+
30 * | ,+---+---+---+---+'| z
31 * ,+---+'| 0 | 0 | 0 | + .'
32 * +---+'|,+---+---+---+'|
33 * | 0 | +---+---+'| 0 | +
34 * +---+'| 1 | 1 |,+---+'|
35 * | 0 |,+---+---+---+'| +
36 * +---+---+---+---+'| +'
37 * | 0 | 0 | 0 | 0 | +'
38 * +---+---+---+---+' -- x
41 /* Nearest neighbor interpolation */
42 void nearest2(void *_in, void *_out, int x, int y, int s)
44 float (*in )[y*1] = _in;
45 float (*out)[y*s] = _out;
46 for (int yi=0; yi < y*s; yi++)
47 for (int xi=0; xi < x*s; xi++) {
48 out[xi][yi] = in[xi/s][yi/s];
52 /* Linear interpolation */
53 void linear2(void *_in, void *_out, int x, int y, int s)
55 float (*in )[y*1] = _in;
56 float (*out)[y*s] = _out;
57 for (int yi=s/2; yi+s/2 < y*s; yi++)
58 for (int xi=s/2; xi+s/2 < x*s; xi++) {
59 float xf = (xi+0.5)/s;
60 float yf = (yi+0.5)/s;
65 float f00 = in[xl][yl];
66 float f01 = in[xl][yh];
67 float f10 = in[xh][yl];
68 float f11 = in[xh][yh];
69 float xs = xf - (xl+0.5);
70 float ys = yf - (yl+0.5);
80 * Cubic interpolation (Catmull–Rom)
82 * val[k+1] - val[k-1] val[k+1] - val[k-1]
83 * m[k] = ------------------- == -------------------
84 * pos[k+1] - pos[k-1] 2
91 float cubic(float t, float pl, float p0, float p1, float ph)
95 //printf("%5.2f %5.2f %5.2f %5.2f - %5.2f", p0, p1, m0, m1, t);
96 return (1+2*t) * (1-t) * (1-t) * p0 +
97 t * (1-t) * (1-t) * m0 +
98 t * t * (3-2*t) * p1 +
102 void cubic1(float *in, float *out, int x, int s)
104 for (int xi=0; xi < x*s; xi++) {
105 float xf = (xi+0.5)/s;
106 int xll = MAX(xf - 1.5, 0 );
107 int xl = MAX(xf - 0.5, 0 );
108 int xh = MIN(xf + 0.5, x-1);
109 int xhh = MIN(xf + 1.5, x-1);
110 float xt = (xf+0.5) - (int)(xf+0.5);
111 //printf("%2d: %d %d %d %d - %6.3f | ", xi, xll, xl, xh, xhh, xt);
112 out[xi] = cubic(xt, in[xll], in[xl], in[xh], in[xhh]);
113 //printf(" | %5.2f\n", out[xi]);
115 // 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0
116 // 0 1 2 3 4 5 6 7 8 9 a b c d e f
121 void cubic2(void *_in, void *_out, int x, int y, int s)
123 float (*in )[x*1] = _in;
124 float (*out)[x*s] = _out;
126 /* Interpolate in y direction */
127 for (int yi=0; yi < y; yi++)
128 cubic1(in[yi], out[yi*s], x, s);
130 /* Interpolate in x direction */
131 /* Todo: use a stride, etc instead of copying */
134 for (int xi=0; xi < x*s; xi++) {
135 for (int yi = 0; yi < y; yi++)
136 yin[yi] = out[yi*s][xi];
137 cubic1(yin, yout, y, s);
138 for (int yi = 0; yi < y*s; yi++)
139 out[yi][xi] = yout[yi];
146 //float orig [ 3][ 4] = {};
147 //float smooth[15][20] = {};
152 //binearest(orig, smooth, 4, 3, 4);
153 //printf("Binearest:\n");
155 //print(smooth, 16, 12);
157 //bilinear(orig, smooth, 4, 3, 4);
158 //printf("Bilinear:\n");
160 //print(smooth, 16, 12);
162 //printf("cubic 2:\n");
163 //cubic2(orig, smooth, 4, 3, 5);
164 //print2(orig, 4, 3);
165 //print2(smooth, 20, 15);
167 //float lorig [4] = {0, 1, 1, 0};
168 //float lsmooth[16] = {};
169 //printf("Cubic1:\n");
170 //cubic1(lorig, lsmooth, 4, 4);
172 //print1(lsmooth, 16);
175 /* Test with matlab */
176 //float smooth[80][80] = {};
177 //float orig [ 4][ 4] =
182 //cubic2(orig, smooth, 4, 4, 20);
183 //print2(smooth, 80, 80);
184 // data = textread('<output>');
185 // [xs ys] = meshgrid(linspace(0,3,size(data,2)), linspace(0,3,size(data,1)));
186 // surf(xs, ys, data);
191 /* interpolatecolormaps */
192 float smooth[3][80] = {};
194 {{0x00, 0x04, 0x01, 0x03, 0x02, 0x01, 0x00, 0xfd,
195 0xe5, 0xfd, 0xfd, 0xd4, 0xbc, 0xf8, 0x98, 0xfd},
196 {0x00, 0xe9, 0x9f, 0x00, 0xfd, 0xc5, 0x8e, 0xf8,
197 0xbc, 0x95, 0x00, 0x00, 0x00, 0x00, 0x54, 0xfd},
198 {0x00, 0xe7, 0xf4, 0xf4, 0x02, 0x01, 0x00, 0x02,
199 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xc6, 0xfd}};
200 cubic1(orig[0], smooth[0], 16, 5);
201 cubic1(orig[1], smooth[1], 16, 5);
202 cubic1(orig[2], smooth[2], 16, 5);
203 for (int i = 0; i < 80; i++)
204 printf("{0x%02x,0x%02x,0x%02x}\n",
205 (uint8_t)round(CLAMP(smooth[0][i], 0x00, 0xff)),
206 (uint8_t)round(CLAMP(smooth[1][i], 0x00, 0xff)),
207 (uint8_t)round(CLAMP(smooth[2][i], 0x00, 0xff)));