Пример #1
0
static void
get_bounding_box (GtkWidget    *widget,
                  GdkRectangle *bounds)
{
  GdkWindow *window;
  gint x, y;
  gint w, h;
  gint x1, y1;
  gint x2, y2;
  gint x3, y3;
  gint x4, y4;

  window = gtk_widget_get_parent_window (widget);

  x = widget->allocation.x;
  y = widget->allocation.y;
  w = widget->allocation.width;
  h = widget->allocation.height;

  gdk_window_get_root_coords (window, x, y, &x1, &y1);
  gdk_window_get_root_coords (window, x + w, y, &x2, &y2);
  gdk_window_get_root_coords (window, x, y + h, &x3, &y3);
  gdk_window_get_root_coords (window, x + w, y + h, &x4, &y4);

#define MIN4(a,b,c,d) MIN(MIN(a,b),MIN(c,d))
#define MAX4(a,b,c,d) MAX(MAX(a,b),MAX(c,d))

  bounds->x = floor (MIN4 (x1, x2, x3, x4));
  bounds->y = floor (MIN4 (y1, y2, y3, y4));
  bounds->width = ceil (MAX4 (x1, x2, x3, x4)) - bounds->x;
  bounds->height = ceil (MAX4 (y1, y2, y3, y4)) - bounds->y;
}
Пример #2
0
static void
gimp_overlay_child_transform_bounds (GimpOverlayChild *child,
                                     GdkRectangle     *bounds_child,
                                     GdkRectangle     *bounds_box)
{
  gdouble x1, x2, x3, x4;
  gdouble y1, y2, y3, y4;

  x1 = bounds_child->x;
  y1 = bounds_child->y;

  x2 = bounds_child->x + bounds_child->width;
  y2 = bounds_child->y;

  x3 = bounds_child->x;
  y3 = bounds_child->y + bounds_child->height;

  x4 = bounds_child->x + bounds_child->width;
  y4 = bounds_child->y + bounds_child->height;

  cairo_matrix_transform_point (&child->matrix, &x1, &y1);
  cairo_matrix_transform_point (&child->matrix, &x2, &y2);
  cairo_matrix_transform_point (&child->matrix, &x3, &y3);
  cairo_matrix_transform_point (&child->matrix, &x4, &y4);

  bounds_box->x      = (gint) floor (MIN4 (x1, x2, x3, x4));
  bounds_box->y      = (gint) floor (MIN4 (y1, y2, y3, y4));
  bounds_box->width  = (gint) ceil (MAX4 (x1, x2, x3, x4)) - bounds_box->x;
  bounds_box->height = (gint) ceil (MAX4 (y1, y2, y3, y4)) - bounds_box->y;
}
Пример #3
0
fz_bbox
fz_transform_bbox(fz_matrix m, fz_bbox b)
{
    fz_point s, t, u, v;

    if (fz_is_infinite_bbox(b))
        return b;

    s.x = b.x0;
    s.y = b.y0;
    t.x = b.x0;
    t.y = b.y1;
    u.x = b.x1;
    u.y = b.y1;
    v.x = b.x1;
    v.y = b.y0;
    s = fz_transform_point(m, s);
    t = fz_transform_point(m, t);
    u = fz_transform_point(m, u);
    v = fz_transform_point(m, v);
    b.x0 = MIN4(s.x, t.x, u.x, v.x);
    b.y0 = MIN4(s.y, t.y, u.y, v.y);
    b.x1 = MAX4(s.x, t.x, u.x, v.x);
    b.y1 = MAX4(s.y, t.y, u.y, v.y);
    return b;

}
Пример #4
0
fz_rect
fz_transform_rect(fz_matrix m, fz_rect r)
{
    fz_point s, t, u, v;

    if (fz_is_infinite_rect(r))
        return r;

    s.x = r.x0;
    s.y = r.y0;
    t.x = r.x0;
    t.y = r.y1;
    u.x = r.x1;
    u.y = r.y1;
    v.x = r.x1;
    v.y = r.y0;
    s = fz_transform_point(m, s);
    t = fz_transform_point(m, t);
    u = fz_transform_point(m, u);
    v = fz_transform_point(m, v);
    r.x0 = MIN4(s.x, t.x, u.x, v.x);
    r.y0 = MIN4(s.y, t.y, u.y, v.y);
    r.x1 = MAX4(s.x, t.x, u.x, v.x);
    r.y1 = MAX4(s.y, t.y, u.y, v.y);
    return r;
}
Пример #5
0
static void sp_ctrlquadr_update(SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags)
{
    SPCtrlQuadr *cq = SP_CTRLQUADR(item);

    item->canvas->requestRedraw((int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2);

    if (SP_CANVAS_ITEM_CLASS(sp_ctrlquadr_parent_class)->update) {
        SP_CANVAS_ITEM_CLASS(sp_ctrlquadr_parent_class)->update(item, affine, flags);
    }

    sp_canvas_item_reset_bounds (item);

    cq->affine = affine;

    Geom::Point p1(cq->p1 * affine);
    Geom::Point p2(cq->p2 * affine);
    Geom::Point p3(cq->p3 * affine);
    Geom::Point p4(cq->p4 * affine);
        
    item->x1 = (int)(MIN4(p1[Geom::X], p2[Geom::X], p3[Geom::X], p4[Geom::X]));
    item->y1 = (int)(MIN4(p1[Geom::Y], p2[Geom::Y], p3[Geom::Y], p4[Geom::Y]));
    item->x2 = (int)(MAX4(p1[Geom::X], p2[Geom::X], p3[Geom::X], p4[Geom::X]));
    item->y2 = (int)(MAX4(p1[Geom::Y], p2[Geom::Y], p3[Geom::Y], p4[Geom::Y]));

    item->canvas->requestRedraw((int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2);
}
Пример #6
0
//------------------------------------------------------------------------
//
//------------------------------------------------------------------------
void
seedChkr2::compSeeds(void)
{
   Datareg2 &reg2 = (Datareg2&)data;
   int i, j;
   int xdim, ydim;
   float val[4];
   float min4, max4;
   int nseed;

   if (verbose)
      printf("***** Seed Creation\n");

   xdim = reg2.dim[0];
   ydim = reg2.dim[1];

   // proceed through the slices computing seeds
   nseed=0;

   // process the k'th slab
   for (i=0; i<xdim-1; i+=2)
      for (j=0; j<ydim-1; j+=2) {

         // load the voxel data
         reg2.getCellValues(i, j, val);

         min4 = MIN4(val[0], val[1], val[2], val[3]);
         max4 = MAX4(val[0], val[1], val[2], val[3]);

         seeds.AddSeed(reg2.index2cell(i,j), min4, max4);

         nseed++;
      }

   for (i=1; i<xdim-1; i+=2)
      for (j=1; j<ydim-1; j+=2) {

         // load the voxel data
         reg2.getCellValues(i, j, val);

         min4 = MIN4(val[0], val[1], val[2], val[3]);
         max4 = MAX4(val[0], val[1], val[2], val[3]);

         seeds.AddSeed(reg2.index2cell(i,j), min4, max4);

         nseed++;
      }

   if (verbose)
      printf("computed %d seeds\n", nseed);
}
Пример #7
0
static PyObject *M_Geometry_interpolate_bezier(PyObject *UNUSED(self), PyObject *args)
{
	VectorObject *vec_k1, *vec_h1, *vec_k2, *vec_h2;
	int resolu;
	int dims;
	int i;
	float *coord_array, *fp;
	PyObject *list;

	float k1[4] = {0.0, 0.0, 0.0, 0.0};
	float h1[4] = {0.0, 0.0, 0.0, 0.0};
	float k2[4] = {0.0, 0.0, 0.0, 0.0};
	float h2[4] = {0.0, 0.0, 0.0, 0.0};


	if (!PyArg_ParseTuple(args, "O!O!O!O!i:interpolate_bezier",
	                      &vector_Type, &vec_k1,
	                      &vector_Type, &vec_h1,
	                      &vector_Type, &vec_h2,
	                      &vector_Type, &vec_k2, &resolu))
	{
		return NULL;
	}

	if (resolu <= 1) {
		PyErr_SetString(PyExc_ValueError,
		                "resolution must be 2 or over");
		return NULL;
	}

	if (BaseMath_ReadCallback(vec_k1) == -1 ||
	    BaseMath_ReadCallback(vec_h1) == -1 ||
	    BaseMath_ReadCallback(vec_k2) == -1 ||
	    BaseMath_ReadCallback(vec_h2) == -1)
	{
		return NULL;
	}

	dims = MAX4(vec_k1->size, vec_h1->size, vec_h2->size, vec_k2->size);

	for (i = 0; i < vec_k1->size; i++) k1[i] = vec_k1->vec[i];
	for (i = 0; i < vec_h1->size; i++) h1[i] = vec_h1->vec[i];
	for (i = 0; i < vec_k2->size; i++) k2[i] = vec_k2->vec[i];
	for (i = 0; i < vec_h2->size; i++) h2[i] = vec_h2->vec[i];

	coord_array = MEM_callocN(dims * (resolu) * sizeof(float), "interpolate_bezier");
	for (i = 0; i < dims; i++) {
		BKE_curve_forward_diff_bezier(k1[i], h1[i], h2[i], k2[i], coord_array + i, resolu - 1, sizeof(float) * dims);
	}

	list = PyList_New(resolu);
	fp = coord_array;
	for (i = 0; i < resolu; i++, fp = fp + dims) {
		PyList_SET_ITEM(list, i, Vector_CreatePyObject(fp, dims, Py_NEW, NULL));
	}
	MEM_freeN(coord_array);
	return list;
}
void
gimp_display_shell_rotate_bounds (GimpDisplayShell *shell,
                                  gdouble           x1,
                                  gdouble           y1,
                                  gdouble           x2,
                                  gdouble           y2,
                                  gdouble          *nx1,
                                  gdouble          *ny1,
                                  gdouble          *nx2,
                                  gdouble          *ny2)
{

  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));

  if (shell->rotate_transform)
    {
      gdouble tx1 = x1;
      gdouble ty1 = y1;
      gdouble tx2 = x1;
      gdouble ty2 = y2;
      gdouble tx3 = x2;
      gdouble ty3 = y1;
      gdouble tx4 = x2;
      gdouble ty4 = y2;

      cairo_matrix_transform_point (shell->rotate_transform, &tx1, &ty1);
      cairo_matrix_transform_point (shell->rotate_transform, &tx2, &ty2);
      cairo_matrix_transform_point (shell->rotate_transform, &tx3, &ty3);
      cairo_matrix_transform_point (shell->rotate_transform, &tx4, &ty4);

      *nx1 = MIN4 (tx1, tx2, tx3, tx4);
      *ny1 = MIN4 (ty1, ty2, ty3, ty4);
      *nx2 = MAX4 (tx1, tx2, tx3, tx4);
      *ny2 = MAX4 (ty1, ty2, ty3, ty4);
    }
  else
    {
      *nx1 = x1;
      *ny1 = y1;
      *nx2 = x2;
      *ny2 = y2;
    }
}
Пример #9
0
static void
gth_transform_resize (cairo_matrix_t        *matrix,
		      GthTransformResize     resize,
		      cairo_rectangle_int_t *original,
		      cairo_rectangle_int_t *boundary)
{
	int x1, y1, x2, y2;

	x1 = original->x;
	y1 = original->y;
	x2 = original->x + original->width;
	y2 = original->y + original->height;

	switch (resize) {
	case GTH_TRANSFORM_RESIZE_CLIP:
		/* keep the original size */
		break;

	case GTH_TRANSFORM_RESIZE_BOUNDING_BOX:
	case GTH_TRANSFORM_RESIZE_CROP:
		{
			double dx1, dx2, dx3, dx4;
			double dy1, dy2, dy3, dy4;

			_cairo_matrix_transform_point (matrix, x1, y1, &dx1, &dy1);
			_cairo_matrix_transform_point (matrix, x2, y1, &dx2, &dy2);
			_cairo_matrix_transform_point (matrix, x1, y2, &dx3, &dy3);
			_cairo_matrix_transform_point (matrix, x2, y2, &dx4, &dy4);

			x1 = (int) floor (MIN4 (dx1, dx2, dx3, dx4));
			y1 = (int) floor (MIN4 (dy1, dy2, dy3, dy4));
			x2 = (int) ceil  (MAX4 (dx1, dx2, dx3, dx4));
			y2 = (int) ceil  (MAX4 (dy1, dy2, dy3, dy4));
			break;
		}
	}

	boundary->x = x1;
	boundary->y = y1;
	boundary->width = x2 - x1;
	boundary->height = y2 - y1;
}
Пример #10
0
/* this calculates the smallest rectangle (with sides parallel to x- and
 * y-axis) that contains the points d1 to d4
 */
