Beispiel #1
0
static void    
d2alaw_array      (double *ptr, unsigned int index, unsigned char *buffer, unsigned int count, double normfact)
{	unsigned int	k ;

	for (k = 0 ; k < count ; k++)
	{	if (ptr [index] >= 0) 
			buffer [k] = alaw_encode [(DOUBLE_TO_INT (normfact * ptr [index])) / 16] ;
		else
			buffer [k] = 0x7F & alaw_encode [(DOUBLE_TO_INT (normfact * ptr [index])) / -16] ;
		index ++ ;
		} ;
} /* d2alaw_array */
Beispiel #2
0
static void image_ttf_faceinstance_set_height(INT32 args)
{
   struct image_ttf_face_struct *face_s;
   struct image_ttf_faceinstance_struct *face_i=THISi;
   int h=0;

   if (!args)
      Pike_error("Image.TTF.FaceInstance->set_height(): missing arguments\n");

   if (sp[-args].type==T_INT)
      h = sp[-args].u.integer*64;
   else if (sp[-args].type==T_FLOAT)
      h = DOUBLE_TO_INT(sp[-args].u.float_number*64);
   else
      Pike_error("Image.TTF.FaceInstance->set_height(): illegal argument 1\n");
   if (h<1) h=1;

   if (!(face_s=(struct image_ttf_face_struct*)
	 get_storage(THISi->faceobj,image_ttf_face_program)))
      Pike_error("Image.TTF.FaceInstance->write(): lost Face\n");

   ttf_instance_setc(face_s,face_i,h,"Image.TTF.FaceInstance->set_height()");

   pop_n_elems(args);
   ref_push_object(THISOBJ);
}
Beispiel #3
0
static void ttf_instance_setc(struct image_ttf_face_struct *face_s,
			      struct image_ttf_faceinstance_struct *face_i,
			      int towhat,
			      char *where)
{
   TT_Face_Properties prop;
   TT_Instance_Metrics metr;
   int res;
   int resol;

   if ((res=TT_Get_Face_Properties(face_s->face,&prop)))
      my_tt_error(where,"TT_Get_Face_Properties",res);

   resol=58; /* should be 72, but glyphs fit using this value */
      /*
         (int)((72*(prop.horizontal->Ascender+
		    prop.horizontal->Descender)/
		(float)prop.horizontal->Ascender));
*/

   if ((res=TT_Set_Instance_Resolutions(face_i->instance,
					(TT_UShort)resol, (TT_UShort)resol)))
      my_tt_error("Image.TTF.FaceInstance()",
		  "TT_Set_Instance_Resolutions: ",res);

   if ((res=TT_Get_Instance_Metrics(face_i->instance,&metr)))
      my_tt_error(where,"TT_Get_Instance_Metrics",res);

   if ((res=TT_Set_Instance_CharSize(face_i->instance,towhat)))
      my_tt_error(where,"TT_Set_Instance_CharSize: ",res);

   face_i->baseline=
      DOUBLE_TO_INT(((double)(towhat/64.0+towhat/640.0)*
		     prop.horizontal->Ascender)/
		    (prop.horizontal->Ascender - prop.horizontal->Descender));

   face_i->height= (towhat/64 + towhat/640);

   face_i->trans = ~63 &
      (32 +
       DOUBLE_TO_INT(64*((towhat/64.0+towhat/640.0)*
			 prop.horizontal->Ascender)/
		     (prop.horizontal->Ascender-prop.horizontal->Descender)));
}
Beispiel #4
0
static INLINE void polyfill_slant_add(double *buf,
                                      double xmin, double xmax,
                                      double lot,
                                      double y1,
                                      double dy)
{
    int i;
    int xmin_i = DOUBLE_TO_INT(floor(xmin));
    int xmax_i = DOUBLE_TO_INT(floor(xmax));

    if (xmax_i<0) return;
    if (xmin_i == xmax_i) {
        double dx = xmax - xmin;
        buf[xmin_i] += lot*(y1+dy*dx/2)*dx;
    }
    else if (xmin_i>=0)
    {
        double dx = DO_NOT_WARN(1.0 - (xmin-((double)xmin_i)));
        buf[xmin_i] += lot*(y1+dy*dx/2.0)*dx;
        y1 += dy*dx;
        for (i=xmin_i+1; i<xmax_i; i++) {
            buf[i] += lot*(y1+dy/2.0);
            y1 += dy;
        }
        dx = (xmax-((double)xmax_i));
        buf[xmax_i] += lot*(y1+dy*dx/2.0)*dx;
    }
    else
    {
        double dx;
        y1 -= dy*xmin;	/* Adjust y1 for the first -xmin steps. */
        for (i=0; i<xmax_i; i++) {
            buf[i] += lot*(y1+dy/2.0);
            y1 += dy;
        }
        dx = (xmax-((double)xmax_i));
        buf[xmax_i] += lot*(y1+dy*dx/2)*dx;
    }
}
Beispiel #5
0
static INLINE void polyfill_row_add(double *buf,
                                    double xmin, double xmax,
                                    double add)
{
    int i;
    int xmin_i = DOUBLE_TO_INT(floor(xmin));
    int xmax_i = DOUBLE_TO_INT(floor(xmax));
    if (xmax_i<0) return;
    if (xmin_i == xmax_i)
        buf[xmin_i] += (xmax-xmin)*add;
    else if (xmin_i>=0)
    {
        buf[xmin_i] += (1-(xmin-((double)xmin_i)))*add;
        for (i=xmin_i+1; i<xmax_i; i++) buf[i]+=add;
        buf[xmax_i] += add*(xmax-((double)xmax_i));
    }
    else
    {
        for (i=0; i<xmax_i; i++) buf[i]+=add;
        buf[xmax_i] += add*(xmax-((float)xmax_i));
    }
}
Beispiel #6
0
void image_dct(INT32 args)
{
   rgbd_group *area,*val;
   struct object *o;
   struct image *img;
   INT32 x,y,u,v;
   double xsz2,ysz2,enh,xp,yp,dx,dy;
   double *costbl;
   rgb_group *pix;

   if (!THIS->img)
     Pike_error("Called Image.Image object is not initialized\n");

#ifdef DCT_DEBUG
   fprintf(stderr,"%lu bytes, %lu bytes\n",
	   DO_NOT_WARN((unsigned long)(sizeof(rgbd_group)*THIS->xsize*THIS->ysize)),
	   DO_NOT_WARN((unsigned long)(sizeof(rgb_group)*THIS->xsize*THIS->ysize+1)));
#endif

   area=xalloc(sizeof(rgbd_group)*THIS->xsize*THIS->ysize+1);

   if (!(costbl=malloc(sizeof(double)*THIS->xsize+1)))
   {
      free(area);
      resource_error(NULL,0,0,"memory",0,"Out of memory.\n");
   }

   o=clone_object(image_program,0);
   img=(struct image*)(o->storage);
   *img=*THIS;
   
   if (args>=2 
       && sp[-args].type==T_INT 
       && sp[1-args].type==T_INT)
   {
      img->xsize=MAXIMUM(1,sp[-args].u.integer);
      img->ysize=MAXIMUM(1,sp[1-args].u.integer);
   }
   else {
     free(area);
     free(costbl);
     free_object(o);
     bad_arg_error("image->dct",sp-args,args,0,"",sp-args,
		   "Bad arguments to image->dct()\n");
   }

   if (!(img->img=(rgb_group*)malloc(sizeof(rgb_group)*
				     img->xsize*img->ysize+1)))
   {
      free(area);
      free(costbl);
      free_object(o);
      resource_error(NULL,0,0,"memory",0,"Out of memory.\n");
   }

   xsz2=THIS->xsize*2.0;
   ysz2=THIS->ysize*2.0;

   enh=(8.0/THIS->xsize)*(8.0/THIS->ysize);

   for (u=0; u<THIS->xsize; u++)
   {
      double d,z0;
      rgbd_group sum;

      for (v=0; v<THIS->ysize; v++)
      {
	 d=(u?1:c0)*(v?1:c0)/4.0;
	 sum.r=sum.g=sum.b=0;
	 pix=THIS->img;
	 
	 for (x=0; x<THIS->xsize; x++)
	    costbl[x]=cos( (2*x+1)*u*pi/xsz2 );

	 for (y=0; y<THIS->ysize; y++)
	 {
	    z0=cos( (2*y+1)*v*pi/ysz2 );
	    for (x=0; x<THIS->xsize; x++)
	    {
	       double z;
	       z =  costbl[x] * z0;
	       sum.r += (float)(pix->r*z);
	       sum.g += (float)(pix->g*z);
	       sum.b += (float)(pix->b*z);
	       pix++;
	    }
	 }
	 sum.r *= (float)d;
	 sum.g *= (float)d;
	 sum.b *= (float)d;
	 area[u+v*THIS->xsize]=sum;
      }
#ifdef DCT_DEBUG
      fprintf(stderr,"."); fflush(stderr);
#endif
   }
#ifdef DCT_DEBUG
   fprintf(stderr,"\n");
#endif

   dx=((double)(THIS->xsize-1))/(img->xsize);
   dy=((double)(THIS->ysize-1))/(img->ysize);

   pix=img->img;
   for (y=0,yp=0; y<img->ysize; y++,yp+=dy)
   {
      double z0;
      rgbd_group sum;

      for (x=0,xp=0; x<img->xsize; x++,xp+=dx)
      {
	 sum.r=sum.g=sum.b=0;
	 val=area;

	 for (u=0; u<THIS->xsize; u++)
	    costbl[u]=cos( (2*xp+1)*u*pi/xsz2 );

	 for (v=0; v<THIS->ysize; v++)
	 {
	    z0=cos( (2*yp+1)*v*pi/ysz2 )*(v?1:c0)/4.0;
	    for (u=0; u<THIS->xsize; u++)
	    {
	       double z;
	       z = (u?1:c0) * costbl[u] * z0; 
	       sum.r += DO_NOT_WARN((float)(val->r*z));
	       sum.g += DO_NOT_WARN((float)(val->g*z));
	       sum.b += DO_NOT_WARN((float)(val->b*z));
	       val++;
	    }
	 }
	 sum.r *= (float)enh;
	 sum.g *= (float)enh;
	 sum.b *= (float)enh;
	 pix->r=testrange((DOUBLE_TO_INT(sum.r+0.5)));
	 pix->g=testrange((DOUBLE_TO_INT(sum.g+0.5)));
	 pix->b=testrange((DOUBLE_TO_INT(sum.b+0.5)));
	 pix++;
      }
#ifdef DCT_DEBUG
      fprintf(stderr,"."); fflush(stderr);
#endif
   }

   free(area);
   free(costbl);

   pop_n_elems(args);
   push_object(o);
}
Beispiel #7
0
static void image_ttf_faceinstance_write(INT32 args)
{
   int **sstr;
   int *slen;
   int i,res=0,base=0,a;
   struct image_ttf_face_struct *face_s;
   struct image_ttf_faceinstance_struct *face_i=THISi;
   TT_CharMap charMap;
   TT_Kerning kerning;
   int has_kerning = 0;
   char *errs=NULL;
   int scalefactor=0;
   int xmin=1000,xmax=-1000,pos=0,ypos;
   int width,height,mod;

   unsigned char* pixmap;
   int maxcharwidth = 0;

   if (!(face_s=(struct image_ttf_face_struct*)
	 get_storage(THISi->faceobj,image_ttf_face_program)))
      Pike_error("Image.TTF.FaceInstance->write(): lost Face\n");

   if(!TT_Get_Kerning_Directory( face_s->face, &kerning ))
   {
     TT_Instance_Metrics metrics;
/*      fprintf(stderr, "has kerning!\n"); */
     has_kerning = 1;
     if(TT_Get_Instance_Metrics( face_i->instance, &metrics ))
       Pike_error("Nope. No way.\n");
     scalefactor = metrics.x_scale;
/*      fprintf(stderr, "offset=%d\n", (int)metrics.x_scale); */
   }

   if (args && sp[-1].type==T_INT)
   {
      base=sp[-1].u.integer;
      args--;
      pop_stack();
   }

   if (!args)
   {
      push_empty_string();
      args=1;
   }

   ttf_get_nice_charmap(face_s->face,&charMap,
			"Image.TTF.FaceInstance->write()");

   sstr=alloca(args*sizeof(int*));
   slen=alloca(args*sizeof(int));

   /* first pass: figure out total bounding box */

   for (a=0; a<args; a++)
   {
     char *errs=NULL;
     TT_Glyph_Metrics metrics;

      if (sp[a-args].type!=T_STRING)
	 Pike_error("Image.TTF.FaceInstance->write(): illegal argument %d\n",a+1);

      switch(sp[a-args].u.string->size_shift)
      {
       case 0:
	 ttf_translate_8bit(charMap,(unsigned char*)sp[a-args].u.string->str,
			    sstr+a,
			    DO_NOT_WARN(slen[a]=sp[a-args].u.string->len),
			    base);
	 break;
       case 1:
	 ttf_translate_16bit(charMap,(unsigned short*)sp[a-args].u.string->str,
			     sstr+a,
			     DO_NOT_WARN(slen[a]=sp[a-args].u.string->len),
			     base);
	 break;
       case 2:
	 Pike_error("Too wide string for truetype\n");
	 break;
      }

      pos=0;
      for (i=0; i<slen[a]; i++)
      {
	 TT_Glyph glyph;
	 int ind;

	 ind=sstr[a][i];
/* 	 fprintf(stderr,"glyph: %d\n",ind); */

	 if ((res=TT_New_Glyph(face_s->face,&glyph)))
	    { errs="TT_New_Glyph: "; break; }

	 if ((res=TT_Load_Glyph(face_i->instance, glyph, (TT_UShort)ind,
				(TT_UShort)face_i->load_flags)))
	    { errs="TT_Load_Glyph: "; break; }

	 if ((res=TT_Get_Glyph_Metrics(glyph,&metrics)))
	    { errs="TT_Get_Glyph_Metrics: "; break; }

	 if (pos+metrics.bbox.xMin<xmin)
	   xmin=pos+metrics.bbox.xMin;
	 if (pos+metrics.bbox.xMax>xmax)
	   xmax=pos+metrics.bbox.xMax;

	 if((metrics.bbox.xMax-(metrics.bbox.xMin<0?metrics.bbox.xMin:0))
	    >maxcharwidth)
	   maxcharwidth =
	     (metrics.bbox.xMax-(metrics.bbox.xMin<0?metrics.bbox.xMin:0));

	 pos+=metrics.advance;
	 if(has_kerning && i<slen[a]-1)
	 {
	   int kern = find_kerning( kerning, ind, sstr[a][i+1] );
	   pos += DOUBLE_TO_INT(kern * (scalefactor/65535.0));
	 }
	 if ((res=TT_Done_Glyph(glyph)))
	    { errs="TT_Done_Glyph: "; break; }
      }
      pos -= metrics.advance;
      pos += metrics.bbox.xMax-metrics.bbox.xMin;
      if (pos>xmax)
	xmax=pos;
      if (errs)
      {
	 for (i=0; i<a; i++) free(sstr[i]);
	 my_tt_error("Image.TTF.FaceInstance->write()",errs,res);
      }
   }

   pop_n_elems(args);

/*    fprintf(stderr,"xmin=%f xmax=%f\n",xmin/64.0,xmax/64.0); */

   xmin&=~63;
   width=((xmax-xmin+63)>>6)+4;
   height=face_i->height*args;
   mod=(4-(maxcharwidth&3))&3;
   if (width<1) width=1;

   if ((pixmap=malloc((maxcharwidth+mod)*face_i->height)))
   {
      /* second pass: write the stuff */

      TT_Raster_Map rastermap;
      struct object *o;
      struct image *img;
      rgb_group *d;


      rastermap.rows=face_i->height;
      rastermap.cols=rastermap.width=maxcharwidth+mod;
      rastermap.flow=TT_Flow_Down;
      rastermap.bitmap=pixmap;
      rastermap.size=rastermap.cols*rastermap.rows;

      ypos=0;

/*       fprintf(stderr,"rastermap.rows=%d cols=%d width=%d\n", */
/* 	      rastermap.rows,rastermap.cols,rastermap.width); */


      push_int(width);
      push_int(height);
      o=clone_object(image_program,2);
      img=(struct image*)get_storage(o,image_program);
      d=img->img;

      for (a=0; a<args; a++)
      {
         pos=-xmin;
	 for (i=0; i<slen[a]; i++)
	 {
    	    int sw, xp;
	    TT_Glyph glyph;
	    TT_Glyph_Metrics metrics;
	    int ind, x, y;

	    ind=sstr[a][i];
/* 	    fprintf(stderr,"glyph: %d\n",ind); */


	    if ((res=TT_New_Glyph(face_s->face,&glyph)))
	       { errs="TT_New_Glyph: "; break; }

	    if ((res=TT_Load_Glyph(face_i->instance, glyph, (TT_UShort)ind,
				   (TT_UShort)face_i->load_flags)))
	       { errs="TT_Load_Glyph: "; break; }

	    if ((res=TT_Get_Glyph_Metrics(glyph,&metrics)))
	       { errs="TT_Get_Glyph_Metrics: "; break; }

	    MEMSET(pixmap,0,rastermap.size);

	    if ((res=TT_Get_Glyph_Pixmap(glyph,
					 &rastermap,
					 -metrics.bbox.xMin
                                         /*+pos%64*/,
					 face_i->height*64-
					 face_i->trans)))
	       { errs="TT_Get_Glyph_Pixmap: "; break; }


	    sw = metrics.bbox.xMax-(metrics.bbox.xMin<0?metrics.bbox.xMin:0);
	    /* Copy source pixmap to destination image object. */
	    for(y=0; y<face_i->height; y++)
	    {
	      unsigned int s;
	      unsigned char * source = pixmap+rastermap.width*y;
	      rgb_group *dt=d+(ypos+y)*width+(xp=(metrics.bbox.xMin+pos)/64);

	      for(x=0; x<sw && xp<width; x++,xp++,source++,dt++)
		if(xp<0 || !(s = *source))
		  continue;
		else if((s=dt->r+s) < 256)
		  dt->r=dt->g=dt->b=s;
		else
		  dt->r=dt->g=dt->b=255;
	    }

	    pos+=metrics.advance;
/* 	    if(metrics.bbox.xMin < 0) */
/* 	      pos += metrics.bbox.xMin; */
	    if(has_kerning && i<slen[a]-1)
	    {
	      int kern = find_kerning( kerning, sstr[a][i], sstr[a][i+1] );
	      pos += DOUBLE_TO_INT(kern * (scalefactor/65535.0));
/* 	      fprintf(stderr, "Adjusted is %d\n", */
/* 		      (int)(kern * (scalefactor/65535.0))); */
	    }

	    if ((res=TT_Done_Glyph(glyph)))
	       { errs="TT_Done_Glyph: "; break; }
	 }
	 if (errs)
	 {
	    for (a=0; a<args; a++) free(sstr[a]);
	    free(pixmap);
	    free_object(o);
	    my_tt_error("Image.TTF.FaceInstance->write()",errs,res);
	 }
	 ypos+=face_i->height;
      }
      free(pixmap);
      push_object(o);
   }
   else
   {
      Pike_error("Image.TTF.FaceInstance->write(): out of memory\n");
   }

   for (a=0; a<args; a++)
      free(sstr[a]);
}
Beispiel #8
0
static void polyfill_some(struct image *img,
                          struct vertex *v,
                          double *buf)
{
    struct line_list *ll=NULL;
    int y=0;
    double ixmax = (double)img->xsize;
    struct vertex *to_add=v,*to_loose=v;
    /* beat row for row */

    if (y+1.0+1e-10<v->y)
        y = DOUBLE_TO_INT(v->y);

    while (y<img->ysize && (to_loose||to_add) )
    {
        double yp = y;
        struct line_list *c;
        double xmin, xmax;
        rgb_group *d;
        int tog=0;
        int i;

#ifdef POLYDEBUG
        fprintf(stderr,"\nline %d..%d\n",y,y+1);
#endif

        /* update values for current lines */
        c=ll;
        while (c)
        {
            c->xmin=line_xmin(c,yp,&c->yxmin);
            c->xmax=line_xmax(c,yp,&c->yxmax);
            c=c->next;
        }

        /* add any new vertices */
        while (to_add && to_add->y<yp+1.0)
        {
            struct vertex *vx=to_add;
            to_add=to_add->next;
            add_vertices(&ll,vx->below,yp);
        }

#ifdef POLYDEBUG
        c=ll;
        while (c)
        {
            fprintf(stderr,"  line %g,%g - %g,%g [%g,%g - %g,%g]\n",
                    c->xmin,c->yxmin,c->xmax,c->yxmax,
                    c->above->x,c->above->y,c->below->x,c->below->y);
            c=c->next;
        }

#endif

        if (!ll)
        {
            y++;
            continue;
        }

        /* begin with zeros */
        for (i=0; i<img->xsize; i++) buf[i]=0.0;

        /* sanity check */
        c=ll;
        while (c && c->next)
        {
            if (c->xmin > c->next->xmax ||
                    c->xmax > c->next->xmin ||
                    ( c->xmin!=c->xmax &&
                      c->next->xmin!=c->next->xmax &&
                      c->next->xmax>=c->xmin &&
                      c->next->xmin<=c->xmin &&
                      VY(c,c->xmin)>VY(c->next,c->xmin)))
            {
                struct line_list *l1;
                /* resort */
#ifdef POLYDEBUG
                fprintf(stderr,"  !!! resort !!!\n");
#endif
                l1=NULL;
                add_vertices(&l1,ll,yp);

                while ((c=ll))
                {
                    ll=c->next;
                    free(c);
                }

                ll=l1;

                break;
            }
            c=c->next;
        }

        /* find first horisintal event */
        xmin=ll->xmin;
        c=ll;
        while (c)
        {
            if (c->xmin<xmin) xmin=c->xmin;
            c=c->next;
        }

        /* loop through all horisontal events */
        while (xmin<ixmax)
        {
            xmax=1e10;
            c=ll;
            while (c)
            {
                /* each line has two events: beginning and end */
                if (c->xmin<xmax && c->xmin>xmin) xmax=c->xmin;
                if (c->xmax<xmax && c->xmax>xmin) xmax=c->xmax;
                c=c->next;
            }
            if (xmax==1e10) break; /* no more events */

            if (xmax>ixmax) xmax=ixmax;
            tog=polyfill_event(xmin,xmax,yp,buf,&ll,tog);

            /* shift to get next event */
            xmin = xmax;
            xmax = DO_NOT_WARN(xmin - 1.0);
        }


        /* remove any old vertices */
        while (to_loose!=to_add && to_loose->y<yp+1.0-1e-10)
        {
            struct vertex *vx=to_loose;
            to_loose=to_loose->next;
            sub_vertices(&ll,vx,yp);
        }

        /* write this row */
        d=img->img+img->xsize*y;
        if(THIS->alpha)
        {
            for (i=0; i<img->xsize; i++)
            {
#ifdef POLYDEBUG
                fprintf(stderr,"%3.2f ",buf[i]);
#endif

#define apply_alpha(x,y,alpha) \
   ((unsigned char)((y*(255L-(alpha))+x*(alpha))/255L))

                d->r = apply_alpha( d->r,
                                    DOUBLE_TO_COLORTYPE((d->r*(1.0-buf[i]))+
                                                        (img->rgb.r*buf[i])),
                                    THIS->alpha );
                d->g = apply_alpha( d->g,
                                    DOUBLE_TO_COLORTYPE((d->g*(1.0-buf[i]))+
                                                        (img->rgb.g*buf[i])),
                                    THIS->alpha );
                d->b = apply_alpha( d->b,
                                    DOUBLE_TO_COLORTYPE((d->b*(1.0-buf[i]))+
                                                        (img->rgb.b*buf[i])),
                                    THIS->alpha );
                d++;
            }
#ifdef POLYDEBUG
            fprintf(stderr,"\n");
#endif
        }
        else {
            for (i=0; i<img->xsize; i++)
            {
#ifdef POLYDEBUG
                fprintf(stderr,"%3.2f ",buf[i]);
#endif
                d->r = DOUBLE_TO_COLORTYPE((d->r*(1.0-buf[i]))+(img->rgb.r*buf[i]));
                d->g = DOUBLE_TO_COLORTYPE((d->g*(1.0-buf[i]))+(img->rgb.g*buf[i]));
                d->b = DOUBLE_TO_COLORTYPE((d->b*(1.0-buf[i]))+(img->rgb.b*buf[i]));
                d++;
            }
#ifdef POLYDEBUG
            fprintf(stderr,"\n");
#endif
        }

        y++;
    }
    while (ll)
    {
        struct line_list *c;
        ll=(c=ll)->next;
        free(c);
    }
}