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