static void
gimp_transform_resize_adjust (gdouble  dx1,
                              gdouble  dy1,
                              gdouble  dx2,
                              gdouble  dy2,
                              gdouble  dx3,
                              gdouble  dy3,
                              gdouble  dx4,
                              gdouble  dy4,
                              gint    *x1,
                              gint    *y1,
                              gint    *x2,
                              gint    *y2)
{
  *x1 = (gint) floor (MIN4 (dx1, dx2, dx3, dx4));
  *y1 = (gint) floor (MIN4 (dy1, dy2, dy3, dy4));

  *x2 = (gint) ceil (MAX4 (dx1, dx2, dx3, dx4));
  *y2 = (gint) ceil (MAX4 (dy1, dy2, dy3, dy4));
}
void
gimp_display_shell_untransform_bounds (const GimpDisplayShell *shell,
                                       gdouble                 x1,
                                       gdouble                 y1,
                                       gdouble                 x2,
                                       gdouble                 y2,
                                       gdouble                *nx1,
                                       gdouble                *ny1,
                                       gdouble                *nx2,
                                       gdouble                *ny2)
{
  g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
  g_return_if_fail (nx1 != NULL);
  g_return_if_fail (ny1 != NULL);
  g_return_if_fail (nx2 != NULL);
  g_return_if_fail (ny2 != NULL);

  if (shell->rotate_untransform)
    {
      gdouble tx1, ty1;
      gdouble tx2, ty2;
      gdouble tx3, ty3;
      gdouble tx4, ty4;

      gimp_display_shell_untransform_xy_f (shell, x1, y1, &tx1, &ty1);
      gimp_display_shell_untransform_xy_f (shell, x1, y2, &tx2, &ty2);
      gimp_display_shell_untransform_xy_f (shell, x2, y1, &tx3, &ty3);
      gimp_display_shell_untransform_xy_f (shell, x2, y2, &tx4, &ty4);

      *nx1 = MIN4 (tx1, tx2, tx3, tx4);
      *ny1 = MIN4 (ty1, ty2, ty3, ty4);
      *nx2 = MAX4 (tx1, tx2, tx3, tx4);
      *ny2 = MAX4 (ty1, ty2, ty3, ty4);
    }
  else
    {
      gimp_display_shell_untransform_xy_f (shell, x1, y1, nx1, ny1);
      gimp_display_shell_untransform_xy_f (shell, x2, y2, nx2, ny2);
    }
}
Пример #12
0
static void
get_bounding_box (GtkWidget    *widget,
                  GdkRectangle *bounds)
{
  GtkAllocation allocation;
  GtkBorder border = { 0, };
  GdkWindow *window;
  gint x, y;
  gint w, h;
  gint x1, y1;
  gint x2, y2;
  gint x3, y3;
  gint x4, y4;

  window = gtk_widget_get_parent_window (widget);
  if (window == NULL)
    window = gtk_widget_get_window (widget);

  gtk_widget_get_allocation (widget, &allocation);
  if (GTK_IS_WINDOW (widget))
    _gtk_window_get_shadow_width (GTK_WINDOW (widget), &border);
  x = allocation.x + border.left;
  y = allocation.y + border.right;
  w = allocation.width - border.left - border.right;
  h = allocation.height - border.top - border.bottom;

  gdk_window_get_root_coords (window, x, y, &x1, &y1);
  gdk_window_get_root_coords (window, x + w, y, &x2, &y2);
  gdk_window_get_root_coords (window, x, y + h, &x3, &y3);
  gdk_window_get_root_coords (window, x + w, y + h, &x4, &y4);

#define MIN4(a,b,c,d) MIN(MIN(a,b),MIN(c,d))
#define MAX4(a,b,c,d) MAX(MAX(a,b),MAX(c,d))

  bounds->x = floor (MIN4 (x1, x2, x3, x4));
  bounds->y = floor (MIN4 (y1, y2, y3, y4));
  bounds->width = ceil (MAX4 (x1, x2, x3, x4)) - bounds->x;
  bounds->height = ceil (MAX4 (y1, y2, y3, y4)) - bounds->y;
}
Пример #13
0
static PyObject *M_Geometry_BezierInterp( PyObject * self, PyObject * args )
{
	VectorObject *vec_k1, *vec_h1, *vec_k2, *vec_h2;
	int resolu;
	int dims;
	int i;
	float *coord_array, *fp;
	PyObject *list;
	
	float k1[4] = {0.0, 0.0, 0.0, 0.0};
	float h1[4] = {0.0, 0.0, 0.0, 0.0};
	float k2[4] = {0.0, 0.0, 0.0, 0.0};
	float h2[4] = {0.0, 0.0, 0.0, 0.0};
	
	
	if( !PyArg_ParseTuple ( args, "O!O!O!O!i",
	  &vector_Type, &vec_k1,
	  &vector_Type, &vec_h1,
	  &vector_Type, &vec_h2,
	  &vector_Type, &vec_k2, &resolu) || (resolu<=1)
	) {
		PyErr_SetString( PyExc_TypeError, "expected 4 vector types and an int greater then 1\n" );
		return NULL;
	}
	
	if(!BaseMath_ReadCallback(vec_k1) || !BaseMath_ReadCallback(vec_h1) || !BaseMath_ReadCallback(vec_k2) || !BaseMath_ReadCallback(vec_h2))
		return NULL;
	
	dims= MAX4(vec_k1->size, vec_h1->size, vec_h2->size, vec_k2->size);
	
	for(i=0; i < vec_k1->size; i++) k1[i]= vec_k1->vec[i];
	for(i=0; i < vec_h1->size; i++) h1[i]= vec_h1->vec[i];
	for(i=0; i < vec_k2->size; i++) k2[i]= vec_k2->vec[i];
	for(i=0; i < vec_h2->size; i++) h2[i]= vec_h2->vec[i];
	
	coord_array = MEM_callocN(dims * (resolu) * sizeof(float), "BezierInterp");
	for(i=0; i<dims; i++) {
		forward_diff_bezier(k1[i], h1[i], h2[i], k2[i], coord_array+i, resolu-1, sizeof(float)*dims);
	}
	
	list= PyList_New(resolu);
	fp= coord_array;
	for(i=0; i<resolu; i++, fp= fp+dims) {
		PyList_SET_ITEM(list, i, newVectorObject(fp, dims, Py_NEW, NULL));
	}
	MEM_freeN(coord_array);
	return list;
}
Пример #14
0
static inline void
calc_set_num(instr_t *instr, t_glob_reg_state* glob_reg_state )
{
  int i;
  //general purpose registers. Instead of using the whole enum, we only need to check for the
  //largest registers, any overlapping accesses will also trigger.
#ifdef X64
  update_setnrs(instr, DR_REG_START_64, DR_REG_STOP_64, glob_reg_state);
#else
  update_setnrs(instr, DR_REG_START_32, DR_REG_STOP_32, glob_reg_state);
#endif
#ifdef CONSIDER_MORE_REGS
  update_setnrs(instr, DR_REG_START_MMX, DR_REG_STOP_MMX, glob_reg_state);
  update_setnrs(instr, DR_REG_START_XMM, DR_REG_STOP_XMM, glob_reg_state);
  update_setnrs(instr, DR_REG_START_YMM, DR_REG_STOP_YMM, glob_reg_state);
  update_setnrs(instr, DR_REG_START_FLOAT, DR_REG_STOP_FLOAT, glob_reg_state);
  update_setnrs(instr, DR_REG_START_SEGMENT, DR_REG_START_CR, glob_reg_state);
  update_setnrs(instr, DR_REG_START_DR, DR_REG_STOP_DR, glob_reg_state);
  update_setnrs(instr, DR_REG_START_CR, DR_REG_STOP_CR, glob_reg_state);
#endif
#ifdef CONSIDER_EFLAGS
  update_eflag_setnrs(instr, glob_reg_state);
#endif
  glob_reg_state->final_setnr = MAX4(glob_reg_state->raw_setnr, glob_reg_state->war_setnr,
                        glob_reg_state->waw_setnr, glob_reg_state->else_setnr);
  //assigning the set number
  for (i = 0; i <= DR_REG_LAST_VALID_ENUM; i++) {
    if ( (i != DR_REG_NULL) && (i != DR_REG_INVALID) ) {
        if(instr_reads_from_reg(instr, i)) {
            glob_reg_state->my_readfrom[i] = MAX(glob_reg_state->my_readfrom[i],
                                                 glob_reg_state->final_setnr);
        }
        if(instr_writes_to_reg(instr, i)) {
            glob_reg_state->my_writtento[i] = MAX(glob_reg_state->my_writtento[i],
                                                  glob_reg_state->final_setnr);
        }
    }
  }
  glob_reg_state->num_sets = MAX(glob_reg_state->num_sets, glob_reg_state->final_setnr);
}
Пример #15
0
/* make a shape curve from area and aspect ratios	*/
shape_t *shape_from_aspect(double area, double min, 
                           double max, int rotable,
						   int n_orients)
{
	shape_t *shape;
	double r=1, minx, maxx, tmin, tmax;
	int i, overlap = 0;

	/* rotatable blocks have 2n no. of orients	*/
	if (n_orients <= 1 || (n_orients & 1))
		fatal("n_orients should be an even number greater than 1\n");

	shape = (shape_t *) calloc(1, sizeof(shape_t));
	if (!shape)
		fatal("memory allocation error\n");
	if (min == max)	
		shape->size = 1 + (!!rotable);
	else
		shape->size = n_orients;

	shape->x = (double *) calloc(shape->size, sizeof(double));
	shape->y = (double *) calloc(shape->size, sizeof(double));
	if (!shape->x || !shape->y)
		fatal("memory allocation error\n");

	/* overlapping regions of aspect ratios */
	if (rotable && min <= 1.0 && max >= 1.0) {
		overlap = 1;
		tmin = MIN4(min, max, 1.0/min, 1.0/max);
		tmax = MAX4(min, max, 1.0/min, 1.0/max);
		min = tmin;
		max = tmax;
	}

	if (!rotable || overlap) {
		minx = sqrt(area * min);
		maxx = sqrt(area * max);
		if (shape->size > 1)
			r = pow((maxx / minx) , 1.0/(shape->size-1));
		for (i = 0; i < shape->size; i++) {
			shape->x[i] = minx * pow(r, i);
			shape->y[i] = area / shape->x[i];
		}
	/* rotable but no overlap, hence two sets of orientations	*/		
	} else {
		int n = shape->size / 2;
		/* orientations with aspect ratios < 1	*/
		tmin = MIN(min, 1.0/min);
		tmax = MIN(max, 1.0/max);
		minx = sqrt(area * MIN(tmin, tmax));
		maxx = sqrt(area * MAX(tmin, tmax));
		if ( n > 1)
			r = pow((maxx / minx) , 1.0/(n-1));
		for (i = 0; i < n; i++) {
			shape->x[i] = minx * pow(r, i);
			shape->y[i] = area / shape->x[i];
		}
		/* orientations with aspect ratios > 1	*/
		tmin = MAX(min, 1.0/min);
		tmax = MAX(max, 1.0/max);
		minx = sqrt(area * MIN(tmin, tmax));
		maxx = sqrt(area * MAX(tmin, tmax));
		if ( n > 1)
			r = pow((maxx / minx) , 1.0/(n-1));
		for (i = 0; i < n; i++) {
			shape->x[n+i] = minx * pow(r, i);
			shape->y[n+i] = area / shape->x[n+i];
		}
	}
	return shape;
}
Пример #16
0
static boolean
try_setup_line( struct lp_setup_context *setup,
               const float (*v1)[4],
               const float (*v2)[4])
{
   struct llvmpipe_context *lp_context = (struct llvmpipe_context *)setup->pipe;
   struct lp_scene *scene = setup->scene;
   const struct lp_setup_variant_key *key = &setup->setup.variant->key;
   struct lp_rast_triangle *line;
   struct lp_rast_plane *plane;
   struct lp_line_info info;
   float width = MAX2(1.0, setup->line_width);
   const struct u_rect *scissor;
   struct u_rect bbox, bboxpos;
   boolean s_planes[4];
   unsigned tri_bytes;
   int x[4]; 
   int y[4];
   int i;
   int nr_planes = 4;
   unsigned viewport_index = 0;
   unsigned layer = 0;
   
   /* linewidth should be interpreted as integer */
   int fixed_width = util_iround(width) * FIXED_ONE;

   float x_offset=0;
   float y_offset=0;
   float x_offset_end=0;
   float y_offset_end=0;
      
   float x1diff;
   float y1diff;
   float x2diff;
   float y2diff;
   float dx, dy;
   float area;
   const float (*pv)[4];

   boolean draw_start;
   boolean draw_end;
   boolean will_draw_start;
   boolean will_draw_end;

   if (0)
      print_line(setup, v1, v2);

   if (setup->flatshade_first) {
      pv = v1;
   }
   else {
      pv = v2;
   }
   if (setup->viewport_index_slot > 0) {
      unsigned *udata = (unsigned*)pv[setup->viewport_index_slot];
      viewport_index = lp_clamp_viewport_idx(*udata);
   }
   if (setup->layer_slot > 0) {
      layer = *(unsigned*)pv[setup->layer_slot];
      layer = MIN2(layer, scene->fb_max_layer);
   }

   dx = v1[0][0] - v2[0][0];
   dy = v1[0][1] - v2[0][1];
   area = (dx * dx  + dy * dy);
   if (area == 0) {
      LP_COUNT(nr_culled_tris);
      return TRUE;
   }

   info.oneoverarea = 1.0f / area;
   info.dx = dx;
   info.dy = dy;
   info.v1 = v1;
   info.v2 = v2;

  
   /* X-MAJOR LINE */
   if (fabsf(dx) >= fabsf(dy)) {
      float dydx = dy / dx;

      x1diff = v1[0][0] - (float) floor(v1[0][0]) - 0.5;
      y1diff = v1[0][1] - (float) floor(v1[0][1]) - 0.5;
      x2diff = v2[0][0] - (float) floor(v2[0][0]) - 0.5;
      y2diff = v2[0][1] - (float) floor(v2[0][1]) - 0.5;

      if (y2diff==-0.5 && dy<0){
         y2diff = 0.5;
      }
      
      /* 
       * Diamond exit rule test for starting point 
       */    
      if (fabsf(x1diff) + fabsf(y1diff) < 0.5) {
         draw_start = TRUE;
      }
      else if (sign(x1diff) == sign(-dx)) {
         draw_start = FALSE;
      }
      else if (sign(-y1diff) != sign(dy)) {
         draw_start = TRUE;
      }
      else {
         /* do intersection test */
         float yintersect = fracf(v1[0][1]) + x1diff * dydx;
         draw_start = (yintersect < 1.0 && yintersect > 0.0);
      }


      /* 
       * Diamond exit rule test for ending point 
       */    
      if (fabsf(x2diff) + fabsf(y2diff) < 0.5) {
         draw_end = FALSE;
      }
      else if (sign(x2diff) != sign(-dx)) {
         draw_end = FALSE;
      }
      else if (sign(-y2diff) == sign(dy)) {
         draw_end = TRUE;
      }
      else {
         /* do intersection test */
         float yintersect = fracf(v2[0][1]) + x2diff * dydx;
         draw_end = (yintersect < 1.0 && yintersect > 0.0);
      }

      /* Are we already drawing start/end?
       */
      will_draw_start = sign(-x1diff) != sign(dx);
      will_draw_end = (sign(x2diff) == sign(-dx)) || x2diff==0;

      if (dx < 0) {
         /* if v2 is to the right of v1, swap pointers */
         const float (*temp)[4] = v1;
         v1 = v2;
         v2 = temp;
         dx = -dx;
         dy = -dy;
         /* Otherwise shift planes appropriately */
         if (will_draw_start != draw_start) {
            x_offset_end = - x1diff - 0.5;
            y_offset_end = x_offset_end * dydx;

         }
         if (will_draw_end != draw_end) {
            x_offset = - x2diff - 0.5;
            y_offset = x_offset * dydx;
         }

      }
      else{
         /* Otherwise shift planes appropriately */
         if (will_draw_start != draw_start) {
            x_offset = - x1diff + 0.5;
            y_offset = x_offset * dydx;
         }
         if (will_draw_end != draw_end) {
            x_offset_end = - x2diff + 0.5;
            y_offset_end = x_offset_end * dydx;
         }
      }
  
      /* x/y positions in fixed point */
      x[0] = subpixel_snap(v1[0][0] + x_offset     - setup->pixel_offset);
      x[1] = subpixel_snap(v2[0][0] + x_offset_end - setup->pixel_offset);
      x[2] = subpixel_snap(v2[0][0] + x_offset_end - setup->pixel_offset);
      x[3] = subpixel_snap(v1[0][0] + x_offset     - setup->pixel_offset);
      
      y[0] = subpixel_snap(v1[0][1] + y_offset     - setup->pixel_offset) - fixed_width/2;
      y[1] = subpixel_snap(v2[0][1] + y_offset_end - setup->pixel_offset) - fixed_width/2;
      y[2] = subpixel_snap(v2[0][1] + y_offset_end - setup->pixel_offset) + fixed_width/2;
      y[3] = subpixel_snap(v1[0][1] + y_offset     - setup->pixel_offset) + fixed_width/2;
      
   }
   else {
      const float dxdy = dx / dy;

      /* Y-MAJOR LINE */      
      x1diff = v1[0][0] - (float) floor(v1[0][0]) - 0.5;
      y1diff = v1[0][1] - (float) floor(v1[0][1]) - 0.5;
      x2diff = v2[0][0] - (float) floor(v2[0][0]) - 0.5;
      y2diff = v2[0][1] - (float) floor(v2[0][1]) - 0.5;

      if (x2diff==-0.5 && dx<0) {
         x2diff = 0.5;
      }

      /* 
       * Diamond exit rule test for starting point 
       */    
      if (fabsf(x1diff) + fabsf(y1diff) < 0.5) {
         draw_start = TRUE;
      }
      else if (sign(-y1diff) == sign(dy)) {
         draw_start = FALSE;
      }
      else if (sign(x1diff) != sign(-dx)) {
         draw_start = TRUE;
      }
      else {
         /* do intersection test */
         float xintersect = fracf(v1[0][0]) + y1diff * dxdy;
         draw_start = (xintersect < 1.0 && xintersect > 0.0);
      }

      /* 
       * Diamond exit rule test for ending point 
       */    
      if (fabsf(x2diff) + fabsf(y2diff) < 0.5) {
         draw_end = FALSE;
      }
      else if (sign(-y2diff) != sign(dy) ) {
         draw_end = FALSE;
      }
      else if (sign(x2diff) == sign(-dx) ) {
         draw_end = TRUE;
      }
      else {
         /* do intersection test */
         float xintersect = fracf(v2[0][0]) + y2diff * dxdy;
         draw_end = (xintersect < 1.0 && xintersect >= 0.0);
      }

      /* Are we already drawing start/end?
       */
      will_draw_start = sign(y1diff) == sign(dy);
      will_draw_end = (sign(-y2diff) == sign(dy)) || y2diff==0;

      if (dy > 0) {
         /* if v2 is on top of v1, swap pointers */
         const float (*temp)[4] = v1;
         v1 = v2;
         v2 = temp; 
         dx = -dx;
         dy = -dy;

         /* Otherwise shift planes appropriately */
         if (will_draw_start != draw_start) {
            y_offset_end = - y1diff + 0.5;
            x_offset_end = y_offset_end * dxdy;
         }
         if (will_draw_end != draw_end) {
            y_offset = - y2diff + 0.5;
            x_offset = y_offset * dxdy;
         }
      }
      else {
         /* Otherwise shift planes appropriately */
         if (will_draw_start != draw_start) {
            y_offset = - y1diff - 0.5;
            x_offset = y_offset * dxdy;
                     
         }
         if (will_draw_end != draw_end) {
            y_offset_end = - y2diff - 0.5;
            x_offset_end = y_offset_end * dxdy;
         }
      }

      /* x/y positions in fixed point */
      x[0] = subpixel_snap(v1[0][0] + x_offset     - setup->pixel_offset) - fixed_width/2;
      x[1] = subpixel_snap(v2[0][0] + x_offset_end - setup->pixel_offset) - fixed_width/2;
      x[2] = subpixel_snap(v2[0][0] + x_offset_end - setup->pixel_offset) + fixed_width/2;
      x[3] = subpixel_snap(v1[0][0] + x_offset     - setup->pixel_offset) + fixed_width/2;
     
      y[0] = subpixel_snap(v1[0][1] + y_offset     - setup->pixel_offset); 
      y[1] = subpixel_snap(v2[0][1] + y_offset_end - setup->pixel_offset);
      y[2] = subpixel_snap(v2[0][1] + y_offset_end - setup->pixel_offset);
      y[3] = subpixel_snap(v1[0][1] + y_offset     - setup->pixel_offset);
   }

   /* Bounding rectangle (in pixels) */
   {
      /* Yes this is necessary to accurately calculate bounding boxes
       * with the two fill-conventions we support.  GL (normally) ends
       * up needing a bottom-left fill convention, which requires
       * slightly different rounding.
       */
      int adj = (setup->bottom_edge_rule != 0) ? 1 : 0;

      bbox.x0 = (MIN4(x[0], x[1], x[2], x[3]) + (FIXED_ONE-1)) >> FIXED_ORDER;
      bbox.x1 = (MAX4(x[0], x[1], x[2], x[3]) + (FIXED_ONE-1)) >> FIXED_ORDER;
      bbox.y0 = (MIN4(y[0], y[1], y[2], y[3]) + (FIXED_ONE-1) + adj) >> FIXED_ORDER;
      bbox.y1 = (MAX4(y[0], y[1], y[2], y[3]) + (FIXED_ONE-1) + adj) >> FIXED_ORDER;

      /* Inclusive coordinates:
       */
      bbox.x1--;
      bbox.y1--;
   }

   if (bbox.x1 < bbox.x0 ||
       bbox.y1 < bbox.y0) {
      if (0) debug_printf("empty bounding box\n");
      LP_COUNT(nr_culled_tris);
      return TRUE;
   }

   if (!u_rect_test_intersection(&setup->draw_regions[viewport_index], &bbox)) {
      if (0) debug_printf("offscreen\n");
      LP_COUNT(nr_culled_tris);
      return TRUE;
   }

   bboxpos = bbox;

   /* Can safely discard negative regions:
    */
   bboxpos.x0 = MAX2(bboxpos.x0, 0);
   bboxpos.y0 = MAX2(bboxpos.y0, 0);

   nr_planes = 4;
   /*
    * Determine how many scissor planes we need, that is drop scissor
    * edges if the bounding box of the tri is fully inside that edge.
    */
   if (setup->scissor_test) {
      /* why not just use draw_regions */
      scissor = &setup->scissors[viewport_index];
      scissor_planes_needed(s_planes, &bboxpos, scissor);
      nr_planes += s_planes[0] + s_planes[1] + s_planes[2] + s_planes[3];
   }

   line = lp_setup_alloc_triangle(scene,
                                  key->num_inputs,
                                  nr_planes,
                                  &tri_bytes);
   if (!line)
      return FALSE;

#ifdef DEBUG
   line->v[0][0] = v1[0][0];
   line->v[1][0] = v2[0][0];   
   line->v[0][1] = v1[0][1];
   line->v[1][1] = v2[0][1];
#endif

   LP_COUNT(nr_tris);

   if (lp_context->active_statistics_queries &&
       !llvmpipe_rasterization_disabled(lp_context)) {
      lp_context->pipeline_statistics.c_primitives++;
   }

   /* calculate the deltas */
   plane = GET_PLANES(line);
   plane[0].dcdy = x[0] - x[1];
   plane[1].dcdy = x[1] - x[2];
   plane[2].dcdy = x[2] - x[3];
   plane[3].dcdy = x[3] - x[0];

   plane[0].dcdx = y[0] - y[1];
   plane[1].dcdx = y[1] - y[2];
   plane[2].dcdx = y[2] - y[3];
   plane[3].dcdx = y[3] - y[0];

   if (draw_will_inject_frontface(lp_context->draw) &&
       setup->face_slot > 0) {
      line->inputs.frontfacing = v1[setup->face_slot][0];
   } else {
      line->inputs.frontfacing = TRUE;
   }

   /* Setup parameter interpolants:
    */
   info.a0 = GET_A0(&line->inputs);
   info.dadx = GET_DADX(&line->inputs);
   info.dady = GET_DADY(&line->inputs);
   info.frontfacing = line->inputs.frontfacing;
   setup_line_coefficients(setup, &info); 

   line->inputs.disable = FALSE;
   line->inputs.opaque = FALSE;
   line->inputs.layer = layer;
   line->inputs.viewport_index = viewport_index;

   /*
    * XXX: this code is mostly identical to the one in lp_setup_tri, except it
    * uses 4 planes instead of 3. Could share the code (including the sse
    * assembly, in fact we'd get the 4th plane for free).
    * The only difference apart from storing the 4th plane would be some
    * different shuffle for calculating dcdx/dcdy.
    */
   for (i = 0; i < 4; i++) {

      /* half-edge constants, will be iterated over the whole render
       * target.
       */
      plane[i].c = IMUL64(plane[i].dcdx, x[i]) - IMUL64(plane[i].dcdy, y[i]);

      /* correct for top-left vs. bottom-left fill convention.
       */
      if (plane[i].dcdx < 0) {
         /* both fill conventions want this - adjust for left edges */
         plane[i].c++;
      }
      else if (plane[i].dcdx == 0) {
         if (setup->pixel_offset == 0) {
            /* correct for top-left fill convention:
             */
            if (plane[i].dcdy > 0) plane[i].c++;
         }
         else {
            /* correct for bottom-left fill convention:
             */
            if (plane[i].dcdy < 0) plane[i].c++;
         }
      }

      plane[i].dcdx *= FIXED_ONE;
      plane[i].dcdy *= FIXED_ONE;

      /* find trivial reject offsets for each edge for a single-pixel
       * sized block.  These will be scaled up at each recursive level to
       * match the active blocksize.  Scaling in this way works best if
       * the blocks are square.
       */
      plane[i].eo = 0;
      if (plane[i].dcdx < 0) plane[i].eo -= plane[i].dcdx;
      if (plane[i].dcdy > 0) plane[i].eo += plane[i].dcdy;
   }


   /* 
    * When rasterizing scissored tris, use the intersection of the
    * triangle bounding box and the scissor rect to generate the
    * scissor planes.
    *
    * This permits us to cut off the triangle "tails" that are present
    * in the intermediate recursive levels caused when two of the
    * triangles edges don't diverge quickly enough to trivially reject
    * exterior blocks from the triangle.
    *
    * It's not really clear if it's worth worrying about these tails,
    * but since we generate the planes for each scissored tri, it's
    * free to trim them in this case.
    * 
    * Note that otherwise, the scissor planes only vary in 'C' value,
    * and even then only on state-changes.  Could alternatively store
    * these planes elsewhere.
    * (Or only store the c value together with a bit indicating which
    * scissor edge this is, so rasterization would treat them differently
    * (easier to evaluate) to ordinary planes.)
    */
   if (nr_planes > 4) {
      struct lp_rast_plane *plane_s = &plane[4];

      if (s_planes[0]) {
         plane_s->dcdx = -1 << 8;
         plane_s->dcdy = 0;
         plane_s->c = (1-scissor->x0) << 8;
         plane_s->eo = 1 << 8;
         plane_s++;
      }
      if (s_planes[1]) {
         plane_s->dcdx = 1 << 8;
         plane_s->dcdy = 0;
         plane_s->c = (scissor->x1+1) << 8;
         plane_s->eo = 0 << 8;
         plane_s++;
      }
      if (s_planes[2]) {
         plane_s->dcdx = 0;
         plane_s->dcdy = 1 << 8;
         plane_s->c = (1-scissor->y0) << 8;
         plane_s->eo = 1 << 8;
         plane_s++;
      }
      if (s_planes[3]) {
         plane_s->dcdx = 0;
         plane_s->dcdy = -1 << 8;
         plane_s->c = (scissor->y1+1) << 8;
         plane_s->eo = 0;
         plane_s++;
      }
      assert(plane_s == &plane[nr_planes]);
   }

   return lp_setup_bin_triangle(setup, line, &bbox, &bboxpos, nr_planes, viewport_index);
}
Пример #17
0
static GeglBuffer *
gimp_perspective_clone_get_source (GimpSourceCore   *source_core,
                                   GimpDrawable     *drawable,
                                   GimpPaintOptions *paint_options,
                                   GimpPickable     *src_pickable,
                                   gint              src_offset_x,
                                   gint              src_offset_y,
                                   GeglBuffer       *paint_buffer,
                                   gint              paint_buffer_x,
                                   gint              paint_buffer_y,
                                   gint             *paint_area_offset_x,
                                   gint             *paint_area_offset_y,
                                   gint             *paint_area_width,
                                   gint             *paint_area_height,
                                   GeglRectangle    *src_rect)
{
  GimpPerspectiveClone *clone         = GIMP_PERSPECTIVE_CLONE (source_core);
  GimpCloneOptions     *clone_options = GIMP_CLONE_OPTIONS (paint_options);
  GeglBuffer           *src_buffer;
  GeglBuffer           *dest_buffer;
  const Babl           *src_format_alpha;
  gint                  x1d, y1d, x2d, y2d;
  gdouble               x1s, y1s, x2s, y2s, x3s, y3s, x4s, y4s;
  gint                  xmin, ymin, xmax, ymax;
  GimpMatrix3           matrix;
  GimpMatrix3           gegl_matrix;

  src_buffer       = gimp_pickable_get_buffer (src_pickable);
  src_format_alpha = gimp_pickable_get_format_with_alpha (src_pickable);

  /* Destination coordinates that will be painted */
  x1d = paint_buffer_x;
  y1d = paint_buffer_y;
  x2d = paint_buffer_x + gegl_buffer_get_width  (paint_buffer);
  y2d = paint_buffer_y + gegl_buffer_get_height (paint_buffer);

  /* Boundary box for source pixels to copy: Convert all the vertex of
   * the box to paint in destination area to its correspondent in
   * source area bearing in mind perspective
   */
  gimp_perspective_clone_get_source_point (clone, x1d, y1d, &x1s, &y1s);
  gimp_perspective_clone_get_source_point (clone, x1d, y2d, &x2s, &y2s);
  gimp_perspective_clone_get_source_point (clone, x2d, y1d, &x3s, &y3s);
  gimp_perspective_clone_get_source_point (clone, x2d, y2d, &x4s, &y4s);

  xmin = floor (MIN4 (x1s, x2s, x3s, x4s));
  ymin = floor (MIN4 (y1s, y2s, y3s, y4s));
  xmax = ceil  (MAX4 (x1s, x2s, x3s, x4s));
  ymax = ceil  (MAX4 (y1s, y2s, y3s, y4s));

  switch (clone_options->clone_type)
    {
    case GIMP_IMAGE_CLONE:
      if (! gimp_rectangle_intersect (xmin, ymin,
                                      xmax - xmin, ymax - ymin,
                                      0, 0,
                                      gegl_buffer_get_width  (src_buffer),
                                      gegl_buffer_get_height (src_buffer),
                                      NULL, NULL, NULL, NULL))
        {
          /* if the source area is completely out of the image */
          return NULL;
        }
      break;

    case GIMP_PATTERN_CLONE:
      gegl_node_set (clone->crop,
                     "x",      (gdouble) xmin,
                     "y",      (gdouble) ymin,
                     "width",  (gdouble) xmax - xmin,
                     "height", (gdouble) ymax - ymin,
                     NULL);
      break;
    }

  dest_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0, x2d - x1d, y2d - y1d),
                                 src_format_alpha);

  gimp_perspective_clone_get_matrix (clone, &matrix);

  gimp_matrix3_identity (&gegl_matrix);
  gimp_matrix3_mult (&matrix, &gegl_matrix);
  gimp_matrix3_translate (&gegl_matrix, -x1d, -y1d);

  gimp_gegl_node_set_matrix (clone->transform_node, &gegl_matrix);

  gegl_node_set (clone->dest_node,
                 "buffer", dest_buffer,
                 NULL);

  gegl_node_blit (clone->dest_node, 1.0,
                  GEGL_RECTANGLE (0, 0, x2d - x1d, y2d - y1d),
                  NULL, NULL, 0, GEGL_BLIT_DEFAULT);

  *src_rect = *GEGL_RECTANGLE (0, 0, x2d - x1d, y2d - y1d);

  return dest_buffer;
}
Пример #18
0
void AffineUnit::process_package(LoadPackage *package)
{
	AffinePackage *pkg = (AffinePackage*)package;
	int min_in_x = server->in_x;
	int min_in_y = server->in_y;
	int max_in_x = server->in_x + server->in_w - 1;
	int max_in_y = server->in_y + server->in_h - 1;

	int min_out_x = server->out_x;
	int min_out_y = server->out_y;
	int max_out_x = server->out_x + server->out_w;
	int max_out_y = server->out_y + server->out_h;

// Amount to shift the input coordinates relative to the output coordinates
// To get the pivots to line up
	int pivot_offset_x = server->in_pivot_x - server->out_pivot_x;
	int pivot_offset_y = server->in_pivot_y - server->out_pivot_y;

// Calculate real coords
	float out_x1, out_y1, out_x2, out_y2, out_x3, out_y3, out_x4, out_y4;
	if(server->mode == AffineEngine::STRETCH ||
		server->mode == AffineEngine::PERSPECTIVE ||
		server->mode == AffineEngine::ROTATE)
	{
		out_x1 = (float)server->in_x + (float)server->x1 * server->in_w / 100;
		out_y1 = (float)server->in_y + (float)server->y1 * server->in_h / 100;
		out_x2 = (float)server->in_x + (float)server->x2 * server->in_w / 100;
		out_y2 = (float)server->in_y + (float)server->y2 * server->in_h / 100;
		out_x3 = (float)server->in_x + (float)server->x3 * server->in_w / 100;
		out_y3 = (float)server->in_y + (float)server->y3 * server->in_h / 100;
		out_x4 = (float)server->in_x + (float)server->x4 * server->in_w / 100;
		out_y4 = (float)server->in_y + (float)server->y4 * server->in_h / 100;
	}
	else
	{
		out_x1 = (float)server->in_x + (float)server->x1 * server->in_w / 100;
		out_y1 = server->in_y;
		out_x2 = out_x1 + server->in_w;
		out_y2 = server->in_y;
		out_x4 = (float)server->in_x + (float)server->x4 * server->in_w / 100;
		out_y4 = server->in_y + server->in_h;
		out_x3 = out_x4 + server->in_w;
		out_y3 = server->in_y + server->in_h;
	}
// Rotation with OpenGL uses a simple quad.
	if(server->mode == AffineEngine::ROTATE &&
		server->use_opengl)
	{
#ifdef HAVE_GL
		server->output->to_texture();
		server->output->enable_opengl();
		server->output->init_screen();
		server->output->bind_texture(0);
		server->output->clear_pbuffer();

		int texture_w = server->output->get_texture_w();
		int texture_h = server->output->get_texture_h();
		float output_h = server->output->get_h();
		float in_x1 = (float)server->in_x / texture_w;
		float in_x2 = (float)(server->in_x + server->in_w) / texture_w;
		float in_y1 = (float)server->in_y / texture_h;
		float in_y2 = (float)(server->in_y + server->in_h) / texture_h;

		glBegin(GL_QUADS);
		glNormal3f(0, 0, 1.0);

		glTexCoord2f(in_x1, in_y1);
		glVertex3f(out_x1, -output_h+out_y1, 0);

		glTexCoord2f(in_x2, in_y1);
		glVertex3f(out_x2, -output_h+out_y2, 0);

		glTexCoord2f(in_x2, in_y2);
		glVertex3f(out_x3, -output_h+out_y3, 0);

		glTexCoord2f(in_x1, in_y2);
		glVertex3f(out_x4, -output_h+out_y4, 0);

		glEnd();

		server->output->set_opengl_state(VFrame::SCREEN);
#endif
	}
	else
	if(server->mode == AffineEngine::PERSPECTIVE ||
		server->mode == AffineEngine::SHEER ||
		server->mode == AffineEngine::ROTATE)
	{
		AffineMatrix matrix;
		float temp;
// swap points 3 & 4
		temp = out_x4;
		out_x4 = out_x3;
		out_x3 = temp;
		temp = out_y4;
		out_y4 = out_y3;
		out_y3 = temp;

		calculate_matrix(
			server->in_x,
			server->in_y,
			server->in_x + server->in_w,
			server->in_y + server->in_h,
			out_x1,
			out_y1,
			out_x2,
			out_y2,
			out_x3,
			out_y3,
			out_x4,
			out_y4,
			&matrix);

		int interpolate = 1;
		int reverse = !server->forward;
		float tx, ty, tw;
		float xinc, yinc, winc;
		AffineMatrix m, im;
		float ttx = 0, tty = 0;
		int itx = 0, ity = 0;
		int tx1 = 0, ty1 = 0, tx2 = 0, ty2 = 0;

		if(reverse)
		{
			m.copy_from(&matrix);
			m.invert(&im);
			matrix.copy_from(&im);
		}
		else
		{
			matrix.invert(&m);
		}

		float dx1 = 0, dy1 = 0;
		float dx2 = 0, dy2 = 0;
		float dx3 = 0, dy3 = 0;
		float dx4 = 0, dy4 = 0;
		matrix.transform_point(server->in_x, server->in_y, &dx1, &dy1);
		matrix.transform_point(server->in_x + server->in_w, server->in_y, &dx2, &dy2);
		matrix.transform_point(server->in_x, server->in_y + server->in_h, &dx3, &dy3);
		matrix.transform_point(server->in_x + server->in_w, server->in_y + server->in_h, &dx4, &dy4);

		if(server->use_opengl)
		{
#ifdef HAVE_GL
			static char *affine_frag =
				(char*)"uniform sampler2D tex;\n"
				"uniform mat3 affine_matrix;\n"
				"uniform vec2 texture_extents;\n"
				"uniform vec2 image_extents;\n"
				"uniform vec4 border_color;\n"
				"void main()\n"
				"{\n"
				"	vec2 outcoord = gl_TexCoord[0].st;\n"
				"	outcoord *= texture_extents;\n"
				"	mat3 coord_matrix = mat3(\n"
				"		outcoord.x, outcoord.y, 1.0, \n"
				"		outcoord.x, outcoord.y, 1.0, \n"
				"		outcoord.x, outcoord.y, 1.0);\n"
				"	mat3 incoord_matrix = affine_matrix * coord_matrix;\n"
				"	vec2 incoord = vec2(incoord_matrix[0][0], incoord_matrix[0][1]);\n"
				"	incoord /= incoord_matrix[0][2];\n"
				"	incoord /= texture_extents;\n"
				"	if(incoord.x > image_extents.x || incoord.y > image_extents.y)\n"
				"		gl_FragColor = border_color;\n"
				"	else\n"
				"		gl_FragColor = texture2D(tex, incoord);\n"
				"}\n";

			float affine_matrix[9] = {
				(float)m.values[0][0], (float)m.values[1][0], (float)m.values[2][0],
				(float)m.values[0][1], (float)m.values[1][1], (float)m.values[2][1],
				(float)m.values[0][2], (float)m.values[1][2], (float)m.values[2][2]
			};

			server->output->to_texture();
			server->output->enable_opengl();
			unsigned int frag_shader = VFrame::make_shader(0,
					affine_frag,
					0);
			if(frag_shader > 0)
			{
				glUseProgram(frag_shader);
				glUniform1i(glGetUniformLocation(frag_shader, "tex"), 0);
				glUniformMatrix3fv(glGetUniformLocation(frag_shader, "affine_matrix"), 
					1,
					0,
					affine_matrix);
				glUniform2f(glGetUniformLocation(frag_shader, "texture_extents"), 
					(GLfloat)server->output->get_texture_w(),
					(GLfloat)server->output->get_texture_h());
				glUniform2f(glGetUniformLocation(frag_shader, "image_extents"), 
					(GLfloat)server->output->get_w() / server->output->get_texture_w(),
					(GLfloat)server->output->get_h() / server->output->get_texture_h());
				float border_color[] = { 0, 0, 0, 0 };
				if(BC_CModels::is_yuv(server->output->get_color_model()))
				{
					border_color[1] = 0.5;
					border_color[2] = 0.5;
				}
				if(!BC_CModels::has_alpha(server->output->get_color_model()))
				{
					border_color[3] = 1.0;
				}

				glUniform4fv(glGetUniformLocation(frag_shader, "border_color"), 
					1,
					(GLfloat*)border_color);
				server->output->init_screen();
				server->output->bind_texture(0);
				glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color);
				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
				server->output->draw_texture();
				glUseProgram(0);
				server->output->set_opengl_state(VFrame::SCREEN);
			}
			return;
#endif // HAVE_GL
		}

#define ROUND(x) ((int)((x > 0) ? (x) + 0.5 : (x) - 0.5))
#define MIN4(a,b,c,d) MIN(MIN(MIN(a,b),c),d)
#define MAX4(a,b,c,d) MAX(MAX(MAX(a,b),c),d)

		tx1 = ROUND(MIN4(dx1 - pivot_offset_x, dx2 - pivot_offset_x, dx3 - pivot_offset_x, dx4 - pivot_offset_x));
		ty1 = ROUND(MIN4(dy1 - pivot_offset_y, dy2 - pivot_offset_y, dy3 - pivot_offset_y, dy4 - pivot_offset_y));

		tx2 = ROUND(MAX4(dx1 - pivot_offset_x, dx2 - pivot_offset_x, dx3 - pivot_offset_x, dx4 - pivot_offset_x));
		ty2 = ROUND(MAX4(dy1 - pivot_offset_y, dy2 - pivot_offset_y, dy3 - pivot_offset_y, dy4 - pivot_offset_y));

		CLAMP(ty1, pkg->y1, pkg->y2);
		CLAMP(ty2, pkg->y1, pkg->y2);
		CLAMP(tx1, server->out_x, server->out_x + server->out_w);
		CLAMP(tx2, server->out_x, server->out_x + server->out_w);

		xinc = m.values[0][0];
		yinc = m.values[1][0];
		winc = m.values[2][0];

#define CUBIC_ROW(in_row, chroma_offset) \
	transform_cubic(dx, \
		in_row[col1_offset] - chroma_offset, \
		in_row[col2_offset] - chroma_offset, \
		in_row[col3_offset] - chroma_offset, \
		in_row[col4_offset] - chroma_offset)


#define TRANSFORM(components, type, temp_type, chroma_offset, max) \
{ \
	type **in_rows = (type**)server->input->get_rows(); \
	float round_factor = 0.0; \
	if(sizeof(type) < 4) round_factor = 0.5; \
	for(int y = ty1; y < ty2; y++) \
	{ \
		type *out_row = (type*)server->output->get_rows()[y]; \
 \
		if(!interpolate) \
		{ \
        	tx = xinc * (tx1 + 0.5) + \
				m.values[0][1] * (y + pivot_offset_y + 0.5) + \
				m.values[0][2] + \
				pivot_offset_x * xinc; \
        	ty = yinc * (tx1 + 0.5) + \
				m.values[1][1] * (y + pivot_offset_y + 0.5) + \
				m.values[1][2] + \
				pivot_offset_x * yinc; \
        	tw = winc * (tx1 + 0.5) + \
				m.values[2][1] * (y + pivot_offset_y + 0.5) + \
				m.values[2][2] + \
				pivot_offset_x * winc; \
		} \
		else \
		{ \
			tx = xinc * tx1 + \
				m.values[0][1] * (y + pivot_offset_y) + \
				m.values[0][2] + \
				pivot_offset_x * xinc; \
			ty = yinc * tx1 + \
				m.values[1][1] * (y + pivot_offset_y) + \
				m.values[1][2] + \
				pivot_offset_x * yinc; \
			tw = winc * tx1 + \
				m.values[2][1] * (y + pivot_offset_y) + \
				m.values[2][2] + \
				pivot_offset_x * winc; \
		} \
 \
		out_row += tx1 * components; \
		for(int x = tx1; x < tx2; x++) \
		{ \
/* Normalize homogeneous coords */ \
			if(tw == 0.0) \
			{ \
				ttx = 0.0; \
				tty = 0.0; \
			} \
			else \
			if(tw != 1.0) \
			{ \
				ttx = tx / tw; \
				tty = ty / tw; \
			} \
			else \
			{ \
				ttx = tx; \
				tty = ty; \
			} \
			itx = (int)ttx; \
			ity = (int)tty; \
 \
			int row1 = ity - 1; \
			int row2 = ity; \
			int row3 = ity + 1; \
			int row4 = ity + 2; \
			CLAMP(row1, min_in_y, max_in_y); \
			CLAMP(row2, min_in_y, max_in_y); \
			CLAMP(row3, min_in_y, max_in_y); \
			CLAMP(row4, min_in_y, max_in_y); \
 \
/* Set destination pixels if in clipping region */ \
			if(!interpolate && \
				x >= min_out_x && \
				x < max_out_x) \
			{ \
				if(itx >= min_in_x && \
					itx <= max_in_x && \
					ity >= min_in_y && \
					ity <= max_in_y) \
				{ \
					type *src = in_rows[ity] + itx * components; \
					*out_row++ = *src++; \
					*out_row++ = *src++; \
					*out_row++ = *src++; \
					if(components == 4) *out_row++ = *src; \
				} \
				else \
/* Fill with chroma */ \
				{ \
					*out_row++ = 0; \
					*out_row++ = chroma_offset; \
					*out_row++ = chroma_offset; \
					if(components == 4) *out_row++ = 0; \
				} \
			} \
			else \
/* Bicubic algorithm */ \
			if(interpolate &&  \
				x >= min_out_x &&  \
				x < max_out_x) \
			{ \
/* clipping region */ \
				if ((itx + 2) >= min_in_x && \
					(itx - 1) <= max_in_x && \
					(ity + 2) >= min_in_y && \
					(ity - 1) <= max_in_y) \
				{ \
					float dx, dy; \
 \
/* the fractional error */ \
					dx = ttx - itx; \
					dy = tty - ity; \
 \
/* Row and column offsets in cubic block */ \
					int col1 = itx - 1; \
					int col2 = itx; \
					int col3 = itx + 1; \
					int col4 = itx + 2; \
					CLAMP(col1, min_in_x, max_in_x); \
					CLAMP(col2, min_in_x, max_in_x); \
					CLAMP(col3, min_in_x, max_in_x); \
					CLAMP(col4, min_in_x, max_in_x); \
					int col1_offset = col1 * components; \
					int col2_offset = col2 * components; \
					int col3_offset = col3 * components; \
					int col4_offset = col4 * components; \
 \
					type *row1_ptr = in_rows[row1]; \
					type *row2_ptr = in_rows[row2]; \
					type *row3_ptr = in_rows[row3]; \
					type *row4_ptr = in_rows[row4]; \
					temp_type r, g, b, a; \
 \
					r = (temp_type)(transform_cubic(dy, \
						CUBIC_ROW(row1_ptr, 0x0), \
						CUBIC_ROW(row2_ptr, 0x0), \
						CUBIC_ROW(row3_ptr, 0x0), \
						CUBIC_ROW(row4_ptr, 0x0)) + \
						round_factor); \
 \
					row1_ptr++; \
					row2_ptr++; \
					row3_ptr++; \
					row4_ptr++; \
					g = (temp_type)(transform_cubic(dy, \
						CUBIC_ROW(row1_ptr, chroma_offset), \
						CUBIC_ROW(row2_ptr, chroma_offset), \
						CUBIC_ROW(row3_ptr, chroma_offset), \
						CUBIC_ROW(row4_ptr, chroma_offset)) + \
						round_factor); \
					g += chroma_offset; \
 \
					row1_ptr++; \
					row2_ptr++; \
					row3_ptr++; \
					row4_ptr++; \
					b = (temp_type)(transform_cubic(dy, \
						CUBIC_ROW(row1_ptr, chroma_offset), \
						CUBIC_ROW(row2_ptr, chroma_offset), \
						CUBIC_ROW(row3_ptr, chroma_offset), \
						CUBIC_ROW(row4_ptr, chroma_offset)) + \
						round_factor); \
					b += chroma_offset; \
 \
					if(components == 4) \
					{ \
						row1_ptr++; \
						row2_ptr++; \
						row3_ptr++; \
						row4_ptr++; \
						a = (temp_type)(transform_cubic(dy, \
							CUBIC_ROW(row1_ptr, 0x0), \
							CUBIC_ROW(row2_ptr, 0x0), \
							CUBIC_ROW(row3_ptr, 0x0), \
							CUBIC_ROW(row4_ptr, 0x0)) +  \
							round_factor); \
					} \
 \
 					if(sizeof(type) < 4) \
					{ \
						*out_row++ = CLIP(r, 0, max); \
						*out_row++ = CLIP(g, 0, max); \
						*out_row++ = CLIP(b, 0, max); \
						if(components == 4) *out_row++ = CLIP(a, 0, max); \
					} \
					else \
					{ \
						*out_row++ = r; \
						*out_row++ = g; \
						*out_row++ = b; \
						if(components == 4) *out_row++ = a; \
					} \
				} \
				else \
/* Fill with chroma */ \
				{ \
					*out_row++ = 0; \
					*out_row++ = chroma_offset; \
					*out_row++ = chroma_offset; \
					if(components == 4) *out_row++ = 0; \
				} \
			} \
			else \
			{ \
				out_row += components; \
			} \
 \
/*  increment the transformed coordinates  */ \
			tx += xinc; \
			ty += yinc; \
			tw += winc; \
		} \
	} \
}

		switch(server->input->get_color_model())
		{
		case BC_RGB_FLOAT:
			TRANSFORM(3, float, float, 0x0, 1.0)
			break;
		case BC_RGB888:
			TRANSFORM(3, unsigned char, int, 0x0, 0xff)
			break;
		case BC_RGBA_FLOAT:
			TRANSFORM(4, float, float, 0x0, 1.0)
			break;
		case BC_RGBA8888:
			TRANSFORM(4, unsigned char, int, 0x0, 0xff)
			break;
		case BC_YUV888:
			{
				unsigned char **in_rows = (unsigned char**)server->input->get_rows();
				float round_factor = 0.0;
				if(sizeof(unsigned char) < 4) round_factor = 0.5;
				for(int y = ty1; y < ty2; y++)
				{
					unsigned char *out_row = (unsigned char*)server->output->get_rows()[y];

					if(!interpolate)
					{
						tx = xinc * (tx1 + 0.5) +
							m.values[0][1] * (y + pivot_offset_y + 0.5) +
							m.values[0][2] +
							pivot_offset_x * xinc;
						ty = yinc * (tx1 + 0.5) +
							m.values[1][1] * (y + pivot_offset_y + 0.5) +
							m.values[1][2] +
							pivot_offset_x * yinc;
						tw = winc * (tx1 + 0.5) +
							m.values[2][1] * (y + pivot_offset_y + 0.5) +
							m.values[2][2] +
							pivot_offset_x * winc;
					}
					else
					{
						tx = xinc * tx1 +
							m.values[0][1] * (y + pivot_offset_y) +
							m.values[0][2] +
							pivot_offset_x * xinc;
						ty = yinc * tx1 +
							m.values[1][1] * (y + pivot_offset_y) +
							m.values[1][2] +
							pivot_offset_x * yinc;
						tw = winc * tx1 +
							m.values[2][1] * (y + pivot_offset_y) +
							m.values[2][2] +
							pivot_offset_x * winc;
					}

					out_row += tx1 * 3;
					for(int x = tx1; x < tx2; x++)
					{
// Normalize homogeneous coords
						if(tw == 0.0)
						{
							ttx = 0.0;
							tty = 0.0;
						}
						else
						if(tw != 1.0)
						{
							ttx = tx / tw;
							tty = ty / tw;
						}
						else
						{
							ttx = tx;
							tty = ty;
						}
						itx = (int)ttx;
						ity = (int)tty;

						int row1 = ity - 1;
						int row2 = ity;
						int row3 = ity + 1;
						int row4 = ity + 2;
						CLAMP(row1, min_in_y, max_in_y);
						CLAMP(row2, min_in_y, max_in_y);
						CLAMP(row3, min_in_y, max_in_y);
						CLAMP(row4, min_in_y, max_in_y);
// Set destination pixels if in clipping region
						if(!interpolate &&
							x >= min_out_x &&
							x < max_out_x)
						{
							if(itx >= min_in_x &&
								itx <= max_in_x &&
								ity >= min_in_y &&
								ity <= max_in_y)
							{
								unsigned char *src = in_rows[ity] + itx * 3;
								*out_row++ = *src++;
								*out_row++ = *src++;
								*out_row++ = *src++;
							}
							else
// Fill with chroma
							{
								*out_row++ = 0;
								*out_row++ = 0x80;
								*out_row++ = 0x80;
							}
						}
						else
// Bicubic algorithm
						if(interpolate &&
							x >= min_out_x &&
							x < max_out_x)
						{
// clipping region
							if((itx + 2) >= min_in_x &&
								(itx - 1) <= max_in_x &&
								(ity + 2) >= min_in_y &&
								(ity - 1) <= max_in_y)
							{
								float dx, dy;
// the fractional error
								dx = ttx - itx;
								dy = tty - ity;
// Row and column offsets in cubic block
								int col1 = itx - 1;
								int col2 = itx;
								int col3 = itx + 1;
								int col4 = itx + 2;
								CLAMP(col1, min_in_x, max_in_x);
								CLAMP(col2, min_in_x, max_in_x);
								CLAMP(col3, min_in_x, max_in_x);
								CLAMP(col4, min_in_x, max_in_x);

								int col1_offset = col1 * 3;
								int col2_offset = col2 * 3;
								int col3_offset = col3 * 3;
								int col4_offset = col4 * 3;

								unsigned char *row1_ptr = in_rows[row1];
								unsigned char *row2_ptr = in_rows[row2];
								unsigned char *row3_ptr = in_rows[row3];
								unsigned char *row4_ptr = in_rows[row4];
								int r, g, b, a;

								r = (int)(transform_cubic(dy,
									CUBIC_ROW(row1_ptr, 0x0),
									CUBIC_ROW(row2_ptr, 0x0),
									CUBIC_ROW(row3_ptr, 0x0),
									CUBIC_ROW(row4_ptr, 0x0)) +
									round_factor);

								row1_ptr++;
								row2_ptr++;
								row3_ptr++;
								row4_ptr++;
								g = (int)(transform_cubic(dy,
									CUBIC_ROW(row1_ptr, 0x80),
									CUBIC_ROW(row2_ptr, 0x80),
									CUBIC_ROW(row3_ptr, 0x80),
									CUBIC_ROW(row4_ptr, 0x80)) +
									round_factor);
								g += 0x80;

								row1_ptr++;
								row2_ptr++;
								row3_ptr++;
								row4_ptr++;
								b = (int)(transform_cubic(dy,
									CUBIC_ROW(row1_ptr, 0x80),
									CUBIC_ROW(row2_ptr, 0x80),
									CUBIC_ROW(row3_ptr, 0x80),
									CUBIC_ROW(row4_ptr, 0x80)) +
									round_factor);
								b += 0x80;

								if(sizeof(unsigned char) < 4)
								{
									*out_row++ = CLIP(r, 0, 0xff);
									*out_row++ = CLIP(g, 0, 0xff);
									*out_row++ = CLIP(b, 0, 0xff);
								}
								else
								{
									*out_row++ = r;
									*out_row++ = g;
									*out_row++ = b;
								}
							}
							else
// Fill with chroma
							{
								*out_row++ = 0;
								*out_row++ = 0x80;
								*out_row++ = 0x80;
							}
						}
						else
						{
							out_row += 3;
						}

//  increment the transformed coordinates
						tx += xinc;
						ty += yinc;
						tw += winc;
					}
				}
			}

			break;
		case BC_YUVA8888:
			TRANSFORM(4, unsigned char, int, 0x80, 0xff)
			break;
		case BC_RGB161616:
			TRANSFORM(3, uint16_t, int, 0x0, 0xffff)
			break;
		case BC_RGBA16161616:
			TRANSFORM(4, uint16_t, int, 0x0, 0xffff)
			break;
		case BC_YUV161616:
			TRANSFORM(3, uint16_t, int, 0x8000, 0xffff)
			break;
		case BC_YUVA16161616:
			TRANSFORM(4, uint16_t, int, 0x8000, 0xffff)
			break;
		}
	}
