Index: source/blender/blenkernel/BKE_node.h =================================================================== RCS file: /cvsroot/bf-blender/blender/source/blender/blenkernel/BKE_node.h,v retrieving revision 1.19 diff -u -r1.19 BKE_node.h --- source/blender/blenkernel/BKE_node.h 29 Aug 2006 14:32:06 -0000 1.19 +++ source/blender/blenkernel/BKE_node.h 7 Sep 2006 15:37:16 -0000 @@ -230,6 +230,7 @@ #define CMP_NODE_COMBRGBA 227 #define CMP_NODE_DILATEERODE 228 #define CMP_NODE_ROTATE 229 +#define CMP_NODE_SCALE 230 /* filter types */ #define CMP_FILT_SOFT 0 Index: source/blender/blenkernel/intern/node_composite.c =================================================================== RCS file: /cvsroot/bf-blender/blender/source/blender/blenkernel/intern/node_composite.c,v retrieving revision 1.61 diff -u -r1.61 node_composite.c --- source/blender/blenkernel/intern/node_composite.c 6 Sep 2006 19:13:22 -0000 1.61 +++ source/blender/blenkernel/intern/node_composite.c 7 Sep 2006 15:37:22 -0000 @@ -3200,6 +3200,76 @@ }; +/* **************** Scale ******************** */ + +static bNodeSocketType cmp_node_scale_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_VALUE, 1, "X", 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, 100.0f}, + { SOCK_VALUE, 1, "Y", 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, 100.0f}, + { -1, 0, "" } +}; +static bNodeSocketType cmp_node_scale_out[]= { + { SOCK_RGBA, 0, "Image", 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +/* only supports RGBA nodes now */ +static void node_composit_exec_scale(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + if(out[0]->hasoutput==0) + return; + + if(in[0]->data) { + CompBuf *stackbuf, *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA); + ImBuf *ibuf; + int newx, newy; + + newx= MAX2((int)(in[1]->vec[0]*cbuf->x), 1); + newy= MAX2((int)(in[2]->vec[0]*cbuf->y), 1); + newx= MIN2(newx, 10000); + newy= MIN2(newy, 10000); + + ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0, 0); + if(ibuf) { + ibuf->rect_float= cbuf->rect; + IMB_scaleImBuf(ibuf, newx, newy); + + if(ibuf->rect_float == cbuf->rect) { + /* no scaling happened */ + stackbuf= pass_on_compbuf(cbuf); + } + else { + stackbuf= alloc_compbuf(newx, newy, CB_RGBA, 0); + stackbuf->rect= ibuf->rect_float; + stackbuf->malloc= 1; + } + + ibuf->rect_float= NULL; + ibuf->mall &= ~IB_rectfloat; + IMB_freeImBuf(ibuf); + } + else { + stackbuf= pass_on_compbuf(cbuf); + printf("Scaling to %dx%d failed\n", newx, newy); + } + + out[0]->data= stackbuf; + if(cbuf!=in[0]->data) + free_compbuf(cbuf); + } +} + +static bNodeType cmp_node_scale= { + /* type code */ CMP_NODE_SCALE, + /* name */ "Scale", + /* width+range */ 140, 100, 320, + /* class+opts */ NODE_CLASS_CONVERTOR, NODE_OPTIONS, + /* input sock */ cmp_node_scale_in, + /* output sock */ cmp_node_scale_out, + /* storage */ "", + /* execfunc */ node_composit_exec_scale +}; + /* ****************** types array for all shaders ****************** */ bNodeType *node_all_composit[]= { @@ -3233,6 +3303,7 @@ &cmp_node_zcombine, &cmp_node_dilateerode, &cmp_node_rotate, + &cmp_node_scale, NULL }; Index: source/blender/imbuf/intern/scaling.c =================================================================== RCS file: /cvsroot/bf-blender/blender/source/blender/imbuf/intern/scaling.c,v retrieving revision 1.13 diff -u -r1.13 scaling.c --- source/blender/imbuf/intern/scaling.c 10 Jun 2006 19:56:28 -0000 1.13 +++ source/blender/imbuf/intern/scaling.c 7 Sep 2006 15:37:22 -0000 @@ -53,11 +53,13 @@ uchar *p1,*_p1,*dest; short a,r,g,b,x,y; float af,rf,gf,bf, *p1f, *_p1f, *destf; - int do_float = 0; + int do_rect, do_float; if (ibuf1==NULL) return (0); - if (ibuf1->rect==NULL) return (0); - if (ibuf1->rect_float) do_float = 1; + if (ibuf1->rect==NULL && ibuf1->rect_float==NULL) return (0); + + do_rect= (ibuf1->rect != NULL); + do_float= (ibuf1->rect_float != NULL); if (ibuf1->x <= 1) return(IMB_dupImBuf(ibuf1)); @@ -74,18 +76,20 @@ p1 = _p1; p1f = _p1f; for(x = ibuf2->x ; x>0 ; x--){ - a = *(p1++) ; - b = *(p1++) ; - g = *(p1++) ; - r = *(p1++); - a += *(p1++) ; - b += *(p1++) ; - g += *(p1++) ; - r += *(p1++); - *(dest++) = a >> 1; - *(dest++) = b >> 1; - *(dest++) = g >> 1; - *(dest++) = r >> 1; + if (do_rect) { + a = *(p1++) ; + b = *(p1++) ; + g = *(p1++) ; + r = *(p1++); + a += *(p1++) ; + b += *(p1++) ; + g += *(p1++) ; + r += *(p1++); + *(dest++) = a >> 1; + *(dest++) = b >> 1; + *(dest++) = g >> 1; + *(dest++) = r >> 1; + } if (do_float) { af = *(p1f++); bf = *(p1f++); @@ -101,7 +105,7 @@ *(destf++) = 0.5f*rf; } } - _p1 += (ibuf1->x << 2); + if (do_rect) _p1 += (ibuf1->x << 2); if (do_float) _p1f += (ibuf1->x << 2); } return (ibuf2); @@ -111,13 +115,15 @@ struct ImBuf *IMB_double_fast_x(struct ImBuf *ibuf1) { struct ImBuf *ibuf2; - int *p1,*dest, i, col, do_float=0; + int *p1,*dest, i, col, do_rect, do_float; float *p1f, *destf, colf; if (ibuf1==NULL) return (0); - if (ibuf1->rect==NULL) return (0); - if (ibuf1->rect_float) do_float = 1; + if (ibuf1->rect==NULL && ibuf1->rect_float==NULL) return (0); + do_rect= (ibuf1->rect != NULL); + do_float= (ibuf1->rect_float != NULL); + ibuf2 = IMB_allocImBuf(2 * ibuf1->x , ibuf1->y , ibuf1->depth, ibuf1->flags, 0); if (ibuf2==NULL) return (0); @@ -127,13 +133,15 @@ destf = ibuf2->rect_float; for(i = ibuf1->y * ibuf1->x ; i>0 ; i--) { - col = *p1++; - *dest++ = col; - *dest++ = col; + if (do_rect) { + col = *p1++; + *dest++ = col; + *dest++ = col; + } if (do_float) { colf = *p1f++; - *destf++ = col; - *destf++ = col; + *destf++ = colf; + *destf++ = colf; } } @@ -145,7 +153,7 @@ struct ImBuf *ibuf2; if (ibuf1==NULL) return (0); - if (ibuf1->rect==NULL) return (0); + if (ibuf1->rect==NULL && ibuf1->rect_float==NULL) return (0); ibuf2 = IMB_double_fast_x(ibuf1); @@ -159,15 +167,18 @@ struct ImBuf *ibuf2; uchar *p1,*p2,*_p1,*dest; short a,r,g,b,x,y; - int do_float = 0; + int do_rect, do_float; float af,rf,gf,bf,*p1f,*p2f,*_p1f,*destf; - p1f = NULL; p2f = NULL; + p1= p2= NULL; + p1f= p2f= NULL; if (ibuf1==NULL) return (0); - if (ibuf1->rect==NULL) return (0); - if (ibuf1->rect_float) do_float = 1; + if (ibuf1->rect==NULL && ibuf1->rect_float==NULL) return (0); if (ibuf1->y <= 1) return(IMB_dupImBuf(ibuf1)); + do_rect= (ibuf1->rect != NULL); + do_float= (ibuf1->rect_float != NULL); + ibuf2 = IMB_allocImBuf(ibuf1->x , (ibuf1->y) / 2 , ibuf1->depth, ibuf1->flags, 0); if (ibuf2==NULL) return (0); @@ -177,25 +188,29 @@ destf= ibuf2->rect_float; for(y=ibuf2->y ; y>0 ; y--){ - p1 = _p1; - p2 = _p1 + (ibuf1->x << 2); + if (do_rect) { + p1 = _p1; + p2 = _p1 + (ibuf1->x << 2); + } if (do_float) { p1f = _p1f; p2f = _p1f + (ibuf1->x << 2); } for(x = ibuf2->x ; x>0 ; x--){ - a = *(p1++) ; - b = *(p1++) ; - g = *(p1++) ; - r = *(p1++); - a += *(p2++) ; - b += *(p2++) ; - g += *(p2++) ; - r += *(p2++); - *(dest++) = a >> 1; - *(dest++) = b >> 1; - *(dest++) = g >> 1; - *(dest++) = r >> 1; + if (do_rect) { + a = *(p1++) ; + b = *(p1++) ; + g = *(p1++) ; + r = *(p1++); + a += *(p2++) ; + b += *(p2++) ; + g += *(p2++) ; + r += *(p2++); + *(dest++) = a >> 1; + *(dest++) = b >> 1; + *(dest++) = g >> 1; + *(dest++) = r >> 1; + } if (do_float) { af = *(p1f++) ; bf = *(p1f++) ; @@ -211,7 +226,7 @@ *(destf++) = 0.5f*rf; } } - _p1 += (ibuf1->x << 3); + if (do_rect) _p1 += (ibuf1->x << 3); if (do_float) _p1f += (ibuf1->x << 3); } return (ibuf2); @@ -224,11 +239,13 @@ int *p1, *dest1, *dest2; float *p1f, *dest1f, *dest2f; short x,y; - int do_float =0; + int do_rect, do_float; if (ibuf1==NULL) return (0); - if (ibuf1->rect==NULL) return (0); - if (ibuf1->rect_float) do_float =1; + if (ibuf1->rect==NULL && ibuf1->rect_float==NULL) return (0); + + do_rect= (ibuf1->rect != NULL); + do_float= (ibuf1->rect_float != NULL); ibuf2 = IMB_allocImBuf(ibuf1->x , 2 * ibuf1->y , ibuf1->depth, ibuf1->flags, 0); if (ibuf2==NULL) return (0); @@ -239,9 +256,11 @@ dest1f= ibuf2->rect_float; for(y = ibuf1->y ; y>0 ; y--){ - dest2 = dest1 + ibuf2->x; - for(x = ibuf2->x ; x>0 ; x--) *dest1++ = *dest2++ = *p1++; - dest1 = dest2; + if (do_rect) { + dest2 = dest1 + ibuf2->x; + for(x = ibuf2->x ; x>0 ; x--) *dest1++ = *dest2++ = *p1++; + dest1 = dest2; + } if (do_float) { dest2f = dest1f + ibuf2->x; for(x = ibuf2->x ; x>0 ; x--) *dest1f++ = *dest2f++ = *p1f++; @@ -269,14 +288,16 @@ struct ImBuf *IMB_onehalf(struct ImBuf *ibuf1) { struct ImBuf *ibuf2; - uchar *p1, *p2, *dest; + uchar *p1, *p2 = NULL, *dest; float *p1f, *destf, *p2f = NULL; int x,y; - int do_float =0; + int do_rect, do_float; if (ibuf1==NULL) return (0); - if (ibuf1->rect==NULL) return (0); - if (ibuf1->rect_float) do_float = 1; + if (ibuf1->rect==NULL && ibuf1->rect_float==NULL) return (0); + + do_rect= (ibuf1->rect != NULL); + do_float= (ibuf1->rect_float != NULL); if (ibuf1->x <= 1) return(IMB_half_y(ibuf1)); if (ibuf1->y <= 1) return(IMB_half_x(ibuf1)); @@ -290,16 +311,18 @@ dest=(uchar *) ibuf2->rect; for(y=ibuf2->y;y>0;y--){ - p2 = p1 + (ibuf1->x << 2); + if (do_rect) p2 = p1 + (ibuf1->x << 2); if (do_float) p2f = p1f + (ibuf1->x << 2); for(x=ibuf2->x;x>0;x--){ - dest[0] = (p1[0] + p2[0] + p1[4] + p2[4]) >> 2; - dest[1] = (p1[1] + p2[1] + p1[5] + p2[5]) >> 2; - dest[2] = (p1[2] + p2[2] + p1[6] + p2[6]) >> 2; - dest[3] = (p1[3] + p2[3] + p1[7] + p2[7]) >> 2; - p1 += 8; - p2 += 8; - dest += 4; + if (do_rect) { + dest[0] = (p1[0] + p2[0] + p1[4] + p2[4]) >> 2; + dest[1] = (p1[1] + p2[1] + p1[5] + p2[5]) >> 2; + dest[2] = (p1[2] + p2[2] + p1[6] + p2[6]) >> 2; + dest[3] = (p1[3] + p2[3] + p1[7] + p2[7]) >> 2; + p1 += 8; + p2 += 8; + dest += 4; + } if (do_float){ destf[0] = 0.25f*(p1f[0] + p2f[0] + p1f[4] + p2f[4]); destf[1] = 0.25f*(p1f[1] + p2f[1] + p1f[5] + p2f[5]); @@ -310,10 +333,10 @@ destf += 4; } } - p1=p2; + if (do_rect) p1=p2; if (do_float) p1f=p2f; if(ibuf1->x & 1) { - p1+=4; + if (do_rect) p1+=4; if (do_float) p1f+=4; } } @@ -327,14 +350,17 @@ struct ImBuf *ibuf2; uchar *p1,*p2,*p3,*dest; float *p1f, *p2f, *p3f, *destf; - int do_float=0; + int do_rect, do_float; short a,r,g,b,x,y,i; float af,rf,gf,bf; - p2f = NULL; p3f = NULL; + p2= p3= NULL; + p2f= p3f= NULL; if (ibuf1==NULL) return (0); - if (ibuf1->rect==NULL) return (0); - if (ibuf1->rect_float) do_float = 1; + if (ibuf1->rect==NULL && ibuf1->rect_float==NULL) return (0); + + do_rect= (ibuf1->rect != NULL); + do_float= (ibuf1->rect_float != NULL); ibuf2=IMB_allocImBuf((ibuf1->x)/3, (ibuf1->y)/3, ibuf1->depth, ibuf1->flags, 0); if (ibuf2==NULL) return (0); @@ -345,8 +371,10 @@ dest=(uchar *) ibuf2->rect; for(y=ibuf2->y;y>0;y--){ - p2 = p1 + (ibuf1->x << 2); - p3 = p2 + (ibuf1->x << 2); + if (do_rect) { + p2 = p1 + (ibuf1->x << 2); + p3 = p2 + (ibuf1->x << 2); + } if (do_float) { p2f = p1f + (ibuf1->x <<2); p3f = p2f + (ibuf1->x <<2); @@ -355,10 +383,12 @@ a=r=g=b=0; af=rf=gf=bf=0; for (i=3;i>0;i--){ - a += *(p1++) + *(p2++) + *(p3++); - b += *(p1++) + *(p2++) + *(p3++); - g += *(p1++) + *(p2++) + *(p3++); - r += *(p1++) + *(p2++) + *(p3++); + if (do_rect) { + a += *(p1++) + *(p2++) + *(p3++); + b += *(p1++) + *(p2++) + *(p3++); + g += *(p1++) + *(p2++) + *(p3++); + r += *(p1++) + *(p2++) + *(p3++); + } if (do_float) { af += *(p1f++) + *(p2f++) + *(p3f++); bf += *(p1f++) + *(p2f++) + *(p3f++); @@ -366,10 +396,12 @@ rf += *(p1f++) + *(p2f++) + *(p3f++); } } - *(dest++) = a/9; - *(dest++) = b/9; - *(dest++) = g/9; - *(dest++) = r/9; + if (do_rect) { + *(dest++) = a/9; + *(dest++) = b/9; + *(dest++) = g/9; + *(dest++) = r/9; + } if (do_float) { *(destf++) = af/9.0f; *(destf++) = bf/9.0f; @@ -377,7 +409,7 @@ *(destf++) = rf/9.0f; } } - p1=p3; + if (do_rect) p1=p3; if (do_float) p1f = p3f; } return (ibuf2); @@ -391,12 +423,15 @@ float *p1f,*p2f,*destf; short a,r,g,b,x,y,i; float af,rf,gf,bf; - int do_float = 0; + int do_rect, do_float; - p2f = NULL; + p2= NULL; + p2f= NULL; if (ibuf1==NULL) return (0); - if (ibuf1->rect==NULL) return (0); - if (ibuf1->rect_float) do_float = 1; + if (ibuf1->rect==NULL && ibuf1->rect_float==NULL) return (0); + + do_rect= (ibuf1->rect != NULL); + do_float= (ibuf1->rect_float != NULL); ibuf2=IMB_allocImBuf((ibuf1->x)/4, (ibuf1->y)/2, ibuf1->depth, ibuf1->flags, 0); if (ibuf2==NULL) return (0); @@ -407,16 +442,18 @@ dest=(uchar *) ibuf2->rect; for(y= ibuf2->y / 2 ; y>0;y--){ - p2 = p1 + (ibuf1->x << 3); + if (do_rect) p2 = p1 + (ibuf1->x << 3); if (do_float) p2f = p1f + (ibuf1->x << 3); for(x = 2 * ibuf2->x;x>0;x--){ a=r=g=b=0; af=rf=gf=bf=0; for (i=4;i>0;i--){ - a += *(p1++) + *(p2++); - b += *(p1++) + *(p2++); - g += *(p1++) + *(p2++); - r += *(p1++) + *(p2++); + if (do_rect) { + a += *(p1++) + *(p2++); + b += *(p1++) + *(p2++); + g += *(p1++) + *(p2++); + r += *(p1++) + *(p2++); + } if (do_float) { af += *(p1f++) + *(p2f++); bf += *(p1f++) + *(p2f++); @@ -424,10 +461,12 @@ rf += *(p1f++) + *(p2f++); } } - *(dest++) = a >> 3; - *(dest++) = b >> 3; - *(dest++) = g >> 3; - *(dest++) = r >> 3; + if (do_rect) { + *(dest++) = a >> 3; + *(dest++) = b >> 3; + *(dest++) = g >> 3; + *(dest++) = r >> 3; + } if (do_float) { *(destf++) = 0.125f*af; *(destf++) = 0.125f*bf; @@ -435,7 +474,7 @@ *(destf++) = 0.125f*rf; } } - p1 = p2; + if (do_rect) p1 = p2; if (do_float) p1f = p2f; } return (ibuf2); @@ -447,28 +486,36 @@ uchar *rect, *_newrect, *newrect; float *rectf, *_newrectf, *newrectf; float sample, add, val[4], nval[4], valf[4], nvalf[4]; - int x, y, do_float=0; + int x, y, do_rect = 0, do_float = 0; - rectf = NULL; _newrectf= NULL; newrectf = NULL; + rectf= _newrectf= newrectf= NULL; + rect=_newrect= newrect= NULL; nval[0]= nval[1]= nval[2]= nval[3]= 0.0f; nvalf[0]=nvalf[1]=nvalf[2]=nvalf[3]= 0.0f; if (ibuf==NULL) return(0); - if (ibuf->rect==NULL) return(ibuf); + if (ibuf->rect==NULL && ibuf->rect_float==NULL) return (ibuf); + + if (ibuf->rect) { + do_rect = 1; + _newrect = MEM_mallocN(newx * ibuf->y * sizeof(int), "scaledownx"); + if (_newrect==NULL) return(ibuf); + } if (ibuf->rect_float) { do_float = 1; _newrectf = MEM_mallocN(newx * ibuf->y * sizeof(float) * 4, "scaledownxf"); - if (_newrectf==NULL) return(ibuf); + if (_newrectf==NULL) { + if (_newrect) MEM_freeN(_newrect); + return(ibuf); + } } - _newrect = MEM_mallocN(newx * ibuf->y * sizeof(int), "scaledownx"); - if (_newrect==NULL) return(ibuf); - add = (ibuf->x - 0.001) / newx; - rect = (uchar *) ibuf->rect; - newrect = _newrect; - + if (do_rect) { + rect = (uchar *) ibuf->rect; + newrect = _newrect; + } if (do_float) { rectf = ibuf->rect_float; newrectf = _newrectf; @@ -480,11 +527,12 @@ valf[0]=valf[1]=valf[2]=valf[3]= 0.0f; for (x = newx ; x>0 ; x--) { - nval[0] = - val[0] * sample; - nval[1] = - val[1] * sample; - nval[2] = - val[2] * sample; - nval[3] = - val[3] * sample; - + if (do_rect) { + nval[0] = - val[0] * sample; + nval[1] = - val[1] * sample; + nval[2] = - val[2] * sample; + nval[3] = - val[3] * sample; + } if (do_float) { nvalf[0] = - valf[0] * sample; nvalf[1] = - valf[1] * sample; @@ -497,12 +545,13 @@ while (sample >= 1.0f){ sample -= 1.0f; - nval[0] += rect[0]; - nval[1] += rect[1]; - nval[2] += rect[2]; - nval[3] += rect[3]; - rect += 4; - + if (do_rect) { + nval[0] += rect[0]; + nval[1] += rect[1]; + nval[2] += rect[2]; + nval[3] += rect[3]; + rect += 4; + } if (do_float) { nvalf[0] += rectf[0]; nvalf[1] += rectf[1]; @@ -512,16 +561,17 @@ } } - val[0]= rect[0];val[1]= rect[1];val[2]= rect[2];val[3]= rect[3]; - rect += 4; - - newrect[0] = ((nval[0] + sample * val[0])/add + 0.5f); - newrect[1] = ((nval[1] + sample * val[1])/add + 0.5f); - newrect[2] = ((nval[2] + sample * val[2])/add + 0.5f); - newrect[3] = ((nval[3] + sample * val[3])/add + 0.5f); - - newrect += 4; - + if (do_rect) { + val[0]= rect[0];val[1]= rect[1];val[2]= rect[2];val[3]= rect[3]; + rect += 4; + + newrect[0] = ((nval[0] + sample * val[0])/add + 0.5f); + newrect[1] = ((nval[1] + sample * val[1])/add + 0.5f); + newrect[2] = ((nval[2] + sample * val[2])/add + 0.5f); + newrect[3] = ((nval[3] + sample * val[3])/add + 0.5f); + + newrect += 4; + } if (do_float) { valf[0]= rectf[0];valf[1]= rectf[1];valf[2]= rectf[2];valf[3]= rectf[3]; @@ -539,10 +589,11 @@ } } - imb_freerectImBuf(ibuf); - ibuf->mall |= IB_rect; - ibuf->rect = (unsigned int *) _newrect; - + if (do_rect) { + imb_freerectImBuf(ibuf); + ibuf->mall |= IB_rect; + ibuf->rect = (unsigned int *) _newrect; + } if (do_float) { imb_freerectfloatImBuf(ibuf); ibuf->mall |= IB_rectfloat; @@ -559,31 +610,38 @@ uchar *rect, *_newrect, *newrect; float *rectf, *_newrectf, *newrectf; float sample, add, val[4], nval[4], valf[4], nvalf[4]; - int x, y, skipx, do_float = 0; + int x, y, skipx, do_rect = 0, do_float = 0; - rectf= NULL; _newrectf = NULL; newrectf = NULL; + rectf= _newrectf= newrectf= NULL; + rect= _newrect= newrect= NULL; nval[0]= nval[1]= nval[2]= nval[3]= 0.0f; nvalf[0]=nvalf[1]=nvalf[2]=nvalf[3]= 0.0f; if (ibuf==NULL) return(0); - if (ibuf->rect==NULL) return(ibuf); - + if (ibuf->rect==NULL && ibuf->rect_float==NULL) return (ibuf); + + if (ibuf->rect) { + do_rect = 1; + _newrect = MEM_mallocN(newy * ibuf->x * sizeof(int), "scaledowny"); + if (_newrect==NULL) return(ibuf); + } if (ibuf->rect_float) { do_float = 1; _newrectf = MEM_mallocN(newy * ibuf->x * sizeof(float) * 4, "scaldownyf"); - if (_newrectf==NULL) return(ibuf); + if (_newrectf==NULL) { + if (_newrect) MEM_freeN(_newrect); + return(ibuf); + } } - _newrect = MEM_mallocN(newy * ibuf->x * sizeof(int), "scaledowny"); - if (_newrect==NULL) return(ibuf); - add = (ibuf->y - 0.001) / newy; skipx = 4 * ibuf->x; for (x = skipx - 4; x>=0 ; x-= 4) { - - rect = ((uchar *) ibuf->rect) + x; - newrect = _newrect + x; + if (do_rect) { + rect = ((uchar *) ibuf->rect) + x; + newrect = _newrect + x; + } if (do_float) { rectf = ibuf->rect_float + x; newrectf = _newrectf + x; @@ -594,11 +652,12 @@ valf[0]=valf[1]=valf[2]=valf[3]= 0.0f; for (y = newy ; y>0 ; y--) { - nval[0] = - val[0] * sample; - nval[1] = - val[1] * sample; - nval[2] = - val[2] * sample; - nval[3] = - val[3] * sample; - + if (do_rect) { + nval[0] = - val[0] * sample; + nval[1] = - val[1] * sample; + nval[2] = - val[2] * sample; + nval[3] = - val[3] * sample; + } if (do_float) { nvalf[0] = - valf[0] * sample; nvalf[1] = - valf[1] * sample; @@ -611,12 +670,13 @@ while (sample >= 1.0) { sample -= 1.0; - nval[0] += rect[0]; - nval[1] += rect[1]; - nval[2] += rect[2]; - nval[3] += rect[3]; - rect += skipx; - + if (do_rect) { + nval[0] += rect[0]; + nval[1] += rect[1]; + nval[2] += rect[2]; + nval[3] += rect[3]; + rect += skipx; + } if (do_float) { nvalf[0] += rectf[0]; nvalf[1] += rectf[1]; @@ -625,16 +685,18 @@ rectf += skipx; } } - val[0]= rect[0];val[1]= rect[1];val[2]= rect[2];val[3]= rect[3]; - rect += skipx; - - newrect[0] = ((nval[0] + sample * val[0])/add + 0.5f); - newrect[1] = ((nval[1] + sample * val[1])/add + 0.5f); - newrect[2] = ((nval[2] + sample * val[2])/add + 0.5f); - newrect[3] = ((nval[3] + sample * val[3])/add + 0.5f); - - newrect += skipx; - + + if (do_rect) { + val[0]= rect[0];val[1]= rect[1];val[2]= rect[2];val[3]= rect[3]; + rect += skipx; + + newrect[0] = ((nval[0] + sample * val[0])/add + 0.5f); + newrect[1] = ((nval[1] + sample * val[1])/add + 0.5f); + newrect[2] = ((nval[2] + sample * val[2])/add + 0.5f); + newrect[3] = ((nval[3] + sample * val[3])/add + 0.5f); + + newrect += skipx; + } if (do_float) { valf[0]= rectf[0];valf[1]= rectf[1];valf[2]= rectf[2];valf[3]= rectf[3]; @@ -652,10 +714,11 @@ } } - imb_freerectImBuf(ibuf); - ibuf->mall |= IB_rect; - ibuf->rect = (unsigned int *) _newrect; - + if (do_rect) { + imb_freerectImBuf(ibuf); + ibuf->mall |= IB_rect; + ibuf->rect = (unsigned int *) _newrect; + } if (do_float) { imb_freerectfloatImBuf(ibuf); ibuf->mall |= IB_rectfloat; @@ -669,7 +732,7 @@ static struct ImBuf *scaleupx(struct ImBuf *ibuf, int newx) { - uchar *rect,*_newrect,*newrect; + uchar *rect,*_newrect=NULL,*newrect; float *rectf,*_newrectf=NULL,*newrectf; float sample,add; float val_a,nval_a,diff_a; @@ -680,23 +743,29 @@ float val_bf,nval_bf,diff_bf; float val_gf,nval_gf,diff_gf; float val_rf,nval_rf,diff_rf; - int x,y, do_float = 0; + int x,y, do_rect = 0, do_float = 0; + val_a = nval_a = diff_a = val_b = nval_b = diff_b = 0; + val_g = nval_g = diff_g = val_r = nval_r = diff_r = 0; val_af = nval_af = diff_af = val_bf = nval_bf = diff_bf = 0; val_gf = nval_gf = diff_gf = val_rf = nval_rf = diff_rf = 0; if (ibuf==NULL) return(0); - if (ibuf->rect==NULL) return(ibuf); - - _newrect = MEM_mallocN(newx * ibuf->y * sizeof(int), "scaleupx"); - if (_newrect==NULL) return(ibuf); + if (ibuf->rect==NULL && ibuf->rect_float==NULL) return (ibuf); + if (ibuf->rect) { + do_rect = 1; + _newrect = MEM_mallocN(newx * ibuf->y * sizeof(int), "scaleupx"); + if (_newrect==NULL) return(ibuf); + } if (ibuf->rect_float) { do_float = 1; _newrectf = MEM_mallocN(newx * ibuf->y * sizeof(float) * 4, "scaleupxf"); - if (_newrectf==NULL) return(ibuf); + if (_newrectf==NULL) { + if (_newrect) MEM_freeN(_newrect); + return(ibuf); + } } - add = (ibuf->x - 1.001) / (newx - 1.0); rect = (uchar *) ibuf->rect; @@ -707,48 +776,46 @@ for (y = ibuf->y; y>0 ; y--){ sample = 0; - val_a = rect[0] ; - nval_a = rect[4]; - diff_a = nval_a - val_a ; - val_a += 0.5; - - val_b = rect[1] ; - nval_b = rect[5]; - diff_b = nval_b - val_b ; - val_b += 0.5; - - val_g = rect[2] ; - nval_g = rect[6]; - diff_g = nval_g - val_g ; - val_g += 0.5; - - val_r = rect[3] ; - nval_r = rect[7]; - diff_r = nval_r - val_r ; - val_r += 0.5; - - rect += 8; + + if (do_rect) { + val_a = rect[0] ; + nval_a = rect[4]; + diff_a = nval_a - val_a ; + val_a += 0.5; + + val_b = rect[1] ; + nval_b = rect[5]; + diff_b = nval_b - val_b ; + val_b += 0.5; + + val_g = rect[2] ; + nval_g = rect[6]; + diff_g = nval_g - val_g ; + val_g += 0.5; + + val_r = rect[3] ; + nval_r = rect[7]; + diff_r = nval_r - val_r ; + val_r += 0.5; + rect += 8; + } if (do_float) { val_af = rectf[0] ; nval_af = rectf[4]; diff_af = nval_af - val_af; - val_af += 0.5; val_bf = rectf[1] ; nval_bf = rectf[5]; diff_bf = nval_bf - val_bf; - val_bf += 0.5; val_gf = rectf[2] ; nval_gf = rectf[6]; diff_gf = nval_gf - val_gf; - val_gf += 0.5; val_rf = rectf[3] ; nval_rf = rectf[7]; diff_rf = nval_rf - val_rf; - val_rf += 0.5; rectf += 8; } @@ -756,55 +823,54 @@ if (sample >= 1.0){ sample -= 1.0; - val_a = nval_a ; - nval_a = rect[0] ; - diff_a = nval_a - val_a ; - val_a += 0.5; - - val_b = nval_b ; - nval_b = rect[1] ; - diff_b = nval_b - val_b ; - val_b += 0.5; - - val_g = nval_g ; - nval_g = rect[2] ; - diff_g = nval_g - val_g ; - val_g += 0.5; - - val_r = nval_r ; - nval_r = rect[3] ; - diff_r = nval_r - val_r ; - val_r += 0.5; - rect += 4; - + if (do_rect) { + val_a = nval_a ; + nval_a = rect[0] ; + diff_a = nval_a - val_a ; + val_a += 0.5; + + val_b = nval_b ; + nval_b = rect[1] ; + diff_b = nval_b - val_b ; + val_b += 0.5; + + val_g = nval_g ; + nval_g = rect[2] ; + diff_g = nval_g - val_g ; + val_g += 0.5; + + val_r = nval_r ; + nval_r = rect[3] ; + diff_r = nval_r - val_r ; + val_r += 0.5; + rect += 4; + } if (do_float) { val_af = nval_af ; nval_af = rectf[0] ; diff_af = nval_af - val_af ; - val_af += 0.5; val_bf = nval_bf ; nval_bf = rectf[1] ; diff_bf = nval_bf - val_bf ; - val_bf += 0.5; val_gf = nval_gf ; nval_gf = rectf[2] ; diff_gf = nval_gf - val_gf ; - val_gf += 0.5; val_rf = nval_rf ; nval_rf = rectf[3] ; diff_rf = nval_rf - val_rf; - val_rf += 0.5; rectf += 4; } } - newrect[0] = val_a + sample * diff_a; - newrect[1] = val_b + sample * diff_b; - newrect[2] = val_g + sample * diff_g; - newrect[3] = val_r + sample * diff_r; - newrect += 4; + if (do_rect) { + newrect[0] = val_a + sample * diff_a; + newrect[1] = val_b + sample * diff_b; + newrect[2] = val_g + sample * diff_g; + newrect[3] = val_r + sample * diff_r; + newrect += 4; + } if (do_float) { newrectf[0] = val_af + sample * diff_af; newrectf[1] = val_bf + sample * diff_bf; @@ -816,10 +882,11 @@ } } - imb_freerectImBuf(ibuf); - ibuf->mall |= IB_rect; - ibuf->rect = (unsigned int *) _newrect; - + if (do_rect) { + imb_freerectImBuf(ibuf); + ibuf->mall |= IB_rect; + ibuf->rect = (unsigned int *) _newrect; + } if (do_float) { imb_freerectfloatImBuf(ibuf); ibuf->mall |= IB_rectfloat; @@ -830,99 +897,181 @@ return(ibuf); } - static struct ImBuf *scaleupy(struct ImBuf *ibuf, int newy) { - uchar *rect,*_newrect,*newrect; - float *rectf = NULL, *newrectf = NULL, *_newrectf = NULL; - float sample,add,val,nval,diff, valf=0.0f, nvalf=0.0f, difff=0.0f; - int x,y,i,skipx, do_float = 0; + uchar *rect,*_newrect=NULL,*newrect; + float *rectf,*_newrectf=NULL,*newrectf; + float sample,add; + float val_a,nval_a,diff_a; + float val_b,nval_b,diff_b; + float val_g,nval_g,diff_g; + float val_r,nval_r,diff_r; + float val_af,nval_af,diff_af; + float val_bf,nval_bf,diff_bf; + float val_gf,nval_gf,diff_gf; + float val_rf,nval_rf,diff_rf; + int x,y, do_rect = 0, do_float = 0, skipx; + val_a = nval_a = diff_a = val_b = nval_b = diff_b = 0; + val_g = nval_g = diff_g = val_r = nval_r = diff_r = 0; + val_af = nval_af = diff_af = val_bf = nval_bf = diff_bf = 0; + val_gf = nval_gf = diff_gf = val_rf = nval_rf = diff_rf = 0; if (ibuf==NULL) return(0); - if (ibuf->rect==NULL) return(ibuf); - - _newrect = MEM_mallocN(newy * ibuf->x * sizeof(int), "scaleupy"); - if (_newrect==NULL) return(ibuf); + if (ibuf->rect==NULL && ibuf->rect_float==NULL) return (ibuf); + if (ibuf->rect) { + do_rect = 1; + _newrect = MEM_mallocN(ibuf->x * newy * sizeof(int), "scaleupy"); + if (_newrect==NULL) return(ibuf); + } if (ibuf->rect_float) { do_float = 1; - _newrectf = MEM_mallocN(newy * ibuf->x * sizeof(float) * 4, "scaleupyf"); - if (_newrectf==NULL) return(ibuf); + _newrectf = MEM_mallocN(ibuf->x * newy * sizeof(float) * 4, "scaleupyf"); + if (_newrectf==NULL) { + if (_newrect) MEM_freeN(_newrect); + return(ibuf); + } } add = (ibuf->y - 1.001) / (newy - 1.0); skipx = 4 * ibuf->x; - /* all four components, rgba/abgr */ - for(i=3 ; i>=0 ; i--){ - for (x = skipx - 4; x >= 0 ; x -= 4){ - - rect = (uchar *) ibuf->rect; - rect += i + x; - newrect = _newrect + i + x; - - if (do_float) { - rectf = ibuf->rect_float; - rectf += i * x; - newrectf = _newrectf + i + x; - valf = *rectf; - rectf += skipx; - nvalf = *rectf; - rectf += skipx; - difff = nvalf - valf; - valf += 0.5; - } + rect = (uchar *) ibuf->rect; + rectf = (float *) ibuf->rect_float; + newrect = _newrect; + newrectf = _newrectf; + + for (x = ibuf->x; x>0 ; x--){ + + sample = 0; + if (do_rect) { + rect = ((uchar *)ibuf->rect) + 4*(x-1); + newrect = _newrect + 4*(x-1); + + val_a = rect[0] ; + nval_a = rect[skipx]; + diff_a = nval_a - val_a ; + val_a += 0.5; + + val_b = rect[1] ; + nval_b = rect[skipx+1]; + diff_b = nval_b - val_b ; + val_b += 0.5; + + val_g = rect[2] ; + nval_g = rect[skipx+2]; + diff_g = nval_g - val_g ; + val_g += 0.5; + + val_r = rect[3] ; + nval_r = rect[skipx+4]; + diff_r = nval_r - val_r ; + val_r += 0.5; + + rect += 2*skipx; + } + if (do_float) { + rectf = ((float *)ibuf->rect_float) + 4*(x-1); + newrectf = _newrectf + 4*(x-1); + + val_af = rectf[0] ; + nval_af = rectf[skipx]; + diff_af = nval_af - val_af; + + val_bf = rectf[1] ; + nval_bf = rectf[skipx+1]; + diff_bf = nval_bf - val_bf; + + val_gf = rectf[2] ; + nval_gf = rectf[skipx+2]; + diff_gf = nval_gf - val_gf; - sample = 0; - val = *rect ; - rect += skipx; - nval = *rect; - rect += skipx; - diff = nval - val; - val += 0.5; - - for (y = newy ; y>0 ; y--){ - if (sample >= 1.0){ - sample -= 1.0; - val = nval; - nval = *rect; + val_rf = rectf[3] ; + nval_rf = rectf[skipx+3]; + diff_rf = nval_rf - val_rf; + + rectf += 2*skipx; + } + + for (y = newy ; y>0 ; y--){ + if (sample >= 1.0){ + sample -= 1.0; + + if (do_rect) { + val_a = nval_a ; + nval_a = rect[0] ; + diff_a = nval_a - val_a ; + val_a += 0.5; + + val_b = nval_b ; + nval_b = rect[1] ; + diff_b = nval_b - val_b ; + val_b += 0.5; + + val_g = nval_g ; + nval_g = rect[2] ; + diff_g = nval_g - val_g ; + val_g += 0.5; + + val_r = nval_r ; + nval_r = rect[3] ; + diff_r = nval_r - val_r ; + val_r += 0.5; rect += skipx; - diff = nval - val; - val += 0.5; - - if (do_float) { - valf = nvalf; - nvalf = *rectf; - rectf += skipx; - difff = nvalf - valf; - valf += 0.5; - } } - *newrect = val + sample * diff; - newrect += skipx; - if (do_float) { - *newrectf = valf + sample * difff; - newrectf += skipx; + val_af = nval_af ; + nval_af = rectf[0] ; + diff_af = nval_af - val_af ; + + val_bf = nval_bf ; + nval_bf = rectf[1] ; + diff_bf = nval_bf - val_bf ; + + val_gf = nval_gf ; + nval_gf = rectf[2] ; + diff_gf = nval_gf - val_gf ; + + val_rf = nval_rf ; + nval_rf = rectf[3] ; + diff_rf = nval_rf - val_rf; + rectf += skipx; } - sample += add; } + if (do_rect) { + newrect[0] = val_a + sample * diff_a; + newrect[1] = val_b + sample * diff_b; + newrect[2] = val_g + sample * diff_g; + newrect[3] = val_r + sample * diff_r; + newrect += skipx; + } + if (do_float) { + newrectf[0] = val_af + sample * diff_af; + newrectf[1] = val_bf + sample * diff_bf; + newrectf[2] = val_gf + sample * diff_gf; + newrectf[3] = val_rf + sample * diff_rf; + newrectf += skipx; + } + sample += add; } } - imb_freerectImBuf(ibuf); - ibuf->mall |= IB_rect; - ibuf->rect = (unsigned int *) _newrect; - - if(do_float) { + if (do_rect) { + imb_freerectImBuf(ibuf); + ibuf->mall |= IB_rect; + ibuf->rect = (unsigned int *) _newrect; + } + if (do_float) { imb_freerectfloatImBuf(ibuf); ibuf->mall |= IB_rectfloat; - ibuf->rect_float = _newrectf; + ibuf->rect_float = (float *) _newrectf; } + ibuf->y = newy; return(ibuf); } + /* no float buf needed here! */ static void scalefast_Z_ImBuf(ImBuf *ibuf, short newx, short newy) { @@ -960,7 +1109,7 @@ struct ImBuf *IMB_scaleImBuf(struct ImBuf * ibuf, short newx, short newy) { if (ibuf==NULL) return (0); - if (ibuf->rect==NULL) return (ibuf); + if (ibuf->rect==NULL && ibuf->rect_float==NULL) return (ibuf); // scaleup / scaledown functions below change ibuf->x and ibuf->y // so we first scale the Z-buffer (if any) @@ -1003,7 +1152,10 @@ if (do_float) { _newrectf = MEM_mallocN(newx * newy * sizeof(float) * 4, "scalefastimbuf f"); - if (_newrectf==NULL) return(ibuf); + if (_newrectf==NULL) { + if (_newrect) MEM_freeN(_newrect); + return(ibuf); + } newrectf = _newrectf; }