Пример #1
0
trans2D_t *invert_transform(trans2D_t *T) {
    double d = det(T);
    double cofactor;
    int i, j;
    int one[3] = { 1, 0, 0 };
    int two[3] = { 2, 2, 1 };

    trans2D_t *Tinv = new_identity_transform(), *I;
    
    /* Check if the transform is invertible */
    if (d == 0.0) {
        printf("Singular transformation detected!\n");
        return NULL;
    }
  
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 3; j++) {
            int parity = (i+j) % 2;
            cofactor = (parity ? -1.0 : 1.0) * 
                (T->T[one[i]][one[j]] * T->T[two[i]][two[j]] - 
                 T->T[one[i]][two[j]] * T->T[two[i]][one[j]]);

            Tinv->T[j][i] = cofactor / d;
        }
    }

    I = transform_product(T, Tinv);
    printf("Tinv:\n");
    print_transform(Tinv);
    printf("I:\n");
    print_transform(I);
    transform_free(I);

    return Tinv;
}
Пример #2
0
bvol_t *transform_bin_volume_2D(bvol_t *b, trans2D_t *T) {
    /* Test each point in the plane for inclusion in the new
     * (transformed) binary image */
    bvol_t *Tb = new_bin_volume(b->w, b->h, b->d, BVOL_BITS);

    /* Compute the inverse of T */
    trans2D_t *Tinv = transform_invert(T);

    int x, y, z;
    int xc, yc, zc;

    for (z = 0; z < (int) b->d; z++) {
        for (y = 0; y < (int) b->h; y++) {
            for (x = 0; x < (int) b->w; x++) {
                double out[3];
                
                transform_point(Tinv, (double) x, (double) y, out + 0, out + 1);
		out[2] = z;

                /* Check if the point lies in the set */
                xc = iround(out[0]);
                yc = iround(out[1]);
                zc = iround(out[2]);

                if (bvol_getbit(b, xc, yc, zc))
                    bvol_setbit(Tb, x, y, z);
            }
        }
    }
    
    transform_free(Tinv);

    return Tb;
}
Пример #3
0
/* Create a new image by applying transformation T to img and 
 * resampling.  Resize the image so that the whole thing fits when
 * transformed. */
img_t *img_resample_bbox(img_t *img, trans2D_t *T) {
    int w = img->w, h = img->h;
    int x, y;
    trans2D_t *Tinv = transform_invert(T);
    int w_new, h_new, i;
    // double x_min = DBL_MAX, x_max = -DBL_MAX, y_min = DBL_MAX, y_max = -DBL_MAX;
    v2_t min = v2_new(DBL_MAX, DBL_MAX);
    v2_t max = v2_new(-DBL_MAX, -DBL_MAX);
    v2_t origin;
    img_t *Timg;

    /* Find the new dimensions of the window */
    v2_t crs[4]; /* Four corners of the original image */

    crs[0] = v2_new(0, 0);
    crs[1] = v2_new(0, h - 1);
    crs[2] = v2_new(w - 1, 0);
    crs[3] = v2_new(w - 1, h - 1);

    for (i = 0; i < 4; i++) {
	crs[i] = v2_add(crs[i], img->origin);
	crs[i] = transform_vector(T, crs[i]);
	min = v2_minimum(min, crs[i]);
	max = v2_maximum(max, crs[i]);
    }

    Vx(min) = floor(Vx(min));
    Vy(min) = floor(Vy(min));

    w_new = iround(floor(Vx(max) - Vx(min) + 1));
    h_new = iround(floor(Vy(max) - Vy(min) + 1));
    origin = min;

    Timg = img_new(w_new, h_new);
    Timg->origin = origin;

    for (y = 0; y < h_new; y++) {
        for (x = 0; x < w_new; x++) {
            double Tp[2];
	    fcolor_t c;

            /* Invert the point (x, y) - trans */
            transform_point(Tinv, x + Vx(origin), y + Vy(origin), &Tp[0], &Tp[1]);
            
#if 1
            /* Check if the result is in range */
            if (Tp[0] < Vx(img->origin) || Tp[1] < Vy(img->origin) || 
		Tp[0] > Vx(img->origin) + w - 1 || Tp[1] > Vy(img->origin) + h - 1) {

		/* pass */

	    } else {
		/* Check if the result is valid */
		int x_f = (int) (Tp[0] - Vx(img->origin));
		int x_c = x_f + 1;
		int y_f = (int) (Tp[1] - Vy(img->origin));
		int y_c = y_f + 1;

		if (img_pixel_is_valid(img, x_f, y_f) ||
		    img_pixel_is_valid(img, x_c, y_f) ||
		    img_pixel_is_valid(img, x_f, y_c) ||
		    img_pixel_is_valid(img, x_c, y_c)) {

		    /* Apply bilinear interpolation */
		    c = pixel_lerp(img, Tp[0] - Vx(img->origin), Tp[1] - Vy(img->origin));
		    img_set_pixel(Timg, x, y, iround(c.r), iround(c.g), iround(c.b));
		} else {
		    // img_nullify_pixel(Timg, x, y);
		}
		
            }
#else
	    if (Tp[0] < 0.0) Tp[0] = 0.0;
	    else if (Tp[0] > w - 1) Tp[0] = w - 1;
	    if (Tp[1] < 0.0) Tp[1] = 0.0;
	    else if (Tp[1] > h - 1) Tp[1] = h - 1;

	    c = pixel_lerp(img, Tp[0], Tp[1]);
	    img_set_pixel(Timg, x, y, c.r, c.g, c.b);
#endif
        }
    }

    /* Add the old origin to the image */
    // Timg->origin = v2_add(origin, img->origin);
    transform_free(Tinv);

    return Timg;
}
Пример #4
0
/**
 * \defgroup public Kitsune API
 * 
 * Calls to kitsune_update indicate that a possible update point has been
 * reached.  The argument "pt_name" provides an identifier indicating which
 * point was reached.
 * @{
 */