Пример #19
0
// Fill in traceback matrix
static void alignment_fill_matrices(aligner_t *aligner, char is_sw)
{
  score_t *match_scores = aligner->match_scores;
  score_t *gap_a_scores = aligner->gap_a_scores;
  score_t *gap_b_scores = aligner->gap_b_scores;
  const scoring_t *scoring = aligner->scoring;
  size_t score_width = aligner->score_width;
  size_t score_height = aligner->score_height;

  size_t i, j;

  const score_t min = is_sw ? 0 : SCORE_MIN;

  size_t seq_i, seq_j, len_i = score_width-1, len_j = score_height-1;
  size_t index, index_left, index_up, index_upleft;

  // [0][0]
  match_scores[0] = 0;
  gap_a_scores[0] = 0;
  gap_b_scores[0] = 0;

  if(is_sw)
  {
    for(i = 1; i < score_width; i++)
      match_scores[i] = gap_a_scores[i] = gap_b_scores[i] = 0;
    for(j = 1, index = score_width; j < score_height; j++, index += score_width)
      match_scores[index] = gap_a_scores[index] = gap_b_scores[index] = min;
  }
  else
  {
    // work along first row -> [i][0]
    for(i = 1; i < score_width; i++)
    {
      match_scores[i] = min;

      // Think carefully about which way round these are
      gap_a_scores[i] = min;
      gap_b_scores[i] = scoring->no_start_gap_penalty ? 0
                        : scoring->gap_open + (long)i * scoring->gap_extend;
    }

    // work down first column -> [0][j]
    for(j = 1, index = score_width; j < score_height; j++, index += score_width)
    {
      match_scores[index] = min;

      // Think carefully about which way round these are
      gap_a_scores[index] = scoring->no_start_gap_penalty ? 0
                            : scoring->gap_open + (long)j * scoring->gap_extend;
      gap_b_scores[index] = min;
    }
  }

  // These are longs to force addition to be done with higher accuracy
  long gap_open_penalty = scoring->gap_extend + scoring->gap_open;
  long gap_extend_penalty = scoring->gap_extend;
  long substitution_penalty;

  // start at position [1][1]
  index_upleft = 0;
  index_up = 1;
  index_left = score_width;
  index = score_width+1;

  for(seq_j = 0; seq_j < len_j; seq_j++)
  {
    for(seq_i = 0; seq_i < len_i; seq_i++)
    {
      // Update match_scores[i][j] with position [i-1][j-1]
      // substitution penalty
      bool is_match;
      int tmp_penalty;

      scoring_lookup(scoring, aligner->seq_a[seq_i], aligner->seq_b[seq_j],
                     &tmp_penalty, &is_match);

      if(scoring->no_mismatches && !is_match)
      {
        match_scores[index] = min;
      }
      else
      {
        substitution_penalty = tmp_penalty; // cast to long

        // substitution
        // 1) continue alignment
        // 2) close gap in seq_a
        // 3) close gap in seq_b
        match_scores[index]
          = MAX4(match_scores[index_upleft] + substitution_penalty,
                 gap_a_scores[index_upleft] + substitution_penalty,
                 gap_b_scores[index_upleft] + substitution_penalty,
                 min);
      }

      // Long arithmetic since some INTs are set to min and penalty is -ve
      // (adding as ints would cause an integer overflow)

      // Update gap_a_scores[i][j] from position [i][j-1]
      if(seq_i == len_i-1 && scoring->no_end_gap_penalty)
      {
        gap_a_scores[index] = MAX3(match_scores[index_up],
                                   gap_a_scores[index_up],
                                   gap_b_scores[index_up]);
      }
      else if(!scoring->no_gaps_in_a || seq_i == len_i-1)
      {
        gap_a_scores[index]
          = MAX4(match_scores[index_up] + gap_open_penalty,
                 gap_a_scores[index_up] + gap_extend_penalty,
                 gap_b_scores[index_up] + gap_open_penalty,
                 min);
      }
      else
        gap_a_scores[index] = min;

      // Update gap_b_scores[i][j] from position [i-1][j]
      if(seq_j == len_j-1 && scoring->no_end_gap_penalty)
      {
        gap_b_scores[index] = MAX3(match_scores[index_left],
                                   gap_a_scores[index_left],
                                   gap_b_scores[index_left]);
      }
      else if(!scoring->no_gaps_in_b || seq_j == len_j-1)
      {
        gap_b_scores[index]
          = MAX4(match_scores[index_left] + gap_open_penalty,
                 gap_a_scores[index_left] + gap_open_penalty,
                 gap_b_scores[index_left] + gap_extend_penalty,
                 min);
      }
      else
        gap_b_scores[index] = min;

      index++;
      index_left++;
      index_up++;
      index_upleft++;
    }

    index++;
    index_left++;
    index_up++;
    index_upleft++;
  }
}
Пример #20
0
/*
 * Get the logical and ink extents of the specified string.
 */
