Ejemplo n.º 1
0
/**
 * art_svp_diff: Compute the symmetric difference of two sorted vector paths.
 * @svp1: One sorted vector path.
 * @svp2: The other sorted vector path.
 *
 * Computes the symmetric of the two argument svp's. Given two svp's
 * with winding numbers of 0 and 1 everywhere, the resulting winding
 * number will be 1 where either, but not both, of the argument svp's
 * has a winding number 1, 0 otherwise. The result is newly allocated.
 *
 * Currently, this routine has accuracy problems pending the
 * implementation of the new intersector.
 *
 * Return value: The symmetric difference of @svp1 and @svp2.
 **/
ArtSVP *
art_svp_diff (const ArtSVP *svp1, const ArtSVP *svp2)
{
#ifdef ART_USE_NEW_INTERSECTOR 
  ArtSVP *svp3, *svp_new;
  ArtSvpWriter *swr;

  svp3 = art_svp_merge (svp1, svp2);
  swr = art_svp_writer_rewind_new (ART_WIND_RULE_ODDEVEN);
  art_svp_intersector (svp3, swr);
  svp_new = art_svp_writer_rewind_reap (swr);
  art_free (svp3); /* shallow free because svp3 contains shared segments */

  return svp_new;
#else
  ArtSVP *svp3, *svp4, *svp_new;

  svp3 = art_svp_merge_perturbed (svp1, svp2);
  svp4 = art_svp_uncross (svp3);
  art_svp_free (svp3);

  svp_new = art_svp_rewind_uncrossed (svp4, ART_WIND_RULE_ODDEVEN);
  art_svp_free (svp4);
  return svp_new;
#endif
}
Ejemplo n.º 2
0
ArtSVP *
art_svp_minus (const ArtSVP *svp1, const ArtSVP *svp2)
{
  ArtSVP *svp2_mod;
  ArtSVP *svp3, *svp_new;
  ArtSvpWriter *swr;
  int i;

  svp2_mod = (ArtSVP *) svp2; /* get rid of the const for a while */

  /* First invert svp2 to "turn it inside out" */
  for (i = 0; i < svp2_mod->n_segs; i++)
    svp2_mod->segs[i].dir = !svp2_mod->segs[i].dir;

  svp3 = art_svp_merge (svp1, svp2_mod);
  swr = art_svp_writer_rewind_new (ART_WIND_RULE_POSITIVE);
  art_svp_intersector (svp3, swr);
  svp_new = art_svp_writer_rewind_reap (swr);
  art_free (svp3); /* shallow free because svp3 contains shared segments */

  /* Flip svp2 back to its original state */
  for (i = 0; i < svp2_mod->n_segs; i++)
    svp2_mod->segs[i].dir = !svp2_mod->segs[i].dir;

  return svp_new;
}
Ejemplo n.º 3
0
static void
nr_typeface_w32_finalize (NRObject *object)
{
    NRTypeFaceW32 *tfw32;

    tfw32 = (NRTypeFaceW32 *) object;

    nr_free (tfw32->otm);
    DeleteFont (tfw32->hfont);


    if (tfw32->slots) {
        unsigned int i;
        for (i = 0; i < tfw32->slots_length; i++) {
            if (tfw32->slots[i].outline.path > 0) {
				art_free (tfw32->slots[i].outline.path);
            }
        }
		nr_free (tfw32->slots);
    }
    if (tfw32->hgidx) nr_free (tfw32->hgidx);
    if (tfw32->vgidx) nr_free (tfw32->vgidx);

	((NRObjectClass *) (parent_class))->finalize (object);
}
Ejemplo n.º 4
0
/**
 * art_svp_intersect: Compute the intersection of two sorted vector paths.
 * @svp1: One sorted vector path.
 * @svp2: The other sorted vector path.
 *
 * Computes the intersection of the two argument svp's. Given two
 * svp's with winding numbers of 0 and 1 everywhere, the resulting
 * winding number will be 1 where both of the argument svp's has a
 * winding number 1, 0 otherwise. The result is newly allocated.
 *
 * Currently, this routine has accuracy problems pending the
 * implementation of the new intersector.
 *
 * Return value: The intersection of @svp1 and @svp2.
 **/
ArtSVP *
art_svp_intersect (const ArtSVP *svp1, const ArtSVP *svp2)
{
#ifdef ART_USE_NEW_INTERSECTOR 
  ArtSVP *svp3, *svp_new;
  ArtSvpWriter *swr;
#ifdef	ROBIN_DEBUG
	dump_svp("art_svp_intersect svp1", svp1);
	dump_svp("art_svp_intersect svp2", svp2);
#endif

  svp3 = art_svp_merge (svp1, svp2);
  swr = art_svp_writer_rewind_new (ART_WIND_RULE_INTERSECT);
  art_svp_intersector (svp3, swr);
  svp_new = art_svp_writer_rewind_reap (swr);
  art_free (svp3); /* shallow free because svp3 contains shared segments */
#ifdef	ROBIN_DEBUG
  dump_svp("art_svp_intersect svp_new", svp_new);
#endif

  return svp_new;
#else
  ArtSVP *svp3, *svp4, *svp_new;

  svp3 = art_svp_merge_perturbed (svp1, svp2);
  svp4 = art_svp_uncross (svp3);
  art_svp_free (svp3);

  svp_new = art_svp_rewind_uncrossed (svp4, ART_WIND_RULE_INTERSECT);
  art_svp_free (svp4);
  return svp_new;
#endif
}
Ejemplo n.º 5
0
static int
gnome_print_multipage_stroke (GnomePrintContext *pc, const ArtBpath *bpath)
{
	GnomePrintMultipage *mp;
	const ArtVpathDash *dash;
	ArtBpath *p;
	gint ret;

	mp = GNOME_PRINT_MULTIPAGE (pc);
	dash = gp_gc_get_dash (pc->gc);
	p = art_bpath_affine_transform (bpath, mp->subpage->data);

	gnome_print_setrgbcolor   (mp->subpc, gp_gc_get_red (pc->gc), gp_gc_get_green (pc->gc), gp_gc_get_blue (pc->gc));
	gnome_print_setopacity    (mp->subpc, gp_gc_get_opacity    (pc->gc));
	gnome_print_setlinewidth  (mp->subpc, gp_gc_get_linewidth  (pc->gc));
	gnome_print_setmiterlimit (mp->subpc, gp_gc_get_miterlimit (pc->gc));
	gnome_print_setlinejoin   (mp->subpc, gp_gc_get_linejoin   (pc->gc));
	gnome_print_setlinecap    (mp->subpc, gp_gc_get_linecap    (pc->gc));
	gnome_print_setdash       (mp->subpc, dash->n_dash, dash->dash, dash->offset);

	ret = gnome_print_stroke_bpath (mp->subpc, p);

	art_free (p);

	return ret;
}
static void
free_seg (ArtSVPSeg *seg)
{
	g_assert (seg != NULL);
	g_assert (seg->points != NULL);
	
	art_free (seg->points);
}
Ejemplo n.º 7
0
int create_instance_backing (ncInstance * instance)
{
    int ret = ERROR;
    virtualMachine * vm = &(instance->params);
    artifact * sentinel = NULL;

    // ensure instance directory exists
    set_path (instance->instancePath,    sizeof (instance->instancePath),    instance, NULL);
    if (ensure_directories_exist (instance->instancePath, 0, NULL, "root", BACKING_DIRECTORY_PERM) == -1)
        goto out;

    // set various instance-directory-relative paths in the instance struct
    set_path (instance->xmlFilePath,     sizeof (instance->xmlFilePath),     instance, "instance.xml");
    set_path (instance->libvirtFilePath, sizeof (instance->libvirtFilePath), instance, "libvirt.xml");
    set_path (instance->consoleFilePath, sizeof (instance->consoleFilePath), instance, "console.log");
    if (strstr (instance->platform, "windows")) {
        // generate the floppy file for windows instances
        if (makeWindowsFloppy (nc_state.home, instance->instancePath, instance->keyName, instance->instanceId)) {
            logprintfl (EUCAERROR, "[%s] error: could not create windows bootup script floppy\n", instance->instanceId);
            goto out;
        } else {
            set_path (instance->floppyFilePath, sizeof (instance->floppyFilePath), instance, "floppy");
        }
    }
    
    char work_prefix [1024]; // {userId}/{instanceId}
    set_id (instance, NULL, work_prefix, sizeof (work_prefix));
    
    // compute tree of dependencies
    sentinel = vbr_alloc_tree (vm, // the struct containing the VBR
                               FALSE, // for Xen and KVM we do not need to make disk bootable
                               TRUE, // make working copy of runtime-modifiable files
                               (instance->do_inject_key)?(instance->keyName):(NULL), // the SSH key
                               instance->instanceId); // ID is for logging
    if (sentinel == NULL) {
        logprintfl (EUCAERROR, "[%s] error: failed to prepare backing for instance\n", instance->instanceId);
        goto out;
    }

    sem_p (disk_sem);
    // download/create/combine the dependencies
    int rc = art_implement_tree (sentinel, work_bs, cache_bs, work_prefix, INSTANCE_PREP_TIMEOUT_USEC);
    sem_v (disk_sem);

    if (rc != OK) {
        logprintfl (EUCAERROR, "[%s] error: failed to implement backing for instance\n", instance->instanceId);
        goto out;
    }

    if (save_instance_struct (instance)) // update instance checkpoint now that the struct got updated
        goto out;

    ret = OK;
 out:
    if (sentinel)
        art_free (sentinel);
    return ret;
}
Ejemplo n.º 8
0
static void
test_dash (void)
{
    ArtVpath *vpath, *vpath2;
    double dash_data[] = { 10, 4, 1, 4};
    ArtVpathDash dash;

    dash.offset = 0;
    dash.n_dash = 3;
    dash.dash = dash_data;

    vpath = randstar (50);
    vpath2 = art_vpath_dash (vpath, &dash);
    printf ("%%!\n");
    print_vpath (vpath2);
    printf ("showpage\n");
    art_free (vpath);
    art_free (vpath2);
}
Ejemplo n.º 9
0
/**
 * art_uta_from_svp: Generate uta covering an svp.
 * @svp: The source svp.
 *
 * Generates a uta covering @svp. The resulting uta is of course
 * approximate, ie it may cover more pixels than covered by @svp.
 *
 * Note: I will want to replace this with a more direct
 * implementation. But this gets the api in place.
 *
 * Return value: the new uta.
 **/
