1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
/***********************************************************************
* pc_pointlist.c
*
* Point list handling. Create, get and set values from the
* basic PCPOINTLIST structure.
*
* PgSQL Pointcloud is free and open source software provided
* by the Government of Canada
* Copyright (c) 2013 Natural Resources Canada
*
***********************************************************************/
#include "pc_api_internal.h"
#include <assert.h>
PCPOINTLIST *pc_pointlist_make(uint32_t npoints)
{
PCPOINTLIST *pl = pcalloc(sizeof(PCPOINTLIST));
pl->points = pcalloc(sizeof(PCPOINT *) * npoints);
pl->maxpoints = npoints;
pl->npoints = 0;
pl->mem = NULL;
return pl;
}
void pc_pointlist_free(PCPOINTLIST *pl)
{
int i;
for (i = 0; i < pl->npoints; i++)
{
pc_point_free(pl->points[i]);
}
if (pl->mem)
pcfree(pl->mem);
pcfree(pl->points);
pcfree(pl);
return;
}
void pc_pointlist_add_point(PCPOINTLIST *pl, PCPOINT *pt)
{
if (pl->npoints >= pl->maxpoints)
{
if (pl->maxpoints < 1)
pl->maxpoints = 1;
pl->maxpoints *= 2;
pl->points = pcrealloc(pl->points, pl->maxpoints * sizeof(PCPOINT *));
}
pl->points[pl->npoints] = pt;
pl->npoints += 1;
return;
}
PCPOINT *pc_pointlist_get_point(const PCPOINTLIST *pl, int i)
{
return pl->points[i];
}
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;
}
PCPOINTLIST *pc_pointlist_from_patch(const PCPATCH *patch)
{
switch (patch->type)
{
case PC_NONE:
{
return pc_pointlist_from_uncompressed((PCPATCH_UNCOMPRESSED *)patch);
}
case PC_DIMENSIONAL:
{
return pc_pointlist_from_dimensional((PCPATCH_DIMENSIONAL *)patch);
}
case PC_LAZPERF:
{
return pc_pointlist_from_lazperf((PCPATCH_LAZPERF *)patch);
}
}
/* Don't get here */
pcerror("pc_pointlist_from_patch: unsupported compression type %d",
patch->type);
return NULL;
}
|