static DFBResult
IDirectFBFont_GetStringExtents( IDirectFBFont *thiz,
                                const char *text, int bytes,
                                DFBRectangle *logical_rect,
                                DFBRectangle *ink_rect )
{
     DFBResult  ret;
     CoreFont  *font;
     int        xbaseline = 0;
     int        ybaseline = 0;


     DIRECT_INTERFACE_GET_DATA(IDirectFBFont)

     D_DEBUG_AT( Font, "%s( %p )\n", __FUNCTION__, thiz );


     if (!text)
          return DFB_INVARG;

     if (!logical_rect && !ink_rect)
          return DFB_INVARG;

     if (bytes < 0)
          bytes = strlen (text);

     if (ink_rect)
          memset (ink_rect, 0, sizeof (DFBRectangle));

     font = data->font;

     dfb_font_lock( font );

     if (bytes > 0) {
          int          i, num;
          unsigned int prev  = 0;
          unsigned int indices[bytes];

          /* Decode string to character indices. */
          ret = dfb_font_decode_text( font, data->encoding, text, bytes, indices, &num );
          if (ret) {
               dfb_font_unlock( font );
               return ret;
          }

          for (i=0; i<num; i++) {
               unsigned int   current = indices[i];
               CoreGlyphData *glyph;

               if (dfb_font_get_glyph_data( font, current, 0, &glyph ) == DFB_OK) {  // FIXME: support font layers
                    int kx, ky = 0;

                    if (prev && font->GetKerning &&
                        font->GetKerning( font, prev, current, &kx, &ky ) == DFB_OK) {
                         xbaseline += kx;
                         ybaseline += ky;
                    }

                    if (ink_rect) {
                         DFBRectangle glyph_rect = { xbaseline + glyph->left,
                              ybaseline + glyph->top,
                              glyph->width, glyph->height};
                         dfb_rectangle_union (ink_rect, &glyph_rect);
                    }

                    xbaseline += glyph->xadvance;
                    ybaseline += glyph->yadvance;
               }

               prev = current;
          }
     }

     if (logical_rect) {
          // We already have the text baseline vector in (xbaseline,ybaseline).
          // Now find the ascender and descender vectors:
          int xascender =  font->ascender * font->up_unit_x;
          int yascender =  font->ascender * font->up_unit_y;
          int xdescender = font->descender * font->up_unit_x;
          int ydescender = font->descender * font->up_unit_y;

          // Now find top/bottom left/right points relative to the text:
          int top_left_x     = xascender;
          int top_left_y     = yascender;
          int bottom_left_x  = xdescender;
          int bottom_left_y  = ydescender;
          int top_right_x    = top_left_x + xbaseline;
          int top_right_y    = top_left_y + ybaseline;
          int bottom_right_x = bottom_left_x + xbaseline;
          int bottom_right_y = bottom_left_y + ybaseline;

          // The logical rectangle is the bounding-box of these points:
#define MIN4(a,b,c,d) (MIN(MIN((a),(b)),MIN((c),(d))))
#define MAX4(a,b,c,d) (MAX(MAX((a),(b)),MAX((c),(d))))
          logical_rect->x = MIN4(top_left_x, bottom_left_x, top_right_x, bottom_right_x);
          logical_rect->y = MIN4(top_left_y, bottom_left_y, top_right_y, bottom_right_y);
          logical_rect->w = MAX4(top_left_x, bottom_left_x, top_right_x, bottom_right_x) - logical_rect->x;
          logical_rect->h = MAX4(top_left_y, bottom_left_y, top_right_y, bottom_right_y) - logical_rect->y;
     }

     if (ink_rect) {
          if (ink_rect->w < 0) {  /* PBE FIXME what is this doing? */
               ink_rect->x += ink_rect->w;
               ink_rect->w = -ink_rect->w;
          }
          ink_rect->x += font->ascender * font->up_unit_x;
          ink_rect->y += font->ascender * font->up_unit_y;
     }

     dfb_font_unlock( font );

     return DFB_OK;
}
Пример #21
0
float smith_waterman_custom(const char *str1, const char *str2, const void *v_conf) {

	const sub_cost_t *sub_cost = v_conf;

	float cost;
	float max_so_far = (float) 0;

	int n = strlen(str1);
	int m = strlen(str2);
	int i, j;

	if ((n == 0) || (m == 0))
		return ((float) 0);

	float d[n][m];

	for (i = 0; i < n; i++) {

		cost = sub_cost->cost_func(str1, i, str2, 0);

		if (i == 0)
			d[0][0] = MAX3((float)0, -sub_cost->cost->gap_cost, cost);
		else
			d[i][0] = MAX3(0, d[i - 1][0] - sub_cost->cost->gap_cost, cost);

		if (d[i][0] > max_so_far)
			max_so_far = d[i][0];

	}

	for (j = 0; j < m; j++) {

		cost = sub_cost->cost_func(str1, 0, str2, j);

		if (j == 0)
			d[0][0] = MAX3(0, -sub_cost->cost->gap_cost, cost);
		else
			d[0][j] = MAX3(0, d[0][j-1] - sub_cost->cost->gap_cost, cost);

		if (d[0][j] > max_so_far)
			max_so_far = d[0][j];

	}

	for (i = 1; i < n; i++) {

		for (j = 1; j < m; j++) {

			cost = sub_cost->cost_func(str1, i, str2, j);

			d[i][j] = MAX4((float)0, (d[i - 1][j] - sub_cost->cost->gap_cost), (d[i][j - 1] - sub_cost->cost->gap_cost), (d[i - 1][j - 1] + cost));

			if (d[i][j] > max_so_far)
				max_so_far = d[i][j];

		}

	}

	return (max_so_far);

}
Пример #22
0
static boolean
try_setup_line( struct lp_setup_context *setup,
               const float (*v1)[4],
               const float (*v2)[4])
{
   struct lp_scene *scene = setup->scene;
   const struct lp_setup_variant_key *key = &setup->setup.variant->key;
   struct lp_rast_triangle *line;
   struct lp_rast_plane *plane;
   struct lp_line_info info;
   float width = MAX2(1.0, setup->line_width);
   struct u_rect bbox;
   unsigned tri_bytes;
   int x[4]; 
   int y[4];
   int i;
   int nr_planes = 4;
   
   /* linewidth should be interpreted as integer */
   int fixed_width = util_iround(width) * FIXED_ONE;

   float x_offset=0;
   float y_offset=0;
   float x_offset_end=0;
   float y_offset_end=0;
      
   float x1diff;
   float y1diff;
   float x2diff;
   float y2diff;
   float dx, dy;
   float area;

   boolean draw_start;
   boolean draw_end;
   boolean will_draw_start;
   boolean will_draw_end;

   if (0)
      print_line(setup, v1, v2);

   if (setup->scissor_test) {
      nr_planes = 8;
   }
   else {
      nr_planes = 4;
   }


   dx = v1[0][0] - v2[0][0];
   dy = v1[0][1] - v2[0][1];
   area = (dx * dx  + dy * dy);
   if (area == 0) {
      LP_COUNT(nr_culled_tris);
      return TRUE;
   }

   info.oneoverarea = 1.0f / area;
   info.dx = dx;
   info.dy = dy;
   info.v1 = v1;
   info.v2 = v2;

  
   /* X-MAJOR LINE */
   if (fabsf(dx) >= fabsf(dy)) {
      float dydx = dy / dx;

      x1diff = v1[0][0] - (float) floor(v1[0][0]) - 0.5;
      y1diff = v1[0][1] - (float) floor(v1[0][1]) - 0.5;
      x2diff = v2[0][0] - (float) floor(v2[0][0]) - 0.5;
      y2diff = v2[0][1] - (float) floor(v2[0][1]) - 0.5;

      if (y2diff==-0.5 && dy<0){
         y2diff = 0.5;
      }
      
      /* 
       * Diamond exit rule test for starting point 
       */    
      if (fabsf(x1diff) + fabsf(y1diff) < 0.5) {
         draw_start = TRUE;
      }
      else if (sign(x1diff) == sign(-dx)) {
         draw_start = FALSE;
      }
      else if (sign(-y1diff) != sign(dy)) {
         draw_start = TRUE;
      }
      else {
         /* do intersection test */
         float yintersect = fracf(v1[0][1]) + x1diff * dydx;
         draw_start = (yintersect < 1.0 && yintersect > 0.0);
      }


      /* 
       * Diamond exit rule test for ending point 
       */    
      if (fabsf(x2diff) + fabsf(y2diff) < 0.5) {
         draw_end = FALSE;
      }
      else if (sign(x2diff) != sign(-dx)) {
         draw_end = FALSE;
      }
      else if (sign(-y2diff) == sign(dy)) {
         draw_end = TRUE;
      }
      else {
         /* do intersection test */
         float yintersect = fracf(v2[0][1]) + x2diff * dydx;
         draw_end = (yintersect < 1.0 && yintersect > 0.0);
      }

      /* Are we already drawing start/end?
       */
      will_draw_start = sign(-x1diff) != sign(dx);
      will_draw_end = (sign(x2diff) == sign(-dx)) || x2diff==0;

      if (dx < 0) {
         /* if v2 is to the right of v1, swap pointers */
         const float (*temp)[4] = v1;
         v1 = v2;
         v2 = temp;
         dx = -dx;
         dy = -dy;
         /* Otherwise shift planes appropriately */
         if (will_draw_start != draw_start) {
            x_offset_end = - x1diff - 0.5;
            y_offset_end = x_offset_end * dydx;

         }
         if (will_draw_end != draw_end) {
            x_offset = - x2diff - 0.5;
            y_offset = x_offset * dydx;
         }

      }
      else{
         /* Otherwise shift planes appropriately */
         if (will_draw_start != draw_start) {
            x_offset = - x1diff + 0.5;
            y_offset = x_offset * dydx;
         }
         if (will_draw_end != draw_end) {
            x_offset_end = - x2diff + 0.5;
            y_offset_end = x_offset_end * dydx;
         }
      }
  
      /* x/y positions in fixed point */
      x[0] = subpixel_snap(v1[0][0] + x_offset     - setup->pixel_offset);
      x[1] = subpixel_snap(v2[0][0] + x_offset_end - setup->pixel_offset);
      x[2] = subpixel_snap(v2[0][0] + x_offset_end - setup->pixel_offset);
      x[3] = subpixel_snap(v1[0][0] + x_offset     - setup->pixel_offset);
      
      y[0] = subpixel_snap(v1[0][1] + y_offset     - setup->pixel_offset) - fixed_width/2;
      y[1] = subpixel_snap(v2[0][1] + y_offset_end - setup->pixel_offset) - fixed_width/2;
      y[2] = subpixel_snap(v2[0][1] + y_offset_end - setup->pixel_offset) + fixed_width/2;
      y[3] = subpixel_snap(v1[0][1] + y_offset     - setup->pixel_offset) + fixed_width/2;
      
   }
   else {
      const float dxdy = dx / dy;

      /* Y-MAJOR LINE */      
      x1diff = v1[0][0] - (float) floor(v1[0][0]) - 0.5;
      y1diff = v1[0][1] - (float) floor(v1[0][1]) - 0.5;
      x2diff = v2[0][0] - (float) floor(v2[0][0]) - 0.5;
      y2diff = v2[0][1] - (float) floor(v2[0][1]) - 0.5;

      if (x2diff==-0.5 && dx<0) {
         x2diff = 0.5;
      }

      /* 
       * Diamond exit rule test for starting point 
       */    
      if (fabsf(x1diff) + fabsf(y1diff) < 0.5) {
         draw_start = TRUE;
      }
      else if (sign(-y1diff) == sign(dy)) {
         draw_start = FALSE;
      }
      else if (sign(x1diff) != sign(-dx)) {
         draw_start = TRUE;
      }
      else {
         /* do intersection test */
         float xintersect = fracf(v1[0][0]) + y1diff * dxdy;
         draw_start = (xintersect < 1.0 && xintersect > 0.0);
      }

      /* 
       * Diamond exit rule test for ending point 
       */    
      if (fabsf(x2diff) + fabsf(y2diff) < 0.5) {
         draw_end = FALSE;
      }
      else if (sign(-y2diff) != sign(dy) ) {
         draw_end = FALSE;
      }
      else if (sign(x2diff) == sign(-dx) ) {
         draw_end = TRUE;
      }
      else {
         /* do intersection test */
         float xintersect = fracf(v2[0][0]) + y2diff * dxdy;
         draw_end = (xintersect < 1.0 && xintersect >= 0.0);
      }

      /* Are we already drawing start/end?
       */
      will_draw_start = sign(y1diff) == sign(dy);
      will_draw_end = (sign(-y2diff) == sign(dy)) || y2diff==0;

      if (dy > 0) {
         /* if v2 is on top of v1, swap pointers */
         const float (*temp)[4] = v1;
         v1 = v2;
         v2 = temp; 
         dx = -dx;
         dy = -dy;

         /* Otherwise shift planes appropriately */
         if (will_draw_start != draw_start) {
            y_offset_end = - y1diff + 0.5;
            x_offset_end = y_offset_end * dxdy;
         }
         if (will_draw_end != draw_end) {
            y_offset = - y2diff + 0.5;
            x_offset = y_offset * dxdy;
         }
      }
      else {
         /* Otherwise shift planes appropriately */
         if (will_draw_start != draw_start) {
            y_offset = - y1diff - 0.5;
            x_offset = y_offset * dxdy;
                     
         }
         if (will_draw_end != draw_end) {
            y_offset_end = - y2diff - 0.5;
            x_offset_end = y_offset_end * dxdy;
         }
      }

      /* x/y positions in fixed point */
      x[0] = subpixel_snap(v1[0][0] + x_offset     - setup->pixel_offset) - fixed_width/2;
      x[1] = subpixel_snap(v2[0][0] + x_offset_end - setup->pixel_offset) - fixed_width/2;
      x[2] = subpixel_snap(v2[0][0] + x_offset_end - setup->pixel_offset) + fixed_width/2;
      x[3] = subpixel_snap(v1[0][0] + x_offset     - setup->pixel_offset) + fixed_width/2;
     
      y[0] = subpixel_snap(v1[0][1] + y_offset     - setup->pixel_offset); 
      y[1] = subpixel_snap(v2[0][1] + y_offset_end - setup->pixel_offset);
      y[2] = subpixel_snap(v2[0][1] + y_offset_end - setup->pixel_offset);
      y[3] = subpixel_snap(v1[0][1] + y_offset     - setup->pixel_offset);
   }



   LP_COUNT(nr_tris);

 
   /* Bounding rectangle (in pixels) */
   {
      /* Yes this is necessary to accurately calculate bounding boxes
       * with the two fill-conventions we support.  GL (normally) ends
       * up needing a bottom-left fill convention, which requires
       * slightly different rounding.
       */
      int adj = (setup->pixel_offset != 0) ? 1 : 0;

      bbox.x0 = (MIN4(x[0], x[1], x[2], x[3]) + (FIXED_ONE-1)) >> FIXED_ORDER;
      bbox.x1 = (MAX4(x[0], x[1], x[2], x[3]) + (FIXED_ONE-1)) >> FIXED_ORDER;
      bbox.y0 = (MIN4(y[0], y[1], y[2], y[3]) + (FIXED_ONE-1) + adj) >> FIXED_ORDER;
      bbox.y1 = (MAX4(y[0], y[1], y[2], y[3]) + (FIXED_ONE-1) + adj) >> FIXED_ORDER;

      /* Inclusive coordinates:
       */
      bbox.x1--;
      bbox.y1--;
   }

   if (bbox.x1 < bbox.x0 ||
       bbox.y1 < bbox.y0) {
      if (0) debug_printf("empty bounding box\n");
      LP_COUNT(nr_culled_tris);
      return TRUE;
   }

   if (!u_rect_test_intersection(&setup->draw_region, &bbox)) {
      if (0) debug_printf("offscreen\n");
      LP_COUNT(nr_culled_tris);
      return TRUE;
   }

   /* Can safely discard negative regions:
    */
   bbox.x0 = MAX2(bbox.x0, 0);
   bbox.y0 = MAX2(bbox.y0, 0);

   line = lp_setup_alloc_triangle(scene,
                                  key->num_inputs,
                                  nr_planes,
                                  &tri_bytes);
   if (!line)
      return FALSE;

#ifdef DEBUG
   line->v[0][0] = v1[0][0];
   line->v[1][0] = v2[0][0];   
   line->v[0][1] = v1[0][1];
   line->v[1][1] = v2[0][1];
#endif

   /* calculate the deltas */
   plane = GET_PLANES(line);
   plane[0].dcdy = x[0] - x[1];
   plane[1].dcdy = x[1] - x[2];
   plane[2].dcdy = x[2] - x[3];
   plane[3].dcdy = x[3] - x[0];

   plane[0].dcdx = y[0] - y[1];
   plane[1].dcdx = y[1] - y[2];
   plane[2].dcdx = y[2] - y[3];
   plane[3].dcdx = y[3] - y[0];


   /* Setup parameter interpolants:
    */
   info.a0 = GET_A0(&line->inputs);
   info.dadx = GET_DADX(&line->inputs);
   info.dady = GET_DADY(&line->inputs);
   setup_line_coefficients(setup, &info); 

   line->inputs.frontfacing = TRUE;
   line->inputs.disable = FALSE;
   line->inputs.opaque = FALSE;

   for (i = 0; i < 4; i++) {

      /* half-edge constants, will be interated over the whole render
       * target.
       */
      plane[i].c = plane[i].dcdx * x[i] - plane[i].dcdy * y[i];

      
      /* correct for top-left vs. bottom-left fill convention.  
       *
       * note that we're overloading gl_rasterization_rules to mean
       * both (0.5,0.5) pixel centers *and* bottom-left filling
       * convention.
       *
       * GL actually has a top-left filling convention, but GL's
       * notion of "top" differs from gallium's...
       *
       * Also, sometimes (in FBO cases) GL will render upside down
       * to its usual method, in which case it will probably want
       * to use the opposite, top-left convention.
       */         
      if (plane[i].dcdx < 0) {
         /* both fill conventions want this - adjust for left edges */
         plane[i].c++;            
      }
      else if (plane[i].dcdx == 0) {
         if (setup->pixel_offset == 0) {
            /* correct for top-left fill convention:
             */
            if (plane[i].dcdy > 0) plane[i].c++;
         }
         else {
            /* correct for bottom-left fill convention:
             */
            if (plane[i].dcdy < 0) plane[i].c++;
         }
      }

      plane[i].dcdx *= FIXED_ONE;
      plane[i].dcdy *= FIXED_ONE;

      /* find trivial reject offsets for each edge for a single-pixel
       * sized block.  These will be scaled up at each recursive level to
       * match the active blocksize.  Scaling in this way works best if
       * the blocks are square.
       */
      plane[i].eo = 0;
      if (plane[i].dcdx < 0) plane[i].eo -= plane[i].dcdx;
      if (plane[i].dcdy > 0) plane[i].eo += plane[i].dcdy;
   }


   /* 
    * When rasterizing scissored tris, use the intersection of the
    * triangle bounding box and the scissor rect to generate the
    * scissor planes.
    *
    * This permits us to cut off the triangle "tails" that are present
    * in the intermediate recursive levels caused when two of the
    * triangles edges don't diverge quickly enough to trivially reject
    * exterior blocks from the triangle.
    *
    * It's not really clear if it's worth worrying about these tails,
    * but since we generate the planes for each scissored tri, it's
    * free to trim them in this case.
    * 
    * Note that otherwise, the scissor planes only vary in 'C' value,
    * and even then only on state-changes.  Could alternatively store
    * these planes elsewhere.
    */
   if (nr_planes == 8) {
      const struct u_rect *scissor = &setup->scissor;

      plane[4].dcdx = -1;
      plane[4].dcdy = 0;
      plane[4].c = 1-scissor->x0;
      plane[4].eo = 1;

      plane[5].dcdx = 1;
      plane[5].dcdy = 0;
      plane[5].c = scissor->x1+1;
      plane[5].eo = 0;

      plane[6].dcdx = 0;
      plane[6].dcdy = 1;
      plane[6].c = 1-scissor->y0;
      plane[6].eo = 1;

      plane[7].dcdx = 0;
      plane[7].dcdy = -1;
      plane[7].c = scissor->y1+1;
      plane[7].eo = 0;
   }

   return lp_setup_bin_triangle(setup, line, &bbox, nr_planes);
}
Пример #23
0
static gboolean
gimp_perspective_clone_get_source (GimpSourceCore   *source_core,
                                   GimpDrawable     *drawable,
                                   GimpPaintOptions *paint_options,
                                   GimpPickable     *src_pickable,
                                   gint              src_offset_x,
                                   gint              src_offset_y,
                                   TempBuf          *paint_area,
                                   gint             *paint_area_offset_x,
                                   gint             *paint_area_offset_y,
                                   gint             *paint_area_width,
                                   gint             *paint_area_height,
                                   PixelRegion      *srcPR)
{
  GimpPerspectiveClone *clone      = GIMP_PERSPECTIVE_CLONE (source_core);
  GimpPaintCore        *paint_core = GIMP_PAINT_CORE (source_core);
  GimpSourceOptions    *options    = GIMP_SOURCE_OPTIONS (paint_options);
  GimpImage            *src_image;
  GimpImage            *image;
  GimpImageType         src_type;
  gint                  x1d, y1d, x2d, y2d;
  gdouble               x1s, y1s, x2s, y2s, x3s, y3s, x4s, y4s;
  gint                  xmin, ymin, xmax, ymax;
  TileManager          *src_tiles;
  TileManager          *orig_tiles;
  PixelRegion           origPR;
  PixelRegion           destPR;
  GimpMatrix3           matrix;
  gint                  bytes;

  src_image = gimp_pickable_get_image (src_pickable);
  image     = gimp_item_get_image (GIMP_ITEM (drawable));

  src_type  = gimp_pickable_get_image_type (src_pickable);
  src_tiles = gimp_pickable_get_tiles (src_pickable);

  /* Destination coordinates that will be painted */
  x1d = paint_area->x;
  y1d = paint_area->y;
  x2d = paint_area->x + paint_area->width;
  y2d = paint_area->y + paint_area->height;

  /* Boundary box for source pixels to copy: Convert all the vertex of
   * the box to paint in destination area to its correspondent in
   * source area bearing in mind perspective
   */
  gimp_perspective_clone_get_source_point (clone, x1d, y1d, &x1s, &y1s);
  gimp_perspective_clone_get_source_point (clone, x1d, y2d, &x2s, &y2s);
  gimp_perspective_clone_get_source_point (clone, x2d, y1d, &x3s, &y3s);
  gimp_perspective_clone_get_source_point (clone, x2d, y2d, &x4s, &y4s);

  xmin = floor (MIN4 (x1s, x2s, x3s, x4s));
  ymin = floor (MIN4 (y1s, y2s, y3s, y4s));
  xmax = ceil  (MAX4 (x1s, x2s, x3s, x4s));
  ymax = ceil  (MAX4 (y1s, y2s, y3s, y4s));

  xmin = CLAMP (xmin - 1, 0, tile_manager_width  (src_tiles));
  ymin = CLAMP (ymin - 1, 0, tile_manager_height (src_tiles));
  xmax = CLAMP (xmax + 1, 0, tile_manager_width  (src_tiles));
  ymax = CLAMP (ymax + 1, 0, tile_manager_height (src_tiles));

  /* if the source area is completely out of the image */
  if (!(xmax - xmin) || !(ymax - ymin))
    return FALSE;

  /*  If the source image is different from the destination,
   *  then we should copy straight from the source image
   *  to the canvas.
   *  Otherwise, we need a call to get_orig_image to make sure
   *  we get a copy of the unblemished (offset) image
   */
  if ((  options->sample_merged && (src_image                 != image)) ||
      (! options->sample_merged && (source_core->src_drawable != drawable)))
    {
      pixel_region_init (&origPR, src_tiles,
                         xmin, ymin, xmax - xmin, ymax - ymin, FALSE);
    }
  else
    {
      TempBuf *orig;

      /*  get the original image  */
      if (options->sample_merged)
        orig = gimp_paint_core_get_orig_proj (paint_core,
                                              src_pickable,
                                              xmin, ymin, xmax, ymax);
      else
        orig = gimp_paint_core_get_orig_image (paint_core,
                                               GIMP_DRAWABLE (src_pickable),
                                               xmin, ymin, xmax, ymax);

      pixel_region_init_temp_buf (&origPR, orig,
                                  0, 0, xmax - xmin, ymax - ymin);
    }

  /*  copy the original image to a tile manager, adding alpha if needed  */

  bytes = GIMP_IMAGE_TYPE_BYTES (GIMP_IMAGE_TYPE_WITH_ALPHA (src_type));

  orig_tiles = tile_manager_new (xmax - xmin, ymax - ymin, bytes);

  tile_manager_set_offsets (orig_tiles, xmin, ymin);

  pixel_region_init (&destPR, orig_tiles,
                     0, 0, xmax - xmin, ymax - ymin,
                     TRUE);

  if (bytes > origPR.bytes)
    add_alpha_region (&origPR, &destPR);
  else
    copy_region (&origPR, &destPR);

  clone->src_area = temp_buf_resize (clone->src_area,
                                     tile_manager_bpp (orig_tiles),
                                     0, 0,
                                     x2d - x1d, y2d - y1d);

  pixel_region_init_temp_buf (&destPR, clone->src_area,
                              0, 0,
                              x2d - x1d, y2d - y1d);

  gimp_perspective_clone_get_matrix (clone, &matrix);

  gimp_transform_region (src_pickable,
                         GIMP_CONTEXT (paint_options),
                         orig_tiles,
                         &destPR,
                         x1d, y1d, x2d, y2d,
                         &matrix,
                         GIMP_INTERPOLATION_LINEAR, 0, NULL);

  tile_manager_unref (orig_tiles);

  pixel_region_init_temp_buf (srcPR, clone->src_area,
                              0, 0, x2d - x1d, y2d - y1d);

  return TRUE;
}
Пример #24
0
float custom_smith_waterman_gotoh(const char *str1, const char *str2, const w_comp_idx_cost_t *conf) {

	float cost;
	float max_so_far = 0;
	float max_gap_cost = 0;
	float max_gap_cost1 = 0;
	float max_gap_cost2 = 0;

	int n = strlen(str1);
	int m = strlen(str2);
	int i, j, k, w_st;

	if ((n == 0) || (m == 0))
		return (float) 0;

	float d[n][m];

	for (i = 0; i < n; i++) {

		cost = conf->comp_conf->sub_cost->cost_func(str1, i, str2, 0);

		if (i == 0)
			d[0][0] = MAX(0, cost);
		else {

			w_st = i - conf->win_size;

			if (w_st < 1)
				w_st = 1;

			for (k = w_st; k < i; k++)
				max_gap_cost = MAX(max_gap_cost, d[i - k][0] - conf->comp_conf->gap_cost->cost_func(i - k, i));

			d[i][0] = MAX3(0, max_gap_cost, cost);

		}

		if (d[i][0] > max_so_far)
			max_so_far = d[i][0];

	}

	for (j = 0; j < m; j++) {

		cost = conf->comp_conf->sub_cost->cost_func(str1, 0, str2, j);

		if (j == 0)
			d[0][0] = MAX(0, cost);
		else {

			max_gap_cost = 0;
			w_st = j - conf->win_size;

			if (w_st < 1)
				w_st = 1;

			for (k = w_st; k < j; k++)
				max_gap_cost = MAX(max_gap_cost, d[0][j - k] - conf->comp_conf->gap_cost->cost_func(j - k, j));

			d[0][j] = MAX3(0, max_gap_cost, cost);

		}

		if (d[0][j] > max_so_far)
			max_so_far = d[0][j];

	}

	for (i = 1; i < n; i++) {

		for (j = 1; j < m; j++) {

			cost = conf->comp_conf->sub_cost->cost_func(str1, i, str2, j);
			w_st = i - conf->win_size;

			if (w_st < 1)
				w_st = 1;

			for (k = w_st; k < i; k++)
				max_gap_cost1 = MAX(max_gap_cost1, d[i - k][j] - conf->comp_conf->gap_cost->cost_func(i - k, i));

			w_st = j - conf->win_size;

			if (w_st < 1)
				w_st = 1;

			for (k = w_st; k < j; k++)
				max_gap_cost2 = MAX(max_gap_cost2, d[i][j-k] - conf->comp_conf->gap_cost->cost_func(j - k, j));

			d[i][j] = MAX4(0, max_gap_cost1, max_gap_cost2, d[i - 1][j - 1] + cost);

			if (d[i][j] > max_so_far)
				max_so_far = d[i][j];

		}

	}

	return max_so_far;

}
Пример #25
0
/*
从三个备份中读出一个备份的数据
*/
void ReadThreeBackupEnergy(uint ReadAdd1, uint ReadAdd2, uint ReadAdd3, uchar len, uint BackupErrAdd, uint BackupALLErrAdd, uchar *pOut)
{
	uchar bkBlockFlg = 0, bkBlockOk=0, i, tmp;
	uint eeAddr[3] = {ReadAdd1, ReadAdd2, ReadAdd3};
	uchar bkbuf[12];
	
	LowVoltage = 0x55;
	ThreeBferro = 0x55;
	WDTE = 0xAC;
	
	if(0 == len)	
	{
		return;
	}
	
	//检查三个备份的数据是否正确,记录在bkBlockFlg中
	for(i=0; i<3; i++)
	{
		BackupErrAdd += 2*i;	//BackupErrAdd的使用情况?E2分配情况?
		Read512(bkbuf+4*i, eeAddr[i], len);
		tmp = Check_CS(bkbuf+4*i, len);	//检查校验值
		if(TRUE == tmp)
		{
			bkBlockFlg |= (0x01<<i);
		}
		else
		{
			bkBlockFlg &= ~(0x01<<i);
			E2PINC(BackupErrAdd, 2);	//对应的错误记录加1
		}
	}
	
	//三个备份数据都错误
	if(0x00 == bkBlockFlg)
	{
		E2PINC(BackupALLErrAdd, 2);
		ThreeBferro = 0xAA;
	}
	
	switch(bkBlockFlg)
	{
		case 0x00:			//三备份数据都错误,默认从第一备份读(?)
			bkBlockOk = BK_1ST;
			IndexEnergyBackup = BK_2ND;
			Eeprom_err = Eeprom_err | 4;	//用于错误显示等
			break;
		
		case 0x01:			//只第一备份正确
			bkBlockOk = BK_1ST;
			IndexEnergyBackup = BK_2ND;
			break;
			
		case 0x02:
			bkBlockOk = BK_2ND;
			IndexEnergyBackup = BK_3RD;
			break;
		
		case 0x04:
			bkBlockOk = BK_3RD;
			IndexEnergyBackup = BK_1ST;
			break;
			
		case 0x03:		//第一、二备份正确
			if(TRUE == Max3(bkbuf, bkbuf+4, 4))	//这个函数后续也改一下命名吧...
			{
				bkBlockOk = BK_1ST;
			}
			else
			{
				bkBlockOk = BK_2ND;
			}
			IndexEnergyBackup = BK_3RD;
			break;
			
		case 0x05:		//第一、三备份正确
			if(TRUE == MAX3(bkbuf, bkbuf+8, 4))
			{
				bkBlockOk = BK_1ST;
			}
			else
			{
				bkBlockOk = BK_3RD;
			}
			IndexEnergyBackup = BK_2ND;
			break;
		
		case 0x06:		//第二、三备份正确
			if(TRUE == MAX3(bkbuf+4, bkbuf+8, 4))
			{
				bkBlockOk = BK_2ND;
			}
			else
			{
				bkBlockOk = BK_3RD;
			}
			IndexEnergyBackup = BK_1ST;
			break;
		
		case 0x07:		//三备份都正确
			tmp = MAX4(bkbuf, bkbuf+4, bkbuf+8, 4);		//比较三备份谁比较大
			if(0x01 == tmp)
			{
				bkBlockOk = BK_1ST;
				IndexEnergyBackup = BK_2ND;
			}
			if(0x02 == tmp)
			{
				bkBlockOk = BK_2ND;
				IndexEnergyBackup = BK_3RD;
			}
			if(0x03 == tmp)
			{
				bkBlockOk = BK_3RD;
				IndexEnergyBackup = BK_1ST;
			}
			break;
		
		default:
			bkBlockOk = BK_1ST;
			break;
	}
	
	switch(bkBlockOk)
	{
		case BK_1ST:
			xmemcpy(bkbuf, pOut, len);
			break;
		
		case BK_2ND:
			xmemcpy(bkbuf+4, pOut, len);
			break;
		
		case BK_3RD:
			xmemcpy(bkbuf+8, pOut, len);
			break;
		default:
			break;
	}
}
Пример #26
0
inline wg_v4sf Recognizer::dtw4(float *s, unsigned int n, 
                                float *t0, unsigned int m0,
                                float *t1, unsigned int m1,
                                float *t2, unsigned int m2,
                                float *t3, unsigned int m3) {
    /*
    Compare an input sequence with 4 reference sequences.

    For one column of the DTW matrix, MIN4(m0,m1,m2,m3) cells are calculated
    using vector instructions. The rest of the cells are calculated
    sequentially.

    s: input sequence
    n: number of vectors in s

    t0..t3: reference sequences
    m0..m3: number of vectors in the sequence
    */
    unsigned int i, j, common;
    wg_v4sf cost;
    float costf;
    float *t_start0, *t_start1, *t_start2, *t_start3;
    wg_v4sf *tmp;
    wg_v4sf res;

    t_start0 = t0; t_start1 = t1; t_start2 = t2; t_start3 = t3;

    /* Initialize the edge cells */
    dtw1v[0].v = _mm_set_ps1(0);
    dtw2v[0].v = _mm_set_ps1(FLT_MAX);

    for (i=1; i < MAX4(m0,m1,m2,m3); i++)
        dtw1v[i].v = _mm_set_ps1(FLT_MAX);

    s += VEC_DIM_MAX;
   
    common = MIN4(m0,m1,m2,m3);

    /* Iterate over columns */
    for (i=1; i < n; i++) {
        t0 = t_start0 + VEC_DIM_MAX; t1 = t_start1 + VEC_DIM_MAX;
        t2 = t_start2 + VEC_DIM_MAX; t3 = t_start3 + VEC_DIM_MAX;

        /* Iterate over cells of that column */
        /* Process 4 cells at a time in parallel */
        for (j=1; j < common; j++) {
            cost = local_distance4(s, t0, t1, t2, t3);
            /* Inductive step */
            dtw2v[j].v = _mm_add_ps(cost.v,
                                MIN3VEC(dtw2v[j-1].v,dtw1v[j].v,dtw1v[j-1].v));

            t0 += VEC_DIM_MAX; t1 += VEC_DIM_MAX;
            t2 += VEC_DIM_MAX; t3 += VEC_DIM_MAX;
        }

        /* The remaining of cells is calculated sequentially */
        DTW4_PROCESS_REMAINING(0, m0, t0);
        DTW4_PROCESS_REMAINING(1, m1, t1);
        DTW4_PROCESS_REMAINING(2, m2, t2);
        DTW4_PROCESS_REMAINING(3, m3, t3);

        SWAP(dtw1v,dtw2v,tmp);
        dtw2v[0].v = _mm_set_ps1(FLT_MAX);

        s += VEC_DIM_MAX;
    }

    res.s[0] = dtw1v[m0-1].s[0]; res.s[1] = dtw1v[m1-1].s[1];
    res.s[2] = dtw1v[m2-1].s[2]; res.s[3] = dtw1v[m3-1].s[3];
    
    return res;
}
Пример #27
0
/* this takes the smallest ortho-aligned (the sides of the rectangle are
 * parallel to the x- and y-axis) rectangle fitting around the points a to d,
 * checks if the whole rectangle is inside the polygon described by points and
 * writes it to r if the area is bigger than the rectangle already stored in r.
 */