ArtUta *
art_uta_from_svp (const ArtSVP *svp)
{
  ArtVpath *vpath;
  ArtUta *uta;

  vpath = art_vpath_from_svp (svp);
  uta = art_uta_from_vpath (vpath);
  art_free (vpath);
  return uta;
}
Ejemplo n.º 10
0
static ArtSVP *
art_svp_merge_perturbed (const ArtSVP *svp1, const ArtSVP *svp2)
{
  ArtVpath *vpath1, *vpath2;
  ArtVpath *vpath1_p, *vpath2_p;
  ArtSVP *svp1_p, *svp2_p;
  ArtSVP *svp_new;

  vpath1 = art_vpath_from_svp (svp1);
  vpath1_p = art_vpath_perturb (vpath1);
  art_free (vpath1);
  svp1_p = art_svp_from_vpath (vpath1_p);
  art_free (vpath1_p);

  vpath2 = art_vpath_from_svp (svp2);
  vpath2_p = art_vpath_perturb (vpath2);
  art_free (vpath2);
  svp2_p = art_svp_from_vpath (vpath2_p);
  art_free (vpath2_p);

  svp_new = art_svp_merge (svp1_p, svp2_p);
#ifdef VERBOSE
  print_ps_svp (svp1_p);
  print_ps_svp (svp2_p);
  print_ps_svp (svp_new);
#endif
  art_free (svp1_p);
  art_free (svp2_p);

  return svp_new;
}
Ejemplo n.º 11
0
/**
 * art_svp_vpath_stroke: Stroke a vector path.
 * @vpath: #ArtVPath to stroke.
 * @join: Join style.
 * @cap: Cap style.
 * @line_width: Width of stroke.
 * @miter_limit: Miter limit.
 * @flatness: Flatness.
 *
 * Computes an svp representing the stroked outline of @vpath. The
 * width of the stroked line is @line_width.
 *
 * Lines are joined according to the @join rule. Possible values are
 * ART_PATH_STROKE_JOIN_MITER (for mitered joins),
 * ART_PATH_STROKE_JOIN_ROUND (for round joins), and
 * ART_PATH_STROKE_JOIN_BEVEL (for bevelled joins). The mitered join
 * is converted to a bevelled join if the miter would extend to a
 * distance of more than @miter_limit * @line_width from the actual
 * join point.
 *
 * If there are open subpaths, the ends of these subpaths are capped
 * according to the @cap rule. Possible values are
 * ART_PATH_STROKE_CAP_BUTT (squared cap, extends exactly to end
 * point), ART_PATH_STROKE_CAP_ROUND (rounded half-circle centered at
 * the end point), and ART_PATH_STROKE_CAP_SQUARE (squared cap,
 * extending half @line_width past the end point).
 *
 * The @flatness parameter controls the accuracy of the rendering. It
 * is most important for determining the number of points to use to
 * approximate circular arcs for round lines and joins. In general, the
 * resulting vector path will be within @flatness pixels of the "ideal"
 * path containing actual circular arcs. I reserve the right to use
 * the @flatness parameter to convert bevelled joins to miters for very
 * small turn angles, as this would reduce the number of points in the
 * resulting outline path.
 *
 * The resulting path is "clean" with respect to self-intersections, i.e.
 * the winding number is 0 or 1 at each point.
 *
 * Return value: Resulting stroked outline in svp format.
 **/
