Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/imbuf/intern/imageprocess.c')
-rw-r--r--source/blender/imbuf/intern/imageprocess.c87
1 files changed, 53 insertions, 34 deletions
diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c
index 4890e240c6b..d7f1ab4419d 100644
--- a/source/blender/imbuf/intern/imageprocess.c
+++ b/source/blender/imbuf/intern/imageprocess.c
@@ -48,22 +48,28 @@ I stole it from util.h in the plugins api */
/* Only this one is used liberally here, and in imbuf */
void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf)
{
- int size, do_float=0;
+ int size;
unsigned char rt, *cp = (unsigned char *)ibuf->rect;
float rtf, *cpf = ibuf->rect_float;
-
- if (ibuf->rect_float) do_float = 1;
- size = ibuf->x * ibuf->y;
- while(size-- > 0) {
- rt= cp[0];
- cp[0]= cp[3];
- cp[3]= rt;
- rt= cp[1];
- cp[1]= cp[2];
- cp[2]= rt;
- cp+= 4;
- if (do_float) {
+ if (ibuf->rect) {
+ size = ibuf->x * ibuf->y;
+
+ while(size-- > 0) {
+ rt= cp[0];
+ cp[0]= cp[3];
+ cp[3]= rt;
+ rt= cp[1];
+ cp[1]= cp[2];
+ cp[2]= rt;
+ cp+= 4;
+ }
+ }
+
+ if (ibuf->rect_float) {
+ size = ibuf->x * ibuf->y;
+
+ while(size-- > 0) {
rtf= cpf[0];
cpf[0]= cpf[3];
cpf[3]= rtf;
@@ -87,16 +93,14 @@ void IMB_convert_rgba_to_abgr(struct ImBuf *ibuf)
*/
/* function assumes out to be zero'ed, only does RGBA */
static float P(float k){
- float aux;
- aux=(float)(1.0f/6.0f)*( pow( MAX2(k+2.0f,0) , 3.0f ) - 4.0f * pow( MAX2(k+1.0f,0) , 3.0f ) + 6.0f * pow( MAX2(k,0) , 3.0f ) - 4.0f * pow( MAX2(k-1.0f,0) , 3.0f));
- return aux ;
+ return (float)(1.0f/6.0f)*( pow( MAX2(k+2.0f,0) , 3.0f ) - 4.0f * pow( MAX2(k+1.0f,0) , 3.0f ) + 6.0f * pow( MAX2(k,0) , 3.0f ) - 4.0f * pow( MAX2(k-1.0f,0) , 3.0f));
}
void bicubic_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, int yout)
{
int i,j,n,m,x1,y1;
unsigned char *dataI,*outI;
- float a,b, outR,outG,outB,outA,*dataF,*outF;
+ float a,b,w,wx,wy[4], outR,outG,outB,outA,*dataF,*outF;
int do_rect, do_float;
if (in == NULL) return;
@@ -114,24 +118,39 @@ void bicubic_interpolation(ImBuf *in, ImBuf *out, float x, float y, int xout, in
outG= 0.0f;
outB= 0.0f;
outA= 0.0f;
+
+ /* avoid calling multiple times */
+ wy[0] = P(b-(-1));
+ wy[1] = P(b- 0);
+ wy[2] = P(b- 1);
+ wy[3] = P(b- 2);
+
for(n= -1; n<= 2; n++){
- for(m= -1; m<= 2; m++){
- x1= i+n;
- y1= j+m;
- if (x1>0 && x1 < in->x && y1>0 && y1<in->y) {
- if (do_float) {
- dataF= in->rect_float + in->x * y1 * 4 + 4*x1;
- outR+= dataF[0] * P(n-a) * P(b-m);
- outG+= dataF[1] * P(n-a) * P(b-m);
- outB+= dataF[2] * P(n-a) * P(b-m);
- outA+= dataF[3] * P(n-a) * P(b-m);
- }
- if (do_rect) {
- dataI= (unsigned char*)in->rect + in->x * y1 * 4 + 4*x1;
- outR+= dataI[0] * P(n-a) * P(b-m);
- outG+= dataI[1] * P(n-a) * P(b-m);
- outB+= dataI[2] * P(n-a) * P(b-m);
- outA+= dataI[3] * P(n-a) * P(b-m);
+ x1= i+n;
+ if (x1>0 && x1 < in->x) {
+ wx = P(n-a);
+ for(m= -1; m<= 2; m++){
+ y1= j+m;
+ if (y1>0 && y1<in->y) {
+ /* normally we could do this */
+ /* w = P(n-a) * P(b-m); */
+ /* except that would call P() 16 times per pixel therefor pow() 64 times, better precalc these */
+ w = wx * wy[m+1];
+
+ if (do_float) {
+ dataF= in->rect_float + in->x * y1 * 4 + 4*x1;
+ outR+= dataF[0] * w;
+ outG+= dataF[1] * w;
+ outB+= dataF[2] * w;
+ outA+= dataF[3] * w;
+ }
+ if (do_rect) {
+ dataI= (unsigned char*)in->rect + in->x * y1 * 4 + 4*x1;
+ outR+= dataI[0] * w;
+ outG+= dataI[1] * w;
+ outB+= dataI[2] * w;
+ outA+= dataI[3] * w;
+ }
}
}
}