From 1482aa5e0d65066feb25e66ca77b183e2b8a9d47 Mon Sep 17 00:00:00 2001 From: Per Hedbor <ph@opera.com> Date: Sun, 23 Nov 1997 06:28:29 +0100 Subject: [PATCH] optimized img_clear and fixed tuned_box Rev: src/modules/Image/blit.c:1.19 Rev: src/modules/Image/image.c:1.65 Rev: src/modules/Image/image.h:1.15 --- src/modules/Image/blit.c | 23 ++++++-- src/modules/Image/image.c | 110 +++++++++++++++++++++----------------- src/modules/Image/image.h | 7 ++- 3 files changed, 86 insertions(+), 54 deletions(-) diff --git a/src/modules/Image/blit.c b/src/modules/Image/blit.c index c3749fa8db..c414aa3621 100644 --- a/src/modules/Image/blit.c +++ b/src/modules/Image/blit.c @@ -1,10 +1,10 @@ -/* $Id: blit.c,v 1.18 1997/11/11 01:58:37 grubba Exp $ */ +/* $Id: blit.c,v 1.19 1997/11/23 05:28:27 per Exp $ */ #include "global.h" /* **! module Image **! note -**! $Id: blit.c,v 1.18 1997/11/11 01:58:37 grubba Exp $ +**! $Id: blit.c,v 1.19 1997/11/23 05:28:27 per Exp $ **! class image */ @@ -104,8 +104,25 @@ static INLINE void getrgb(struct image *img, void img_clear(rgb_group *dest,rgb_group rgb,INT32 size) { + int ok = 0; THREADS_ALLOW(); - while (size--) *(dest++)=rgb; + if(sizeof(rgb.r) == 1) + { + if(rgb.r == rgb.b && rgb.b == rgb.g) + (ok = 1),MEMSET(dest, rgb.r, size*sizeof(rgb_group)); + } else { + if(!rgb.r && !rgb.b && !rgb.g) + (ok = 1),MEMSET(dest, 0, size*sizeof(rgb_group)); + } + if(!ok) + { + int increment = 1; + rgb_group *from = dest; + *(dest++)=rgb; + for (; size > increment; size-=increment,dest+=increment,increment*=2) + MEMCPY(dest,from,increment*sizeof(rgb_group)); + MEMCPY(dest,from,size*sizeof(rgb_group)); + } THREADS_DISALLOW(); } diff --git a/src/modules/Image/image.c b/src/modules/Image/image.c index e4e83da599..2b4454f8a7 100644 --- a/src/modules/Image/image.c +++ b/src/modules/Image/image.c @@ -1,9 +1,9 @@ -/* $Id: image.c,v 1.64 1997/11/23 03:29:35 per Exp $ */ +/* $Id: image.c,v 1.65 1997/11/23 05:28:28 per Exp $ */ /* **! module Image **! note -**! $Id: image.c,v 1.64 1997/11/23 03:29:35 per Exp $ +**! $Id: image.c,v 1.65 1997/11/23 05:28:28 per Exp $ **! class image **! **! The main object of the <ref>Image</ref> module, this object @@ -82,7 +82,7 @@ #include "stralloc.h" #include "global.h" -RCSID("$Id: image.c,v 1.64 1997/11/23 03:29:35 per Exp $"); +RCSID("$Id: image.c,v 1.65 1997/11/23 05:28:28 per Exp $"); #include "pike_macros.h" #include "object.h" #include "constants.h" @@ -184,6 +184,8 @@ static void exit_image_struct(struct object *obj) set_rgb_group_alpha(THIS->img[(x)+(y)*THIS->xsize],THIS->rgb,THIS->alpha): \ ((pixel(THIS,x,y)=THIS->rgb),0)) +#define color_equal(A,B) ((A.r == B.r) && (A.g == B.g) && (A.b == B.b)) + #define setpixel_test(x,y) \ ((((int)x)<0||((int)y)<0||((int)x)>=(int)THIS->xsize||((int)y)>=(int)THIS->ysize)? \ 0:(setpixel((int)x,(int)y),0)) @@ -1100,34 +1102,34 @@ static INLINE void get_rgba_group_from_array_index(rgba_group *rgba,struct array } static INLINE void - add_to_rgba_sum_with_factor(rgba_group *sum, - rgba_group rgba, - float factor) + add_to_rgbda_sum_with_factor(rgbda_group *sum, + rgba_group rgba, + float factor) { /* NOTE: - * This code MUST be MT-SAFE! + * This code MUST be MT-SAFE! (but also fast /per) */ - HIDE_GLOBAL_VARIABLES(); - sum->r=testrange(sum->r+(INT32)(rgba.r*factor+0.5)); - sum->g=testrange(sum->g+(INT32)(rgba.g*factor+0.5)); - sum->b=testrange(sum->b+(INT32)(rgba.b*factor+0.5)); - sum->alpha=testrange(sum->alpha+(INT32)(rgba.alpha*factor+0.5)); - REVEAL_GLOBAL_VARIABLES(); +/* HIDE_GLOBAL_VARIABLES(); */ + sum->r=sum->r+rgba.r*factor; + sum->g=sum->g+rgba.g*factor; + sum->b=sum->b+rgba.b*factor; + sum->alpha=sum->alpha+rgba.alpha*factor; +/* REVEAL_GLOBAL_VARIABLES(); */ } static INLINE void - add_to_rgb_sum_with_factor(rgb_group *sum, - rgba_group rgba, - float factor) + add_to_rgbd_sum_with_factor(rgbd_group *sum, + rgba_group rgba, + float factor) { /* NOTE: - * This code MUST be MT-SAFE! + * This code MUST be MT-SAFE! (but also fast /per) */ - HIDE_GLOBAL_VARIABLES(); - sum->r=testrange(sum->r+(INT32)(rgba.r*factor+0.5)); - sum->g=testrange(sum->g+(INT32)(rgba.g*factor+0.5)); - sum->b=testrange(sum->b+(INT32)(rgba.b*factor+0.5)); - REVEAL_GLOBAL_VARIABLES(); +/* HIDE_GLOBAL_VARIABLES(); */ + sum->r=sum->r+rgba.r*factor; + sum->g=sum->g+rgba.g*factor; + sum->b=sum->b+rgba.b*factor; +/* REVEAL_GLOBAL_VARIABLES(); */ } /* @@ -1199,14 +1201,15 @@ image_tuned_box_topbottom(const rgba_group left, const rgba_group right, color.r = (((long)left.r)*(height-y)+((long)right.r)*(y))/height; color.g = (((long)left.g)*(height-y)+((long)right.g)*(y))/height; color.b = (((long)left.b)*(height-y)+((long)right.b)*(y))/height; - if(y && old.r == color.r && old.g == color.g && old.b == color.b) + if(y && color_equal(old, color)) { MEMCPY(dest,dest-xsize,length*sizeof(rgb_group)); dest+=xsize; } else { + from = dest; for(x=0; x<64; x++) *(dest++) = color; - from = (dest-=64); - for(;x<length-64;x+=64) MEMCPY((dest+=64), from, 64*sizeof(rgb_group)); + for(;x<length-64;x+=64,dest+=64) + MEMCPY(dest, from, 64*sizeof(rgb_group)); for(;x<length; x++) *(dest++) = color; dest += xsize-length; old = color; @@ -1218,7 +1221,7 @@ image_tuned_box_topbottom(const rgba_group left, const rgba_group right, color.r = (((long)left.r)*(height-y)+((long)right.r)*(y))/height; color.g = (((long)left.g)*(height-y)+((long)right.g)*(y))/height; color.b = (((long)left.b)*(height-y)+((long)right.b)*(y))/height; - if(y && old.r == color.r && old.g == color.g && old.b == color.b) + if(y && color_equal(old, color)) { MEMCPY(dest,dest-xsize,length*sizeof(rgb_group)); dest+=xsize; @@ -1236,8 +1239,10 @@ void image_tuned_box(INT32 args) INT32 x1,y1,x2,y2,xw,yw,x,y; rgba_group topleft,topright,bottomleft,bottomright,sum,sumzero={0,0,0,0}; rgb_group *img; + INT32 ymax; struct image *this; float dxw, dyw; + rgb_group *rows, *cols; if (args<5|| sp[-args].type!=T_INT|| @@ -1261,9 +1266,6 @@ void image_tuned_box(INT32 args) get_rgba_group_from_array_index(&bottomleft,sp[4-args].u.array,2); get_rgba_group_from_array_index(&bottomright,sp[4-args].u.array,3); -#define color_equal(A,B) ((A.r == B.r) && (A.g == B.g) && (A.b == B.b) && (A.alpha == B.alpha)) - - if (x1>x2) x1^=x2,x2^=x1,x1^=x2, sum=topleft,topleft=topright,topright=sum, sum=bottomleft,bottomleft=bottomright,bottomright=sum; @@ -1274,10 +1276,6 @@ void image_tuned_box(INT32 args) xw=x2-x1; yw=y2-y1; if(xw == 0 || yw == 0) return; - - dxw = 1.0/(float)xw; - dyw = 1.0/(float)yw; - this=THIS; THREADS_ALLOW(); @@ -1287,53 +1285,65 @@ void image_tuned_box(INT32 args) { image_tuned_box_leftright(topleft, bottomright, this->img+x1+this->xsize*y1, - xw, this->xsize, yw); + xw+1, this->xsize, yw+1); return; } else if(color_equal(topleft,topright) && color_equal(bottomleft,bottomright)) { image_tuned_box_topbottom(topleft, bottomleft, this->img+x1+this->xsize*y1, - xw, this->xsize, yw); + xw+1, this->xsize, yw+1); return; } - + dxw = 1.0/(float)xw; + dyw = 1.0/(float)yw; + ymax=min(yw,this->ysize-y1); for (x=max(0,-x1); x<=xw && x+x1<this->xsize; x++) { #define tune_factor(a,aw) (1.0-((float)(a)*(aw))) - INT32 ymax; float tfx1=tune_factor(x,dxw); float tfx2=tune_factor(xw-x,dxw); - ymax=min(yw,this->ysize-y1); img=this->img+x+x1+this->xsize*max(0,y1); if (topleft.alpha||topright.alpha||bottomleft.alpha||bottomright.alpha) for (y=max(0,-y1); y<ymax; y++) { float tfy; - sum=sumzero; + rgbda_group sum={0.0,0.0,0.0,0.0}; + rgbd_group rgb; + + add_to_rgbda_sum_with_factor(&sum,topleft,(tfy=tune_factor(y,dyw))*tfx1); + add_to_rgbda_sum_with_factor(&sum,topright,tfy*tfx2); + add_to_rgbda_sum_with_factor(&sum,bottomleft,(tfy=tune_factor(yw-y,dyw))*tfx1); + add_to_rgbda_sum_with_factor(&sum,bottomright,tfy*tfx2); + + sum.alpha*=(1.0/255.0); + + rgb.r=sum.r*sum.alpha+img->r*(1.0-sum.alpha); + rgb.g=sum.g*sum.alpha+img->g*(1.0-sum.alpha); + rgb.b=sum.b*sum.alpha+img->b*(1.0-sum.alpha); - add_to_rgba_sum_with_factor(&sum,topleft,(tfy=tune_factor(y,dyw))*tfx1); - add_to_rgba_sum_with_factor(&sum,topright,tfy*tfx2); - add_to_rgba_sum_with_factor(&sum,bottomleft,(tfy=tune_factor(yw-y,dyw))*tfx1); - add_to_rgba_sum_with_factor(&sum,bottomright,tfy*tfx2); + img->r=testrange(rgb.r+0.5); + img->g=testrange(rgb.g+0.5); + img->b=testrange(rgb.b+0.5); - set_rgb_group_alpha(*img, sum,sum.alpha); img+=this->xsize; } else for (y=max(0,-y1); y<ymax; y++) { float tfy; - rgb_group rgbsum={0,0,0}; + rgbd_group sum={0,0,0}; - add_to_rgb_sum_with_factor(&rgbsum,topleft,(tfy=tune_factor(y,dyw))*tfx1); - add_to_rgb_sum_with_factor(&rgbsum,topright,tfy*tfx2); - add_to_rgb_sum_with_factor(&rgbsum,bottomleft,(tfy=tune_factor(yw-y,dyw))*tfx1); - add_to_rgb_sum_with_factor(&rgbsum,bottomright,tfy*tfx2); + add_to_rgbd_sum_with_factor(&sum,topleft,(tfy=tune_factor(y,dyw))*tfx1); + add_to_rgbd_sum_with_factor(&sum,topright,tfy*tfx2); + add_to_rgbd_sum_with_factor(&sum,bottomleft,(tfy=tune_factor(yw-y,dyw))*tfx1); + add_to_rgbd_sum_with_factor(&sum,bottomright,tfy*tfx2); - *img=rgbsum; + img->r=testrange(sum.r+0.5); + img->g=testrange(sum.g+0.5); + img->b=testrange(sum.b+0.5); img+=this->xsize; } diff --git a/src/modules/Image/image.h b/src/modules/Image/image.h index 8707190bd1..2abc64c24d 100644 --- a/src/modules/Image/image.h +++ b/src/modules/Image/image.h @@ -1,7 +1,7 @@ /* **! module Image **! note -**! $Id: image.h,v 1.14 1997/11/12 03:40:19 mirar Exp $ +**! $Id: image.h,v 1.15 1997/11/23 05:28:29 per Exp $ */ #ifdef PIKE_IMAGE_IMAGE_H @@ -39,6 +39,11 @@ typedef struct float r,g,b; } rgbd_group; /* use float, it gets so big otherwise... */ +typedef struct +{ + float r,g,b,alpha; +} rgbda_group; /* use float, it gets so big otherwise... */ + struct image { rgb_group *img; -- GitLab