ArtSVP *
art_svp_vpath_stroke (ArtVpath *vpath,
		      ArtPathStrokeJoinType join,
		      ArtPathStrokeCapType cap,
		      double line_width,
		      double miter_limit,
		      double flatness)
{
  ArtVpath *vpath_stroke, *vpath2;
  ArtSVP *svp, *svp2, *svp3;

  vpath_stroke = art_svp_vpath_stroke_raw (vpath, join, cap,
					   line_width, miter_limit, flatness);
#ifdef VERBOSE
  print_ps_vpath (vpath_stroke);
#endif
  vpath2 = art_vpath_perturb (vpath_stroke);
#ifdef VERBOSE
  print_ps_vpath (vpath2);
#endif
  art_free (vpath_stroke);
  svp = art_svp_from_vpath (vpath2);
#ifdef VERBOSE
  print_ps_svp (svp);
#endif
  art_free (vpath2);
  svp2 = art_svp_uncross (svp);
#ifdef VERBOSE
  print_ps_svp (svp2);
#endif
  art_svp_free (svp);
  svp3 = art_svp_rewind_uncrossed (svp2, ART_WIND_RULE_NONZERO);
#ifdef VERBOSE
  print_ps_svp (svp3);
#endif
  art_svp_free (svp2);

  return svp3;
}
Ejemplo n.º 12
0
static int
gnome_print_multipage_clip (GnomePrintContext *pc, const ArtBpath *bpath, ArtWindRule rule)
{
	GnomePrintMultipage *mp;
	ArtBpath *p;
	gint ret;

	mp = GNOME_PRINT_MULTIPAGE (pc);

	p = art_bpath_affine_transform (bpath, mp->subpage->data);

	ret = gnome_print_clip_bpath_rule (mp->subpc, p, rule);

	art_free (p);

	return ret;
}
Ejemplo n.º 13
0
static int
gnome_print_multipage_fill (GnomePrintContext *pc, const ArtBpath *bpath, ArtWindRule rule)
{
	GnomePrintMultipage *mp;
	ArtBpath *p;
	gint ret;

	mp = GNOME_PRINT_MULTIPAGE(pc);

	p = art_bpath_affine_transform (bpath, mp->subpage->data);

	gnome_print_setrgbcolor (mp->subpc, gp_gc_get_red (pc->gc), gp_gc_get_green (pc->gc), gp_gc_get_blue (pc->gc));
	gnome_print_setopacity (mp->subpc, gp_gc_get_opacity (pc->gc));

	ret = gnome_print_fill_bpath_rule (mp->subpc, p, rule);

	art_free (p);

	return ret;
}
Ejemplo n.º 14
0
gfxpoly_t* gfxpoly_intersect(gfxpoly_t*poly1, gfxpoly_t*poly2)
{
    ArtSvpWriter *swr;

    static int counter = 0;
    
    ArtSVP* svp1 = (ArtSVP*)poly1;
    ArtSVP* svp2 = (ArtSVP*)poly2;
    msg("<verbose> Intersecting two polygons of %d and %d segments", svp1->n_segs, svp2->n_segs);
    
#ifdef DEBUG
    char filename[80];
    sprintf(filename, "isvp%d_src1.ps", counter);
    write_svp_postscript(filename, svp1);
    sprintf(filename, "isvp%d_src2.ps", counter);
    write_svp_postscript(filename, svp2);
#endif
    
    ArtSVP* svp3 = art_svp_merge (svp1, svp2);

#ifdef DEBUG
    sprintf(filename, "isvp%d_src.ps", counter);
    write_svp_postscript(filename, svp3);
#endif

    //write_svp_postscript("svp.ps", svp3);
    ArtSVP*svp_new = run_intersector(svp3, ART_WIND_RULE_INTERSECT);

    art_free (svp3); /* shallow free because svp3 contains shared segments */

#ifdef DEBUG
    sprintf(filename, "isvp%d.ps", counter);
    write_svp_postscript(filename, svp_new);
#endif

    counter++;
    
    //write_svp_postscript("svp_new.ps", svp_new);
	
    return (gfxpoly_t*)svp_new;
}
Ejemplo n.º 15
0
static void
nr_typeface_gnome_finalize (NRObject *object)
{
    NRTypeFace *tf;
    NRTypeFaceGnome *tfg;

    tf = (NRTypeFace *) object;
    tfg = (NRTypeFaceGnome *) object;

    if (tfg->voutlines) {
        int i;
        for (i = 0; i < tf->nglyphs; i++) {
            if (tfg->voutlines[i].path) art_free (tfg->voutlines[i].path);
        }
        nr_free (tfg->voutlines);
    }

    gnome_font_face_unref (tfg->face);

    ((NRObjectClass *) (parent_class))->finalize (object);
}
Ejemplo n.º 16
0
static void
make_testpat (void)
{
    ArtVpath *vpath, *vpath2, *vpath3;
    ArtSVP *svp, *svp2;
    ArtSVP *svp3;
    art_u8 buf[512 * 512 * BYTES_PP];
    int i, j;
    int iter;
    art_u8 colorimg[256][256][3];
    art_u8 rgbaimg[256][256][4];
    art_u8 bitimg[16][2];
    int x, y;
    double affine[6];
    double affine2[6];
    double affine3[6];
    ArtAlphaGamma *alphagamma;
    double dash_data[] = { 20 };
    ArtVpathDash dash;

    dash.offset = 0;
    dash.n_dash = 1;
    dash.dash = dash_data;

#ifdef TEST_AFFINE
    test_affine ();
    exit (0);
#endif

    vpath = randstar (50);
    svp = art_svp_from_vpath (vpath);
    art_free (vpath);

    vpath2 = randstar (50);
#if 1
    vpath3 = art_vpath_dash (vpath2, &dash);
    art_free (vpath2);
    svp2 = art_svp_vpath_stroke (vpath3,
                                 ART_PATH_STROKE_JOIN_MITER,
                                 ART_PATH_STROKE_CAP_BUTT,
                                 15,
                                 4,
                                 0.5);
    art_free (vpath3);
#else
    svp2 = art_svp_from_vpath (vpath2);
#endif

#if 1
    svp3 = art_svp_intersect (svp, svp2);
#else
    svp3 = svp2;
#endif

#if 0
    print_svp (svp);
#endif

    for (y = 0; y < 256; y++)
        for (x = 0; x < 256; x++)
        {
            colorimg[y][x][0] = (x + y) >> 1;
            colorimg[y][x][1] = (x + (255 - y)) >> 1;
            colorimg[y][x][2] = ((255 - x) + y) >> 1;

            rgbaimg[y][x][0] = (x + y) >> 1;
            rgbaimg[y][x][1] = (x + (255 - y)) >> 1;
            rgbaimg[y][x][2] = ((255 - x) + y) >> 1;
            rgbaimg[y][x][3] = y;
        }

    for (y = 0; y < 16; y++)
        for (x = 0; x < 2; x++)
            bitimg[y][x] = (x << 4) | y;

    affine[0] = 0.5;
    affine[1] = .2;
    affine[2] = -.2;
    affine[3] = 0.5;
    affine[4] = 64;
    affine[5] = 64;

    affine2[0] = 1;
    affine2[1] = -.2;
    affine2[2] = .2;
    affine2[3] = 1;
    affine2[4] = 128;
    affine2[5] = 128;

    affine3[0] = 5;
    affine3[1] = -.2;
    affine3[2] = .2;
    affine3[3] = 5;
    affine3[4] = 384;
    affine3[5] = 32;

#if 0
    alphagamma = art_alphagamma_new (1.8);
#else
    alphagamma = NULL;
#endif

#ifdef COLOR
    printf ("P6\n512 512\n255\n");
#else
    printf ("P5\n512 512\n255\n");
#endif
    for (iter = 0; iter < NUM_ITERS; iter++)
        for (j = 0; j < 512; j += TILE_SIZE)
            for (i = 0; i < 512; i += TILE_SIZE)
            {
#ifdef COLOR
                art_rgb_svp_aa (svp, i, j, i + TILE_SIZE, j + TILE_SIZE,
                                0xffe0a0, 0x100040,
                                buf + (j * 512 + i) * BYTES_PP, 512 * BYTES_PP,
                                alphagamma);
                art_rgb_svp_alpha (svp2, i, j, i + TILE_SIZE, j + TILE_SIZE,
                                   0xff000080,
                                   buf + (j * 512 + i) * BYTES_PP, 512 * BYTES_PP,
                                   alphagamma);
                art_rgb_svp_alpha (svp3, i, j, i + TILE_SIZE, j + TILE_SIZE,
                                   0x00ff0080,
                                   buf + (j * 512 + i) * BYTES_PP, 512 * BYTES_PP,
                                   alphagamma);
                art_rgb_affine (buf + (j * 512 + i) * BYTES_PP,
                                i, j, i + TILE_SIZE, j + TILE_SIZE, 512 * BYTES_PP,
                                (art_u8 *)colorimg, 256, 256, 256 * 3,
                                affine,
                                ART_FILTER_NEAREST, alphagamma);
                art_rgb_rgba_affine (buf + (j * 512 + i) * BYTES_PP,
                                     i, j, i + TILE_SIZE, j + TILE_SIZE,
                                     512 * BYTES_PP,
                                     (art_u8 *)rgbaimg, 256, 256, 256 * 4,
                                     affine2,
                                     ART_FILTER_NEAREST, alphagamma);
                art_rgb_bitmap_affine (buf + (j * 512 + i) * BYTES_PP,
                                       i, j, i + TILE_SIZE, j + TILE_SIZE,
                                       512 * BYTES_PP,
                                       (art_u8 *)bitimg, 16, 16, 2,
                                       0xffff00ff,
                                       affine3,
                                       ART_FILTER_NEAREST, alphagamma);
#else
                art_gray_svp_aa (svp, i, j, i + TILE_SIZE, j + TILE_SIZE,
                                 buf + (j * 512 + i) * BYTES_PP, 512 * BYTES_PP);
#endif
            }

    art_svp_free (svp2);
    art_svp_free (svp3);
    art_svp_free (svp);

#if 1
    fwrite (buf, 1, 512 * 512 * BYTES_PP, stdout);
#endif
}
Ejemplo n.º 17
0
void art_draw_poly(art_buffer_p buffer, art_context_p context, int filled,
		   float *x, float *y, int n, int closed)
{
  ArtVpath *vec, *vec2;
  ArtSVP *svp;
  double dash_data[2];
  ArtVpathDash dash;
  ArtDRect drect;
  ArtIRect irect;
  int i, mark = 0;

  vec = art_new(ArtVpath, n + 1 + closed);
  for(i = 0; i < n; i++) {
    vec[mark].code = i ? ART_LINETO : ART_MOVETO;
    if(i == 0 || i == n - 1 || hypot(x[i] - vec[mark - 1].x,
				     (buffer->height - y[i]) - 
				     vec[mark - 1].y) > 1.0) {
      vec[mark].x = x[i];
      vec[mark].y = buffer->height - y[i];
      mark++;
    }
  }
  n = mark;
  if(closed) {
    vec[n].code = ART_LINETO;
    vec[n].x = vec[0].x;
    vec[n].y = vec[0].y;
  }
  vec[n + closed].code = ART_END;
  vec[n + closed].x = 0;
  vec[n + closed].y = 0;
  if(context->current_dash_on > 0) {
    dash.offset = 0;
    dash_data[0] = context->current_dash_on;
    dash_data[1] = context->current_dash_off;
    dash.n_dash = 2;
    dash.dash = dash_data;
    vec2 = art_vpath_dash(vec, &dash);
    art_free(vec);
    vec = vec2;
  }

  if(filled)
    svp = art_svp_from_vpath(vec);
  else
    svp = art_svp_vpath_stroke(vec, context->current_jointype, 
			       context->current_captype,
			       context->current_linewidth,
			       context->current_miterlimit, 
			       context->current_flatness);
  art_free(vec);

  art_drect_svp(&drect, svp);
  art_drect_to_irect(&irect, &drect);
  if(irect.x1 > buffer->width)
    irect.x1 = buffer->width;
  if(irect.y1 > buffer->height)
    irect.y1 = buffer->height;
  if(irect.x0 < 0)
    irect.x0 = 0;
  if(irect.y0 < 0)
    irect.y0 = 0;
  art_rgb_svp_alpha(svp, irect.x0, irect.y0, irect.x1, irect.y1, 
		    context->current_color,
		    buffer->buffer + (irect.y0 * buffer->width + irect.x0) * 3,
		    buffer->width * 3, NULL);
  art_svp_free(svp);
}
Ejemplo n.º 18
0
//!
//! Implement the backing store for a given instance
//!
//! @param[in] instance pointer to the instance
//! @param[in] is_migration_dest
//!
//! @return EUCA_OK on success or EUCA_ERROR on failure
//!
//! @pre The instance parameter must not be NULL.
//!
//! @post
//!
int create_instance_backing(ncInstance * instance, boolean is_migration_dest)
{
    int rc = 0;
    int ret = EUCA_ERROR;
    virtualMachine *vm = &(instance->params);
    artifact *sentinel = NULL;
    char work_prefix[1024] = { 0 };    // {userId}/{instanceId}

    // set various instance-directory-relative paths in the instance struct
    set_instance_paths(instance);

    // ensure instance directory exists
    if (ensure_directories_exist(instance->instancePath, 0, NULL, "root", BACKING_DIRECTORY_PERM) == -1)
        goto out;

    if (strstr(instance->platform, "windows")) {
        // generate the floppy file for windows instances
        if (makeWindowsFloppy(nc_state.home, instance->instancePath, instance->keyName, instance->instanceId)) {
            LOGERROR("[%s] could not create windows bootup script floppy\n", instance->instanceId);
            goto out;
        } else {
            set_path(instance->floppyFilePath, sizeof(instance->floppyFilePath), instance, "floppy");
        }
    } else if (strlen(instance->instancePk) > 0) {  // TODO: credential floppy is limited to Linux instances ATM
        LOGDEBUG("[%s] creating floppy for instance credential\n", instance->instanceId);
        if (make_credential_floppy(nc_state.home, instance)) {
            LOGERROR("[%s] could not create credential floppy\n", instance->instanceId);
            goto out;
        } else {
            set_path(instance->floppyFilePath, sizeof(instance->floppyFilePath), instance, "floppy");
        }
    }

    set_id(instance, NULL, work_prefix, sizeof(work_prefix));

    // if this looks like a partition m1.small image, make it a bootable disk
    virtualMachine *vm2 = NULL;
    LOGDEBUG("vm->virtualBootRecordLen=%d\n", vm->virtualBootRecordLen);
    if (vm->virtualBootRecordLen == 5) {    // TODO: make this check more robust

        // as an experiment, construct a new VBR, without swap and ephemeral
        virtualMachine vm_copy;
        vm2 = &vm_copy;
        memcpy(vm2, vm, sizeof(virtualMachine));
        bzero(vm2->virtualBootRecord, EUCA_MAX_VBRS * sizeof(virtualBootRecord));
        vm2->virtualBootRecordLen = 0;

        virtualBootRecord *emi_vbr = NULL;
        for (int i = 0; i < EUCA_MAX_VBRS && i < vm->virtualBootRecordLen; i++) {
            virtualBootRecord *vbr = &(vm->virtualBootRecord[i]);
            if (vbr->type != NC_RESOURCE_KERNEL && vbr->type != NC_RESOURCE_RAMDISK && vbr->type != NC_RESOURCE_IMAGE)
                continue;
            if (vbr->type == NC_RESOURCE_IMAGE)
                emi_vbr = vbr;
            memcpy(vm2->virtualBootRecord + (vm2->virtualBootRecordLen++), vbr, sizeof(virtualBootRecord));
        }

        if (emi_vbr == NULL) {
            LOGERROR("[%s] failed to find EMI among VBR entries\n", instance->instanceId);
            goto out;
        }

        if (vbr_add_ascii("boot:none:104857600:ext3:sda2:none", vm2) != EUCA_OK) {
            LOGERROR("[%s] could not add a boot partition VBR entry\n", instance->instanceId);
            goto out;
        }
        if (vbr_parse(vm2, NULL) != EUCA_OK) {
            LOGERROR("[%s] could not parse the boot partition VBR entry\n", instance->instanceId);
            goto out;
        }
        // compute tree of dependencies
        sentinel = vbr_alloc_tree(vm2, // the struct containing the VBR
                                  TRUE, // we always make the disk bootable, for consistency
                                  TRUE, // make working copy of runtime-modifiable files
                                  is_migration_dest,    // tree of an instance on the migration destination
                                  (instance->do_inject_key) ? (instance->keyName) : (NULL), // the SSH key
                                  instance->instanceId);    // ID is for logging
        if (sentinel == NULL) {
            LOGERROR("[%s] failed to prepare backing for instance\n", instance->instanceId);
            goto out;
        }

        LOGDEBUG("disk size prior to tree implementation is = %lld\n", sentinel->deps[0]->size_bytes);
        long long right_disk_size = sentinel->deps[0]->size_bytes;

        sem_p(disk_sem);
        {
            // download/create/combine the dependencies
            rc = art_implement_tree(sentinel, work_bs, cache_bs, work_prefix, INSTANCE_PREP_TIMEOUT_USEC);
        }
        sem_v(disk_sem);

        if (rc != EUCA_OK) {
            LOGERROR("[%s] failed to implement backing for instance\n", instance->instanceId);
            goto out;
        }

        LOGDEBUG("[%s] created the initial bootable disk\n", instance->instanceId);

        /* option A starts */
        assert(emi_vbr);
        assert(sentinel->deps[0]);
        strcpy(emi_vbr->guestDeviceName, "sda");    // switch 'sda1' to 'sda' now that we've built the disk
        //emi_vbr->sizeBytes = sentinel->deps[0]->size_bytes; // update the size to match the disk
        emi_vbr->sizeBytes = right_disk_size;   // this is bad...
        LOGDEBUG("at boot disk creation time emi_vbr->sizeBytes = %lld\n", emi_vbr->sizeBytes);
        euca_strncpy(emi_vbr->id, sentinel->deps[0]->id, SMALL_CHAR_BUFFER_SIZE);   // change to the ID of the disk
        if (vbr_parse(vm, NULL) != EUCA_OK) {
            LOGERROR("[%s] could not parse the boot partition VBR entry\n", instance->instanceId);
            goto out;
        }
        emi_vbr->locationType = NC_LOCATION_NONE;   // i.e., it should already exist

        art_free(sentinel);
        /* option A end */

        /* option B starts *
           memcpy(vm, vm2, sizeof(virtualMachine));
           if (save_instance_struct(instance)) // update instance checkpoint now that the struct got updated
           goto out;
           ret = EUCA_OK;
           goto out;
           * option B ends */
    }
    // compute tree of dependencies
    sentinel = vbr_alloc_tree(vm,      // the struct containing the VBR
                              FALSE,   // if image had to be made bootable, that was done above
                              TRUE,    // make working copy of runtime-modifiable files
                              is_migration_dest,    // tree of an instance on the migration destination
                              (instance->do_inject_key) ? (instance->keyName) : (NULL), // the SSH key
                              instance->instanceId);    // ID is for logging
    if (sentinel == NULL) {
        LOGERROR("[%s] failed to prepare extended backing for instance\n", instance->instanceId);
        goto out;
    }

    sem_p(disk_sem);
    {
        // download/create/combine the dependencies
        rc = art_implement_tree(sentinel, work_bs, cache_bs, work_prefix, INSTANCE_PREP_TIMEOUT_USEC);
    }
    sem_v(disk_sem);

    if (rc != EUCA_OK) {
        LOGERROR("[%s] failed to implement backing for instance\n", instance->instanceId);
        goto out;
    }

    if (save_instance_struct(instance)) // update instance checkpoint now that the struct got updated
        goto out;

    ret = EUCA_OK;

out:
    if (sentinel)
        art_free(sentinel);
    return (ret);
}
static MateComponent_Canvas_ArtUTA *
impl_MateComponent_Canvas_Component_update (PortableServer_Servant     servant,
				     const MateComponent_Canvas_State *state,
				     const MateComponent_Canvas_affine aff,
				     const MateComponent_Canvas_SVP   *clip_path,
				     CORBA_long                 flags,
				     CORBA_double              *x1, 
				     CORBA_double              *y1, 
				     CORBA_double              *x2, 
				     CORBA_double              *y2, 
				     CORBA_Environment         *ev)
{
	Gcc *gcc = GCC (matecomponent_object_from_servant (servant));
	MateCanvasItem *item = MATE_CANVAS_ITEM (gcc->priv->item);
	double affine [6];
	int i;
	ArtSVP *svp = NULL;
	MateComponent_Canvas_ArtUTA *cuta;

	MateCanvasItemClass *gci_class = g_type_class_ref (
					mate_canvas_item_get_type ());

	restore_state (item, state);
	for (i = 0; i < 6; i++)
		affine [i] = aff [i];

	if (clip_path->_length > 0) {
		svp = art_alloc (sizeof (ArtSVP) + (clip_path->_length * sizeof (ArtSVPSeg)));
		if (svp == NULL)
			goto fail;

		svp->n_segs = clip_path->_length;
		
		for (i = 0; svp->n_segs; i++) {
			gboolean ok;
		
			ok = CORBA_SVP_Segment_to_SVPSeg (&clip_path->_buffer [i], &svp->segs [i]);

			if (!ok) {
				int j;

				for (j = 0; j < i; j++) {
					free_seg (&svp->segs [j]);
					art_free (svp);
					goto fail;
				}
			}
		}
	}

	invoke_update (item, (double *)aff, svp, flags);

	if (svp){
		for (i = 0; i < svp->n_segs; i++)
			free_seg (&svp->segs [i]);
		art_free (svp);
	}

 fail:
	if (getenv ("CC_DEBUG"))
		printf ("%g %g %g %g\n", item->x1, item->x2, item->y1, item->y2);
	*x1 = item->x1;
	*x2 = item->x2;
	*y1 = item->y1;
	*y2 = item->y2;

	cuta = CORBA_UTA (item->canvas->redraw_area);
	if (cuta == NULL) {
		CORBA_exception_set_system (ev, ex_CORBA_NO_MEMORY, CORBA_COMPLETED_NO);
		return NULL;
	}

	/*
	 * Now, mark our canvas as fully up to date
	 */

        /* Clears flags for root item. */
	(* gci_class->update) (item->canvas->root, affine, svp, flags);

	if (item->canvas->redraw_area) {
		art_uta_free (item->canvas->redraw_area);
		item->canvas->redraw_area = NULL;
	}
	item->canvas->need_redraw = FALSE;
	
	return cuta;
}
Ejemplo n.º 20
0
/**
 * art_svp_vpath_stroke: Stroke a vector path.
 * @vpath: #ArtVPath to stroke.
 * @join: Join style.
 * @cap: Cap style.
 * @line_width: Width of stroke.
 * @miter_limit: Miter limit.
 * @flatness: Flatness.
 *
 * Computes an svp representing the stroked outline of @vpath. The
 * width of the stroked line is @line_width.
 *
 * Lines are joined according to the @join rule. Possible values are
 * ART_PATH_STROKE_JOIN_MITER (for mitered joins),
 * ART_PATH_STROKE_JOIN_ROUND (for round joins), and
 * ART_PATH_STROKE_JOIN_BEVEL (for bevelled joins). The mitered join
 * is converted to a bevelled join if the miter would extend to a
 * distance of more than @miter_limit * @line_width from the actual
 * join point.
 *
 * If there are open subpaths, the ends of these subpaths are capped
 * according to the @cap rule. Possible values are
 * ART_PATH_STROKE_CAP_BUTT (squared cap, extends exactly to end
 * point), ART_PATH_STROKE_CAP_ROUND (rounded half-circle centered at
 * the end point), and ART_PATH_STROKE_CAP_SQUARE (squared cap,
 * extending half @line_width past the end point).
 *
 * The @flatness parameter controls the accuracy of the rendering. It
 * is most important for determining the number of points to use to
 * approximate circular arcs for round lines and joins. In general, the
 * resulting vector path will be within @flatness pixels of the "ideal"
 * path containing actual circular arcs. I reserve the right to use
 * the @flatness parameter to convert bevelled joins to miters for very
 * small turn angles, as this would reduce the number of points in the
 * resulting outline path.
 *
 * The resulting path is "clean" with respect to self-intersections, i.e.
 * the winding number is 0 or 1 at each point.
 *
 * Return value: Resulting stroked outline in svp format.
 **/
