int pc_patch_uncompressed_compute_extent(PCPATCH_UNCOMPRESSED *patch) { int i; PCPOINT *pt = pc_point_from_data(patch->schema, patch->data); PCBOUNDS b; double x, y; /* Calculate bounds */ pc_bounds_init(&b); for ( i = 0; i < patch->npoints; i++ ) { /* Just push the data buffer forward by one point at a time */ pt->data = patch->data + i * patch->schema->size; x = pc_point_get_x(pt); y = pc_point_get_y(pt); if ( b.xmin > x ) b.xmin = x; if ( b.ymin > y ) b.ymin = y; if ( b.xmax < x ) b.xmax = x; if ( b.ymax < y ) b.ymax = y; } patch->bounds = b; pcfree(pt); return PC_SUCCESS; }
PCPOINTLIST * pc_pointlist_from_dimensional(const PCPATCH_DIMENSIONAL *pdl) { PCPOINTLIST *pl; PCPATCH_DIMENSIONAL *pdl_uncompressed; const PCSCHEMA *schema = pdl->schema; int i, j, ndims, npoints; uint8_t *data; assert(pdl); pdl_uncompressed = pc_patch_dimensional_decompress(pdl); ndims = schema->ndims; npoints = pdl->npoints; pl = pc_pointlist_make(npoints); pl->mem = data = pcalloc(npoints * schema->size); for ( i = 0; i < npoints; i++ ) { PCPOINT *pt = pc_point_from_data(schema,data); for ( j = 0; j < ndims; j++ ) { PCDIMENSION *dim = pc_schema_get_dimension(schema, j); uint8_t *in = pdl_uncompressed->bytes[j].bytes + dim->size * i; uint8_t *out = data + dim->byteoffset; memcpy(out, in, dim->size); } pc_pointlist_add_point(pl, pt); data += schema->size; } pc_patch_dimensional_free(pdl_uncompressed); return pl; }
PCPOINTLIST * pc_pointlist_from_uncompressed(const PCPATCH_UNCOMPRESSED *patch) { int i; PCPOINTLIST *pl; size_t pt_size = patch->schema->size; uint32_t npoints = patch->npoints; pl = pc_pointlist_make(npoints); for ( i = 0; i < npoints; i++ ) { pc_pointlist_add_point(pl, pc_point_from_data(patch->schema, patch->data + i*pt_size)); } return pl; }
PCPOINT * pc_point_deserialize(const SERIALIZED_POINT *serpt, const PCSCHEMA *schema) { PCPOINT *pcpt; size_t pgsize = VARSIZE(serpt) + 1 - sizeof(SERIALIZED_POINT); /* * Big problem, the size on disk doesn't match what we expect, * so we cannot reliably interpret the contents. */ if ( schema->size != pgsize ) { elog(ERROR, "schema size and disk size mismatch, repair the schema"); return NULL; } pcpt = pc_point_from_data(schema, serpt->data); return pcpt; }
PCPOINT * pc_point_from_wkb(const PCSCHEMA *schema, uint8_t *wkb, size_t wkblen) { /* byte: endianness (1 = NDR, 0 = XDR) uint32: pcid (key to POINTCLOUD_SCHEMAS) uchar[]: data (interpret relative to pcid) */ const size_t hdrsz = 1+4; /* endian + pcid */ uint8_t wkb_endian; uint32_t pcid; uint8_t *data; PCPOINT *pt; if ( ! wkblen ) { pcerror("pc_point_from_wkb: zero length wkb"); } wkb_endian = wkb[0]; pcid = wkb_get_pcid(wkb); if ( (wkblen-hdrsz) != schema->size ) { pcerror("pc_point_from_wkb: wkb size inconsistent with schema size"); } if ( wkb_endian != machine_endian() ) { /* uncompressed_bytes_flip_endian creates a flipped copy */ data = uncompressed_bytes_flip_endian(wkb+hdrsz, schema, 1); } else { data = pcalloc(schema->size); memcpy(data, wkb+hdrsz, wkblen-hdrsz); } pt = pc_point_from_data(schema, data); pt->readonly = PC_FALSE; return pt; }
/** get point n, 0-based, positive */ PCPOINT *pc_patch_uncompressed_pointn(const PCPATCH_UNCOMPRESSED *patch, int n) { return pc_point_from_data(patch->schema, patch->data+n*patch->schema->size); }