Exemple #1
0
int test_curve(int c) {
    spiro_cp spiro[16];
    int nextknot[17];
    spiro_seg *segs = NULL;
    bezctx *bc;
    int i;

    /* Load sample data so that we can see if library is callable */
    load_test_curve(spiro,nextknot,c);

    /* Check if run_spiro works okay */
    printf("testing run_spiro() using data=path%d[].\n",c);
    if ( (segs=run_spiro(spiro,cl[c]))==0 ) {
	printf("error with run_spiro() using data=path%d[].\n",c);
	return -1;
    }

    /* Quick visual check shows X,Y knots match with each pathN[] */
    for (i=0; i < cl[c]; i++) {
	printf("curve %d, line %d, x=%f y=%f t=%c bend=%f ch=%f th=%f l=%f \n",c,i,segs[i].x,segs[i].y,segs[i].ty,segs[i].bend_th,segs[i].seg_ch,segs[i].seg_th,segs[i].l);
    }

    /* Quick visual check shows X,Y knots match with each pathN[] */
    printf("testing spiro_to_bpath() using data from run_spiro(data=path%d[],len=%d).\n",c,cl[c]);
    bc = new_bezctx_test();
    spiro_to_bpath(segs,cl[c],bc);

    free(segs);

    /* Check if TaggedSpiroCPsToBezier0() works okay */
    printf("---\ntesting TaggedSpiroCPsToBezier0() using data=path%d[].\n",c);
    if ( TaggedSpiroCPsToBezier0(spiro,bc)!=1 ) {
	printf("error with TaggedSpiroCPsToBezier0() using data=path%d[].\n",c);
	return -1;
    }

    /* Check if SpiroCPsToBezier0() works okay */
    printf("---\ntesting SpiroCPsToBezier0() using data=path%d[].\n",c);
    if ( SpiroCPsToBezier0(spiro,cl[c],(c==0 ? 1 : 0),bc)!=1 ) {
	printf("error with SpiroCPsToBezier0() using data=path%d[].\n",c);
	return -1;
    }

    free(bc);
    return 0;
}
Exemple #2
0
int test_multi_curves(void) {
    spiro_cp **spiro = NULL;
    int *pk, **nextknot = NULL;
    int *scl = NULL;
    test_bezctx **bc;
    int i, j, k, ret;

#if HAVE_PTHREADS
    printf("---\nMulti-thread testing of libspiro.\n");
    /* pthread default limit is currently about 380 without mods. */
#define S_TESTS 300
#else
    printf("---\nSequential tests of libspiro.\n");
#define S_TESTS 3000
#endif

    ret = -1;	/* return error if out of memory */


    /* Expect lots of results */
    if ( (bc=(test_bezctx**)calloc(S_TESTS,sizeof(test_bezctx*)))==NULL )
	goto test_multi_curves_exit;
    for (i=0; i < S_TESTS; i++) {
	if ( (bc[i]=(test_bezctx*)malloc(sizeof(test_bezctx)))==NULL )
	    goto test_multi_curves_exit;
	bc[i]->base.moveto = test_s_moveto;
	bc[i]->base.lineto = test_s_lineto;
	bc[i]->base.quadto = test_s_quadto;
	bc[i]->base.curveto = test_s_curveto;
	bc[i]->base.mark_knot = test_s_mark_knot;
	if ( (bc[i]->my_curve=(my_curve_data*)calloc(S_RESULTS,sizeof(my_curve_data)))==NULL )
	    goto test_multi_curves_exit;
	bc[i]->len = 0;		/* no curve yet, len=0 */
	bc[i]->is_open = 0;
	bc[i]->c_id = i;	/* identify each curve */
    }

    if ( (scl=(int*)malloc(S_TESTS*sizeof(int)))==NULL || \
	 (spiro=(spiro_cp**)calloc(S_TESTS,sizeof(spiro_cp*)))==NULL || \
	 (nextknot=(int**)calloc(S_TESTS,sizeof(int*)))==NULL )
	goto test_multi_curves_exit;
    for (i=0; i < S_TESTS; ) {
	/* NOTE: S_TESTS has to be multiple of 3 here. */
	if ( (spiro[i]=malloc(cl[0]*sizeof(spiro_cp)))==NULL || \
	      (nextknot[i]=calloc(cl[0]+1,sizeof(int)))==NULL )
	    goto test_multi_curves_exit;
	load_test_curve(spiro[i], nextknot[i], 0);
	scl[i++]=cl[0];
	if ( (spiro[i]=malloc(cl[1]*sizeof(spiro_cp)))==NULL || \
	      (nextknot[i]=calloc(cl[1],sizeof(int)))==NULL )
	    goto test_multi_curves_exit;
	load_test_curve(spiro[i], nextknot[i], 1);
	scl[i++]=cl[1];
	if ( (spiro[i]=malloc(cl[2]*sizeof(spiro_cp)))==NULL || \
	      (nextknot[i]=calloc(cl[2],sizeof(int)))==NULL )
	    goto test_multi_curves_exit;
	load_test_curve(spiro[i], nextknot[i], 2);
	scl[i++]=cl[2];
    }

    /* Change to different sizes to make sure no duplicates */
    for (i=0; i < S_TESTS; i++) {
	spiro_cp *temp;
	temp = spiro[i];
	for (j=0; j < scl[i]; j++) {
	    temp[j].x = temp[j].x * ((i+1.0)/100);
	    temp[j].y = temp[j].y * ((i+1.0)/100);
	}
    }

#if HAVE_PTHREADS
    /* Test all curves - all at same time, wait for all to finish */
    pthread_t curve_test[S_TESTS];
    pthread_pcurve pdata[S_TESTS];
    for (i=0; i < S_TESTS; i++) {
	pdata[i].spiro = spiro[i];
	pdata[i].bc = (bezctx*)(bc[i]);
	pdata[i].ret = i;
    }

    j=0;
    for (i=0; i < S_TESTS; i++)
	/* all values passed are joined at "->" (should be okay). */
	if ( pthread_create(&curve_test[i],NULL,test_a_curve,(void *)&pdata[i]) ) {
	    printf("bad pthread_create[%d]\n",i);
	    j=-1;
	    break;
	}
    while (--i >= 0)
	if ( pthread_join(curve_test[i],NULL) ) {
	    printf("bad pthread_join[%d]\n",i);
	    j=-1;
	}
    if (j) goto test_multi_curves_exit;

    for (i=0; i < S_TESTS; i++)
	if ( pdata[i].ret!=1 ) {
	    printf("error with TaggedSpiroCPsToBezier0() using data=%d.\n",i);
	    goto test_multi_curves_exit;
	}
#else
    /* No pthreads.h, test all curves sequentially, one at a time */
    for (i=0; i < S_TESTS; i++) {
	if ( TaggedSpiroCPsToBezier0(spiro[i],(bezctx*)(bc[i]))!=1 ) {
	    printf("error with TaggedSpiroCPsToBezier0() using data=%d.\n",i);
	    goto test_multi_curves_exit;
	}
    }
#endif

    /* Check ending x,y points versus input spiro knot locations. */
    for (i=0; i < S_TESTS; i++) {
	spiro_cp *temp;
	double x, y;
	char ty;
	temp = spiro[i];
	pk = nextknot[i];
	k=0;
	for (j=0; j < scl[i] && temp[j].ty!='z'; j++) {
	    ty = bc[i]->my_curve[k].ty;
	    x  = bc[i]->my_curve[k].x1;
	    y  = bc[i]->my_curve[k].y1;
	    if ( ty=='q' ) {
		x = bc[i]->my_curve[k].x2;
		y = bc[i]->my_curve[k].y2;
	    }
	    if ( ty=='c' ) {
		x = bc[i]->my_curve[k].x3;
		y = bc[i]->my_curve[k].y3;
	    }
#ifdef VERBOSE
	    printf("len=%d s[%d].ty=%c x=%g y=%g, len=%d pk=%d mc[%d] x=%g y=%g\n", \
		   scl[i],j,temp[j].ty,temp[j].x,temp[j].y, bc[i]->len,pk[j],k,x,y);
#endif
	    if ( (fabs(temp[j].x - x) > 1e-8) || (fabs(temp[j].y - y) > 1e-8) ) {
		printf("error with test_multi_curves() using data %d\n",i);
		goto test_multi_curves_exit;
	    }
	    k += pk[j]+1;
	}
    }

#if HAVE_PTHREADS
    printf("Multi-thread testing of libspiro passed.\n");
#else
    printf("Sequential tests of libspiro passed.\n");
#endif
    ret = 0;

test_multi_curves_exit:
    if ( nextknot!=NULL ) for (i=0; i < S_TESTS; i++) free(nextknot[i]);
    if ( spiro!=NULL ) for (i=0; i < S_TESTS; i++) free(spiro[i]);
    free(nextknot); free(spiro); free(scl);
    if ( bc!=NULL ) for (i=0; i < S_TESTS; i++) {
	free(bc[i]->my_curve); free(bc[i]);
    }
    free(bc);
    return ret;
}
Exemple #3
0
int test_multi_curves(void) {
    spiro_cp **spiro = NULL;
    spiro_cp *temp;
    int *pk, **nextknot = NULL;
    int *scl = NULL;
    test_bezctx **bc;
    int i, j, k, l, ret;
    double x, y;
    char ty;

    /* our simple curve test-check breaks-down if we go more than */
    /* 10x larger curves due to rounding errors on double values, */
    /* so, we either need a more complex curve test-check at end, */
    /* or we can cleverly do stepping-up 0.01 one thousand times. */
#define S_TESTS 3000

#ifdef HAVE_PTHREADS
    pthread_attr_t tattr;
    pthread_t curve_test[S_TESTS];
    pthread_pcurve pdata[S_TESTS];

    printf("---\nMulti-thread testing of libspiro.\n");
    /* pthread default limit is currently about 380 without mods. */
#else
    printf("---\nSequential tests of libspiro.\n");
#endif

    ret = -1;	/* return error if out of memory */


    /* Expect lots of results, therefore create available memory. */
    /* This way, we won't be wasting time doing malloc because we */
    /* really want to shoot a whole bunch of pthreads all at once.*/
    if ( (bc=(test_bezctx**)calloc(S_TESTS,sizeof(test_bezctx*)))==NULL )
	goto test_multi_curves_exit;
    for (i=0; i < S_TESTS; i++) {
	if ( (bc[i]=(test_bezctx*)malloc(sizeof(test_bezctx)))==NULL )
	    goto test_multi_curves_exit;
	bc[i]->base.moveto = test_s_moveto;
	bc[i]->base.lineto = test_s_lineto;
	bc[i]->base.quadto = test_s_quadto;
	bc[i]->base.curveto = test_s_curveto;
	bc[i]->base.mark_knot = test_s_mark_knot;
	if ( (bc[i]->my_curve=(my_curve_data*)calloc(S_RESULTS,sizeof(my_curve_data)))==NULL )
	    goto test_multi_curves_exit;
	bc[i]->len = 0;		/* no curve yet, len=0 */
	bc[i]->is_open = 0;
	bc[i]->c_id = i;	/* identify each curve */
    }

    if ( (scl=(int*)malloc(S_TESTS*sizeof(int)))==NULL || \
	 (spiro=(spiro_cp**)calloc(S_TESTS,sizeof(spiro_cp*)))==NULL || \
	 (nextknot=(int**)calloc(S_TESTS,sizeof(int*)))==NULL )
	goto test_multi_curves_exit;
    for (i=0; i < S_TESTS; ) {
	/* NOTE: S_TESTS has to be multiple of 3 here. */
	/* ...because we test using path[0/1/2]tables, */
	/* ...and path[3] is used to test NOT success. */
	if ( (spiro[i]=malloc(cl[0]*sizeof(spiro_cp)))==NULL || \
	      (nextknot[i]=calloc(cl[0]+1,sizeof(int)))==NULL )
	    goto test_multi_curves_exit;
	load_test_curve(spiro[i], nextknot[i], 0);
	scl[i++]=cl[0];
	if ( (spiro[i]=malloc(cl[1]*sizeof(spiro_cp)))==NULL || \
	      (nextknot[i]=calloc(cl[1],sizeof(int)))==NULL )
	    goto test_multi_curves_exit;
	load_test_curve(spiro[i], nextknot[i], 1);
	scl[i++]=cl[1];
	if ( (spiro[i]=malloc(cl[2]*sizeof(spiro_cp)))==NULL || \
	      (nextknot[i]=calloc(cl[2],sizeof(int)))==NULL )
	    goto test_multi_curves_exit;
	load_test_curve(spiro[i], nextknot[i], 2);
	scl[i++]=cl[2];
    }

    /* Change to different sizes to make sure no duplicates */
    /* ...to verify we do not overwrite different user data */
    /* while running multiple threads all at the same time. */
    for (i=0; i < S_TESTS; i++) {
	temp = spiro[i];
	for (j=0; j < scl[i]; j++) {
	    temp[j].x = temp[j].x * ((i+1.0)/100);
	    temp[j].y = temp[j].y * ((i+1.0)/100);
	}
    }

    --ret;

#ifdef HAVE_PTHREADS
    /* Data and memory prepared before Pthreads.  Ready? Set? GO! */
    /* Test all curves, all at same time, wait for all to finish. */
    /* This test could fail if we had globally set variables that */
    /* could affect other functions, eg: static n=4 was moved out */
    /* into passed variable so that one user won't affect others. */
    /* GEGL is a good example of multiple users all at same time. */
    for (i=0; i < S_TESTS; i++) {
	pdata[i].spiro = spiro[i];
	pdata[i].bc = (bezctx*)(bc[i]);
	pdata[i].ret = i;
    }

    j=0;
    for (k=0; k < S_TESTS;) {
	/* Initialize and set thread joinable attribute */
	pthread_attr_init(&tattr);
	pthread_attr_setdetachstate(&tattr,PTHREAD_CREATE_JOINABLE);

	/* Some processors can't do too many pthreads at once so then */
	/* we need to run threads in batches until completing S_TESTS */
	for (i=k; i < S_TESTS-1; i++) {
	    /* all values passed are joined at "->" (should be okay). */
	    if ( pthread_create(&curve_test[i],&tattr,test_a_curve,(void *)&pdata[i]) ) {
		if ( i-k < 20 ) {
		    printf("bad pthread_create[%d]\n",i); /* not many */
		    j=-1;
		}
		break;
	    }
	}
	pthread_attr_destroy(&tattr);	/* Free thread attribute */
	if ( j!=-1 ) {
	    /* Test another curve while waiting for threads to finish */
	    pdata[i].ret = TaggedSpiroCPsToBezier0(pdata[i].spiro,pdata[i].bc);
	    printf("running simultaneous threads[%d..%d]\n",k,i);
	}
	l=i;
	while (--i >= k)
	    if ( pthread_join(curve_test[i],NULL) ) {
		printf("bad pthread_join[%d]\n",i);
		j=-1;
	    }
	k=++l;
	if (j) goto test_multi_curves_exit;
    }

    for (i=0; i < S_TESTS; i++)
	if ( pdata[i].ret!=1 ) {
	    printf("error with TaggedSpiroCPsToBezier0() using data=%d.\n",i);
	    ret=ret-i;
	    goto test_multi_curves_exit;
	}
    /* All threads returned okay, Now, go check all data is good. */
#else
    /* No pthreads.h, test all curves sequentially, one at a time */
    /* Just do a math check and leave the pthread check for other */
    /* operating systems to verify libspiro has no static values. */
    for (i=0; i < S_TESTS; i++) {
	if ( TaggedSpiroCPsToBezier0(spiro[i],(bezctx*)(bc[i]))!=1 ) {
	    printf("error with TaggedSpiroCPsToBezier0() using data=%d.\n",i);
	    ret=ret-i;
	    goto test_multi_curves_exit;
	}
    }
#endif
    ret=ret-S_TESTS;

    /* Check ending x,y points versus input spiro knot locations. */
    for (i=0; i < S_TESTS; i++) {
	temp = spiro[i];
	pk = nextknot[i];
	k=0;
	for (j=0; j < scl[i] && temp[j].ty!='z'; j++) {
	    ty = bc[i]->my_curve[k].ty;
	    x  = bc[i]->my_curve[k].x1;
	    y  = bc[i]->my_curve[k].y1;
	    if ( ty=='q' ) {
		x = bc[i]->my_curve[k].x2;
		y = bc[i]->my_curve[k].y2;
	    }
	    if ( ty=='c' ) {
		x = bc[i]->my_curve[k].x3;
		y = bc[i]->my_curve[k].y3;
	    }
#ifdef VERBOSE
	    printf("len=%d s[%d].ty=%c x=%g y=%g, len=%d pk=%d mc[%d] x=%g y=%g\n", \
		   scl[i],j,temp[j].ty,temp[j].x,temp[j].y, bc[i]->len,pk[j],k,x,y);
#endif
	    if ( (fabs(temp[j].x - x) > 1e-8) || (fabs(temp[j].y - y) > 1e-8) ) {
		/* close-enough for testing 10x range of doubles. */
		printf("error with test_multi_curves() using data %d\n",i);
		ret=ret-i;
		goto test_multi_curves_exit;
	    }
	    k += pk[j]+1;
	}
    }

#ifdef HAVE_PTHREADS
    printf("Multi-thread testing of libspiro passed.\n");
#else
    printf("Sequential tests of libspiro passed.\n");
#endif
    ret = 0;

test_multi_curves_exit:
    if ( nextknot!=NULL ) for (i=0; i < S_TESTS; i++) free(nextknot[i]);
    if ( spiro!=NULL ) for (i=0; i < S_TESTS; i++) free(spiro[i]);
    free(nextknot); free(spiro); free(scl);
    if ( bc!=NULL ) for (i=0; i < S_TESTS; i++) {
	free(bc[i]->my_curve); free(bc[i]);
    }
    free(bc);
    return ret;
}