ArtSVP *
art_svp_vpath_stroke (ArtVpath *vpath,
                      ArtPathStrokeJoinType join,
                      ArtPathStrokeCapType cap,
                      double line_width,
                      double miter_limit,
                      double flatness)
{
#ifdef ART_USE_NEW_INTERSECTOR
    ArtVpath *vpath_stroke;
    ArtSVP *svp, *svp2;
    ArtSvpWriter *swr;

    vpath_stroke = art_svp_vpath_stroke_raw (vpath, join, cap,
                   line_width, miter_limit, flatness);
#ifdef VERBOSE
    print_ps_vpath (vpath_stroke);
#endif
    svp = art_svp_from_vpath (vpath_stroke);
#ifdef VERBOSE
    print_ps_svp (svp);
#endif
    art_free (vpath_stroke);

    swr = art_svp_writer_rewind_new (ART_WIND_RULE_NONZERO);
    art_svp_intersector (svp, swr);

    svp2 = art_svp_writer_rewind_reap (swr);
#ifdef VERBOSE
    print_ps_svp (svp2);
#endif
    art_svp_free (svp);
    return svp2;
#else
    ArtVpath *vpath_stroke, *vpath2;
    ArtSVP *svp, *svp2, *svp3;

    vpath_stroke = art_svp_vpath_stroke_raw (vpath, join, cap,
                   line_width, miter_limit, flatness);
#ifdef VERBOSE
    print_ps_vpath (vpath_stroke);
#endif
    vpath2 = art_vpath_perturb (vpath_stroke);
#ifdef VERBOSE
    print_ps_vpath (vpath2);
#endif
    art_free (vpath_stroke);
    svp = art_svp_from_vpath (vpath2);
#ifdef VERBOSE
    print_ps_svp (svp);
#endif
    art_free (vpath2);
    svp2 = art_svp_uncross (svp);
#ifdef VERBOSE
    print_ps_svp (svp2);
#endif
    art_svp_free (svp);
    svp3 = art_svp_rewind_uncrossed (svp2, ART_WIND_RULE_NONZERO);
#ifdef VERBOSE
    print_ps_svp (svp3);
#endif
    art_svp_free (svp2);

    return svp3;
#endif
}
Ejemplo n.º 21
0
/**
 * art_alphagamma_free: Free an #ArtAlphaGamma.
 * @alphagamma: An #ArtAlphaGamma.
 *
 * Frees the #ArtAlphaGamma.
 **/
