Initial revision
[blender.git] / source / blender / imbuf / intern / scaling.c
1 /**
2  *
3  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30  * allocimbuf.c
31  *
32  * $Id$
33  */
34
35 #ifdef WIN32
36 #include "BLI_winstuff.h"
37 #endif
38 #include "BLI_blenlib.h"
39
40 #include "imbuf.h"
41 #include "imbuf_patch.h"
42 #include "IMB_imbuf_types.h"
43 #include "IMB_imbuf.h"
44
45 #include "IMB_allocimbuf.h"
46 #include "IMB_filter.h"
47
48 /************************************************************************/
49 /*                                                              SCALING                                                                 */
50 /************************************************************************/
51
52
53 struct ImBuf *IMB_half_x(struct ImBuf *ibuf1)
54 {
55         struct ImBuf *ibuf2;
56         uchar *p1,*_p1,*dest;
57         short a,r,g,b,x,y;
58
59         if (ibuf1==0) return (0);
60         if (ibuf1->rect == 0) return (0);
61         
62         if (ibuf1->x <= 1) return(IMB_dupImBuf(ibuf1));
63         
64         ibuf2 = IMB_allocImBuf((ibuf1->x)/2 , ibuf1->y , ibuf1->depth,1,0);
65         if (ibuf2==0) return (0);
66
67         _p1 = (uchar *) ibuf1->rect;
68         dest=(uchar *) ibuf2->rect;
69
70         for(y=ibuf2->y;y>0;y--){
71                 p1 = _p1;
72                 for(x = ibuf2->x ; x>0 ; x--){
73                         a = *(p1++) ;
74                         b = *(p1++) ;
75                         g = *(p1++) ;
76                         r = *(p1++);
77                         a += *(p1++) ;
78                         b += *(p1++) ;
79                         g += *(p1++) ;
80                         r += *(p1++);
81                         *(dest++) = a >> 1;
82                         *(dest++) = b >> 1;
83                         *(dest++) = g >> 1;
84                         *(dest++) = r >> 1;
85                 }
86                 _p1 += (ibuf1->x << 2);
87         }
88         return (ibuf2);
89 }
90
91
92 struct ImBuf *IMB_double_fast_x(struct ImBuf *ibuf1)
93 {
94         struct ImBuf *ibuf2;
95         int *p1,*dest, i, col;
96
97         if (ibuf1==0) return (0);
98         if (ibuf1->rect == 0) return (0);
99
100         ibuf2 = IMB_allocImBuf(2 * ibuf1->x , ibuf1->y , ibuf1->depth,1,0);
101         if (ibuf2==0) return (0);
102
103         p1 = (int *) ibuf1->rect;
104         dest=(int *) ibuf2->rect;
105
106         for(i = ibuf1->y * ibuf1->x ; i>0 ; i--) {
107                 col = *p1++;
108                 *dest++ = col;
109                 *dest++ = col;
110         }
111
112         return (ibuf2);
113 }
114
115 struct ImBuf *IMB_double_x(struct ImBuf *ibuf1)
116 {
117         struct ImBuf *ibuf2;
118
119         if (ibuf1==0) return (0);
120         if (ibuf1->rect == 0) return (0);
121
122         ibuf2 = IMB_double_fast_x(ibuf1);
123
124         imb_filterx(ibuf2);
125         return (ibuf2);
126 }
127
128
129 struct ImBuf *IMB_half_y(struct ImBuf *ibuf1)
130 {
131         struct ImBuf *ibuf2;
132         uchar *p1,*p2,*_p1,*dest;
133         short a,r,g,b,x,y;
134
135         if (ibuf1==0) return (0);
136         if (ibuf1->rect == 0) return (0);
137         if (ibuf1->y <= 1) return(IMB_dupImBuf(ibuf1));
138
139         ibuf2 = IMB_allocImBuf(ibuf1->x , (ibuf1->y) / 2 , ibuf1->depth,1,0);
140         if (ibuf2==0) return (0);
141
142         _p1 = (uchar *) ibuf1->rect;
143         dest=(uchar *) ibuf2->rect;
144
145         for(y=ibuf2->y ; y>0 ; y--){
146                 p1 = _p1;
147                 p2 = _p1 + (ibuf1->x << 2);
148                 for(x = ibuf2->x ; x>0 ; x--){
149                         a = *(p1++) ;
150                         b = *(p1++) ;
151                         g = *(p1++) ;
152                         r = *(p1++);
153                         a += *(p2++) ;
154                         b += *(p2++) ;
155                         g += *(p2++) ;
156                         r += *(p2++);
157                         *(dest++) = a >> 1;
158                         *(dest++) = b >> 1;
159                         *(dest++) = g >> 1;
160                         *(dest++) = r >> 1;
161                 }
162                 _p1 += (ibuf1->x << 3);
163         }
164         return (ibuf2);
165 }
166
167
168 struct ImBuf *IMB_double_fast_y(struct ImBuf *ibuf1)
169 {
170         struct ImBuf *ibuf2;
171         int *p1, *dest1, *dest2;
172         short x,y;
173
174         if (ibuf1==0) return (0);
175         if (ibuf1->rect == 0) return (0);
176
177         ibuf2 = IMB_allocImBuf(ibuf1->x , 2 * ibuf1->y , ibuf1->depth,1,0);
178         if (ibuf2==0) return (0);
179
180         p1 = (int *) ibuf1->rect;
181         dest1=(int *) ibuf2->rect;
182
183         for(y = ibuf1->y ; y>0 ; y--){
184                 dest2 = dest1 + ibuf2->x;
185                 for(x = ibuf2->x ; x>0 ; x--) *dest1++ = *dest2++ = *p1++;
186                 dest1 = dest2;
187         }
188
189         return (ibuf2);
190 }
191
192 struct ImBuf *IMB_double_y(struct ImBuf *ibuf1)
193 {
194         struct ImBuf *ibuf2;
195
196         if (ibuf1==0) return (0);
197         if (ibuf1->rect == 0) return (0);
198
199         ibuf2 = IMB_double_fast_y(ibuf1);
200         
201         IMB_filtery(ibuf2);
202         return (ibuf2);
203 }
204
205
206 struct ImBuf *IMB_onehalf(struct ImBuf *ibuf1)
207 {
208         struct ImBuf *ibuf2;
209         uchar *p1,*p2,*dest;
210         int x,y;
211
212         if (ibuf1 == 0) return (0);
213         if (ibuf1->rect == 0) return (0);
214
215         if (ibuf1->x <= 1) return(IMB_half_y(ibuf1));
216         if (ibuf1->y <= 1) return(IMB_half_x(ibuf1));
217         
218         ibuf2=IMB_allocImBuf((ibuf1->x)/2,(ibuf1->y)/2,ibuf1->depth,1,0);
219         if (ibuf2==0) return (0);
220
221         p1 = (uchar *) ibuf1->rect;
222         dest=(uchar *) ibuf2->rect;
223
224         for(y=ibuf2->y;y>0;y--){
225                 p2 = p1 + (ibuf1->x << 2);
226                 for(x=ibuf2->x;x>0;x--){
227                         dest[0] = (p1[0] + p2[0] + p1[4] + p2[4]) >> 2;
228                         dest[1] = (p1[1] + p2[1] + p1[5] + p2[5]) >> 2;
229                         dest[2] = (p1[2] + p2[2] + p1[6] + p2[6]) >> 2;
230                         dest[3] = (p1[3] + p2[3] + p1[7] + p2[7]) >> 2;
231                         p1 += 8; 
232                         p2 += 8; 
233                         dest += 4;
234                 }
235                 p1=p2;
236                 if(ibuf1->x & 1) {
237                         p1+=4;
238                 }
239         }
240         return (ibuf2);
241 }
242
243
244
245 struct ImBuf *IMB_onethird(struct ImBuf *ibuf1)
246 {
247         struct ImBuf *ibuf2;
248         uchar *p1,*p2,*p3,*dest;
249         short a,r,g,b,x,y,i;
250
251         if (ibuf1 == 0) return (0);
252         if (ibuf1->rect == 0) return (0);
253
254         ibuf2=IMB_allocImBuf((ibuf1->x)/3,(ibuf1->y)/3,ibuf1->depth,1,0);
255         if (ibuf2==0) return (0);
256
257         p1 = (uchar *) ibuf1->rect;
258         dest=(uchar *) ibuf2->rect;
259
260         for(y=ibuf2->y;y>0;y--){
261                 p2 = p1 + (ibuf1->x << 2);
262                 p3 = p2 + (ibuf1->x << 2);
263                 for(x=ibuf2->x;x>0;x--){
264                         a=r=g=b=0;
265                         for (i=3;i>0;i--){
266                                 a += *(p1++) + *(p2++) + *(p3++);
267                                 b += *(p1++) + *(p2++) + *(p3++);
268                                 g += *(p1++) + *(p2++) + *(p3++);
269                                 r += *(p1++) + *(p2++) + *(p3++);
270                         }
271                         *(dest++) = a/9;
272                         *(dest++) = b/9;
273                         *(dest++) = g/9;
274                         *(dest++) = r/9;
275                 }
276                 p1=p3;
277         }
278         return (ibuf2);
279 }
280
281
282 struct ImBuf *IMB_halflace(struct ImBuf *ibuf1)
283 {
284         struct ImBuf *ibuf2;
285         uchar *p1,*p2,*dest;
286         short a,r,g,b,x,y,i;
287
288         if (ibuf1 == 0) return (0);
289         if (ibuf1->rect == 0) return (0);
290
291         ibuf2=IMB_allocImBuf((ibuf1->x)/4,(ibuf1->y)/2,ibuf1->depth,1,0);
292         if (ibuf2==0) return (0);
293
294         p1 = (uchar *) ibuf1->rect;
295         dest=(uchar *) ibuf2->rect;
296
297         for(y= ibuf2->y / 2 ; y>0;y--){
298                 p2 = p1 + (ibuf1->x << 3);
299                 for(x = 2 * ibuf2->x;x>0;x--){
300                         a=r=g=b=0;
301                         for (i=4;i>0;i--){
302                                 a += *(p1++) + *(p2++);
303                                 b += *(p1++) + *(p2++);
304                                 g += *(p1++) + *(p2++);
305                                 r += *(p1++) + *(p2++);
306                         }
307                         *(dest++) = a >> 3;
308                         *(dest++) = b >> 3;
309                         *(dest++) = g >> 3;
310                         *(dest++) = r >> 3;
311                 }
312                 p1 = p2;
313         }
314         return (ibuf2);
315 }
316
317
318 static struct ImBuf *scaledownx(struct ImBuf *ibuf, int newx)
319 {
320         uchar *rect,*_newrect,*newrect;
321         float sample, add, val, nval;
322         int x, y, i;
323
324         if (ibuf == 0) return(0);
325         if (ibuf->rect == 0) return(ibuf);
326
327         _newrect = (uchar *) malloc(newx * ibuf->y * sizeof(int));
328         if (_newrect == 0) return(ibuf);
329
330         add = (ibuf->x - 0.001) / newx;
331
332         /* all four components, rgba/abgr */
333         for(i=3 ; i >= 0 ; i--){
334                 rect = (uchar *) ibuf->rect;
335                 rect += i;
336                 newrect = _newrect + i;
337
338                 for (y = ibuf->y; y>0 ; y--){
339                         val = sample = 0.0;
340
341                         for (x = newx ; x>0 ; x--){
342                                 nval = - val * sample;
343                                 sample += add;
344
345                                 while (sample >= 1.0){
346                                         sample -= 1.0;
347                                         nval += *rect;
348                                         rect += 4;
349                                 }
350                                 val = *rect;
351                                 rect += 4;
352                                 nval += sample * val;
353                                 sample -= 1.0;
354                                 *newrect = (nval/add) + 0.5;
355                                 newrect += 4;
356                         }
357                 }
358         }
359
360         imb_freerectImBuf(ibuf);
361         ibuf->mall |= IB_rect;
362         ibuf->rect = (unsigned int *) _newrect;
363         ibuf->x = newx;
364         return(ibuf);
365 }
366
367
368 static struct ImBuf *scaledowny(struct ImBuf *ibuf, int newy)
369 {
370         uchar *rect,*_newrect,*newrect;
371         float sample,add,val,nval;
372         int x,y,i,skipx;
373
374         if (ibuf == 0) return(0);
375         if (ibuf->rect == 0) return(ibuf);
376
377         _newrect = (uchar *) malloc(newy * ibuf->x * sizeof(int));
378         if (_newrect == 0) return(ibuf);
379
380         add = (ibuf->y - 0.001) / newy;
381         skipx = 4 * ibuf->x;
382
383         /* all four components, rgba/abgr */
384         for(i=3 ; i>=0 ; i--){
385                 for (x = skipx - 4; x>=0 ; x-= 4){
386                         rect = ((uchar *) ibuf->rect) + i + x;
387                         newrect = _newrect + i + x;
388                         val = sample = 0.0;
389
390                         for (y = newy ; y>0 ; y--){
391                                 nval = - val * sample;
392                                 sample += add;
393
394                                 while (sample >= 1.0){
395                                         sample -= 1.0;
396                                         nval += *rect;
397                                         rect += skipx;
398                                 }
399                                 val = *rect;
400                                 rect += skipx;
401                                 nval += sample * val;
402                                 sample -= 1.0;
403                                 *newrect = (nval/add) + 0.5;
404                                 newrect += skipx;
405                         }
406                 }
407         }
408
409         imb_freerectImBuf(ibuf);
410         ibuf->mall |= IB_rect;
411         ibuf->rect = (unsigned int *) _newrect;
412         ibuf->y = newy;
413         return(ibuf);
414 }
415
416
417 static struct ImBuf *scaleupx(struct ImBuf *ibuf, int newx)
418 {
419         uchar *rect,*_newrect,*newrect;
420         float sample,add;
421         float val_a,nval_a,diff_a;
422         float val_b,nval_b,diff_b;
423         float val_g,nval_g,diff_g;
424         float val_r,nval_r,diff_r;
425         int x,y;
426
427         if (ibuf == 0) return(0);
428         if (ibuf->rect == 0) return(ibuf);
429
430         _newrect = (uchar *) malloc(newx * ibuf->y * sizeof(int));
431         if (_newrect == 0) return(ibuf);
432
433         add = (ibuf->x - 1.001) / (newx - 1.0);
434
435         rect = (uchar *) ibuf->rect;
436         newrect = _newrect;
437
438         for (y = ibuf->y; y>0 ; y--){
439
440                 sample = 0;
441                 val_a = rect[0] ;
442                 nval_a = rect[4];
443                 diff_a = nval_a - val_a ;
444                 val_a += 0.5;
445
446                 val_b = rect[1] ;
447                 nval_b = rect[5];
448                 diff_b = nval_b - val_b ;
449                 val_b += 0.5;
450
451                 val_g = rect[2] ;
452                 nval_g = rect[6];
453                 diff_g = nval_g - val_g ;
454                 val_g += 0.5;
455
456                 val_r = rect[3] ;
457                 nval_r = rect[7];
458                 diff_r = nval_r - val_r ;
459                 val_r += 0.5;
460
461                 rect += 8;
462                 for (x = newx ; x>0 ; x--){
463                         if (sample >= 1.0){
464                                 sample -= 1.0;
465                                 val_a = nval_a ;
466                                 nval_a = rect[0] ;
467                                 diff_a = nval_a - val_a ;
468                                 val_a += 0.5;
469
470                                 val_b = nval_b ;
471                                 nval_b = rect[1] ;
472                                 diff_b = nval_b - val_b ;
473                                 val_b += 0.5;
474
475                                 val_g = nval_g ;
476                                 nval_g = rect[2] ;
477                                 diff_g = nval_g - val_g ;
478                                 val_g += 0.5;
479
480                                 val_r = nval_r ;
481                                 nval_r = rect[3] ;
482                                 diff_r = nval_r - val_r ;
483                                 val_r += 0.5;
484                                 rect += 4;
485                         }
486                         newrect[0] = val_a + sample * diff_a;
487                         newrect[1] = val_b + sample * diff_b;
488                         newrect[2] = val_g + sample * diff_g;
489                         newrect[3] = val_r + sample * diff_r;
490                         newrect += 4;
491                         sample += add;
492                 }
493         }
494
495         imb_freerectImBuf(ibuf);
496         ibuf->mall |= IB_rect;
497         ibuf->rect = (unsigned int *) _newrect;
498         ibuf->x = newx;
499         return(ibuf);
500 }
501
502
503 static struct ImBuf *scaleupy(struct ImBuf *ibuf, int newy)
504 {
505         uchar *rect,*_newrect,*newrect;
506         float sample,add,val,nval,diff;
507         int x,y,i,skipx;
508
509         if (ibuf == 0) return(0);
510         if (ibuf->rect == 0) return(ibuf);
511
512         _newrect = (uchar *)malloc(newy * ibuf->x * sizeof(int));
513         if (_newrect == 0) return(ibuf);
514
515         add = (ibuf->y - 1.001) / (newy - 1.0);
516         skipx = 4 * ibuf->x;
517
518         /* all four components, rgba/abgr */
519         for(i=3 ; i>=0 ; i--){
520                 for (x = skipx - 4; x >= 0 ; x -= 4){
521                         rect = (uchar *) ibuf->rect;
522                         rect += i + x;
523                         newrect = _newrect + i + x;
524
525                         sample = 0;
526                         val = *rect ;
527                         rect += skipx;
528                         nval = *rect;
529                         rect += skipx;
530                         diff = nval - val;
531                         val += 0.5;
532
533                         for (y = newy ; y>0 ; y--){
534                                 if (sample >= 1.0){
535                                         sample -= 1.0;
536                                         val = nval;
537                                         nval = *rect;
538                                         rect += skipx;
539                                         diff = nval - val;
540                                         val += 0.5;
541                                 }
542                                 *newrect = val + sample * diff;
543                                 newrect += skipx;
544                                 sample += add;
545                         }
546                 }
547         }
548
549         imb_freerectImBuf(ibuf);
550         ibuf->mall |= IB_rect;
551         ibuf->rect = (unsigned int *) _newrect;
552         ibuf->y = newy;
553         return(ibuf);
554 }
555
556 static void scalefast_Z_ImBuf(ImBuf *ibuf, short newx, short newy)
557 {
558         unsigned int *rect,*_newrect,*newrect;
559         int x,y;
560         int ofsx,ofsy,stepx,stepy;
561
562         if (ibuf->zbuf) {
563                 _newrect = malloc(newx * newy * sizeof(int));
564                 if (_newrect == 0) return;
565         
566                 stepx = (65536.0 * (ibuf->x - 1.0) / (newx - 1.0)) + 0.5;
567                 stepy = (65536.0 * (ibuf->y - 1.0) / (newy - 1.0)) + 0.5;
568                 ofsy = 32768;
569
570                 newrect = _newrect;
571         
572                 for (y = newy; y > 0 ; y--){
573                         rect = (unsigned int*) ibuf->zbuf;
574                         rect += (ofsy >> 16) * ibuf->x;
575                         ofsy += stepy;
576                         ofsx = 32768;
577                         for (x = newx ; x > 0 ; x--){
578                                 *newrect++ = rect[ofsx >> 16];
579                                 ofsx += stepx;
580                         }
581                 }
582         
583                 IMB_freezbufImBuf(ibuf);
584                 ibuf->mall |= IB_zbuf;
585                 ibuf->zbuf = (int*) _newrect;
586         }
587 }
588
589 struct ImBuf *IMB_scaleImBuf(struct ImBuf * ibuf, short newx, short newy)
590 {
591         if (ibuf == 0) return (0);
592         if (ibuf->rect == 0) return (ibuf);
593
594         // scaleup / scaledown functions below change ibuf->x and ibuf->y
595         // so we first scale the Z-buffer (if any)
596         scalefast_Z_ImBuf(ibuf, newx, newy);
597
598         if (newx < ibuf->x) if (newx) scaledownx(ibuf,newx);
599         if (newy < ibuf->y) if (newy) scaledowny(ibuf,newy);
600         if (newx > ibuf->x) if (newx) scaleupx(ibuf,newx);
601         if (newy > ibuf->y) if (newy) scaleupy(ibuf,newy);
602         
603         return(ibuf);
604 }
605
606
607 struct ImBuf *IMB_scalefastImBuf(struct ImBuf *ibuf, short newx, short newy)
608 {
609         unsigned int *rect,*_newrect,*newrect;
610         int x,y;
611         int ofsx,ofsy,stepx,stepy;
612
613         if (ibuf == 0) return(0);
614         if (ibuf->rect == 0) return(ibuf);
615
616         if (newx == ibuf->x && newy == ibuf->y) return(ibuf);
617
618         _newrect = malloc(newx * newy * sizeof(int));
619         if (_newrect == 0) return(ibuf);
620
621         newrect = _newrect;
622         stepx = (65536.0 * (ibuf->x - 1.0) / (newx - 1.0)) + 0.5;
623         stepy = (65536.0 * (ibuf->y - 1.0) / (newy - 1.0)) + 0.5;
624         ofsy = 32768;
625
626         for (y = newy; y > 0 ; y--){
627                 rect = ibuf->rect;
628                 rect += (ofsy >> 16) * ibuf->x;
629                 ofsy += stepy;
630                 ofsx = 32768;
631                 for (x = newx ; x>0 ; x--){
632                         *newrect++ = rect[ofsx >> 16];
633                         ofsx += stepx;
634                 }
635         }
636
637         imb_freerectImBuf(ibuf);
638         ibuf->mall |= IB_rect;
639         ibuf->rect = _newrect;
640         
641         scalefast_Z_ImBuf(ibuf, newx, newy);
642         
643         ibuf->x = newx;
644         ibuf->y = newy;
645         return(ibuf);
646 }
647
648
649 static struct ImBuf *generic_fieldscale(struct ImBuf *ibuf, short newx, short newy, struct ImBuf *(*scalefunc)(ImBuf *, short, short) )
650 {
651         struct ImBuf *sbuf1, *sbuf2;
652 /*      extern void rectcpy(); */
653         
654         sbuf1 = IMB_allocImBuf(ibuf->x, ibuf->y / 2, ibuf->depth, IB_rect, 0);
655         sbuf2 = IMB_allocImBuf(ibuf->x, ibuf->y / 2, ibuf->depth, IB_rect, 0);
656         
657         ibuf->x *= 2;
658         /* more args needed, 0 assumed... (nzc) */
659 /*      rectop(sbuf1, ibuf, 0, 0, 0, 0, 32767, 32767, rectcpy); */
660 /*      rectop(sbuf2, ibuf, 0, 0, sbuf2->x, 0, 32767, 32767, rectcpy); */
661         IMB_rectop(sbuf1, ibuf, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0);
662         IMB_rectop(sbuf2, ibuf, 0, 0, sbuf2->x, 0, 32767, 32767, IMB_rectcpy, 0);
663         
664         imb_freerectImBuf(ibuf);
665         ibuf->x = newx;
666         ibuf->y = newy;
667         imb_addrectImBuf(ibuf);
668         
669         scalefunc(sbuf1, newx, newy / 2);
670         scalefunc(sbuf2, newx, newy / 2);       
671         
672         ibuf->x *= 2;
673         
674         /* more args needed, 0 assumed... (nzc) */
675 /*      rectop(ibuf, sbuf1, 0, 0, 0, 0, 32767, 32767, rectcpy); */
676 /*      rectop(ibuf, sbuf2, sbuf2->x, 0, 0, 0, 32767, 32767, rectcpy); */
677         IMB_rectop(ibuf, sbuf1, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0);
678         IMB_rectop(ibuf, sbuf2, sbuf2->x, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0);
679         
680         ibuf->x /= 2;
681         
682         IMB_freeImBuf(sbuf1);
683         IMB_freeImBuf(sbuf2);
684         
685         return(ibuf);
686 }
687
688
689 struct ImBuf *IMB_scalefastfieldImBuf(struct ImBuf *ibuf,
690                                                                           short newx,
691                                                                           short newy)
692 {
693         return(generic_fieldscale(ibuf, newx, newy, IMB_scalefastImBuf));
694 }
695
696 struct ImBuf *IMB_scalefieldImBuf(struct ImBuf *ibuf, short newx, short newy)
697 {
698         return(generic_fieldscale(ibuf, newx, newy, IMB_scaleImBuf));
699 }