static void
add_rectangle (Point      points[4],
               Rectangle *r,
               Point      a,
               Point      b,
               Point      c,
               Point      d)
{
  gdouble width;
  gdouble height;
  gdouble minx, maxx;
  gdouble miny, maxy;

  /* get the orthoaligned (the sides of the rectangle are parallel to the x-
   * and y-axis) rectangle surrounding the points a to d.
   */
  minx = MIN4 (a.x, b.x, c.x, d.x);
  maxx = MAX4 (a.x, b.x, c.x, d.x);
  miny = MIN4 (a.y, b.y, c.y, d.y);
  maxy = MAX4 (a.y, b.y, c.y, d.y);

  a.x = minx;
  a.y = miny;

  b.x = maxx;
  b.y = miny;

  c.x = maxx;
  c.y = maxy;

  d.x = minx;
  d.y = maxy;

  width  =  maxx - minx;
  height =  maxy - miny;

  /* check if this rectangle is inside the polygon "points" */
  if (in_poly (points, a) &&
      in_poly (points, b) &&
      in_poly (points, c) &&
      in_poly (points, d))
    {
      gdouble area = width * height;

      /* check if the new rectangle is larger (in terms of area)
       * than the currently stored rectangle in r, if yes store
       * new rectangle to r
       */
      if (r->area <= area)
        {
          r->a.x = a.x;
          r->a.y = a.y;

          r->b.x = b.x;
          r->b.y = b.y;

          r->c.x = c.x;
          r->c.y = c.y;

          r->d.x = d.x;
          r->d.y = d.y;

          r->area = area;
        }
    }
}
Пример #28
0
cholmod_sparse *CHOLMOD(ssmult)
(
    /* ---- input ---- */
    cholmod_sparse *A,	/* left matrix to multiply */
    cholmod_sparse *B,	/* right matrix to multiply */
    int stype,		/* requested stype of C */
    int values,		/* TRUE: do numerical values, FALSE: pattern only */
    int sorted,		/* if TRUE then return C with sorted columns */
    /* --------------- */
    cholmod_common *Common
)
{
    double bjt ;
    double *Ax, *Bx, *Cx, *W ;
    Int *Ap, *Anz, *Ai, *Bp, *Bnz, *Bi, *Cp, *Ci, *Flag ;
    cholmod_sparse *C, *A2, *B2, *A3, *B3, *C2 ;
    Int apacked, bpacked, j, i, pa, paend, pb, pbend, ncol, mark, cnz, t, p,
        nrow, anz, bnz, do_swap_and_transpose, n1, n2 ;

    /* ---------------------------------------------------------------------- */
    /* check inputs */
    /* ---------------------------------------------------------------------- */

    RETURN_IF_NULL_COMMON (NULL) ;
    RETURN_IF_NULL (A, NULL) ;
    RETURN_IF_NULL (B, NULL) ;
    values = values &&
             (A->xtype != CHOLMOD_PATTERN) && (B->xtype != CHOLMOD_PATTERN) ;
    RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN,
                             values ? CHOLMOD_REAL : CHOLMOD_ZOMPLEX, NULL) ;
    RETURN_IF_XTYPE_INVALID (B, CHOLMOD_PATTERN,
                             values ? CHOLMOD_REAL : CHOLMOD_ZOMPLEX, NULL) ;
    if (A->ncol != B->nrow)
    {
        /* inner dimensions must agree */
        ERROR (CHOLMOD_INVALID, "A and B inner dimensions must match") ;
        return (NULL) ;
    }
    /* A and B must have the same numerical type if values is TRUE (both must
     * be CHOLMOD_REAL, this is implicitly checked above) */
    Common->status = CHOLMOD_OK ;

    /* ---------------------------------------------------------------------- */
    /* allocate workspace */
    /* ---------------------------------------------------------------------- */

    if (A->nrow <= 1)
    {
        /* C will be implicitly sorted, so no need to sort it here */
        sorted = FALSE ;
    }
    if (sorted)
    {
        n1 = MAX (A->nrow, B->ncol) ;
    }
    else
    {
        n1 = A->nrow ;
    }
    n2 = MAX4 (A->ncol, A->nrow, B->nrow, B->ncol) ;
    CHOLMOD(allocate_work) (n1, n2, values ? n1 : 0, Common) ;
    if (Common->status < CHOLMOD_OK)
    {
        /* out of memory */
        return (NULL) ;
    }
    ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n1 : 0, Common)) ;

    /* ---------------------------------------------------------------------- */
    /* get inputs */
    /* ---------------------------------------------------------------------- */

    /* convert A to unsymmetric, if necessary */
    A2 = NULL ;
    B2 = NULL ;
    if (A->stype)
    {
        /* workspace: Iwork (max (A->nrow,A->ncol)) */
        A2 = CHOLMOD(copy) (A, 0, values, Common) ;
        if (Common->status < CHOLMOD_OK)
        {
            /* out of memory */
            ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n1:0, Common)) ;
            return (NULL) ;
        }
        A = A2 ;
    }

    /* convert B to unsymmetric, if necessary */
    if (B->stype)
    {
        /* workspace: Iwork (max (B->nrow,B->ncol)) */
        B2 = CHOLMOD(copy) (B, 0, values, Common) ;
        if (Common->status < CHOLMOD_OK)
        {
            /* out of memory */
            CHOLMOD(free_sparse) (&A2, Common) ;
            ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n1:0, Common)) ;
            return (NULL) ;
        }
        B = B2 ;
    }

    ASSERT (CHOLMOD(dump_sparse) (A, "A", Common) >= 0) ;
    ASSERT (CHOLMOD(dump_sparse) (B, "B", Common) >= 0) ;

    /* get the A matrix */
    Ap  = A->p ;
    Anz = A->nz ;
    Ai  = A->i ;
    Ax  = A->x ;
    apacked = A->packed ;

    /* get the B matrix */
    Bp  = B->p ;
    Bnz = B->nz ;
    Bi  = B->i ;
    Bx  = B->x ;
    bpacked = B->packed ;

    /* get the size of C */
    nrow = A->nrow ;
    ncol = B->ncol ;

    /* get workspace */
    W = Common->Xwork ;		/* size nrow, unused if values is FALSE */
    Flag = Common->Flag ;	/* size nrow, Flag [0..nrow-1] < mark on input*/

    /* ---------------------------------------------------------------------- */
    /* count the number of entries in the result C */
    /* ---------------------------------------------------------------------- */

    cnz = 0 ;
    for (j = 0 ; j < ncol ; j++)
    {
        /* clear the Flag array */
        /* mark = CHOLMOD(clear_flag) (Common) ; */
        CHOLMOD_CLEAR_FLAG (Common) ;
        mark = Common->mark ;

        /* for each nonzero B(t,j) in column j, do: */
        pb = Bp [j] ;
        pbend = (bpacked) ? (Bp [j+1]) : (pb + Bnz [j]) ;
        for ( ; pb < pbend ; pb++)
        {
            /* B(t,j) is nonzero */
            t = Bi [pb] ;

            /* add the nonzero pattern of A(:,t) to the pattern of C(:,j) */
            pa = Ap [t] ;
            paend = (apacked) ? (Ap [t+1]) : (pa + Anz [t]) ;
            for ( ; pa < paend ; pa++)
            {
                i = Ai [pa] ;
                if (Flag [i] != mark)
                {
                    Flag [i] = mark ;
                    cnz++ ;
                }
            }
        }
        if (cnz < 0)
        {
            break ;	    /* integer overflow case */
        }
    }

    /* mark = CHOLMOD(clear_flag) (Common) ; */
    CHOLMOD_CLEAR_FLAG (Common) ;
    mark = Common->mark ;

    /* ---------------------------------------------------------------------- */
    /* check for integer overflow */
    /* ---------------------------------------------------------------------- */

    if (cnz < 0)
    {
        ERROR (CHOLMOD_TOO_LARGE, "problem too large") ;
        CHOLMOD(free_sparse) (&A2, Common) ;
        CHOLMOD(free_sparse) (&B2, Common) ;
        ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n1:0, Common)) ;
        return (NULL) ;
    }

    /* ---------------------------------------------------------------------- */
    /* Determine how to return C sorted (if requested) */
    /* ---------------------------------------------------------------------- */

    do_swap_and_transpose = FALSE ;

    if (sorted)
    {
        /* Determine the best way to return C with sorted columns.  Computing
         * C = (B'*A')' takes cnz + anz + bnz time (ignoring O(n) terms).
         * Sorting C when done, C = (A*B)'', takes 2*cnz time.  Pick the one
         * with the least amount of work. */

        anz = CHOLMOD(nnz) (A, Common) ;
        bnz = CHOLMOD(nnz) (B, Common) ;

        do_swap_and_transpose = (anz + bnz < cnz) ;

        if (do_swap_and_transpose)
        {

            /* -------------------------------------------------------------- */
            /* C = (B'*A')' */
            /* -------------------------------------------------------------- */

            /* workspace: Iwork (A->nrow) */
            A3 = CHOLMOD(ptranspose) (A, values, NULL, NULL, 0, Common) ;
            CHOLMOD(free_sparse) (&A2, Common) ;
            A2 = A3 ;
            if (Common->status < CHOLMOD_OK)
            {
                /* out of memory */
                CHOLMOD(free_sparse) (&A2, Common) ;
                CHOLMOD(free_sparse) (&B2, Common) ;
                ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n1:0, Common));
                return (NULL) ;
            }
            /* workspace: Iwork (B->nrow) */
            B3 = CHOLMOD(ptranspose) (B, values, NULL, NULL, 0, Common) ;
            CHOLMOD(free_sparse) (&B2, Common) ;
            B2 = B3 ;
            if (Common->status < CHOLMOD_OK)
            {
                /* out of memory */
                CHOLMOD(free_sparse) (&A2, Common) ;
                CHOLMOD(free_sparse) (&B2, Common) ;
                ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n1:0, Common));
                return (NULL) ;
            }
            A = B2 ;
            B = A2 ;

            /* get the new A matrix */
            Ap  = A->p ;
            Anz = A->nz ;
            Ai  = A->i ;
            Ax  = A->x ;
            apacked = A->packed ;

            /* get the new B matrix */
            Bp  = B->p ;
            Bnz = B->nz ;
            Bi  = B->i ;
            Bx  = B->x ;
            bpacked = B->packed ;

            /* get the size of C' */
            nrow = A->nrow ;
            ncol = B->ncol ;
        }
    }

    /* ---------------------------------------------------------------------- */
    /* allocate C */
    /* ---------------------------------------------------------------------- */

    C = CHOLMOD(allocate_sparse) (nrow, ncol, cnz, FALSE, TRUE, 0,
                                  values ? A->xtype : CHOLMOD_PATTERN, Common) ;
    if (Common->status < CHOLMOD_OK)
    {
        /* out of memory */
        CHOLMOD(free_sparse) (&A2, Common) ;
        CHOLMOD(free_sparse) (&B2, Common) ;
        ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n1:0, Common)) ;
        return (NULL) ;
    }

    Cp = C->p ;
    Ci = C->i ;
    Cx = C->x ;

    /* ---------------------------------------------------------------------- */
    /* C = A*B */
    /* ---------------------------------------------------------------------- */

    cnz = 0 ;

    if (values)
    {

        /* pattern and values */
        for (j = 0 ; j < ncol ; j++)
        {
            /* clear the Flag array */
            /* mark = CHOLMOD(clear_flag (Common)) ; */
            CHOLMOD_CLEAR_FLAG (Common) ;
            mark = Common->mark ;

            /* start column j of C */
            Cp [j] = cnz ;

            /* for each nonzero B(t,j) in column j, do: */
            pb = Bp [j] ;
            pbend = (bpacked) ? (Bp [j+1]) : (pb + Bnz [j]) ;
            for ( ; pb < pbend ; pb++)
            {
                /* B(t,j) is nonzero */
                t = Bi [pb] ;
                bjt = Bx [pb] ;

                /* add the nonzero pattern of A(:,t) to the pattern of C(:,j)
                 * and scatter the values into W */
                pa = Ap [t] ;
                paend = (apacked) ? (Ap [t+1]) : (pa + Anz [t]) ;
                for ( ; pa < paend ; pa++)
                {
                    i = Ai [pa] ;
                    if (Flag [i] != mark)
                    {
                        Flag [i] = mark ;
                        Ci [cnz++] = i ;
                    }
                    W [i] += Ax [pa] * bjt ;
                }
            }

            /* gather the values into C(:,j) */
            for (p = Cp [j] ; p < cnz ; p++)
            {
                i = Ci [p] ;
                Cx [p] = W [i] ;
                W [i] = 0 ;
            }
        }

    }
    else
    {

        /* pattern only */
        for (j = 0 ; j < ncol ; j++)
        {
            /* clear the Flag array */
            /* mark = CHOLMOD(clear_flag) (Common) ; */
            CHOLMOD_CLEAR_FLAG (Common) ;
            mark = Common->mark ;

            /* start column j of C */
            Cp [j] = cnz ;

            /* for each nonzero B(t,j) in column j, do: */
            pb = Bp [j] ;
            pbend = (bpacked) ? (Bp [j+1]) : (pb + Bnz [j]) ;
            for ( ; pb < pbend ; pb++)
            {
                /* B(t,j) is nonzero */
                t = Bi [pb] ;

                /* add the nonzero pattern of A(:,t) to the pattern of C(:,j) */
                pa = Ap [t] ;
                paend = (apacked) ? (Ap [t+1]) : (pa + Anz [t]) ;
                for ( ; pa < paend ; pa++)
                {
                    i = Ai [pa] ;
                    if (Flag [i] != mark)
                    {
                        Flag [i] = mark ;
                        Ci [cnz++] = i ;
                    }
                }
            }
        }
    }

    Cp [ncol] = cnz ;
    ASSERT (MAX (1,cnz) == C->nzmax) ;

    /* ---------------------------------------------------------------------- */
    /* clear workspace and free temporary matrices */
    /* ---------------------------------------------------------------------- */

    CHOLMOD(free_sparse) (&A2, Common) ;
    CHOLMOD(free_sparse) (&B2, Common) ;
    /* CHOLMOD(clear_flag) (Common) ; */
    CHOLMOD_CLEAR_FLAG (Common) ;
    ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n1:0, Common)) ;

    /* ---------------------------------------------------------------------- */
    /* convert C to a symmetric upper/lower matrix if requested */
    /* ---------------------------------------------------------------------- */

    /* convert C in place, which cannot fail since no memory is allocated */
    if (stype > 0)
    {
        /* C = triu (C), in place */
        (void) CHOLMOD(band_inplace) (0, ncol, values, C, Common) ;
        C->stype = 1 ;
    }
    else if (stype < 0)
    {
        /* C = tril (C), in place */
        (void) CHOLMOD(band_inplace) (-nrow, 0, values, C, Common) ;
        C->stype = -1 ;
    }
    ASSERT (Common->status >= CHOLMOD_OK) ;

    /* ---------------------------------------------------------------------- */
    /* sort C, if requested */
    /* ---------------------------------------------------------------------- */

    if (sorted)
    {
        if (do_swap_and_transpose)
        {
            /* workspace: Iwork (C->ncol), which is A->nrow since C=(B'*A') */
            C2 = CHOLMOD(ptranspose) (C, values, NULL, NULL, 0, Common) ;
            CHOLMOD(free_sparse) (&C, Common) ;
            if (Common->status < CHOLMOD_OK)
            {
                /* out of memory */
                ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n1:0, Common));
                return (NULL) ;
            }
            C = C2 ;
        }
        else
        {
            /* workspace: Iwork (max (C->nrow,C->ncol)) */
            if (!CHOLMOD(sort) (C, Common))
            {
                /* out of memory */
                CHOLMOD(free_sparse) (&C, Common) ;
                ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n1:0, Common));
                return (NULL) ;
            }
        }
    }

    /* ---------------------------------------------------------------------- */
    /* return result */
    /* ---------------------------------------------------------------------- */

    DEBUG (CHOLMOD(dump_sparse) (C, "ssmult", Common) >= 0) ;
    ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, values ? n1:0, Common)) ;
    return (C) ;
}
Пример #29
0
/*
 * The state machine looks for (approximately) these Perl regular expressions:
 *
 *    m|\/\*.*?\*\/|
 *    m|\/\/.*|
 *    m|'.*?'|
 *    m|".*?"|
 *    m|#\s*include\s*"(.*?)"|
 *    m|#\s*include\s*<(.*?>"|
 *
 * About 98% of the CPU time is spent here, and most of that is in
 * the 'start' paragraph.  Because the current characters are
 * in a register, the start loop usually eats 4 or 8 characters
 * per memory read.  The MAX4 and MIN4 tests dispose of most
 * input characters with 1 or 2 comparisons.
 */
