/** * 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 }
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; }
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); }
/** * 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 }
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); }
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; }
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); }
/** * 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; }
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; }
/** * 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; }
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; }
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; }
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; }
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); }
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 }
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); }
//! //! 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; }
/** * 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 }
/** * art_alphagamma_free: Free an #ArtAlphaGamma. * @alphagamma: An #ArtAlphaGamma. * * Frees the #ArtAlphaGamma. **/ void art_alphagamma_free (ArtAlphaGamma *alphagamma) { art_free (alphagamma); }
//! //! 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); }
/** * 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; }
//! //! 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); }
//! //! 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); }
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; }