static void _image_orient(struct image *source, struct object *o[5], struct image *img[5]) { int i; struct { int x,y; } or[4]={ {1,0}, {1,1}, {0,1}, {-1,1} }; int x,y; for (i=0; i<5; i++) { push_int(source->xsize); push_int(source->ysize); o[i]=clone_object(image_program,2); img[i]=get_storage(o[i],image_program); push_object(o[i]); } THREADS_ALLOW(); CHRONO("start"); for (i=0; i<4; i++) /* four directions */ { rgb_group *d=img[i]->img; rgb_group *s=source->img; int xz=source->xsize; int yz=source->ysize; int xd=or[i].x; int yd=or[i].y; for(x=1; x<xz-1; x++) for(y=1; y<yz-1; y++) { #define FOOBAR(CO) \ d[x+y*xz].CO \ = \ (COLORTYPE) \ my_abs( s[(x+xd)+(y+yd)*xz].CO - s[(x-xd)+(y-yd)*xz].CO ) FOOBAR(r); FOOBAR(g); FOOBAR(b); #undef FOOBAR } } CHRONO("end"); THREADS_DISALLOW(); }
// -------------------------------------------- void bench_mandelbrot_SIMD(int n, int max_iter) // -------------------------------------------- { // ne rien modifier dans cette fonction int h, w; float a0, a1, b0, b1; vuint32 **M32; uint32 **wM32; uint8 **M8; // chronometrie int iter, niter = 4; int run, nrun = 5; double t0, t1, dt, tmin, t; double cycles; //puts("---------------------------"); //puts("-- bench_mandelbrot_SIMD --"); //puts("---------------------------"); h = w = n; M32 = vui32matrix(0, h-1, 0, w/4-1); M8 = ui8matrix(0, h-1, 0, w-1); wM32 = (uint32**) M32; // ne pas changer a0 = -1.5; a1 = +0.5; b0 = -1.0; b1 = +1.0; CHRONO(calc_mandelbrot_SIMD_F32(M32, h, w, a0, a1, b0, b1, max_iter), cycles); printf("SIMD F32: %10.2f\n", cycles/(n*n)); CHRONO(calc_mandelbrot_SIMD_I32(M32, h, w, a0, a1, b0, b1, max_iter), cycles); // facultatif printf("SIMD I32: %10.2f\n\n", cycles/(n*n)); DEBUG(convert_ui32matrix_ui8matrix(wM32, 0, h-1, 0, w-1, M8)); DEBUG(SavePGM_ui8matrix(M8, 0, h-1, 0, w-1, "M_v.pgm")); free_vui32matrix(M32, 0, h-1, 0, w/4-1); free_ui8matrix(M8, 0, h-1, 0, w-1); }
// ---------------------------------------------- void bench_mandelbrot_scalar(int n, int max_iter) // ---------------------------------------------- { // ne rien modifier dans cette fonction int h, w; int i0, i1, j0, j1; float a0, a1, b0, b1; uint32 **M32; uint8 **M8; // chronometrie int iter, niter = 4; int run, nrun = 5; double t0, t1, dt, tmin, t; double cycles; //puts("-----------------------------"); //puts("-- bench_mandelbrot_scalar --"); //puts("-----------------------------"); h = w = n; M32 = ui32matrix(0, h-1, 0, w-1); M8 = ui8matrix(0, h-1, 0, w-1); a0 = -1.5; a1 = +0.5; b0 = -1.0; b1 = +1.0; CHRONO(calc_mandelbrot_scalar(M32, h, w, a0, a1, b0, b1, max_iter), cycles); printf("scalar: %10.2f\n", cycles/(n*n)); DEBUG(convert_ui32matrix_ui8matrix(M32, 0, h-1, 0, w-1, M8)); DEBUG(SavePGM_ui8matrix(M8, 0, h-1, 0, w-1, "M_scalar.pgm")); free_ui32matrix(M32, 0, h-1, 0, w-1); free_ui8matrix(M8, 0, h-1, 0, w-1); }
void image_orient(INT32 args) { struct object *o[5]; struct image *img[5],*this,*img1; int n; rgb_group *d,*s1,*s2,*s3,*s0; double mag; int i, w, h; CHECK_INIT(); this=THIS; if (args) { if (TYPEOF(sp[-args]) == T_INT) mag=sp[-args].u.integer; else if (TYPEOF(sp[-args]) == T_FLOAT) mag=sp[-args].u.float_number; else { SIMPLE_ARG_TYPE_ERROR("orient",1,"int|float"); UNREACHABLE(mag=0.0); } } else mag=1.0; if (args==1) pop_n_elems(args); if (args>1) { if (TYPEOF(sp[1-args]) != T_ARRAY) SIMPLE_ARG_TYPE_ERROR("orient",2,"array"); if (sp[1-args].u.array->size!=4) Pike_error("The array given as argument 2 to orient do not have size 4\n"); for(i=0; i<4; i++) if ((TYPEOF(sp[1-args].u.array->item[i]) != T_OBJECT) || (!(sp[1-args].u.array->item[i].u.object)) || (sp[1-args].u.array->item[i].u.object->prog!=image_program)) Pike_error("The array given as argument 2 to orient do not contain images\n"); img1=(struct image*)sp[1-args].u.array->item[0].u.object->storage; w=this->xsize; h=this->ysize; for(i=0; i<4; i++) { img1=(struct image*)sp[1-args].u.array->item[i].u.object->storage; if ((img1->xsize!=w)|| (img1->ysize!=h)) Pike_error("The images in the array given as argument 2 to orient have different sizes\n"); } for(i=0; i<4; i++) img[i]=get_storage(sp[1-args].u.array->item[i].u.object,image_program); pop_n_elems(args); push_int(this->xsize); push_int(this->ysize); o[4]=clone_object(image_program,2); img[4]=get_storage(o[4],image_program); push_object(o[4]); w=1; } else { _image_orient(this,o,img); w=0; } s0=img[0]->img; s1=img[1]->img; s2=img[2]->img; s3=img[3]->img; d=img[4]->img; THREADS_ALLOW(); CHRONO("begin hsv..."); n=this->xsize*this->ysize; while (n--) { /* Första färg, sista mörkhet */ double j=(s0->r+s0->g+s0->b-s2->r-s2->g-s2->b)/3.0; /* riktning - - riktning | */ double h=(s1->r+s1->g+s1->b-s3->r-s3->g-s3->b)/3.0; /* riktning \ - riktning / */ int z,w; if (my_abs((int)h) > my_abs((int)j)) if (h) { z = -(int)(32*(j/h)+(h>0)*128+64); w = my_abs((int)h); } else z=0,w=0; else { if (j) { z = -(int)(-32*(h/j)+(j>0)*128+128); w = my_abs((int)j); } else z=0,w=0; } d->r=(COLORTYPE)z; d->g=255; d->b = MINIMUM((COLORTYPE)(w*mag), 255); d++; s0++; s1++; s2++; s3++; } CHRONO("end hsv..."); THREADS_DISALLOW(); if (!w) { add_ref(o[4]); pop_n_elems(5); push_object(o[4]); } }