Example #1
0
void melee_free(scene *scene) {
    melee_local *local = scene_get_userdata(scene);
    game_player *player2 = game_state_get_player(scene->gs, 1);

    surface_free(&local->feh);
    surface_free(&local->bleh);
    surface_free(&local->select_hilight);
    for(int i = 0; i < 2; i++) {
        component_free(local->bar_power[i]);
        component_free(local->bar_agility[i]);
        component_free(local->bar_endurance[i]);
    }

    for(int i = 0; i < 10; i++) {
        object_free(&local->pilots[i]);
        object_free(&local->harportraits_player1[i]);
        object_free(&local->har_player1[i]);
        if (player2->selectable) {
            object_free(&local->harportraits_player2[i]);
            object_free(&local->har_player2[i]);
        }
    }

    object_free(&local->player2_placeholder);
    object_free(&local->unselected_har_portraits);
    object_free(&local->bigportrait1);
    if (player2->selectable) {
        object_free(&local->bigportrait2);
    }
    free(local);
}
Example #2
0
static void textinput_free(component *c) {
    textinput *tb = widget_get_obj(c);
    surface_free(&tb->sur);
    free(tb->text);
    free(tb->buf);
    free(tb);
}
Example #3
0
void textbutton_free(component *c) {
    textbutton *tb = c->obj;
    if(tb->border_created) {
        surface_free(&tb->border);
    }
    free(tb);
    component_free(c);
}
Example #4
0
static void textbutton_free(component *c) {
    textbutton *tb = widget_get_obj(c);

    if(tb->border_created) {
        surface_free(&tb->border);
    }
    free(tb->text);
    free(tb);
}
Example #5
0
// newsroom callbacks
void newsroom_free(scene *scene) {
    newsroom_local *local = scene_get_userdata(scene);
    surface_free(&local->news_bg);
    str_free(&local->news_str);
    str_free(&local->pilot1);
    str_free(&local->pilot2);
    str_free(&local->har1);
    str_free(&local->har2);
    dialog_free(&local->continue_dialog);
    free(local);
}
Example #6
0
void bk_free(bk *b) {
    surface_free(&b->background);
    vector_free(&b->palettes);

    // Free info structs
    iterator it;
    hashmap_iter_begin(&b->infos, &it);
    hashmap_pair *pair = NULL;
    while((pair = iter_next(&it)) != NULL) {
        bk_info_free((bk_info*)pair->val);
    }
    hashmap_free(&b->infos);
}
Example #7
0
bool_t fb_putcode(struct fb * fb, u32_t code, u32_t fc, u32_t bc, u32_t x, u32_t y)
{
	struct surface_t * face;
	bool_t ret;

	face = surface_alloc_from_gimage(lookup_console_font_face(code, fc, bc));
	if(!face)
		return FALSE;

	ret = fb_blit(fb, face, x, y, face->w, face->h, 0, 0);
	surface_free(face);

	return ret;
}
Example #8
0
void textbutton_set_border(component *c, color col) {
    textbutton *tb = c->obj;
    tb->border_enabled = 1;
    tb->border_color = col;
    if(tb->border_created) {
        // destroy the old border first
        surface_free(&tb->border);
    }

    // create new border
    int chars = strlen(tb->text);
    int width = chars*tb->font->w;
    menu_background_border_create(&tb->border, width+6, tb->font->h+3);
    tb->border_created = 1;
}
Example #9
0
void textbutton_set_border(component *c, color col) {
    textbutton *tb = widget_get_obj(c);
    tb->border_enabled = 1;
    tb->border_color = col;
    if(tb->border_created) {
        // destroy the old border first
        surface_free(&tb->border);
    }

    // create new border
    int chars = strlen(tb->text);
    int fsize = text_char_width(&tb->tconf);
    int width = chars * fsize;
    menu_background_border_create(&tb->border, width+6, fsize+3);
    tb->border_created = 1;
}
Example #10
0
void vs_free(scene *scene) {
    vs_local *local = scene_get_userdata(scene);
    game_player *player2 = game_state_get_player(scene->gs, 1);

    dialog_free(&local->quit_dialog);
    dialog_free(&local->too_pathetic_dialog);
    surface_free(&local->arena_select_bg);
    object_free(&local->player1_portrait);
    object_free(&local->player2_portrait);
    object_free(&local->player1_har);
    object_free(&local->player2_har);
    if (player2->selectable) {
        object_free(&local->arena_select);
    }
    free(local);
}
Example #11
0
int video_area_capture(surface *sur, int x, int y, int w, int h) {
    float scale_x = (float)state.w / NATIVE_W;
    float scale_y = (float)state.h / NATIVE_H;

    // Correct position (take scaling into account)
    SDL_Rect r;
    r.x = x * scale_x;
    r.y = y * scale_y;
    r.w = w * scale_x;
    r.h = h * scale_y;

    // Create a new surface
    surface_create(sur, SURFACE_TYPE_RGBA, r.w, r.h);

    // Read pixels
    int ret = SDL_RenderReadPixels(state.renderer, &r, SDL_PIXELFORMAT_ABGR8888, sur->data, sur->w * 4);
    if(ret != 0) {
        surface_free(sur);
        PERROR("Unable to read pixels from renderer: %s", SDL_GetError());
        return 1;
    }

    return 0;
}
Example #12
0
void kernel_main(uint32_t mb_addr, uint32_t mb_magic)
{
	if(mb_magic != MULTIBOOT_BOOTLOADER_MAGIC)
	{
		kprintf(PANIC,"Wrong Bootloader Magic\n");
		for(;;);
	}

	multiboot_info_t* mb_info = (multiboot_info_t*)mb_addr;
	vbe_info_t* vbe_info = (vbe_info_t *)(mb_info->vbe_mode_info);

	uint32_t top = mb_info->mem_upper;
	uint32_t bot = mb_info->mem_lower;
	uint32_t mem = top+bot;

	clear_console();

	char version[20];
	get_version(version);
	kp("Welcome to ZOS v%s",version);

	kp("System Information");
	kp("	Booting Flag: 0x%x",mb_info->flags);
	if(check_flag(mb_info->flags,0))
		kp("	Available Memory: %d KB / %d MB",mem,mem/1024);
	if(check_flag(mb_info->flags,1))
		kp("	Booting Device: 0x%x",mb_info->boot_device);
	if(check_flag(mb_info->flags,2))
	{
		if(strlen((char*)mb_info->cmdline)>1)
			kp("	Booting Command: %s",(char*)mb_info->cmdline);
	}
	if(check_flag(mb_info->flags,3))
		{}
	if(check_flag(mb_info->flags,4))
		{}
	if(check_flag(mb_info->flags,5))
		kernel_elf = elf_from_multiboot(mb_info);
	if(check_flag(mb_info->flags,6))
	{
		/*
		multiboot_memory_map_t *mmap;
		kp ("mmap_addr = 0x%x, mmap_length = 0x%x",
			(unsigned) mb_info->mmap_addr, (unsigned) mb_info->mmap_length);
		for (mmap = (multiboot_memory_map_t *) mb_info->mmap_addr;
			(unsigned long) mmap < mb_info->mmap_addr + mb_info->mmap_length;
			mmap = (multiboot_memory_map_t *) ((unsigned long) mmap
			+ mmap->size + sizeof (mmap->size)))
		{
			kp (" size = 0x%x, base_addr = 0x%x%x,"
			" length = 0x%x%x, type = 0x%x",
			(unsigned) mmap->size,
			mmap->addr >> 32,
			mmap->addr & 0xffffffff,
			mmap->len >> 32,
			mmap->len & 0xffffffff,
			(unsigned) mmap->type);
		}
		*/		
	}
	gdt_init();		/* Global Descriptor Table */
	idt_init();		/* Interrupt Descriptor Table */
	isrs_init();	/* Interrupt Service Requests */
	irq_init();		/* Hardware Interrupt Requests */ 

	open_serial_output();

	timer_init();
	paging_init(mem);
	heap_init();
	
	keyboard_init();

	//pci_init();
	kp("login: "******"Welcome to ZOS\n",
		"Hello!\n",
		"abcdefghijklmnopqrstuvwxyz1234567890\n",
		0
	};
	for(int i=0;i!=3;i++)
	{
		for(int j = 0;j!=strlen(str[i]);j++)
		{
			gfx_print(str[i][j]);
		}
	}
	

	void render(window_t* win)
	{
	}

	void update(window_t* win)
	{
		surface_fill(win->surface,0,rgb(255,255,255));

		key_event_t* head;
		int len;
		keyboard_event_get(&head,&len);
		for(int i=0;i!=len;i++)
		{
			key_event_t* eve = head+i;
			if(eve->type == KEY_DOWN)
			{
				gfx_print(eve->character);
			}
		}
		keyboard_event_clear();
		
		rect_t trect = {0,0,720,20};
		for(int i=0;i!=24;i++)
		{
			if(strlen(gfx_con_buf[i]))
			{
				surface_t* surf = font_render(gfx_con_buf[i],col);
				surface_blend(surf,0,win->surface,&trect);
				surface_free(surf);
			}
			trect.y += 20;
		}
	}
Example #13
0
struct surface_t * map_software_rotate(struct surface_t * surface, struct rect_t * rect, enum rotate_type type)
{
	struct surface_t * rotate;
	struct rect_t clipped;
	u32_t w, h;

	if(!surface)
		return NULL;

	if (!surface->pixels)
		return NULL;

	if (surface->info.bits_per_pixel < 8)
		return NULL;

	clipped.x = 0;
	clipped.y = 0;
	clipped.w = surface->w;
	clipped.h = surface->h;

	if(rect)
	{
		if (!rect_intersect(rect, &clipped, &clipped))
			return NULL;
	}
	rect = &clipped;

	switch(type)
	{
	case ROTATE_DEGREE_0:
	case ROTATE_DEGREE_180:
	case ROTATE_MIRROR_H:
	case ROTATE_MIRROR_V:
		w = rect->w;
		h = rect->h;
		break;

	case ROTATE_DEGREE_90:
	case ROTATE_DEGREE_270:
		w = rect->h;
		h = rect->w;
		break;

	default:
		return NULL;
	}

	rotate = surface_alloc(NULL, w, h, surface->info.fmt);
	if(!rotate)
		return NULL;

	switch (surface->info.bytes_per_pixel)
	{
	case 1:
		software_rotate_1byte(rotate, surface, rect, type);
		break;

	case 2:
		software_rotate_2byte(rotate, surface, rect, type);
		break;

	case 3:
		software_rotate_3byte(rotate, surface, rect, type);
		break;

	case 4:
		software_rotate_4byte(rotate, surface, rect, type);
		break;

	default:
		surface_free(rotate);
		return NULL;
	}

	return rotate;
}
Example #14
0
void scoreboard_free(scene *scene) {
    scoreboard_local *local = scene_get_userdata(scene);
    surface_free(&local->black_surface);
    free(local);
}
Example #15
0
int
geomap(
        const size_t ninput, const coord_t* const input,
        const size_t nref, const coord_t* const ref,
        const bbox_t* const bbox,
        const geomap_fit_e fit_geometry,
        const surface_type_e function,
        const size_t xxorder,
        const size_t xyorder,
        const size_t yxorder,
        const size_t yyorder,
        const xterms_e xxterms,
        const xterms_e yxterms,
        const size_t maxiter,
        const double reject,
        /* Input/Output */
        size_t* const noutput,
        /* Output */
        geomap_output_t* const output, /* [MAX(ninput, nref)] */
        geomap_result_t* const result,
        stimage_error_t* const error) {

    geomap_fit_t     fit;
    bbox_t           tbbox;
    size_t           ninput_in_bbox = ninput;
    size_t           nref_in_bbox   = nref;
    coord_t*         input_in_bbox  = NULL;
    coord_t*         ref_in_bbox    = NULL;
    double*          xfit           = NULL;
    double*          yfit           = NULL;
    double*          weights        = NULL;
    double*          tweights       = NULL;
    geomap_output_t* outi           = NULL;
    surface_t        sx1, sy1, sx2, sy2;
    int              has_sx2        = 0;
    int              has_sy2        = 0;
    size_t           i              = 0;
    double           my_nan         = fmod(1.0, 0.0);
    int              status         = 1;

    assert(input);
    assert(ref);
    assert(error);

    if (ninput != nref) {
        stimage_error_set_message(
            error, "Must have the same number of input and reference coordinates.");
        goto exit;
    }

    surface_new(&sx1);
    surface_new(&sy1);
    surface_new(&sx2);
    surface_new(&sy2);

    geomap_fit_init(
            &fit, geomap_proj_none, fit_geometry, function,
            xxorder, xyorder, xxterms, yxorder, yyorder, yxterms,
            maxiter, reject);

    /* If bbox is NULL, provide a dummy one full of NaNs */
    if (bbox == NULL) {
        bbox_init(&tbbox);
    } else {
        bbox_copy(bbox, &tbbox);
    }

    /* If the bbox is all NaNs, we don't need to reduce the data, saving an
       alloc and copy */
    if (bbox == NULL ||
        (!isfinite64(tbbox.min.x) && !isfinite64(tbbox.min.y) &&
         !isfinite64(tbbox.max.x) && !isfinite64(tbbox.max.y))) {
        /* If we have no bbox, we don't need to allocate and copy */
        input_in_bbox = (coord_t*)input;
        ref_in_bbox = (coord_t*)ref;
        ninput_in_bbox = ninput;
        nref_in_bbox = nref;
    } else {
        input_in_bbox = malloc_with_error(
                ninput * sizeof(coord_t), error);
        if (input_in_bbox == NULL) goto exit;

        ref_in_bbox = malloc_with_error(
                nref * sizeof(coord_t), error);
        if (ref_in_bbox == NULL) goto exit;

        /* Reduce data to only those in the bbox */
        ninput_in_bbox = nref_in_bbox = limit_to_bbox(
                ninput, input, ref, &tbbox, input_in_bbox, ref_in_bbox);
    }

    /* Compute the mean of the reference and input coordinates */
    compute_mean_coord(nref_in_bbox, ref_in_bbox, &fit.oref);
    compute_mean_coord(ninput_in_bbox, input_in_bbox, &fit.oin);

    /* Set the reference point for the projections to undefined */
    fit.refpt.x = my_nan;
    fit.refpt.y = my_nan;

    /* Allocate some memory */
    xfit = malloc_with_error(ninput_in_bbox * sizeof(double), error);
    if (xfit == NULL) goto exit;

    yfit = malloc_with_error(ninput_in_bbox * sizeof(double), error);
    if (yfit == NULL) goto exit;

    /* Compute the weights */
    weights = malloc_with_error(ninput_in_bbox * sizeof(double), error);
    if (weights == NULL) goto exit;

    for (i = 0; i < ninput_in_bbox; ++i) {
        weights[i] = 1.0;
    }

    /* Determine the actual max and min of the coordinates */
    determine_bbox(nref_in_bbox, ref_in_bbox, &tbbox);
    bbox_copy(&tbbox, &fit.bbox);

    if (geofit(
                &fit, &sx1, &sy1, &sx2, &sy2, &has_sx2, &has_sy2,
                ninput_in_bbox, input_in_bbox, ref_in_bbox, weights,
                error)) goto exit;

    /* Compute the fitted x and y values */
    if (geoeval(
                &sx1, &sy1, &sx2, &sy2, has_sx2, has_sy2, ninput_in_bbox,
                ref_in_bbox, xfit, yfit, error)) goto exit;

    if (geo_get_results(
                &fit, &sx1, &sy1, &sx2, &sy2, has_sx2, has_sy2, result,
                error)) goto exit;

    /* DIFF: This section is from geo_plistd */

    /* Copy the results to the output buffer */
    tweights = malloc_with_error(ninput_in_bbox * sizeof(double), error);
    if (tweights == NULL) goto exit;

    for (i = 0; i < ninput_in_bbox; ++i) {
        tweights[i] = weights[i];
    }

    for (i = 0; i < fit.nreject; ++i) {
        assert(fit.rej);
        assert(fit.rej[i] < ninput_in_bbox);
        if (weights[fit.rej[i]] > 0.0) {
            tweights[fit.rej[i]] = 0.0;
        }
    }

    outi = output;
    for (i = 0; i < ninput_in_bbox; ++i, ++outi) {
        outi->ref.x = ref_in_bbox[i].x;
        outi->ref.y = ref_in_bbox[i].y;
        outi->input.x = input_in_bbox[i].x;
        outi->input.y = input_in_bbox[i].y;
        if (tweights[i] > 0.0) {
            outi->fit.x = xfit[i];
            outi->fit.y = yfit[i];
            outi->residual.x = input_in_bbox[i].x - xfit[i];
            outi->residual.y = input_in_bbox[i].y - yfit[i];
        } else {
            outi->fit.x = my_nan;
            outi->fit.y = my_nan;
            outi->residual.x = my_nan;
            outi->residual.y = my_nan;
        }
    }
    *noutput = ninput_in_bbox;

    status = 0;

 exit:

    if (input_in_bbox != input) {
        free(input_in_bbox);
    }
    if (ref_in_bbox != ref) {
        free(ref_in_bbox);
    }
    free(weights);
    free(xfit);
    free(yfit);
    free(tweights);
    surface_free(&sx1);
    surface_free(&sy1);
    surface_free(&sx2);
    surface_free(&sy2);

    return status;
}
Example #16
0
void menu_free(menu *menu) {
    vector_free(&menu->objs);
    surface_free(&menu->sur);
}
Example #17
0
SDL_Texture* tcache_get(surface *sur,
                        screen_palette *pal,
                        char *remap_table,
                        uint8_t pal_offset) {

    if(sur == NULL || sur->w == 0 || sur->h == 0 || sur->data == NULL) {
        if(sur != NULL) {
            DEBUG("Invalid surface requested from tcache: w,h = %d,%d data = %p", sur->w, sur->h, sur->data);
        } else {
            DEBUG("Invalid surface requested from tcache: w,h = %d,%d surface = %p", sur->w, sur->h, sur);
        }
        return NULL;
    }

    // Form a key
    tcache_entry_key key;
    memset(&key, 0, sizeof(tcache_entry_key));
    key.c_pal_offset = (sur->type == SURFACE_TYPE_RGBA) ? 0 : pal_offset;
    key.c_remap_table = (sur->type == SURFACE_TYPE_RGBA) ? 0 : remap_table;
    key.c_surface = sur;
    key.w = sur->w;
    key.h = sur->h;

    // Attempt to find appropriate surface
    // If surface is cacheable and hasn't changed, just return here.
    tcache_entry_value *val = tcache_get_entry(&key);
    if(val != NULL && (val->pal_version == pal->version || sur->type == SURFACE_TYPE_RGBA) && !sur->force_refresh) {
        val->age = 0;
        cache->hits++;
        return val->tex;
    }

    // Reset refresh flag here
    sur->force_refresh = 0;

    // If there was no fitting surface tex in the cache at all,
    // then we need to create one
    if(val == NULL) {
        tcache_entry_value new_entry;
        new_entry.age = 0;
        new_entry.pal_version = pal->version;
        new_entry.tex = SDL_CreateTexture(cache->renderer,
                                          SDL_PIXELFORMAT_ABGR8888,
                                          SDL_TEXTUREACCESS_STREAMING,
                                          sur->w * cache->scale_factor,
                                          sur->h * cache->scale_factor);
        SDL_SetTextureBlendMode(new_entry.tex, SDL_BLENDMODE_BLEND);
        val = tcache_add_entry(&key, &new_entry);
    }

    // We have a texture either from the cache, or we just created one.
    // Either one, it needs to be updated. Let's do it now.
    // Also, scale surface if necessary
    if(cache->scale_factor > 1) {
        char *raw = malloc(sur->w * sur->h * 4);
        surface scaled;
        surface_create(&scaled,
                       SURFACE_TYPE_RGBA,
                       sur->w * cache->scale_factor,
                       sur->h * cache->scale_factor);

        surface_to_rgba(sur, raw, pal, remap_table, pal_offset);
        scaler_scale(cache->scaler, raw, scaled.data, sur->w, sur->h, cache->scale_factor);
        surface_to_texture(&scaled, val->tex, pal, remap_table, pal_offset);
        surface_free(&scaled);
        free(raw);
    } else {
        surface_to_texture(sur, val->tex, pal, remap_table, pal_offset);
    }

    // Set correct age and palette version
    val->age = 0;
    val->pal_version = pal->version;

    // Do some statistics stuff
    cache->misses++;
    return val->tex;
}
Example #18
0
/* DIFF: was gto_fit_rxyscale */
static int
geo_fit_linear(
        geomap_fit_t* const fit,
        surface_t* const sx1,
        surface_t* const sy1,
        const size_t ncoord,
        const coord_t* const input,
        const coord_t* const ref,
        const double* const weights,
        double* const residual_x,
        double* const residual_y,
        stimage_error_t* error) {

    bbox_t  bbox;
    double  sw      = 0.0;
    coord_t sr      = {0.0, 0.0};
    coord_t si      = {0.0, 0.0};
    coord_t r0      = {0.0, 0.0};
    coord_t i0      = {0.0, 0.0};
    double  sxrxr   = 0.0;
    double  syryr   = 0.0;
    double  syrxi   = 0.0;
    double  sxryi   = 0.0;
    double  sxrxi   = 0.0;
    double  syryi   = 0.0;
    double  num     = 0.0;
    double  denom   = 0.0;
    double  theta   = 0.0;
    double  ctheta  = 0.0;
    double  stheta  = 0.0;
    coord_t cthetac = {0.0, 0.0};
    coord_t sthetac = {0.0, 0.0};
    double  xmag    = 0.0;
    double  ymag    = 0.0;
    size_t  i       = 0;
    int     status  = 1;

    assert(fit);
    assert(sx1);
    assert(sy1);
    assert(input);
    assert(ref);
    assert(weights);
    assert(residual_x);
    assert(residual_y);

    surface_free(sx1);
    surface_free(sy1);

    bbox_copy(&fit->bbox, &bbox);
    bbox_make_nonsingular(&bbox);

    /* Compute the sums required to determine the offsets */
    compute_sums(ncoord, input, ref, weights, &sw, &si, &sr);

    if (sw < 3.0) {
        if (fit->projection == geomap_proj_none) {
            stimage_error_set_message(
                    error, "Too few data points for X and Y fits.");
        } else {
            stimage_error_set_message(
                    error, "Too few data points for XI and ETA fits.");
        }
        goto exit;
    }

    r0.x = sr.x / sw;
    r0.y = sr.y / sw;
    i0.x = si.x / sw;
    i0.y = si.y / sw;
    for (i = 0; i < ncoord; ++i) {
        sxrxr += weights[i] * (ref[i].x - r0.x) * (ref[i].x - r0.x);
        syryr += weights[i] * (ref[i].y - r0.y) * (ref[i].y - r0.y);
        syrxi += weights[i] * (ref[i].y - r0.y) * (input[i].x - i0.x);
        sxryi += weights[i] * (ref[i].x - r0.x) * (input[i].y - i0.y);
        sxrxi += weights[i] * (ref[i].x - r0.x) * (input[i].x - i0.x);
        syryi += weights[i] * (ref[i].y - r0.y) * (input[i].y - i0.y);
    }

    /* Compute the rotation angle */
    num = 2.0 * (sxrxr * syrxi * syryi - syryr * sxrxi * sxryi);
    denom = syryr * (sxrxi - sxryi) * (sxrxi + sxryi) - \
        sxrxr * (syrxi + syryi) * (syrxi - syryi);
    if (double_approx_equal(num, 0.0) && double_approx_equal(denom, 0.0)) {
        theta = 0.0;
    } else {
        theta = atan2(num, denom) / 2.0;
        if (theta < 0.0) {
            theta += M_PI * 2.0;
        }
    }

    ctheta = cos(theta);
    stheta = sin(theta);

    /* Compute the X magnification factor */
    num = sxrxi * ctheta - sxryi * stheta;
    denom = sxrxr;
    if (denom <= 0.0) {
        xmag = 1.0;
    } else {
        xmag = num / denom;
    }

    /* Compute the Y magnification factor */
    num = syrxi * stheta + syryi * ctheta;
    denom = syryr;
    if (denom <= 0.0) {
        ymag = 1.0;
    } else {
        ymag = num / denom;
    }

    /* Compute the polynomial coefficients */
    cthetac.x = xmag * ctheta;
    sthetac.x = ymag * stheta;
    sthetac.y = xmag * stheta;
    cthetac.x = ymag * ctheta;

    /* Compute the X and Y fit coefficients */
    if (compute_surface_coefficients(
                fit->function, &bbox, &i0, &r0, &cthetac, &sthetac, sx1, sy1,
                error)) goto exit;

    /* Compute the residuals */
    if (compute_residuals(
                sx1, sy1, ncoord, input, ref, residual_x, residual_y,
                error)) goto exit;

    /* Compute the number of zero-weighted points */
    fit->n_zero_weighted = count_zero_weighted(ncoord, weights);

    /* Compute the rms of the x and y fits */
    compute_rms(
            ncoord, weights, residual_x, residual_y, &fit->xrms, &fit->yrms);

    fit->ncoord = ncoord;

    status = 0;

 exit:

    return status;
}
Example #19
0
/* was geo_fxyd */
static int
geo_fit_xy(
        geomap_fit_t* const fit,
        surface_t* const sf1,
        surface_t* const sf2,
        const size_t ncoord,
        const int xfit,
        const coord_t* const input,
        const coord_t* const ref,
        /* Output */
        int* has_secondary,
        double* const weights,
        double* const residual,
        stimage_error_t* error) {

    bbox_t              bbox;
    double*             zfit      = NULL;
    const double* const z = (double*)input + (xfit ? 0 : 1);
    surface_t           savefit;
    surface_fit_error_e fit_error = surface_fit_error_ok;
    size_t              i         = 0;
    int                 status    = 1;

    assert(fit);
    assert(sf1);
    assert(sf2);
    assert(ref);
    assert(weights);
    assert(residual);
    assert(has_secondary);
    assert(error);

    surface_new(&savefit);

    surface_free(sf1);
    surface_free(sf2);

    *has_secondary = 1;

    zfit = malloc_with_error(ncoord * sizeof(double), error);
    if (zfit == NULL) goto exit;

    bbox_copy(&fit->bbox, &bbox);
    bbox_make_nonsingular(&bbox);

    if (xfit) {
        switch(fit->fit_geometry) {
        case geomap_fit_shift:
            if (surface_init(
                        &savefit, fit->function, 2, 2, xterms_none, &bbox,
                        error)) goto exit;
            surface_free(sf1);
            if (surface_init(
                        sf1, fit->function, 1, 1, xterms_none, &bbox,
                        error)) goto exit;
            for (i = 0; i < ncoord; ++i) {
                zfit[i] = z[i<<1] - ref[i].x;
            }

            if (surface_fit(
                        sf1, ncoord, ref, zfit, weights,
                        surface_fit_weight_user, &fit_error, error)) goto exit;

            if (fit->function == surface_type_polynomial) {
                savefit.coeff[0] = sf1->coeff[0];
                savefit.coeff[1] = 1.0;
                savefit.coeff[2] = 0.0;
            } else {
                savefit.coeff[0] = sf1->coeff[0] + (bbox.max.x + bbox.min.x) / 2.0;
                savefit.coeff[1] = (bbox.max.x - bbox.min.x) / 2.0;
                savefit.coeff[2] = 0.0;
            }
            surface_free(sf1);
            if (surface_copy(&savefit, sf1, error)) goto exit;
            *has_secondary = 0;
            break;

        case geomap_fit_xyscale:
            if (surface_init(
                        sf1, fit->function, 2, 1, xterms_none, &bbox,
                        error)) goto exit;
            if (surface_fit(
                        sf1, ncoord, ref, z, weights,
                        surface_fit_weight_user, &fit_error, error)) goto exit;
            *has_secondary = 0;
            break;

        default:
            if (surface_init(
                        sf1, fit->function, 2, 2, xterms_none, &bbox,
                        error)) goto exit;
            if (surface_fit(
                        sf1, ncoord, ref, z, weights,
                        surface_fit_weight_user, &fit_error, error)) goto exit;

            if (fit->xxorder > 2 || fit->xyorder > 2 ||
                fit->xxterms == xterms_full) {
                if (surface_init(
                            sf2, fit->function, fit->xxorder, fit->xyorder,
                            fit->xxterms, &fit->bbox, error)) {
                    surface_free(sf1);
                    goto exit;
                }
            } else {
                *has_secondary = 0;
            }
            break;
        }
    } else {
        switch(fit->fit_geometry) {
        case geomap_fit_shift:
            if (surface_init(
                        &savefit, fit->function, 2, 2, xterms_none, &bbox,
                        error)) goto exit;
            surface_free(sf1);
            if (surface_init(
                        sf1, fit->function, 1, 1, xterms_none, &bbox,
                        error)) goto exit;
            for (i = 0; i < ncoord; ++i) {
                zfit[i] = z[i<<1] - ref[i].y;
            }
            if (surface_fit(
                        sf1, ncoord, ref, zfit, weights,
                        surface_fit_weight_user, &fit_error, error)) goto exit;
            if (fit->function == surface_type_polynomial) {
                savefit.coeff[0] = sf1->coeff[0];
                savefit.coeff[1] = 0.0;
                savefit.coeff[2] = 1.0;
            } else {
                savefit.coeff[0] = sf1->coeff[0] + (bbox.min.y + bbox.max.y) / 2.0;
                savefit.coeff[1] = 0.0;
                savefit.coeff[2] = (bbox.max.y - bbox.min.y) / 2.0;
            }
            surface_free(sf1);
            if (surface_copy(&savefit, sf1, error)) goto exit;

            *has_secondary = 0;
            break;

        case geomap_fit_xyscale:
            if (surface_init(
                        sf1, fit->function, 1, 2, xterms_none, &bbox,
                        error)) goto exit;
            if (surface_fit(
                        sf1, ncoord, ref, z, weights,
                        surface_fit_weight_user, &fit_error, error)) goto exit;
            *has_secondary = 0;
            break;

        default:
            if (surface_init(
                        sf1, fit->function, 2, 2, xterms_none, &bbox,
                        error)) goto exit;
            if (surface_fit(
                        sf1, ncoord, ref, z, weights,
                        surface_fit_weight_user, &fit_error, error)) goto exit;
            if (fit->yxorder > 2 || fit->yyorder > 2 ||
                fit->yxterms == xterms_full) {
                if (surface_init(
                            sf2, fit->function, fit->yxorder, fit->yyorder,
                            fit->yxterms, &bbox, error)) goto exit;
            } else {
                *has_secondary = 0;
            }

            break;
        }
    }

    if (_geo_fit_xy_validate_fit_error(
                fit_error, xfit, fit->projection, error)) goto exit;

    if (surface_vector(sf1, ncoord, ref, residual, error)) goto exit;
    for (i = 0; i < ncoord; ++i) {
        residual[i] = z[i<<1] - residual[i];
    }

    /* Calculate the higher-order fit */
    if (*has_secondary) {
        if (surface_fit(
                    sf2, ncoord, ref, residual, weights,
                    surface_fit_weight_user, &fit_error, error)) goto exit;
        if (_geo_fit_xy_validate_fit_error(
                    fit_error, xfit, fit->projection, error)) goto exit;

        if (surface_vector(sf2, ncoord, ref, zfit, error)) goto exit;
        for (i = 0; i < ncoord; ++i) {
            residual[i] = zfit[i] - residual[i];
        }
    }

    /* Compute the number of zero weighted points */
    fit->n_zero_weighted = count_zero_weighted(ncoord, weights);

    /* Calculate the RMS of the fit */
    if (xfit) {
        fit->xrms = 0.0;
        for (i = 0; i < ncoord; ++i) {
            fit->xrms += weights[i] * residual[i] * residual[i];
        }
    } else {
        fit->yrms = 0.0;
        for (i = 0; i < ncoord; ++i) {
            fit->yrms += weights[i] * residual[i] * residual[i];
        }
    }

    fit->ncoord = ncoord;

    status = 0;

 exit:

    surface_free(&savefit);
    free(zfit);

    return status;
}