1 /*********************************************************************** 2 * pc_api_internal.h 3 * 4 * Signatures we need to share within the library, but not for 5 * use outside it. 6 * 7 * PgSQL Pointcloud is free and open source software provided 8 * by the Government of Canada 9 * 10 * Copyright (c) 2013 Natural Resources Canada 11 * Copyright (c) 2013 OpenGeo 12 * 13 ***********************************************************************/ 14 15 #ifndef _PC_API_INTERNAL_H 16 #define _PC_API_INTERNAL_H 17 18 #include "pc_api.h" 19 20 /** 21 * Utility defines 22 */ 23 #define PC_TRUE 1 24 #define PC_FALSE 0 25 #define PC_SUCCESS 1 26 #define PC_FAILURE 0 27 28 /** 29 * How many compression types do we support? 30 */ 31 #define PCCOMPRESSIONTYPES 2 32 33 /** 34 * Memory allocation for patch starts at 64 points 35 */ 36 #define PCPATCH_DEFAULT_MAXPOINTS 64 37 38 /** 39 * How many points to sample before considering 40 * a PCDIMSTATS done? 41 */ 42 #define PCDIMSTATS_MIN_SAMPLE 10000 43 44 /** 45 * Interpretation types for our dimension descriptions 46 */ 47 #define NUM_INTERPRETATIONS 11 48 49 enum INTERPRETATIONS 50 { 51 PC_UNKNOWN = 0, 52 PC_INT8 = 1, PC_UINT8 = 2, 53 PC_INT16 = 3, PC_UINT16 = 4, 54 PC_INT32 = 5, PC_UINT32 = 6, 55 PC_INT64 = 7, PC_UINT64 = 8, 56 PC_DOUBLE = 9, PC_FLOAT = 10 57 }; 58 59 enum DIMCOMPRESSIONS 60 { 61 PC_DIM_NONE = 0, 62 PC_DIM_RLE = 1, 63 PC_DIM_SIGBITS = 2, 64 PC_DIM_ZLIB = 3 65 }; 66 67 /* PCDOUBLESTAT are members of PCDOUBLESTATS */ 68 typedef struct 69 { 70 double min; 71 double max; 72 double sum; 73 } PCDOUBLESTAT; 74 75 /* PCDOUBLESTATS are internal to calculating stats in this module */ 76 typedef struct 77 { 78 uint32_t npoints; 79 PCDOUBLESTAT *dims; 80 } PCDOUBLESTATS; 81 82 83 typedef struct 84 { 85 uint32_t nset; 86 uint32_t npoints; 87 uint8_t *map; 88 } PCBITMAP; 89 90 91 /** What is the endianness of this system? */ 92 char machine_endian(void); 93 94 /** Flips the bytes of an int32_t */ 95 int32_t int32_flip_endian(int32_t val); 96 97 /** Read the the npoints from WKB form of a PATCH */ 98 uint32_t wkb_get_compression(const uint8_t *wkb); 99 100 /** Read an int32 from a byte array, flipping if requested */ 101 int32_t wkb_get_int32(const uint8_t *wkb, int flip_endian); 102 103 /** Read an int16 from a byte array, flipping if requested */ 104 int16_t wkb_get_int16(const uint8_t *wkb, int flip_endian); 105 106 /** Read the number of points from a wkb */ 107 uint32_t wkb_get_npoints(const uint8_t *wkb); 108 109 /** Write a double into a byte array */ 110 uint8_t *wkb_set_double(uint8_t *wkb, double d); 111 112 /** Write a uint32 into a byte array */ 113 uint8_t *wkb_set_uint32(uint8_t *wkb, uint32_t i); 114 115 /** Write a char into a byte array */ 116 uint8_t *wkb_set_char(uint8_t *wkb, char c); 117 118 /** Force a byte array into the machine endianness */ 119 uint8_t* uncompressed_bytes_flip_endian(const uint8_t *bytebuf, const PCSCHEMA *schema, uint32_t npoints); 120 121 /** Update a value using the scale/offset info from a dimension */ 122 double pc_value_scale_offset(double val, const PCDIMENSION *dim); 123 124 /** Remove the scale/offset values from a number before storage */ 125 double pc_value_unscale_unoffset(double val, const PCDIMENSION *dim); 126 127 /** Read interpretation type from buffer and cast to double */ 128 double pc_double_from_ptr(const uint8_t *ptr, uint32_t interpretation); 129 130 /** Write value to buffer in the interpretation type */ 131 int pc_double_to_ptr(uint8_t *ptr, uint32_t interpretation, double val); 132 133 /** Return number of bytes in a given interpretation */ 134 size_t pc_interpretation_size(uint32_t interp); 135 136 /** Convert XML string token to type interpretation number */ 137 const char * pc_interpretation_string(uint32_t interp); 138 139 /** Copy a string within the global memory management context */ 140 char* pcstrdup(const char *str); 141 142 /** Scales/offsets double, casts to appropriate dimension type, and writes into point */ 143 int pc_point_set_double_by_index(PCPOINT *pt, uint32_t idx, double val); 144 145 /** Scales/offsets double, casts to appropriate dimension type, and writes into point */ 146 int pc_point_set_double_by_name(PCPOINT *pt, const char *name, double val); 147 148 /** Scales/offsets double, casts to appropriate dimension type, and writes into point */ 149 int pc_point_set_double(PCPOINT *pt, const PCDIMENSION *dim, double val); 150 151 152 /**************************************************************************** 153 * DIMENSION STATISTICS 154 */ 155 156 /** Analyze the bytes in the #PCPATCH_DIMENSIONAL and update the #PCDIMSTATS */ 157 int pc_dimstats_update(PCDIMSTATS *pds, const PCPATCH_DIMENSIONAL *pdl); 158 /** Free the PCDIMSTATS memory */ 159 void pc_dimstats_free(PCDIMSTATS *pds); 160 char* pc_dimstats_to_string(const PCDIMSTATS *pds); 161 162 163 /**************************************************************************** 164 * PATCHES 165 */ 166 167 /** Returns newly allocated patch that only contains the points fitting the filter condition */ 168 PCPATCH* pc_patch_filter(const PCPATCH *pa, uint32_t dimnum, PC_FILTERTYPE filter, double val1, double val2); 169 void pc_patch_free_stats(PCPATCH *pa); 170 171 /* DIMENSIONAL PATCHES */ 172 char* pc_patch_dimensional_to_string(const PCPATCH_DIMENSIONAL *pa); 173 PCPATCH_DIMENSIONAL* pc_patch_dimensional_from_uncompressed(const PCPATCH_UNCOMPRESSED *pa); 174 PCPATCH_DIMENSIONAL* pc_patch_dimensional_compress(const PCPATCH_DIMENSIONAL *pdl, PCDIMSTATS *pds); 175 PCPATCH_DIMENSIONAL* pc_patch_dimensional_decompress(const PCPATCH_DIMENSIONAL *pdl); 176 void pc_patch_dimensional_free(PCPATCH_DIMENSIONAL *pdl); 177 int pc_patch_dimensional_compute_extent(PCPATCH_DIMENSIONAL *pdl); 178 uint8_t* pc_patch_dimensional_to_wkb(const PCPATCH_DIMENSIONAL *patch, size_t *wkbsize); 179 PCPATCH* pc_patch_dimensional_from_wkb(const PCSCHEMA *schema, const uint8_t *wkb, size_t wkbsize); 180 PCPATCH_DIMENSIONAL* pc_patch_dimensional_from_pointlist(const PCPOINTLIST *pdl); 181 PCPOINTLIST* pc_pointlist_from_dimensional(const PCPATCH_DIMENSIONAL *pdl); 182 PCPATCH_DIMENSIONAL* pc_patch_dimensional_clone(const PCPATCH_DIMENSIONAL *patch); 183 PCPOINT *pc_patch_dimensional_pointn(const PCPATCH_DIMENSIONAL *pdl, int n); 184 185 /* UNCOMPRESSED PATCHES */ 186 char* pc_patch_uncompressed_to_string(const PCPATCH_UNCOMPRESSED *patch); 187 uint8_t* pc_patch_uncompressed_to_wkb(const PCPATCH_UNCOMPRESSED *patch, size_t *wkbsize); 188 PCPATCH* pc_patch_uncompressed_from_wkb(const PCSCHEMA *s, const uint8_t *wkb, size_t wkbsize); 189 PCPATCH_UNCOMPRESSED* pc_patch_uncompressed_make(const PCSCHEMA *s, uint32_t maxpoints); 190 int pc_patch_uncompressed_compute_extent(PCPATCH_UNCOMPRESSED *patch); 191 int pc_patch_uncompressed_compute_stats(PCPATCH_UNCOMPRESSED *patch); 192 void pc_patch_uncompressed_free(PCPATCH_UNCOMPRESSED *patch); 193 uint8_t *pc_patch_uncompressed_readonly(PCPATCH_UNCOMPRESSED *patch); 194 PCPOINTLIST* pc_pointlist_from_uncompressed(const PCPATCH_UNCOMPRESSED *patch); 195 PCPATCH_UNCOMPRESSED* pc_patch_uncompressed_from_pointlist(const PCPOINTLIST *pl); 196 PCPATCH_UNCOMPRESSED* pc_patch_uncompressed_from_dimensional(const PCPATCH_DIMENSIONAL *pdl); 197 int pc_patch_uncompressed_add_point(PCPATCH_UNCOMPRESSED *c, const PCPOINT *p); 198 PCPOINT *pc_patch_uncompressed_pointn(const PCPATCH_UNCOMPRESSED *patch, int n); 199 200 /* LAZPERF PATCHES */ 201 PCPATCH_LAZPERF* pc_patch_lazperf_from_pointlist(const PCPOINTLIST *pl); 202 PCPATCH_LAZPERF* pc_patch_lazperf_from_uncompressed(const PCPATCH_UNCOMPRESSED *pa); 203 PCPOINTLIST* pc_pointlist_from_lazperf(const PCPATCH_LAZPERF *palaz); 204 PCPATCH_UNCOMPRESSED* pc_patch_uncompressed_from_lazperf(const PCPATCH_LAZPERF *palaz); 205 int pc_patch_lazperf_compute_extent(PCPATCH_LAZPERF *patch); 206 char* pc_patch_lazperf_to_string(const PCPATCH_LAZPERF *pa); 207 void pc_patch_lazperf_free(PCPATCH_LAZPERF *palaz); 208 uint8_t* pc_patch_lazperf_to_wkb(const PCPATCH_LAZPERF *patch, size_t *wkbsize); 209 PCPATCH* pc_patch_lazperf_from_wkb(const PCSCHEMA *schema, const uint8_t *wkb, size_t wkbsize); 210 PCPOINT *pc_patch_lazperf_pointn(const PCPATCH_LAZPERF *patch, int n); 211 212 /**************************************************************************** 213 * BYTES 214 */ 215 216 /** Construct empty byte array (zero out attribute and allocate byte buffer) */ 217 PCBYTES pc_bytes_make(const PCDIMENSION *dim, uint32_t npoints); 218 /** Empty the byte array (free the byte buffer) */ 219 void pc_bytes_free(PCBYTES bytes); 220 /** Apply the compresstion to the byte array in place, freeing the original byte buffer */ 221 PCBYTES pc_bytes_encode(PCBYTES pcb, int compression); 222 /** Convert the bytes in #PCBYTES to PC_DIM_NONE compression */ 223 PCBYTES pc_bytes_decode(PCBYTES epcb); 224 225 /** Convert value bytes to RLE bytes */ 226 PCBYTES pc_bytes_run_length_encode(const PCBYTES pcb); 227 /** Convert RLE bytes to value bytes */ 228 PCBYTES pc_bytes_run_length_decode(const PCBYTES pcb); 229 /** Convert value bytes to bit packed bytes */ 230 PCBYTES pc_bytes_sigbits_encode(const PCBYTES pcb); 231 /** Convert bit packed bytes to value bytes */ 232 PCBYTES pc_bytes_sigbits_decode(const PCBYTES pcb); 233 /** Compress bytes using zlib */ 234 PCBYTES pc_bytes_zlib_encode(const PCBYTES pcb); 235 /** De-compress bytes using zlib */ 236 PCBYTES pc_bytes_zlib_decode(const PCBYTES pcb); 237 238 /** How many runs are there in a value array? */ 239 uint32_t pc_bytes_run_count(const PCBYTES *pcb); 240 /** How many bits are shared by all elements of this array? */ 241 uint32_t pc_bytes_sigbits_count(const PCBYTES *pcb); 242 /** Using an 8-bit word, what is the common word and number of bits in common? */ 243 uint8_t pc_bytes_sigbits_count_8 (const PCBYTES *pcb, uint32_t *nsigbits); 244 /** Using an 16-bit word, what is the common word and number of bits in common? */ 245 uint16_t pc_bytes_sigbits_count_16(const PCBYTES *pcb, uint32_t *nsigbits); 246 /** Using an 32-bit word, what is the common word and number of bits in common? */ 247 uint32_t pc_bytes_sigbits_count_32(const PCBYTES *pcb, uint32_t *nsigbits); 248 /** Using an 64-bit word, what is the common word and number of bits in common? */ 249 uint64_t pc_bytes_sigbits_count_64(const PCBYTES *pcb, uint32_t *nsigbits); 250 251 /* NOTE: stats are gathered without applying scale and offset */ 252 PCBYTES pc_bytes_filter(const PCBYTES *pcb, const PCBITMAP *map, PCDOUBLESTAT *stats); 253 254 PCBITMAP* pc_bytes_bitmap(const PCBYTES *pcb, PC_FILTERTYPE filter, double val1, double val2); 255 int pc_bytes_minmax(const PCBYTES *pcb, double *min, double *max, double *avg); 256 257 /** getting the n-th point out of a PCBYTE into a buffer */ 258 void pc_bytes_uncompressed_to_ptr(uint8_t *buf, PCBYTES pcb, int n); 259 void pc_bytes_run_length_to_ptr(uint8_t *buf, PCBYTES pcb, int n); 260 void pc_bytes_sigbits_to_ptr_32(uint8_t *buf, PCBYTES pcb, int n); 261 void pc_bytes_sigbits_to_ptr(uint8_t *buf, PCBYTES pcb, int n); 262 void pc_bytes_zlib_to_ptr(uint8_t *buf, PCBYTES pcb, int n); 263 void pc_bytes_to_ptr(uint8_t *buf, PCBYTES pcb, int n); 264 265 /**************************************************************************** 266 * BOUNDS 267 */ 268 269 /** Initialize with very large mins and very small maxes */ 270 void pc_bounds_init(PCBOUNDS *b); 271 /** Copy a bounds */ 272 PCSTATS* pc_stats_clone(const PCSTATS *stats); 273 /** Expand extents of b1 to encompass b2 */ 274 void pc_bounds_merge(PCBOUNDS *b1, const PCBOUNDS *b2); 275 276 /**************************************************************************** 277 * BITMAPS 278 */ 279 280 /** Allocate new unset bitmap */ 281 PCBITMAP* pc_bitmap_new(uint32_t npoints); 282 /** Deallocate bitmap */ 283 void pc_bitmap_free(PCBITMAP *map); 284 /** Set indicated bit on bitmap if filter and value are consistent */ 285 void pc_bitmap_filter(PCBITMAP *map, PC_FILTERTYPE filter, int i, double d, double val1, double val2); 286 287 /** Read indicated bit of bitmap */ 288 #define pc_bitmap_get(map, i) ((map)->map[(i)]) 289 290 291 292 #endif /* _PC_API_INTERNAL_H */ 293