void kitsune_update(const char *pt_name)
{
  /*
   * If we were starting up following an update from a previous version (and so
   * the updating flag is set) the fact that we have reached an update point
   * indicates that we are done starting up and now resume regular execution.
   */
  if (kitsune_is_updating()) {

    /*
     * If we're starting up following an update, but we're not at the update
     * point corresponding to the long-running loop that we need to reach, then
     * we just return.  This allows reaching intermediate upate points on the
     * way to the final point.
     */
    if (!kitsune_is_updating_from(pt_name))
      return;
    
    /*
     * We may wish to perform some initialization (e.g., altering the set of
     * threads) after we reach the main thread's update point, but before any
     * child threads are created.
     */
#ifdef ENABLE_THREADING
    if (ktthread_is_main()) {
#endif
      state_xform_fn_t mu_fn = kitsune_get_cur_val("_kitsune_mainupdate_xform");
      if (mu_fn) {
        kitsune_log("Calling main-update transformation function.");
        mu_fn();
      }
#ifdef ENABLE_THREADING
    }
#endif

#ifdef ENABLE_THREADING
    if (ktthread_is_main()) {
      
      /* Now that we've reached the main loop of the main thread, we can kick
         off execution of the child threads and then wait until they reach their
         main loops (or die) */
      ktthread_launch_wait();
#endif
      
      /*
       * Free any memory used to store the old versions stack variables (those
       * managed through the stackvars API).
       */
      kitsune_log("before freeing....");
      bench_log_resource_usage();
      stackvars_free();
      registervars_free();
      addresscheck_free();
      
      /*
       * Since we're done accessing values from the previous version, we now close
       * our handle to its shared library which makes its state inaccessible and
       * unloads its code.
       */
      if (dlclose(prev_ver_handle)) {
        kitsune_log("dlclose: error occurred: (%s)\n", dlerror());
        exit(1);
      }

      prev_ver_handle = NULL;
      transform_free();

      bench_finish();
      kitsune_log("teardown complete....");
      bench_log_resource_usage();

#ifdef ENABLE_THREADING
      /* Signal threads to continue running */
      ktthread_main_finish_update();
    } else {
      stackvars_free();
      ktthread_finish_update();
    }
#endif
  }
  
  /*
   * Check whether an update is available.
   */
  if (update_requested) {
    kitsune_log("Updating(%s)...\n", pt_name);

    bench_log_resource_usage();
    bench_start();

    /*
     * Move current stack variables (managed through the stackvars API) from the
     * stack to the heap.
     */
    stackvars_move_to_heap();
    
#ifdef ENABLE_THREADING
    ktthread_rapidq();
    if (ktthread_is_main()) {
#endif
      /*
       * To update, we store the current update point taken to make it available
       * to the next version 
       */
      update_pt = pt_name;
      
      /* 
       * And then longjmp back to the driver code.
       */
      assert(jmp_env != NULL);
      longjmp(*jmp_env, 1);
#ifdef ENABLE_THREADING
    } else {
      ktthread_do_update(pt_name);
    }
#endif
  }
}