]> git.sesse.net Git - mlt/blob - src/modules/plus/interp.h
Clamp out of range values.
[mlt] / src / modules / plus / interp.h
1 //interp.c
2 /*
3  * Copyright (C) 2010 Marko Cebokli   http://lea.hamradio.si/~s57uuu
4  * This file is a part of the Frei0r plugin "c0rners"
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20
21 /*******************************************************************
22  * The remapping functions use a map aray, which contains a pair
23  * of floating values fo each pixel of the output image. These
24  * represent the location in the input image, from where the value
25  * of the given output pixel should be interpolated.
26  * They are given in pixels of the input image.
27  * If the output image is wo pixels wide, then the x coordinate
28  * of the pixel in row r and column c is at  2*(r*wo+c) in the map
29  * array, and y at 2*(r*wo+c)+1
30  *
31  * The map array is usually computation intensive to generate, and
32  * he purpose of the map array is to allow fast remapping of
33  * several images (video) using the same map array.
34  ******************************************************************/
35
36
37 //compile:   gcc -c -O2 -Wall -std=c99 -fPIC interp.c -o interp.o
38
39 //      -std=c99 za rintf()
40 //      -fPIC da lahko linkas v .so (za frei0r)
41
42 #include <math.h>
43 #include <stdio.h>      /* za debug printoute */
44 #include <inttypes.h>
45
46
47 //#define TEST_XY_LIMITS
48
49 //--------------------------------------------------------
50 //pointer to an interpolating function
51 //parameters:
52 //  source image
53 //  source width
54 //  source height
55 //  X coordinate
56 //  Y coordinate
57 //  opacity
58 //  destination image
59 //  flag to overwrite alpha channel
60 typedef int (*interpp)(unsigned char*, int, int, float, float, float, unsigned char*, int);
61
62 //**************************************
63 //HERE BEGIN THE INTERPOLATION FUNCTIONS
64
65 //------------------------------------------------------
66 //za debugging - z izpisovanjem
67 //interpolacija "najblizji sosed" (ni prava interpolacija)
68 //za byte (char) vrednosti
69 //      *sl vhodni array (slika)
70 //      w,h dimenzija slike je wxh
71 //      x,y tocka, za katero izracuna interpolirano vrednost
72 //  o opacity
73 //      *v interpolirana vrednost
74 int interpNNpr_b(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
75 {
76         //printf("u=%5.2f v=%5.2f   ",x,y);
77         printf("u=%5.3f v=%5.3f     ",x/(w-1),y/(h-1));
78         //printf("U=%2d V=%2d   ",(int)rintf(x),(int)rintf(y));
79
80 #ifdef TEST_XY_LIMITS
81         if ((x<0)||(x>=(w-1))||(y<0)||(y>=(h-1))) return -1;
82 #endif
83
84         *v=sl[(int)rintf(x)+(int)rintf(y)*w];
85         return 0;
86 }
87
88 //------------------------------------------------------
89 //interpolacija "najblizji sosed" (ni prava interpolacija)
90 //za byte (char) vrednosti
91 //      *sl vhodni array (slika)
92 //      w,h dimenzija slike je wxh
93 //      x,y tocka, za katero izracuna interpolirano vrednost
94 //  o opacity
95 //      *v interpolirana vrednost
96 int interpNN_b(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
97 {
98 #ifdef TEST_XY_LIMITS
99         if ((x<0)||(x>=(w-1))||(y<0)||(y>=(h-1))) return -1;
100 #endif
101
102         *v=sl[(int)rintf(x)+(int)rintf(y)*w];
103         return 0;
104 }
105
106 //------------------------------------------------------
107 //interpolacija "najblizji sosed" (ni prava interpolacija)
108 //za byte (char) vrednosti  v packed color 32 bitnem formatu
109 //little endian !!
110 //      *sl vhodni array (slika)
111 //      w,h dimenzija slike je wxh
112 //      x,y tocka, za katero izracuna interpolirano vrednost
113 //  o opacity
114 //      *v interpolirana vrednost
115 int interpNN_b32(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
116 {
117 #ifdef TEST_XY_LIMITS
118         if ((x<0)||(x>=(w-1))||(y<0)||(y>=(h-1))) return -1;
119 #endif
120         int p = (int) rintf(x) * 4 + (int) rintf(y) * 4 * w;
121         float alpha = (float) sl[p + 3] / 255.0 * o;
122         v[0]= v[0] * (1.0 - alpha) + sl[p] * alpha;
123         v[1]= v[1] * (1.0 - alpha) + sl[p + 1] * alpha;
124         v[2]= v[2] * (1.0 - alpha) + sl[p + 2] * alpha;
125         if (is_alpha) v[3] = sl[p +3];
126
127         return 0;
128 }
129
130 //------------------------------------------------------
131 //bilinearna interpolacija
132 //za byte (char) vrednosti
133 //      *sl vhodni array (slika)
134 //      w,h dimenzija slike je wxh
135 //      x,y tocka, za katero izracuna interpolirano vrednost
136 //  o opacity
137 //      *v interpolirana vrednost
138 int interpBL_b(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
139 {
140         int m,n,k,l;
141         float a,b;
142
143 #ifdef TEST_XY_LIMITS
144         if ((x<0)||(x>=(w-1))||(y<0)||(y>=(h-1))) return -1;
145 #endif
146
147         m=(int)floorf(x); n=(int)floorf(y);
148         k=n*w+m; l=(n+1)*w+m;
149         a=sl[k]+(sl[k+1]-sl[k])*(x-(float)m);
150         b=sl[l]+(sl[l+1]-sl[l])*(x-(float)m);
151         *v=a+(b-a)*(y-(float)n);
152         return 0;
153 }
154
155 //------------------------------------------------------
156 //bilinearna interpolacija
157 //za byte (char) vrednosti  v packed color 32 bitnem formatu
158 int interpBL_b32(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
159 {
160         int m,n,k,l,n1,l1,k1;
161         float a,b;
162
163 #ifdef TEST_XY_LIMITS
164         if ((x<0)||(x>=(w-1))||(y<0)||(y>=(h-1))) return -1;
165 #endif
166
167         m=(int)floorf(x); n=(int)floorf(y);
168         k=n*w+m; l=(n+1)*w+m;
169         k1=4*(k+1); l1=4*(l+1); n1=4*((n+1)*w+m);
170         l=4*l; k=4*k;
171
172         a=sl[k+3]+(sl[k1+3]-sl[k+3])*(x-(float)m);
173         b=sl[l+3]+(sl[l1+3]-sl[n1+3])*(x-(float)m);
174         float alpha = a+(b-a)*(y-(float)n);
175         if (is_alpha) v[3] = alpha;
176         alpha = alpha / 255.0 * o;
177
178         a=sl[k]+(sl[k1]-sl[k])*(x-(float)m);
179         b=sl[l]+(sl[l1]-sl[n1])*(x-(float)m);
180         v[0]= v[0] * (1.0 - alpha) + (a+(b-a)*(y-(float)n)) * alpha;
181
182         a=sl[k+1]+(sl[k1+1]-sl[k+1])*(x-(float)m);
183         b=sl[l+1]+(sl[l1+1]-sl[n1+1])*(x-(float)m);
184         v[1]= v[1] * (1.0 - alpha) + (a+(b-a)*(y-(float)n)) * alpha;
185
186         a=sl[k+2]+(sl[k1+2]-sl[k+2])*(x-(float)m);
187         b=sl[l+2]+(sl[l1+2]-sl[n1+2])*(x-(float)m);
188         v[2]= v[2] * (1.0 - alpha) + (a+(b-a)*(y-(float)n)) * alpha;
189
190         return 0;
191 }
192
193 //------------------------------------------------------
194 //bikubicna interpolacija  "smooth"
195 //za byte (char) vrednosti
196 //kar Aitken-Neville formula iz Bronstajna
197 //      *sl vhodni array (slika)
198 //      w,h dimenzija slike je wxh
199 //      x,y tocka, za katero izracuna interpolirano vrednost
200 //  o opacity
201 //      *v interpolirana vrednost
202 int interpBC_b(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
203 {
204         int i,j,l,m,n;
205         float k;
206         float p[4],p1[4],p2[4],p3[4],p4[4];
207
208 #ifdef TEST_XY_LIMITS
209         if ((x<0)||(x>=(w-1))||(y<0)||(y>=(h-1))) return -1;
210 #endif
211
212         m=(int)ceilf(x)-2; if (m<0) m=0; if ((m+5)>w) m=w-4;
213         n=(int)ceilf(y)-2; if (n<0) n=0; if ((n+5)>h) n=h-4;
214
215         //njaprej po y  (stiri stolpce)
216         for (i=0;i<4;i++)
217         {
218                 l=m+(i+n)*w;
219                 p1[i]=sl[l];
220                 p2[i]=sl[l+1];
221                 p3[i]=sl[l+2];
222                 p4[i]=sl[l+3];
223         }
224         for (j=1;j<4;j++)
225                 for (i=3;i>=j;i--)
226                 {
227                 k=(y-i-n)/j;
228                 p1[i]=p1[i]+k*(p1[i]-p1[i-1]);
229                 p2[i]=p2[i]+k*(p2[i]-p2[i-1]);
230                 p3[i]=p3[i]+k*(p3[i]-p3[i-1]);
231                 p4[i]=p4[i]+k*(p4[i]-p4[i-1]);
232         }
233
234         //zdaj pa po x
235         p[0]=p1[3]; p[1]=p2[3]; p[2]=p3[3]; p[3]=p4[3];
236         for (j=1;j<4;j++)
237                 for (i=3;i>=j;i--)
238                         p[i]=p[i]+(x-i-m)/j*(p[i]-p[i-1]);
239
240         if (p[3]<0.0) p[3]=0.0;                 //printf("p=%f ",p[3]);
241         if (p[3]>256.0) p[3]=255.0;             //printf("p=%f ",p[3]);
242
243         *v=p[3];
244
245         return 0;
246 }
247
248 //------------------------------------------------------
249 //bikubicna interpolacija  "smooth"
250 //za byte (char) vrednosti  v packed color 32 bitnem formatu
251 int interpBC_b32(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
252 {
253         int i,j,b,l,m,n;
254         float k;
255         float p[4],p1[4],p2[4],p3[4],p4[4];
256         float alpha = 1.0;
257
258 #ifdef TEST_XY_LIMITS
259         if ((x<0)||(x>=(w-1))||(y<0)||(y>=(h-1))) return -1;
260 #endif
261
262         m=(int)ceilf(x)-2; if (m<0) m=0; if ((m+5)>w) m=w-4;
263         n=(int)ceilf(y)-2; if (n<0) n=0; if ((n+5)>h) n=h-4;
264
265
266         for (b=3;b>-1;b--)
267         {
268                 //njaprej po y  (stiri stolpce)
269                 for (i=0;i<4;i++)
270                 {
271                         l=m+(i+n)*w;
272                         p1[i]=sl[4*l+b];
273                         p2[i]=sl[4*(l+1)+b];
274                         p3[i]=sl[4*(l+2)+b];
275                         p4[i]=sl[4*(l+3)+b];
276                 }
277                 for (j=1;j<4;j++)
278                         for (i=3;i>=j;i--)
279                         {
280                                 k=(y-i-n)/j;
281                                 p1[i]=p1[i]+k*(p1[i]-p1[i-1]);
282                                 p2[i]=p2[i]+k*(p2[i]-p2[i-1]);
283                                 p3[i]=p3[i]+k*(p3[i]-p3[i-1]);
284                                 p4[i]=p4[i]+k*(p4[i]-p4[i-1]);
285                         }
286
287                 //zdaj pa po x
288                 p[0]=p1[3]; p[1]=p2[3]; p[2]=p3[3]; p[3]=p4[3];
289                 for (j=1;j<4;j++)
290                         for (i=3;i>=j;i--)
291                                 p[i]=p[i]+(x-i-m)/j*(p[i]-p[i-1]);
292
293                 if (p[3]<0.0) p[3]=0.0;
294                 if (p[3]>255.0) p[3]=255.0;
295
296                 if (b == 3) {
297                         alpha = p[3] / 255.0 * o;
298                         if (is_alpha) v[3] = p[3];
299                 } else {
300                         v[b] = v[b] * (1.0 - alpha) + p[3] * alpha;
301                 }
302         }
303
304         return 0;
305 }
306
307 //------------------------------------------------------
308 //bikubicna interpolacija  "sharp"
309 //za byte (char) vrednosti
310 //Helmut Dersch polinom
311 //      *sl vhodni array (slika)
312 //      w,h dimenzija slike je wxh
313 //      x,y tocka, za katero izracuna interpolirano vrednost
314 //  o opacity
315 //      *v interpolirana vrednost
316 //!!! ODKOD SUM???  (ze po eni rotaciji v interp_test !!)
317 //!!! v defish tega suma ni???
318 int interpBC2_b(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
319 {
320         int i,k,l,m,n;
321         float pp,p[4],wx[4],wy[4],xx;
322
323 #ifdef TEST_XY_LIMITS
324         if ((x<0)||(x>=(w-1))||(y<0)||(y>=(h-1))) return -1;
325 #endif
326
327         m=(int)ceilf(x)-2; if (m<0) m=0; if ((m+5)>w) m=w-4;
328         n=(int)ceilf(y)-2; if (n<0) n=0; if ((n+5)>h) n=h-4;
329
330
331         //najprej po y (stiri stolpce)
332         xx=y-n;    wy[0]=(-0.75*(xx-5.0)*xx-6.0)*xx+3.0;
333         xx=xx-1.0; wy[1]=(1.25*xx-2.25)*xx*xx+1.0;
334         xx=1.0-xx; wy[2]=(1.25*xx-2.25)*xx*xx+1.0;
335         xx=xx+1.0; wy[3]=(-0.75*(xx-5.0)*xx-6.0)*xx+3.0;
336         //se po x
337         xx=x-m;    wx[0]=(-0.75*(xx-5.0)*xx-6.0)*xx+3.0;
338         xx=xx-1.0; wx[1]=(1.25*xx-2.25)*xx*xx+1.0;
339         xx=1.0-xx; wx[2]=(1.25*xx-2.25)*xx*xx+1.0;
340         xx=xx+1.0; wx[3]=(-0.75*(xx-5.0)*xx-6.0)*xx+3.0;
341
342         k=n*w+m;
343         for (i=0;i<4;i++)
344         {
345                 p[i]=0.0;
346                 l=k+i;
347                 p[i]=wy[0]*sl[l]; l+=w;
348                 p[i]+=wy[1]*sl[l]; l+=w;
349                 p[i]+=wy[2]*sl[l]; l+=w;
350                 p[i]+=wy[3]*sl[l];
351         }
352
353         pp=wx[0]*p[0];
354         pp+=wx[1]*p[1];
355         pp+=wx[2]*p[2];
356         pp+=wx[3]*p[3];
357
358         if (pp<0.0) pp=0.0;
359         if (pp>256.0) pp=255.0;
360
361         *v=pp;
362         return 0;
363 }
364
365 //------------------------------------------------------
366 //bikubicna interpolacija  "sharp"
367 //za byte (char) vrednosti  v packed color 32 bitnem formatu
368 //!!! ODKOD SUM???  (ze po eni rotaciji v interp_test !!)
369 //!!! v defish tega suma ni???
370 int interpBC2_b32(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
371 {
372         int b,i,k,l,m,n,u;
373         float pp,p[4],wx[4],wy[4],xx;
374
375 #ifdef TEST_XY_LIMITS
376         if ((x<0)||(x>=(w-1))||(y<0)||(y>=(h-1))) return -1;
377 #endif
378
379         m=(int)ceilf(x)-2; if (m<0) m=0; if ((m+5)>w) m=w-4;
380         n=(int)ceilf(y)-2; if (n<0) n=0; if ((n+5)>h) n=h-4;
381
382         //najprej po y (stiri stolpce)
383         xx=y-n;    wy[0]=(-0.75*(xx-5.0)*xx-6.0)*xx+3.0;
384         xx=xx-1.0; wy[1]=(1.25*xx-2.25)*xx*xx+1.0;
385         xx=1.0-xx; wy[2]=(1.25*xx-2.25)*xx*xx+1.0;
386         xx=xx+1.0; wy[3]=(-0.75*(xx-5.0)*xx-6.0)*xx+3.0;
387         //se po x
388         xx=x-m;    wx[0]=(-0.75*(xx-5.0)*xx-6.0)*xx+3.0;
389         xx=xx-1.0; wx[1]=(1.25*xx-2.25)*xx*xx+1.0;
390         xx=1.0-xx; wx[2]=(1.25*xx-2.25)*xx*xx+1.0;
391         xx=xx+1.0; wx[3]=(-0.75*(xx-5.0)*xx-6.0)*xx+3.0;
392
393         k=4*(n*w+m); u=4*w;
394         for (b=0;b<4;b++)
395         {
396                 for (i=0;i<4;i++)
397                 {
398                         p[i]=0.0;
399                         l=k+4*i;
400                         p[i]=wy[0]*sl[l]; l+=u;
401                         p[i]+=wy[1]*sl[l]; l+=u;
402                         p[i]+=wy[2]*sl[l]; l+=u;
403                         p[i]+=wy[3]*sl[l];
404                 }
405                 k++;
406
407                 pp=wx[0]*p[0];
408                 pp+=wx[1]*p[1];
409                 pp+=wx[2]*p[2];
410                 pp+=wx[3]*p[3];
411
412                 if (pp<0.0) pp=0.0;
413                 if (pp>256.0) pp=255.0;
414
415                 v[b]=pp;
416         }
417
418         return 0;
419 }
420
421 //------------------------------------------------------
422 //spline 4x4 interpolacija
423 //za byte (char) vrednosti
424 //Helmut Dersch polinom
425 //      *sl vhodni array (slika)
426 //      w,h dimenzija slike je wxh
427 //      x,y tocka, za katero izracuna interpolirano vrednost
428 //  o opacity
429 //      *v interpolirana vrednost
430 int interpSP4_b(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
431 {
432         int i,j,m,n;
433         float pp,p[4],wx[4],wy[4],xx;
434
435 #ifdef TEST_XY_LIMITS
436         if ((x<0)||(x>=(w-1))||(y<0)||(y>=(h-1))) return -1;
437 #endif
438
439         m=(int)ceilf(x)-2; if (m<0) m=0; if ((m+5)>w) m=w-4;
440         n=(int)ceilf(y)-2; if (n<0) n=0; if ((n+5)>h) n=h-4;
441
442         //najprej po y (stiri stolpce)
443         xx=y-n;    wy[0]=((-0.333333*(xx-1.0)+0.8)*(xx-1.0)-0.466667)*(xx-1.0);
444         xx=xx-1.0; wy[1]=((xx-1.8)*xx-0.2)*xx+1.0;
445         xx=1.0-xx; wy[2]=((xx-1.8)*xx-0.2)*xx+1.0;
446         xx=xx+1.0; wy[3]=((-0.333333*(xx-1.0)+0.8)*(xx-1.0)-0.466667)*(xx-1.0);
447         //se po x
448         xx=x-m;    wx[0]=((-0.333333*(xx-1.0)+0.8)*(xx-1.0)-0.466667)*(xx-1.0);
449         xx=xx-1.0; wx[1]=((xx-1.8)*xx-0.2)*xx+1.0;
450         xx=1.0-xx; wx[2]=((xx-1.8)*xx-0.2)*xx+1.0;
451         xx=xx+1.0; wx[3]=((-0.333333*(xx-1.0)+0.8)*(xx-1.0)-0.466667)*(xx-1.0);
452
453         for (i=0;i<4;i++)
454         {
455                 p[i]=0.0;
456                 for (j=0;j<4;j++)
457                 {
458                         p[i]=p[i]+wy[j]*sl[(j+n)*w+i+m];
459                 }
460         }
461
462         pp=0.0;
463         for (i=0;i<4;i++)
464                 pp=pp+wx[i]*p[i];
465
466         if (pp<0.0) pp=0.0;
467         if (pp>256.0) pp=255.0;
468
469         *v=pp;
470         return 0;
471 }
472
473 //------------------------------------------------------
474 //spline 4x4 interpolacija
475 //za byte (char) vrednosti  v packed color 32 bitnem formatu
476 int interpSP4_b32(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
477 {
478         int i,j,m,n,b;
479         float pp,p[4],wx[4],wy[4],xx;
480
481 #ifdef TEST_XY_LIMITS
482         if ((x<0)||(x>=(w-1))||(y<0)||(y>=(h-1))) return -1;
483 #endif
484
485         m=(int)ceilf(x)-2; if (m<0) m=0; if ((m+5)>w) m=w-4;
486         n=(int)ceilf(y)-2; if (n<0) n=0; if ((n+5)>h) n=h-4;
487
488         //najprej po y (stiri stolpce)
489         xx=y-n;    wy[0]=((-0.333333*(xx-1.0)+0.8)*(xx-1.0)-0.466667)*(xx-1.0);
490         xx=xx-1.0; wy[1]=((xx-1.8)*xx-0.2)*xx+1.0;
491         xx=1.0-xx; wy[2]=((xx-1.8)*xx-0.2)*xx+1.0;
492         xx=xx+1.0; wy[3]=((-0.333333*(xx-1.0)+0.8)*(xx-1.0)-0.466667)*(xx-1.0);
493         //se po x
494         xx=x-m;    wx[0]=((-0.333333*(xx-1.0)+0.8)*(xx-1.0)-0.466667)*(xx-1.0);
495         xx=xx-1.0; wx[1]=((xx-1.8)*xx-0.2)*xx+1.0;
496         xx=1.0-xx; wx[2]=((xx-1.8)*xx-0.2)*xx+1.0;
497         xx=xx+1.0; wx[3]=((-0.333333*(xx-1.0)+0.8)*(xx-1.0)-0.466667)*(xx-1.0);
498
499         for (b=0;b<4;b++)
500         {
501                 for (i=0;i<4;i++)
502                 {
503                         p[i]=0.0;
504                         for (j=0;j<4;j++)
505                         {
506                                 p[i]=p[i]+wy[j]*sl[4*((j+n)*w+i+m)+b];
507                         }
508                 }
509
510                 pp=0.0;
511                 for (i=0;i<4;i++)
512                         pp=pp+wx[i]*p[i];
513
514                 if (pp<0.0) pp=0.0;
515                 if (pp>256.0) pp=255.0;
516
517                 v[b]=pp;
518         }
519
520         return 0;
521 }
522
523 //------------------------------------------------------
524 //spline 6x6 interpolacija
525 //za byte (char) vrednosti
526 //Helmut Dersch polinom
527 //      *sl vhodni array (slika)
528 //      w,h dimenzija slike je wxh
529 //      x,y tocka, za katero izracuna interpolirano vrednost
530 //  o opacity
531 //      *v interpolirana vrednost
532 //!!! PAZI, TOLE NE DELA CISTO PRAV ???   belina se siri
533 //!!! zaenkrat sem dodal fudge factor...
534 int interpSP6_b(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
535 {
536         int i,j,m,n;
537         float pp,p[6],wx[6],wy[6],xx;
538
539 #ifdef TEST_XY_LIMITS
540         if ((x<0)||(x>=(w-1))||(y<0)||(y>=(h-1))) return -1;
541 #endif
542
543         m=(int)ceilf(x)-3; if (m<0) m=0; if ((m+7)>w) m=w-6;
544         n=(int)ceilf(y)-3; if (n<0) n=0; if ((n+7)>h) n=h-6;
545
546         //najprej po y (sest stolpcev)
547         xx=y-n;
548         wy[0]=((0.090909*(xx-2.0)-0.215311)*(xx-2.0)+0.124402)*(xx-2.0);
549         xx=xx-1.0;
550         wy[1]=((-0.545455*(xx-1.0)+1.291866)*(xx-1.0)-0.746411)*(xx-1.0);
551         xx=xx-1.0;
552         wy[2]=((1.181818*xx-2.167464)*xx+0.014354)*xx+1.0;
553         xx=1.0-xx;
554         wy[3]=((1.181818*xx-2.167464)*xx+0.014354)*xx+1.0;
555         xx=xx+1.0;
556         wy[4]=((-0.545455*(xx-1.0)+1.291866)*(xx-1.0)-0.746411)*(xx-1.0);
557         xx=xx+1.0;
558         wy[5]=((0.090909*(xx-2.0)-0.215311)*(xx-2.0)+0.124402)*(xx-2.0);
559         //se po x
560         xx=x-m;
561         wx[0]=((0.090909*(xx-2.0)-0.215311)*(xx-2.0)+0.124402)*(xx-2.0);
562         xx=xx-1.0;
563         wx[1]=((-0.545455*(xx-1.0)+1.291866)*(xx-1.0)-0.746411)*(xx-1.0);
564         xx=xx-1.0;
565         wx[2]=((1.181818*xx-2.167464)*xx+0.014354)*xx+1.0;
566         xx=1.0-xx;
567         wx[3]=((1.181818*xx-2.167464)*xx+0.014354)*xx+1.0;
568         xx=xx+1.0;
569         wx[4]=((-0.545455*(xx-1.0)+1.291866)*(xx-1.0)-0.746411)*(xx-1.0);
570         xx=xx+1.0;
571         wx[5]=((0.090909*(xx-2.0)-0.215311)*(xx-2.0)+0.124402)*(xx-2.0);
572
573
574         for (i=0;i<6;i++)
575         {
576                 p[i]=0.0;
577                 for (j=0;j<6;j++)
578                 {
579                         p[i]=p[i]+wy[j]*sl[(j+n)*w+i+m];
580                 }
581         }
582
583         pp=0.0;
584         for (i=0;i<6;i++)
585                 pp=pp+wx[i]*p[i];
586
587         pp=0.947*pp;    //fudge factor...!!!    cca 0.947...
588         if (pp<0.0) pp=0.0;
589         if (pp>256.0) pp=255.0;
590
591         *v=pp;
592         return 0;
593 }
594
595 //------------------------------------------------------
596 //spline 6x6 interpolacija
597 //za byte (char) vrednosti  v packed color 32 bitnem formatu
598 //!!! PAZI, TOLE NE DELA CISTO PRAV ???   belina se siri
599 //!!! zaenkrat sem dodal fudge factor...
600 int interpSP6_b32(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
601 {
602         int i,b,j,m,n;
603         float pp,p[6],wx[6],wy[6],xx;
604
605 #ifdef TEST_XY_LIMITS
606         if ((x<0)||(x>=(w-1))||(y<0)||(y>=(h-1))) return -1;
607 #endif
608
609         m=(int)ceilf(x)-3; if (m<0) m=0; if ((m+7)>w) m=w-6;
610         n=(int)ceilf(y)-3; if (n<0) n=0; if ((n+7)>h) n=h-6;
611
612         //najprej po y (sest stolpcev)
613         xx=y-n;
614         wy[0]=((0.090909*(xx-2.0)-0.215311)*(xx-2.0)+0.124402)*(xx-2.0);
615         xx=xx-1.0;
616         wy[1]=((-0.545455*(xx-1.0)+1.291866)*(xx-1.0)-0.746411)*(xx-1.0);
617         xx=xx-1.0;
618         wy[2]=((1.181818*xx-2.167464)*xx+0.014354)*xx+1.0;
619         xx=1.0-xx;
620         wy[3]=((1.181818*xx-2.167464)*xx+0.014354)*xx+1.0;
621         xx=xx+1.0;
622         wy[4]=((-0.545455*(xx-1.0)+1.291866)*(xx-1.0)-0.746411)*(xx-1.0);
623         xx=xx+1.0;
624         wy[5]=((0.090909*(xx-2.0)-0.215311)*(xx-2.0)+0.124402)*(xx-2.0);
625         //se po x
626         xx=x-m;
627         wx[0]=((0.090909*(xx-2.0)-0.215311)*(xx-2.0)+0.124402)*(xx-2.0);
628         xx=xx-1.0;
629         wx[1]=((-0.545455*(xx-1.0)+1.291866)*(xx-1.0)-0.746411)*(xx-1.0);
630         xx=xx-1.0;
631         wx[2]=((1.181818*xx-2.167464)*xx+0.014354)*xx+1.0;
632         xx=1.0-xx;
633         wx[3]=((1.181818*xx-2.167464)*xx+0.014354)*xx+1.0;
634         xx=xx+1.0;
635         wx[4]=((-0.545455*(xx-1.0)+1.291866)*(xx-1.0)-0.746411)*(xx-1.0);
636         xx=xx+1.0;
637         wx[5]=((0.090909*(xx-2.0)-0.215311)*(xx-2.0)+0.124402)*(xx-2.0);
638
639
640         for (b=0;b<4;b++)
641         {
642                 for (i=0;i<6;i++)
643                 {
644                         p[i]=0.0;
645                         for (j=0;j<6;j++)
646                         {
647                                 p[i]=p[i]+wy[j]*sl[4*((j+n)*w+i+m)+b];
648                         }
649                 }
650
651                 pp=0.0;
652                 for (i=0;i<6;i++)
653                         pp=pp+wx[i]*p[i];
654
655                 pp=0.947*pp;    //fudge factor...!!!    cca 0.947...
656                 if (pp<0.0) pp=0.0;
657                 if (pp>256.0) pp=255.0;
658
659                 v[b]=pp;
660         }
661
662         return 0;
663 }
664
665 //------------------------------------------------------
666 //truncated sinc "lanczos" 16x16 interpolacija
667 //za byte (char) vrednosti
668 //      *sl vhodni array (slika)
669 //      w,h dimenzija slike je wxh
670 //      x,y tocka, za katero izracuna interpolirano vrednost
671 //  o opacity
672 //      *v interpolirana vrednost
673 int interpSC16_b(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
674 {
675         int i,j,m,n;
676         float pp,p[16],wx[16],wy[16],xx,xxx,x1;
677         float PI=3.141592654;
678
679 #ifdef TEST_XY_LIMITS
680         if ((x<0)||(x>=(w-1))||(y<0)||(y>=(h-1))) return -1;
681 #endif
682
683         m=(int)ceilf(x)-8; if (m<0) m=0; if ((m+17)>w) m=w-16;
684         n=(int)ceilf(y)-8; if (n<0) n=0; if ((n+17)>h) n=h-16;
685
686         //najprej po y
687         xx=y-n;
688         for (i=7;i>=0;i--)
689         {
690                 x1=xx*PI;
691                 wy[7-i]=(sin(x1)/(x1))*(sin(x1*0.125)/(x1*0.125));
692                 xxx=(float)(2*i+1)-xx;
693                 x1=xxx*PI;
694                 wy[8+i]=(sin(x1)/(x1))*(sin(x1*0.125)/(x1*0.125));
695                 xx=xx-1.0;
696         }
697         //se po x
698         xx=x-m;
699         for (i=7;i>=0;i--)
700         {
701                 x1=xx*PI;
702                 wx[7-i]=(sin(x1)/(x1))*(sin(x1*0.125)/(x1*0.125));
703                 xxx=(float)(2*i+1)-xx;
704                 x1=xxx*PI;
705                 wx[8+i]=(sin(x1)/(x1))*(sin(x1*0.125)/(x1*0.125));
706                 xx=xx-1.0;
707         }
708
709         for (i=0;i<16;i++)
710         {
711                 p[i]=0.0;
712                 for (j=0;j<16;j++)
713                 {
714                         p[i]=p[i]+wy[j]*sl[(j+n)*w+i+m];
715                 }
716         }
717
718         pp=0.0;
719         for (i=0;i<16;i++)
720                 pp=pp+wx[i]*p[i];
721
722         if (pp<0.0) pp=0.0;
723         if (pp>256.0) pp=255.0;
724
725         *v=pp;
726         return 0;
727 }
728
729 //------------------------------------------------------
730 //truncated sinc "lanczos" 16x16 interpolacija
731 //za byte (char) vrednosti  v packed color 32 bitnem formatu
732 int interpSC16_b32(unsigned char *sl, int w, int h, float x, float y, float o, unsigned char *v, int is_alpha)
733 {
734         int i,j,m,b,n;
735         float pp,p[16],wx[16],wy[16],xx,xxx,x1;
736         float PI=3.141592654;
737
738 #ifdef TEST_XY_LIMITS
739         if ((x<0)||(x>=(w-1))||(y<0)||(y>=(h-1))) return -1;
740 #endif
741
742         m=(int)ceilf(x)-8; if (m<0) m=0; if ((m+17)>w) m=w-16;
743         n=(int)ceilf(y)-8; if (n<0) n=0; if ((n+17)>h) n=h-16;
744
745         //najprej po y
746         xx=y-n;
747         for (i=7;i>=0;i--)
748         {
749                 x1=xx*PI;
750                 wy[7-i]=(sin(x1)/(x1))*(sin(x1*0.125)/(x1*0.125));
751                 xxx=(float)(2*i+1)-xx;
752                 x1=xxx*PI;
753                 wy[8+i]=(sin(x1)/(x1))*(sin(x1*0.125)/(x1*0.125));
754                 xx=xx-1.0;
755         }
756         //se po x
757         xx=x-m;
758         for (i=7;i>=0;i--)
759         {
760                 x1=xx*PI;
761                 wx[7-i]=(sin(x1)/(x1))*(sin(x1*0.125)/(x1*0.125));
762                 xxx=(float)(2*i+1)-xx;
763                 x1=xxx*PI;
764                 wx[8+i]=(sin(x1)/(x1))*(sin(x1*0.125)/(x1*0.125));
765                 xx=xx-1.0;
766         }
767
768         for (b=0;b<4;b++)
769         {
770                 for (i=0;i<16;i++)
771                 {
772                         p[i]=0.0;
773                         for (j=0;j<16;j++)
774                         {
775                                 p[i]=p[i]+wy[j]*sl[4*((j+n)*w+i+m)+b];
776                         }
777                 }
778
779                 pp=0.0;
780                 for (i=0;i<16;i++)
781                         pp=pp+wx[i]*p[i];
782
783                 if (pp<0.0) pp=0.0;
784                 if (pp>256.0) pp=255.0;
785
786                 v[b]=pp;
787         }
788
789         return 0;
790 }