1 /*
2
3 rl2dbms -- DBMS related functions
4
5 version 0.1, 2013 March 29
6
7 Author: Sandro Furieri a.furieri@lqt.it
8
9 -----------------------------------------------------------------------------
10
11 Version: MPL 1.1/GPL 2.0/LGPL 2.1
12
13 The contents of this file are subject to the Mozilla Public License Version
14 1.1 (the "License"); you may not use this file except in compliance with
15 the License. You may obtain a copy of the License at
16 http://www.mozilla.org/MPL/
17
18 Software distributed under the License is distributed on an "AS IS" basis,
19 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
20 for the specific language governing rights and limitations under the
21 License.
22
23 The Original Code is the SpatiaLite library
24
25 The Initial Developer of the Original Code is Alessandro Furieri
26
27 Portions created by the Initial Developer are Copyright (C) 2008-2013
28 the Initial Developer. All Rights Reserved.
29
30 Alternatively, the contents of this file may be used under the terms of
31 either the GNU General Public License Version 2 or later (the "GPL"), or
32 the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
33 in which case the provisions of the GPL or the LGPL are applicable instead
34 of those above. If you wish to allow use of your version of this file only
35 under the terms of either the GPL or the LGPL, and not to allow others to
36 use your version of this file under the terms of the MPL, indicate your
37 decision by deleting the provisions above and replace them with the notice
38 and other provisions required by the GPL or the LGPL. If you do not delete
39 the provisions above, a recipient may use your version of this file under
40 the terms of any one of the MPL, the GPL or the LGPL.
41
42 */
43
44 #include <stdlib.h>
45 #include <stdio.h>
46 #include <string.h>
47 #include <float.h>
48
49 #include "config.h"
50
51 #ifdef LOADABLE_EXTENSION
52 #include "rasterlite2/sqlite.h"
53 #endif
54
55 #include "rasterlite2/rasterlite2.h"
56 #include "rasterlite2_private.h"
57
58 #include <spatialite/gaiaaux.h>
59
60 /* 64 bit integer: portable format for printf() */
61 #if defined(_WIN32) && !defined(__MINGW32__)
62 #define ERR_FRMT64 "ERROR: unable to decode Tile ID=%I64d\n"
63 #else
64 #define ERR_FRMT64 "ERROR: unable to decode Tile ID=%lld\n"
65 #endif
66
67 static int
insert_into_raster_coverages(sqlite3 * handle,const char * coverage,unsigned char sample,unsigned char pixel,unsigned char num_bands,unsigned char compression,int quality,unsigned int tile_width,unsigned int tile_height,int srid,double x_res,double y_res,unsigned char * blob,int blob_sz,unsigned char * blob_no_data,int blob_no_data_sz)68 insert_into_raster_coverages (sqlite3 * handle, const char *coverage,
69 unsigned char sample, unsigned char pixel,
70 unsigned char num_bands,
71 unsigned char compression, int quality,
72 unsigned int tile_width,
73 unsigned int tile_height, int srid,
74 double x_res, double y_res, unsigned char *blob,
75 int blob_sz, unsigned char *blob_no_data,
76 int blob_no_data_sz)
77 {
78 /* inserting into "raster_coverages" */
79 int ret;
80 char *sql;
81 sqlite3_stmt *stmt;
82 const char *xsample = "UNKNOWN";
83 const char *xpixel = "UNKNOWN";
84 const char *xcompression = "UNKNOWN";
85
86 sql = "INSERT INTO raster_coverages (coverage_name, sample_type, "
87 "pixel_type, num_bands, compression, quality, tile_width, "
88 "tile_height, horz_resolution, vert_resolution, srid, "
89 "nodata_pixel, palette) VALUES (Lower(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
90 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
91 if (ret != SQLITE_OK)
92 {
93 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
94 return 0;
95 }
96 switch (sample)
97 {
98 case RL2_SAMPLE_1_BIT:
99 xsample = "1-BIT";
100 break;
101 case RL2_SAMPLE_2_BIT:
102 xsample = "2-BIT";
103 break;
104 case RL2_SAMPLE_4_BIT:
105 xsample = "4-BIT";
106 break;
107 case RL2_SAMPLE_INT8:
108 xsample = "INT8";
109 break;
110 case RL2_SAMPLE_UINT8:
111 xsample = "UINT8";
112 break;
113 case RL2_SAMPLE_INT16:
114 xsample = "INT16";
115 break;
116 case RL2_SAMPLE_UINT16:
117 xsample = "UINT16";
118 break;
119 case RL2_SAMPLE_INT32:
120 xsample = "INT32";
121 break;
122 case RL2_SAMPLE_UINT32:
123 xsample = "UINT32";
124 break;
125 case RL2_SAMPLE_FLOAT:
126 xsample = "FLOAT";
127 break;
128 case RL2_SAMPLE_DOUBLE:
129 xsample = "DOUBLE";
130 break;
131 };
132 switch (pixel)
133 {
134 case RL2_PIXEL_MONOCHROME:
135 xpixel = "MONOCHROME";
136 break;
137 case RL2_PIXEL_PALETTE:
138 xpixel = "PALETTE";
139 break;
140 case RL2_PIXEL_GRAYSCALE:
141 xpixel = "GRAYSCALE";
142 break;
143 case RL2_PIXEL_RGB:
144 xpixel = "RGB";
145 break;
146 case RL2_PIXEL_MULTIBAND:
147 xpixel = "MULTIBAND";
148 break;
149 case RL2_PIXEL_DATAGRID:
150 xpixel = "DATAGRID";
151 break;
152 };
153 switch (compression)
154 {
155 case RL2_COMPRESSION_NONE:
156 xcompression = "NONE";
157 break;
158 case RL2_COMPRESSION_DEFLATE:
159 xcompression = "DEFLATE";
160 break;
161 case RL2_COMPRESSION_LZMA:
162 xcompression = "LZMA";
163 break;
164 case RL2_COMPRESSION_PNG:
165 xcompression = "PNG";
166 break;
167 case RL2_COMPRESSION_JPEG:
168 xcompression = "JPEG";
169 break;
170 case RL2_COMPRESSION_LOSSY_WEBP:
171 xcompression = "LOSSY_WEBP";
172 break;
173 case RL2_COMPRESSION_LOSSLESS_WEBP:
174 xcompression = "LOSSLESS_WEBP";
175 break;
176 case RL2_COMPRESSION_CCITTFAX4:
177 xcompression = "CCITTFAX4";
178 break;
179 };
180 sqlite3_reset (stmt);
181 sqlite3_clear_bindings (stmt);
182 sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
183 sqlite3_bind_text (stmt, 2, xsample, strlen (xsample), SQLITE_STATIC);
184 sqlite3_bind_text (stmt, 3, xpixel, strlen (xpixel), SQLITE_STATIC);
185 sqlite3_bind_int (stmt, 4, num_bands);
186 sqlite3_bind_text (stmt, 5, xcompression, strlen (xcompression),
187 SQLITE_STATIC);
188 sqlite3_bind_int (stmt, 6, quality);
189 sqlite3_bind_int (stmt, 7, tile_width);
190 sqlite3_bind_int (stmt, 8, tile_height);
191 sqlite3_bind_double (stmt, 9, x_res);
192 sqlite3_bind_double (stmt, 10, y_res);
193 sqlite3_bind_int (stmt, 11, srid);
194 if (blob_no_data == NULL)
195 sqlite3_bind_null (stmt, 12);
196 else
197 sqlite3_bind_blob (stmt, 12, blob_no_data, blob_no_data_sz, free);
198 if (blob == NULL)
199 sqlite3_bind_null (stmt, 13);
200 else
201 sqlite3_bind_blob (stmt, 13, blob, blob_sz, free);
202 ret = sqlite3_step (stmt);
203 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
204 goto coverage_registered;
205 fprintf (stderr,
206 "sqlite3_step() error: INSERT INTO raster_coverages \"%s\"\n",
207 sqlite3_errmsg (handle));
208 sqlite3_finalize (stmt);
209 return 0;
210 coverage_registered:
211 sqlite3_finalize (stmt);
212 return 1;
213 }
214
215 static int
create_levels(sqlite3 * handle,const char * coverage)216 create_levels (sqlite3 * handle, const char *coverage)
217 {
218 /* creating the LEVELS table */
219 int ret;
220 char *sql;
221 char *sql_err = NULL;
222 char *xcoverage;
223 char *xxcoverage;
224
225 xcoverage = sqlite3_mprintf ("%s_levels", coverage);
226 xxcoverage = gaiaDoubleQuotedSql (xcoverage);
227 sqlite3_free (xcoverage);
228 sql = sqlite3_mprintf ("CREATE TABLE \"%s\" ("
229 "\tpyramid_level INTEGER PRIMARY KEY AUTOINCREMENT,\n"
230 "\tx_resolution_1_1 DOUBLE NOT NULL,\n"
231 "\ty_resolution_1_1 DOUBLE NOT NULL,\n"
232 "\tx_resolution_1_2 DOUBLE,\n"
233 "\ty_resolution_1_2 DOUBLE,\n"
234 "\tx_resolution_1_4 DOUBLE,\n"
235 "\ty_resolution_1_4 DOUBLE,\n"
236 "\tx_resolution_1_8 DOUBLE,\n"
237 "\ty_resolution_1_8 DOUBLE)\n", xxcoverage);
238 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
239 sqlite3_free (sql);
240 if (ret != SQLITE_OK)
241 {
242 fprintf (stderr, "CREATE TABLE \"%s_levels\" error: %s\n", xxcoverage,
243 sql_err);
244 sqlite3_free (sql_err);
245 free (xxcoverage);
246 return 0;
247 }
248 free (xxcoverage);
249 return 1;
250 }
251
252 static int
create_sections(sqlite3 * handle,const char * coverage,int srid)253 create_sections (sqlite3 * handle, const char *coverage, int srid)
254 {
255 /* creating the SECTIONS table */
256 int ret;
257 char *sql;
258 char *sql_err = NULL;
259 char *xcoverage;
260 char *xxcoverage;
261 char *xindex;
262 char *xxindex;
263 char *xtrigger;
264 char *xxtrigger;
265
266 /* creating the SECTIONS table */
267 xcoverage = sqlite3_mprintf ("%s_sections", coverage);
268 xxcoverage = gaiaDoubleQuotedSql (xcoverage);
269 sqlite3_free (xcoverage);
270 sql = sqlite3_mprintf ("CREATE TABLE \"%s\" ("
271 "\tsection_id INTEGER PRIMARY KEY AUTOINCREMENT,\n"
272 "\tsection_name TEXT NOT NULL,\n"
273 "\twidth INTEGER NOT NULL,\n"
274 "\theight INTEGER NOT NULL,\n"
275 "\tfile_path TEXT,\n"
276 "\tstatistics BLOB)", xxcoverage);
277 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
278 sqlite3_free (sql);
279 if (ret != SQLITE_OK)
280 {
281 fprintf (stderr, "CREATE TABLE \"%s\" error: %s\n",
282 xxcoverage, sql_err);
283 sqlite3_free (sql_err);
284 free (xxcoverage);
285 return 0;
286 }
287 free (xxcoverage);
288
289 /* adding the safeguard Triggers */
290 xtrigger = sqlite3_mprintf ("%s_sections_statistics_insert", coverage);
291 xxtrigger = gaiaDoubleQuotedSql (xtrigger);
292 sqlite3_free (xtrigger);
293 xcoverage = sqlite3_mprintf ("%s_sections", coverage);
294 sql = sqlite3_mprintf ("CREATE TRIGGER \"%s\"\n"
295 "BEFORE INSERT ON %Q\nFOR EACH ROW BEGIN\n"
296 "SELECT RAISE(ABORT,'insert on %s violates constraint: "
297 "invalid statistics')\nWHERE NEW.statistics IS NOT NULL AND "
298 "IsValidRasterStatistics(%Q, NEW.statistics) <> 1;\nEND",
299 xxtrigger, xcoverage, xcoverage, coverage);
300 sqlite3_free (xcoverage);
301 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
302 sqlite3_free (sql);
303 if (ret != SQLITE_OK)
304 {
305 fprintf (stderr, "CREATE TRIGGER \"%s\" error: %s\n", xxtrigger,
306 sql_err);
307 sqlite3_free (sql_err);
308 free (xxtrigger);
309 return 0;
310 }
311 free (xxtrigger);
312 xtrigger = sqlite3_mprintf ("%s_sections_statistics_update", coverage);
313 xxtrigger = gaiaDoubleQuotedSql (xtrigger);
314 sqlite3_free (xtrigger);
315 xcoverage = sqlite3_mprintf ("%s_sections", coverage);
316 sql = sqlite3_mprintf ("CREATE TRIGGER \"%s\"\n"
317 "BEFORE UPDATE OF 'statistics' ON %Q"
318 "\nFOR EACH ROW BEGIN\n"
319 "SELECT RAISE(ABORT, 'update on %s violates constraint: "
320 "invalid statistics')\nWHERE NEW.statistics IS NOT NULL AND "
321 "IsValidRasterStatistics(%Q, NEW.statistics) <> 1;\nEND",
322 xxtrigger, xcoverage, xcoverage, coverage);
323 sqlite3_free (xcoverage);
324 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
325 sqlite3_free (sql);
326 if (ret != SQLITE_OK)
327 {
328 fprintf (stderr, "CREATE TRIGGER \"%s\" error: %s\n", xxtrigger,
329 sql_err);
330 sqlite3_free (sql_err);
331 free (xxtrigger);
332 return 0;
333 }
334 free (xxtrigger);
335
336 /* creating the SECTIONS geometry */
337 xcoverage = sqlite3_mprintf ("%s_sections", coverage);
338 sql = sqlite3_mprintf ("SELECT AddGeometryColumn("
339 "%Q, 'geometry', %d, 'POLYGON', 'XY')", xcoverage,
340 srid);
341 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
342 sqlite3_free (sql);
343 if (ret != SQLITE_OK)
344 {
345 fprintf (stderr, "AddGeometryColumn \"%s\" error: %s\n",
346 xcoverage, sql_err);
347 sqlite3_free (sql_err);
348 sqlite3_free (xcoverage);
349 return 0;
350 }
351 sqlite3_free (xcoverage);
352
353 /* creating the SECTIONS spatial index */
354 xcoverage = sqlite3_mprintf ("%s_sections", coverage);
355 sql = sqlite3_mprintf ("SELECT CreateSpatialIndex("
356 "%Q, 'geometry')", xcoverage);
357 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
358 sqlite3_free (sql);
359 if (ret != SQLITE_OK)
360 {
361 fprintf (stderr, "CreateSpatialIndex \"%s\" error: %s\n",
362 xcoverage, sql_err);
363 sqlite3_free (sql_err);
364 sqlite3_free (xcoverage);
365 return 0;
366 }
367 sqlite3_free (xcoverage);
368
369 /* creating the SECTIONS index by name */
370 xcoverage = sqlite3_mprintf ("%s_sections", coverage);
371 xxcoverage = gaiaDoubleQuotedSql (xcoverage);
372 sqlite3_free (xcoverage);
373 xindex = sqlite3_mprintf ("idx_%s_sections", coverage);
374 xxindex = gaiaDoubleQuotedSql (xindex);
375 sqlite3_free (xindex);
376 sql =
377 sqlite3_mprintf ("CREATE UNIQUE INDEX \"%s\" ON \"%s\" (section_name)",
378 xxindex, xxcoverage);
379 free (xxcoverage);
380 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
381 sqlite3_free (sql);
382 if (ret != SQLITE_OK)
383 {
384 fprintf (stderr, "CREATE INDEX \"%s\" error: %s\n", xxindex, sql_err);
385 sqlite3_free (sql_err);
386 free (xxindex);
387 return 0;
388 }
389 free (xxindex);
390 return 1;
391 }
392
393 static int
create_tiles(sqlite3 * handle,const char * coverage,int srid)394 create_tiles (sqlite3 * handle, const char *coverage, int srid)
395 {
396 /* creating the TILES table */
397 int ret;
398 char *sql;
399 char *sql_err = NULL;
400 char *xcoverage;
401 char *xxcoverage;
402 char *xindex;
403 char *xxindex;
404 char *xfk;
405 char *xxfk;
406 char *xmother;
407 char *xxmother;
408 char *xfk2;
409 char *xxfk2;
410 char *xmother2;
411 char *xxmother2;
412 char *xtrigger;
413 char *xxtrigger;
414 char *xtiles;
415 char *xxtiles;
416
417 xcoverage = sqlite3_mprintf ("%s_tiles", coverage);
418 xxcoverage = gaiaDoubleQuotedSql (xcoverage);
419 sqlite3_free (xcoverage);
420 xmother = sqlite3_mprintf ("%s_sections", coverage);
421 xxmother = gaiaDoubleQuotedSql (xmother);
422 sqlite3_free (xmother);
423 xfk = sqlite3_mprintf ("fk_%s_tiles_section", coverage);
424 xxfk = gaiaDoubleQuotedSql (xfk);
425 sqlite3_free (xfk);
426 xmother2 = sqlite3_mprintf ("%s_levels", coverage);
427 xxmother2 = gaiaDoubleQuotedSql (xmother2);
428 sqlite3_free (xmother2);
429 xfk2 = sqlite3_mprintf ("fk_%s_tiles_level", coverage);
430 xxfk2 = gaiaDoubleQuotedSql (xfk2);
431 sqlite3_free (xfk2);
432 sql = sqlite3_mprintf ("CREATE TABLE \"%s\" ("
433 "\ttile_id INTEGER PRIMARY KEY AUTOINCREMENT,\n"
434 "\tpyramid_level INTEGER NOT NULL,\n"
435 "\tsection_id INTEGER,\n"
436 "\tCONSTRAINT \"%s\" FOREIGN KEY (section_id) "
437 "REFERENCES \"%s\" (section_id) ON DELETE CASCADE,\n"
438 "\tCONSTRAINT \"%s\" FOREIGN KEY (pyramid_level) "
439 "REFERENCES \"%s\" (pyramid_level) ON DELETE CASCADE)",
440 xxcoverage, xxfk, xxmother, xxfk2, xxmother2);
441 free (xxfk);
442 free (xxmother);
443 free (xxfk2);
444 free (xxmother2);
445 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
446 sqlite3_free (sql);
447 if (ret != SQLITE_OK)
448 {
449 fprintf (stderr, "CREATE TABLE \"%s_tiles\" error: %s\n",
450 xxcoverage, sql_err);
451 sqlite3_free (sql_err);
452 free (xxcoverage);
453 return 0;
454 }
455 free (xxcoverage);
456
457 /* creating the TILES geometry */
458 xcoverage = sqlite3_mprintf ("%s_tiles", coverage);
459 sql = sqlite3_mprintf ("SELECT AddGeometryColumn("
460 "%Q, 'geometry', %d, 'POLYGON', 'XY')", xcoverage,
461 srid);
462 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
463 sqlite3_free (sql);
464 if (ret != SQLITE_OK)
465 {
466 fprintf (stderr, "AddGeometryColumn \"%s_tiles\" error: %s\n",
467 xcoverage, sql_err);
468 sqlite3_free (sql_err);
469 sqlite3_free (xcoverage);
470 return 0;
471 }
472 sqlite3_free (xcoverage);
473
474 /* creating the TILES spatial Index */
475 xcoverage = sqlite3_mprintf ("%s_tiles", coverage);
476 sql = sqlite3_mprintf ("SELECT CreateSpatialIndex("
477 "%Q, 'geometry')", xcoverage);
478 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
479 sqlite3_free (sql);
480 if (ret != SQLITE_OK)
481 {
482 fprintf (stderr, "CreateSpatialIndex \"%s_tiles\" error: %s\n",
483 xcoverage, sql_err);
484 sqlite3_free (sql_err);
485 sqlite3_free (xcoverage);
486 return 0;
487 }
488 sqlite3_free (xcoverage);
489
490 /* creating the TILES index by section */
491 xcoverage = sqlite3_mprintf ("%s_tiles", coverage);
492 xxcoverage = gaiaDoubleQuotedSql (xcoverage);
493 sqlite3_free (xcoverage);
494 xindex = sqlite3_mprintf ("idx_%s_tiles", coverage);
495 xxindex = gaiaDoubleQuotedSql (xindex);
496 sqlite3_free (xindex);
497 sql =
498 sqlite3_mprintf ("CREATE INDEX \"%s\" ON \"%s\" (section_id)", xxindex,
499 xxcoverage);
500 free (xxcoverage);
501 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
502 sqlite3_free (sql);
503 if (ret != SQLITE_OK)
504 {
505 fprintf (stderr, "CREATE INDEX \"%s\" error: %s\n", xxindex, sql_err);
506 sqlite3_free (sql_err);
507 free (xxindex);
508 return 0;
509 }
510 free (xxindex);
511
512 /* creating the TILE_DATA table */
513 xcoverage = sqlite3_mprintf ("%s_tile_data", coverage);
514 xxcoverage = gaiaDoubleQuotedSql (xcoverage);
515 sqlite3_free (xcoverage);
516 xmother = sqlite3_mprintf ("%s_tiles", coverage);
517 xxmother = gaiaDoubleQuotedSql (xmother);
518 sqlite3_free (xmother);
519 xfk = sqlite3_mprintf ("fk_%s_tile_data", coverage);
520 xxfk = gaiaDoubleQuotedSql (xfk);
521 sqlite3_free (xfk);
522 sql = sqlite3_mprintf ("CREATE TABLE \"%s\" ("
523 "\ttile_id INTEGER NOT NULL PRIMARY KEY,\n"
524 "\ttile_data_odd BLOB NOT NULL,\n"
525 "\ttile_data_even BLOB,\n"
526 "CONSTRAINT \"%s\" FOREIGN KEY (tile_id) "
527 "REFERENCES \"%s\" (tile_id) ON DELETE CASCADE)",
528 xxcoverage, xxfk, xxmother);
529 free (xxfk);
530 free (xxmother);
531 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
532 sqlite3_free (sql);
533 if (ret != SQLITE_OK)
534 {
535 fprintf (stderr, "CREATE TABLE \"%s_tile_data\" error: %s\n",
536 xxcoverage, sql_err);
537 sqlite3_free (sql_err);
538 free (xxcoverage);
539 return 0;
540 }
541 free (xxcoverage);
542
543 /* adding the safeguard Triggers */
544 xtrigger = sqlite3_mprintf ("%s_tile_data_insert", coverage);
545 xxtrigger = gaiaDoubleQuotedSql (xtrigger);
546 sqlite3_free (xtrigger);
547 xcoverage = sqlite3_mprintf ("%s_tile_data", coverage);
548 xtiles = sqlite3_mprintf ("%s_tiles", coverage);
549 xxtiles = gaiaDoubleQuotedSql (xtiles);
550 sqlite3_free (xtiles);
551 sql = sqlite3_mprintf ("CREATE TRIGGER \"%s\"\n"
552 "BEFORE INSERT ON %Q\nFOR EACH ROW BEGIN\n"
553 "SELECT RAISE(ABORT,'insert on %s violates constraint: "
554 "invalid tile_data')\nWHERE IsValidRasterTile(%Q, "
555 "(SELECT t.pyramid_level FROM \"%s\" AS t WHERE t.tile_id = NEW.tile_id), "
556 "NEW.tile_data_odd, NEW.tile_data_even) <> 1;\nEND",
557 xxtrigger, xcoverage, xcoverage, coverage, xxtiles);
558 sqlite3_free (xcoverage);
559 free (xxtiles);
560 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
561 sqlite3_free (sql);
562 if (ret != SQLITE_OK)
563 {
564 fprintf (stderr, "CREATE TRIGGER \"%s\" error: %s\n", xxtrigger,
565 sql_err);
566 sqlite3_free (sql_err);
567 free (xxtrigger);
568 return 0;
569 }
570 free (xxtrigger);
571 xtrigger = sqlite3_mprintf ("%s_tile_data_update", coverage);
572 xxtrigger = gaiaDoubleQuotedSql (xtrigger);
573 sqlite3_free (xtrigger);
574 xcoverage = sqlite3_mprintf ("%s_tile_data", coverage);
575 xtiles = sqlite3_mprintf ("%s_tiles", coverage);
576 xxtiles = gaiaDoubleQuotedSql (xtiles);
577 sqlite3_free (xtiles);
578 sql = sqlite3_mprintf ("CREATE TRIGGER \"%s\"\n"
579 "BEFORE UPDATE ON %Q\nFOR EACH ROW BEGIN\n"
580 "SELECT RAISE(ABORT, 'update on %s violates constraint: "
581 "invalid tile_data')\nWHERE IsValidRasterTile(%Q, "
582 "(SELECT t.pyramid_level FROM \"%s\" AS t WHERE t.tile_id = NEW.tile_id), "
583 "NEW.tile_data_odd, NEW.tile_data_even) <> 1;\nEND",
584 xxtrigger, xcoverage, xcoverage, coverage, xxtiles);
585 sqlite3_free (xcoverage);
586 free (xxtiles);
587 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
588 sqlite3_free (sql);
589 if (ret != SQLITE_OK)
590 {
591 fprintf (stderr, "CREATE TRIGGER \"%s\" error: %s\n", xxtrigger,
592 sql_err);
593 sqlite3_free (sql_err);
594 free (xxtrigger);
595 return 0;
596 }
597 free (xxtrigger);
598 return 1;
599 }
600
601 RL2_DECLARE int
rl2_create_dbms_coverage(sqlite3 * handle,const char * coverage,unsigned char sample,unsigned char pixel,unsigned char num_bands,unsigned char compression,int quality,unsigned int tile_width,unsigned int tile_height,int srid,double x_res,double y_res,rl2PixelPtr no_data,rl2PalettePtr palette)602 rl2_create_dbms_coverage (sqlite3 * handle, const char *coverage,
603 unsigned char sample, unsigned char pixel,
604 unsigned char num_bands, unsigned char compression,
605 int quality, unsigned int tile_width,
606 unsigned int tile_height, int srid, double x_res,
607 double y_res, rl2PixelPtr no_data,
608 rl2PalettePtr palette)
609 {
610 /* creating a DBMS-based Coverage */
611 unsigned char *blob = NULL;
612 int blob_size = 0;
613 unsigned char *blob_no_data = NULL;
614 int blob_no_data_sz = 0;
615 if (pixel == RL2_PIXEL_PALETTE)
616 {
617 /* installing a default (empty) Palette */
618 if (rl2_serialize_dbms_palette (palette, &blob, &blob_size) != RL2_OK)
619 goto error;
620 }
621 if (no_data != NULL)
622 {
623 if (rl2_serialize_dbms_pixel
624 (no_data, &blob_no_data, &blob_no_data_sz) != RL2_OK)
625 goto error;
626 }
627 if (!insert_into_raster_coverages
628 (handle, coverage, sample, pixel, num_bands, compression, quality,
629 tile_width, tile_height, srid, x_res, y_res, blob, blob_size,
630 blob_no_data, blob_no_data_sz))
631 goto error;
632 if (!create_levels (handle, coverage))
633 goto error;
634 if (!create_sections (handle, coverage, srid))
635 goto error;
636 if (!create_tiles (handle, coverage, srid))
637 goto error;
638 return RL2_OK;
639 error:
640 return RL2_ERROR;
641 }
642
643 RL2_DECLARE int
rl2_get_dbms_section_id(sqlite3 * handle,const char * coverage,const char * section,sqlite3_int64 * section_id)644 rl2_get_dbms_section_id (sqlite3 * handle, const char *coverage,
645 const char *section, sqlite3_int64 * section_id)
646 {
647 /* retrieving a Section ID by its name */
648 int ret;
649 char *sql;
650 char *table;
651 char *xtable;
652 int found = 0;
653 sqlite3_stmt *stmt = NULL;
654
655 table = sqlite3_mprintf ("%s_sections", coverage);
656 xtable = gaiaDoubleQuotedSql (table);
657 sqlite3_free (table);
658 sql =
659 sqlite3_mprintf ("SELECT section_id FROM \"%s\" WHERE section_name = ?",
660 xtable);
661 free (xtable);
662 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
663 sqlite3_free (sql);
664 if (ret != SQLITE_OK)
665 {
666 printf ("SELECT section_name SQL error: %s\n",
667 sqlite3_errmsg (handle));
668 goto error;
669 }
670
671 /* querying the section */
672 sqlite3_reset (stmt);
673 sqlite3_clear_bindings (stmt);
674 sqlite3_bind_text (stmt, 1, section, strlen (section), SQLITE_STATIC);
675 while (1)
676 {
677 ret = sqlite3_step (stmt);
678 if (ret == SQLITE_DONE)
679 break;
680 if (ret == SQLITE_ROW)
681 {
682 *section_id = sqlite3_column_int64 (stmt, 0);
683 found++;
684 }
685 else
686 {
687 fprintf (stderr,
688 "SELECT section_name; sqlite3_step() error: %s\n",
689 sqlite3_errmsg (handle));
690 goto error;
691 }
692 }
693 sqlite3_finalize (stmt);
694 stmt = NULL;
695 if (found == 1)
696 return RL2_OK;
697
698 error:
699 if (stmt != NULL)
700 sqlite3_finalize (stmt);
701 return RL2_ERROR;
702 }
703
704 RL2_DECLARE int
rl2_delete_dbms_section(sqlite3 * handle,const char * coverage,sqlite3_int64 section_id)705 rl2_delete_dbms_section (sqlite3 * handle, const char *coverage,
706 sqlite3_int64 section_id)
707 {
708 /* deleting a Raster Section */
709 int ret;
710 char *sql;
711 rl2CoveragePtr cvg = NULL;
712 char *table;
713 char *xtable;
714 sqlite3_stmt *stmt = NULL;
715
716 table = sqlite3_mprintf ("%s_sections", coverage);
717 xtable = gaiaDoubleQuotedSql (table);
718 sqlite3_free (table);
719 sql = sqlite3_mprintf ("DELETE FROM \"%s\" WHERE section_id = ?", xtable);
720 free (xtable);
721 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
722 sqlite3_free (sql);
723 if (ret != SQLITE_OK)
724 {
725 printf ("DELETE sections SQL error: %s\n", sqlite3_errmsg (handle));
726 goto error;
727 }
728
729 /* DELETing the section */
730 sqlite3_reset (stmt);
731 sqlite3_clear_bindings (stmt);
732 sqlite3_bind_int64 (stmt, 1, section_id);
733 ret = sqlite3_step (stmt);
734 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
735 ;
736 else
737 {
738 fprintf (stderr,
739 "DELETE sections; sqlite3_step() error: %s\n",
740 sqlite3_errmsg (handle));
741 goto error;
742 }
743 sqlite3_finalize (stmt);
744
745 rl2_destroy_coverage (cvg);
746 return RL2_OK;
747
748 error:
749 if (stmt != NULL)
750 sqlite3_finalize (stmt);
751 if (cvg != NULL)
752 rl2_destroy_coverage (cvg);
753 return RL2_ERROR;
754 }
755
756 RL2_DECLARE int
rl2_drop_dbms_coverage(sqlite3 * handle,const char * coverage)757 rl2_drop_dbms_coverage (sqlite3 * handle, const char *coverage)
758 {
759 /* dropping a Raster Coverage */
760 int ret;
761 char *sql;
762 char *sql_err = NULL;
763 char *table;
764 char *xtable;
765
766 /* disabling the SECTIONS spatial index */
767 xtable = sqlite3_mprintf ("%s_sections", coverage);
768 sql = sqlite3_mprintf ("SELECT DisableSpatialIndex("
769 "%Q, 'geometry')", xtable);
770 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
771 sqlite3_free (sql);
772 if (ret != SQLITE_OK)
773 {
774 fprintf (stderr, "DisableSpatialIndex \"%s\" error: %s\n", xtable,
775 sql_err);
776 sqlite3_free (sql_err);
777 sqlite3_free (xtable);
778 goto error;
779 }
780 sqlite3_free (xtable);
781
782 /* dropping the SECTIONS spatial index */
783 table = sqlite3_mprintf ("idx_%s_sections_geometry", coverage);
784 xtable = gaiaDoubleQuotedSql (table);
785 sql = sqlite3_mprintf ("DROP TABLE \"%s\"", xtable);
786 free (xtable);
787 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
788 sqlite3_free (sql);
789 if (ret != SQLITE_OK)
790 {
791 fprintf (stderr, "DROP TABLE \"%s\" error: %s\n", table, sql_err);
792 sqlite3_free (sql_err);
793 sqlite3_free (table);
794 goto error;
795 }
796 sqlite3_free (table);
797
798 /* disabling the TILES spatial index */
799 xtable = sqlite3_mprintf ("%s_tiles", coverage);
800 sql = sqlite3_mprintf ("SELECT DisableSpatialIndex("
801 "%Q, 'geometry')", xtable);
802 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
803 sqlite3_free (sql);
804 if (ret != SQLITE_OK)
805 {
806 fprintf (stderr, "DisableSpatialIndex \"%s\" error: %s\n", xtable,
807 sql_err);
808 sqlite3_free (sql_err);
809 sqlite3_free (xtable);
810 goto error;
811 }
812 sqlite3_free (xtable);
813
814 /* dropping the TILES spatial index */
815 table = sqlite3_mprintf ("idx_%s_tiles_geometry", coverage);
816 xtable = gaiaDoubleQuotedSql (table);
817 sql = sqlite3_mprintf ("DROP TABLE \"%s\"", xtable);
818 free (xtable);
819 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
820 sqlite3_free (sql);
821 if (ret != SQLITE_OK)
822 {
823 fprintf (stderr, "DROP TABLE \"%s\" error: %s\n", table, sql_err);
824 sqlite3_free (sql_err);
825 sqlite3_free (table);
826 goto error;
827 }
828 sqlite3_free (table);
829
830 /* dropping the TILE_DATA table */
831 table = sqlite3_mprintf ("%s_tile_data", coverage);
832 xtable = gaiaDoubleQuotedSql (table);
833 sql = sqlite3_mprintf ("DROP TABLE \"%s\"", xtable);
834 free (xtable);
835 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
836 sqlite3_free (sql);
837 if (ret != SQLITE_OK)
838 {
839 fprintf (stderr, "DROP TABLE \"%s\" error: %s\n", table, sql_err);
840 sqlite3_free (sql_err);
841 sqlite3_free (table);
842 goto error;
843 }
844 sqlite3_free (table);
845
846 /* deleting the TILES Geometry definition */
847 table = sqlite3_mprintf ("%s_tiles", coverage);
848 xtable = gaiaDoubleQuotedSql (table);
849 sqlite3_free (table);
850 sql = sqlite3_mprintf ("DELETE FROM geometry_columns "
851 "WHERE Lower(f_table_name) = Lower(%Q)", xtable);
852 free (xtable);
853 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
854 sqlite3_free (sql);
855 if (ret != SQLITE_OK)
856 {
857 fprintf (stderr, "DELETE TilesGeometry \"%s\" error: %s\n",
858 coverage, sql_err);
859 sqlite3_free (sql_err);
860 goto error;
861 }
862
863 /* deleting the SECTIONS Geometry definition */
864 table = sqlite3_mprintf ("%s_sections", coverage);
865 xtable = gaiaDoubleQuotedSql (table);
866 sql = sqlite3_mprintf ("DELETE FROM geometry_columns "
867 "WHERE Lower(f_table_name) = Lower(%Q)", xtable);
868 free (xtable);
869 sqlite3_free (table);
870 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
871 sqlite3_free (sql);
872 if (ret != SQLITE_OK)
873 {
874 fprintf (stderr, "DELETE SectionsGeometry \"%s\" error: %s\n",
875 coverage, sql_err);
876 sqlite3_free (sql_err);
877 goto error;
878 }
879
880 /* dropping the TILES table */
881 table = sqlite3_mprintf ("%s_tiles", coverage);
882 xtable = gaiaDoubleQuotedSql (table);
883 sql = sqlite3_mprintf ("DROP TABLE \"%s\"", xtable);
884 free (xtable);
885 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
886 sqlite3_free (sql);
887 if (ret != SQLITE_OK)
888 {
889 fprintf (stderr, "DROP TABLE \"%s\" error: %s\n", table, sql_err);
890 sqlite3_free (sql_err);
891 sqlite3_free (table);
892 goto error;
893 }
894 sqlite3_free (table);
895
896 /* dropping the SECTIONS table */
897 table = sqlite3_mprintf ("%s_sections", coverage);
898 xtable = gaiaDoubleQuotedSql (table);
899 sql = sqlite3_mprintf ("DROP TABLE \"%s\"", xtable);
900 free (xtable);
901 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
902 sqlite3_free (sql);
903 if (ret != SQLITE_OK)
904 {
905 fprintf (stderr, "DROP TABLE \"%s\" error: %s\n", table, sql_err);
906 sqlite3_free (sql_err);
907 sqlite3_free (table);
908 goto error;
909 }
910 sqlite3_free (table);
911
912 /* dropping the LEVELS table */
913 table = sqlite3_mprintf ("%s_levels", coverage);
914 xtable = gaiaDoubleQuotedSql (table);
915 sql = sqlite3_mprintf ("DROP TABLE \"%s\"", xtable);
916 free (xtable);
917 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
918 sqlite3_free (sql);
919 if (ret != SQLITE_OK)
920 {
921 fprintf (stderr, "DROP TABLE \"%s\" error: %s\n", table, sql_err);
922 sqlite3_free (sql_err);
923 sqlite3_free (table);
924 goto error;
925 }
926 sqlite3_free (table);
927
928 /* deleting the Raster Coverage definition */
929 sql = sqlite3_mprintf ("DELETE FROM raster_coverages "
930 "WHERE Lower(coverage_name) = Lower(%Q)", coverage);
931 ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
932 sqlite3_free (sql);
933 if (ret != SQLITE_OK)
934 {
935 fprintf (stderr, "DELETE raster_coverage \"%s\" error: %s\n",
936 coverage, sql_err);
937 sqlite3_free (sql_err);
938 goto error;
939 }
940 return RL2_OK;
941
942 error:
943 return RL2_ERROR;
944 }
945
946 static void
prime_void_tile_int8(void * pixels,unsigned int width,unsigned int height,rl2PixelPtr no_data)947 prime_void_tile_int8 (void *pixels, unsigned int width, unsigned int height,
948 rl2PixelPtr no_data)
949 {
950 /* priming a void tile buffer - INT8 */
951 unsigned int row;
952 unsigned int col;
953 char *p = pixels;
954 char val = 0;
955
956 if (no_data != NULL)
957 {
958 /* retrieving the NO-DATA value */
959 unsigned char sample_type;
960 unsigned char pixel_type;
961 unsigned char num_bands;
962 if (rl2_get_pixel_type
963 (no_data, &sample_type, &pixel_type, &num_bands) != RL2_OK)
964 goto done;
965 if (sample_type != RL2_SAMPLE_INT8 || num_bands != 1)
966 goto done;
967 rl2_get_pixel_sample_int8 (no_data, &val);
968 }
969
970 done:
971 for (row = 0; row < height; row++)
972 {
973 for (col = 0; col < width; col++)
974 *p++ = val;
975 }
976 }
977
978 static void
prime_void_tile_uint8(void * pixels,unsigned int width,unsigned int height,unsigned char num_bands,rl2PixelPtr no_data)979 prime_void_tile_uint8 (void *pixels, unsigned int width,
980 unsigned int height, unsigned char num_bands,
981 rl2PixelPtr no_data)
982 {
983 /* priming a void tile buffer - UINT8 */
984 unsigned int row;
985 unsigned int col;
986 int band;
987 unsigned char *p = pixels;
988 unsigned char val = 0;
989 int ok_no_data = 0;
990
991 if (no_data != NULL)
992 {
993 /* retrieving the NO-DATA value */
994 unsigned char sample_type;
995 unsigned char pixel_type;
996 unsigned char num_bands;
997 if (rl2_get_pixel_type
998 (no_data, &sample_type, &pixel_type, &num_bands) != RL2_OK)
999 goto done;
1000 if (sample_type != RL2_SAMPLE_UINT8)
1001 goto done;
1002 ok_no_data = 1;
1003 }
1004
1005 done:
1006 for (row = 0; row < height; row++)
1007 {
1008 for (col = 0; col < width; col++)
1009 {
1010 for (band = 0; band < num_bands; band++)
1011 {
1012 if (ok_no_data)
1013 rl2_get_pixel_sample_uint8 (no_data, band, &val);
1014 *p++ = val;
1015 }
1016 }
1017 }
1018 }
1019
1020 static void
prime_void_tile_int16(void * pixels,unsigned int width,unsigned int height,rl2PixelPtr no_data)1021 prime_void_tile_int16 (void *pixels, unsigned int width,
1022 unsigned int height, rl2PixelPtr no_data)
1023 {
1024 /* priming a void tile buffer - INT16 */
1025 unsigned int row;
1026 unsigned int col;
1027 short *p = pixels;
1028 short val = 0;
1029
1030 if (no_data != NULL)
1031 {
1032 /* retrieving the NO-DATA value */
1033 unsigned char sample_type;
1034 unsigned char pixel_type;
1035 unsigned char num_bands;
1036 if (rl2_get_pixel_type
1037 (no_data, &sample_type, &pixel_type, &num_bands) != RL2_OK)
1038 goto done;
1039 if (sample_type != RL2_SAMPLE_INT16 || num_bands != 1)
1040 goto done;
1041 rl2_get_pixel_sample_int16 (no_data, &val);
1042 }
1043
1044 done:
1045 for (row = 0; row < height; row++)
1046 {
1047 for (col = 0; col < width; col++)
1048 *p++ = val;
1049 }
1050 }
1051
1052 static void
prime_void_tile_uint16(void * pixels,unsigned int width,unsigned int height,unsigned char num_bands,rl2PixelPtr no_data)1053 prime_void_tile_uint16 (void *pixels, unsigned int width,
1054 unsigned int height, unsigned char num_bands,
1055 rl2PixelPtr no_data)
1056 {
1057 /* priming a void tile buffer - UINT16 */
1058 unsigned int row;
1059 unsigned int col;
1060 int band;
1061 unsigned short *p = pixels;
1062 unsigned short val = 0;
1063 int ok_no_data = 0;
1064
1065 if (no_data != NULL)
1066 {
1067 /* retrieving the NO-DATA value */
1068 unsigned char sample_type;
1069 unsigned char pixel_type;
1070 unsigned char num_bands;
1071 if (rl2_get_pixel_type
1072 (no_data, &sample_type, &pixel_type, &num_bands) != RL2_OK)
1073 goto done;
1074 if (sample_type != RL2_SAMPLE_UINT16)
1075 goto done;
1076 ok_no_data = 1;
1077 }
1078
1079 done:
1080 for (row = 0; row < height; row++)
1081 {
1082 for (col = 0; col < width; col++)
1083 {
1084 for (band = 0; band < num_bands; band++)
1085 {
1086 if (ok_no_data)
1087 rl2_get_pixel_sample_uint16 (no_data, band, &val);
1088 *p++ = val;
1089 }
1090 }
1091 }
1092 }
1093
1094 static void
prime_void_tile_int32(void * pixels,unsigned int width,unsigned int height,rl2PixelPtr no_data)1095 prime_void_tile_int32 (void *pixels, unsigned int width,
1096 unsigned int height, rl2PixelPtr no_data)
1097 {
1098 /* priming a void tile buffer - INT32 */
1099 unsigned int row;
1100 unsigned int col;
1101 int *p = pixels;
1102 int val = 0;
1103
1104 if (no_data != NULL)
1105 {
1106 /* retrieving the NO-DATA value */
1107 unsigned char sample_type;
1108 unsigned char pixel_type;
1109 unsigned char num_bands;
1110 if (rl2_get_pixel_type
1111 (no_data, &sample_type, &pixel_type, &num_bands) != RL2_OK)
1112 goto done;
1113 if (sample_type != RL2_SAMPLE_INT32 || num_bands != 1)
1114 goto done;
1115 rl2_get_pixel_sample_int32 (no_data, &val);
1116 }
1117
1118 done:
1119 for (row = 0; row < height; row++)
1120 {
1121 for (col = 0; col < width; col++)
1122 *p++ = val;
1123 }
1124 }
1125
1126 static void
prime_void_tile_uint32(void * pixels,unsigned int width,unsigned int height,rl2PixelPtr no_data)1127 prime_void_tile_uint32 (void *pixels, unsigned int width,
1128 unsigned int height, rl2PixelPtr no_data)
1129 {
1130 /* priming a void tile buffer - UINT32 */
1131 unsigned int row;
1132 unsigned int col;
1133 unsigned int *p = pixels;
1134 unsigned int val = 0;
1135
1136 if (no_data != NULL)
1137 {
1138 /* retrieving the NO-DATA value */
1139 unsigned char sample_type;
1140 unsigned char pixel_type;
1141 unsigned char num_bands;
1142 if (rl2_get_pixel_type
1143 (no_data, &sample_type, &pixel_type, &num_bands) != RL2_OK)
1144 goto done;
1145 if (sample_type != RL2_SAMPLE_UINT32 || num_bands != 1)
1146 goto done;
1147 rl2_get_pixel_sample_uint32 (no_data, &val);
1148 }
1149
1150 done:
1151 for (row = 0; row < height; row++)
1152 {
1153 for (col = 0; col < width; col++)
1154 *p++ = val;
1155 }
1156 }
1157
1158 static void
prime_void_tile_float(void * pixels,unsigned int width,unsigned int height,rl2PixelPtr no_data)1159 prime_void_tile_float (void *pixels, unsigned int width,
1160 unsigned int height, rl2PixelPtr no_data)
1161 {
1162 /* priming a void tile buffer - Float */
1163 unsigned int row;
1164 unsigned int col;
1165 float *p = pixels;
1166 float val = 0.0;
1167
1168 if (no_data != NULL)
1169 {
1170 /* retrieving the NO-DATA value */
1171 unsigned char sample_type;
1172 unsigned char pixel_type;
1173 unsigned char num_bands;
1174 if (rl2_get_pixel_type
1175 (no_data, &sample_type, &pixel_type, &num_bands) != RL2_OK)
1176 goto done;
1177 if (sample_type != RL2_SAMPLE_FLOAT || num_bands != 1)
1178 goto done;
1179 rl2_get_pixel_sample_float (no_data, &val);
1180 }
1181
1182 done:
1183 for (row = 0; row < height; row++)
1184 {
1185 for (col = 0; col < width; col++)
1186 *p++ = val;
1187 }
1188 }
1189
1190 static void
prime_void_tile_double(void * pixels,unsigned int width,unsigned int height,rl2PixelPtr no_data)1191 prime_void_tile_double (void *pixels, unsigned int width,
1192 unsigned int height, rl2PixelPtr no_data)
1193 {
1194 /* priming a void tile buffer - Double */
1195 unsigned int row;
1196 unsigned int col;
1197 double *p = pixels;
1198 double val = 0.0;
1199
1200 if (no_data != NULL)
1201 {
1202 /* retrieving the NO-DATA value */
1203 unsigned char sample_type;
1204 unsigned char pixel_type;
1205 unsigned char num_bands;
1206 if (rl2_get_pixel_type
1207 (no_data, &sample_type, &pixel_type, &num_bands) != RL2_OK)
1208 goto done;
1209 if (sample_type != RL2_SAMPLE_DOUBLE || num_bands != 1)
1210 goto done;
1211 rl2_get_pixel_sample_double (no_data, &val);
1212 }
1213
1214 done:
1215 for (row = 0; row < height; row++)
1216 {
1217 for (col = 0; col < width; col++)
1218 *p++ = val;
1219 }
1220 }
1221
1222 RL2_DECLARE void
rl2_prime_void_tile(void * pixels,unsigned int width,unsigned int height,unsigned char sample_type,unsigned char num_bands,rl2PixelPtr no_data)1223 rl2_prime_void_tile (void *pixels, unsigned int width, unsigned int height,
1224 unsigned char sample_type, unsigned char num_bands,
1225 rl2PixelPtr no_data)
1226 {
1227 /* priming a void tile buffer */
1228 switch (sample_type)
1229 {
1230 case RL2_SAMPLE_INT8:
1231 prime_void_tile_int8 (pixels, width, height, no_data);
1232 break;
1233 case RL2_SAMPLE_1_BIT:
1234 case RL2_SAMPLE_2_BIT:
1235 case RL2_SAMPLE_4_BIT:
1236 case RL2_SAMPLE_UINT8:
1237 prime_void_tile_uint8 (pixels, width, height, num_bands, no_data);
1238 break;
1239 case RL2_SAMPLE_INT16:
1240 prime_void_tile_int16 (pixels, width, height, no_data);
1241 break;
1242 case RL2_SAMPLE_UINT16:
1243 prime_void_tile_uint16 (pixels, width, height, num_bands, no_data);
1244 break;
1245 case RL2_SAMPLE_INT32:
1246 prime_void_tile_int32 (pixels, width, height, no_data);
1247 break;
1248 case RL2_SAMPLE_UINT32:
1249 prime_void_tile_uint32 (pixels, width, height, no_data);
1250 break;
1251 case RL2_SAMPLE_FLOAT:
1252 prime_void_tile_float (pixels, width, height, no_data);
1253 break;
1254 case RL2_SAMPLE_DOUBLE:
1255 prime_void_tile_double (pixels, width, height, no_data);
1256 break;
1257 };
1258 }
1259
1260 RL2_DECLARE void
rl2_prime_void_tile_palette(void * pixels,unsigned int width,unsigned int height,rl2PixelPtr no_data)1261 rl2_prime_void_tile_palette (void *pixels, unsigned int width,
1262 unsigned int height, rl2PixelPtr no_data)
1263 {
1264 /* priming a void tile buffer (PALETTE) */
1265 unsigned int row;
1266 unsigned int col;
1267 unsigned char index = 0;
1268 unsigned char *p = pixels;
1269
1270 if (no_data != NULL)
1271 {
1272 /* retrieving the NO-DATA value */
1273 unsigned char sample_type;
1274 unsigned char pixel_type;
1275 unsigned char num_bands;
1276 if (rl2_get_pixel_type
1277 (no_data, &sample_type, &pixel_type, &num_bands) != RL2_OK)
1278 goto done;
1279 if (pixel_type != RL2_PIXEL_PALETTE || num_bands != 1)
1280 goto done;
1281 switch (sample_type)
1282 {
1283 case RL2_SAMPLE_1_BIT:
1284 rl2_get_pixel_sample_1bit (no_data, &index);
1285 break;
1286 case RL2_SAMPLE_2_BIT:
1287 rl2_get_pixel_sample_2bit (no_data, &index);
1288 break;
1289 case RL2_SAMPLE_4_BIT:
1290 rl2_get_pixel_sample_4bit (no_data, &index);
1291 break;
1292 case RL2_SAMPLE_UINT8:
1293 rl2_get_pixel_sample_uint8 (no_data, 0, &index);
1294 break;
1295 };
1296 }
1297
1298 done:
1299 for (row = 0; row < height; row++)
1300 {
1301 for (col = 0; col < width; col++)
1302 *p++ = index;
1303 }
1304 }
1305
1306 RL2_DECLARE rl2CoveragePtr
rl2_create_coverage_from_dbms(sqlite3 * handle,const char * coverage)1307 rl2_create_coverage_from_dbms (sqlite3 * handle, const char *coverage)
1308 {
1309 /* attempting to create a Coverage Object from the DBMS definition */
1310 char *sql;
1311 int ret;
1312 sqlite3_stmt *stmt;
1313 int sample;
1314 int pixel;
1315 int num_bands;
1316 int compression;
1317 int quality;
1318 int tile_width;
1319 int tile_height;
1320 double x_res;
1321 double y_res;
1322 int srid;
1323 int ok = 0;
1324 const char *value;
1325 rl2PixelPtr no_data = NULL;
1326 rl2CoveragePtr cvg;
1327
1328 /* querying the Coverage metadata defs */
1329 sql =
1330 "SELECT sample_type, pixel_type, num_bands, compression, quality, tile_width, "
1331 "tile_height, horz_resolution, vert_resolution, srid, nodata_pixel "
1332 "FROM raster_coverages WHERE Lower(coverage_name) = Lower(?)";
1333 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
1334 if (ret != SQLITE_OK)
1335 {
1336 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
1337 return NULL;
1338 }
1339 sqlite3_reset (stmt);
1340 sqlite3_clear_bindings (stmt);
1341 sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
1342 while (1)
1343 {
1344 /* scrolling the result set rows */
1345 ret = sqlite3_step (stmt);
1346 if (ret == SQLITE_DONE)
1347 break; /* end of result set */
1348 if (ret == SQLITE_ROW)
1349 {
1350 int ok_sample = 0;
1351 int ok_pixel = 0;
1352 int ok_num_bands = 0;
1353 int ok_compression = 0;
1354 int ok_quality = 0;
1355 int ok_tile_width = 0;
1356 int ok_tile_height = 0;
1357 int ok_x_res = 0;
1358 int ok_y_res = 0;
1359 int ok_srid = 0;
1360 int ok_nodata = 1;
1361 if (sqlite3_column_type (stmt, 0) == SQLITE_TEXT)
1362 {
1363 value = (const char *) sqlite3_column_text (stmt, 0);
1364 if (strcasecmp (value, "1-BIT") == 0)
1365 {
1366 ok_sample = 1;
1367 sample = RL2_SAMPLE_1_BIT;
1368 }
1369 if (strcasecmp (value, "2-BIT") == 0)
1370 {
1371 ok_sample = 1;
1372 sample = RL2_SAMPLE_2_BIT;
1373 }
1374 if (strcasecmp (value, "4-BIT") == 0)
1375 {
1376 ok_sample = 1;
1377 sample = RL2_SAMPLE_4_BIT;
1378 }
1379 if (strcasecmp (value, "INT8") == 0)
1380 {
1381 ok_sample = 1;
1382 sample = RL2_SAMPLE_INT8;
1383 }
1384 if (strcasecmp (value, "UINT8") == 0)
1385 {
1386 ok_sample = 1;
1387 sample = RL2_SAMPLE_UINT8;
1388 }
1389 if (strcasecmp (value, "INT16") == 0)
1390 {
1391 ok_sample = 1;
1392 sample = RL2_SAMPLE_INT16;
1393 }
1394 if (strcasecmp (value, "UINT16") == 0)
1395 {
1396 ok_sample = 1;
1397 sample = RL2_SAMPLE_UINT16;
1398 }
1399 if (strcasecmp (value, "INT32") == 0)
1400 {
1401 ok_sample = 1;
1402 sample = RL2_SAMPLE_INT32;
1403 }
1404 if (strcasecmp (value, "UINT32") == 0)
1405 {
1406 ok_sample = 1;
1407 sample = RL2_SAMPLE_UINT32;
1408 }
1409 if (strcasecmp (value, "FLOAT") == 0)
1410 {
1411 ok_sample = 1;
1412 sample = RL2_SAMPLE_FLOAT;
1413 }
1414 if (strcasecmp (value, "DOUBLE") == 0)
1415 {
1416 ok_sample = 1;
1417 sample = RL2_SAMPLE_DOUBLE;
1418 }
1419 }
1420 if (sqlite3_column_type (stmt, 1) == SQLITE_TEXT)
1421 {
1422 value = (const char *) sqlite3_column_text (stmt, 1);
1423 if (strcasecmp (value, "MONOCHROME") == 0)
1424 {
1425 ok_pixel = 1;
1426 pixel = RL2_PIXEL_MONOCHROME;
1427 }
1428 if (strcasecmp (value, "PALETTE") == 0)
1429 {
1430 ok_pixel = 1;
1431 pixel = RL2_PIXEL_PALETTE;
1432 }
1433 if (strcasecmp (value, "GRAYSCALE") == 0)
1434 {
1435 ok_pixel = 1;
1436 pixel = RL2_PIXEL_GRAYSCALE;
1437 }
1438 if (strcasecmp (value, "RGB") == 0)
1439 {
1440 ok_pixel = 1;
1441 pixel = RL2_PIXEL_RGB;
1442 }
1443 if (strcasecmp (value, "MULTIBAND") == 0)
1444 {
1445 ok_pixel = 1;
1446 pixel = RL2_PIXEL_MULTIBAND;
1447 }
1448 if (strcasecmp (value, "DATAGRID") == 0)
1449 {
1450 ok_pixel = 1;
1451 pixel = RL2_PIXEL_DATAGRID;
1452 }
1453 }
1454 if (sqlite3_column_type (stmt, 2) == SQLITE_INTEGER)
1455 {
1456 num_bands = sqlite3_column_int (stmt, 2);
1457 ok_num_bands = 1;
1458 }
1459 if (sqlite3_column_type (stmt, 3) == SQLITE_TEXT)
1460 {
1461 value = (const char *) sqlite3_column_text (stmt, 3);
1462 if (strcasecmp (value, "NONE") == 0)
1463 {
1464 ok_compression = 1;
1465 compression = RL2_COMPRESSION_NONE;
1466 }
1467 if (strcasecmp (value, "DEFLATE") == 0)
1468 {
1469 ok_compression = 1;
1470 compression = RL2_COMPRESSION_DEFLATE;
1471 }
1472 if (strcasecmp (value, "LZMA") == 0)
1473 {
1474 ok_compression = 1;
1475 compression = RL2_COMPRESSION_LZMA;
1476 }
1477 if (strcasecmp (value, "PNG") == 0)
1478 {
1479 ok_compression = 1;
1480 compression = RL2_COMPRESSION_PNG;
1481 }
1482 if (strcasecmp (value, "JPEG") == 0)
1483 {
1484 ok_compression = 1;
1485 compression = RL2_COMPRESSION_JPEG;
1486 }
1487 if (strcasecmp (value, "LOSSY_WEBP") == 0)
1488 {
1489 ok_compression = 1;
1490 compression = RL2_COMPRESSION_LOSSY_WEBP;
1491 }
1492 if (strcasecmp (value, "LOSSLESS_WEBP") == 0)
1493 {
1494 ok_compression = 1;
1495 compression = RL2_COMPRESSION_LOSSLESS_WEBP;
1496 }
1497 if (strcasecmp (value, "CCITTFAX4") == 0)
1498 {
1499 ok_compression = 1;
1500 compression = RL2_COMPRESSION_CCITTFAX4;
1501 }
1502 }
1503 if (sqlite3_column_type (stmt, 4) == SQLITE_INTEGER)
1504 {
1505 quality = sqlite3_column_int (stmt, 4);
1506 ok_quality = 1;
1507 }
1508 if (sqlite3_column_type (stmt, 5) == SQLITE_INTEGER)
1509 {
1510 tile_width = sqlite3_column_int (stmt, 5);
1511 ok_tile_width = 1;
1512 }
1513 if (sqlite3_column_type (stmt, 6) == SQLITE_INTEGER)
1514 {
1515 tile_height = sqlite3_column_int (stmt, 6);
1516 ok_tile_height = 1;
1517 }
1518 if (sqlite3_column_type (stmt, 7) == SQLITE_FLOAT)
1519 {
1520 x_res = sqlite3_column_double (stmt, 7);
1521 ok_x_res = 1;
1522 }
1523 if (sqlite3_column_type (stmt, 8) == SQLITE_FLOAT)
1524 {
1525 y_res = sqlite3_column_double (stmt, 8);
1526 ok_y_res = 1;
1527 }
1528 if (sqlite3_column_type (stmt, 9) == SQLITE_INTEGER)
1529 {
1530 srid = sqlite3_column_int (stmt, 9);
1531 ok_srid = 1;
1532 }
1533 if (sqlite3_column_type (stmt, 10) == SQLITE_BLOB)
1534 {
1535 const unsigned char *blob =
1536 sqlite3_column_blob (stmt, 10);
1537 int blob_sz = sqlite3_column_bytes (stmt, 10);
1538 no_data = rl2_deserialize_dbms_pixel (blob, blob_sz);
1539 if (no_data == NULL)
1540 ok_nodata = 0;
1541 }
1542 if (ok_sample && ok_pixel && ok_num_bands && ok_compression
1543 && ok_quality && ok_tile_width && ok_tile_height && ok_x_res
1544 && ok_y_res && ok_srid && ok_nodata)
1545 ok = 1;
1546 }
1547 }
1548 sqlite3_finalize (stmt);
1549
1550 if (!ok)
1551 {
1552 fprintf (stderr, "ERROR: unable to find a Coverage named \"%s\"\n",
1553 coverage);
1554 return NULL;
1555 }
1556
1557 cvg =
1558 rl2_create_coverage (coverage, sample, pixel, num_bands, compression,
1559 quality, tile_width, tile_height, no_data);
1560 if (cvg == NULL)
1561 {
1562 fprintf (stderr,
1563 "ERROR: unable to create a Coverage Object supporting \"%s\"\n",
1564 coverage);
1565 return NULL;
1566 }
1567 if (rl2_coverage_georeference (cvg, srid, x_res, y_res) != RL2_OK)
1568 {
1569 fprintf (stderr,
1570 "ERROR: unable to Georeference a Coverage Object supporting \"%s\"\n",
1571 coverage);
1572 rl2_destroy_coverage (cvg);
1573 return NULL;
1574 }
1575 return cvg;
1576 }
1577
1578 static void
void_int8_raw_buffer(char * buffer,unsigned int width,unsigned int height,rl2PixelPtr no_data)1579 void_int8_raw_buffer (char *buffer, unsigned int width, unsigned int height,
1580 rl2PixelPtr no_data)
1581 {
1582 /* preparing an empty/void INT8 raw buffer */
1583 rl2PrivPixelPtr pxl = NULL;
1584 unsigned int x;
1585 unsigned int y;
1586 char *p = buffer;
1587 char nd_value = 0;
1588 if (no_data != NULL)
1589 {
1590 pxl = (rl2PrivPixelPtr) no_data;
1591 if (pxl->sampleType == RL2_SAMPLE_INT8 && pxl->nBands == 1)
1592 {
1593
1594 rl2PrivSamplePtr sample = pxl->Samples + 0;
1595 nd_value = sample->int8;
1596 }
1597 }
1598 for (y = 0; y < height; y++)
1599 {
1600 for (x = 0; x < width; x++)
1601 *p++ = nd_value;
1602 }
1603 }
1604
1605 static void
void_uint8_raw_buffer(unsigned char * buffer,unsigned int width,unsigned int height,unsigned char num_bands,rl2PixelPtr no_data)1606 void_uint8_raw_buffer (unsigned char *buffer, unsigned int width,
1607 unsigned int height, unsigned char num_bands,
1608 rl2PixelPtr no_data)
1609 {
1610 /* preparing an empty/void UINT8 raw buffer */
1611 rl2PrivPixelPtr pxl = NULL;
1612 unsigned int x;
1613 unsigned int y;
1614 unsigned char b;
1615 unsigned char *p = buffer;
1616 int has_nodata = 0;
1617 if (no_data != NULL)
1618 {
1619 pxl = (rl2PrivPixelPtr) no_data;
1620 if (pxl->sampleType == RL2_SAMPLE_UINT8 && pxl->nBands == num_bands)
1621 has_nodata = 1;
1622 }
1623 if (!has_nodata)
1624 {
1625 for (y = 0; y < height; y++)
1626 {
1627 for (x = 0; x < width; x++)
1628 {
1629 for (b = 0; b < num_bands; b++)
1630 *p++ = 0;
1631 }
1632 }
1633 }
1634 else
1635 {
1636 for (y = 0; y < height; y++)
1637 {
1638 for (x = 0; x < width; x++)
1639 {
1640 for (b = 0; b < num_bands; b++)
1641 {
1642 rl2PrivSamplePtr sample = pxl->Samples + b;
1643 *p++ = sample->uint8;
1644 }
1645 }
1646 }
1647 }
1648 }
1649
1650 static void
void_int16_raw_buffer(short * buffer,unsigned int width,unsigned int height,rl2PixelPtr no_data)1651 void_int16_raw_buffer (short *buffer, unsigned int width,
1652 unsigned int height, rl2PixelPtr no_data)
1653 {
1654 /* preparing an empty/void INT16 raw buffer */
1655 rl2PrivPixelPtr pxl = NULL;
1656 unsigned int x;
1657 unsigned int y;
1658 short *p = buffer;
1659 short nd_value = 0;
1660 if (no_data != NULL)
1661 {
1662 pxl = (rl2PrivPixelPtr) no_data;
1663 if (pxl->sampleType == RL2_SAMPLE_INT16 && pxl->nBands == 1)
1664 {
1665
1666 rl2PrivSamplePtr sample = pxl->Samples + 0;
1667 nd_value = sample->int16;
1668 }
1669 }
1670 for (y = 0; y < height; y++)
1671 {
1672 for (x = 0; x < width; x++)
1673 *p++ = nd_value;
1674 }
1675 }
1676
1677 static void
void_uint16_raw_buffer(unsigned short * buffer,unsigned int width,unsigned int height,unsigned char num_bands,rl2PixelPtr no_data)1678 void_uint16_raw_buffer (unsigned short *buffer, unsigned int width,
1679 unsigned int height, unsigned char num_bands,
1680 rl2PixelPtr no_data)
1681 {
1682 /* preparing an empty/void UINT16 raw buffer */
1683 rl2PrivPixelPtr pxl = NULL;
1684 unsigned int x;
1685 unsigned int y;
1686 unsigned char b;
1687 unsigned short *p = buffer;
1688 int has_nodata = 0;
1689 if (no_data != NULL)
1690 {
1691 pxl = (rl2PrivPixelPtr) no_data;
1692 if (pxl->sampleType == RL2_SAMPLE_UINT16 && pxl->nBands == num_bands)
1693 has_nodata = 1;
1694 }
1695 if (!has_nodata)
1696 {
1697 for (y = 0; y < height; y++)
1698 {
1699 for (x = 0; x < width; x++)
1700 {
1701 for (b = 0; b < num_bands; b++)
1702 *p++ = 0;
1703 }
1704 }
1705 }
1706 else
1707 {
1708 for (y = 0; y < height; y++)
1709 {
1710 for (x = 0; x < width; x++)
1711 {
1712 for (b = 0; b < num_bands; b++)
1713 {
1714 rl2PrivSamplePtr sample = pxl->Samples + b;
1715 *p++ = sample->uint16;
1716 }
1717 }
1718 }
1719 }
1720 }
1721
1722 static void
void_int32_raw_buffer(int * buffer,unsigned int width,unsigned int height,rl2PixelPtr no_data)1723 void_int32_raw_buffer (int *buffer, unsigned int width, unsigned int height,
1724 rl2PixelPtr no_data)
1725 {
1726 /* preparing an empty/void INT32 raw buffer */
1727 rl2PrivPixelPtr pxl = NULL;
1728 unsigned int x;
1729 unsigned int y;
1730 int *p = buffer;
1731 int nd_value = 0;
1732 if (no_data != NULL)
1733 {
1734 pxl = (rl2PrivPixelPtr) no_data;
1735 if (pxl->sampleType == RL2_SAMPLE_INT32 && pxl->nBands == 1)
1736 {
1737
1738 rl2PrivSamplePtr sample = pxl->Samples + 0;
1739 nd_value = sample->int32;
1740 }
1741 }
1742 for (y = 0; y < height; y++)
1743 {
1744 for (x = 0; x < width; x++)
1745 *p++ = nd_value;
1746 }
1747 }
1748
1749 static void
void_uint32_raw_buffer(unsigned int * buffer,unsigned int width,unsigned int height,rl2PixelPtr no_data)1750 void_uint32_raw_buffer (unsigned int *buffer, unsigned int width,
1751 unsigned int height, rl2PixelPtr no_data)
1752 {
1753 /* preparing an empty/void UINT32 raw buffer */
1754 rl2PrivPixelPtr pxl = NULL;
1755 unsigned int x;
1756 unsigned int y;
1757 unsigned int *p = buffer;
1758 unsigned int nd_value = 0;
1759 if (no_data != NULL)
1760 {
1761 pxl = (rl2PrivPixelPtr) no_data;
1762 if (pxl->sampleType == RL2_SAMPLE_UINT32 && pxl->nBands == 1)
1763 {
1764
1765 rl2PrivSamplePtr sample = pxl->Samples + 0;
1766 nd_value = sample->uint32;
1767 }
1768 }
1769 for (y = 0; y < height; y++)
1770 {
1771 for (x = 0; x < width; x++)
1772 *p++ = nd_value;
1773 }
1774 }
1775
1776 static void
void_float_raw_buffer(float * buffer,unsigned int width,unsigned int height,rl2PixelPtr no_data)1777 void_float_raw_buffer (float *buffer, unsigned int width,
1778 unsigned int height, rl2PixelPtr no_data)
1779 {
1780 /* preparing an empty/void FLOAT raw buffer */
1781 rl2PrivPixelPtr pxl = NULL;
1782 unsigned int x;
1783 unsigned int y;
1784 float *p = buffer;
1785 float nd_value = 0.0;
1786 if (no_data != NULL)
1787 {
1788 pxl = (rl2PrivPixelPtr) no_data;
1789 if (pxl->sampleType == RL2_SAMPLE_FLOAT && pxl->nBands == 1)
1790 {
1791
1792 rl2PrivSamplePtr sample = pxl->Samples + 0;
1793 nd_value = sample->float32;
1794 }
1795 }
1796 for (y = 0; y < height; y++)
1797 {
1798 for (x = 0; x < width; x++)
1799 *p++ = nd_value;
1800 }
1801 }
1802
1803 static void
void_double_raw_buffer(double * buffer,unsigned int width,unsigned int height,rl2PixelPtr no_data)1804 void_double_raw_buffer (double *buffer, unsigned int width,
1805 unsigned int height, rl2PixelPtr no_data)
1806 {
1807 /* preparing an empty/void DOUBLE raw buffer */
1808 rl2PrivPixelPtr pxl = NULL;
1809 unsigned int x;
1810 unsigned int y;
1811 double *p = buffer;
1812 double nd_value = 0.0;
1813 if (no_data != NULL)
1814 {
1815 pxl = (rl2PrivPixelPtr) no_data;
1816 if (pxl->sampleType == RL2_SAMPLE_DOUBLE && pxl->nBands == 1)
1817 {
1818
1819 rl2PrivSamplePtr sample = pxl->Samples + 0;
1820 nd_value = sample->float64;
1821 }
1822 }
1823 for (y = 0; y < height; y++)
1824 {
1825 for (x = 0; x < width; x++)
1826 *p++ = nd_value;
1827 }
1828 }
1829
1830 RL2_PRIVATE void
void_raw_buffer(unsigned char * buffer,unsigned int width,unsigned int height,unsigned char sample_type,unsigned char num_bands,rl2PixelPtr no_data)1831 void_raw_buffer (unsigned char *buffer, unsigned int width,
1832 unsigned int height, unsigned char sample_type,
1833 unsigned char num_bands, rl2PixelPtr no_data)
1834 {
1835 /* preparing an empty/void buffer */
1836 switch (sample_type)
1837 {
1838 case RL2_SAMPLE_INT8:
1839 void_int8_raw_buffer ((char *) buffer, width, height, no_data);
1840 break;
1841 case RL2_SAMPLE_INT16:
1842 void_int16_raw_buffer ((short *) buffer, width, height, no_data);
1843 break;
1844 case RL2_SAMPLE_UINT16:
1845 void_uint16_raw_buffer ((unsigned short *) buffer, width, height,
1846 num_bands, no_data);
1847 break;
1848 case RL2_SAMPLE_INT32:
1849 void_int32_raw_buffer ((int *) buffer, width, height, no_data);
1850 break;
1851 case RL2_SAMPLE_UINT32:
1852 void_uint32_raw_buffer ((unsigned int *) buffer, width, height,
1853 no_data);
1854 break;
1855 case RL2_SAMPLE_FLOAT:
1856 void_float_raw_buffer ((float *) buffer, width, height, no_data);
1857 break;
1858 case RL2_SAMPLE_DOUBLE:
1859 void_double_raw_buffer ((double *) buffer, width, height, no_data);
1860 break;
1861 default:
1862 void_uint8_raw_buffer ((unsigned char *) buffer, width, height,
1863 num_bands, no_data);
1864 break;
1865 };
1866 }
1867
1868 RL2_PRIVATE void
void_raw_buffer_palette(unsigned char * buffer,unsigned int width,unsigned int height,rl2PixelPtr no_data)1869 void_raw_buffer_palette (unsigned char *buffer, unsigned int width,
1870 unsigned int height, rl2PixelPtr no_data)
1871 {
1872 /* preparing an empty/void buffer (PALETTE) */
1873 unsigned int row;
1874 unsigned int col;
1875 unsigned char index = 0;
1876 unsigned char *p = buffer;
1877
1878 if (no_data != NULL)
1879 {
1880 /* retrieving the NO-DATA value */
1881 unsigned char sample_type;
1882 unsigned char pixel_type;
1883 unsigned char num_bands;
1884 if (rl2_get_pixel_type
1885 (no_data, &sample_type, &pixel_type, &num_bands) != RL2_OK)
1886 goto done;
1887 if (pixel_type != RL2_PIXEL_PALETTE || num_bands != 1)
1888 goto done;
1889 switch (sample_type)
1890 {
1891 case RL2_SAMPLE_1_BIT:
1892 rl2_get_pixel_sample_1bit (no_data, &index);
1893 break;
1894 case RL2_SAMPLE_2_BIT:
1895 rl2_get_pixel_sample_2bit (no_data, &index);
1896 break;
1897 case RL2_SAMPLE_4_BIT:
1898 rl2_get_pixel_sample_4bit (no_data, &index);
1899 break;
1900 case RL2_SAMPLE_UINT8:
1901 rl2_get_pixel_sample_uint8 (no_data, 0, &index);
1902 break;
1903 };
1904 }
1905
1906 done:
1907 for (row = 0; row < height; row++)
1908 {
1909 for (col = 0; col < width; col++)
1910 *p++ = index;
1911 }
1912 }
1913
1914 static int
load_dbms_tiles_common(sqlite3 * handle,sqlite3_stmt * stmt_tiles,sqlite3_stmt * stmt_data,unsigned char * outbuf,unsigned int width,unsigned int height,unsigned char sample_type,unsigned char num_bands,double x_res,double y_res,double minx,double maxy,int scale,rl2PalettePtr palette,rl2PixelPtr no_data,rl2RasterStylePtr style,rl2RasterStatisticsPtr stats)1915 load_dbms_tiles_common (sqlite3 * handle, sqlite3_stmt * stmt_tiles,
1916 sqlite3_stmt * stmt_data, unsigned char *outbuf,
1917 unsigned int width,
1918 unsigned int height, unsigned char sample_type,
1919 unsigned char num_bands, double x_res, double y_res,
1920 double minx, double maxy,
1921 int scale, rl2PalettePtr palette, rl2PixelPtr no_data,
1922 rl2RasterStylePtr style, rl2RasterStatisticsPtr stats)
1923 {
1924 /* retrieving a full image from DBMS tiles */
1925 rl2RasterPtr raster = NULL;
1926 rl2PalettePtr plt = NULL;
1927 int ret;
1928
1929 /* querying the tiles */
1930 while (1)
1931 {
1932 ret = sqlite3_step (stmt_tiles);
1933 if (ret == SQLITE_DONE)
1934 break;
1935 if (ret == SQLITE_ROW)
1936 {
1937 const unsigned char *blob_odd = NULL;
1938 int blob_odd_sz = 0;
1939 const unsigned char *blob_even = NULL;
1940 int blob_even_sz = 0;
1941 sqlite3_int64 tile_id = sqlite3_column_int64 (stmt_tiles, 0);
1942 double tile_minx = sqlite3_column_double (stmt_tiles, 1);
1943 double tile_maxy = sqlite3_column_double (stmt_tiles, 2);
1944
1945 /* retrieving tile raw data from BLOBs */
1946 sqlite3_reset (stmt_data);
1947 sqlite3_clear_bindings (stmt_data);
1948 sqlite3_bind_int64 (stmt_data, 1, tile_id);
1949 ret = sqlite3_step (stmt_data);
1950 if (ret == SQLITE_DONE)
1951 break;
1952 if (ret == SQLITE_ROW)
1953 {
1954 if (sqlite3_column_type (stmt_data, 0) == SQLITE_BLOB)
1955 {
1956 blob_odd = sqlite3_column_blob (stmt_data, 0);
1957 blob_odd_sz = sqlite3_column_bytes (stmt_data, 0);
1958 }
1959 if (scale == RL2_SCALE_1)
1960 {
1961 if (sqlite3_column_type (stmt_data, 1) ==
1962 SQLITE_BLOB)
1963 {
1964 blob_even =
1965 sqlite3_column_blob (stmt_data, 1);
1966 blob_even_sz =
1967 sqlite3_column_bytes (stmt_data, 1);
1968 }
1969 }
1970 }
1971 else
1972 {
1973 fprintf (stderr,
1974 "SELECT tiles data; sqlite3_step() error: %s\n",
1975 sqlite3_errmsg (handle));
1976 goto error;
1977 }
1978 plt = rl2_clone_palette (palette);
1979 raster =
1980 rl2_raster_decode (scale, blob_odd, blob_odd_sz, blob_even,
1981 blob_even_sz, plt);
1982 plt = NULL;
1983 if (raster == NULL)
1984 {
1985 fprintf (stderr, ERR_FRMT64, tile_id);
1986 goto error;
1987 }
1988 if (!copy_raw_pixels
1989 (raster, outbuf, width, height, sample_type,
1990 num_bands, x_res, y_res, minx, maxy, tile_minx, tile_maxy,
1991 no_data, style, stats))
1992 goto error;
1993 rl2_destroy_raster (raster);
1994 raster = NULL;
1995 }
1996 else
1997 {
1998 fprintf (stderr,
1999 "SELECT tiles; sqlite3_step() error: %s\n",
2000 sqlite3_errmsg (handle));
2001 goto error;
2002 }
2003 }
2004
2005 return 1;
2006
2007 error:
2008 if (raster != NULL)
2009 rl2_destroy_raster (raster);
2010 if (plt != NULL)
2011 rl2_destroy_palette (plt);
2012 return 0;
2013 }
2014
2015 static int
is_nodata_u16(rl2PrivPixelPtr no_data,const unsigned short * p_in)2016 is_nodata_u16 (rl2PrivPixelPtr no_data, const unsigned short *p_in)
2017 {
2018 /* testing for NO-DATA */
2019 if (no_data != NULL)
2020 {
2021 unsigned char band;
2022 int match = 0;
2023 rl2PrivSamplePtr sample;
2024 for (band = 0; band < no_data->nBands; band++)
2025 {
2026 sample = no_data->Samples + band;
2027 if (*(p_in + band) == sample->uint16)
2028 match++;
2029 }
2030 if (match == no_data->nBands)
2031 return 1;
2032 }
2033 return 0;
2034 }
2035
2036 static int
copy_triple_band_raw_pixels_u16(rl2RasterPtr raster,unsigned short * outbuf,unsigned int width,unsigned int height,unsigned char red_band,unsigned char green_band,unsigned char blue_band,double x_res,double y_res,double minx,double maxy,double tile_minx,double tile_maxy,rl2PixelPtr no_data)2037 copy_triple_band_raw_pixels_u16 (rl2RasterPtr raster, unsigned short *outbuf,
2038 unsigned int width, unsigned int height,
2039 unsigned char red_band,
2040 unsigned char green_band,
2041 unsigned char blue_band, double x_res,
2042 double y_res, double minx, double maxy,
2043 double tile_minx, double tile_maxy,
2044 rl2PixelPtr no_data)
2045 {
2046 /* copying raw pixels into the output buffer - UINT16 */
2047 unsigned int tile_width;
2048 unsigned int tile_height;
2049 unsigned int x;
2050 unsigned int y;
2051 int out_x;
2052 int out_y;
2053 double geo_x;
2054 double geo_y;
2055 const unsigned short *p_in;
2056 const unsigned char *p_msk;
2057 unsigned short *p_out;
2058 int transparent;
2059 unsigned char sample_type;
2060 unsigned char pixel_type;
2061 unsigned char nbands;
2062 unsigned char num_bands;
2063 int ignore_no_data = 1;
2064 double y_res2 = y_res / 2.0;
2065 double x_res2 = x_res / 2.0;
2066 rl2PrivPixelPtr no_data_in;
2067 rl2PrivRasterPtr rst = (rl2PrivRasterPtr) raster;
2068
2069 if (rl2_get_raster_size (raster, &tile_width, &tile_height) != RL2_OK)
2070 return 0;
2071 if (rl2_get_raster_type (raster, &sample_type, &pixel_type, &num_bands) !=
2072 RL2_OK)
2073 return 0;
2074
2075 if (no_data != NULL)
2076 {
2077 ignore_no_data = 0;
2078 if (rl2_get_pixel_type
2079 (no_data, &sample_type, &pixel_type, &nbands) != RL2_OK)
2080 ignore_no_data = 1;
2081 if (pixel_type != RL2_PIXEL_RGB)
2082 ignore_no_data = 1;
2083 if (nbands != 3)
2084 ignore_no_data = 1;
2085 if (sample_type != RL2_SAMPLE_UINT16)
2086 ignore_no_data = 1;
2087 }
2088
2089 p_in = (const unsigned short *) (rst->rasterBuffer);
2090 p_msk = (unsigned char *) (rst->maskBuffer);
2091 no_data_in = rst->noData;
2092
2093 geo_y = tile_maxy + y_res2;
2094 for (y = 0; y < tile_height; y++)
2095 {
2096 geo_y -= y_res;
2097 out_y = (maxy - geo_y) / y_res;
2098 if (out_y < 0 || (unsigned int) out_y >= height)
2099 {
2100 p_in += tile_width * num_bands;
2101 if (p_msk != NULL)
2102 p_msk += tile_width;
2103 continue;
2104 }
2105 geo_x = tile_minx - x_res2;
2106 for (x = 0; x < tile_width; x++)
2107 {
2108 geo_x += x_res;
2109 out_x = (geo_x - minx) / x_res;
2110 if (out_x < 0 || (unsigned int) out_x >= width)
2111 {
2112 p_in += num_bands;
2113 if (p_msk != NULL)
2114 p_msk++;
2115 continue;
2116 }
2117 p_out = outbuf + (out_y * width * 3) + (out_x * 3);
2118 transparent = 0;
2119 if (p_msk != NULL)
2120 {
2121 if (*p_msk++ == 0)
2122 transparent = 1;
2123 }
2124 if (!transparent)
2125 transparent = is_nodata_u16 (no_data_in, p_in);
2126 if (transparent || ignore_no_data)
2127 {
2128 /* already transparent or missing NO-DATA value */
2129 if (transparent)
2130 {
2131 /* skipping a transparent pixel */
2132 p_out += 3;
2133 p_in += num_bands;
2134 }
2135 else
2136 {
2137 unsigned short r = *(p_in + red_band);
2138 unsigned short g = *(p_in + green_band);
2139 unsigned short b = *(p_in + blue_band);
2140 p_in += num_bands;
2141 *p_out++ = r;
2142 *p_out++ = g;
2143 *p_out++ = b;
2144 }
2145 }
2146 else
2147 {
2148 /* testing for NO-DATA values */
2149 int match = 0;
2150 unsigned short sample;
2151 unsigned short r = *(p_in + red_band);
2152 unsigned short g = *(p_in + green_band);
2153 unsigned short b = *(p_in + blue_band);
2154 p_in += num_bands;
2155 rl2_get_pixel_sample_uint16 (no_data, 0, &sample);
2156 if (sample == r)
2157 match++;
2158 rl2_get_pixel_sample_uint16 (no_data, 1, &sample);
2159 if (sample == g)
2160 match++;
2161 rl2_get_pixel_sample_uint16 (no_data, 2, &sample);
2162 if (sample == b)
2163 match++;
2164 if (match != 3)
2165 {
2166 /* opaque pixel */
2167 *p_out++ = r;
2168 *p_out++ = g;
2169 *p_out++ = b;
2170 }
2171 else
2172 {
2173 /* NO-DATA pixel */
2174 p_out += 3;
2175 }
2176 }
2177 }
2178 }
2179
2180 return 1;
2181 }
2182
2183 static int
is_nodata_u8(rl2PrivPixelPtr no_data,const unsigned char * p_in)2184 is_nodata_u8 (rl2PrivPixelPtr no_data, const unsigned char *p_in)
2185 {
2186 /* testing for NO-DATA */
2187 if (no_data != NULL)
2188 {
2189 unsigned char band;
2190 int match = 0;
2191 rl2PrivSamplePtr sample;
2192 for (band = 0; band < no_data->nBands; band++)
2193 {
2194 sample = no_data->Samples + band;
2195 if (*(p_in + band) == sample->uint8)
2196 match++;
2197 }
2198 if (match == no_data->nBands)
2199 return 1;
2200 }
2201 return 0;
2202 }
2203
2204 static int
copy_triple_band_raw_pixels(rl2RasterPtr raster,unsigned char * outbuf,unsigned int width,unsigned int height,unsigned char red_band,unsigned char green_band,unsigned char blue_band,double x_res,double y_res,double minx,double maxy,double tile_minx,double tile_maxy,rl2PixelPtr no_data)2205 copy_triple_band_raw_pixels (rl2RasterPtr raster, unsigned char *outbuf,
2206 unsigned int width,
2207 unsigned int height, unsigned char red_band,
2208 unsigned char green_band,
2209 unsigned char blue_band, double x_res,
2210 double y_res, double minx, double maxy,
2211 double tile_minx, double tile_maxy,
2212 rl2PixelPtr no_data)
2213 {
2214 /* copying raw pixels into the output buffer */
2215 unsigned int tile_width;
2216 unsigned int tile_height;
2217 unsigned int x;
2218 unsigned int y;
2219 int out_x;
2220 int out_y;
2221 double geo_x;
2222 double geo_y;
2223 const unsigned char *p_in;
2224 const unsigned char *p_msk;
2225 unsigned char *p_out;
2226 int transparent;
2227 unsigned char sample_type;
2228 unsigned char pixel_type;
2229 unsigned char nbands;
2230 unsigned char num_bands;
2231 int ignore_no_data = 1;
2232 double y_res2 = y_res / 2.0;
2233 double x_res2 = x_res / 2.0;
2234 rl2PrivPixelPtr no_data_in;
2235 rl2PrivRasterPtr rst = (rl2PrivRasterPtr) raster;
2236
2237 if (rst->sampleType == RL2_SAMPLE_UINT16)
2238 return copy_triple_band_raw_pixels_u16 (raster,
2239 (unsigned short *) outbuf,
2240 width, height, red_band,
2241 green_band, blue_band, x_res,
2242 y_res, minx, maxy, tile_minx,
2243 tile_maxy, no_data);
2244
2245 if (rl2_get_raster_size (raster, &tile_width, &tile_height) != RL2_OK)
2246 return 0;
2247 if (rl2_get_raster_type (raster, &sample_type, &pixel_type, &num_bands) !=
2248 RL2_OK)
2249 return 0;
2250
2251 if (no_data != NULL)
2252 {
2253 ignore_no_data = 0;
2254 if (rl2_get_pixel_type
2255 (no_data, &sample_type, &pixel_type, &nbands) != RL2_OK)
2256 ignore_no_data = 1;
2257 if (pixel_type != RL2_PIXEL_RGB)
2258 ignore_no_data = 1;
2259 if (nbands != 3)
2260 ignore_no_data = 1;
2261 if (sample_type != RL2_SAMPLE_UINT8)
2262 ignore_no_data = 1;
2263 }
2264
2265 p_in = rst->rasterBuffer;
2266 p_msk = rst->maskBuffer;
2267 no_data_in = rst->noData;
2268
2269 geo_y = tile_maxy + y_res2;
2270 for (y = 0; y < tile_height; y++)
2271 {
2272 geo_y -= y_res;
2273 out_y = (maxy - geo_y) / y_res;
2274 if (out_y < 0 || (unsigned int) out_y >= height)
2275 {
2276 p_in += tile_width * num_bands;
2277 if (p_msk != NULL)
2278 p_msk += tile_width;
2279 continue;
2280 }
2281 geo_x = tile_minx - x_res2;
2282 for (x = 0; x < tile_width; x++)
2283 {
2284 geo_x += x_res;
2285 out_x = (geo_x - minx) / x_res;
2286 if (out_x < 0 || (unsigned int) out_x >= width)
2287 {
2288 p_in += num_bands;
2289 if (p_msk != NULL)
2290 p_msk++;
2291 continue;
2292 }
2293 p_out = outbuf + (out_y * width * 3) + (out_x * 3);
2294 transparent = 0;
2295 if (p_msk != NULL)
2296 {
2297 if (*p_msk++ == 0)
2298 transparent = 1;
2299 }
2300 if (!transparent)
2301 transparent = is_nodata_u8 (no_data_in, p_in);
2302 if (transparent || ignore_no_data)
2303 {
2304 /* already transparent or missing NO-DATA value */
2305 if (transparent)
2306 {
2307 /* skipping a transparent pixel */
2308 p_out += 3;
2309 p_in += num_bands;
2310 }
2311 else
2312 {
2313 unsigned char r = *(p_in + red_band);
2314 unsigned char g = *(p_in + green_band);
2315 unsigned char b = *(p_in + blue_band);
2316 p_in += num_bands;
2317 *p_out++ = r;
2318 *p_out++ = g;
2319 *p_out++ = b;
2320 }
2321 }
2322 else
2323 {
2324 /* testing for NO-DATA values */
2325 int match = 0;
2326 unsigned char sample;
2327 unsigned char r = *(p_in + red_band);
2328 unsigned char g = *(p_in + green_band);
2329 unsigned char b = *(p_in + blue_band);
2330 p_in += num_bands;
2331 rl2_get_pixel_sample_uint8 (no_data, 0, &sample);
2332 if (sample == r)
2333 match++;
2334 rl2_get_pixel_sample_uint8 (no_data, 1, &sample);
2335 if (sample == g)
2336 match++;
2337 rl2_get_pixel_sample_uint8 (no_data, 2, &sample);
2338 if (sample == b)
2339 match++;
2340 if (match != 3)
2341 {
2342 /* opaque pixel */
2343 *p_out++ = r;
2344 *p_out++ = g;
2345 *p_out++ = b;
2346 }
2347 else
2348 {
2349 /* NO-DATA pixel */
2350 p_out += 3;
2351 }
2352 }
2353 }
2354 }
2355
2356 return 1;
2357 }
2358
2359 static int
load_triple_band_dbms_tiles(sqlite3 * handle,sqlite3_stmt * stmt_tiles,sqlite3_stmt * stmt_data,unsigned char * outbuf,unsigned int width,unsigned int height,unsigned char red_band,unsigned char green_band,unsigned char blue_band,double x_res,double y_res,double minx,double miny,double maxx,double maxy,int level,int scale,rl2PixelPtr no_data)2360 load_triple_band_dbms_tiles (sqlite3 * handle, sqlite3_stmt * stmt_tiles,
2361 sqlite3_stmt * stmt_data, unsigned char *outbuf,
2362 unsigned int width, unsigned int height,
2363 unsigned char red_band, unsigned char green_band,
2364 unsigned char blue_band, double x_res,
2365 double y_res, double minx, double miny,
2366 double maxx, double maxy, int level, int scale,
2367 rl2PixelPtr no_data)
2368 {
2369 /* retrieving a full image from DBMS tiles */
2370 rl2RasterPtr raster = NULL;
2371 int ret;
2372
2373 /* binding the query args */
2374 sqlite3_reset (stmt_tiles);
2375 sqlite3_clear_bindings (stmt_tiles);
2376 sqlite3_bind_int (stmt_tiles, 1, level);
2377 sqlite3_bind_double (stmt_tiles, 2, minx);
2378 sqlite3_bind_double (stmt_tiles, 3, miny);
2379 sqlite3_bind_double (stmt_tiles, 4, maxx);
2380 sqlite3_bind_double (stmt_tiles, 5, maxy);
2381
2382 /* querying the tiles */
2383 while (1)
2384 {
2385 ret = sqlite3_step (stmt_tiles);
2386 if (ret == SQLITE_DONE)
2387 break;
2388 if (ret == SQLITE_ROW)
2389 {
2390 const unsigned char *blob_odd = NULL;
2391 int blob_odd_sz = 0;
2392 const unsigned char *blob_even = NULL;
2393 int blob_even_sz = 0;
2394 sqlite3_int64 tile_id = sqlite3_column_int64 (stmt_tiles, 0);
2395 double tile_minx = sqlite3_column_double (stmt_tiles, 1);
2396 double tile_maxy = sqlite3_column_double (stmt_tiles, 2);
2397
2398 /* retrieving tile raw data from BLOBs */
2399 sqlite3_reset (stmt_data);
2400 sqlite3_clear_bindings (stmt_data);
2401 sqlite3_bind_int64 (stmt_data, 1, tile_id);
2402 ret = sqlite3_step (stmt_data);
2403 if (ret == SQLITE_DONE)
2404 break;
2405 if (ret == SQLITE_ROW)
2406 {
2407 if (sqlite3_column_type (stmt_data, 0) == SQLITE_BLOB)
2408 {
2409 blob_odd = sqlite3_column_blob (stmt_data, 0);
2410 blob_odd_sz = sqlite3_column_bytes (stmt_data, 0);
2411 }
2412 if (sqlite3_column_type (stmt_data, 1) == SQLITE_BLOB)
2413 {
2414 blob_even = sqlite3_column_blob (stmt_data, 1);
2415 blob_even_sz = sqlite3_column_bytes (stmt_data, 1);
2416 }
2417 }
2418 else
2419 {
2420 fprintf (stderr,
2421 "SELECT tiles data; sqlite3_step() error: %s\n",
2422 sqlite3_errmsg (handle));
2423 goto error;
2424 }
2425 raster =
2426 rl2_raster_decode (scale, blob_odd, blob_odd_sz, blob_even,
2427 blob_even_sz, NULL);
2428 if (raster == NULL)
2429 {
2430 fprintf (stderr, ERR_FRMT64, tile_id);
2431 goto error;
2432 }
2433 if (!copy_triple_band_raw_pixels
2434 (raster, outbuf, width, height, red_band, green_band,
2435 blue_band, x_res, y_res, minx, maxy, tile_minx, tile_maxy,
2436 no_data))
2437 goto error;
2438 rl2_destroy_raster (raster);
2439 raster = NULL;
2440 }
2441 else
2442 {
2443 fprintf (stderr,
2444 "SELECT tiles; sqlite3_step() error: %s\n",
2445 sqlite3_errmsg (handle));
2446 goto error;
2447 }
2448 }
2449
2450 return 1;
2451
2452 error:
2453 if (raster != NULL)
2454 rl2_destroy_raster (raster);
2455 return 0;
2456 }
2457
2458 static int
copy_mono_band_raw_pixels_u16(rl2RasterPtr raster,unsigned char * outbuf,unsigned int width,unsigned int height,unsigned char mono_band,double x_res,double y_res,double minx,double maxy,double tile_minx,double tile_maxy,rl2PixelPtr no_data)2459 copy_mono_band_raw_pixels_u16 (rl2RasterPtr raster, unsigned char *outbuf,
2460 unsigned int width, unsigned int height,
2461 unsigned char mono_band, double x_res,
2462 double y_res, double minx, double maxy,
2463 double tile_minx, double tile_maxy,
2464 rl2PixelPtr no_data)
2465 {
2466 /* copying raw pixels into the output buffer - UINT16 */
2467 unsigned int tile_width;
2468 unsigned int tile_height;
2469 unsigned int x;
2470 unsigned int y;
2471 int out_x;
2472 int out_y;
2473 double geo_x;
2474 double geo_y;
2475 const unsigned short *p_in;
2476 const unsigned char *p_msk;
2477 unsigned short *p_out;
2478 int transparent;
2479 unsigned char sample_type;
2480 unsigned char pixel_type;
2481 unsigned char nbands;
2482 unsigned char num_bands;
2483 int ignore_no_data = 1;
2484 double y_res2 = y_res / 2.0;
2485 double x_res2 = x_res / 2.0;
2486 rl2PrivRasterPtr rst = (rl2PrivRasterPtr) raster;
2487
2488 if (rl2_get_raster_size (raster, &tile_width, &tile_height) != RL2_OK)
2489 return 0;
2490 if (rl2_get_raster_type (raster, &sample_type, &pixel_type, &num_bands) !=
2491 RL2_OK)
2492 return 0;
2493
2494 if (no_data != NULL)
2495 {
2496 ignore_no_data = 0;
2497 if (rl2_get_pixel_type
2498 (no_data, &sample_type, &pixel_type, &nbands) != RL2_OK)
2499 ignore_no_data = 1;
2500 if (pixel_type != RL2_PIXEL_DATAGRID)
2501 ignore_no_data = 1;
2502 if (nbands != 1)
2503 ignore_no_data = 1;
2504 if (sample_type != RL2_SAMPLE_UINT16)
2505 ignore_no_data = 1;
2506 }
2507
2508 p_in = (const unsigned short *) (rst->rasterBuffer);
2509 p_msk = (unsigned char *) (rst->maskBuffer);
2510
2511 geo_y = tile_maxy + y_res2;
2512 for (y = 0; y < (unsigned int) tile_height; y++)
2513 {
2514 geo_y -= y_res;
2515 out_y = (maxy - geo_y) / y_res;
2516 if (out_y < 0 || (unsigned int) out_y >= height)
2517 {
2518 p_in += tile_width * num_bands;
2519 if (p_msk != NULL)
2520 p_msk += tile_width;
2521 continue;
2522 }
2523 geo_x = tile_minx - x_res2;
2524 for (x = 0; x < (unsigned int) tile_width; x++)
2525 {
2526 geo_x += x_res;
2527 out_x = (geo_x - minx) / x_res;
2528 if (out_x < 0 || (unsigned int) out_x >= width)
2529 {
2530 p_in += num_bands;
2531 if (p_msk != NULL)
2532 p_msk++;
2533 continue;
2534 }
2535 p_out = (unsigned short *) outbuf;
2536 p_out += (out_y * width) + out_x;
2537 transparent = 0;
2538 if (p_msk != NULL)
2539 {
2540 if (*p_msk++ == 0)
2541 transparent = 1;
2542 }
2543 if (transparent || ignore_no_data)
2544 {
2545 /* already transparent or missing NO-DATA value */
2546 if (transparent)
2547 {
2548 /* skipping a transparent pixel */
2549 p_out++;
2550 p_in += num_bands;
2551 }
2552 else
2553 {
2554 *p_out++ = *(p_in + mono_band);
2555 p_in += num_bands;
2556 }
2557 }
2558 else
2559 {
2560 /* testing for NO-DATA values */
2561 int match = 0;
2562 unsigned short sample;
2563 unsigned short gray = *(p_in + mono_band);
2564 p_in += num_bands;
2565 rl2_get_pixel_sample_uint16 (no_data, 0, &sample);
2566 if (sample == gray)
2567 match++;
2568 if (match != 1)
2569 {
2570 /* opaque pixel */
2571 *p_out++ = gray;
2572 }
2573 else
2574 {
2575 /* NO-DATA pixel */
2576 p_out++;
2577 }
2578 }
2579 }
2580 }
2581
2582 return 1;
2583 }
2584
2585 static int
copy_mono_band_raw_pixels(rl2RasterPtr raster,unsigned char * outbuf,unsigned int width,unsigned int height,unsigned char mono_band,double x_res,double y_res,double minx,double maxy,double tile_minx,double tile_maxy,rl2PixelPtr no_data)2586 copy_mono_band_raw_pixels (rl2RasterPtr raster, unsigned char *outbuf,
2587 unsigned int width, unsigned int height,
2588 unsigned char mono_band, double x_res, double y_res,
2589 double minx, double maxy, double tile_minx,
2590 double tile_maxy, rl2PixelPtr no_data)
2591 {
2592 /* copying raw pixels into the output buffer */
2593 unsigned int tile_width;
2594 unsigned int tile_height;
2595 unsigned int x;
2596 unsigned int y;
2597 int out_x;
2598 int out_y;
2599 double geo_x;
2600 double geo_y;
2601 const unsigned char *p_in;
2602 const unsigned char *p_msk;
2603 unsigned char *p_out;
2604 int transparent;
2605 unsigned char sample_type;
2606 unsigned char pixel_type;
2607 unsigned char nbands;
2608 unsigned char num_bands;
2609 int ignore_no_data = 1;
2610 double y_res2 = y_res / 2.0;
2611 double x_res2 = x_res / 2.0;
2612 rl2PrivRasterPtr rst = (rl2PrivRasterPtr) raster;
2613
2614 if (rst->sampleType == RL2_SAMPLE_UINT16)
2615 return copy_mono_band_raw_pixels_u16 (raster, outbuf, width, height,
2616 mono_band, x_res, y_res, minx,
2617 maxy, tile_minx, tile_maxy,
2618 no_data);
2619
2620 if (rl2_get_raster_size (raster, &tile_width, &tile_height) != RL2_OK)
2621 return 0;
2622 if (rl2_get_raster_type (raster, &sample_type, &pixel_type, &num_bands) !=
2623 RL2_OK)
2624 return 0;
2625
2626 if (no_data != NULL)
2627 {
2628 ignore_no_data = 0;
2629 if (rl2_get_pixel_type
2630 (no_data, &sample_type, &pixel_type, &nbands) != RL2_OK)
2631 ignore_no_data = 1;
2632 if (pixel_type != RL2_PIXEL_GRAYSCALE)
2633 ignore_no_data = 1;
2634 if (nbands != 1)
2635 ignore_no_data = 1;
2636 if (sample_type != RL2_SAMPLE_UINT8)
2637 ignore_no_data = 1;
2638 }
2639
2640 p_in = rst->rasterBuffer;
2641 p_msk = rst->maskBuffer;
2642
2643 geo_y = tile_maxy + y_res2;
2644 for (y = 0; y < tile_height; y++)
2645 {
2646 geo_y -= y_res;
2647 out_y = (maxy - geo_y) / y_res;
2648 if (out_y < 0 || (unsigned int) out_y >= height)
2649 {
2650 p_in += tile_width * num_bands;
2651 if (p_msk != NULL)
2652 p_msk += tile_width;
2653 continue;
2654 }
2655 geo_x = tile_minx - x_res2;
2656 for (x = 0; x < (unsigned int) tile_width; x++)
2657 {
2658 geo_x += x_res;
2659 out_x = (geo_x - minx) / x_res;
2660 if (out_x < 0 || (unsigned int) out_x >= width)
2661 {
2662 p_in += num_bands;
2663 if (p_msk != NULL)
2664 p_msk++;
2665 continue;
2666 }
2667 p_out = outbuf + (out_y * width) + out_x;
2668 transparent = 0;
2669 if (p_msk != NULL)
2670 {
2671 if (*p_msk++ == 0)
2672 transparent = 1;
2673 }
2674 if (transparent || ignore_no_data)
2675 {
2676 /* already transparent or missing NO-DATA value */
2677 if (transparent)
2678 {
2679 /* skipping a transparent pixel */
2680 p_out++;
2681 p_in += num_bands;
2682 }
2683 else
2684 {
2685 unsigned char gray = *(p_in + mono_band);
2686 p_in += num_bands;
2687 *p_out++ = gray;
2688 }
2689 }
2690 else
2691 {
2692 /* testing for NO-DATA values */
2693 int match = 0;
2694 unsigned char sample;
2695 unsigned char gray = *(p_in + mono_band);
2696 p_in += num_bands;
2697 rl2_get_pixel_sample_uint8 (no_data, 0, &sample);
2698 if (sample == gray)
2699 match++;
2700 if (match != 1)
2701 {
2702 /* opaque pixel */
2703 *p_out++ = gray;
2704 }
2705 else
2706 {
2707 /* NO-DATA pixel */
2708 p_out++;
2709 }
2710 }
2711 }
2712 }
2713
2714 return 1;
2715 }
2716
2717 static int
load_mono_band_dbms_tiles(sqlite3 * handle,sqlite3_stmt * stmt_tiles,sqlite3_stmt * stmt_data,unsigned char * outbuf,unsigned int width,unsigned int height,unsigned char mono_band,double x_res,double y_res,double minx,double miny,double maxx,double maxy,int level,int scale,rl2PixelPtr no_data)2718 load_mono_band_dbms_tiles (sqlite3 * handle, sqlite3_stmt * stmt_tiles,
2719 sqlite3_stmt * stmt_data, unsigned char *outbuf,
2720 unsigned int width, unsigned int height,
2721 unsigned char mono_band, double x_res, double y_res,
2722 double minx, double miny, double maxx, double maxy,
2723 int level, int scale, rl2PixelPtr no_data)
2724 {
2725 /* retrieving a full image from DBMS tiles */
2726 rl2RasterPtr raster = NULL;
2727 int ret;
2728
2729 /* binding the query args */
2730 sqlite3_reset (stmt_tiles);
2731 sqlite3_clear_bindings (stmt_tiles);
2732 sqlite3_bind_int (stmt_tiles, 1, level);
2733 sqlite3_bind_double (stmt_tiles, 2, minx);
2734 sqlite3_bind_double (stmt_tiles, 3, miny);
2735 sqlite3_bind_double (stmt_tiles, 4, maxx);
2736 sqlite3_bind_double (stmt_tiles, 5, maxy);
2737
2738 /* querying the tiles */
2739 while (1)
2740 {
2741 ret = sqlite3_step (stmt_tiles);
2742 if (ret == SQLITE_DONE)
2743 break;
2744 if (ret == SQLITE_ROW)
2745 {
2746 const unsigned char *blob_odd = NULL;
2747 int blob_odd_sz = 0;
2748 const unsigned char *blob_even = NULL;
2749 int blob_even_sz = 0;
2750 sqlite3_int64 tile_id = sqlite3_column_int64 (stmt_tiles, 0);
2751 double tile_minx = sqlite3_column_double (stmt_tiles, 1);
2752 double tile_maxy = sqlite3_column_double (stmt_tiles, 2);
2753
2754 /* retrieving tile raw data from BLOBs */
2755 sqlite3_reset (stmt_data);
2756 sqlite3_clear_bindings (stmt_data);
2757 sqlite3_bind_int64 (stmt_data, 1, tile_id);
2758 ret = sqlite3_step (stmt_data);
2759 if (ret == SQLITE_DONE)
2760 break;
2761 if (ret == SQLITE_ROW)
2762 {
2763 if (sqlite3_column_type (stmt_data, 0) == SQLITE_BLOB)
2764 {
2765 blob_odd = sqlite3_column_blob (stmt_data, 0);
2766 blob_odd_sz = sqlite3_column_bytes (stmt_data, 0);
2767 }
2768 if (sqlite3_column_type (stmt_data, 1) == SQLITE_BLOB)
2769 {
2770 blob_even = sqlite3_column_blob (stmt_data, 1);
2771 blob_even_sz = sqlite3_column_bytes (stmt_data, 1);
2772 }
2773 }
2774 else
2775 {
2776 fprintf (stderr,
2777 "SELECT tiles data; sqlite3_step() error: %s\n",
2778 sqlite3_errmsg (handle));
2779 goto error;
2780 }
2781 raster =
2782 rl2_raster_decode (scale, blob_odd, blob_odd_sz, blob_even,
2783 blob_even_sz, NULL);
2784 if (raster == NULL)
2785 {
2786 fprintf (stderr, ERR_FRMT64, tile_id);
2787 goto error;
2788 }
2789 if (!copy_mono_band_raw_pixels
2790 (raster, outbuf, width, height, mono_band, x_res, y_res,
2791 minx, maxy, tile_minx, tile_maxy, no_data))
2792 goto error;
2793 rl2_destroy_raster (raster);
2794 raster = NULL;
2795 }
2796 else
2797 {
2798 fprintf (stderr,
2799 "SELECT tiles; sqlite3_step() error: %s\n",
2800 sqlite3_errmsg (handle));
2801 goto error;
2802 }
2803 }
2804
2805 return 1;
2806
2807 error:
2808 if (raster != NULL)
2809 rl2_destroy_raster (raster);
2810 return 0;
2811 }
2812
2813 RL2_PRIVATE int
load_dbms_tiles(sqlite3 * handle,sqlite3_stmt * stmt_tiles,sqlite3_stmt * stmt_data,unsigned char * outbuf,unsigned int width,unsigned int height,unsigned char sample_type,unsigned char num_bands,double x_res,double y_res,double minx,double miny,double maxx,double maxy,int level,int scale,rl2PalettePtr palette,rl2PixelPtr no_data,rl2RasterStylePtr style,rl2RasterStatisticsPtr stats)2814 load_dbms_tiles (sqlite3 * handle, sqlite3_stmt * stmt_tiles,
2815 sqlite3_stmt * stmt_data, unsigned char *outbuf,
2816 unsigned int width,
2817 unsigned int height, unsigned char sample_type,
2818 unsigned char num_bands, double x_res, double y_res,
2819 double minx, double miny, double maxx, double maxy, int level,
2820 int scale, rl2PalettePtr palette, rl2PixelPtr no_data,
2821 rl2RasterStylePtr style, rl2RasterStatisticsPtr stats)
2822 {
2823 /* binding the query args */
2824 sqlite3_reset (stmt_tiles);
2825 sqlite3_clear_bindings (stmt_tiles);
2826 sqlite3_bind_int (stmt_tiles, 1, level);
2827 sqlite3_bind_double (stmt_tiles, 2, minx);
2828 sqlite3_bind_double (stmt_tiles, 3, miny);
2829 sqlite3_bind_double (stmt_tiles, 4, maxx);
2830 sqlite3_bind_double (stmt_tiles, 5, maxy);
2831
2832 if (!load_dbms_tiles_common
2833 (handle, stmt_tiles, stmt_data, outbuf, width, height,
2834 sample_type, num_bands, x_res, y_res, minx, maxy, scale,
2835 palette, no_data, style, stats))
2836 return 0;
2837 return 1;
2838 }
2839
2840 RL2_PRIVATE int
load_dbms_tiles_section(sqlite3 * handle,sqlite3_int64 section_id,sqlite3_stmt * stmt_tiles,sqlite3_stmt * stmt_data,unsigned char * outbuf,unsigned int width,unsigned int height,unsigned char sample_type,unsigned char num_bands,double x_res,double y_res,double minx,double maxy,int scale,rl2PalettePtr palette,rl2PixelPtr no_data)2841 load_dbms_tiles_section (sqlite3 * handle, sqlite3_int64 section_id,
2842 sqlite3_stmt * stmt_tiles, sqlite3_stmt * stmt_data,
2843 unsigned char *outbuf,
2844 unsigned int width, unsigned int height,
2845 unsigned char sample_type, unsigned char num_bands,
2846 double x_res, double y_res, double minx, double maxy,
2847 int scale, rl2PalettePtr palette, rl2PixelPtr no_data)
2848 {
2849 /* binding the query args */
2850 sqlite3_reset (stmt_tiles);
2851 sqlite3_clear_bindings (stmt_tiles);
2852 sqlite3_bind_int (stmt_tiles, 1, section_id);
2853
2854 if (!load_dbms_tiles_common
2855 (handle, stmt_tiles, stmt_data, outbuf, width, height,
2856 sample_type, num_bands, x_res, y_res, minx, maxy, scale,
2857 palette, no_data, NULL, NULL))
2858 return 0;
2859 return 1;
2860 }
2861
2862 RL2_DECLARE int
rl2_find_matching_resolution(sqlite3 * handle,rl2CoveragePtr cvg,double * x_res,double * y_res,unsigned char * level,unsigned char * scale)2863 rl2_find_matching_resolution (sqlite3 * handle, rl2CoveragePtr cvg,
2864 double *x_res, double *y_res,
2865 unsigned char *level, unsigned char *scale)
2866 {
2867 /* attempting to identify the corresponding resolution level */
2868 rl2PrivCoveragePtr coverage = (rl2PrivCoveragePtr) cvg;
2869 int ret;
2870 int found = 0;
2871 int x_level;
2872 int x_scale;
2873 double z_x_res;
2874 double z_y_res;
2875 char *xcoverage;
2876 char *xxcoverage;
2877 char *sql;
2878 sqlite3_stmt *stmt = NULL;
2879
2880 if (coverage == NULL)
2881 return RL2_ERROR;
2882 if (coverage->coverageName == NULL)
2883 return RL2_ERROR;
2884
2885 xcoverage = sqlite3_mprintf ("%s_levels", coverage->coverageName);
2886 xxcoverage = gaiaDoubleQuotedSql (xcoverage);
2887 sqlite3_free (xcoverage);
2888 sql =
2889 sqlite3_mprintf
2890 ("SELECT pyramid_level, x_resolution_1_1, y_resolution_1_1, "
2891 "x_resolution_1_2, y_resolution_1_2, x_resolution_1_4, y_resolution_1_4, "
2892 "x_resolution_1_8, y_resolution_1_8 FROM \"%s\"", xxcoverage);
2893 free (xxcoverage);
2894 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
2895 if (ret != SQLITE_OK)
2896 {
2897 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
2898 goto error;
2899 }
2900 sqlite3_free (sql);
2901
2902 while (1)
2903 {
2904 /* scrolling the result set rows */
2905 ret = sqlite3_step (stmt);
2906 if (ret == SQLITE_DONE)
2907 break; /* end of result set */
2908 if (ret == SQLITE_ROW)
2909 {
2910 double xx_res;
2911 double yy_res;
2912 double confidence;
2913 int ok;
2914 int lvl = sqlite3_column_int (stmt, 0);
2915 if (sqlite3_column_type (stmt, 1) == SQLITE_FLOAT
2916 && sqlite3_column_type (stmt, 2) == SQLITE_FLOAT)
2917 {
2918 ok = 1;
2919 xx_res = sqlite3_column_double (stmt, 1);
2920 yy_res = sqlite3_column_double (stmt, 2);
2921 confidence = xx_res / 100.0;
2922 if (*x_res < (xx_res - confidence)
2923 || *x_res > (xx_res + confidence))
2924 ok = 0;
2925 confidence = yy_res / 100.0;
2926 if (*y_res < (yy_res - confidence)
2927 || *y_res > (yy_res + confidence))
2928 ok = 0;
2929 if (ok)
2930 {
2931 found = 1;
2932 x_level = lvl;
2933 x_scale = RL2_SCALE_1;
2934 z_x_res = xx_res;
2935 z_y_res = yy_res;
2936 }
2937 }
2938 if (sqlite3_column_type (stmt, 3) == SQLITE_FLOAT
2939 && sqlite3_column_type (stmt, 4) == SQLITE_FLOAT)
2940 {
2941 ok = 1;
2942 xx_res = sqlite3_column_double (stmt, 3);
2943 yy_res = sqlite3_column_double (stmt, 4);
2944 confidence = xx_res / 100.0;
2945 if (*x_res < (xx_res - confidence)
2946 || *x_res > (xx_res + confidence))
2947 ok = 0;
2948 confidence = yy_res / 100.0;
2949 if (*y_res < (yy_res - confidence)
2950 || *y_res > (yy_res + confidence))
2951 ok = 0;
2952 if (ok)
2953 {
2954 found = 1;
2955 x_level = lvl;
2956 x_scale = RL2_SCALE_2;
2957 z_x_res = xx_res;
2958 z_y_res = yy_res;
2959 }
2960 }
2961 if (sqlite3_column_type (stmt, 5) == SQLITE_FLOAT
2962 && sqlite3_column_type (stmt, 6) == SQLITE_FLOAT)
2963 {
2964 ok = 1;
2965 xx_res = sqlite3_column_double (stmt, 5);
2966 yy_res = sqlite3_column_double (stmt, 6);
2967 confidence = xx_res / 100.0;
2968 if (*x_res < (xx_res - confidence)
2969 || *x_res > (xx_res + confidence))
2970 ok = 0;
2971 confidence = yy_res / 100.0;
2972 if (*y_res < (yy_res - confidence)
2973 || *y_res > (yy_res + confidence))
2974 ok = 0;
2975 if (ok)
2976 {
2977 found = 1;
2978 x_level = lvl;
2979 x_scale = RL2_SCALE_4;
2980 z_x_res = xx_res;
2981 z_y_res = yy_res;
2982 }
2983 }
2984 if (sqlite3_column_type (stmt, 7) == SQLITE_FLOAT
2985 && sqlite3_column_type (stmt, 8) == SQLITE_FLOAT)
2986 {
2987 ok = 1;
2988 xx_res = sqlite3_column_double (stmt, 7);
2989 yy_res = sqlite3_column_double (stmt, 8);
2990 confidence = xx_res / 100.0;
2991 if (*x_res < (xx_res - confidence)
2992 || *x_res > (xx_res + confidence))
2993 ok = 0;
2994 confidence = yy_res / 100.0;
2995 if (*y_res < (yy_res - confidence)
2996 || *y_res > (yy_res + confidence))
2997 ok = 0;
2998 if (ok)
2999 {
3000 found = 1;
3001 x_level = lvl;
3002 x_scale = RL2_SCALE_8;
3003 z_x_res = xx_res;
3004 z_y_res = yy_res;
3005 }
3006 }
3007 }
3008 else
3009 {
3010 fprintf (stderr, "SQL error: %s\n%s\n", sql,
3011 sqlite3_errmsg (handle));
3012 goto error;
3013 }
3014 }
3015 sqlite3_finalize (stmt);
3016 if (found)
3017 {
3018 *level = x_level;
3019 *scale = x_scale;
3020 *x_res = z_x_res;
3021 *y_res = z_y_res;
3022 return RL2_OK;
3023 }
3024 return RL2_ERROR;
3025
3026 error:
3027 if (stmt != NULL)
3028 sqlite3_finalize (stmt);
3029 return RL2_ERROR;
3030 }
3031
3032 static int
has_styled_rgb_colors(rl2RasterStylePtr style)3033 has_styled_rgb_colors (rl2RasterStylePtr style)
3034 {
3035 /* testing for a RasterSymbolizer requiring RGB colors */
3036 rl2PrivColorMapPointPtr color;
3037 rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
3038 if (stl == NULL)
3039 return 0;
3040 if (stl->shadedRelief && stl->brightnessOnly)
3041 return 0;
3042 if (stl->categorize != NULL)
3043 {
3044 if (stl->categorize->dfltRed == stl->categorize->dfltGreen
3045 && stl->categorize->dfltRed == stl->categorize->dfltBlue)
3046 ;
3047 else
3048 return 1;
3049 if (stl->categorize->baseRed == stl->categorize->baseGreen
3050 && stl->categorize->baseRed == stl->categorize->baseBlue)
3051 ;
3052 else
3053 return 1;
3054 color = stl->categorize->first;
3055 while (color != NULL)
3056 {
3057 if (color->red == color->green && color->red == color->blue)
3058 ;
3059 else
3060 return 1;
3061 color = color->next;
3062 }
3063 }
3064 if (stl->interpolate != NULL)
3065 {
3066 if (stl->interpolate->dfltRed == stl->interpolate->dfltGreen
3067 && stl->interpolate->dfltRed == stl->interpolate->dfltBlue)
3068 ;
3069 else
3070 return 1;
3071 color = stl->interpolate->first;
3072 while (color != NULL)
3073 {
3074 if (color->red == color->green && color->red == color->blue)
3075 ;
3076 else
3077 return 1;
3078 color = color->next;
3079 }
3080 }
3081 return 0;
3082 }
3083
3084 RL2_PRIVATE double
rl2_get_shaded_relief_scale_factor(sqlite3 * handle,const char * coverage)3085 rl2_get_shaded_relief_scale_factor (sqlite3 * handle, const char *coverage)
3086 {
3087 /* return the appropriate Scale Factor for Shaded Relief
3088 / when SRID is of the Long/Lat type
3089 / this is strictly required because in this case
3090 / X and Y are measured in degrees, but elevations
3091 / (Z) are measured in meters
3092 */
3093 double scale_factor = 1.0;
3094 int ret;
3095 char **results;
3096 int rows;
3097 int columns;
3098 int i;
3099 char *sql = sqlite3_mprintf ("SELECT s.srid FROM raster_coverages AS r "
3100 "JOIN spatial_ref_sys AS s ON (s.srid = r.srid AND "
3101 "s.proj4text LIKE '%%+proj=longlat%%') "
3102 "WHERE Lower(r.coverage_name) = Lower(%Q)",
3103 coverage);
3104 ret = sqlite3_get_table (handle, sql, &results, &rows, &columns, NULL);
3105 sqlite3_free (sql);
3106 if (ret != SQLITE_OK)
3107 return scale_factor;
3108 for (i = 1; i <= rows; i++)
3109 scale_factor = 11.1120;
3110 sqlite3_free_table (results);
3111 return scale_factor;
3112 }
3113
3114 static int
get_raw_raster_data_common(sqlite3 * handle,rl2CoveragePtr cvg,unsigned int width,unsigned int height,double minx,double miny,double maxx,double maxy,double x_res,double y_res,unsigned char ** buffer,int * buf_size,rl2PalettePtr * palette,unsigned char out_pixel,rl2PixelPtr bgcolor,rl2RasterStylePtr style,rl2RasterStatisticsPtr stats)3115 get_raw_raster_data_common (sqlite3 * handle, rl2CoveragePtr cvg,
3116 unsigned int width, unsigned int height,
3117 double minx, double miny, double maxx, double maxy,
3118 double x_res, double y_res, unsigned char **buffer,
3119 int *buf_size, rl2PalettePtr * palette,
3120 unsigned char out_pixel, rl2PixelPtr bgcolor,
3121 rl2RasterStylePtr style,
3122 rl2RasterStatisticsPtr stats)
3123 {
3124 /* attempting to return a buffer containing raw pixels from the DBMS Coverage */
3125 rl2PalettePtr plt = NULL;
3126 rl2PixelPtr no_data = NULL;
3127 rl2PixelPtr kill_no_data = NULL;
3128 const char *coverage;
3129 unsigned char level;
3130 unsigned char scale;
3131 double xx_res = x_res;
3132 double yy_res = y_res;
3133 unsigned char *bufpix = NULL;
3134 int bufpix_size;
3135 int pix_sz = 1;
3136 unsigned char sample_type;
3137 unsigned char pixel_type;
3138 unsigned char cvg_pixel_type;
3139 unsigned char num_bands;
3140 char *xtiles;
3141 char *xxtiles;
3142 char *xdata;
3143 char *xxdata;
3144 char *sql;
3145 sqlite3_stmt *stmt_tiles = NULL;
3146 sqlite3_stmt *stmt_data = NULL;
3147 int ret;
3148 int has_shaded_relief;
3149 int brightness_only;
3150 double relief_factor;
3151 float *shaded_relief = NULL;
3152 int shaded_relief_sz;
3153
3154 if (cvg == NULL || handle == NULL)
3155 goto error;
3156 coverage = rl2_get_coverage_name (cvg);
3157 if (coverage == NULL)
3158 goto error;
3159 if (rl2_find_matching_resolution
3160 (handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
3161 goto error;
3162 if (rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands) !=
3163 RL2_OK)
3164 goto error;
3165 cvg_pixel_type = pixel_type;
3166
3167 if (pixel_type == RL2_PIXEL_MONOCHROME && out_pixel == RL2_PIXEL_GRAYSCALE)
3168 {
3169 /* Pyramid tiles MONOCHROME */
3170 rl2PixelPtr nd = NULL;
3171 nd = rl2_get_coverage_no_data (cvg);
3172 if (nd != NULL)
3173 {
3174 /* creating a Grayscale NoData pixel */
3175 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) nd;
3176 rl2PrivSamplePtr sample = pxl->Samples + 0;
3177 no_data = rl2_create_pixel (RL2_SAMPLE_UINT8,
3178 RL2_PIXEL_GRAYSCALE, 1);
3179 kill_no_data = no_data;
3180 if (sample->uint8 == 0)
3181 rl2_set_pixel_sample_uint8 (no_data,
3182 RL2_GRAYSCALE_BAND, 255);
3183 else
3184 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND, 0);
3185 }
3186 sample_type = RL2_SAMPLE_UINT8;
3187 pixel_type = RL2_PIXEL_GRAYSCALE;
3188 num_bands = 1;
3189 }
3190 else if (pixel_type == RL2_PIXEL_PALETTE && out_pixel == RL2_PIXEL_RGB)
3191 {
3192 /* Pyramid tiles PALETTE */
3193 rl2PixelPtr nd = NULL;
3194 nd = rl2_get_coverage_no_data (cvg);
3195 plt = rl2_get_dbms_palette (handle, coverage);
3196 if (nd != NULL)
3197 {
3198 /* creating an RGB NoData pixel */
3199 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) nd;
3200 rl2PrivSamplePtr sample = pxl->Samples + 0;
3201 no_data = rl2_create_pixel (RL2_SAMPLE_UINT8, RL2_PIXEL_RGB, 3);
3202 kill_no_data = no_data;
3203 if (plt == NULL)
3204 {
3205 /* default: white */
3206 rl2_set_pixel_sample_uint8 (no_data, RL2_RED_BAND, 255);
3207 rl2_set_pixel_sample_uint8 (no_data, RL2_GREEN_BAND, 255);
3208 rl2_set_pixel_sample_uint8 (no_data, RL2_BLUE_BAND, 255);
3209 }
3210 else
3211 {
3212 /* retrieving the color from within the palette */
3213 int ok = 0;
3214 unsigned short num_entries;
3215 unsigned char *red = NULL;
3216 unsigned char *green = NULL;
3217 unsigned char *blue = NULL;
3218 if (rl2_get_palette_colors
3219 (plt, &num_entries, &red, &green, &blue) == RL2_OK)
3220 {
3221 if (sample->uint8 < num_entries)
3222 {
3223 rl2_set_pixel_sample_uint8 (no_data,
3224 RL2_RED_BAND,
3225 red
3226 [sample->uint8]);
3227 rl2_set_pixel_sample_uint8 (no_data,
3228 RL2_GREEN_BAND,
3229 green
3230 [sample->uint8]);
3231 rl2_set_pixel_sample_uint8 (no_data,
3232 RL2_BLUE_BAND,
3233 blue
3234 [sample->uint8]);
3235 ok = 1;
3236 }
3237 free (red);
3238 free (green);
3239 free (blue);
3240 }
3241 if (!ok)
3242 {
3243 /* default: white */
3244 rl2_set_pixel_sample_uint8 (no_data, RL2_RED_BAND,
3245 255);
3246 rl2_set_pixel_sample_uint8 (no_data, RL2_GREEN_BAND,
3247 255);
3248 rl2_set_pixel_sample_uint8 (no_data, RL2_BLUE_BAND,
3249 255);
3250 }
3251 }
3252 }
3253 if (plt != NULL)
3254 rl2_destroy_palette (plt);
3255 plt = NULL;
3256 sample_type = RL2_SAMPLE_UINT8;
3257 pixel_type = RL2_PIXEL_RGB;
3258 num_bands = 3;
3259 }
3260 else
3261 {
3262 if (pixel_type == RL2_PIXEL_PALETTE)
3263 {
3264 /* attempting to retrieve the Coverage's Palette */
3265 plt = rl2_get_dbms_palette (handle, coverage);
3266 if (plt == NULL)
3267 goto error;
3268 }
3269 no_data = rl2_get_coverage_no_data (cvg);
3270 }
3271
3272 if (style != NULL && stats != NULL)
3273 {
3274 if (out_pixel == RL2_PIXEL_RGB)
3275 {
3276 sample_type = RL2_SAMPLE_UINT8;
3277 pixel_type = RL2_PIXEL_RGB;
3278 num_bands = 3;
3279 }
3280 if (out_pixel == RL2_PIXEL_GRAYSCALE)
3281 {
3282 sample_type = RL2_SAMPLE_UINT8;
3283 pixel_type = RL2_PIXEL_GRAYSCALE;
3284 num_bands = 1;
3285 }
3286 }
3287
3288 switch (sample_type)
3289 {
3290 case RL2_SAMPLE_INT16:
3291 case RL2_SAMPLE_UINT16:
3292 pix_sz = 2;
3293 break;
3294 case RL2_SAMPLE_INT32:
3295 case RL2_SAMPLE_UINT32:
3296 case RL2_SAMPLE_FLOAT:
3297 pix_sz = 4;
3298 break;
3299 case RL2_SAMPLE_DOUBLE:
3300 pix_sz = 8;
3301 break;
3302 };
3303 if (out_pixel == RL2_PIXEL_GRAYSCALE
3304 && cvg_pixel_type == RL2_PIXEL_DATAGRID)
3305 {
3306 if (has_styled_rgb_colors (style))
3307 {
3308 /* RGB RasterSymbolizer: promoting to RGB */
3309 out_pixel = RL2_PIXEL_RGB;
3310 sample_type = RL2_SAMPLE_UINT8;
3311 pixel_type = RL2_PIXEL_RGB;
3312 pix_sz = 1;
3313 num_bands = 3;
3314 }
3315 }
3316 bufpix_size = pix_sz * num_bands * width * height;
3317 bufpix = malloc (bufpix_size);
3318 if (bufpix == NULL)
3319 {
3320 fprintf (stderr,
3321 "rl2_get_raw_raster_data: Insufficient Memory !!!\n");
3322 goto error;
3323 }
3324
3325 if (style != NULL)
3326 {
3327 /* testing for Shaded Relief */
3328 if (rl2_has_raster_style_shaded_relief (style, &has_shaded_relief) !=
3329 RL2_OK)
3330 goto error;
3331 if (has_shaded_relief)
3332 {
3333 /* preparing a Shaded Relief mask */
3334 double scale_factor =
3335 rl2_get_shaded_relief_scale_factor (handle, coverage);
3336 if (rl2_get_raster_style_shaded_relief
3337 (style, &brightness_only, &relief_factor) != RL2_OK)
3338 goto error;
3339 if (rl2_build_shaded_relief_mask
3340 (handle, cvg, relief_factor, scale_factor, width, height,
3341 minx, miny, maxx, maxy, x_res, y_res, &shaded_relief,
3342 &shaded_relief_sz) != RL2_OK)
3343 goto error;
3344
3345 if (brightness_only || !has_styled_rgb_colors (style))
3346 {
3347 /* returning a Grayscale ShadedRelief (BrightnessOnly) */
3348 unsigned int row;
3349 unsigned int col;
3350 float *p_in = shaded_relief;
3351 unsigned char *p_out = bufpix;
3352 if (bgcolor != NULL)
3353 void_raw_buffer (bufpix, width, height, sample_type,
3354 num_bands, bgcolor);
3355 else
3356 void_raw_buffer (bufpix, width, height, sample_type,
3357 num_bands, no_data);
3358 for (row = 0; row < height; row++)
3359 {
3360 for (col = 0; col < width; col++)
3361 {
3362 float coeff = *p_in++;
3363 if (coeff < 0.0)
3364 p_out++; /* transparent */
3365 else
3366 *p_out++ =
3367 (unsigned char) (255.0 * coeff);
3368 }
3369 }
3370 free (shaded_relief);
3371 *buffer = bufpix;
3372 *buf_size = bufpix_size;
3373 if (kill_no_data != NULL)
3374 rl2_destroy_pixel (kill_no_data);
3375 return RL2_OK;
3376 }
3377 }
3378 }
3379
3380 /* preparing the "tiles" SQL query */
3381 xtiles = sqlite3_mprintf ("%s_tiles", coverage);
3382 xxtiles = gaiaDoubleQuotedSql (xtiles);
3383 sql =
3384 sqlite3_mprintf ("SELECT tile_id, MbrMinX(geometry), MbrMaxY(geometry) "
3385 "FROM \"%s\" "
3386 "WHERE pyramid_level = ? AND ROWID IN ( "
3387 "SELECT ROWID FROM SpatialIndex WHERE f_table_name = %Q "
3388 "AND search_frame = BuildMBR(?, ?, ?, ?))", xxtiles,
3389 xtiles);
3390 sqlite3_free (xtiles);
3391 free (xxtiles);
3392 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_tiles, NULL);
3393 sqlite3_free (sql);
3394 if (ret != SQLITE_OK)
3395 {
3396 printf ("SELECT raw tiles SQL error: %s\n", sqlite3_errmsg (handle));
3397 goto error;
3398 }
3399
3400 if (scale == RL2_SCALE_1)
3401 {
3402 /* preparing the data SQL query - both ODD and EVEN */
3403 xdata = sqlite3_mprintf ("%s_tile_data", coverage);
3404 xxdata = gaiaDoubleQuotedSql (xdata);
3405 sqlite3_free (xdata);
3406 sql = sqlite3_mprintf ("SELECT tile_data_odd, tile_data_even "
3407 "FROM \"%s\" WHERE tile_id = ?", xxdata);
3408 free (xxdata);
3409 ret =
3410 sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_data, NULL);
3411 sqlite3_free (sql);
3412 if (ret != SQLITE_OK)
3413 {
3414 printf ("SELECT raw tiles data(2) SQL error: %s\n",
3415 sqlite3_errmsg (handle));
3416 goto error;
3417 }
3418 }
3419 else
3420 {
3421 /* preparing the data SQL query - only ODD */
3422 xdata = sqlite3_mprintf ("%s_tile_data", coverage);
3423 xxdata = gaiaDoubleQuotedSql (xdata);
3424 sqlite3_free (xdata);
3425 sql = sqlite3_mprintf ("SELECT tile_data_odd "
3426 "FROM \"%s\" WHERE tile_id = ?", xxdata);
3427 free (xxdata);
3428 ret =
3429 sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_data, NULL);
3430 sqlite3_free (sql);
3431 if (ret != SQLITE_OK)
3432 {
3433 printf ("SELECT raw tiles data(1) SQL error: %s\n",
3434 sqlite3_errmsg (handle));
3435 goto error;
3436 }
3437 }
3438
3439 /* preparing a raw pixels buffer */
3440 if (pixel_type == RL2_PIXEL_PALETTE)
3441 void_raw_buffer_palette (bufpix, width, height, no_data);
3442 else
3443 {
3444 if (bgcolor != NULL)
3445 void_raw_buffer (bufpix, width, height, sample_type, num_bands,
3446 bgcolor);
3447 else
3448 void_raw_buffer (bufpix, width, height, sample_type, num_bands,
3449 no_data);
3450 }
3451 if (!load_dbms_tiles
3452 (handle, stmt_tiles, stmt_data, bufpix, width, height, sample_type,
3453 num_bands, xx_res, yy_res, minx, miny, maxx, maxy, level, scale, plt,
3454 no_data, style, stats))
3455 goto error;
3456 if (kill_no_data != NULL)
3457 rl2_destroy_pixel (kill_no_data);
3458 sqlite3_finalize (stmt_tiles);
3459 sqlite3_finalize (stmt_data);
3460 if (shaded_relief != NULL)
3461 {
3462 /* applying the Shaded Relief */
3463 unsigned int row;
3464 unsigned int col;
3465 float *p_in = shaded_relief;
3466 unsigned char *p_out = bufpix;
3467 for (row = 0; row < height; row++)
3468 {
3469 for (col = 0; col < width; col++)
3470 {
3471 float coeff = *p_in++;
3472 if (coeff < 0.0)
3473 p_out += 3; /* unaffected */
3474 else
3475 {
3476 unsigned char r = *p_out;
3477 unsigned char g = *(p_out + 1);
3478 unsigned char b = *(p_out + 2);
3479 *p_out++ = (unsigned char) (r * coeff);
3480 *p_out++ = (unsigned char) (g * coeff);
3481 *p_out++ = (unsigned char) (b * coeff);
3482 }
3483 }
3484 }
3485 }
3486 *buffer = bufpix;
3487 *buf_size = bufpix_size;
3488 if (palette != NULL)
3489 *palette = plt;
3490 if (shaded_relief != NULL)
3491 free (shaded_relief);
3492 return RL2_OK;
3493
3494 error:
3495 if (stmt_tiles != NULL)
3496 sqlite3_finalize (stmt_tiles);
3497 if (stmt_data != NULL)
3498 sqlite3_finalize (stmt_data);
3499 if (bufpix != NULL)
3500 free (bufpix);
3501 if (kill_no_data != NULL)
3502 rl2_destroy_pixel (kill_no_data);
3503 if (shaded_relief != NULL)
3504 free (shaded_relief);
3505 return RL2_ERROR;
3506 }
3507
3508 RL2_DECLARE int
rl2_get_raw_raster_data(sqlite3 * handle,rl2CoveragePtr cvg,unsigned int width,unsigned int height,double minx,double miny,double maxx,double maxy,double x_res,double y_res,unsigned char ** buffer,int * buf_size,rl2PalettePtr * palette,unsigned char out_pixel)3509 rl2_get_raw_raster_data (sqlite3 * handle, rl2CoveragePtr cvg,
3510 unsigned int width, unsigned int height,
3511 double minx, double miny, double maxx, double maxy,
3512 double x_res, double y_res, unsigned char **buffer,
3513 int *buf_size, rl2PalettePtr * palette,
3514 unsigned char out_pixel)
3515 {
3516 /* attempting to return a buffer containing raw pixels from the DBMS Coverage */
3517 return get_raw_raster_data_common (handle, cvg, width, height, minx, miny,
3518 maxx, maxy, x_res, y_res, buffer,
3519 buf_size, palette, out_pixel, NULL,
3520 NULL, NULL);
3521 }
3522
3523 RL2_DECLARE int
rl2_get_triple_band_raw_raster_data(sqlite3 * handle,rl2CoveragePtr cvg,unsigned int width,unsigned int height,double minx,double miny,double maxx,double maxy,double x_res,double y_res,unsigned char red_band,unsigned char green_band,unsigned char blue_band,unsigned char ** buffer,int * buf_size,rl2PixelPtr bgcolor)3524 rl2_get_triple_band_raw_raster_data (sqlite3 * handle, rl2CoveragePtr cvg,
3525 unsigned int width,
3526 unsigned int height, double minx,
3527 double miny, double maxx, double maxy,
3528 double x_res, double y_res,
3529 unsigned char red_band,
3530 unsigned char green_band,
3531 unsigned char blue_band,
3532 unsigned char **buffer, int *buf_size,
3533 rl2PixelPtr bgcolor)
3534 {
3535 /* attempting to return a buffer containing raw pixels from the DBMS Coverage */
3536 rl2PixelPtr no_data = NULL;
3537 const char *coverage;
3538 unsigned char level;
3539 unsigned char scale;
3540 double xx_res = x_res;
3541 double yy_res = y_res;
3542 unsigned char *bufpix = NULL;
3543 int bufpix_size;
3544 unsigned char sample_type;
3545 unsigned char pixel_type;
3546 unsigned char num_bands;
3547 char *xtiles;
3548 char *xxtiles;
3549 char *xdata;
3550 char *xxdata;
3551 char *sql;
3552 sqlite3_stmt *stmt_tiles = NULL;
3553 sqlite3_stmt *stmt_data = NULL;
3554 int ret;
3555
3556 if (cvg == NULL || handle == NULL)
3557 goto error;
3558 coverage = rl2_get_coverage_name (cvg);
3559 if (coverage == NULL)
3560 goto error;
3561 if (rl2_find_matching_resolution
3562 (handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
3563 goto error;
3564 if (rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands) !=
3565 RL2_OK)
3566 goto error;
3567 if (pixel_type != RL2_PIXEL_RGB && pixel_type != RL2_PIXEL_MULTIBAND)
3568 goto error;
3569 if (sample_type != RL2_SAMPLE_UINT8 && sample_type != RL2_SAMPLE_UINT16)
3570 goto error;
3571 if (red_band >= num_bands)
3572 goto error;
3573 if (green_band >= num_bands)
3574 goto error;
3575 if (blue_band >= num_bands)
3576 goto error;
3577
3578 if (bgcolor != NULL)
3579 {
3580 /* using the externally define background color */
3581 no_data = bgcolor;
3582 goto ok_no_data;
3583 }
3584
3585 ok_no_data:
3586 bufpix_size = 3 * width * height;
3587 if (sample_type == RL2_SAMPLE_UINT16)
3588 bufpix_size *= 2;
3589 bufpix = malloc (bufpix_size);
3590 if (bufpix == NULL)
3591 {
3592 fprintf (stderr,
3593 "rl2_get_triple_band_raw_raster_data: Insufficient Memory !!!\n");
3594 goto error;
3595 }
3596
3597 /* preparing the "tiles" SQL query */
3598 xtiles = sqlite3_mprintf ("%s_tiles", coverage);
3599 xxtiles = gaiaDoubleQuotedSql (xtiles);
3600 sql =
3601 sqlite3_mprintf ("SELECT tile_id, MbrMinX(geometry), MbrMaxY(geometry) "
3602 "FROM \"%s\" "
3603 "WHERE pyramid_level = ? AND ROWID IN ( "
3604 "SELECT ROWID FROM SpatialIndex WHERE f_table_name = %Q "
3605 "AND search_frame = BuildMBR(?, ?, ?, ?))", xxtiles,
3606 xtiles);
3607 sqlite3_free (xtiles);
3608 free (xxtiles);
3609 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_tiles, NULL);
3610 sqlite3_free (sql);
3611 if (ret != SQLITE_OK)
3612 {
3613 printf ("SELECT raw tiles SQL error: %s\n", sqlite3_errmsg (handle));
3614 goto error;
3615 }
3616
3617 /* preparing the data SQL query - both ODD and EVEN */
3618 xdata = sqlite3_mprintf ("%s_tile_data", coverage);
3619 xxdata = gaiaDoubleQuotedSql (xdata);
3620 sqlite3_free (xdata);
3621 sql = sqlite3_mprintf ("SELECT tile_data_odd, tile_data_even "
3622 "FROM \"%s\" WHERE tile_id = ?", xxdata);
3623 free (xxdata);
3624 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_data, NULL);
3625 sqlite3_free (sql);
3626 if (ret != SQLITE_OK)
3627 {
3628 printf ("SELECT raw tiles data(2) SQL error: %s\n",
3629 sqlite3_errmsg (handle));
3630 goto error;
3631 }
3632
3633 /* preparing a raw pixels buffer */
3634 void_raw_buffer (bufpix, width, height, sample_type, 3, no_data);
3635 if (!load_triple_band_dbms_tiles
3636 (handle, stmt_tiles, stmt_data, bufpix, width, height, red_band,
3637 green_band, blue_band, xx_res, yy_res, minx, miny, maxx, maxy, level,
3638 scale, no_data))
3639 goto error;
3640 sqlite3_finalize (stmt_tiles);
3641 sqlite3_finalize (stmt_data);
3642 *buffer = bufpix;
3643 *buf_size = bufpix_size;
3644 return RL2_OK;
3645
3646 error:
3647 if (stmt_tiles != NULL)
3648 sqlite3_finalize (stmt_tiles);
3649 if (stmt_data != NULL)
3650 sqlite3_finalize (stmt_data);
3651 if (bufpix != NULL)
3652 free (bufpix);
3653 return RL2_ERROR;
3654 }
3655
3656 static int
get_mono_band_raw_raster_data_common(sqlite3 * handle,rl2CoveragePtr cvg,unsigned int width,unsigned int height,double minx,double miny,double maxx,double maxy,double x_res,double y_res,unsigned char ** buffer,int * buf_size,unsigned char mono_band,rl2PixelPtr bgcolor)3657 get_mono_band_raw_raster_data_common (sqlite3 * handle, rl2CoveragePtr cvg,
3658 unsigned int width,
3659 unsigned int height, double minx,
3660 double miny, double maxx, double maxy,
3661 double x_res, double y_res,
3662 unsigned char **buffer, int *buf_size,
3663 unsigned char mono_band,
3664 rl2PixelPtr bgcolor)
3665 {
3666 /* attempting to return a buffer containing raw pixels from the DBMS Coverage */
3667 rl2PixelPtr no_data = NULL;
3668 const char *coverage;
3669 unsigned char level;
3670 unsigned char scale;
3671 double xx_res = x_res;
3672 double yy_res = y_res;
3673 unsigned char *bufpix = NULL;
3674 int bufpix_size;
3675 unsigned char sample_type;
3676 unsigned char pixel_type;
3677 unsigned char num_bands;
3678 char *xtiles;
3679 char *xxtiles;
3680 char *xdata;
3681 char *xxdata;
3682 char *sql;
3683 sqlite3_stmt *stmt_tiles = NULL;
3684 sqlite3_stmt *stmt_data = NULL;
3685 int ret;
3686
3687 if (cvg == NULL || handle == NULL)
3688 goto error;
3689 coverage = rl2_get_coverage_name (cvg);
3690 if (coverage == NULL)
3691 goto error;
3692 if (rl2_find_matching_resolution
3693 (handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
3694 goto error;
3695 if (rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands) !=
3696 RL2_OK)
3697 goto error;
3698 if (pixel_type != RL2_PIXEL_RGB && pixel_type != RL2_PIXEL_MULTIBAND)
3699 goto error;
3700 if (sample_type != RL2_SAMPLE_UINT8 && sample_type != RL2_SAMPLE_UINT16)
3701 goto error;
3702 if (mono_band >= num_bands)
3703 goto error;
3704
3705 if (bgcolor != NULL)
3706 {
3707 /* using the externally define background color */
3708 no_data = bgcolor;
3709 goto ok_no_data;
3710 }
3711
3712 ok_no_data:
3713 bufpix_size = width * height;
3714 if (sample_type == RL2_SAMPLE_UINT16)
3715 bufpix_size *= 2;
3716 bufpix = malloc (bufpix_size);
3717 if (bufpix == NULL)
3718 {
3719 fprintf (stderr,
3720 "rl2_get_mono_band_raw_raster_data: Insufficient Memory !!!\n");
3721 goto error;
3722 }
3723
3724 /* preparing the "tiles" SQL query */
3725 xtiles = sqlite3_mprintf ("%s_tiles", coverage);
3726 xxtiles = gaiaDoubleQuotedSql (xtiles);
3727 sql =
3728 sqlite3_mprintf ("SELECT tile_id, MbrMinX(geometry), MbrMaxY(geometry) "
3729 "FROM \"%s\" "
3730 "WHERE pyramid_level = ? AND ROWID IN ( "
3731 "SELECT ROWID FROM SpatialIndex WHERE f_table_name = %Q "
3732 "AND search_frame = BuildMBR(?, ?, ?, ?))", xxtiles,
3733 xtiles);
3734 sqlite3_free (xtiles);
3735 free (xxtiles);
3736 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_tiles, NULL);
3737 sqlite3_free (sql);
3738 if (ret != SQLITE_OK)
3739 {
3740 printf ("SELECT raw tiles SQL error: %s\n", sqlite3_errmsg (handle));
3741 goto error;
3742 }
3743
3744 /* preparing the data SQL query - both ODD and EVEN */
3745 xdata = sqlite3_mprintf ("%s_tile_data", coverage);
3746 xxdata = gaiaDoubleQuotedSql (xdata);
3747 sqlite3_free (xdata);
3748 sql = sqlite3_mprintf ("SELECT tile_data_odd, tile_data_even "
3749 "FROM \"%s\" WHERE tile_id = ?", xxdata);
3750 free (xxdata);
3751 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_data, NULL);
3752 sqlite3_free (sql);
3753 if (ret != SQLITE_OK)
3754 {
3755 printf ("SELECT raw tiles data(2) SQL error: %s\n",
3756 sqlite3_errmsg (handle));
3757 goto error;
3758 }
3759
3760 /* preparing a raw pixels buffer */
3761 void_raw_buffer (bufpix, width, height, sample_type, 1, no_data);
3762 if (!load_mono_band_dbms_tiles
3763 (handle, stmt_tiles, stmt_data, bufpix, width, height, mono_band,
3764 xx_res, yy_res, minx, miny, maxx, maxy, level, scale, no_data))
3765 goto error;
3766 sqlite3_finalize (stmt_tiles);
3767 sqlite3_finalize (stmt_data);
3768 *buffer = bufpix;
3769 *buf_size = bufpix_size;
3770 return RL2_OK;
3771
3772 error:
3773 if (stmt_tiles != NULL)
3774 sqlite3_finalize (stmt_tiles);
3775 if (stmt_data != NULL)
3776 sqlite3_finalize (stmt_data);
3777 if (bufpix != NULL)
3778 free (bufpix);
3779 return RL2_ERROR;
3780 }
3781
3782 RL2_DECLARE int
rl2_get_mono_band_raw_raster_data(sqlite3 * handle,rl2CoveragePtr cvg,unsigned int width,unsigned int height,double minx,double miny,double maxx,double maxy,double x_res,double y_res,unsigned char mono_band,unsigned char ** buffer,int * buf_size,rl2PixelPtr no_data)3783 rl2_get_mono_band_raw_raster_data (sqlite3 * handle, rl2CoveragePtr cvg,
3784 unsigned int width,
3785 unsigned int height, double minx,
3786 double miny, double maxx, double maxy,
3787 double x_res, double y_res,
3788 unsigned char mono_band,
3789 unsigned char **buffer, int *buf_size,
3790 rl2PixelPtr no_data)
3791 {
3792 /* attempting to return a buffer containing raw pixels from the DBMS Coverage */
3793 return get_mono_band_raw_raster_data_common (handle, cvg, width, height,
3794 minx, miny, maxx, maxy,
3795 x_res, y_res, buffer,
3796 buf_size, mono_band, no_data);
3797 }
3798
3799 RL2_DECLARE int
rl2_get_raw_raster_data_bgcolor(sqlite3 * handle,rl2CoveragePtr cvg,unsigned int width,unsigned int height,double minx,double miny,double maxx,double maxy,double x_res,double y_res,unsigned char ** buffer,int * buf_size,rl2PalettePtr * palette,unsigned char * out_pixel,unsigned char bg_red,unsigned char bg_green,unsigned char bg_blue,rl2RasterStylePtr style,rl2RasterStatisticsPtr stats)3800 rl2_get_raw_raster_data_bgcolor (sqlite3 * handle, rl2CoveragePtr cvg,
3801 unsigned int width, unsigned int height,
3802 double minx, double miny, double maxx,
3803 double maxy, double x_res, double y_res,
3804 unsigned char **buffer, int *buf_size,
3805 rl2PalettePtr * palette,
3806 unsigned char *out_pixel, unsigned char bg_red,
3807 unsigned char bg_green, unsigned char bg_blue,
3808 rl2RasterStylePtr style,
3809 rl2RasterStatisticsPtr stats)
3810 {
3811 /* attempting to return a buffer containing raw pixels from the DBMS Coverage + bgcolor */
3812 int ret;
3813 rl2PixelPtr no_data = NULL;
3814 const char *coverage;
3815 unsigned char sample_type;
3816 unsigned char pixel_type;
3817 unsigned char num_bands;
3818 rl2RasterStylePtr xstyle = style;
3819
3820 if (cvg == NULL || handle == NULL)
3821 return RL2_ERROR;
3822 if (rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands) !=
3823 RL2_OK)
3824 return RL2_ERROR;
3825 coverage = rl2_get_coverage_name (cvg);
3826 if (coverage == NULL)
3827 return RL2_ERROR;
3828
3829 if (pixel_type == RL2_PIXEL_MONOCHROME && *out_pixel == RL2_PIXEL_GRAYSCALE)
3830 {
3831 /* Pyramid tiles MONOCHROME - Grayscale pixel */
3832 no_data = rl2_create_pixel (RL2_SAMPLE_UINT8, RL2_PIXEL_GRAYSCALE, 1);
3833 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND, bg_red);
3834 }
3835 else if (pixel_type == RL2_PIXEL_PALETTE && *out_pixel == RL2_PIXEL_RGB)
3836 {
3837 /* Pyramid tiles PALETTE - RGB pixel */
3838 no_data = rl2_create_pixel (RL2_SAMPLE_UINT8, RL2_PIXEL_RGB, 3);
3839 rl2_set_pixel_sample_uint8 (no_data, RL2_RED_BAND, bg_red);
3840 rl2_set_pixel_sample_uint8 (no_data, RL2_GREEN_BAND, bg_green);
3841 rl2_set_pixel_sample_uint8 (no_data, RL2_BLUE_BAND, bg_blue);
3842 }
3843 else if (pixel_type == RL2_PIXEL_MONOCHROME)
3844 {
3845 /* Monochrome */
3846 no_data =
3847 rl2_create_pixel (RL2_SAMPLE_1_BIT, RL2_PIXEL_MONOCHROME, 1);
3848 if (bg_red > 128)
3849 rl2_set_pixel_sample_1bit (no_data, 0);
3850 else
3851 rl2_set_pixel_sample_1bit (no_data, 1);
3852 }
3853 else if (pixel_type == RL2_PIXEL_PALETTE)
3854 {
3855 /* Palette */
3856 int index = -1;
3857 rl2PalettePtr palette = rl2_get_dbms_palette (handle, coverage);
3858 if (palette != NULL)
3859 {
3860 /* searching the background color from within the palette */
3861 int i;
3862 unsigned short num_entries;
3863 unsigned char *red = NULL;
3864 unsigned char *green = NULL;
3865 unsigned char *blue = NULL;
3866 if (rl2_get_palette_colors
3867 (palette, &num_entries, &red, &green, &blue) == RL2_OK)
3868 {
3869 for (i = 0; i < num_entries; i++)
3870 {
3871 if (red[i] == bg_red && green[i] == bg_green
3872 && blue[i] == bg_blue)
3873 {
3874 index = i;
3875 break;
3876 }
3877 }
3878 free (red);
3879 free (green);
3880 free (blue);
3881 }
3882 }
3883 if (index < 0)
3884 {
3885 /* palette color found */
3886 switch (sample_type)
3887 {
3888 case RL2_SAMPLE_1_BIT:
3889 no_data =
3890 rl2_create_pixel (RL2_SAMPLE_1_BIT, RL2_PIXEL_PALETTE,
3891 1);
3892 rl2_set_pixel_sample_1bit (no_data,
3893 (unsigned char) index);
3894 break;
3895 case RL2_SAMPLE_2_BIT:
3896 no_data =
3897 rl2_create_pixel (RL2_SAMPLE_2_BIT, RL2_PIXEL_PALETTE,
3898 1);
3899 rl2_set_pixel_sample_2bit (no_data,
3900 (unsigned char) index);
3901 break;
3902 case RL2_SAMPLE_4_BIT:
3903 no_data =
3904 rl2_create_pixel (RL2_SAMPLE_4_BIT, RL2_PIXEL_PALETTE,
3905 1);
3906 rl2_set_pixel_sample_4bit (no_data,
3907 (unsigned char) index);
3908 break;
3909 case RL2_SAMPLE_UINT8:
3910 no_data =
3911 rl2_create_pixel (RL2_SAMPLE_UINT8, RL2_PIXEL_PALETTE,
3912 1);
3913 rl2_set_pixel_sample_uint8 (no_data, RL2_PALETTE_BAND,
3914 (unsigned char) index);
3915 break;
3916
3917 };
3918 }
3919 }
3920 else if (pixel_type == RL2_PIXEL_GRAYSCALE)
3921 {
3922 /* Grayscale */
3923 if (sample_type == RL2_SAMPLE_UINT8)
3924 {
3925 /* 256 levels grayscale */
3926 no_data =
3927 rl2_create_pixel (RL2_SAMPLE_UINT8, RL2_PIXEL_GRAYSCALE, 1);
3928 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND,
3929 bg_red);
3930 }
3931 else if (sample_type == RL2_SAMPLE_1_BIT)
3932 {
3933 /* 2 levels grayscale */
3934 no_data =
3935 rl2_create_pixel (RL2_SAMPLE_1_BIT, RL2_PIXEL_GRAYSCALE, 1);
3936 if (bg_red >= 128)
3937 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND, 1);
3938 else
3939 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND, 0);
3940 }
3941 else if (sample_type == RL2_SAMPLE_2_BIT)
3942 {
3943 /* 4 levels grayscale */
3944 no_data =
3945 rl2_create_pixel (RL2_SAMPLE_1_BIT, RL2_PIXEL_GRAYSCALE, 1);
3946 if (bg_red >= 192)
3947 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND, 3);
3948 else if (bg_red >= 128)
3949 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND, 2);
3950 else if (bg_red >= 64)
3951 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND, 1);
3952 else
3953 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND, 0);
3954 }
3955 else if (sample_type == RL2_SAMPLE_4_BIT)
3956 {
3957 /* 16 levels grayscale */
3958 no_data =
3959 rl2_create_pixel (RL2_SAMPLE_1_BIT, RL2_PIXEL_GRAYSCALE, 1);
3960 if (bg_red >= 240)
3961 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND,
3962 15);
3963 else if (bg_red >= 224)
3964 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND,
3965 14);
3966 else if (bg_red >= 208)
3967 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND,
3968 13);
3969 else if (bg_red >= 192)
3970 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND,
3971 12);
3972 else if (bg_red >= 176)
3973 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND,
3974 11);
3975 else if (bg_red >= 160)
3976 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND,
3977 10);
3978 else if (bg_red >= 144)
3979 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND, 9);
3980 else if (bg_red >= 128)
3981 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND, 8);
3982 else if (bg_red >= 112)
3983 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND, 7);
3984 else if (bg_red >= 96)
3985 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND, 6);
3986 else if (bg_red >= 80)
3987 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND, 5);
3988 else if (bg_red >= 64)
3989 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND, 4);
3990 else if (bg_red >= 48)
3991 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND, 3);
3992 else if (bg_red >= 32)
3993 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND, 2);
3994 else if (bg_red >= 16)
3995 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND, 1);
3996 else
3997 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND, 0);
3998 }
3999 }
4000 else if (pixel_type == RL2_PIXEL_RGB)
4001 {
4002 /* RGB */
4003 no_data = rl2_create_pixel (RL2_SAMPLE_UINT8, RL2_PIXEL_RGB, 3);
4004 rl2_set_pixel_sample_uint8 (no_data, RL2_RED_BAND, bg_red);
4005 rl2_set_pixel_sample_uint8 (no_data, RL2_GREEN_BAND, bg_green);
4006 rl2_set_pixel_sample_uint8 (no_data, RL2_BLUE_BAND, bg_blue);
4007 }
4008 if (no_data == NULL)
4009 {
4010 unsigned char pixel = *out_pixel;
4011 if (pixel == RL2_PIXEL_GRAYSCALE && pixel_type == RL2_PIXEL_DATAGRID)
4012 {
4013 if (has_styled_rgb_colors (style))
4014 {
4015 /* RGB RasterSymbolizer: promoting to RGB */
4016 pixel = RL2_PIXEL_RGB;
4017 }
4018 }
4019 if (pixel == RL2_PIXEL_GRAYSCALE)
4020 {
4021 /* output Grayscale pixel */
4022 no_data =
4023 rl2_create_pixel (RL2_SAMPLE_UINT8, RL2_PIXEL_GRAYSCALE, 1);
4024 rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND,
4025 bg_red);
4026 }
4027 if (pixel == RL2_PIXEL_RGB)
4028 {
4029 /* output RGB pixel */
4030 no_data = rl2_create_pixel (RL2_SAMPLE_UINT8, RL2_PIXEL_RGB, 3);
4031 rl2_set_pixel_sample_uint8 (no_data, RL2_RED_BAND, bg_red);
4032 rl2_set_pixel_sample_uint8 (no_data, RL2_GREEN_BAND, bg_green);
4033 rl2_set_pixel_sample_uint8 (no_data, RL2_BLUE_BAND, bg_blue);
4034 }
4035 }
4036 if (pixel_type == RL2_PIXEL_MONOCHROME)
4037 xstyle = NULL;
4038 ret =
4039 get_raw_raster_data_common (handle, cvg, width, height, minx, miny,
4040 maxx, maxy, x_res, y_res, buffer, buf_size,
4041 palette, *out_pixel, no_data, xstyle,
4042 stats);
4043 if (no_data != NULL)
4044 rl2_destroy_pixel (no_data);
4045 if (*out_pixel == RL2_PIXEL_GRAYSCALE && pixel_type == RL2_PIXEL_DATAGRID)
4046 {
4047 if (has_styled_rgb_colors (style))
4048 {
4049 /* RGB RasterSymbolizer: promoting to RGB */
4050 *out_pixel = RL2_PIXEL_RGB;
4051 }
4052 }
4053 if (pixel_type == RL2_PIXEL_MONOCHROME)
4054 {
4055 unsigned char red;
4056 unsigned char green;
4057 unsigned char blue;
4058 int ok = 0;
4059 if (style != NULL)
4060 {
4061 rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
4062 if (stl->categorize != NULL)
4063 {
4064 rl2PrivColorMapPointPtr color = stl->categorize->first;
4065 while (color != NULL)
4066 {
4067 if (color->value == 1.0)
4068 {
4069 ok = 1;
4070 red = color->red;
4071 green = color->green;
4072 blue = color->blue;
4073 break;
4074 }
4075 color = color->next;
4076 }
4077 }
4078 }
4079 if (*out_pixel != RL2_PIXEL_MONOCHROME)
4080 {
4081 int i;
4082 unsigned char *p = *buffer;
4083 for (i = 0; i < *buf_size; i++)
4084 {
4085 if (*p > 224)
4086 *p = 255;
4087 p++;
4088 }
4089 if (ok == 1)
4090 ok = 2;
4091 }
4092 if (ok == 1)
4093 {
4094 /* creating a Palette 0/1 */
4095 rl2PalettePtr plt = rl2_create_palette (2);
4096 rl2_set_palette_color (plt, 0, 255, 255, 255);
4097 rl2_set_palette_color (plt, 1, red, green, blue);
4098 *palette = plt;
4099 *out_pixel = RL2_PIXEL_PALETTE;
4100 }
4101 if (ok == 2)
4102 {
4103 /* creating a Palette 0/255 */
4104 int i;
4105 double dr = 255.0 - red;
4106 double dg = 255.0 - green;
4107 double db = 255.0 - blue;
4108 rl2PalettePtr plt = rl2_create_palette (256);
4109 for (i = 0; i < 256; i++)
4110 {
4111 double scale = 255.0 / (double) i;
4112 double r = (double) red + (dr / scale);
4113 double g = (double) green + (dg / scale);
4114 double b = (double) blue + (db / scale);
4115 if (r < 0.0)
4116 r = 0.0;
4117 if (r > 255.0)
4118 r = 255.0;
4119 if (g < 0.0)
4120 g = 0.0;
4121 if (g > 255.0)
4122 g = 255.0;
4123 if (b < 0.0)
4124 b = 0.0;
4125 if (b > 255.0)
4126 b = 255.0;
4127 rl2_set_palette_color (plt, i, (unsigned char) r,
4128 (unsigned char) g,
4129 (unsigned char) b);
4130 }
4131 *palette = plt;
4132 *out_pixel = RL2_PIXEL_PALETTE;
4133 }
4134 }
4135
4136 return ret;
4137 }
4138
4139 RL2_DECLARE rl2PalettePtr
rl2_get_dbms_palette(sqlite3 * handle,const char * coverage)4140 rl2_get_dbms_palette (sqlite3 * handle, const char *coverage)
4141 {
4142 /* attempting to retrieve a Coverage's Palette from the DBMS */
4143 rl2PalettePtr palette = NULL;
4144 char *sql;
4145 int ret;
4146 sqlite3_stmt *stmt = NULL;
4147
4148 if (handle == NULL || coverage == NULL)
4149 return NULL;
4150
4151 sql = sqlite3_mprintf ("SELECT palette FROM raster_coverages "
4152 "WHERE Lower(coverage_name) = Lower(%Q)", coverage);
4153 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
4154 sqlite3_free (sql);
4155 if (ret != SQLITE_OK)
4156 {
4157 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
4158 goto error;
4159 }
4160
4161 while (1)
4162 {
4163 /* scrolling the result set rows */
4164 ret = sqlite3_step (stmt);
4165 if (ret == SQLITE_DONE)
4166 break; /* end of result set */
4167 if (ret == SQLITE_ROW)
4168 {
4169 if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
4170 {
4171 const unsigned char *blob = sqlite3_column_blob (stmt, 0);
4172 int blob_sz = sqlite3_column_bytes (stmt, 0);
4173 palette = rl2_deserialize_dbms_palette (blob, blob_sz);
4174 }
4175 }
4176 else
4177 {
4178 fprintf (stderr, "SQL error: %s\n%s\n", sql,
4179 sqlite3_errmsg (handle));
4180 goto error;
4181 }
4182 }
4183
4184 if (palette == NULL)
4185 goto error;
4186 sqlite3_finalize (stmt);
4187 return palette;
4188
4189 error:
4190 if (stmt != NULL)
4191 sqlite3_finalize (stmt);
4192 return NULL;
4193 }
4194
4195 RL2_DECLARE int
rl2_update_dbms_palette(sqlite3 * handle,const char * coverage,rl2PalettePtr palette)4196 rl2_update_dbms_palette (sqlite3 * handle, const char *coverage,
4197 rl2PalettePtr palette)
4198 {
4199 /* attempting to update a Coverage's Palette into the DBMS */
4200 unsigned char sample_type = RL2_SAMPLE_UNKNOWN;
4201 unsigned char pixel_type = RL2_PIXEL_UNKNOWN;
4202 unsigned short num_entries;
4203 unsigned char *blob;
4204 int blob_size;
4205 sqlite3_stmt *stmt = NULL;
4206 char *sql;
4207 int ret;
4208 if (handle == NULL || coverage == NULL || palette == NULL)
4209 return RL2_ERROR;
4210
4211 sql =
4212 sqlite3_mprintf ("SELECT sample_type, pixel_type FROM raster_coverages "
4213 "WHERE Lower(coverage_name) = Lower(%Q)", coverage);
4214 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
4215 sqlite3_free (sql);
4216 if (ret != SQLITE_OK)
4217 {
4218 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
4219 goto error;
4220 }
4221
4222 while (1)
4223 {
4224 /* scrolling the result set rows */
4225 ret = sqlite3_step (stmt);
4226 if (ret == SQLITE_DONE)
4227 break; /* end of result set */
4228 if (ret == SQLITE_ROW)
4229 {
4230 const char *sample =
4231 (const char *) sqlite3_column_text (stmt, 0);
4232 const char *pixel =
4233 (const char *) sqlite3_column_text (stmt, 1);
4234 if (strcmp (sample, "1-BIT") == 0)
4235 sample_type = RL2_SAMPLE_1_BIT;
4236 if (strcmp (sample, "2-BIT") == 0)
4237 sample_type = RL2_SAMPLE_2_BIT;
4238 if (strcmp (sample, "4-BIT") == 0)
4239 sample_type = RL2_SAMPLE_4_BIT;
4240 if (strcmp (sample, "UINT8") == 0)
4241 sample_type = RL2_SAMPLE_UINT8;
4242 if (strcmp (pixel, "PALETTE") == 0)
4243 pixel_type = RL2_PIXEL_PALETTE;
4244 }
4245 else
4246 {
4247 fprintf (stderr, "SQL error: %s\n%s\n", sql,
4248 sqlite3_errmsg (handle));
4249 goto error;
4250 }
4251 }
4252 sqlite3_finalize (stmt);
4253 stmt = NULL;
4254
4255 /* testing for self-consistency */
4256 if (pixel_type != RL2_PIXEL_PALETTE)
4257 goto error;
4258 if (rl2_get_palette_entries (palette, &num_entries) != RL2_OK)
4259 goto error;
4260 switch (sample_type)
4261 {
4262 case RL2_SAMPLE_UINT8:
4263 if (num_entries > 256)
4264 goto error;
4265 break;
4266 case RL2_SAMPLE_1_BIT:
4267 if (num_entries > 2)
4268 goto error;
4269 break;
4270 case RL2_SAMPLE_2_BIT:
4271 if (num_entries > 4)
4272 goto error;
4273 break;
4274 case RL2_SAMPLE_4_BIT:
4275 if (num_entries > 16)
4276 goto error;
4277 break;
4278 default:
4279 goto error;
4280 };
4281
4282 if (rl2_serialize_dbms_palette (palette, &blob, &blob_size) != RL2_OK)
4283 goto error;
4284 sql = sqlite3_mprintf ("UPDATE raster_coverages SET palette = ? "
4285 "WHERE Lower(coverage_name) = Lower(%Q)", coverage);
4286 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
4287 sqlite3_free (sql);
4288 if (ret != SQLITE_OK)
4289 {
4290 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
4291 goto error;
4292 }
4293 sqlite3_reset (stmt);
4294 sqlite3_clear_bindings (stmt);
4295 sqlite3_bind_blob (stmt, 1, blob, blob_size, free);
4296 ret = sqlite3_step (stmt);
4297 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
4298 {
4299 sqlite3_finalize (stmt);
4300 return RL2_OK;
4301 }
4302 fprintf (stderr,
4303 "sqlite3_step() error: UPDATE raster_coverages \"%s\"\n",
4304 sqlite3_errmsg (handle));
4305
4306 error:
4307 if (stmt != NULL)
4308 sqlite3_finalize (stmt);
4309 return RL2_ERROR;
4310 }
4311
4312 static void
set_remapped_palette(rl2PrivTiffOriginPtr origin,rl2PalettePtr palette)4313 set_remapped_palette (rl2PrivTiffOriginPtr origin, rl2PalettePtr palette)
4314 {
4315 /* installing a remapped Palette into the TIFF origin */
4316 int j;
4317 rl2PrivPaletteEntryPtr entry;
4318 rl2PrivPalettePtr plt = (rl2PrivPalettePtr) palette;
4319
4320 if (plt->nEntries != origin->remapMaxPalette)
4321 {
4322 /* reallocating the remapped palette */
4323 if (origin->remapRed != NULL)
4324 free (origin->remapRed);
4325 if (origin->remapGreen != NULL)
4326 free (origin->remapGreen);
4327 if (origin->remapBlue != NULL)
4328 free (origin->remapBlue);
4329 origin->remapMaxPalette = plt->nEntries;
4330 origin->remapRed = malloc (origin->remapMaxPalette);
4331 origin->remapGreen = malloc (origin->remapMaxPalette);
4332 origin->remapBlue = malloc (origin->remapMaxPalette);
4333 }
4334 for (j = 0; j < plt->nEntries; j++)
4335 {
4336 entry = plt->entries + j;
4337 origin->remapRed[j] = entry->red;
4338 origin->remapGreen[j] = entry->green;
4339 origin->remapBlue[j] = entry->blue;
4340 }
4341 }
4342
4343 RL2_DECLARE int
rl2_check_dbms_palette(sqlite3 * handle,rl2CoveragePtr coverage,rl2TiffOriginPtr tiff)4344 rl2_check_dbms_palette (sqlite3 * handle, rl2CoveragePtr coverage,
4345 rl2TiffOriginPtr tiff)
4346 {
4347 /*attempting to merge/update a Coverage's Palette */
4348 int i;
4349 int j;
4350 int changed = 0;
4351 int maxPalette = 0;
4352 unsigned char red[256];
4353 unsigned char green[256];
4354 unsigned char blue[256];
4355 int ok;
4356 rl2PalettePtr palette = NULL;
4357 rl2PrivPaletteEntryPtr entry;
4358 rl2PrivPalettePtr plt;
4359 rl2PrivCoveragePtr cvg = (rl2PrivCoveragePtr) coverage;
4360 rl2PrivTiffOriginPtr origin = (rl2PrivTiffOriginPtr) tiff;
4361 if (cvg == NULL || origin == NULL)
4362 return RL2_ERROR;
4363 palette = rl2_get_dbms_palette (handle, cvg->coverageName);
4364 if (palette == NULL)
4365 goto error;
4366 plt = (rl2PrivPalettePtr) palette;
4367 for (j = 0; j < plt->nEntries; j++)
4368 {
4369 entry = plt->entries + j;
4370 ok = 0;
4371 for (i = 0; i < maxPalette; i++)
4372 {
4373 if (red[i] == entry->red && green[i] == entry->green
4374 && blue[i] == entry->blue)
4375 {
4376 ok = 1;
4377 break;
4378 }
4379 }
4380 if (ok)
4381 continue;
4382 if (maxPalette == 256)
4383 goto error;
4384 red[maxPalette] = entry->red;
4385 green[maxPalette] = entry->green;
4386 blue[maxPalette] = entry->blue;
4387 maxPalette++;
4388 }
4389
4390 for (i = 0; i < origin->maxPalette; i++)
4391 {
4392 /* checking TIFF palette entries */
4393 unsigned char tiff_red = origin->red[i];
4394 unsigned char tiff_green = origin->green[i];
4395 unsigned char tiff_blue = origin->blue[i];
4396 ok = 0;
4397 for (j = 0; j < maxPalette; j++)
4398 {
4399 if (tiff_red == red[j] && tiff_green == green[j]
4400 && tiff_blue == blue[j])
4401 {
4402 /* found a matching color */
4403 ok = 1;
4404 break;
4405 }
4406 }
4407 if (!ok)
4408 {
4409 /* attempting to insert a new color into the pseudo-Palette */
4410 if (maxPalette == 256)
4411 goto error;
4412 red[maxPalette] = tiff_red;
4413 green[maxPalette] = tiff_green;
4414 blue[maxPalette] = tiff_blue;
4415 maxPalette++;
4416 changed = 1;
4417 }
4418 }
4419 if (changed)
4420 {
4421 /* updating the DBMS Palette */
4422 rl2PalettePtr plt2 = rl2_create_palette (maxPalette);
4423 if (plt2 == NULL)
4424 goto error;
4425 rl2_destroy_palette (palette);
4426 palette = plt2;
4427 for (j = 0; j < maxPalette; j++)
4428 rl2_set_palette_color (palette, j, red[j], green[j], blue[j]);
4429 if (rl2_update_dbms_palette (handle, cvg->coverageName, palette) !=
4430 RL2_OK)
4431 goto error;
4432 }
4433 set_remapped_palette (origin, palette);
4434 rl2_destroy_palette (palette);
4435 return RL2_OK;
4436
4437 error:
4438 if (palette != NULL)
4439 rl2_destroy_palette (palette);
4440 return RL2_ERROR;
4441 }
4442
4443 RL2_DECLARE int
rl2_update_dbms_coverage(sqlite3 * handle,const char * coverage)4444 rl2_update_dbms_coverage (sqlite3 * handle, const char *coverage)
4445 {
4446 /*attempting to update a Coverage (statistics and extent) */
4447 int ret;
4448 char *sql;
4449 char *xtable;
4450 char *xxtable;
4451 rl2RasterStatisticsPtr coverage_stats = NULL;
4452 unsigned char *blob_stats;
4453 int blob_stats_sz;
4454 int first;
4455 sqlite3_stmt *stmt_ext_in = NULL;
4456 sqlite3_stmt *stmt_ext_out = NULL;
4457 sqlite3_stmt *stmt_stats_in = NULL;
4458 sqlite3_stmt *stmt_stats_out = NULL;
4459
4460 /* Extent query stmt */
4461 xtable = sqlite3_mprintf ("%s_sections", coverage);
4462 xxtable = gaiaDoubleQuotedSql (xtable);
4463 sqlite3_free (xtable);
4464 sql =
4465 sqlite3_mprintf
4466 ("SELECT Min(MbrMinX(geometry)), Min(MbrMinY(geometry)), "
4467 "Max(MbrMaxX(geometry)), Max(MbrMaxY(geometry)) " "FROM \"%s\"",
4468 xxtable);
4469 free (xxtable);
4470 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_ext_in, NULL);
4471 sqlite3_free (sql);
4472 if (ret != SQLITE_OK)
4473 {
4474 printf ("SELECT Coverage extent SQL error: %s\n",
4475 sqlite3_errmsg (handle));
4476 goto error;
4477 }
4478 /* Extent update stmt */
4479 sql = sqlite3_mprintf ("UPDATE raster_coverages SET extent_minx = ?, "
4480 "extent_miny = ?, extent_maxx = ?, extent_maxy = ? "
4481 "WHERE Lower(coverage_name) = Lower(%Q)", coverage);
4482 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_ext_out, NULL);
4483 sqlite3_free (sql);
4484 if (ret != SQLITE_OK)
4485 {
4486 printf ("UPDATE Coverage extent SQL error: %s\n",
4487 sqlite3_errmsg (handle));
4488 goto error;
4489 }
4490
4491 while (1)
4492 {
4493 /* querying the extent */
4494 ret = sqlite3_step (stmt_ext_in);
4495 if (ret == SQLITE_DONE)
4496 break;
4497 if (ret == SQLITE_ROW)
4498 {
4499 double minx = sqlite3_column_double (stmt_ext_in, 0);
4500 double miny = sqlite3_column_double (stmt_ext_in, 1);
4501 double maxx = sqlite3_column_double (stmt_ext_in, 2);
4502 double maxy = sqlite3_column_double (stmt_ext_in, 3);
4503
4504 /* updating the extent */
4505 sqlite3_reset (stmt_ext_out);
4506 sqlite3_clear_bindings (stmt_ext_out);
4507 sqlite3_bind_double (stmt_ext_out, 1, minx);
4508 sqlite3_bind_double (stmt_ext_out, 2, miny);
4509 sqlite3_bind_double (stmt_ext_out, 3, maxx);
4510 sqlite3_bind_double (stmt_ext_out, 4, maxy);
4511 ret = sqlite3_step (stmt_ext_out);
4512 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
4513 break;
4514 else
4515 {
4516 fprintf (stderr,
4517 "UPDATE Coverage Extent sqlite3_step() error: %s\n",
4518 sqlite3_errmsg (handle));
4519 goto error;
4520 }
4521 }
4522 else
4523 {
4524 fprintf (stderr,
4525 "SELECT Coverage Extent sqlite3_step() error: %s\n",
4526 sqlite3_errmsg (handle));
4527 goto error;
4528 }
4529 }
4530
4531 sqlite3_finalize (stmt_ext_in);
4532 sqlite3_finalize (stmt_ext_out);
4533 stmt_ext_in = NULL;
4534 stmt_ext_out = NULL;
4535
4536 /* Raster Statistics query stmt */
4537 xtable = sqlite3_mprintf ("%s_sections", coverage);
4538 xxtable = gaiaDoubleQuotedSql (xtable);
4539 sqlite3_free (xtable);
4540 sql = sqlite3_mprintf ("SELECT statistics FROM \"%s\"", xxtable);
4541 free (xxtable);
4542 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_stats_in, NULL);
4543 sqlite3_free (sql);
4544 if (ret != SQLITE_OK)
4545 {
4546 printf ("SELECT Coverage Statistics SQL error: %s\n",
4547 sqlite3_errmsg (handle));
4548 goto error;
4549 }
4550 /* Raster Statistics update stmt */
4551 sql = sqlite3_mprintf ("UPDATE raster_coverages SET statistics = ? "
4552 "WHERE Lower(coverage_name) = Lower(%Q)", coverage);
4553 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_stats_out, NULL);
4554 sqlite3_free (sql);
4555 if (ret != SQLITE_OK)
4556 {
4557 printf ("UPDATE Coverage Statistics SQL error: %s\n",
4558 sqlite3_errmsg (handle));
4559 goto error;
4560 }
4561
4562 first = 1;
4563 while (1)
4564 {
4565 /* querying the statistics */
4566 ret = sqlite3_step (stmt_stats_in);
4567 if (ret == SQLITE_DONE)
4568 break;
4569 if (ret == SQLITE_ROW)
4570 {
4571 rl2RasterStatisticsPtr stats;
4572 blob_stats =
4573 (unsigned char *) sqlite3_column_blob (stmt_stats_in, 0);
4574 blob_stats_sz = sqlite3_column_bytes (stmt_stats_in, 0);
4575 stats =
4576 rl2_deserialize_dbms_raster_statistics (blob_stats,
4577 blob_stats_sz);
4578 if (stats == NULL)
4579 goto error;
4580
4581 if (first)
4582 {
4583 double no_data;
4584 double count;
4585 unsigned char sample_type;
4586 unsigned char num_bands;
4587 if (rl2_get_raster_statistics_summary
4588 (stats, &no_data, &count, &sample_type,
4589 &num_bands) != RL2_OK)
4590 goto error;
4591 coverage_stats =
4592 rl2_create_raster_statistics (sample_type, num_bands);
4593 if (coverage_stats == NULL)
4594 goto error;
4595 first = 0;
4596 }
4597
4598 rl2_aggregate_raster_statistics (stats, coverage_stats);
4599 rl2_destroy_raster_statistics (stats);
4600 }
4601 else
4602 {
4603 fprintf (stderr,
4604 "SELECT Coverage Statistics sqlite3_step() error: %s\n",
4605 sqlite3_errmsg (handle));
4606 goto error;
4607 }
4608 }
4609 if (coverage_stats == NULL)
4610 goto error;
4611
4612 /* updating the statistics */
4613 compute_aggregate_sq_diff (coverage_stats);
4614 sqlite3_reset (stmt_stats_out);
4615 sqlite3_clear_bindings (stmt_stats_out);
4616 rl2_serialize_dbms_raster_statistics (coverage_stats, &blob_stats,
4617 &blob_stats_sz);
4618 sqlite3_bind_blob (stmt_stats_out, 1, blob_stats, blob_stats_sz, free);
4619 ret = sqlite3_step (stmt_stats_out);
4620 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
4621 ;
4622 else
4623 {
4624 fprintf (stderr,
4625 "UPDATE Coverage Statistics sqlite3_step() error: %s\n",
4626 sqlite3_errmsg (handle));
4627 goto error;
4628 }
4629
4630 sqlite3_finalize (stmt_stats_in);
4631 sqlite3_finalize (stmt_stats_out);
4632 rl2_destroy_raster_statistics (coverage_stats);
4633 return RL2_OK;
4634
4635 error:
4636 if (stmt_ext_in != NULL)
4637 sqlite3_finalize (stmt_ext_in);
4638 if (stmt_ext_out != NULL)
4639 sqlite3_finalize (stmt_ext_out);
4640 if (stmt_stats_in != NULL)
4641 sqlite3_finalize (stmt_stats_in);
4642 if (stmt_stats_out != NULL)
4643 sqlite3_finalize (stmt_stats_out);
4644 if (coverage_stats != NULL)
4645 rl2_destroy_raster_statistics (coverage_stats);
4646 return RL2_ERROR;
4647 }
4648
4649 RL2_DECLARE rl2RasterStylePtr
rl2_create_raster_style_from_dbms(sqlite3 * handle,const char * coverage,const char * style)4650 rl2_create_raster_style_from_dbms (sqlite3 * handle, const char *coverage,
4651 const char *style)
4652 {
4653 /* attempting to load and parse a RasterSymbolizer style */
4654 const char *sql;
4655 int ret;
4656 sqlite3_stmt *stmt = NULL;
4657 rl2RasterStylePtr stl = NULL;
4658 char *name = NULL;
4659 char *title = NULL;
4660 char *abstract = NULL;
4661 unsigned char *xml = NULL;
4662
4663 sql = "SELECT style_name, XB_GetTitle(style), XB_GetAbstract(style), "
4664 "XB_GetDocument(style) FROM SE_raster_styled_layers "
4665 "WHERE Lower(coverage_name) = Lower(?) AND Lower(style_name) = Lower(?)";
4666 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
4667 if (ret != SQLITE_OK)
4668 {
4669 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
4670 goto error;
4671 }
4672 sqlite3_reset (stmt);
4673 sqlite3_clear_bindings (stmt);
4674 sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
4675 sqlite3_bind_text (stmt, 2, style, strlen (style), SQLITE_STATIC);
4676 while (1)
4677 {
4678 /* scrolling the result set rows */
4679 ret = sqlite3_step (stmt);
4680 if (ret == SQLITE_DONE)
4681 break; /* end of result set */
4682 if (ret == SQLITE_ROW)
4683 {
4684 int len;
4685 const char *str;
4686 const unsigned char *ustr;
4687 if (sqlite3_column_type (stmt, 0) == SQLITE_TEXT)
4688 {
4689 str = (const char *) sqlite3_column_text (stmt, 0);
4690 len = strlen (str);
4691 name = malloc (len + 1);
4692 strcpy (name, str);
4693 }
4694 if (sqlite3_column_type (stmt, 1) == SQLITE_TEXT)
4695 {
4696 str = (const char *) sqlite3_column_text (stmt, 1);
4697 len = strlen (str);
4698 title = malloc (len + 1);
4699 strcpy (title, str);
4700 }
4701 if (sqlite3_column_type (stmt, 2) == SQLITE_TEXT)
4702 {
4703 str = (const char *) sqlite3_column_text (stmt, 2);
4704 len = strlen (str);
4705 abstract = malloc (len + 1);
4706 strcpy (abstract, str);
4707 }
4708 if (sqlite3_column_type (stmt, 3) == SQLITE_TEXT)
4709 {
4710 ustr = sqlite3_column_text (stmt, 3);
4711 len = strlen ((const char *) ustr);
4712 xml = malloc (len + 1);
4713 strcpy ((char *) xml, (const char *) ustr);
4714 }
4715 }
4716 else
4717 {
4718 fprintf (stderr, "SQL error: %s\n%s\n", sql,
4719 sqlite3_errmsg (handle));
4720 goto error;
4721 }
4722 }
4723 sqlite3_finalize (stmt);
4724 stmt = NULL;
4725
4726 if (name == NULL || xml == NULL)
4727 {
4728 if (name != NULL)
4729 free (name);
4730 if (title != NULL)
4731 free (title);
4732 if (abstract != NULL)
4733 free (abstract);
4734 if (xml != NULL)
4735 free (xml);
4736 goto error;
4737 }
4738 stl = raster_style_from_sld_se_xml (name, title, abstract, xml);
4739 if (stl == NULL)
4740 goto error;
4741 return stl;
4742
4743 error:
4744 if (stmt != NULL)
4745 sqlite3_finalize (stmt);
4746 if (stl != NULL)
4747 rl2_destroy_raster_style (stl);
4748 return NULL;
4749 }
4750
4751 static int
test_named_layer(sqlite3 * handle,const char * groupName,const char * namedLayer)4752 test_named_layer (sqlite3 * handle, const char *groupName,
4753 const char *namedLayer)
4754 {
4755 /* testing a Named Layer for validity */
4756 int ret;
4757 char **results;
4758 int rows;
4759 int columns;
4760 int i;
4761 int ok = 0;
4762 /* testing if the Raster Coverage exists */
4763 char *sql = sqlite3_mprintf ("SELECT coverage_name FROM raster_coverages "
4764 "WHERE Lower(coverage_name) = Lower(%Q)",
4765 namedLayer);
4766 ret = sqlite3_get_table (handle, sql, &results, &rows, &columns, NULL);
4767 sqlite3_free (sql);
4768 if (ret != SQLITE_OK)
4769 return 0;
4770 for (i = 1; i <= rows; i++)
4771 ok = 1;
4772 sqlite3_free_table (results);
4773 if (!ok)
4774 return 0;
4775
4776 ok = 0;
4777 /* testing if the Raster Coverage belong to the Layer Group */
4778 sql = sqlite3_mprintf ("SELECT coverage_name FROM SE_styled_group_refs "
4779 "WHERE Lower(group_name) = Lower(%Q) AND "
4780 "Lower(coverage_name) = Lower(%Q)", groupName,
4781 namedLayer);
4782 ret = sqlite3_get_table (handle, sql, &results, &rows, &columns, NULL);
4783 sqlite3_free (sql);
4784 if (ret != SQLITE_OK)
4785 return 0;
4786 for (i = 1; i <= rows; i++)
4787 ok = 1;
4788 sqlite3_free_table (results);
4789 return ok;
4790 }
4791
4792 static int
test_named_style(sqlite3 * handle,const char * namedLayer,const char * namedStyle)4793 test_named_style (sqlite3 * handle, const char *namedLayer,
4794 const char *namedStyle)
4795 {
4796 /* testing a Named Style for validity */
4797 int ret;
4798 char **results;
4799 int rows;
4800 int columns;
4801 int i;
4802 int ok = 0;
4803 /* testing if the Layer Style exists */
4804 char *sql =
4805 sqlite3_mprintf ("SELECT style_name FROM SE_raster_styled_layers "
4806 "WHERE Lower(coverage_name) = Lower(%Q) AND "
4807 "Lower(style_name) = Lower(%Q)", namedLayer,
4808 namedStyle);
4809 ret = sqlite3_get_table (handle, sql, &results, &rows, &columns, NULL);
4810 sqlite3_free (sql);
4811 if (ret != SQLITE_OK)
4812 return 0;
4813 for (i = 1; i <= rows; i++)
4814 ok = 1;
4815 sqlite3_free_table (results);
4816 return ok;
4817 }
4818
4819 RL2_DECLARE rl2GroupStylePtr
rl2_create_group_style_from_dbms(sqlite3 * handle,const char * group,const char * style)4820 rl2_create_group_style_from_dbms (sqlite3 * handle, const char *group,
4821 const char *style)
4822 {
4823 /* attempting to load and parse a Layer Group style */
4824 const char *sql;
4825 int ret;
4826 sqlite3_stmt *stmt = NULL;
4827 rl2GroupStylePtr stl = NULL;
4828 char *name = NULL;
4829 char *title = NULL;
4830 char *abstract = NULL;
4831 unsigned char *xml = NULL;
4832 rl2PrivGroupStylePtr grp_stl;
4833 rl2PrivChildStylePtr child;
4834
4835 sql = "SELECT style_name, XB_GetTitle(style), XB_GetAbstract(style), "
4836 "XB_GetDocument(style) FROM SE_group_styles "
4837 "WHERE Lower(group_name) = Lower(?) AND Lower(style_name) = Lower(?)";
4838 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
4839 if (ret != SQLITE_OK)
4840 {
4841 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
4842 goto error;
4843 }
4844 sqlite3_reset (stmt);
4845 sqlite3_clear_bindings (stmt);
4846 sqlite3_bind_text (stmt, 1, group, strlen (group), SQLITE_STATIC);
4847 sqlite3_bind_text (stmt, 2, style, strlen (style), SQLITE_STATIC);
4848 while (1)
4849 {
4850 /* scrolling the result set rows */
4851 ret = sqlite3_step (stmt);
4852 if (ret == SQLITE_DONE)
4853 break; /* end of result set */
4854 if (ret == SQLITE_ROW)
4855 {
4856 int len;
4857 const char *str;
4858 const unsigned char *ustr;
4859 if (sqlite3_column_type (stmt, 0) == SQLITE_TEXT)
4860 {
4861 str = (const char *) sqlite3_column_text (stmt, 0);
4862 len = strlen (str);
4863 name = malloc (len + 1);
4864 strcpy (name, str);
4865 }
4866 if (sqlite3_column_type (stmt, 1) == SQLITE_TEXT)
4867 {
4868 str = (const char *) sqlite3_column_text (stmt, 1);
4869 len = strlen (str);
4870 title = malloc (len + 1);
4871 strcpy (title, str);
4872 }
4873 if (sqlite3_column_type (stmt, 2) == SQLITE_TEXT)
4874 {
4875 str = (const char *) sqlite3_column_text (stmt, 2);
4876 len = strlen (str);
4877 abstract = malloc (len + 1);
4878 strcpy (abstract, str);
4879 }
4880 if (sqlite3_column_type (stmt, 3) == SQLITE_TEXT)
4881 {
4882 ustr = sqlite3_column_text (stmt, 3);
4883 len = strlen ((const char *) ustr);
4884 xml = malloc (len + 1);
4885 strcpy ((char *) xml, (const char *) ustr);
4886 }
4887 }
4888 else
4889 {
4890 fprintf (stderr, "SQL error: %s\n%s\n", sql,
4891 sqlite3_errmsg (handle));
4892 goto error;
4893 }
4894 }
4895 sqlite3_finalize (stmt);
4896 stmt = NULL;
4897
4898 if (name == NULL || xml == NULL)
4899 {
4900 if (name != NULL)
4901 free (name);
4902 if (title != NULL)
4903 free (title);
4904 if (abstract != NULL)
4905 free (abstract);
4906 if (xml != NULL)
4907 free (xml);
4908 goto error;
4909 }
4910
4911 /* final validation */
4912 stl = group_style_from_sld_xml (name, title, abstract, xml);
4913 if (stl == NULL)
4914 goto error;
4915 grp_stl = (rl2PrivGroupStylePtr) stl;
4916 child = grp_stl->first;
4917 while (child != NULL)
4918 {
4919 /* testing NamedLayers and NamedStyles */
4920 if (child->namedLayer != NULL)
4921 {
4922 if (test_named_layer (handle, group, child->namedLayer))
4923 child->validLayer = 1;
4924 }
4925 if (child->validLayer == 1)
4926 {
4927 if (child->namedStyle != NULL)
4928 {
4929 if (strcmp (child->namedStyle, "default") == 0)
4930 child->validStyle = 1;
4931 else if (test_named_style
4932 (handle, child->namedLayer, child->namedStyle))
4933 child->validStyle = 1;
4934 }
4935 else
4936 child->validStyle = 1;
4937 }
4938 child = child->next;
4939 }
4940 grp_stl->valid = 1;
4941 child = grp_stl->first;
4942 while (child != NULL)
4943 {
4944 if (child->validLayer == 0 || child->validStyle == 0)
4945 grp_stl->valid = 0;
4946 child = child->next;
4947 }
4948
4949 return stl;
4950
4951 error:
4952 if (stmt != NULL)
4953 sqlite3_finalize (stmt);
4954 if (stl != NULL)
4955 rl2_destroy_group_style (stl);
4956 return NULL;
4957 }
4958
4959 RL2_DECLARE rl2RasterStatisticsPtr
rl2_create_raster_statistics_from_dbms(sqlite3 * handle,const char * coverage)4960 rl2_create_raster_statistics_from_dbms (sqlite3 * handle, const char *coverage)
4961 {
4962 /* attempting to load a Covrage's RasterStatistics object */
4963 const char *sql;
4964 int ret;
4965 sqlite3_stmt *stmt = NULL;
4966 rl2RasterStatisticsPtr stats = NULL;
4967
4968 sql = "SELECT statistics FROM raster_coverages "
4969 "WHERE Lower(coverage_name) = Lower(?)";
4970 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
4971 if (ret != SQLITE_OK)
4972 {
4973 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
4974 goto error;
4975 }
4976 sqlite3_reset (stmt);
4977 sqlite3_clear_bindings (stmt);
4978 sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
4979 while (1)
4980 {
4981 /* scrolling the result set rows */
4982 ret = sqlite3_step (stmt);
4983 if (ret == SQLITE_DONE)
4984 break; /* end of result set */
4985 if (ret == SQLITE_ROW)
4986 {
4987 if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
4988 {
4989 const unsigned char *blob = sqlite3_column_blob (stmt, 0);
4990 int blob_sz = sqlite3_column_bytes (stmt, 0);
4991 stats =
4992 rl2_deserialize_dbms_raster_statistics (blob,
4993 blob_sz);
4994 }
4995 }
4996 else
4997 {
4998 fprintf (stderr, "SQL error: %s\n%s\n", sql,
4999 sqlite3_errmsg (handle));
5000 goto error;
5001 }
5002 }
5003 sqlite3_finalize (stmt);
5004 return stats;
5005
5006 error:
5007 if (stmt != NULL)
5008 sqlite3_finalize (stmt);
5009 return NULL;
5010 }
5011