void
art_alphagamma_free (ArtAlphaGamma *alphagamma)
{
  art_free (alphagamma);
}
Ejemplo n.º 22
0
//!
//! Implement the backing store for a given instance
//!
//! @param[in] instance pointer to the instance
//! @param[in] is_migration_dest
//!
//! @return EUCA_OK on success or EUCA_ERROR on failure
//!
//! @pre The instance parameter must not be NULL.
//!
//! @post
//!
int create_instance_backing(ncInstance * instance, boolean is_migration_dest)
{
    int rc = 0;
    int ret = EUCA_ERROR;
    virtualMachine *vm = &(instance->params);
    artifact *sentinel = NULL;
    char work_prefix[1024] = { 0 };    // {userId}/{instanceId}

    // set various instance-directory-relative paths in the instance struct
    set_instance_paths(instance);

    // ensure instance directory exists
    if (ensure_directories_exist(instance->instancePath, 0, NULL, "root", BACKING_DIRECTORY_PERM) == -1)
        goto out;

    if (strstr(instance->platform, "windows")) {
        // generate the floppy file for windows instances
        if (makeWindowsFloppy(nc_state.home, instance->instancePath, instance->keyName, instance->instanceId)) {
            LOGERROR("[%s] could not create windows bootup script floppy\n", instance->instanceId);
            goto out;
        } else {
            set_path(instance->floppyFilePath, sizeof(instance->floppyFilePath), instance, "floppy");
        }
    }else if (instance->instancePk != NULL && strlen(instance->instancePk) > 0) {  // TODO: credential floppy is limited to Linux instances ATM
        LOGDEBUG("[%s] creating floppy for instance credential\n", instance->instanceId);
        if (make_credential_floppy(nc_state.home, instance)) {
            LOGERROR("[%s] could not create credential floppy\n", instance->instanceId);
            goto out;
        } else {
            set_path(instance->floppyFilePath, sizeof(instance->floppyFilePath), instance, "floppy");
        }
    }

    set_id(instance, NULL, work_prefix, sizeof(work_prefix));

    // compute tree of dependencies
    sentinel = vbr_alloc_tree(vm,      // the struct containing the VBR
                              FALSE,   // for Xen and KVM we do not need to make disk bootable
                              TRUE,    // make working copy of runtime-modifiable files
                              is_migration_dest,    // tree of an instance on the migration destination
                              (instance->do_inject_key) ? (instance->keyName) : (NULL), // the SSH key
                              instance->instanceId);    // ID is for logging
    if (sentinel == NULL) {
        LOGERROR("[%s] failed to prepare backing for instance\n", instance->instanceId);
        goto out;
    }

    sem_p(disk_sem);
    {
        // download/create/combine the dependencies
        rc = art_implement_tree(sentinel, work_bs, cache_bs, work_prefix, INSTANCE_PREP_TIMEOUT_USEC);
    }
    sem_v(disk_sem);

    if (rc != EUCA_OK) {
        LOGERROR("[%s] failed to implement backing for instance\n", instance->instanceId);
        goto out;
    }

    if (save_instance_struct(instance)) // update instance checkpoint now that the struct got updated
        goto out;

    ret = EUCA_OK;

out:
    if (sentinel)
        art_free(sentinel);
    return (ret);
}
Ejemplo n.º 23
0
/**
 * art_svp_from_vpath_raw: Stroke a vector path, raw version
 * @vpath: #ArtVPath to stroke.
 * @join: Join style.
 * @cap: Cap style.
 * @line_width: Width of stroke.
 * @miter_limit: Miter limit.
 * @flatness: Flatness.
 *
 * Exactly the same as art_svp_vpath_stroke(), except that the resulting
 * stroke outline may self-intersect and have regions of winding number
 * greater than 1.
 *
 * Return value: Resulting raw stroked outline in svp format.
 **/