void state_machine(const char * map, const char * end)
{
    const char * next = map;
    const char * map_dot;
    unsigned long __buf = 0;

    for (;;) {
start:
        GETNEXT
__start:
        if (current > MAX4('/','\'','"','#')) goto start;
        if (current < MIN4('/','\'','"','#')) goto start;
        CASE('/',  slash);
        CASE('\'', squote);
        CASE('"',  dquote);
        CASE('#',  pound);
        goto start;

        /* // */
slash_slash:
        GETNEXT
        CASE('\n', start);
        NOTCASE('\\', slash_slash);
        GETNEXT
        goto slash_slash;

        /* / */
slash:
        GETNEXT
        CASE('/',  slash_slash);
        NOTCASE('*', __start);
slash_star_dot_star:
        GETNEXT
__slash_star_dot_star:
        NOTCASE('*', slash_star_dot_star);
        GETNEXT
        NOTCASE('/', __slash_star_dot_star);
        goto start;

        /* '.*?' */
squote:
        GETNEXT
        CASE('\'', start);
        NOTCASE('\\', squote);
        GETNEXT
        goto squote;

        /* ".*?" */
dquote:
        GETNEXT
        CASE('"', start);
        NOTCASE('\\', dquote);
        GETNEXT
        goto dquote;

        /* #\s* */
pound:
        GETNEXT
        CASE(' ',  pound);
        CASE('\t', pound);
        CASE('i',  pound_i);
        goto __start;

        /* #\s*i */
pound_i:
        GETNEXT NOTCASE('n', __start);
        GETNEXT NOTCASE('c', __start);
        GETNEXT NOTCASE('l', __start);
        GETNEXT NOTCASE('u', __start);
        GETNEXT NOTCASE('d', __start);
        GETNEXT NOTCASE('e', __start);
        goto pound_include;

        /* #\s*include\s* */
pound_include:
        GETNEXT
        CASE(' ',  pound_include);
        CASE('\t', pound_include);
        map_dot = next;
        CASE('"',  pound_include_dquote);
        CASE('<',  pound_include_langle);
        goto __start;

        /* #\s*include\s*"(.*)" */
pound_include_dquote:
        GETNEXT
        CASE('\n', start);
        NOTCASE('"', pound_include_dquote);
        handle_include(0, map_dot, next - map_dot - 1);
        goto start;

        /* #\s*include\s*<(.*)> */
pound_include_langle:
        GETNEXT
        CASE('\n', start);
        NOTCASE('>', pound_include_langle);
        handle_include(1, map_dot, next - map_dot - 1);
        goto start;
    }
}
Пример #30
0
int main( int argc, char** argv ){
  
  FILE *ifp;

  gray maxval;
  int cols, rows, format;

  gray* prevrow;
  gray* thisrow;
  gray* tmprow;
  
  int* countTile;   
  int* countEdgeX;  
  int* countEdgeY; 
  int* countVertex; 

  int i, col, row;

  int maxtiles, maxedgex, maxedgey, maxvertex;
  int area, perimeter, eulerchi;

  double l2inv, linv;

  /*
   * parse arg and initialize
   */ 

  pgm_init( &argc, argv );

  if ( argc > 2 ) pm_usage( "[pgmfile]" );
  
  if ( argc == 2 )
    ifp = pm_openr( argv[1] );
  else
    ifp = stdin;

  /*
   * initialize
   */

  pgm_readpgminit( ifp, &cols, &rows, &maxval, &format );
  
  prevrow = pgm_allocrow( cols );
  thisrow = pgm_allocrow( cols );
  
  MALLOCARRAY(countTile   , maxval + 1 );
  MALLOCARRAY(countEdgeX  , maxval + 1 );
  MALLOCARRAY(countEdgeY  , maxval + 1 );
  MALLOCARRAY(countVertex , maxval + 1 );
 
  if (countTile == NULL || countEdgeX == NULL || countEdgeY == NULL ||
      countVertex == NULL)
      pm_error( "out of memory" );
  
  for ( i = 0; i <= maxval; i++ ) countTile[i]   = 0;
  for ( i = 0; i <= maxval; i++ ) countEdgeX[i]  = 0;
  for ( i = 0; i <= maxval; i++ ) countEdgeY[i]  = 0;
  for ( i = 0; i <= maxval; i++ ) countVertex[i] = 0;




  /* first row */

  pgm_readpgmrow( ifp, thisrow, cols, maxval, format );

  /* tiles */

  for ( col = 0; col < cols; ++col ) ++countTile[thisrow[col]]; 
  
  /* y-edges */

  for ( col = 0; col < cols; ++col ) ++countEdgeY[thisrow[col]]; 

  /* x-edges */

  ++countEdgeX[thisrow[0]];

  for ( col = 0; col < cols-1; ++col ) 
    ++countEdgeX[ MAX2(thisrow[col], thisrow[col+1]) ];
  
  ++countEdgeX[thisrow[cols-1]];
  
  /* shortcut: for the first row, countVertex == countEdgeX */
  
  ++countVertex[thisrow[0]];

  for ( col = 0; col < cols-1; ++col ) 
    ++countVertex[ MAX2(thisrow[col], thisrow[col+1]) ];

  ++countVertex[thisrow[cols-1]];

  

  for ( row = 1; row < rows; ++row ){  
    
    tmprow = prevrow; 
    prevrow = thisrow;
    thisrow = tmprow;
 
    pgm_readpgmrow( ifp, thisrow, cols, maxval, format );
  
    /* tiles */

    for ( col = 0; col < cols; ++col ) ++countTile[thisrow[col]]; 
    
    /* y-edges */
    
    for ( col = 0; col < cols; ++col ) 
      ++countEdgeY[ MAX2(thisrow[col], prevrow[col]) ];
    /* x-edges */
    
    ++countEdgeX[thisrow[0]];
    
    for ( col = 0; col < cols-1; ++col ) 
      ++countEdgeX[ MAX2(thisrow[col], thisrow[col+1]) ];
    
    ++countEdgeX[thisrow[cols-1]];
    
    /* vertices */

    ++countVertex[ MAX2(thisrow[0],prevrow[0]) ];

    for ( col = 0; col < cols-1; ++col ) 
      ++countVertex[
        MAX4(thisrow[col], thisrow[col+1], prevrow[col], prevrow[col+1])
      ];
    
    ++countVertex[ MAX2(thisrow[cols-1],prevrow[cols-1]) ];
    
  } /* for row */
  
  /* now thisrow contains the top row*/

  /* tiles and x-edges have been counted, now upper
     y-edges and top vertices remain */
  
  /* y-edges */

  for ( col = 0; col < cols; ++col ) ++countEdgeY[ thisrow[col] ];

  /* vertices */
  
  ++countVertex[thisrow[0]];

  for ( col = 0; col < cols-1; ++col ) 
    ++countVertex[ MAX2(thisrow[col],thisrow[col+1]) ];

  ++countVertex[ thisrow[cols-1] ];


  /* cleanup */

  maxtiles =  rows    * cols;
  maxedgex =  rows    * (cols+1);
  maxedgey = (rows+1) *  cols;
  maxvertex= (rows+1) * (cols+1);
  
  l2inv = 1.0/maxtiles;
  linv  = 0.5/(rows+cols);

  /* And print it. */
  printf( "#threshold\t tiles\tx-edges\ty-edges\tvertices\n" );
  printf( "#---------\t -----\t-------\t-------\t--------\n" );
  for ( i = 0; i <= maxval; i++ ){

    if( !(countTile[i] || countEdgeX[i] || countEdgeY[i] || countVertex[i] ) ) 
      continue; /* skip empty slots */

    area      = maxtiles;
    perimeter = 2*maxedgex + 2*maxedgey - 4*maxtiles;
    eulerchi  = maxtiles - maxedgex - maxedgey + maxvertex;

    printf( "%f\t%6d\t%7d\t%7d\t%8d\t%g\t%g\t%6d\n", (float) i/(1.0*maxval), 
        maxtiles, maxedgex, maxedgey, maxvertex,
        area*l2inv, perimeter*linv, eulerchi
        );


    maxtiles -= countTile[i];
    maxedgex -= countEdgeX[i];
    maxedgey -= countEdgeY[i];
    maxvertex-= countVertex[i];

    /*  i, countTile[i], countEdgeX[i], countEdgeY[i], countVertex[i] */

  }

  /* these should be zero: */
  printf( "#  check:\t%6d\t%7d\t%7d\t%8d\n", 
          maxtiles, maxedgex, maxedgey, maxvertex );

  pm_close( ifp );
  
  exit( 0 );
  
} /*main*/