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