ArtVpath *
art_svp_vpath_stroke_raw (ArtVpath *vpath,
                          ArtPathStrokeJoinType join,
                          ArtPathStrokeCapType cap,
                          double line_width,
                          double miter_limit,
                          double flatness)
{
    int begin_idx, end_idx;
    int i;
    ArtVpath *forw, *rev;
    int n_forw, n_rev;
    int n_forw_max, n_rev_max;
    ArtVpath *result;
    int n_result, n_result_max;
    double half_lw = 0.5 * line_width;
    int closed;
    int last, this, next, second;
    double dx, dy;

    n_forw_max = 16;
    forw = art_new (ArtVpath, n_forw_max);

    n_rev_max = 16;
    rev = art_new (ArtVpath, n_rev_max);

    n_result = 0;
    n_result_max = 16;
    result = art_new (ArtVpath, n_result_max);

    for (begin_idx = 0; vpath[begin_idx].code != ART_END; begin_idx = end_idx)
    {
        n_forw = 0;
        n_rev = 0;

        closed = (vpath[begin_idx].code == ART_MOVETO);

        /* we don't know what the first point joins with until we get to the
        last point and see if it's closed. So we start with the second
         line in the path.

         Note: this is not strictly true (we now know it's closed from
         the opening pathcode), but why fix code that isn't broken?
            */

        this = begin_idx;
        /* skip over identical points at the beginning of the subpath */
        for (i = this + 1; vpath[i].code == ART_LINETO; i++)
        {
            dx = vpath[i].x - vpath[this].x;
            dy = vpath[i].y - vpath[this].y;
            if (dx * dx + dy * dy > EPSILON_2)
                break;
        }
        next = i;
        second = next;

        /* invariant: this doesn't coincide with next */
        while (vpath[next].code == ART_LINETO)
        {
            last = this;
            this = next;
            /* skip over identical points after the beginning of the subpath */
            for (i = this + 1; vpath[i].code == ART_LINETO; i++)
            {
                dx = vpath[i].x - vpath[this].x;
                dy = vpath[i].y - vpath[this].y;
                if (dx * dx + dy * dy > EPSILON_2)
                    break;
            }
            next = i;
            if (vpath[next].code != ART_LINETO)
            {
                /* reached end of path */
                /* make "closed" detection conform to PostScript
                semantics (i.e. explicit closepath code rather than
                 just the fact that end of the path is the beginning) */
                if (closed &&
                        vpath[this].x == vpath[begin_idx].x &&
                        vpath[this].y == vpath[begin_idx].y)
                {
                    int j;

                    /* path is closed, render join to beginning */
                    render_seg (&forw, &n_forw, &n_forw_max,
                                &rev, &n_rev, &n_rev_max,
                                vpath, last, this, second,
                                join, half_lw, miter_limit, flatness);

#ifdef VERBOSE
                    printf ("%% forw %d, rev %d\n", n_forw, n_rev);
#endif
                    /* do forward path */
                    art_vpath_add_point (&result, &n_result, &n_result_max,
                                         ART_MOVETO, forw[n_forw - 1].x,
                                         forw[n_forw - 1].y);
                    for (j = 0; j < n_forw; j++)
                        art_vpath_add_point (&result, &n_result, &n_result_max,
                                             ART_LINETO, forw[j].x,
                                             forw[j].y);

                    /* do reverse path, reversed */
                    art_vpath_add_point (&result, &n_result, &n_result_max,
                                         ART_MOVETO, rev[0].x,
                                         rev[0].y);
                    for (j = n_rev - 1; j >= 0; j--)
                        art_vpath_add_point (&result, &n_result, &n_result_max,
                                             ART_LINETO, rev[j].x,
                                             rev[j].y);
                }
                else
                {
                    /* path is open */
                    int j;

                    /* add to forw rather than result to ensure that
                       forw has at least one point. */
                    render_cap (&forw, &n_forw, &n_forw_max,
                                vpath, last, this,
                                cap, half_lw, flatness);
                    art_vpath_add_point (&result, &n_result, &n_result_max,
                                         ART_MOVETO, forw[0].x,
                                         forw[0].y);
                    for (j = 1; j < n_forw; j++)
                        art_vpath_add_point (&result, &n_result, &n_result_max,
                                             ART_LINETO, forw[j].x,
                                             forw[j].y);
                    for (j = n_rev - 1; j >= 0; j--)
                        art_vpath_add_point (&result, &n_result, &n_result_max,
                                             ART_LINETO, rev[j].x,
                                             rev[j].y);
                    render_cap (&result, &n_result, &n_result_max,
                                vpath, second, begin_idx,
                                cap, half_lw, flatness);
                    art_vpath_add_point (&result, &n_result, &n_result_max,
                                         ART_LINETO, forw[0].x,
                                         forw[0].y);
                }
            }
            else
                render_seg (&forw, &n_forw, &n_forw_max,
                            &rev, &n_rev, &n_rev_max,
                            vpath, last, this, next,
                            join, half_lw, miter_limit, flatness);
        }
        end_idx = next;
    }

    art_free (forw);
    art_free (rev);
#ifdef VERBOSE
    printf ("%% n_result = %d\n", n_result);
#endif
    art_vpath_add_point (&result, &n_result, &n_result_max, ART_END, 0, 0);
    return result;
}
Ejemplo n.º 24
0
//!
//! Implement the backing store for a given instance
//!
//! @param[in] instance pointer to the instance
//! @param[in] is_migration_dest
//!
//! @return EUCA_OK on success or EUCA_ERROR on failure
//!
//! @pre The instance parameter must not be NULL.
//!
//! @post
//!
int create_instance_backing(ncInstance * instance, boolean is_migration_dest)
{
    int rc = 0;
    int ret = EUCA_ERROR;
    virtualMachine *vm = &(instance->params);
    artifact *sentinel = NULL;
    char work_prefix[1024] = { 0 };    // {userId}/{instanceId}
    char base_path[EUCA_MAX_PATH];
    char user_dir_path[EUCA_MAX_PATH];

    // set various instance-directory-relative paths in the instance struct
    set_instance_paths(instance);

    set_path(base_path, sizeof(base_path), NULL, NULL);
    snprintf(user_dir_path, sizeof(user_dir_path), "%s/%s", base_path, instance->userId);
    // create backing directory
    if ((check_path(user_dir_path) == 1) && (mkdir(user_dir_path, INSTANCE_DIRECTORY_PERM) == -1)) {
        LOGERROR("[%s] could not create backing directory %s\n", instance->instanceId, user_dir_path);
        goto out;
    }
    if (mkdir(instance->instancePath, INSTANCE_DIRECTORY_PERM) == -1) {
        LOGERROR("[%s] could not create backing directory %s\n", instance->instanceId, instance->instancePath);
        goto out;
    }

    if (strstr(instance->platform, "windows")) {
        // generate the floppy file for windows instances
        if (makeWindowsFloppy(nc_state.home, instance->instancePath, instance->keyName, instance->instanceId)) {
            LOGERROR("[%s] could not create windows bootup script floppy\n", instance->instanceId);
            goto out;
        } else {
            set_path(instance->floppyFilePath, sizeof(instance->floppyFilePath), instance, "floppy");
            instance->hasFloppy = TRUE;
        }
    } else if (instance->credential && strlen(instance->credential)) {
        LOGDEBUG("[%s] creating floppy for instance credential\n", instance->instanceId);
        if (make_credential_floppy(nc_state.home, instance->instancePath, instance->credential)) {
            LOGERROR("[%s] could not create credential floppy\n", instance->instanceId);
            goto out;
        } else {
            set_path(instance->floppyFilePath, sizeof(instance->floppyFilePath), instance, "floppy");
            instance->hasFloppy = TRUE;
        }
    } else if(instance->hasFloppy && is_migration_dest) {
        LOGDEBUG("[%s] creating blank instance credential floppy\n", instance->instanceId);
        char dest_path[1024] = "";
        int fd = 0;
        snprintf(dest_path, 1024, "%s/floppy", instance->instancePath);
        if ((fd = open(dest_path, O_CREAT | O_TRUNC | O_RDWR, 0700)) < 0) {
           LOGERROR("[%s] failed to create fake floppy\n", instance->instanceId);
           goto out;
        } else {
           lseek(fd, 1024*2048-1, SEEK_SET);
           write(fd, "\n", 1);
        }
        close(fd);
    } else {
        instance->hasFloppy = FALSE;
    }

    set_id(instance, NULL, work_prefix, sizeof(work_prefix));

    // compute tree of dependencies
    sentinel = vbr_alloc_tree(vm,      // the struct containing the VBR
                              TRUE,    // make working copy of runtime-modifiable files
                              is_migration_dest,    // tree of an instance on the migration destination
                              (instance->do_inject_key) ? (instance->keyName) : (NULL), // the SSH key
                              &(instance->bail_flag),   // flag indicating that provisioning should bail
                              instance->instanceId);    // ID is for logging
    if (sentinel == NULL) {
        LOGERROR("[%s] failed to prepare extended backing for instance\n", instance->instanceId);
        goto out;
    }

    sem_p(disk_sem);
    {
        // download/create/combine the dependencies
        rc = art_implement_tree(sentinel, work_bs, cache_bs, work_prefix, INSTANCE_PREP_TIMEOUT_USEC);
    }
    sem_v(disk_sem);

    if (rc != EUCA_OK) {
        LOGERROR("[%s] failed to implement backing for instance\n", instance->instanceId);
        goto out;
    }
    // copy EBS entries from VBR[] to volumes[]
    for (int i = 0; ((i < EUCA_MAX_VBRS) && (i < instance->params.virtualBootRecordLen)); i++) {
        virtualBootRecord *vbr = &(instance->params.virtualBootRecord[i]);
        if (vbr->locationType == NC_LOCATION_SC) {
            char *volumeId = vbr->id;  // id is 'emi-XXXX', replace it with 'vol-XXXX'
            ebs_volume_data *vol_data = NULL;
            if (deserialize_volume(vbr->resourceLocation, &vol_data) == 0) {
                volumeId = vol_data->volumeId;
            }
            if (save_volume(instance, volumeId, vbr->resourceLocation,  // attachmentToken
                            vbr->preparedResourceLocation,  // connect_string
                            vbr->guestDeviceName, VOL_STATE_ATTACHED, vbr->backingPath) == NULL) {  // the XML
                LOGERROR("[%s] failed to add record for volume %s\n", instance->instanceId, volumeId);
            }
            EUCA_FREE(vol_data);
        }
    }

    if (save_instance_struct(instance)) // update instance checkpoint now that the struct got updated
        goto out;

    ret = EUCA_OK;

out:
    if (sentinel)
        art_free(sentinel);
    return (ret);
}
Ejemplo n.º 25
0
//!
//! Main entry point of the application
//!
//! @param[in] argc the number of parameter passed on the command line
//! @param[in] argv the list of arguments
//!
//! @return EUCA_OK on success or EUCA_ERROR on failure.
//!
int main(int argc, char *argv[])
{
    int i = 0;
    int ret = EUCA_OK;
    int nparams = 0;
    int ncmds = 0;
    char *eq = NULL;
    char *key = NULL;
    char *val = NULL;
    char euca_root[] = "";
    char argv_str[4096] = "";
    char *cmd_name = NULL;
    char pid_file[EUCA_MAX_PATH] = "";
    FILE *fp = NULL;
    pid_t pid = 0;
    artifact *root = NULL;
    blobstore *work_bs = NULL;
    blobstore *cache_bs = NULL;
    imager_param *cmd_params = NULL;

    log_fp_set(stderr); // imager logs to stderr so image data can be piped to stdout
    set_debug(print_debug);

    // initialize globals
    artifacts_map = map_create(10);

    // use $EUCALYPTUS env var if available
    euca_home = getenv(EUCALYPTUS_ENV_VAR_NAME);
    if (!euca_home) {
        euca_home = euca_root;
    }
    // save the command line into a buffer so it's easier to rerun it by hand
    argv_str[0] = '\0';
    for (i = 0; i < argc; i++) {
        strncat(argv_str, "\"", sizeof(argv_str) - strlen(argv_str) - 1);
        strncat(argv_str, argv[i], sizeof(argv_str) - strlen(argv_str) - 1);
        strncat(argv_str, "\" ", sizeof(argv_str) - strlen(argv_str) - 1);
    }

    // initialize dependencies
    if (vmdk_init() == EUCA_OK) {
        vddk_available = TRUE;
    }

    // parse command-line parameters
    while (*(++argv)) {
        eq = strstr(*argv, "=");       // all params have '='s
        if (eq == NULL) {              // it's a command
            // process previous command, if any
            if (validate_cmd(ncmds, cmd_name, cmd_params, *argv) != NULL)
                ncmds++;               // increment only if there was a previous command

            if (ncmds + 1 > MAX_REQS)
                err("too many commands (max is %d)", MAX_REQS);

            cmd_name = *argv;
            cmd_params = NULL;
            nparams = 0;
        } else {                       // this is a parameter
            if (strlen(eq) == 1)
                usage("parameters must have non-empty values");
            *eq = '\0';                // split key from value
            if (strlen(*argv) == 1)
                usage("parameters must have non-empty names");

            key = *argv;
            val = eq + 1;
            if (key == NULL || val == NULL)
                usage("syntax error in parameters");

            if (key[0] == '-')
                key++;                 // skip '-' if any

            if (key[0] == '-')
                key++;                 // skip second '-' if any

            if (cmd_name == NULL) {    // without a preceding command => global parameter
                set_global_parameter(key, val);
                continue;
            }

            if (cmd_params == NULL) {
                cmd_params = calloc(MAX_PARAMS + 1, sizeof(imager_param));  // +1 for terminating NULL
                if (!cmd_params)
                    err("calloc failed");
            }

            if (nparams + 1 > MAX_PARAMS)
                err("too many parameters (max is %d)", MAX_PARAMS);
            cmd_params[nparams].key = key;
            cmd_params[nparams].val = val;
            nparams++;
        }
    }

    if (validate_cmd(ncmds, cmd_name, cmd_params, *argv) != NULL)   // validate last command
        ncmds++;

    LOGINFO("verified all parameters for %d command(s)\n", ncmds);
    if (print_argv) {
        LOGDEBUG("argv[]: %s\n", argv_str);
    }
    // record PID, which may be used by VB to kill the imager process (e.g., in cancelBundling)
    pid = getpid();
    sprintf(pid_file, "%s/imager.pid", get_work_dir());
    if ((fp = fopen(pid_file, "w")) == NULL) {
        err("could not create pid file");
    } else {
        fprintf(fp, "%d", pid);
        fclose(fp);
    }

    // invoke the requirements checkers in the same order as on command line,
    // constructing the artifact tree originating at 'root'
    for (i = 0; i < ncmds; i++) {
        if (reqs[i].cmd->requirements != NULL) {
            art_set_instanceId(reqs[i].cmd->name);  // for logging
            if ((root = reqs[i].cmd->requirements(&reqs[i], root)) == NULL) // pass results of earlier checkers to later checkers
                err("failed while verifying requirements");
        }
    }

    // it is OK for root to be NULL at this point

    // see if work blobstore will be needed at any stage
    // and open or create the work blobstore
    if (root && tree_uses_blobstore(root)) {
        // set the function that will catch blobstore errors
        blobstore_set_error_function(&bs_errors);

        if (ensure_directories_exist(get_work_dir(), 0, NULL, NULL, BLOBSTORE_DIRECTORY_PERM) == -1)
            err("failed to open or create work directory %s", get_work_dir());

        work_bs = blobstore_open(get_work_dir(), get_work_limit() / 512, BLOBSTORE_FLAG_CREAT, BLOBSTORE_FORMAT_FILES, BLOBSTORE_REVOCATION_NONE, BLOBSTORE_SNAPSHOT_ANY);
        if (work_bs == NULL) {
            err("failed to open work blobstore: %s", blobstore_get_error_str(blobstore_get_error()));
        }
        // no point in fscking the work blobstore as it was just created
    }
    // see if cache blobstore will be needed at any stage
    if (root && tree_uses_cache(root)) {
        if (ensure_directories_exist(get_cache_dir(), 0, NULL, NULL, BLOBSTORE_DIRECTORY_PERM) == -1)
            err("failed to open or create cache directory %s", get_cache_dir());
        cache_bs = blobstore_open(get_cache_dir(), get_cache_limit() / 512, BLOBSTORE_FLAG_CREAT, BLOBSTORE_FORMAT_DIRECTORY, BLOBSTORE_REVOCATION_LRU, BLOBSTORE_SNAPSHOT_ANY);
        if (cache_bs == NULL) {
            blobstore_close(work_bs);
            err("failed to open cache blobstore: %s\n", blobstore_get_error_str(blobstore_get_error()));
        }

        if (blobstore_fsck(cache_bs, NULL)) //! @TODO: verify checksums?
            err("cache blobstore failed integrity check: %s", blobstore_get_error_str(blobstore_get_error()));

        if (stat_blobstore(get_cache_dir(), cache_bs))
            err("blobstore is unreadable");
    }
    // implement the artifact tree
    ret = EUCA_OK;
    if (root) {
        art_set_instanceId("imager");  // for logging
        ret = art_implement_tree(root, work_bs, cache_bs, NULL, INSTANCE_PREP_TIMEOUT_USEC);    // do all the work!
    }
    // invoke the cleaners for each command to tidy up disk space and memory allocations
    for (i = 0; i < ncmds; i++) {
        if (reqs[i].cmd->cleanup != NULL) {
            art_set_instanceId(reqs[i].cmd->name);  // for logging
            reqs[i].cmd->cleanup(&reqs[i], (i == (ncmds - 1)) ? (TRUE) : (FALSE));
        }
    }

    // free the artifact tree
    if (root) {
        if (tree_uses_blobstore(root)) {
            if (blobstore_fsck(work_bs, stale_blob_examiner)) { // will remove all blobs
                LOGWARN("failed to clean up work space: %s\n", blobstore_get_error_str(blobstore_get_error()));
            }
        }
        art_free(root);
    }
    clean_work_dir(work_bs);

    // indicate completion
    LOGINFO("imager done (exit code=%d)\n", ret);

    exit(ret);
}
Ejemplo n.º 26
0
GdkPixBuf *image_load(FILE *f)
{
	int w,h,i,j;
	art_u8 *pixels=NULL, *dptr;
	unsigned char *lines[4], /* Used to expand rows, via rec_outbuf_height, from
				  the header file:
				  "* Usually rec_outbuf_height will be 1 or 2, at most 4." */
		**lptr;
	struct jpeg_decompress_struct cinfo;
	struct iojpeg_JPEG_error_mgr jerr;
	GdkPixBuf *pixbuf;

	/* setup error handler */
	cinfo.err = jpeg_std_error(&(jerr.pub));
	jerr.pub.error_exit = g_JPEGFatalErrorHandler;

	if (sigsetjmp(jerr.setjmp_buffer, 1)) {
		/* Whoops there was a jpeg error */
		if (pixels != NULL)
			art_free(pixels);
		jpeg_destroy_decompress(&cinfo);
		return NULL;
	}

	/* load header, setup */
	jpeg_create_decompress(&cinfo);
	jpeg_stdio_src(&cinfo, f);
	jpeg_read_header(&cinfo, TRUE);
	jpeg_start_decompress(&cinfo);
	cinfo.do_fancy_upsampling = FALSE;
	cinfo.do_block_smoothing = FALSE;

	w = cinfo.output_width;
	h = cinfo.output_height;
	g_print("w: %d h: %d\n", w, h);

	pixels = art_alloc(h * w * 3);
	if (pixels == NULL) {
		jpeg_destroy_decompress(&cinfo);
		return NULL;
	}
	dptr = pixels;

	/* decompress all the lines, a few at a time */

	while (cinfo.output_scanline < cinfo.output_height) {
		lptr = lines;
		for (i=0;i<cinfo.rec_outbuf_height;i++) {
			*lptr++=dptr;
			dptr+=w*3;
		}
		jpeg_read_scanlines(&cinfo, lines, cinfo.rec_outbuf_height);
		if (cinfo.output_components==1) {
			/* expand grey->colour */
			/* expand from the end of the memory down, so we can use
			   the same buffer */
			for (i=cinfo.rec_outbuf_height-1;i>=0;i--) {
				unsigned char *from, *to;
				from = lines[i]+w-1;
				to = lines[i]+w*3-3;
				for (j=w-1;j>=0;j--) {
					to[0] = from[0];
					to[1] = from[0];
					to[2] = from[0];
					to-=3;
					from--;
				}
			}
		}
	}

	jpeg_finish_decompress(&cinfo);
	jpeg_destroy_decompress(&cinfo);

	/* finish off, create the pixbuf */
	pixbuf = gdk_pixbuf_new (art_pixbuf_new_rgb (pixels, w, h, (w * 3)),
				 NULL);
	if (!pixbuf)
		art_free (pixels);
	
	return pixbuf;
}