extern int metric_tensor(vector_t v, mt_t mt, m2_t *m2) { double a[3]; bilinear_t *B[3] = {mt.a, mt.b, mt.c}; for (int i = 0 ; i < 3 ; i++) { int err = bilinear(v.x, v.y, B[i], a+i); switch (err) { case ERROR_OK: break; case ERROR_NODATA: default: return err; } } M2A(*m2) = a[0]; M2B(*m2) = a[1]; M2C(*m2) = a[1]; M2D(*m2) = a[2]; return ERROR_OK; }
/** Return an allocated memory item to its memory pool. */ void mp_pool_release(void *item) { mp_allocated_t *allocated = (void*) M2A(item); mp_chunk_t *chunk = allocated->in_chunk; ASSERT(chunk); ASSERT(chunk->magic == MP_CHUNK_MAGIC); ASSERT(chunk->n_allocated > 0); allocated->u.next_free = chunk->first_free; chunk->first_free = allocated; if (PREDICT_UNLIKELY(chunk->n_allocated == chunk->capacity)) { /* This chunk was full and is about to be used. */ mp_pool_t *pool = chunk->pool; /* unlink from the full list */ if (chunk->prev) chunk->prev->next = chunk->next; if (chunk->next) chunk->next->prev = chunk->prev; if (chunk == pool->full_chunks) pool->full_chunks = chunk->next; /* link to the used list. */ chunk->next = pool->used_chunks; chunk->prev = NULL; if (chunk->next) chunk->next->prev = chunk; pool->used_chunks = chunk; } else if (PREDICT_UNLIKELY(chunk->n_allocated == 1)) { /* This was used and is about to be empty. */ mp_pool_t *pool = chunk->pool; /* Unlink from the used list */ if (chunk->prev) chunk->prev->next = chunk->next; if (chunk->next) chunk->next->prev = chunk->prev; if (chunk == pool->used_chunks) pool->used_chunks = chunk->next; /* Link to the empty list */ chunk->next = pool->empty_chunks; chunk->prev = NULL; if (chunk->next) chunk->next->prev = chunk; pool->empty_chunks = chunk; /* Reset the guts of this chunk to defragment it, in case it gets * used again. */ chunk->first_free = NULL; chunk->next_mem = chunk->mem; ++pool->n_empty_chunks; } --chunk->n_allocated; }
extern int metric_tensor_new(bbox_t bb, int nx, int ny, mt_t *mt) { int err; bilinear_t* B[4]; for (int k = 0 ; k < 4 ; k++) { if (!(B[k] = bilinear_new())) return ERROR_MALLOC; if ((err = bilinear_dimension(nx,ny,bb,B[k])) != ERROR_OK) return err; } for (int i = 0 ; i < nx ; i++) { for (int j = 0 ; j < ny ; j++) { arrow_t A; bilinear_getxy(i, j, B[0], &(A.centre.x), &(A.centre.y)); err = evaluate(&A); switch (err) { ellipse_t E; m2_t m2; case ERROR_OK: arrow_ellipse(&A,&E); m2 = ellipse_mt(E); bilinear_setz(i, j, M2A(m2), B[0]); bilinear_setz(i, j, M2B(m2), B[1]); bilinear_setz(i, j, M2D(m2), B[2]); bilinear_setz(i, j, E.major*E.minor*M_PI, B[3]); break; case ERROR_NODATA: break; default: return err; } } } mt->a = B[0]; mt->b = B[1]; mt->c = B[2]; mt->area = B[3]; return ERROR_OK; }