1 /*
2
3 rl2pyramid -- DBMS Pyramid functions
4
5 version 0.1, 2014 July 13
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 <sys/types.h>
50 #if defined(_WIN32) && !defined(__MINGW32__)
51 #include <io.h>
52 #include <direct.h>
53 #else
54 #include <dirent.h>
55 #endif
56
57 #include "config.h"
58
59 #ifdef LOADABLE_EXTENSION
60 #include "rasterlite2/sqlite.h"
61 #endif
62
63 #include "rasterlite2/rasterlite2.h"
64 #include "rasterlite2/rl2tiff.h"
65 #include "rasterlite2/rl2graphics.h"
66 #include "rasterlite2_private.h"
67
68 #include <spatialite/gaiaaux.h>
69
70 /* 64 bit integer: portable format for printf() */
71 #if defined(_WIN32) && !defined(__MINGW32__)
72 #define ERR_FRMT64 "ERROR: unable to decode Tile ID=%I64d\n"
73 #else
74 #define ERR_FRMT64 "ERROR: unable to decode Tile ID=%lld\n"
75 #endif
76
77 static int
do_insert_pyramid_levels(sqlite3 * handle,int id_level,double res_x,double res_y,sqlite3_stmt * stmt_levl)78 do_insert_pyramid_levels (sqlite3 * handle, int id_level, double res_x,
79 double res_y, sqlite3_stmt * stmt_levl)
80 {
81 /* INSERTing the Pyramid levels */
82 int ret;
83 sqlite3_reset (stmt_levl);
84 sqlite3_clear_bindings (stmt_levl);
85 sqlite3_bind_int (stmt_levl, 1, id_level);
86 sqlite3_bind_double (stmt_levl, 2, res_x);
87 sqlite3_bind_double (stmt_levl, 3, res_y);
88 sqlite3_bind_double (stmt_levl, 4, res_x * 2.0);
89 sqlite3_bind_double (stmt_levl, 5, res_y * 2.0);
90 sqlite3_bind_double (stmt_levl, 6, res_x * 4.0);
91 sqlite3_bind_double (stmt_levl, 7, res_y * 4.0);
92 sqlite3_bind_double (stmt_levl, 8, res_x * 8.0);
93 sqlite3_bind_double (stmt_levl, 9, res_y * 8.0);
94 ret = sqlite3_step (stmt_levl);
95 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
96 ;
97 else
98 {
99 fprintf (stderr,
100 "INSERT INTO levels; sqlite3_step() error: %s\n",
101 sqlite3_errmsg (handle));
102 goto error;
103 }
104 return 1;
105 error:
106 return 0;
107 }
108
109 static int
do_insert_pyramid_tile(sqlite3 * handle,unsigned char * blob_odd,int blob_odd_sz,unsigned char * blob_even,int blob_even_sz,int id_level,sqlite3_int64 section_id,int srid,double minx,double miny,double maxx,double maxy,sqlite3_stmt * stmt_tils,sqlite3_stmt * stmt_data)110 do_insert_pyramid_tile (sqlite3 * handle, unsigned char *blob_odd,
111 int blob_odd_sz, unsigned char *blob_even,
112 int blob_even_sz, int id_level,
113 sqlite3_int64 section_id, int srid, double minx,
114 double miny, double maxx, double maxy,
115 sqlite3_stmt * stmt_tils, sqlite3_stmt * stmt_data)
116 {
117 /* INSERTing a Pyramid tile */
118 int ret;
119 sqlite3_int64 tile_id;
120 unsigned char *blob;
121 int blob_size;
122 gaiaGeomCollPtr geom;
123
124 sqlite3_reset (stmt_tils);
125 sqlite3_clear_bindings (stmt_tils);
126 sqlite3_bind_int (stmt_tils, 1, id_level);
127 if (section_id < 0)
128 sqlite3_bind_null (stmt_tils, 2);
129 else
130 sqlite3_bind_int64 (stmt_tils, 2, section_id);
131 geom = build_extent (srid, minx, miny, maxx, maxy);
132 gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
133 gaiaFreeGeomColl (geom);
134 sqlite3_bind_blob (stmt_tils, 3, blob, blob_size, free);
135 ret = sqlite3_step (stmt_tils);
136 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
137 ;
138 else
139 {
140 fprintf (stderr,
141 "INSERT INTO tiles; sqlite3_step() error: %s\n",
142 sqlite3_errmsg (handle));
143 goto error;
144 }
145 tile_id = sqlite3_last_insert_rowid (handle);
146 /* INSERTing tile data */
147 sqlite3_reset (stmt_data);
148 sqlite3_clear_bindings (stmt_data);
149 sqlite3_bind_int64 (stmt_data, 1, tile_id);
150 sqlite3_bind_blob (stmt_data, 2, blob_odd, blob_odd_sz, free);
151 if (blob_even == NULL)
152 sqlite3_bind_null (stmt_data, 3);
153 else
154 sqlite3_bind_blob (stmt_data, 3, blob_even, blob_even_sz, free);
155 ret = sqlite3_step (stmt_data);
156 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
157 ;
158 else
159 {
160 fprintf (stderr,
161 "INSERT INTO tile_data; sqlite3_step() error: %s\n",
162 sqlite3_errmsg (handle));
163 goto error;
164 }
165 return 1;
166 error:
167 return 0;
168 }
169
170 static int
resolve_section_id(sqlite3 * handle,const char * coverage,const char * section,sqlite3_int64 * sect_id)171 resolve_section_id (sqlite3 * handle, const char *coverage, const char *section,
172 sqlite3_int64 * sect_id)
173 {
174 /* resolving the Section ID by name */
175 char *table;
176 char *xtable;
177 char *sql;
178 sqlite3_stmt *stmt = NULL;
179 int ret;
180 int ok = 0;
181
182 /* Section infos */
183 table = sqlite3_mprintf ("%s_sections", coverage);
184 xtable = gaiaDoubleQuotedSql (table);
185 sqlite3_free (table);
186 sql = sqlite3_mprintf ("SELECT section_id "
187 "FROM \"%s\" WHERE section_name = %Q", xtable,
188 section);
189 free (xtable);
190 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
191 sqlite3_free (sql);
192 if (ret != SQLITE_OK)
193 {
194 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
195 goto error;
196 }
197 while (1)
198 {
199 ret = sqlite3_step (stmt);
200 if (ret == SQLITE_DONE)
201 break;
202 if (ret == SQLITE_ROW)
203 {
204 *sect_id = sqlite3_column_int64 (stmt, 0);
205 ok = 1;
206 }
207 else
208 {
209 fprintf (stderr,
210 "SELECT section_info; sqlite3_step() error: %s\n",
211 sqlite3_errmsg (handle));
212 goto error;
213 }
214 }
215 sqlite3_finalize (stmt);
216 return ok;
217
218 error:
219 if (stmt != NULL)
220 sqlite3_finalize (stmt);
221 return 0;
222 }
223
224 static int
delete_section_pyramid(sqlite3 * handle,const char * coverage,const char * section)225 delete_section_pyramid (sqlite3 * handle, const char *coverage,
226 const char *section)
227 {
228 /* attempting to delete a section pyramid */
229 char *sql;
230 char *table;
231 char *xtable;
232 sqlite3_int64 section_id;
233 char sect_id[1024];
234 int ret;
235 char *err_msg = NULL;
236
237 if (!resolve_section_id (handle, coverage, section, §ion_id))
238 return 0;
239 #if defined(_WIN32) && !defined(__MINGW32__)
240 sprintf (sect_id, "%I64d", section_id);
241 #else
242 sprintf (sect_id, "%lld", section_id);
243 #endif
244
245 table = sqlite3_mprintf ("%s_tiles", coverage);
246 xtable = gaiaDoubleQuotedSql (table);
247 sqlite3_free (table);
248 sql =
249 sqlite3_mprintf
250 ("DELETE FROM \"%s\" WHERE pyramid_level > 0 AND section_id = %s",
251 xtable, sect_id);
252 free (xtable);
253 ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
254 sqlite3_free (sql);
255 if (ret != SQLITE_OK)
256 {
257 fprintf (stderr, "DELETE FROM \"%s_tiles\" error: %s\n", coverage,
258 err_msg);
259 sqlite3_free (err_msg);
260 return 0;
261 }
262 return 1;
263 }
264
265 static int
check_section_pyramid(sqlite3 * handle,const char * coverage,const char * section)266 check_section_pyramid (sqlite3 * handle, const char *coverage,
267 const char *section)
268 {
269 /* checking if a section's pyramid already exists */
270 char *sql;
271 char *table;
272 char *xtable;
273 sqlite3_int64 section_id;
274 char sect_id[1024];
275 sqlite3_stmt *stmt = NULL;
276 int ret;
277 int count = 0;
278
279 if (!resolve_section_id (handle, coverage, section, §ion_id))
280 return 1;
281 #if defined(_WIN32) && !defined(__MINGW32__)
282 sprintf (sect_id, "%I64d", section_id);
283 #else
284 sprintf (sect_id, "%lld", section_id);
285 #endif
286
287 table = sqlite3_mprintf ("%s_tiles", coverage);
288 xtable = gaiaDoubleQuotedSql (table);
289 sqlite3_free (table);
290 sql =
291 sqlite3_mprintf ("SELECT Count(*) FROM \"%s\" "
292 "WHERE section_id = %s AND pyramid_level > 0", xtable,
293 sect_id);
294 free (xtable);
295 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
296 sqlite3_free (sql);
297 if (ret != SQLITE_OK)
298 return 1;
299 while (1)
300 {
301 ret = sqlite3_step (stmt);
302 if (ret == SQLITE_DONE)
303 break;
304 if (ret == SQLITE_ROW)
305 count = sqlite3_column_int (stmt, 0);
306 else
307 {
308 fprintf (stderr,
309 "SELECT pyramid_exists; sqlite3_step() error: %s\n",
310 sqlite3_errmsg (handle));
311 count = 0;
312 break;
313 }
314 }
315 sqlite3_finalize (stmt);
316 if (count == 0)
317 return 1;
318 return 0;
319 }
320
321 static int
get_section_infos(sqlite3 * handle,const char * coverage,const char * section,sqlite3_int64 * sect_id,unsigned int * sect_width,unsigned int * sect_height,double * minx,double * miny,double * maxx,double * maxy,rl2PalettePtr * palette,rl2PixelPtr * no_data)322 get_section_infos (sqlite3 * handle, const char *coverage, const char *section,
323 sqlite3_int64 * sect_id, unsigned int *sect_width,
324 unsigned int *sect_height, double *minx, double *miny,
325 double *maxx, double *maxy, rl2PalettePtr * palette,
326 rl2PixelPtr * no_data)
327 {
328 /* retrieving the Section most relevant infos */
329 char *table;
330 char *xtable;
331 char *sql;
332 sqlite3_stmt *stmt = NULL;
333 int ret;
334 int ok = 0;
335
336 /* Section infos */
337 table = sqlite3_mprintf ("%s_sections", coverage);
338 xtable = gaiaDoubleQuotedSql (table);
339 sqlite3_free (table);
340 sql =
341 sqlite3_mprintf ("SELECT section_id, width, height, MbrMinX(geometry), "
342 "MbrMinY(geometry), MbrMaxX(geometry), MbrMaxY(geometry) "
343 "FROM \"%s\" WHERE section_name = %Q", xtable,
344 section);
345 free (xtable);
346 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
347 sqlite3_free (sql);
348 if (ret != SQLITE_OK)
349 {
350 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
351 goto error;
352 }
353 while (1)
354 {
355 ret = sqlite3_step (stmt);
356 if (ret == SQLITE_DONE)
357 break;
358 if (ret == SQLITE_ROW)
359 {
360 *sect_id = sqlite3_column_int64 (stmt, 0);
361 *sect_width = sqlite3_column_int (stmt, 1);
362 *sect_height = sqlite3_column_int (stmt, 2);
363 *minx = sqlite3_column_double (stmt, 3);
364 *miny = sqlite3_column_double (stmt, 4);
365 *maxx = sqlite3_column_double (stmt, 5);
366 *maxy = sqlite3_column_double (stmt, 6);
367 ok = 1;
368 }
369 else
370 {
371 fprintf (stderr,
372 "SELECT section_info; sqlite3_step() error: %s\n",
373 sqlite3_errmsg (handle));
374 goto error;
375 }
376 }
377 sqlite3_finalize (stmt);
378 if (!ok)
379 goto error;
380
381 /* Coverage's palette and no-data */
382 sql = sqlite3_mprintf ("SELECT palette, nodata_pixel FROM raster_coverages "
383 "WHERE Lower(coverage_name) = Lower(%Q)", coverage);
384 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
385 sqlite3_free (sql);
386 if (ret != SQLITE_OK)
387 {
388 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
389 goto error;
390 }
391 while (1)
392 {
393 ret = sqlite3_step (stmt);
394 if (ret == SQLITE_DONE)
395 break;
396 if (ret == SQLITE_ROW)
397 {
398 if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
399 {
400 const unsigned char *blob = sqlite3_column_blob (stmt, 0);
401 int blob_sz = sqlite3_column_bytes (stmt, 0);
402 *palette = rl2_deserialize_dbms_palette (blob, blob_sz);
403 }
404 if (sqlite3_column_type (stmt, 1) == SQLITE_BLOB)
405 {
406 const unsigned char *blob = sqlite3_column_blob (stmt, 1);
407 int blob_sz = sqlite3_column_bytes (stmt, 1);
408 *no_data = rl2_deserialize_dbms_pixel (blob, blob_sz);
409 }
410 }
411 else
412 {
413 fprintf (stderr,
414 "SELECT section_info; sqlite3_step() error: %s\n",
415 sqlite3_errmsg (handle));
416 goto error;
417 }
418 }
419 sqlite3_finalize (stmt);
420 return 1;
421
422 error:
423 if (stmt != NULL)
424 sqlite3_finalize (stmt);
425 return 0;
426 }
427
428 static SectionPyramidTileInPtr
alloc_section_pyramid_tile(sqlite3_int64 tile_id,double minx,double miny,double maxx,double maxy)429 alloc_section_pyramid_tile (sqlite3_int64 tile_id, double minx, double miny,
430 double maxx, double maxy)
431 {
432 /* allocating a Section Pyramid Tile object */
433 SectionPyramidTileInPtr tile = malloc (sizeof (SectionPyramidTileIn));
434 if (tile == NULL)
435 return NULL;
436 tile->tile_id = tile_id;
437 tile->cx = minx + ((maxx - minx) / 2.0);
438 tile->cy = miny + ((maxy - miny) / 2.0);
439 tile->next = NULL;
440 return tile;
441 }
442
443 static SectionPyramidPtr
alloc_sect_pyramid(sqlite3_int64 sect_id,unsigned int sect_width,unsigned int sect_height,unsigned char sample_type,unsigned char pixel_type,unsigned char num_samples,unsigned char compression,int quality,int srid,double res_x,double res_y,double tile_width,double tile_height,double minx,double miny,double maxx,double maxy,int scale)444 alloc_sect_pyramid (sqlite3_int64 sect_id, unsigned int sect_width,
445 unsigned int sect_height, unsigned char sample_type,
446 unsigned char pixel_type, unsigned char num_samples,
447 unsigned char compression, int quality, int srid,
448 double res_x, double res_y, double tile_width,
449 double tile_height, double minx, double miny, double maxx,
450 double maxy, int scale)
451 {
452 /* allocating a Section Pyramid object */
453 double ext_x = maxx - minx;
454 double ext_y = maxy - miny;
455 SectionPyramidPtr pyr = malloc (sizeof (SectionPyramid));
456 if (pyr == NULL)
457 return NULL;
458 pyr->section_id = sect_id;
459 pyr->scale = scale;
460 pyr->full_width = sect_width;
461 pyr->full_height = sect_height;
462 pyr->sample_type = sample_type;
463 pyr->pixel_type = pixel_type;
464 pyr->num_samples = num_samples;
465 pyr->compression = compression;
466 pyr->quality = quality;
467 pyr->srid = srid;
468 pyr->res_x = res_x;
469 pyr->res_y = res_y;
470 pyr->scaled_width = ext_x / res_x;
471 pyr->scaled_height = ext_y / res_y;
472 pyr->tile_width = tile_width;
473 pyr->tile_height = tile_height;
474 pyr->minx = minx;
475 pyr->miny = miny;
476 pyr->maxx = maxx;
477 pyr->maxy = maxy;
478 pyr->first_in = NULL;
479 pyr->last_in = NULL;
480 pyr->first_out = NULL;
481 pyr->last_out = NULL;
482 return pyr;
483 }
484
485 static void
delete_sect_pyramid(SectionPyramidPtr pyr)486 delete_sect_pyramid (SectionPyramidPtr pyr)
487 {
488 /* memory cleanup - destroying a Section Pyramid object */
489 SectionPyramidTileInPtr tile_in;
490 SectionPyramidTileInPtr tile_in_n;
491 SectionPyramidTileOutPtr tile_out;
492 SectionPyramidTileOutPtr tile_out_n;
493 if (pyr == NULL)
494 return;
495 tile_out = pyr->first_out;
496 while (tile_out != NULL)
497 {
498 SectionPyramidTileRefPtr ref;
499 SectionPyramidTileRefPtr ref_n;
500 tile_out_n = tile_out->next;
501 ref = tile_out->first;
502 while (ref != NULL)
503 {
504 ref_n = ref->next;
505 free (ref);
506 ref = ref_n;
507 }
508 free (tile_out);
509 tile_out = tile_out_n;
510 }
511 tile_in = pyr->first_in;
512 while (tile_in != NULL)
513 {
514 tile_in_n = tile_in->next;
515 free (tile_in);
516 tile_in = tile_in_n;
517 }
518 free (pyr);
519 }
520
521 static int
insert_tile_into_section_pyramid(SectionPyramidPtr pyr,sqlite3_int64 tile_id,double minx,double miny,double maxx,double maxy)522 insert_tile_into_section_pyramid (SectionPyramidPtr pyr, sqlite3_int64 tile_id,
523 double minx, double miny, double maxx,
524 double maxy)
525 {
526 /* inserting a base tile into the Pyramid level */
527 SectionPyramidTileInPtr tile;
528 if (pyr == NULL)
529 return 0;
530 tile = alloc_section_pyramid_tile (tile_id, minx, miny, maxx, maxy);
531 if (tile == NULL)
532 return 0;
533 if (pyr->first_in == NULL)
534 pyr->first_in = tile;
535 if (pyr->last_in != NULL)
536 pyr->last_in->next = tile;
537 pyr->last_in = tile;
538 return 1;
539 }
540
541 static SectionPyramidTileOutPtr
add_pyramid_out_tile(SectionPyramidPtr pyr,unsigned int row,unsigned int col,double minx,double miny,double maxx,double maxy)542 add_pyramid_out_tile (SectionPyramidPtr pyr, unsigned int row,
543 unsigned int col, double minx, double miny, double maxx,
544 double maxy)
545 {
546 /* inserting a Parent tile (output) */
547 SectionPyramidTileOutPtr tile;
548 if (pyr == NULL)
549 return NULL;
550 tile = malloc (sizeof (SectionPyramidTileOut));
551 if (tile == NULL)
552 return NULL;
553 tile->row = row;
554 tile->col = col;
555 tile->minx = minx;
556 tile->miny = miny;
557 tile->maxx = maxx;
558 tile->maxy = maxy;
559 tile->first = NULL;
560 tile->last = NULL;
561 tile->next = NULL;
562 if (pyr->first_out == NULL)
563 pyr->first_out = tile;
564 if (pyr->last_out != NULL)
565 pyr->last_out->next = tile;
566 pyr->last_out = tile;
567 return tile;
568 }
569
570 static void
add_pyramid_sub_tile(SectionPyramidTileOutPtr parent,SectionPyramidTileInPtr child)571 add_pyramid_sub_tile (SectionPyramidTileOutPtr parent,
572 SectionPyramidTileInPtr child)
573 {
574 /* inserting a Child tile (input) */
575 SectionPyramidTileRefPtr ref;
576 if (parent == NULL)
577 return;
578 ref = malloc (sizeof (SectionPyramidTileRef));
579 if (ref == NULL)
580 return;
581 ref->child = child;
582 ref->next = NULL;
583 if (parent->first == NULL)
584 parent->first = ref;
585 if (parent->last != NULL)
586 parent->last->next = ref;
587 parent->last = ref;
588 }
589
590 static void
set_pyramid_tile_destination(SectionPyramidPtr pyr,double minx,double miny,double maxx,double maxy,unsigned int row,unsigned int col)591 set_pyramid_tile_destination (SectionPyramidPtr pyr, double minx, double miny,
592 double maxx, double maxy, unsigned int row,
593 unsigned int col)
594 {
595 /* aggregating lower level tiles */
596 int first = 1;
597 SectionPyramidTileOutPtr out = NULL;
598 SectionPyramidTileInPtr tile = pyr->first_in;
599 while (tile != NULL)
600 {
601 if (tile->cx > minx && tile->cx < maxx && tile->cy > miny
602 && tile->cy < maxy)
603 {
604 if (first)
605 {
606 out =
607 add_pyramid_out_tile (pyr, row, col, minx, miny, maxx,
608 maxy);
609 first = 0;
610 }
611 if (out != NULL)
612 add_pyramid_sub_tile (out, tile);
613 }
614 tile = tile->next;
615 }
616 }
617
618 static unsigned char *
load_tile_base(sqlite3_stmt * stmt,sqlite3_int64 tile_id,rl2PalettePtr palette,rl2PixelPtr no_data)619 load_tile_base (sqlite3_stmt * stmt, sqlite3_int64 tile_id,
620 rl2PalettePtr palette, rl2PixelPtr no_data)
621 {
622 /* attempting to read a lower-level tile */
623 int ret;
624 const unsigned char *blob_odd = NULL;
625 int blob_odd_sz = 0;
626 const unsigned char *blob_even = NULL;
627 int blob_even_sz = 0;
628 rl2RasterPtr raster = NULL;
629 rl2PalettePtr plt = NULL;
630 unsigned char *rgba_tile = NULL;
631 int rgba_sz;
632 rl2PixelPtr nd;
633
634 sqlite3_reset (stmt);
635 sqlite3_clear_bindings (stmt);
636 sqlite3_bind_int64 (stmt, 1, tile_id);
637 while (1)
638 {
639 /* scrolling the result set rows */
640 ret = sqlite3_step (stmt);
641 if (ret == SQLITE_DONE)
642 break; /* end of result set */
643 if (ret == SQLITE_ROW)
644 {
645 if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
646 {
647 blob_odd = sqlite3_column_blob (stmt, 0);
648 blob_odd_sz = sqlite3_column_bytes (stmt, 0);
649 }
650 if (sqlite3_column_type (stmt, 1) == SQLITE_BLOB)
651 {
652 blob_even = sqlite3_column_blob (stmt, 1);
653 blob_even_sz = sqlite3_column_bytes (stmt, 1);
654 }
655 plt = rl2_clone_palette (palette);
656 raster =
657 rl2_raster_decode (RL2_SCALE_1, blob_odd, blob_odd_sz,
658 blob_even, blob_even_sz, plt);
659 if (raster == NULL)
660 {
661 fprintf (stderr, ERR_FRMT64, tile_id);
662 return NULL;
663 }
664 nd = rl2_clone_pixel (no_data);
665 rl2_set_raster_no_data (raster, nd);
666 if (rl2_raster_data_to_RGBA (raster, &rgba_tile, &rgba_sz) !=
667 RL2_OK)
668 rgba_tile = NULL;
669 rl2_destroy_raster (raster);
670 break;
671 }
672 else
673 return NULL;
674 }
675 return rgba_tile;
676 }
677
678 static rl2RasterPtr
load_tile_base_generic(sqlite3_stmt * stmt,sqlite3_int64 tile_id)679 load_tile_base_generic (sqlite3_stmt * stmt, sqlite3_int64 tile_id)
680 {
681 /* attempting to read a lower-level tile */
682 int ret;
683 const unsigned char *blob_odd = NULL;
684 int blob_odd_sz = 0;
685 const unsigned char *blob_even = NULL;
686 int blob_even_sz = 0;
687 rl2RasterPtr raster = NULL;
688
689 sqlite3_reset (stmt);
690 sqlite3_clear_bindings (stmt);
691 sqlite3_bind_int64 (stmt, 1, tile_id);
692 while (1)
693 {
694 /* scrolling the result set rows */
695 ret = sqlite3_step (stmt);
696 if (ret == SQLITE_DONE)
697 break; /* end of result set */
698 if (ret == SQLITE_ROW)
699 {
700 if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
701 {
702 blob_odd = sqlite3_column_blob (stmt, 0);
703 blob_odd_sz = sqlite3_column_bytes (stmt, 0);
704 }
705 if (sqlite3_column_type (stmt, 1) == SQLITE_BLOB)
706 {
707 blob_even = sqlite3_column_blob (stmt, 1);
708 blob_even_sz = sqlite3_column_bytes (stmt, 1);
709 }
710 raster =
711 rl2_raster_decode (RL2_SCALE_1, blob_odd, blob_odd_sz,
712 blob_even, blob_even_sz, NULL);
713 if (raster == NULL)
714 {
715 fprintf (stderr, ERR_FRMT64, tile_id);
716 return NULL;
717 }
718 return raster;
719 }
720 }
721 return NULL;
722 }
723
724 static double
rescale_pixel_int8(const char * buf_in,unsigned int tileWidth,unsigned int tileHeight,int x,int y,char nd)725 rescale_pixel_int8 (const char *buf_in, unsigned int tileWidth,
726 unsigned int tileHeight, int x, int y, char nd)
727 {
728 /* rescaling a DataGrid pixel (8x8) - INT8 */
729 unsigned int row;
730 unsigned int col;
731 int nodata = 0;
732 int valid = 0;
733 double sum = 0.0;
734
735 for (row = 0; row < 8; row++)
736 {
737 const char *p_in_base;
738 unsigned int yy = y + row;
739 if (yy >= tileHeight)
740 break;
741 p_in_base = buf_in + (yy * tileWidth);
742 for (col = 0; col < 8; col++)
743 {
744 const char *p_in;
745 unsigned int xx = x + col;
746 if (xx >= tileWidth)
747 break;
748 p_in = p_in_base + x;
749 if (*p_in == nd)
750 nodata++;
751 else
752 {
753 valid++;
754 sum += *p_in;
755 }
756 }
757 }
758
759 if (nodata >= valid)
760 return nd;
761 return (char) (sum / (double) valid);
762 }
763
764 static void
rescale_grid_int8(char * buf_out,unsigned int tileWidth,unsigned int tileHeight,const char * buf_in,int x,int y,int tic_x,int tic_y,rl2PixelPtr no_data)765 rescale_grid_int8 (char *buf_out, unsigned int tileWidth,
766 unsigned int tileHeight, const char *buf_in, int x, int y,
767 int tic_x, int tic_y, rl2PixelPtr no_data)
768 {
769 /* rescaling a DataGrid tile - int 8 bit */
770 unsigned int row;
771 unsigned int col;
772 char nd = 0;
773 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) no_data;
774
775 if (pxl != NULL)
776 {
777 /* retrieving the NO-DATA value */
778 if (pxl->sampleType == RL2_SAMPLE_INT8 && pxl->nBands == 1)
779 {
780 rl2PrivSamplePtr sample = pxl->Samples + 0;
781 nd = sample->int8;
782 }
783 }
784
785 for (row = 0; row < (unsigned) tic_y; row++)
786 {
787 unsigned int yy = row + y;
788 char *p_out_base = buf_out + (yy * tileWidth);
789 if (yy >= tileHeight)
790 break;
791 for (col = 0; col < (unsigned int) tic_x; col++)
792 {
793 unsigned int xx = col + x;
794 char *p_out = p_out_base + xx;
795 if (xx >= tileWidth)
796 break;
797 *p_out =
798 rescale_pixel_int8 (buf_in, tileWidth, tileHeight, col * 8,
799 row * 8, nd);
800 }
801 }
802 }
803
804 static double
rescale_pixel_uint8(const unsigned char * buf_in,unsigned int tileWidth,unsigned int tileHeight,int x,int y,unsigned char nd)805 rescale_pixel_uint8 (const unsigned char *buf_in, unsigned int tileWidth,
806 unsigned int tileHeight, int x, int y, unsigned char nd)
807 {
808 /* rescaling a DataGrid pixel (8x8) - UINT8 */
809 unsigned int row;
810 unsigned int col;
811 int nodata = 0;
812 int valid = 0;
813 double sum = 0.0;
814
815 for (row = 0; row < 8; row++)
816 {
817 const unsigned char *p_in_base;
818 unsigned int yy = y + row;
819 if (yy >= tileHeight)
820 break;
821 p_in_base = buf_in + (yy * tileWidth);
822 for (col = 0; col < 8; col++)
823 {
824 const unsigned char *p_in;
825 unsigned int xx = x + col;
826 if (xx >= tileWidth)
827 break;
828 p_in = p_in_base + x;
829 if (*p_in == nd)
830 nodata++;
831 else
832 {
833 valid++;
834 sum += *p_in;
835 }
836 }
837 }
838
839 if (nodata >= valid)
840 return nd;
841 return (unsigned char) (sum / (double) valid);
842 }
843
844 static void
rescale_grid_uint8(unsigned char * buf_out,unsigned int tileWidth,unsigned int tileHeight,const unsigned char * buf_in,int x,int y,int tic_x,int tic_y,rl2PixelPtr no_data)845 rescale_grid_uint8 (unsigned char *buf_out, unsigned int tileWidth,
846 unsigned int tileHeight, const unsigned char *buf_in,
847 int x, int y, int tic_x, int tic_y, rl2PixelPtr no_data)
848 {
849 /* rescaling a DataGrid tile - unsigned int 8 bit */
850 unsigned int row;
851 unsigned int col;
852 unsigned char nd = 0;
853 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) no_data;
854
855 if (pxl != NULL)
856 {
857 /* retrieving the NO-DATA value */
858 if (pxl->sampleType == RL2_SAMPLE_UINT8 && pxl->nBands == 1)
859 {
860 rl2PrivSamplePtr sample = pxl->Samples + 0;
861 nd = sample->uint8;
862 }
863 }
864
865 for (row = 0; row < (unsigned int) tic_y; row++)
866 {
867 unsigned int yy = row + y;
868 unsigned char *p_out_base = buf_out + (yy * tileWidth);
869 if (yy >= tileHeight)
870 break;
871 for (col = 0; col < (unsigned int) tic_x; col++)
872 {
873 unsigned int xx = col + x;
874 unsigned char *p_out = p_out_base + xx;
875 if (xx >= tileWidth)
876 break;
877 *p_out =
878 rescale_pixel_uint8 (buf_in, tileWidth, tileHeight, col * 8,
879 row * 8, nd);
880 }
881 }
882 }
883
884 static double
rescale_pixel_int16(const short * buf_in,unsigned int tileWidth,unsigned int tileHeight,int x,int y,short nd)885 rescale_pixel_int16 (const short *buf_in, unsigned int tileWidth,
886 unsigned int tileHeight, int x, int y, short nd)
887 {
888 /* rescaling a DataGrid pixel (8x8) - INT32 */
889 unsigned int row;
890 unsigned int col;
891 int nodata = 0;
892 int valid = 0;
893 double sum = 0.0;
894
895 for (row = 0; row < 8; row++)
896 {
897 const short *p_in_base;
898 unsigned int yy = y + row;
899 if (yy >= tileHeight)
900 break;
901 p_in_base = buf_in + (yy * tileWidth);
902 for (col = 0; col < 8; col++)
903 {
904 const short *p_in;
905 unsigned int xx = x + col;
906 if (xx >= tileWidth)
907 break;
908 p_in = p_in_base + x;
909 if (*p_in == nd)
910 nodata++;
911 else
912 {
913 valid++;
914 sum += *p_in;
915 }
916 }
917 }
918
919 if (nodata >= valid)
920 return nd;
921 return (short) (sum / (double) valid);
922 }
923
924 static void
rescale_grid_int16(short * buf_out,unsigned int tileWidth,unsigned int tileHeight,const short * buf_in,int x,int y,int tic_x,int tic_y,rl2PixelPtr no_data)925 rescale_grid_int16 (short *buf_out, unsigned int tileWidth,
926 unsigned int tileHeight, const short *buf_in, int x,
927 int y, int tic_x, int tic_y, rl2PixelPtr no_data)
928 {
929 /* rescaling a DataGrid tile - int 16 bit */
930 unsigned int row;
931 unsigned int col;
932 short nd = 0;
933 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) no_data;
934
935 if (pxl != NULL)
936 {
937 /* retrieving the NO-DATA value */
938 if (pxl->sampleType == RL2_SAMPLE_INT16 && pxl->nBands == 1)
939 {
940 rl2PrivSamplePtr sample = pxl->Samples + 0;
941 nd = sample->int16;
942 }
943 }
944
945 for (row = 0; row < (unsigned int) tic_y; row++)
946 {
947 unsigned int yy = row + y;
948 short *p_out_base = buf_out + (yy * tileWidth);
949 if (yy >= tileHeight)
950 break;
951 for (col = 0; col < (unsigned int) tic_x; col++)
952 {
953 unsigned int xx = col + x;
954 short *p_out = p_out_base + xx;
955 if (xx >= tileWidth)
956 break;
957 *p_out =
958 rescale_pixel_int16 (buf_in, tileWidth, tileHeight, col * 8,
959 row * 8, nd);
960 }
961 }
962 }
963
964 static double
rescale_pixel_uint16(const unsigned short * buf_in,unsigned int tileWidth,unsigned int tileHeight,int x,int y,unsigned short nd)965 rescale_pixel_uint16 (const unsigned short *buf_in, unsigned int tileWidth,
966 unsigned int tileHeight, int x, int y, unsigned short nd)
967 {
968 /* rescaling a DataGrid pixel (8x8) - UINT16 */
969 unsigned int row;
970 unsigned int col;
971 int nodata = 0;
972 int valid = 0;
973 double sum = 0.0;
974
975 for (row = 0; row < 8; row++)
976 {
977 const unsigned short *p_in_base;
978 unsigned int yy = y + row;
979 if (yy >= tileHeight)
980 break;
981 p_in_base = buf_in + (yy * tileWidth);
982 for (col = 0; col < 8; col++)
983 {
984 const unsigned short *p_in;
985 unsigned int xx = x + col;
986 if (xx >= tileWidth)
987 break;
988 p_in = p_in_base + x;
989 if (*p_in == nd)
990 nodata++;
991 else
992 {
993 valid++;
994 sum += *p_in;
995 }
996 }
997 }
998
999 if (nodata >= valid)
1000 return nd;
1001 return (unsigned short) (sum / (double) valid);
1002 }
1003
1004 static void
rescale_grid_uint16(unsigned short * buf_out,unsigned int tileWidth,unsigned int tileHeight,const unsigned short * buf_in,int x,int y,int tic_x,int tic_y,rl2PixelPtr no_data)1005 rescale_grid_uint16 (unsigned short *buf_out, unsigned int tileWidth,
1006 unsigned int tileHeight, const unsigned short *buf_in,
1007 int x, int y, int tic_x, int tic_y, rl2PixelPtr no_data)
1008 {
1009 /* rescaling a DataGrid tile - unsigned int 16 bit */
1010 unsigned int row;
1011 unsigned int col;
1012 unsigned short nd = 0;
1013 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) no_data;
1014
1015 if (pxl != NULL)
1016 {
1017 /* retrieving the NO-DATA value */
1018 if (pxl->sampleType == RL2_SAMPLE_UINT16 && pxl->nBands == 1)
1019 {
1020 rl2PrivSamplePtr sample = pxl->Samples + 0;
1021 nd = sample->uint16;
1022 }
1023 }
1024
1025 for (row = 0; row < (unsigned int) tic_y; row++)
1026 {
1027 unsigned int yy = row + y;
1028 unsigned short *p_out_base = buf_out + (yy * tileWidth);
1029 if (yy >= tileHeight)
1030 break;
1031 for (col = 0; col < (unsigned int) tic_x; col++)
1032 {
1033 unsigned int xx = col + x;
1034 unsigned short *p_out = p_out_base + xx;
1035 if (xx >= tileWidth)
1036 break;
1037 *p_out =
1038 rescale_pixel_uint16 (buf_in, tileWidth, tileHeight,
1039 col * 8, row * 8, nd);
1040 }
1041 }
1042 }
1043
1044 static double
rescale_pixel_int32(const int * buf_in,unsigned int tileWidth,unsigned int tileHeight,int x,int y,int nd)1045 rescale_pixel_int32 (const int *buf_in, unsigned int tileWidth,
1046 unsigned int tileHeight, int x, int y, int nd)
1047 {
1048 /* rescaling a DataGrid pixel (8x8) - INT32 */
1049 unsigned int row;
1050 unsigned int col;
1051 int nodata = 0;
1052 int valid = 0;
1053 double sum = 0.0;
1054
1055 for (row = 0; row < 8; row++)
1056 {
1057 const int *p_in_base;
1058 unsigned int yy = y + row;
1059 if (yy >= tileHeight)
1060 break;
1061 p_in_base = buf_in + (yy * tileWidth);
1062 for (col = 0; col < 8; col++)
1063 {
1064 const int *p_in;
1065 unsigned int xx = x + col;
1066 if (xx >= tileWidth)
1067 break;
1068 p_in = p_in_base + x;
1069 if (*p_in == nd)
1070 nodata++;
1071 else
1072 {
1073 valid++;
1074 sum += *p_in;
1075 }
1076 }
1077 }
1078
1079 if (nodata >= valid)
1080 return nd;
1081 return (int) (sum / (double) valid);
1082 }
1083
1084 static void
rescale_grid_int32(int * buf_out,unsigned int tileWidth,unsigned int tileHeight,const int * buf_in,int x,int y,int tic_x,int tic_y,rl2PixelPtr no_data)1085 rescale_grid_int32 (int *buf_out, unsigned int tileWidth,
1086 unsigned int tileHeight, const int *buf_in, int x, int y,
1087 int tic_x, int tic_y, rl2PixelPtr no_data)
1088 {
1089 /* rescaling a DataGrid tile - int 32 bit */
1090 unsigned int row;
1091 unsigned int col;
1092 int nd = 0;
1093 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) no_data;
1094
1095 if (pxl != NULL)
1096 {
1097 /* retrieving the NO-DATA value */
1098 if (pxl->sampleType == RL2_SAMPLE_INT32 && pxl->nBands == 1)
1099 {
1100 rl2PrivSamplePtr sample = pxl->Samples + 0;
1101 nd = sample->int32;
1102 }
1103 }
1104
1105 for (row = 0; row < (unsigned int) tic_y; row++)
1106 {
1107 unsigned int yy = row + y;
1108 int *p_out_base = buf_out + (yy * tileWidth);
1109 if (yy >= tileHeight)
1110 break;
1111 for (col = 0; col < (unsigned int) tic_x; col++)
1112 {
1113 unsigned int xx = col + x;
1114 int *p_out = p_out_base + xx;
1115 if (xx >= tileWidth)
1116 break;
1117 *p_out =
1118 rescale_pixel_int32 (buf_in, tileWidth, tileHeight, col * 8,
1119 row * 8, nd);
1120 }
1121 }
1122 }
1123
1124 static double
rescale_pixel_uint32(const unsigned int * buf_in,unsigned int tileWidth,unsigned int tileHeight,int x,int y,unsigned int nd)1125 rescale_pixel_uint32 (const unsigned int *buf_in, unsigned int tileWidth,
1126 unsigned int tileHeight, int x, int y, unsigned int nd)
1127 {
1128 /* rescaling a DataGrid pixel (8x8) - UINT32 */
1129 unsigned int row;
1130 unsigned int col;
1131 int nodata = 0;
1132 int valid = 0;
1133 double sum = 0.0;
1134
1135 for (row = 0; row < 8; row++)
1136 {
1137 const unsigned int *p_in_base;
1138 unsigned int yy = y + row;
1139 if (yy >= tileHeight)
1140 break;
1141 p_in_base = buf_in + (yy * tileWidth);
1142 for (col = 0; col < 8; col++)
1143 {
1144 const unsigned int *p_in;
1145 unsigned int xx = x + col;
1146 if (xx >= tileWidth)
1147 break;
1148 p_in = p_in_base + x;
1149 if (*p_in == nd)
1150 nodata++;
1151 else
1152 {
1153 valid++;
1154 sum += *p_in;
1155 }
1156 }
1157 }
1158
1159 if (nodata >= valid)
1160 return nd;
1161 return (unsigned int) (sum / (double) valid);
1162 }
1163
1164 static void
rescale_grid_uint32(unsigned int * buf_out,unsigned int tileWidth,unsigned int tileHeight,const unsigned int * buf_in,int x,int y,int tic_x,int tic_y,rl2PixelPtr no_data)1165 rescale_grid_uint32 (unsigned int *buf_out, unsigned int tileWidth,
1166 unsigned int tileHeight, const unsigned int *buf_in,
1167 int x, int y, int tic_x, int tic_y, rl2PixelPtr no_data)
1168 {
1169 /* rescaling a DataGrid tile - unsigned int 32 bit */
1170 unsigned int row;
1171 unsigned int col;
1172 unsigned int nd = 0;
1173 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) no_data;
1174
1175 if (pxl != NULL)
1176 {
1177 /* retrieving the NO-DATA value */
1178 if (pxl->sampleType == RL2_SAMPLE_UINT32 && pxl->nBands == 1)
1179 {
1180 rl2PrivSamplePtr sample = pxl->Samples + 0;
1181 nd = sample->uint32;
1182 }
1183 }
1184
1185 for (row = 0; row < (unsigned int) tic_y; row++)
1186 {
1187 unsigned int yy = row + y;
1188 unsigned int *p_out_base = buf_out + (yy * tileWidth);
1189 if (yy >= tileHeight)
1190 break;
1191 for (col = 0; col < (unsigned int) tic_x; col++)
1192 {
1193 unsigned int xx = col + x;
1194 unsigned int *p_out = p_out_base + xx;
1195 if (xx >= tileWidth)
1196 break;
1197 *p_out =
1198 rescale_pixel_uint32 (buf_in, tileWidth, tileHeight,
1199 col * 8, row * 8, nd);
1200 }
1201 }
1202 }
1203
1204 static double
rescale_pixel_float(const float * buf_in,unsigned int tileWidth,unsigned int tileHeight,int x,int y,float nd)1205 rescale_pixel_float (const float *buf_in, unsigned int tileWidth,
1206 unsigned int tileHeight, int x, int y, float nd)
1207 {
1208 /* rescaling a DataGrid pixel (8x8) - Float */
1209 unsigned int row;
1210 unsigned int col;
1211 int nodata = 0;
1212 int valid = 0;
1213 double sum = 0.0;
1214
1215 for (row = 0; row < 8; row++)
1216 {
1217 const float *p_in_base;
1218 unsigned int yy = y + row;
1219 if (yy >= tileHeight)
1220 break;
1221 p_in_base = buf_in + (yy * tileWidth);
1222 for (col = 0; col < 8; col++)
1223 {
1224 const float *p_in;
1225 unsigned int xx = x + col;
1226 if (xx >= tileWidth)
1227 break;
1228 p_in = p_in_base + x;
1229 if (*p_in == nd)
1230 nodata++;
1231 else
1232 {
1233 valid++;
1234 sum += *p_in;
1235 }
1236 }
1237 }
1238
1239 if (nodata >= valid)
1240 return nd;
1241 return (float) (sum / (double) valid);
1242 }
1243
1244 static void
rescale_grid_float(float * buf_out,unsigned int tileWidth,unsigned int tileHeight,const float * buf_in,int x,int y,int tic_x,int tic_y,rl2PixelPtr no_data)1245 rescale_grid_float (float *buf_out, unsigned int tileWidth,
1246 unsigned int tileHeight, const float *buf_in, int x,
1247 int y, int tic_x, int tic_y, rl2PixelPtr no_data)
1248 {
1249 /* rescaling a DataGrid tile - Float */
1250 unsigned int row;
1251 unsigned int col;
1252 float nd = 0.0;
1253 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) no_data;
1254
1255 if (pxl != NULL)
1256 {
1257 /* retrieving the NO-DATA value */
1258 if (pxl->sampleType == RL2_SAMPLE_FLOAT && pxl->nBands == 1)
1259 {
1260 rl2PrivSamplePtr sample = pxl->Samples + 0;
1261 nd = sample->float32;
1262 }
1263 }
1264
1265 for (row = 0; row < (unsigned int) tic_y; row++)
1266 {
1267 unsigned int yy = row + y;
1268 float *p_out_base = buf_out + (yy * tileWidth);
1269 if (yy >= tileHeight)
1270 break;
1271 for (col = 0; col < (unsigned int) tic_x; col++)
1272 {
1273 unsigned int xx = col + x;
1274 float *p_out = p_out_base + xx;
1275 if (xx >= tileWidth)
1276 break;
1277 *p_out =
1278 rescale_pixel_float (buf_in, tileWidth, tileHeight, col * 8,
1279 row * 8, nd);
1280 }
1281 }
1282 }
1283
1284 static double
rescale_pixel_double(const double * buf_in,unsigned int tileWidth,unsigned int tileHeight,int x,int y,double nd)1285 rescale_pixel_double (const double *buf_in, unsigned int tileWidth,
1286 unsigned int tileHeight, int x, int y, double nd)
1287 {
1288 /* rescaling a DataGrid pixel (8x8) - Double */
1289 unsigned int row;
1290 unsigned int col;
1291 int nodata = 0;
1292 int valid = 0;
1293 double sum = 0.0;
1294
1295 for (row = 0; row < 8; row++)
1296 {
1297 const double *p_in_base;
1298 unsigned int yy = y + row;
1299 if (yy >= tileHeight)
1300 break;
1301 p_in_base = buf_in + (yy * tileWidth);
1302 for (col = 0; col < 8; col++)
1303 {
1304 const double *p_in;
1305 unsigned int xx = x + col;
1306 if (xx >= tileWidth)
1307 break;
1308 p_in = p_in_base + x;
1309 if (*p_in == nd)
1310 nodata++;
1311 else
1312 {
1313 valid++;
1314 sum += *p_in;
1315 }
1316 }
1317 }
1318
1319 if (nodata >= valid)
1320 return nd;
1321 return sum / (double) valid;
1322 }
1323
1324 static void
rescale_grid_double(double * buf_out,unsigned int tileWidth,unsigned int tileHeight,const double * buf_in,int x,int y,int tic_x,int tic_y,rl2PixelPtr no_data)1325 rescale_grid_double (double *buf_out, unsigned int tileWidth,
1326 unsigned int tileHeight, const double *buf_in, int x,
1327 int y, int tic_x, int tic_y, rl2PixelPtr no_data)
1328 {
1329 /* rescaling a DataGrid tile - Double */
1330 unsigned int row;
1331 unsigned int col;
1332 double nd = 0.0;
1333 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) no_data;
1334
1335 if (pxl != NULL)
1336 {
1337 /* retrieving the NO-DATA value */
1338 if (pxl->sampleType == RL2_SAMPLE_DOUBLE && pxl->nBands == 1)
1339 {
1340 rl2PrivSamplePtr sample = pxl->Samples + 0;
1341 nd = sample->float64;
1342 }
1343 }
1344
1345 for (row = 0; row < (unsigned int) tic_y; row++)
1346 {
1347 unsigned int yy = row + y;
1348 double *p_out_base = buf_out + (yy * tileWidth);
1349 if (yy >= tileHeight)
1350 break;
1351 for (col = 0; col < (unsigned int) tic_x; col++)
1352 {
1353 unsigned int xx = col + x;
1354 double *p_out = p_out_base + xx;
1355 if (xx >= tileWidth)
1356 break;
1357 *p_out =
1358 rescale_pixel_double (buf_in, tileWidth, tileHeight,
1359 col * 8, row * 8, nd);
1360 }
1361 }
1362 }
1363
1364 static void
rescale_grid(void * buf_out,unsigned int tileWidth,unsigned int tileHeight,const void * buf_in,unsigned char sample_type,int x,int y,int tic_x,int tic_y,rl2PixelPtr no_data)1365 rescale_grid (void *buf_out, unsigned int tileWidth,
1366 unsigned int tileHeight, const void *buf_in,
1367 unsigned char sample_type, int x, int y, int tic_x, int tic_y,
1368 rl2PixelPtr no_data)
1369 {
1370 /* rescaling a DataGrid tile */
1371 switch (sample_type)
1372 {
1373 case RL2_SAMPLE_INT8:
1374 rescale_grid_int8 ((char *) buf_out, tileWidth, tileHeight,
1375 (const char *) buf_in, x, y, tic_x, tic_y,
1376 no_data);
1377 break;
1378 case RL2_SAMPLE_UINT8:
1379 rescale_grid_uint8 ((unsigned char *) buf_out, tileWidth, tileHeight,
1380 (const unsigned char *) buf_in, x, y, tic_x,
1381 tic_y, no_data);
1382 break;
1383 case RL2_SAMPLE_INT16:
1384 rescale_grid_int16 ((short *) buf_out, tileWidth, tileHeight,
1385 (const short *) buf_in, x, y, tic_x, tic_y,
1386 no_data);
1387 break;
1388 case RL2_SAMPLE_UINT16:
1389 rescale_grid_uint16 ((unsigned short *) buf_out, tileWidth,
1390 tileHeight, (const unsigned short *) buf_in, x,
1391 y, tic_x, tic_y, no_data);
1392 break;
1393 case RL2_SAMPLE_INT32:
1394 rescale_grid_int32 ((int *) buf_out, tileWidth, tileHeight,
1395 (const int *) buf_in, x, y, tic_x, tic_y,
1396 no_data);
1397 break;
1398 case RL2_SAMPLE_UINT32:
1399 rescale_grid_uint32 ((unsigned int *) buf_out, tileWidth, tileHeight,
1400 (const unsigned int *) buf_in, x, y, tic_x,
1401 tic_y, no_data);
1402 break;
1403 case RL2_SAMPLE_FLOAT:
1404 rescale_grid_float ((float *) buf_out, tileWidth, tileHeight,
1405 (const float *) buf_in, x, y, tic_x, tic_y,
1406 no_data);
1407 break;
1408 case RL2_SAMPLE_DOUBLE:
1409 rescale_grid_double ((double *) buf_out, tileWidth, tileHeight,
1410 (const double *) buf_in, x, y, tic_x, tic_y,
1411 no_data);
1412 break;
1413 };
1414 }
1415
1416 static int
update_sect_pyramid_grid(sqlite3 * handle,sqlite3_stmt * stmt_rd,sqlite3_stmt * stmt_tils,sqlite3_stmt * stmt_data,SectionPyramid * pyr,unsigned int tileWidth,unsigned int tileHeight,int id_level,rl2PixelPtr no_data,unsigned char sample_type)1417 update_sect_pyramid_grid (sqlite3 * handle, sqlite3_stmt * stmt_rd,
1418 sqlite3_stmt * stmt_tils, sqlite3_stmt * stmt_data,
1419 SectionPyramid * pyr, unsigned int tileWidth,
1420 unsigned int tileHeight, int id_level,
1421 rl2PixelPtr no_data, unsigned char sample_type)
1422 {
1423 /* creating and inserting Pyramid tiles */
1424 unsigned char *buf_out = NULL;
1425 unsigned char *mask = NULL;
1426 SectionPyramidTileOutPtr tile_out;
1427 SectionPyramidTileRefPtr tile_in;
1428 unsigned int x;
1429 unsigned int y;
1430 unsigned int row;
1431 unsigned int col;
1432 int tic_x;
1433 int tic_y;
1434 double pos_y;
1435 double pos_x;
1436 double geo_x;
1437 double geo_y;
1438 rl2PixelPtr nd = NULL;
1439 rl2RasterPtr raster_out = NULL;
1440 rl2RasterPtr raster_in = NULL;
1441 unsigned char *blob_odd;
1442 int blob_odd_sz;
1443 unsigned char *blob_even;
1444 int blob_even_sz;
1445 int pixel_sz = 1;
1446 int out_sz;
1447 int mask_sz = 0;
1448
1449 if (pyr == NULL)
1450 goto error;
1451 tic_x = tileWidth / pyr->scale;
1452 tic_y = tileHeight / pyr->scale;
1453 geo_x = (double) tic_x *pyr->res_x;
1454 geo_y = (double) tic_y *pyr->res_y;
1455
1456 switch (sample_type)
1457 {
1458 case RL2_SAMPLE_INT16:
1459 case RL2_SAMPLE_UINT16:
1460 pixel_sz = 2;
1461 break;
1462 case RL2_SAMPLE_INT32:
1463 case RL2_SAMPLE_UINT32:
1464 case RL2_SAMPLE_FLOAT:
1465 pixel_sz = 4;
1466 break;
1467 case RL2_SAMPLE_DOUBLE:
1468 pixel_sz = 8;
1469 break;
1470 };
1471 out_sz = tileWidth * tileHeight * pixel_sz;
1472
1473 tile_out = pyr->first_out;
1474 while (tile_out != NULL)
1475 {
1476 rl2PrivRasterPtr rst;
1477 /* allocating the output buffer */
1478 buf_out = malloc (out_sz);
1479 if (buf_out == NULL)
1480 goto error;
1481 rl2_prime_void_tile (buf_out, tileWidth, tileHeight, sample_type, 1,
1482 no_data);
1483
1484 if (tile_out->col + tileWidth > pyr->scaled_width
1485 || tile_out->row + tileHeight > pyr->scaled_height)
1486 {
1487 /* allocating and initializing a transparency mask */
1488 unsigned char *p;
1489 mask_sz = tileWidth * tileHeight;
1490 mask = malloc (mask_sz);
1491 if (mask == NULL)
1492 goto error;
1493 p = mask;
1494 for (row = 0; row < tileHeight; row++)
1495 {
1496 unsigned int x_row = tile_out->row + row;
1497 for (col = 0; col < tileWidth; col++)
1498 {
1499 unsigned int x_col = tile_out->col + col;
1500 if (x_row >= pyr->scaled_height
1501 || x_col >= pyr->scaled_width)
1502 {
1503 /* masking any portion of the tile exceeding the scaled section size */
1504 *p++ = 0;
1505 }
1506 else
1507 *p++ = 1;
1508 }
1509 }
1510 }
1511 else
1512 {
1513 mask = NULL;
1514 mask_sz = 0;
1515 }
1516
1517 /* creating the output (rescaled) tile */
1518 tile_in = tile_out->first;
1519 while (tile_in != NULL)
1520 {
1521 /* loading and rescaling the base tiles */
1522 raster_in =
1523 load_tile_base_generic (stmt_rd, tile_in->child->tile_id);
1524 if (raster_in == NULL)
1525 goto error;
1526 pos_y = tile_out->maxy;
1527 x = 0;
1528 y = 0;
1529 for (row = 0; row < tileHeight; row += tic_y)
1530 {
1531 pos_x = tile_out->minx;
1532 for (col = 0; col < tileWidth; col += tic_x)
1533 {
1534 if (tile_in->child->cy < pos_y
1535 && tile_in->child->cy > (pos_y - geo_y)
1536 && tile_in->child->cx > pos_x
1537 && tile_in->child->cx < (pos_x + geo_x))
1538 {
1539 x = col;
1540 y = row;
1541 break;
1542 }
1543 pos_x += geo_x;
1544 }
1545 pos_y -= geo_y;
1546 }
1547 rst = (rl2PrivRasterPtr) raster_in;
1548 rescale_grid (buf_out, tileWidth, tileHeight, rst->rasterBuffer,
1549 sample_type, x, y, tic_x, tic_y, no_data);
1550 rl2_destroy_raster (raster_in);
1551 raster_in = NULL;
1552 tile_in = tile_in->next;
1553 }
1554
1555 raster_out = NULL;
1556 raster_out =
1557 rl2_create_raster (tileWidth, tileHeight, sample_type,
1558 RL2_PIXEL_DATAGRID, 1, buf_out,
1559 out_sz, NULL, mask, mask_sz, nd);
1560 buf_out = NULL;
1561 mask = NULL;
1562 if (raster_out == NULL)
1563 {
1564 fprintf (stderr, "ERROR: unable to create a Pyramid Tile\n");
1565 goto error;
1566 }
1567 if (rl2_raster_encode
1568 (raster_out, RL2_COMPRESSION_DEFLATE, &blob_odd, &blob_odd_sz,
1569 &blob_even, &blob_even_sz, 100, 1) != RL2_OK)
1570 {
1571 fprintf (stderr, "ERROR: unable to encode a Pyramid tile\n");
1572 goto error;
1573 }
1574 rl2_destroy_raster (raster_out);
1575 raster_out = NULL;
1576
1577 /* INSERTing the tile */
1578 if (!do_insert_pyramid_tile
1579 (handle, blob_odd, blob_odd_sz, blob_even, blob_even_sz, id_level,
1580 pyr->section_id, pyr->srid, tile_out->minx, tile_out->miny,
1581 tile_out->maxx, tile_out->maxy, stmt_tils, stmt_data))
1582 goto error;
1583
1584 tile_out = tile_out->next;
1585 }
1586
1587 return 1;
1588
1589 error:
1590 if (raster_in != NULL)
1591 rl2_destroy_raster (raster_in);
1592 if (raster_out != NULL)
1593 rl2_destroy_raster (raster_out);
1594 if (buf_out != NULL)
1595 free (buf_out);
1596 if (mask != NULL)
1597 free (mask);
1598 return 0;
1599 }
1600
1601 static double
rescale_mb_pixel_uint8(const unsigned char * buf_in,unsigned int tileWidth,unsigned int tileHeight,unsigned int x,unsigned int y,unsigned char nd,unsigned char nb,unsigned char num_bands)1602 rescale_mb_pixel_uint8 (const unsigned char *buf_in, unsigned int tileWidth,
1603 unsigned int tileHeight, unsigned int x, unsigned int y,
1604 unsigned char nd, unsigned char nb,
1605 unsigned char num_bands)
1606 {
1607 /* rescaling a MultiBand pixel sample (8x8) - UINT8 */
1608 unsigned int row;
1609 unsigned int col;
1610 int nodata = 0;
1611 int valid = 0;
1612 double sum = 0.0;
1613
1614 for (row = 0; row < 8; row++)
1615 {
1616 const unsigned char *p_in_base;
1617 unsigned int yy = y + row;
1618 if (yy >= tileHeight)
1619 break;
1620 p_in_base = buf_in + (yy * tileWidth * num_bands);
1621 for (col = 0; col < 8; col++)
1622 {
1623 const unsigned char *p_in;
1624 unsigned int xx = x + col;
1625 if (xx >= tileWidth)
1626 break;
1627 p_in = p_in_base + (xx * num_bands) + nb;
1628 if (*p_in == nd)
1629 nodata++;
1630 else
1631 {
1632 valid++;
1633 sum += *p_in;
1634 }
1635 }
1636 }
1637
1638 if (nodata >= valid)
1639 return nd;
1640 return (unsigned char) (sum / (double) valid);
1641 }
1642
1643 static void
rescale_multiband_uint8(unsigned char * buf_out,unsigned int tileWidth,unsigned int tileHeight,const unsigned char * buf_in,unsigned int x,unsigned int y,unsigned int tic_x,unsigned int tic_y,unsigned char num_bands,rl2PixelPtr no_data)1644 rescale_multiband_uint8 (unsigned char *buf_out, unsigned int tileWidth,
1645 unsigned int tileHeight, const unsigned char *buf_in,
1646 unsigned int x, unsigned int y, unsigned int tic_x,
1647 unsigned int tic_y, unsigned char num_bands,
1648 rl2PixelPtr no_data)
1649 {
1650 /* rescaling a MultiBand tile - unsigned int 8 bit */
1651 unsigned int row;
1652 unsigned int col;
1653 unsigned char nb;
1654 unsigned char nd = 0;
1655 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) no_data;
1656
1657 for (row = 0; row < tic_y; row++)
1658 {
1659 unsigned int yy = row + y;
1660 unsigned char *p_out_base = buf_out + (yy * tileWidth * num_bands);
1661 if (yy >= tileHeight)
1662 break;
1663 for (col = 0; col < tic_x; col++)
1664 {
1665 unsigned int xx = col + x;
1666 unsigned char *p_out = p_out_base + (xx * num_bands);
1667 if (xx >= tileWidth)
1668 break;
1669 for (nb = 0; nb < num_bands; nb++)
1670 {
1671 if (pxl != NULL)
1672 {
1673 if (pxl->sampleType == RL2_SAMPLE_UINT8
1674 && pxl->nBands == num_bands)
1675 {
1676 rl2PrivSamplePtr sample = pxl->Samples + nb;
1677 nd = sample->uint8;
1678 }
1679 }
1680 *(p_out + nb) =
1681 rescale_mb_pixel_uint8 (buf_in, tileWidth, tileHeight,
1682 col * 8, row * 8, nd, nb,
1683 num_bands);
1684 }
1685 }
1686 }
1687 }
1688
1689 static double
rescale_mb_pixel_uint16(const unsigned short * buf_in,unsigned int tileWidth,unsigned int tileHeight,unsigned int x,unsigned int y,unsigned short nd,unsigned char nb,unsigned char num_bands)1690 rescale_mb_pixel_uint16 (const unsigned short *buf_in, unsigned int tileWidth,
1691 unsigned int tileHeight, unsigned int x,
1692 unsigned int y, unsigned short nd, unsigned char nb,
1693 unsigned char num_bands)
1694 {
1695 /* rescaling a MultiBand pixel sample (8x8) - UINT16 */
1696 unsigned int row;
1697 unsigned int col;
1698 int nodata = 0;
1699 int valid = 0;
1700 double sum = 0.0;
1701
1702 for (row = 0; row < 8; row++)
1703 {
1704 const unsigned short *p_in_base;
1705 unsigned int yy = y + row;
1706 if (yy >= tileHeight)
1707 break;
1708 p_in_base = buf_in + (yy * tileWidth * num_bands);
1709 for (col = 0; col < 8; col++)
1710 {
1711 const unsigned short *p_in;
1712 unsigned int xx = x + col;
1713 if (xx >= tileWidth)
1714 break;
1715 p_in = p_in_base + (xx * num_bands) + nb;
1716 if (*p_in == nd)
1717 nodata++;
1718 else
1719 {
1720 valid++;
1721 sum += *p_in;
1722 }
1723 }
1724 }
1725
1726 if (nodata >= valid)
1727 return nd;
1728 return (unsigned short) (sum / (double) valid);
1729 }
1730
1731 static void
rescale_multiband_uint16(unsigned short * buf_out,unsigned int tileWidth,unsigned int tileHeight,const unsigned short * buf_in,unsigned int x,unsigned int y,unsigned int tic_x,unsigned int tic_y,unsigned char num_bands,rl2PixelPtr no_data)1732 rescale_multiband_uint16 (unsigned short *buf_out, unsigned int tileWidth,
1733 unsigned int tileHeight,
1734 const unsigned short *buf_in, unsigned int x,
1735 unsigned int y, unsigned int tic_x,
1736 unsigned int tic_y, unsigned char num_bands,
1737 rl2PixelPtr no_data)
1738 {
1739 /* rescaling a MultiBand tile - unsigned int 16 bit */
1740 unsigned int row;
1741 unsigned int col;
1742 unsigned char nb;
1743 unsigned short nd = 0;
1744 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) no_data;
1745
1746 for (row = 0; row < tic_y; row++)
1747 {
1748 unsigned int yy = row + y;
1749 unsigned short *p_out_base = buf_out + (yy * tileWidth * num_bands);
1750 if (yy >= tileHeight)
1751 break;
1752 for (col = 0; col < tic_x; col++)
1753 {
1754 unsigned int xx = col + x;
1755 unsigned short *p_out = p_out_base + (xx * num_bands);
1756 if (xx >= tileWidth)
1757 break;
1758 for (nb = 0; nb < num_bands; nb++)
1759 {
1760 if (pxl != NULL)
1761 {
1762 if (pxl->sampleType == RL2_SAMPLE_UINT16
1763 && pxl->nBands == num_bands)
1764 {
1765 rl2PrivSamplePtr sample = pxl->Samples + nb;
1766 nd = sample->uint16;
1767 }
1768 }
1769 *(p_out + nb) =
1770 rescale_mb_pixel_uint16 (buf_in, tileWidth,
1771 tileHeight, col * 8, row * 8,
1772 nd, nb, num_bands);
1773 }
1774 }
1775 }
1776 }
1777
1778 static void
rescale_multiband(void * buf_out,unsigned int tileWidth,unsigned int tileHeight,const void * buf_in,unsigned char sample_type,unsigned char num_bands,unsigned int x,unsigned int y,unsigned int tic_x,unsigned int tic_y,rl2PixelPtr no_data)1779 rescale_multiband (void *buf_out, unsigned int tileWidth,
1780 unsigned int tileHeight, const void *buf_in,
1781 unsigned char sample_type, unsigned char num_bands,
1782 unsigned int x, unsigned int y, unsigned int tic_x,
1783 unsigned int tic_y, rl2PixelPtr no_data)
1784 {
1785 /* rescaling a Multiband tile */
1786 switch (sample_type)
1787 {
1788 case RL2_SAMPLE_UINT8:
1789 rescale_multiband_uint8 ((unsigned char *) buf_out, tileWidth,
1790 tileHeight, (const unsigned char *) buf_in,
1791 x, y, tic_x, tic_y, num_bands, no_data);
1792 break;
1793 case RL2_SAMPLE_UINT16:
1794 rescale_multiband_uint16 ((unsigned short *) buf_out, tileWidth,
1795 tileHeight, (const unsigned short *) buf_in,
1796 x, y, tic_x, tic_y, num_bands, no_data);
1797 break;
1798 };
1799 }
1800
1801 static int
update_sect_pyramid_multiband(sqlite3 * handle,sqlite3_stmt * stmt_rd,sqlite3_stmt * stmt_tils,sqlite3_stmt * stmt_data,SectionPyramid * pyr,unsigned int tileWidth,unsigned int tileHeight,int id_level,rl2PixelPtr no_data,unsigned char sample_type,unsigned char num_bands)1802 update_sect_pyramid_multiband (sqlite3 * handle, sqlite3_stmt * stmt_rd,
1803 sqlite3_stmt * stmt_tils,
1804 sqlite3_stmt * stmt_data, SectionPyramid * pyr,
1805 unsigned int tileWidth,
1806 unsigned int tileHeight, int id_level,
1807 rl2PixelPtr no_data, unsigned char sample_type,
1808 unsigned char num_bands)
1809 {
1810 /* creating and inserting Pyramid tiles */
1811 unsigned char *buf_out = NULL;
1812 unsigned char *mask = NULL;
1813 SectionPyramidTileOutPtr tile_out;
1814 SectionPyramidTileRefPtr tile_in;
1815 unsigned int x;
1816 unsigned int y;
1817 unsigned int row;
1818 unsigned int col;
1819 unsigned int tic_x;
1820 unsigned int tic_y;
1821 double pos_y;
1822 double pos_x;
1823 double geo_x;
1824 double geo_y;
1825 rl2PixelPtr nd = NULL;
1826 rl2RasterPtr raster_out = NULL;
1827 rl2RasterPtr raster_in = NULL;
1828 unsigned char *blob_odd;
1829 int blob_odd_sz;
1830 unsigned char *blob_even;
1831 int blob_even_sz;
1832 int pixel_sz = 1;
1833 int out_sz;
1834 int mask_sz = 0;
1835
1836 if (pyr == NULL)
1837 goto error;
1838 tic_x = tileWidth / pyr->scale;
1839 tic_y = tileHeight / pyr->scale;
1840 geo_x = (double) tic_x *pyr->res_x;
1841 geo_y = (double) tic_y *pyr->res_y;
1842
1843 switch (sample_type)
1844 {
1845 case RL2_SAMPLE_UINT16:
1846 pixel_sz = 2;
1847 break;
1848 };
1849 out_sz = tileWidth * tileHeight * pixel_sz * num_bands;
1850
1851 tile_out = pyr->first_out;
1852 while (tile_out != NULL)
1853 {
1854 rl2PrivRasterPtr rst;
1855 /* allocating the output buffer */
1856 buf_out = malloc (out_sz);
1857 if (buf_out == NULL)
1858 goto error;
1859 rl2_prime_void_tile (buf_out, tileWidth, tileHeight, sample_type,
1860 num_bands, no_data);
1861
1862 if (tile_out->col + tileWidth > pyr->scaled_width
1863 || tile_out->row + tileHeight > pyr->scaled_height)
1864 {
1865 /* allocating and initializing a transparency mask */
1866 unsigned char *p;
1867 mask_sz = tileWidth * tileHeight;
1868 mask = malloc (mask_sz);
1869 if (mask == NULL)
1870 goto error;
1871 p = mask;
1872 for (row = 0; row < tileHeight; row++)
1873 {
1874 unsigned int x_row = tile_out->row + row;
1875 for (col = 0; col < tileWidth; col++)
1876 {
1877 unsigned int x_col = tile_out->col + col;
1878 if (x_row >= pyr->scaled_height
1879 || x_col >= pyr->scaled_width)
1880 {
1881 /* masking any portion of the tile exceeding the scaled section size */
1882 *p++ = 0;
1883 }
1884 else
1885 *p++ = 1;
1886 }
1887 }
1888 }
1889 else
1890 {
1891 mask = NULL;
1892 mask_sz = 0;
1893 }
1894
1895 /* creating the output (rescaled) tile */
1896 tile_in = tile_out->first;
1897 while (tile_in != NULL)
1898 {
1899 /* loading and rescaling the base tiles */
1900 raster_in =
1901 load_tile_base_generic (stmt_rd, tile_in->child->tile_id);
1902 if (raster_in == NULL)
1903 goto error;
1904 pos_y = tile_out->maxy;
1905 x = 0;
1906 y = 0;
1907 for (row = 0; row < tileHeight; row += tic_y)
1908 {
1909 pos_x = tile_out->minx;
1910 for (col = 0; col < tileWidth; col += tic_x)
1911 {
1912 if (tile_in->child->cy < pos_y
1913 && tile_in->child->cy > (pos_y - geo_y)
1914 && tile_in->child->cx > pos_x
1915 && tile_in->child->cx < (pos_x + geo_x))
1916 {
1917 x = col;
1918 y = row;
1919 break;
1920 }
1921 pos_x += geo_x;
1922 }
1923 pos_y -= geo_y;
1924 }
1925 rst = (rl2PrivRasterPtr) raster_in;
1926 rescale_multiband (buf_out, tileWidth, tileHeight,
1927 rst->rasterBuffer, sample_type, num_bands, x,
1928 y, tic_x, tic_y, no_data);
1929 rl2_destroy_raster (raster_in);
1930 raster_in = NULL;
1931 tile_in = tile_in->next;
1932 }
1933
1934 raster_out = NULL;
1935 raster_out =
1936 rl2_create_raster (tileWidth, tileHeight, sample_type,
1937 RL2_PIXEL_MULTIBAND, num_bands, buf_out,
1938 out_sz, NULL, mask, mask_sz, nd);
1939 buf_out = NULL;
1940 mask = NULL;
1941 if (raster_out == NULL)
1942 {
1943 fprintf (stderr, "ERROR: unable to create a Pyramid Tile\n");
1944 goto error;
1945 }
1946 if (rl2_raster_encode
1947 (raster_out, RL2_COMPRESSION_DEFLATE, &blob_odd, &blob_odd_sz,
1948 &blob_even, &blob_even_sz, 100, 1) != RL2_OK)
1949 {
1950 fprintf (stderr, "ERROR: unable to encode a Pyramid tile\n");
1951 goto error;
1952 }
1953 rl2_destroy_raster (raster_out);
1954 raster_out = NULL;
1955
1956 /* INSERTing the tile */
1957 if (!do_insert_pyramid_tile
1958 (handle, blob_odd, blob_odd_sz, blob_even, blob_even_sz, id_level,
1959 pyr->section_id, pyr->srid, tile_out->minx, tile_out->miny,
1960 tile_out->maxx, tile_out->maxy, stmt_tils, stmt_data))
1961 goto error;
1962
1963 tile_out = tile_out->next;
1964 }
1965
1966 return 1;
1967
1968 error:
1969 if (raster_in != NULL)
1970 rl2_destroy_raster (raster_in);
1971 if (raster_out != NULL)
1972 rl2_destroy_raster (raster_out);
1973 if (buf_out != NULL)
1974 free (buf_out);
1975 if (mask != NULL)
1976 free (mask);
1977 return 0;
1978 }
1979
1980 static int
update_sect_pyramid(sqlite3 * handle,sqlite3_stmt * stmt_rd,sqlite3_stmt * stmt_tils,sqlite3_stmt * stmt_data,SectionPyramid * pyr,unsigned int tileWidth,unsigned int tileHeight,int id_level,rl2PalettePtr palette,rl2PixelPtr no_data)1981 update_sect_pyramid (sqlite3 * handle, sqlite3_stmt * stmt_rd,
1982 sqlite3_stmt * stmt_tils, sqlite3_stmt * stmt_data,
1983 SectionPyramid * pyr, unsigned int tileWidth,
1984 unsigned int tileHeight, int id_level,
1985 rl2PalettePtr palette, rl2PixelPtr no_data)
1986 {
1987 /* creating and inserting Pyramid tiles */
1988 unsigned char *buf_in;
1989 SectionPyramidTileOutPtr tile_out;
1990 SectionPyramidTileRefPtr tile_in;
1991 rl2GraphicsBitmapPtr base_tile;
1992 rl2GraphicsContextPtr ctx = NULL;
1993 unsigned int x;
1994 unsigned int y;
1995 unsigned int row;
1996 unsigned int col;
1997 unsigned int tic_x;
1998 unsigned int tic_y;
1999 double pos_y;
2000 double pos_x;
2001 double geo_x;
2002 double geo_y;
2003 unsigned char *rgb = NULL;
2004 unsigned char *alpha = NULL;
2005 rl2PixelPtr nd = NULL;
2006 rl2RasterPtr raster = NULL;
2007 unsigned char *blob_odd;
2008 int blob_odd_sz;
2009 unsigned char *blob_even;
2010 int blob_even_sz;
2011 unsigned char *p;
2012 unsigned char compression = RL2_COMPRESSION_NONE;
2013
2014 if (pyr == NULL)
2015 goto error;
2016 tic_x = tileWidth / pyr->scale;
2017 tic_y = tileHeight / pyr->scale;
2018 geo_x = (double) tic_x *pyr->res_x;
2019 geo_y = (double) tic_y *pyr->res_y;
2020
2021 tile_out = pyr->first_out;
2022 while (tile_out != NULL)
2023 {
2024 /* creating the output (rescaled) tile */
2025 ctx = rl2_graph_create_context (tileWidth, tileHeight);
2026 if (ctx == NULL)
2027 goto error;
2028 tile_in = tile_out->first;
2029 while (tile_in != NULL)
2030 {
2031 /* loading and rescaling the base tiles */
2032 buf_in =
2033 load_tile_base (stmt_rd, tile_in->child->tile_id, palette,
2034 no_data);
2035 if (buf_in == NULL)
2036 goto error;
2037 base_tile =
2038 rl2_graph_create_bitmap (buf_in, tileWidth, tileHeight);
2039 if (base_tile == NULL)
2040 {
2041 free (buf_in);
2042 goto error;
2043 }
2044 pos_y = tile_out->maxy;
2045 x = 0;
2046 y = 0;
2047 for (row = 0; row < tileHeight; row += tic_y)
2048 {
2049 pos_x = tile_out->minx;
2050 for (col = 0; col < tileWidth; col += tic_x)
2051 {
2052 if (tile_in->child->cy < pos_y
2053 && tile_in->child->cy > (pos_y - geo_y)
2054 && tile_in->child->cx > pos_x
2055 && tile_in->child->cx < (pos_x + geo_x))
2056 {
2057 x = col;
2058 y = row;
2059 break;
2060 }
2061 pos_x += geo_x;
2062 }
2063 pos_y -= geo_y;
2064 }
2065 rl2_graph_draw_rescaled_bitmap (ctx, base_tile,
2066 1.0 / pyr->scale,
2067 1.0 / pyr->scale, x, y);
2068 rl2_graph_destroy_bitmap (base_tile);
2069 tile_in = tile_in->next;
2070 }
2071
2072 rgb = rl2_graph_get_context_rgb_array (ctx);
2073 if (rgb == NULL)
2074 goto error;
2075 alpha = rl2_graph_get_context_alpha_array (ctx);
2076 if (alpha == NULL)
2077 goto error;
2078 p = alpha;
2079 for (row = 0; row < tileHeight; row++)
2080 {
2081 unsigned int x_row = tile_out->row + row;
2082 for (col = 0; col < tileWidth; col++)
2083 {
2084 unsigned int x_col = tile_out->col + col;
2085 if (x_row >= pyr->scaled_height
2086 || x_col >= pyr->scaled_width)
2087 {
2088 /* masking any portion of the tile exceeding the scaled section size */
2089 *p++ = 0;
2090 }
2091 else
2092 {
2093 if (*p == 0)
2094 p++;
2095 else
2096 *p++ = 1;
2097 }
2098 }
2099 }
2100
2101 raster = NULL;
2102 if (pyr->pixel_type == RL2_PIXEL_GRAYSCALE
2103 || pyr->pixel_type == RL2_PIXEL_MONOCHROME)
2104 {
2105 /* Grayscale Pyramid */
2106 unsigned char *p_in;
2107 unsigned char *p_out;
2108 unsigned char *gray = malloc (tileWidth * tileHeight);
2109 if (gray == NULL)
2110 goto error;
2111 p_in = rgb;
2112 p_out = gray;
2113 for (row = 0; row < tileHeight; row++)
2114 {
2115 for (col = 0; col < tileWidth; col++)
2116 {
2117 *p_out++ = *p_in++;
2118 p_in += 2;
2119 }
2120 }
2121 free (rgb);
2122 if (pyr->pixel_type == RL2_PIXEL_MONOCHROME)
2123 {
2124 if (no_data == NULL)
2125 nd = NULL;
2126 else
2127 {
2128 /* converting the NO-DATA pixel */
2129 rl2PrivPixelPtr pxl = (rl2PrivPixelPtr) no_data;
2130 rl2PrivSamplePtr sample = pxl->Samples + 0;
2131 nd = rl2_create_pixel (RL2_SAMPLE_UINT8,
2132 RL2_PIXEL_GRAYSCALE, 1);
2133 if (sample->uint8 == 0)
2134 rl2_set_pixel_sample_uint8 (nd,
2135 RL2_GRAYSCALE_BAND,
2136 255);
2137 else
2138 rl2_set_pixel_sample_uint8 (nd,
2139 RL2_GRAYSCALE_BAND,
2140 0);
2141 }
2142 compression = RL2_COMPRESSION_PNG;
2143 }
2144 else
2145 {
2146 nd = rl2_clone_pixel (no_data);
2147 compression = RL2_COMPRESSION_JPEG;
2148 }
2149 raster =
2150 rl2_create_raster (tileWidth, tileHeight, RL2_SAMPLE_UINT8,
2151 RL2_PIXEL_GRAYSCALE, 1, gray,
2152 tileWidth * tileHeight, NULL, alpha,
2153 tileWidth * tileHeight, nd);
2154 }
2155 else if (pyr->pixel_type == RL2_PIXEL_RGB)
2156 {
2157 /* RGB Pyramid */
2158 nd = rl2_clone_pixel (no_data);
2159 raster =
2160 rl2_create_raster (tileWidth, tileHeight, RL2_SAMPLE_UINT8,
2161 RL2_PIXEL_RGB, 3, rgb,
2162 tileWidth * tileHeight * 3, NULL, alpha,
2163 tileWidth * tileHeight, nd);
2164 compression = RL2_COMPRESSION_JPEG;
2165 }
2166 if (raster == NULL)
2167 {
2168 fprintf (stderr, "ERROR: unable to create a Pyramid Tile\n");
2169 goto error;
2170 }
2171 if (rl2_raster_encode
2172 (raster, compression, &blob_odd, &blob_odd_sz, &blob_even,
2173 &blob_even_sz, 80, 1) != RL2_OK)
2174 {
2175 fprintf (stderr, "ERROR: unable to encode a Pyramid tile\n");
2176 goto error;
2177 }
2178 rl2_destroy_raster (raster);
2179 raster = NULL;
2180 rl2_graph_destroy_context (ctx);
2181 ctx = NULL;
2182
2183 /* INSERTing the tile */
2184 if (!do_insert_pyramid_tile
2185 (handle, blob_odd, blob_odd_sz, blob_even, blob_even_sz, id_level,
2186 pyr->section_id, pyr->srid, tile_out->minx, tile_out->miny,
2187 tile_out->maxx, tile_out->maxy, stmt_tils, stmt_data))
2188 goto error;
2189
2190 tile_out = tile_out->next;
2191 }
2192
2193 return 1;
2194
2195 error:
2196 if (raster != NULL)
2197 rl2_destroy_raster (raster);
2198 if (ctx != NULL)
2199 rl2_graph_destroy_context (ctx);
2200 return 0;
2201 }
2202
2203 static int
rescale_monolithic_rgba(int id_level,unsigned int tileWidth,unsigned int tileHeight,int factor,double res_x,double res_y,double minx,double miny,double maxx,double maxy,unsigned char * buffer,int buf_size,unsigned char * mask,int * mask_size,rl2PalettePtr palette,rl2PixelPtr no_data,sqlite3_stmt * stmt_geo,sqlite3_stmt * stmt_data)2204 rescale_monolithic_rgba (int id_level,
2205 unsigned int tileWidth, unsigned int tileHeight,
2206 int factor, double res_x, double res_y, double minx,
2207 double miny, double maxx, double maxy,
2208 unsigned char *buffer, int buf_size,
2209 unsigned char *mask, int *mask_size,
2210 rl2PalettePtr palette, rl2PixelPtr no_data,
2211 sqlite3_stmt * stmt_geo, sqlite3_stmt * stmt_data)
2212 {
2213 /* rescaling a monolithic RGBA tile */
2214 rl2GraphicsContextPtr ctx = NULL;
2215 rl2GraphicsBitmapPtr base_tile = NULL;
2216 unsigned char *rgba = NULL;
2217 unsigned int x;
2218 unsigned int y;
2219 int ret;
2220 double shift_x;
2221 double shift_y;
2222 double scale_x;
2223 double scale_y;
2224 unsigned char *rgb = NULL;
2225 unsigned char *alpha = NULL;
2226 int valid_mask = 0;
2227 unsigned char *p_in;
2228 unsigned char *p_out;
2229 unsigned char *p_msk;
2230
2231 /* creating a graphics context */
2232 ctx = rl2_graph_create_context (tileWidth, tileHeight);
2233 if (ctx == NULL)
2234 goto error;
2235 /* binding the BBOX to be queried */
2236 sqlite3_reset (stmt_geo);
2237 sqlite3_clear_bindings (stmt_geo);
2238 sqlite3_bind_int (stmt_geo, 1, id_level);
2239 sqlite3_bind_double (stmt_geo, 2, minx);
2240 sqlite3_bind_double (stmt_geo, 3, miny);
2241 sqlite3_bind_double (stmt_geo, 4, maxx);
2242 sqlite3_bind_double (stmt_geo, 5, maxy);
2243 while (1)
2244 {
2245 /* scrolling the result set rows */
2246 ret = sqlite3_step (stmt_geo);
2247 if (ret == SQLITE_DONE)
2248 break; /* end of result set */
2249 if (ret == SQLITE_ROW)
2250 {
2251 sqlite3_int64 tile_id = sqlite3_column_int64 (stmt_geo, 0);
2252 double tile_x = sqlite3_column_double (stmt_geo, 1);
2253 double tile_y = sqlite3_column_double (stmt_geo, 2);
2254
2255 rgba = load_tile_base (stmt_data, tile_id, palette, no_data);
2256 if (rgba == NULL)
2257 goto error;
2258 base_tile =
2259 rl2_graph_create_bitmap (rgba, tileWidth, tileHeight);
2260 if (base_tile == NULL)
2261 {
2262 free (rgba);
2263 goto error;
2264 }
2265 shift_x = tile_x - minx;
2266 shift_y = maxy - tile_y;
2267 scale_x = 1.0 / (double) factor;
2268 scale_y = 1.0 / (double) factor;
2269 x = (int) (shift_x / res_x);
2270 y = (int) (shift_y / res_y);
2271 rl2_graph_draw_rescaled_bitmap (ctx, base_tile,
2272 scale_x, scale_y, x, y);
2273 rl2_graph_destroy_bitmap (base_tile);
2274 }
2275 }
2276
2277 rgb = rl2_graph_get_context_rgb_array (ctx);
2278 if (rgb == NULL)
2279 goto error;
2280 alpha = rl2_graph_get_context_alpha_array (ctx);
2281 if (alpha == NULL)
2282 goto error;
2283 rl2_graph_destroy_context (ctx);
2284 if (buf_size == (int) (tileWidth * tileHeight))
2285 {
2286 /* Grayscale */
2287 p_in = rgb;
2288 p_msk = alpha;
2289 p_out = buffer;
2290 for (y = 0; y < tileHeight; y++)
2291 {
2292 for (x = 0; x < tileWidth; x++)
2293 {
2294 if (*p_msk++ < 128)
2295 {
2296 /* skipping a transparent pixel */
2297 p_in += 3;
2298 p_out += 3;
2299 }
2300 else
2301 {
2302 /* copying an opaque pixel */
2303 *p_out++ = *p_in++;
2304 p_in += 2;
2305 }
2306 }
2307 }
2308 }
2309 else
2310 {
2311 /* RGB */
2312 p_in = rgb;
2313 p_msk = alpha;
2314 p_out = buffer;
2315 for (y = 0; y < tileHeight; y++)
2316 {
2317 for (x = 0; x < tileWidth; x++)
2318 {
2319 if (*p_msk++ < 128)
2320 {
2321 /* skipping a transparent pixel */
2322 p_in += 3;
2323 p_out += 3;
2324 }
2325 else
2326 {
2327 /* copying an opaque pixel */
2328 *p_out++ = *p_in++;
2329 *p_out++ = *p_in++;
2330 *p_out++ = *p_in++;
2331 }
2332 }
2333 }
2334 }
2335 free (rgb);
2336 p_in = alpha;
2337 p_out = mask;
2338 for (y = 0; y < tileHeight; y++)
2339 {
2340 for (x = 0; x < tileWidth; x++)
2341 {
2342 if (*p_in++ < 128)
2343 {
2344 *p_out++ = 0;
2345 valid_mask = 1;
2346 }
2347 else
2348 *p_out++ = 1;
2349 }
2350 }
2351 free (alpha);
2352 if (!valid_mask)
2353 {
2354 free (mask);
2355 *mask_size = 0;
2356 }
2357
2358 return 1;
2359 error:
2360 if (rgb != NULL)
2361 free (rgb);
2362 if (alpha != NULL)
2363 free (alpha);
2364 if (ctx != NULL)
2365 rl2_graph_destroy_context (ctx);
2366 return 0;
2367 }
2368
2369 #define floor2(exp) ((long) exp)
2370
2371 static rl2RasterPtr
create_124_rescaled_raster(const unsigned char * rgba,unsigned char pixel_type,unsigned int tileWidth,unsigned int tileHeight,int scale)2372 create_124_rescaled_raster (const unsigned char *rgba, unsigned char pixel_type,
2373 unsigned int tileWidth, unsigned int tileHeight,
2374 int scale)
2375 {
2376 /* creating a rescaled raster (1,2 or 4 bit pyramids)
2377 /
2378 / this function builds an high quality rescaled sub-image by applying pixel interpolation
2379 /
2380 / this code is widely inspired by the original GD gdImageCopyResampled() function
2381 */
2382 rl2RasterPtr raster;
2383 unsigned int x;
2384 unsigned int y;
2385 double sy1;
2386 double sy2;
2387 double sx1;
2388 double sx2;
2389 unsigned char r;
2390 unsigned char g;
2391 unsigned char b;
2392 unsigned char a;
2393 unsigned char *rgb = NULL;
2394 int rgb_sz;
2395 unsigned char *mask = NULL;
2396 int mask_sz;
2397 unsigned char num_bands;
2398 const unsigned char *p_in;
2399 unsigned char *p_out;
2400 unsigned char *p_msk;
2401 unsigned int out_width = tileWidth / scale;
2402 unsigned int out_height = tileHeight / scale;
2403
2404 mask_sz = out_width * out_height;
2405 if (pixel_type == RL2_PIXEL_RGB)
2406 {
2407 num_bands = 3;
2408 rgb_sz = out_width * out_height * 3;
2409 rgb = malloc (rgb_sz);
2410 if (rgb == NULL)
2411 return NULL;
2412 mask = malloc (mask_sz);
2413 if (mask == NULL)
2414 {
2415 free (rgb);
2416 return NULL;
2417 }
2418 }
2419 else
2420 {
2421 num_bands = 1;
2422 rgb_sz = out_width * out_height;
2423 rgb = malloc (rgb_sz);
2424 if (rgb == NULL)
2425 return NULL;
2426 mask = malloc (mask_sz);
2427 if (mask == NULL)
2428 {
2429 free (rgb);
2430 return NULL;
2431 }
2432 }
2433 memset (mask, 0, mask_sz);
2434
2435 for (y = 0; y < out_height; y++)
2436 {
2437 sy1 = ((double) y) * (double) tileHeight / (double) out_height;
2438 sy2 = ((double) (y + 1)) * (double) tileHeight / (double) out_height;
2439 for (x = 0; x < out_width; x++)
2440 {
2441 double sx;
2442 double sy;
2443 double spixels = 0;
2444 double red = 0.0;
2445 double green = 0.0;
2446 double blue = 0.0;
2447 double alpha = 0.0;
2448 sx1 = ((double) x) * (double) tileWidth / (double) out_width;
2449 sx2 =
2450 ((double) (x + 1)) * (double) tileWidth /
2451 (double) out_width;
2452 sy = sy1;
2453 do
2454 {
2455 double yportion;
2456 if (floor2 (sy) == floor2 (sy1))
2457 {
2458 yportion = 1.0 - (sy - floor2 (sy));
2459 if (yportion > sy2 - sy1)
2460 {
2461 yportion = sy2 - sy1;
2462 }
2463 sy = floor2 (sy);
2464 }
2465 else if (sy == floor2 (sy2))
2466 {
2467 yportion = sy2 - floor2 (sy2);
2468 }
2469 else
2470 {
2471 yportion = 1.0;
2472 }
2473 sx = sx1;
2474 do
2475 {
2476 double xportion;
2477 double pcontribution;
2478 if (floor2 (sx) == floor2 (sx1))
2479 {
2480 xportion = 1.0 - (sx - floor2 (sx));
2481 if (xportion > sx2 - sx1)
2482 {
2483 xportion = sx2 - sx1;
2484 }
2485 sx = floor2 (sx);
2486 }
2487 else if (sx == floor2 (sx2))
2488 {
2489 xportion = sx2 - floor2 (sx2);
2490 }
2491 else
2492 {
2493 xportion = 1.0;
2494 }
2495 pcontribution = xportion * yportion;
2496 /* retrieving the origin pixel */
2497 p_in = rgba + ((unsigned int) sy * tileWidth * 4);
2498 p_in += (unsigned int) sx *4;
2499 r = *p_in++;
2500 g = *p_in++;
2501 b = *p_in++;
2502 a = *p_in++;
2503
2504 red += r * pcontribution;
2505 green += g * pcontribution;
2506 blue += b * pcontribution;
2507 alpha += a * pcontribution;
2508 spixels += xportion * yportion;
2509 sx += 1.0;
2510 }
2511 while (sx < sx2);
2512 sy += 1.0;
2513 }
2514 while (sy < sy2);
2515 if (spixels != 0.0)
2516 {
2517 red /= spixels;
2518 green /= spixels;
2519 blue /= spixels;
2520 }
2521 if (red > 255.0)
2522 red = 255.0;
2523 if (green > 255.0)
2524 green = 255.0;
2525 if (blue > 255.0)
2526 blue = 255.0;
2527 if (alpha < 192.0)
2528 {
2529 /* skipping almost transparent pixels */
2530 continue;
2531 }
2532 /* setting the destination pixel */
2533 if (pixel_type == RL2_PIXEL_RGB)
2534 p_out = rgb + (y * out_width * 3);
2535 else
2536 p_out = rgb + (y * out_width);
2537 p_msk = mask + (y * out_width);
2538 if (pixel_type == RL2_PIXEL_RGB)
2539 {
2540 p_out += x * 3;
2541 *p_out++ = (unsigned char) red;
2542 *p_out++ = (unsigned char) green;
2543 *p_out = (unsigned char) blue;
2544 p_msk += x;
2545 *p_msk = 1;
2546 }
2547 else
2548 {
2549 if (red <= 224.0)
2550 {
2551 p_out += x;
2552 *p_out = (unsigned char) red;
2553 p_msk += x;
2554 *p_msk = 1;
2555 }
2556 }
2557 }
2558 }
2559
2560 raster =
2561 rl2_create_raster (out_width, out_height, RL2_SAMPLE_UINT8, pixel_type,
2562 num_bands, rgb, rgb_sz, NULL, mask, mask_sz, NULL);
2563 return raster;
2564 }
2565
2566 static void
copy_124_rescaled(rl2RasterPtr raster_out,rl2RasterPtr raster_in,unsigned int base_x,unsigned int base_y)2567 copy_124_rescaled (rl2RasterPtr raster_out, rl2RasterPtr raster_in,
2568 unsigned int base_x, unsigned int base_y)
2569 {
2570 /* copying pixels from rescaled to destination tile buffer */
2571 rl2PrivRasterPtr rst_in = (rl2PrivRasterPtr) raster_in;
2572 rl2PrivRasterPtr rst_out = (rl2PrivRasterPtr) raster_out;
2573 unsigned int x;
2574 unsigned int y;
2575 int dx;
2576 int dy;
2577 unsigned char *p_in;
2578 unsigned char *p_out;
2579 unsigned char *p_msk_in;
2580 unsigned char *p_msk_out;
2581
2582 if (rst_in->sampleType == RL2_SAMPLE_UINT8
2583 && rst_out->sampleType == RL2_SAMPLE_UINT8
2584 && rst_in->pixelType == RL2_PIXEL_GRAYSCALE
2585 && rst_out->pixelType == RL2_PIXEL_GRAYSCALE && rst_in->nBands == 1
2586 && rst_out->nBands == 1 && rst_in->maskBuffer != NULL
2587 && rst_out->maskBuffer != NULL)
2588 {
2589 /* Grayscale */
2590 p_in = rst_in->rasterBuffer;
2591 p_msk_in = rst_in->maskBuffer;
2592 for (y = 0; y < rst_in->height; y++)
2593 {
2594 dy = base_y + y;
2595 if (dy < 0 || dy >= (int) (rst_out->height))
2596 {
2597 p_in += rst_in->width;
2598 p_msk_in += rst_in->width;
2599 continue;
2600 }
2601 for (x = 0; x < rst_in->width; x++)
2602 {
2603 dx = base_x + x;
2604 if (dx < 0 || dx >= (int) (rst_out->width))
2605 {
2606 p_in++;
2607 p_msk_in++;
2608 continue;
2609 }
2610 p_out =
2611 rst_out->rasterBuffer + (dy * rst_out->width) + dx;
2612 p_msk_out =
2613 rst_out->maskBuffer + (dy * rst_out->width) + dx;
2614 if (*p_msk_in++ == 0)
2615 p_in++;
2616 else
2617 {
2618 *p_out++ = *p_in++;
2619 *p_msk_out++ = 1;
2620 }
2621 }
2622 }
2623 }
2624 if (rst_in->sampleType == RL2_SAMPLE_UINT8
2625 && rst_out->sampleType == RL2_SAMPLE_UINT8
2626 && rst_in->pixelType == RL2_PIXEL_RGB
2627 && rst_out->pixelType == RL2_PIXEL_RGB && rst_in->nBands == 3
2628 && rst_out->nBands == 3 && rst_in->maskBuffer != NULL
2629 && rst_out->maskBuffer != NULL)
2630 {
2631 /* RGB */
2632 p_in = rst_in->rasterBuffer;
2633 p_msk_in = rst_in->maskBuffer;
2634 for (y = 0; y < rst_in->height; y++)
2635 {
2636 dy = base_y + y;
2637 if (dy < 0 || dy >= (int) (rst_out->height))
2638 {
2639 p_in += rst_in->width * 3;
2640 p_msk_in += rst_in->width;
2641 continue;
2642 }
2643 for (x = 0; x < rst_in->width; x++)
2644 {
2645 dx = base_x + x;
2646 if (dx < 0 || dx >= (int) (rst_out->width))
2647 {
2648 p_in += 3;
2649 p_msk_in++;
2650 continue;
2651 }
2652 p_out =
2653 rst_out->rasterBuffer + (dy * rst_out->width * 3) +
2654 (dx * 3);
2655 p_msk_out =
2656 rst_out->maskBuffer + (dy * rst_out->width) + dx;
2657 if (*p_msk_in++ == 0)
2658 p_in += 3;
2659 else
2660 {
2661 *p_out++ = *p_in++;
2662 *p_out++ = *p_in++;
2663 *p_out++ = *p_in++;
2664 *p_msk_out++ = 1;
2665 }
2666 }
2667 }
2668 }
2669 }
2670
2671 static int
rescale_monolithic_124(int id_level,unsigned int tileWidth,unsigned int tileHeight,int factor,unsigned char pixel_type,double res_x,double res_y,double minx,double miny,double maxx,double maxy,unsigned char * buffer,int buf_size,unsigned char * mask,int * mask_size,rl2PalettePtr palette,rl2PixelPtr no_data,sqlite3_stmt * stmt_geo,sqlite3_stmt * stmt_data)2672 rescale_monolithic_124 (int id_level,
2673 unsigned int tileWidth, unsigned int tileHeight,
2674 int factor, unsigned char pixel_type, double res_x,
2675 double res_y, double minx, double miny, double maxx,
2676 double maxy, unsigned char *buffer, int buf_size,
2677 unsigned char *mask, int *mask_size,
2678 rl2PalettePtr palette, rl2PixelPtr no_data,
2679 sqlite3_stmt * stmt_geo, sqlite3_stmt * stmt_data)
2680 {
2681 /* rescaling a monolithic 1,2 or 4 bit tile */
2682 rl2RasterPtr raster = NULL;
2683 rl2RasterPtr base_tile = NULL;
2684 rl2PrivRasterPtr rst;
2685 unsigned char *rgba = NULL;
2686 unsigned int x;
2687 unsigned int y;
2688 int ret;
2689 double shift_x;
2690 double shift_y;
2691 int valid_mask = 0;
2692 unsigned char *p_in;
2693 unsigned char *p_out;
2694 unsigned char out_pixel_type;
2695 unsigned char out_num_bands;
2696 rl2PixelPtr nd = NULL;
2697
2698 /* creating the output buffers */
2699 if (pixel_type == RL2_PIXEL_MONOCHROME)
2700 {
2701 out_pixel_type = RL2_PIXEL_GRAYSCALE;
2702 out_num_bands = 1;
2703 p_out = buffer;
2704 for (y = 0; y < tileHeight; y++)
2705 {
2706 /* priming the background color */
2707 for (x = 0; x < tileWidth; x++)
2708 *p_out++ = 255;
2709 }
2710 nd = rl2_create_pixel (RL2_SAMPLE_UINT8, RL2_PIXEL_GRAYSCALE, 1);
2711 rl2_set_pixel_sample_uint8 (nd, RL2_GRAYSCALE_BAND, 255);
2712 }
2713 else
2714 {
2715 out_pixel_type = RL2_PIXEL_RGB;
2716 out_num_bands = 3;
2717 p_out = buffer;
2718 for (y = 0; y < tileHeight; y++)
2719 {
2720 /* priming the background color */
2721 for (x = 0; x < tileWidth; x++)
2722 {
2723 *p_out++ = 255;
2724 *p_out++ = 255;
2725 *p_out++ = 255;
2726 }
2727 }
2728 nd = rl2_create_pixel (RL2_SAMPLE_UINT8, RL2_PIXEL_RGB, 3);
2729 rl2_set_pixel_sample_uint8 (nd, RL2_RED_BAND, 255);
2730 rl2_set_pixel_sample_uint8 (nd, RL2_GREEN_BAND, 255);
2731 rl2_set_pixel_sample_uint8 (nd, RL2_BLUE_BAND, 255);
2732 }
2733 p_out = mask;
2734 for (y = 0; y < tileHeight; y++)
2735 {
2736 /* priming full transparency */
2737 for (x = 0; x < tileWidth; x++)
2738 *p_out++ = 0;
2739 }
2740 /* creating the output raster */
2741 raster =
2742 rl2_create_raster (tileWidth, tileHeight, RL2_SAMPLE_UINT8,
2743 out_pixel_type, out_num_bands, buffer, buf_size,
2744 NULL, mask, *mask_size, nd);
2745 if (raster == NULL)
2746 goto error;
2747
2748 /* binding the BBOX to be queried */
2749 sqlite3_reset (stmt_geo);
2750 sqlite3_clear_bindings (stmt_geo);
2751 sqlite3_bind_int (stmt_geo, 1, id_level);
2752 sqlite3_bind_double (stmt_geo, 2, minx);
2753 sqlite3_bind_double (stmt_geo, 3, miny);
2754 sqlite3_bind_double (stmt_geo, 4, maxx);
2755 sqlite3_bind_double (stmt_geo, 5, maxy);
2756 while (1)
2757 {
2758 /* scrolling the result set rows */
2759 ret = sqlite3_step (stmt_geo);
2760 if (ret == SQLITE_DONE)
2761 break; /* end of result set */
2762 if (ret == SQLITE_ROW)
2763 {
2764 sqlite3_int64 tile_id = sqlite3_column_int64 (stmt_geo, 0);
2765 double tile_x = sqlite3_column_double (stmt_geo, 1);
2766 double tile_y = sqlite3_column_double (stmt_geo, 2);
2767
2768 rgba = load_tile_base (stmt_data, tile_id, palette, no_data);
2769 if (rgba == NULL)
2770 goto error;
2771 base_tile =
2772 create_124_rescaled_raster (rgba, out_pixel_type, tileWidth,
2773 tileHeight, factor);
2774 free (rgba);
2775 if (base_tile == NULL)
2776 goto error;
2777 shift_x = tile_x - minx;
2778 shift_y = maxy - tile_y;
2779 x = (int) (shift_x / res_x);
2780 y = (int) (shift_y / res_y);
2781 copy_124_rescaled (raster, base_tile, x, y);
2782 rl2_destroy_raster (base_tile);
2783 }
2784 }
2785
2786 /* releasing buffers ownership */
2787 rst = (rl2PrivRasterPtr) raster;
2788 rst->rasterBuffer = NULL;
2789 rst->maskBuffer = NULL;
2790 rl2_destroy_raster (raster);
2791
2792 p_in = mask;
2793 for (y = 0; y < tileHeight; y++)
2794 {
2795 for (x = 0; x < tileWidth; x++)
2796 {
2797 if (*p_in++ == 0)
2798 valid_mask = 1;
2799 }
2800 }
2801 if (!valid_mask)
2802 {
2803 free (mask);
2804 *mask_size = 0;
2805 }
2806
2807 return 1;
2808 error:
2809 if (raster != NULL)
2810 {
2811 /* releasing buffers ownership */
2812 rst = (rl2PrivRasterPtr) raster;
2813 rst->rasterBuffer = NULL;
2814 rst->maskBuffer = NULL;
2815 rl2_destroy_raster (raster);
2816 }
2817 return 0;
2818 }
2819
2820 static void
copy_multiband_rescaled(rl2RasterPtr raster_out,rl2RasterPtr raster_in,unsigned int base_x,unsigned int base_y)2821 copy_multiband_rescaled (rl2RasterPtr raster_out, rl2RasterPtr raster_in,
2822 unsigned int base_x, unsigned int base_y)
2823 {
2824 /* copying pixels from rescaled to destination tile buffer */
2825 rl2PrivRasterPtr rst_in = (rl2PrivRasterPtr) raster_in;
2826 rl2PrivRasterPtr rst_out = (rl2PrivRasterPtr) raster_out;
2827 unsigned int x;
2828 unsigned int y;
2829 int dx;
2830 int dy;
2831 unsigned char *p_in_u8;
2832 unsigned char *p_out_u8;
2833 unsigned short *p_in_u16;
2834 unsigned short *p_out_u16;
2835 unsigned char *p_msk_in;
2836 unsigned char *p_msk_out;
2837 int mismatch = 0;
2838 int ib;
2839
2840 if (rst_in->sampleType != rst_out->sampleType)
2841 mismatch = 1;
2842 if (rst_in->pixelType != RL2_PIXEL_MULTIBAND
2843 || rst_out->pixelType != RL2_PIXEL_MULTIBAND)
2844 mismatch = 1;
2845 if (rst_in->nBands != rst_out->nBands)
2846 mismatch = 1;
2847 if (rst_in->maskBuffer == NULL || rst_out->maskBuffer == NULL)
2848 mismatch = 1;
2849 if (mismatch)
2850 {
2851 fprintf (stderr,
2852 "ERROR: Copy MultiBand Rescaled mismatching in/out\n");
2853 return;
2854 }
2855
2856 switch (rst_in->sampleType)
2857 {
2858 case RL2_SAMPLE_UINT8:
2859 p_in_u8 = (unsigned char *) (rst_in->rasterBuffer);
2860 break;
2861 case RL2_SAMPLE_UINT16:
2862 p_in_u16 = (unsigned short *) (rst_in->rasterBuffer);
2863 break;
2864 };
2865 p_msk_in = rst_in->maskBuffer;
2866 for (y = 0; y < rst_in->height; y++)
2867 {
2868 dy = base_y + y;
2869 if (dy < 0 || dy >= (int) (rst_out->height))
2870 {
2871 switch (rst_in->sampleType)
2872 {
2873 case RL2_SAMPLE_UINT8:
2874 p_in_u8 += rst_in->width * rst_in->nBands;
2875 break;
2876 case RL2_SAMPLE_UINT16:
2877 p_in_u16 += rst_in->width * rst_in->nBands;
2878 break;
2879 };
2880 p_msk_in += rst_in->width;
2881 continue;
2882 }
2883 for (x = 0; x < rst_in->width; x++)
2884 {
2885 dx = base_x + x;
2886 if (dx < 0 || dx >= (int) (rst_out->width))
2887 {
2888 switch (rst_in->sampleType)
2889 {
2890 case RL2_SAMPLE_UINT8:
2891 p_in_u8 += rst_in->nBands;
2892 break;
2893 case RL2_SAMPLE_UINT16:
2894 p_in_u16 += rst_in->nBands;
2895 break;
2896 };
2897 p_msk_in++;
2898 continue;
2899 }
2900 switch (rst_out->sampleType)
2901 {
2902 case RL2_SAMPLE_UINT8:
2903 p_out_u8 = (unsigned char *) (rst_out->rasterBuffer);
2904 p_out_u8 +=
2905 (dy * rst_out->width * rst_out->nBands) +
2906 (dx * rst_out->nBands);
2907 break;
2908 case RL2_SAMPLE_UINT16:
2909 p_out_u16 = (unsigned short *) (rst_out->rasterBuffer);
2910 p_out_u16 +=
2911 (dy * rst_out->width * rst_out->nBands) +
2912 (dx * rst_out->nBands);
2913 break;
2914 };
2915 p_msk_out = rst_out->maskBuffer + (dy * rst_out->width) + dx;
2916 if (*p_msk_in++ == 0)
2917 {
2918 switch (rst_in->sampleType)
2919 {
2920 case RL2_SAMPLE_UINT8:
2921 p_in_u8 += rst_out->nBands;
2922 break;
2923 case RL2_SAMPLE_UINT16:
2924 p_in_u16 += rst_out->nBands;
2925 break;
2926 };
2927 }
2928 else
2929 {
2930 for (ib = 0; ib < rst_out->nBands; ib++)
2931 {
2932 switch (rst_out->sampleType)
2933 {
2934 case RL2_SAMPLE_UINT8:
2935 *p_out_u8++ = *p_in_u8++;
2936 break;
2937 case RL2_SAMPLE_UINT16:
2938 *p_out_u16++ = *p_in_u16++;
2939 break;
2940 };
2941 }
2942 *p_msk_out++ = 1;
2943 }
2944 }
2945 }
2946 }
2947
2948 static int
is_mb_nodata_u8(const unsigned char * pixel,unsigned char num_bands,rl2PixelPtr no_data)2949 is_mb_nodata_u8 (const unsigned char *pixel, unsigned char num_bands,
2950 rl2PixelPtr no_data)
2951 {
2952 /* testing for NO-DATA pixel */
2953 int is_valid = 0;
2954 rl2PrivPixelPtr nd = (rl2PrivPixelPtr) no_data;
2955 unsigned char ib;
2956 const unsigned char *p_in = pixel;
2957 if (nd != NULL)
2958 {
2959 if (nd->nBands == num_bands && nd->sampleType == RL2_SAMPLE_UINT8
2960 && nd->pixelType == RL2_PIXEL_MULTIBAND)
2961 is_valid = 1;
2962 }
2963 if (!is_valid)
2964 return 0;
2965 for (ib = 0; ib < num_bands; ib++)
2966 {
2967 if (*p_in++ != (nd->Samples + ib)->uint8)
2968 return 0;
2969 }
2970 return 1;
2971 }
2972
2973 static void
rescale_multiband_u8(unsigned int tileWidth,unsigned int tileHeight,unsigned char num_bands,unsigned int out_width,unsigned int out_height,unsigned int factor,unsigned char * buf_in,const unsigned char * mask_in,unsigned char * buf_out,unsigned char * mask,unsigned int x,unsigned int y,unsigned int ox,unsigned int oy,rl2PixelPtr no_data)2974 rescale_multiband_u8 (unsigned int tileWidth, unsigned int tileHeight,
2975 unsigned char num_bands, unsigned int out_width,
2976 unsigned int out_height, unsigned int factor,
2977 unsigned char *buf_in, const unsigned char *mask_in,
2978 unsigned char *buf_out, unsigned char *mask,
2979 unsigned int x, unsigned int y, unsigned int ox,
2980 unsigned int oy, rl2PixelPtr no_data)
2981 {
2982 /* rescaling a MultiBand (monolithic)- UINT8 */
2983 unsigned int row;
2984 unsigned int col;
2985 int nodata = 0;
2986 int valid = 0;
2987 unsigned char ib;
2988 double *sum;
2989 unsigned char *p_out;
2990 unsigned char *p_msk;
2991
2992 if (ox >= out_width || oy >= out_height)
2993 return;
2994 p_out = buf_out + (out_width * oy * num_bands) + (ox * num_bands);
2995 p_msk = mask + (out_width * oy) + ox;
2996 sum = malloc (sizeof (double) * num_bands);
2997 for (ib = 0; ib < num_bands; ib++)
2998 *(sum + ib) = 0.0;
2999
3000 for (row = 0; row < factor; row++)
3001 {
3002 const unsigned char *p_in_base;
3003 unsigned int yy = y + row;
3004 if (yy >= tileHeight)
3005 break;
3006 p_in_base = buf_in + (yy * tileWidth * num_bands);
3007 for (col = 0; col < factor; col++)
3008 {
3009 const unsigned char *p_in;
3010 unsigned int xx = x + col;
3011 if (xx >= tileWidth)
3012 break;
3013 p_in = p_in_base + (xx * num_bands);
3014 if (mask_in != NULL)
3015 {
3016 /* checking the transparency mask */
3017 const unsigned char *p_msk_in =
3018 mask_in + (yy * tileWidth) + xx;
3019 if (*p_msk_in == 0)
3020 {
3021 nodata++;
3022 continue;
3023 }
3024 }
3025 if (is_mb_nodata_u8 (p_in, num_bands, no_data))
3026 nodata++;
3027 else
3028 {
3029 valid++;
3030 for (ib = 0; ib < num_bands; ib++)
3031 *(sum + ib) += *p_in++;
3032 }
3033 }
3034 }
3035
3036 if (nodata >= valid)
3037 {
3038 free (sum);
3039 return;
3040 }
3041 for (ib = 0; ib < num_bands; ib++)
3042 *p_out++ = (unsigned char) (*(sum + ib) / (double) valid);
3043 free (sum);
3044 *p_msk = 1;
3045 }
3046
3047 static int
is_mb_nodata_u16(const unsigned short * pixel,unsigned char num_bands,rl2PixelPtr no_data)3048 is_mb_nodata_u16 (const unsigned short *pixel, unsigned char num_bands,
3049 rl2PixelPtr no_data)
3050 {
3051 /* testing for NO-DATA pixel */
3052 int is_valid = 0;
3053 rl2PrivPixelPtr nd = (rl2PrivPixelPtr) no_data;
3054 unsigned char ib;
3055 const unsigned short *p_in = pixel;
3056 if (nd != NULL)
3057 {
3058 if (nd->nBands == num_bands && nd->sampleType == RL2_SAMPLE_UINT16
3059 && nd->pixelType == RL2_PIXEL_MULTIBAND)
3060 is_valid = 1;
3061 }
3062 if (!is_valid)
3063 return 0;
3064 for (ib = 0; ib < num_bands; ib++)
3065 {
3066 if (*p_in++ != (nd->Samples + ib)->uint16)
3067 return 0;
3068 }
3069 return 1;
3070 }
3071
3072 static void
rescale_multiband_u16(unsigned int tileWidth,unsigned int tileHeight,unsigned char num_bands,unsigned int out_width,unsigned int out_height,unsigned int factor,unsigned short * buf_in,const unsigned char * mask_in,unsigned short * buf_out,unsigned char * mask,unsigned int x,unsigned int y,unsigned int ox,unsigned int oy,rl2PixelPtr no_data)3073 rescale_multiband_u16 (unsigned int tileWidth, unsigned int tileHeight,
3074 unsigned char num_bands, unsigned int out_width,
3075 unsigned int out_height, unsigned int factor,
3076 unsigned short *buf_in, const unsigned char *mask_in,
3077 unsigned short *buf_out, unsigned char *mask,
3078 unsigned int x, unsigned int y, unsigned int ox,
3079 unsigned int oy, rl2PixelPtr no_data)
3080 {
3081 /* rescaling a MultiBand (monolithic)- UINT16 */
3082 unsigned int row;
3083 unsigned int col;
3084 int nodata = 0;
3085 int valid = 0;
3086 unsigned char ib;
3087 double *sum;
3088 unsigned short *p_out;
3089 unsigned char *p_msk;
3090
3091 if (ox >= out_width || oy >= out_height)
3092 return;
3093 p_out = buf_out + (out_width * oy * num_bands) + (ox * num_bands);
3094 p_msk = mask + (out_width * oy) + ox;
3095 sum = malloc (sizeof (double) * num_bands);
3096 for (ib = 0; ib < num_bands; ib++)
3097 *(sum + ib) = 0.0;
3098
3099 for (row = 0; row < factor; row++)
3100 {
3101 const unsigned short *p_in_base;
3102 unsigned int yy = y + row;
3103 if (yy >= tileHeight)
3104 break;
3105 p_in_base = buf_in + (yy * tileWidth * num_bands);
3106 for (col = 0; col < factor; col++)
3107 {
3108 const unsigned short *p_in;
3109 unsigned int xx = x + col;
3110 if (xx >= tileWidth)
3111 break;
3112 if (mask_in != NULL)
3113 {
3114 /* checking the transparency mask */
3115 const unsigned char *p_msk_in =
3116 mask_in + (yy * tileWidth) + xx;
3117 if (*p_msk_in == 0)
3118 {
3119 nodata++;
3120 continue;
3121 }
3122 }
3123 p_in = p_in_base + (xx * num_bands);
3124 if (is_mb_nodata_u16 (p_in, num_bands, no_data))
3125 nodata++;
3126 else
3127 {
3128 valid++;
3129 for (ib = 0; ib < num_bands; ib++)
3130 *(sum + ib) += *p_in++;
3131 }
3132 }
3133 }
3134
3135 if (nodata >= valid)
3136 {
3137 free (sum);
3138 return;
3139 }
3140 for (ib = 0; ib < num_bands; ib++)
3141 *p_out++ = (unsigned char) (*(sum + ib) / (double) valid);
3142 free (sum);
3143 *p_msk = 1;
3144 }
3145
3146 static void
mb_prime_nodata_u8(unsigned char * buf,unsigned int width,unsigned int height,unsigned char num_bands,rl2PixelPtr no_data)3147 mb_prime_nodata_u8 (unsigned char *buf, unsigned int width, unsigned int height,
3148 unsigned char num_bands, rl2PixelPtr no_data)
3149 {
3150 /* priming a void buffer */
3151 rl2PrivPixelPtr nd = (rl2PrivPixelPtr) no_data;
3152 unsigned int x;
3153 unsigned int y;
3154 unsigned char ib;
3155 unsigned char *p = buf;
3156 int is_valid = 0;
3157
3158 if (nd != NULL)
3159 {
3160 if (nd->nBands == num_bands && nd->sampleType == RL2_SAMPLE_UINT8
3161 && nd->pixelType == RL2_PIXEL_MULTIBAND)
3162 is_valid = 1;
3163 }
3164 for (y = 0; y < height; y++)
3165 {
3166 for (x = 0; x < width; x++)
3167 {
3168 for (ib = 0; ib < num_bands; ib++)
3169 {
3170 if (is_valid)
3171 *p++ = (nd->Samples + ib)->uint8;
3172 else
3173 *p++ = 0;
3174 }
3175 }
3176 }
3177 }
3178
3179 static void
mb_prime_nodata_u16(unsigned short * buf,unsigned int width,unsigned int height,unsigned char num_bands,rl2PixelPtr no_data)3180 mb_prime_nodata_u16 (unsigned short *buf, unsigned int width,
3181 unsigned int height, unsigned char num_bands,
3182 rl2PixelPtr no_data)
3183 {
3184 /* priming a void buffer */
3185 rl2PrivPixelPtr nd = (rl2PrivPixelPtr) no_data;
3186 unsigned int x;
3187 unsigned int y;
3188 unsigned char ib;
3189 unsigned short *p = buf;
3190 int is_valid = 0;
3191
3192 if (nd != NULL)
3193 {
3194 if (nd->nBands == num_bands && nd->sampleType == RL2_SAMPLE_UINT16
3195 && nd->pixelType == RL2_PIXEL_MULTIBAND)
3196 is_valid = 1;
3197 }
3198 for (y = 0; y < height; y++)
3199 {
3200 for (x = 0; x < width; x++)
3201 {
3202 for (ib = 0; ib < num_bands; ib++)
3203 {
3204 if (is_valid)
3205 *p++ = (nd->Samples + ib)->uint16;
3206 else
3207 *p++ = 0;
3208 }
3209 }
3210 }
3211 }
3212
3213 static rl2RasterPtr
create_rescaled_multiband_raster(unsigned int factor,unsigned int tileWidth,unsigned int tileHeight,const void * buf_in,const unsigned char * mask_in,unsigned char sample_type,unsigned char num_bands,rl2PixelPtr no_data)3214 create_rescaled_multiband_raster (unsigned int factor, unsigned int tileWidth,
3215 unsigned int tileHeight, const void *buf_in,
3216 const unsigned char *mask_in,
3217 unsigned char sample_type,
3218 unsigned char num_bands, rl2PixelPtr no_data)
3219 {
3220 /* rescaling a Multiband tile */
3221 unsigned int x;
3222 unsigned int y;
3223 unsigned int ox;
3224 unsigned int oy;
3225 rl2RasterPtr raster = NULL;
3226 unsigned char *mask;
3227 void *buf;
3228 unsigned int mask_sz;
3229 unsigned char pix_sz = 1;
3230 unsigned int buf_sz;
3231 unsigned int out_width = tileWidth / factor;
3232 unsigned int out_height = tileHeight / factor;
3233
3234 mask_sz = out_width * out_height;
3235 switch (sample_type)
3236 {
3237 case RL2_SAMPLE_INT16:
3238 case RL2_SAMPLE_UINT16:
3239 pix_sz = 2;
3240 break;
3241 };
3242 buf_sz = out_width * out_height * pix_sz * num_bands;
3243 buf = malloc (buf_sz);
3244 if (buf == NULL)
3245 return NULL;
3246 mask = malloc (mask_sz);
3247 if (mask == NULL)
3248 {
3249 free (buf);
3250 return NULL;
3251 }
3252 memset (mask, 0, mask_sz);
3253 if (sample_type == RL2_SAMPLE_UINT16)
3254 mb_prime_nodata_u16 (buf, out_width, out_height, num_bands, no_data);
3255 else
3256 mb_prime_nodata_u8 (buf, out_width, out_height, num_bands, no_data);
3257
3258 oy = 0;
3259 for (y = 0; y < tileHeight; y += factor)
3260 {
3261 ox = 0;
3262 for (x = 0; x < tileWidth; x += factor)
3263 {
3264 switch (sample_type)
3265 {
3266 case RL2_SAMPLE_UINT8:
3267 rescale_multiband_u8 (tileWidth, tileHeight, num_bands,
3268 out_width, out_height, factor,
3269 (unsigned char *) buf_in, mask_in,
3270 (unsigned char *) buf, mask, x, y,
3271 ox, oy, no_data);
3272 break;
3273 case RL2_SAMPLE_UINT16:
3274 rescale_multiband_u16 (tileWidth, tileHeight, num_bands,
3275 out_width, out_height, factor,
3276 (unsigned short *) buf_in, mask_in,
3277 (unsigned short *) buf, mask, x, y,
3278 ox, oy, no_data);
3279 break;
3280 };
3281 ox++;
3282 }
3283 oy++;
3284 }
3285
3286 raster =
3287 rl2_create_raster (out_width, out_height, sample_type,
3288 RL2_PIXEL_MULTIBAND, num_bands, buf, buf_sz, NULL,
3289 mask, mask_sz, NULL);
3290 return raster;
3291 }
3292
3293 static void
copy_datagrid_rescaled(rl2RasterPtr raster_out,rl2RasterPtr raster_in,unsigned int base_x,unsigned int base_y)3294 copy_datagrid_rescaled (rl2RasterPtr raster_out, rl2RasterPtr raster_in,
3295 unsigned int base_x, unsigned int base_y)
3296 {
3297 /* copying pixels from rescaled to destination tile buffer */
3298 rl2PrivRasterPtr rst_in = (rl2PrivRasterPtr) raster_in;
3299 rl2PrivRasterPtr rst_out = (rl2PrivRasterPtr) raster_out;
3300 unsigned int x;
3301 unsigned int y;
3302 int dx;
3303 int dy;
3304 char *p_in_8;
3305 char *p_out_8;
3306 unsigned char *p_in_u8;
3307 unsigned char *p_out_u8;
3308 short *p_in_16;
3309 short *p_out_16;
3310 unsigned short *p_in_u16;
3311 unsigned short *p_out_u16;
3312 int *p_in_32;
3313 int *p_out_32;
3314 unsigned int *p_in_u32;
3315 unsigned int *p_out_u32;
3316 float *p_in_flt;
3317 float *p_out_flt;
3318 double *p_in_dbl;
3319 double *p_out_dbl;
3320 unsigned char *p_msk_in;
3321 unsigned char *p_msk_out;
3322 int mismatch = 0;
3323
3324 if (rst_in->sampleType != rst_out->sampleType)
3325 mismatch = 1;
3326 if (rst_in->pixelType != RL2_PIXEL_DATAGRID
3327 || rst_out->pixelType != RL2_PIXEL_DATAGRID)
3328 mismatch = 1;
3329 if (rst_in->nBands != 1 || rst_out->nBands != 1)
3330 mismatch = 1;
3331 if (rst_in->maskBuffer == NULL || rst_out->maskBuffer == NULL)
3332 mismatch = 1;
3333 if (mismatch)
3334 {
3335 fprintf (stderr,
3336 "ERROR: Copy DataGrid Rescaled mismatching in/out\n");
3337 return;
3338 }
3339
3340 switch (rst_in->sampleType)
3341 {
3342 case RL2_SAMPLE_INT8:
3343 p_in_8 = (char *) (rst_in->rasterBuffer);
3344 break;
3345 case RL2_SAMPLE_UINT8:
3346 p_in_u8 = (unsigned char *) (rst_in->rasterBuffer);
3347 break;
3348 case RL2_SAMPLE_INT16:
3349 p_in_16 = (short *) (rst_in->rasterBuffer);
3350 break;
3351 case RL2_SAMPLE_UINT16:
3352 p_in_u16 = (unsigned short *) (rst_in->rasterBuffer);
3353 break;
3354 case RL2_SAMPLE_INT32:
3355 p_in_32 = (int *) (rst_in->rasterBuffer);
3356 break;
3357 case RL2_SAMPLE_UINT32:
3358 p_in_u32 = (unsigned int *) (rst_in->rasterBuffer);
3359 break;
3360 case RL2_SAMPLE_FLOAT:
3361 p_in_flt = (float *) (rst_in->rasterBuffer);
3362 break;
3363 case RL2_SAMPLE_DOUBLE:
3364 p_in_dbl = (double *) (rst_in->rasterBuffer);
3365 break;
3366 };
3367 p_msk_in = rst_in->maskBuffer;
3368 for (y = 0; y < rst_in->height; y++)
3369 {
3370 dy = base_y + y;
3371 if (dy < 0 || dy >= (int) (rst_out->height))
3372 {
3373 switch (rst_in->sampleType)
3374 {
3375 case RL2_SAMPLE_INT8:
3376 p_in_8 += rst_in->width;
3377 break;
3378 case RL2_SAMPLE_UINT8:
3379 p_in_u8 += rst_in->width;
3380 break;
3381 case RL2_SAMPLE_INT16:
3382 p_in_16 += rst_in->width;
3383 break;
3384 case RL2_SAMPLE_UINT16:
3385 p_in_u16 += rst_in->width;
3386 break;
3387 case RL2_SAMPLE_INT32:
3388 p_in_32 += rst_in->width;
3389 break;
3390 case RL2_SAMPLE_UINT32:
3391 p_in_u32 += rst_in->width;
3392 break;
3393 case RL2_SAMPLE_FLOAT:
3394 p_in_flt += rst_in->width;
3395 break;
3396 case RL2_SAMPLE_DOUBLE:
3397 p_in_dbl += rst_in->width;
3398 break;
3399 };
3400 p_msk_in += rst_in->width;
3401 continue;
3402 }
3403 for (x = 0; x < rst_in->width; x++)
3404 {
3405 dx = base_x + x;
3406 if (dx < 0 || dx >= (int) (rst_out->width))
3407 {
3408 switch (rst_in->sampleType)
3409 {
3410 case RL2_SAMPLE_INT8:
3411 p_in_8++;
3412 break;
3413 case RL2_SAMPLE_UINT8:
3414 p_in_u8++;
3415 break;
3416 case RL2_SAMPLE_INT16:
3417 p_in_16++;
3418 break;
3419 case RL2_SAMPLE_UINT16:
3420 p_in_u16++;
3421 break;
3422 case RL2_SAMPLE_INT32:
3423 p_in_32++;
3424 break;
3425 case RL2_SAMPLE_UINT32:
3426 p_in_u32++;
3427 break;
3428 case RL2_SAMPLE_FLOAT:
3429 p_in_flt++;
3430 break;
3431 case RL2_SAMPLE_DOUBLE:
3432 p_in_dbl++;
3433 break;
3434 };
3435 p_msk_in++;
3436 continue;
3437 }
3438 switch (rst_out->sampleType)
3439 {
3440 case RL2_SAMPLE_INT8:
3441 p_out_8 = (char *) (rst_out->rasterBuffer);
3442 p_out_8 += (dy * rst_out->width) + dx;
3443 break;
3444 case RL2_SAMPLE_UINT8:
3445 p_out_u8 = (unsigned char *) (rst_out->rasterBuffer);
3446 p_out_u8 += (dy * rst_out->width) + dx;
3447 break;
3448 case RL2_SAMPLE_INT16:
3449 p_out_16 = (short *) (rst_out->rasterBuffer);
3450 p_out_16 += (dy * rst_out->width) + dx;
3451 break;
3452 case RL2_SAMPLE_UINT16:
3453 p_out_u16 = (unsigned short *) (rst_out->rasterBuffer);
3454 p_out_u16 += (dy * rst_out->width) + dx;
3455 break;
3456 case RL2_SAMPLE_INT32:
3457 p_out_32 = (int *) (rst_out->rasterBuffer);
3458 p_out_32 += (dy * rst_out->width) + dx;
3459 break;
3460 case RL2_SAMPLE_UINT32:
3461 p_out_u32 = (unsigned int *) (rst_out->rasterBuffer);
3462 p_out_u32 += (dy * rst_out->width) + dx;
3463 break;
3464 case RL2_SAMPLE_FLOAT:
3465 p_out_flt = (float *) (rst_out->rasterBuffer);
3466 p_out_flt += (dy * rst_out->width) + dx;
3467 break;
3468 case RL2_SAMPLE_DOUBLE:
3469 p_out_dbl = (double *) (rst_out->rasterBuffer);
3470 p_out_dbl += (dy * rst_out->width) + dx;
3471 break;
3472 };
3473 p_msk_out = rst_out->maskBuffer + (dy * rst_out->width) + dx;
3474 if (*p_msk_in++ == 0)
3475 {
3476 switch (rst_in->sampleType)
3477 {
3478 case RL2_SAMPLE_INT8:
3479 p_in_8++;
3480 break;
3481 case RL2_SAMPLE_UINT8:
3482 p_in_u8++;
3483 break;
3484 case RL2_SAMPLE_INT16:
3485 p_in_16++;
3486 break;
3487 case RL2_SAMPLE_UINT16:
3488 p_in_u16++;
3489 break;
3490 case RL2_SAMPLE_INT32:
3491 p_in_32++;
3492 break;
3493 case RL2_SAMPLE_UINT32:
3494 p_in_u32++;
3495 break;
3496 case RL2_SAMPLE_FLOAT:
3497 p_in_flt++;
3498 break;
3499 case RL2_SAMPLE_DOUBLE:
3500 p_in_dbl++;
3501 break;
3502 };
3503 }
3504 else
3505 {
3506 switch (rst_out->sampleType)
3507 {
3508 case RL2_SAMPLE_INT8:
3509 *p_out_8++ = *p_in_8++;
3510 break;
3511 case RL2_SAMPLE_UINT8:
3512 *p_out_u8 = *p_in_u8++;
3513 break;
3514 case RL2_SAMPLE_INT16:
3515 *p_out_16 = *p_in_16++;
3516 break;
3517 case RL2_SAMPLE_UINT16:
3518 *p_out_u16 = *p_in_u16++;
3519 break;
3520 case RL2_SAMPLE_INT32:
3521 *p_out_32 = *p_in_32++;
3522 break;
3523 case RL2_SAMPLE_UINT32:
3524 *p_out_u32 = *p_in_u32++;
3525 break;
3526 case RL2_SAMPLE_FLOAT:
3527 *p_out_flt = *p_in_flt++;
3528 break;
3529 case RL2_SAMPLE_DOUBLE:
3530 *p_out_dbl = *p_in_dbl++;
3531 break;
3532 };
3533 *p_msk_out++ = 1;
3534 }
3535 }
3536 }
3537 }
3538
3539 static void
rescale_datagrid_8(unsigned int tileWidth,unsigned int tileHeight,unsigned int out_width,unsigned int out_height,unsigned int factor,char * buf_in,char * buf_out,unsigned char * mask,unsigned int x,unsigned int y,unsigned int ox,unsigned int oy,char nd)3540 rescale_datagrid_8 (unsigned int tileWidth, unsigned int tileHeight,
3541 unsigned int out_width, unsigned int out_height,
3542 unsigned int factor, char *buf_in, char *buf_out,
3543 unsigned char *mask, unsigned int x, unsigned int y,
3544 unsigned int ox, unsigned int oy, char nd)
3545 {
3546 /* rescaling a DataGrid (monolithic)- INT8 */
3547 unsigned int row;
3548 unsigned int col;
3549 int nodata = 0;
3550 int valid = 0;
3551 double sum = 0.0;
3552 char *p_out;
3553 unsigned char *p_msk;
3554
3555 if (ox >= out_width || oy >= out_height)
3556 return;
3557 p_out = buf_out + (out_width * oy) + ox;
3558 p_msk = mask + (out_width * oy) + ox;
3559
3560 for (row = 0; row < factor; row++)
3561 {
3562 const char *p_in_base;
3563 unsigned int yy = y + row;
3564 if (yy >= tileHeight)
3565 break;
3566 p_in_base = buf_in + (yy * tileWidth);
3567 for (col = 0; col < factor; col++)
3568 {
3569 const char *p_in;
3570 unsigned int xx = x + col;
3571 if (xx >= tileWidth)
3572 break;
3573 p_in = p_in_base + xx;
3574 if (*p_in == nd)
3575 nodata++;
3576 else
3577 {
3578 valid++;
3579 sum += *p_in;
3580 }
3581 }
3582 }
3583
3584 if (nodata >= valid)
3585 return;
3586 *p_out = (char) (sum / (double) valid);
3587 *p_msk = 1;
3588 }
3589
3590 static void
rescale_datagrid_u8(unsigned int tileWidth,unsigned int tileHeight,unsigned int out_width,unsigned int out_height,unsigned int factor,unsigned char * buf_in,unsigned char * buf_out,unsigned char * mask,unsigned int x,unsigned int y,unsigned int ox,unsigned int oy,unsigned char nd)3591 rescale_datagrid_u8 (unsigned int tileWidth, unsigned int tileHeight,
3592 unsigned int out_width, unsigned int out_height,
3593 unsigned int factor, unsigned char *buf_in,
3594 unsigned char *buf_out, unsigned char *mask,
3595 unsigned int x, unsigned int y, unsigned int ox,
3596 unsigned int oy, unsigned char nd)
3597 {
3598 /* rescaling a DataGrid (monolithic)- UINT8 */
3599 unsigned int row;
3600 unsigned int col;
3601 int nodata = 0;
3602 int valid = 0;
3603 double sum = 0.0;
3604 unsigned char *p_out;
3605 unsigned char *p_msk;
3606
3607 if (ox >= out_width || oy >= out_height)
3608 return;
3609 p_out = buf_out + (out_width * oy) + ox;
3610 p_msk = mask + (out_width * oy) + ox;
3611
3612 for (row = 0; row < factor; row++)
3613 {
3614 const unsigned char *p_in_base;
3615 unsigned int yy = y + row;
3616 if (yy >= tileHeight)
3617 break;
3618 p_in_base = buf_in + (yy * tileWidth);
3619 for (col = 0; col < factor; col++)
3620 {
3621 const unsigned char *p_in;
3622 unsigned int xx = x + col;
3623 if (xx >= tileWidth)
3624 break;
3625 p_in = p_in_base + xx;
3626 if (*p_in == nd)
3627 nodata++;
3628 else
3629 {
3630 valid++;
3631 sum += *p_in;
3632 }
3633 }
3634 }
3635
3636 if (nodata >= valid)
3637 return;
3638 *p_out = (unsigned char) (sum / (double) valid);
3639 *p_msk = 1;
3640 }
3641
3642 static void
rescale_datagrid_16(unsigned int tileWidth,unsigned int tileHeight,unsigned int out_width,unsigned int out_height,unsigned int factor,short * buf_in,short * buf_out,unsigned char * mask,unsigned int x,unsigned int y,unsigned int ox,unsigned int oy,short nd)3643 rescale_datagrid_16 (unsigned int tileWidth, unsigned int tileHeight,
3644 unsigned int out_width, unsigned int out_height,
3645 unsigned int factor, short *buf_in, short *buf_out,
3646 unsigned char *mask, unsigned int x, unsigned int y,
3647 unsigned int ox, unsigned int oy, short nd)
3648 {
3649 /* rescaling a DataGrid (monolithic)- INT16 */
3650 unsigned int row;
3651 unsigned int col;
3652 int nodata = 0;
3653 int valid = 0;
3654 double sum = 0.0;
3655 short *p_out;
3656 unsigned char *p_msk;
3657
3658 if (ox >= out_width || oy >= out_height)
3659 return;
3660 p_out = buf_out + (out_width * oy) + ox;
3661 p_msk = mask + (out_width * oy) + ox;
3662
3663 for (row = 0; row < factor; row++)
3664 {
3665 const short *p_in_base;
3666 unsigned int yy = y + row;
3667 if (yy >= tileHeight)
3668 break;
3669 p_in_base = buf_in + (yy * tileWidth);
3670 for (col = 0; col < factor; col++)
3671 {
3672 const short *p_in;
3673 unsigned int xx = x + col;
3674 if (xx >= tileWidth)
3675 break;
3676 p_in = p_in_base + xx;
3677 if (*p_in == nd)
3678 nodata++;
3679 else
3680 {
3681 valid++;
3682 sum += *p_in;
3683 }
3684 }
3685 }
3686
3687 if (nodata >= valid)
3688 return;
3689 *p_out = (short) (sum / (double) valid);
3690 *p_msk = 1;
3691 }
3692
3693 static void
rescale_datagrid_u16(unsigned int tileWidth,unsigned int tileHeight,unsigned int out_width,unsigned int out_height,unsigned int factor,unsigned short * buf_in,unsigned short * buf_out,unsigned char * mask,unsigned int x,unsigned int y,unsigned int ox,unsigned int oy,unsigned short nd)3694 rescale_datagrid_u16 (unsigned int tileWidth, unsigned int tileHeight,
3695 unsigned int out_width, unsigned int out_height,
3696 unsigned int factor, unsigned short *buf_in,
3697 unsigned short *buf_out, unsigned char *mask,
3698 unsigned int x, unsigned int y, unsigned int ox,
3699 unsigned int oy, unsigned short nd)
3700 {
3701 /* rescaling a DataGrid (monolithic)- UINT16 */
3702 unsigned int row;
3703 unsigned int col;
3704 int nodata = 0;
3705 int valid = 0;
3706 double sum = 0.0;
3707 unsigned short *p_out;
3708 unsigned char *p_msk;
3709
3710 if (ox >= out_width || oy >= out_height)
3711 return;
3712 p_out = buf_out + (out_width * oy) + ox;
3713 p_msk = mask + (out_width * oy) + ox;
3714
3715 for (row = 0; row < factor; row++)
3716 {
3717 const unsigned short *p_in_base;
3718 unsigned int yy = y + row;
3719 if (yy >= tileHeight)
3720 break;
3721 p_in_base = buf_in + (yy * tileWidth);
3722 for (col = 0; col < factor; col++)
3723 {
3724 const unsigned short *p_in;
3725 unsigned int xx = x + col;
3726 if (xx >= tileWidth)
3727 break;
3728 p_in = p_in_base + xx;
3729 if (*p_in == nd)
3730 nodata++;
3731 else
3732 {
3733 valid++;
3734 sum += *p_in;
3735 }
3736 }
3737 }
3738
3739 if (nodata >= valid)
3740 return;
3741 *p_out = (unsigned short) (sum / (double) valid);
3742 *p_msk = 1;
3743 }
3744
3745 static void
rescale_datagrid_32(unsigned int tileWidth,unsigned int tileHeight,unsigned int out_width,unsigned int out_height,unsigned int factor,int * buf_in,int * buf_out,unsigned char * mask,unsigned int x,unsigned int y,unsigned int ox,unsigned int oy,int nd)3746 rescale_datagrid_32 (unsigned int tileWidth, unsigned int tileHeight,
3747 unsigned int out_width, unsigned int out_height,
3748 unsigned int factor, int *buf_in, int *buf_out,
3749 unsigned char *mask, unsigned int x, unsigned int y,
3750 unsigned int ox, unsigned int oy, int nd)
3751 {
3752 /* rescaling a DataGrid (monolithic)- INT32 */
3753 unsigned int row;
3754 unsigned int col;
3755 int nodata = 0;
3756 int valid = 0;
3757 double sum = 0.0;
3758 int *p_out;
3759 unsigned char *p_msk;
3760
3761 if (ox >= out_width || oy >= out_height)
3762 return;
3763 p_out = buf_out + (out_width * oy) + ox;
3764 p_msk = mask + (out_width * oy) + ox;
3765
3766 for (row = 0; row < factor; row++)
3767 {
3768 const int *p_in_base;
3769 unsigned int yy = y + row;
3770 if (yy >= tileHeight)
3771 break;
3772 p_in_base = buf_in + (yy * tileWidth);
3773 for (col = 0; col < factor; col++)
3774 {
3775 const int *p_in;
3776 unsigned int xx = x + col;
3777 if (xx >= tileWidth)
3778 break;
3779 p_in = p_in_base + xx;
3780 if (*p_in == nd)
3781 nodata++;
3782 else
3783 {
3784 valid++;
3785 sum += *p_in;
3786 }
3787 }
3788 }
3789
3790 if (nodata >= valid)
3791 return;
3792 *p_out = (int) (sum / (double) valid);
3793 *p_msk = 1;
3794 }
3795
3796 static void
rescale_datagrid_u32(unsigned int tileWidth,unsigned int tileHeight,unsigned int out_width,unsigned int out_height,unsigned int factor,unsigned int * buf_in,unsigned int * buf_out,unsigned char * mask,unsigned int x,unsigned int y,unsigned int ox,unsigned int oy,unsigned int nd)3797 rescale_datagrid_u32 (unsigned int tileWidth, unsigned int tileHeight,
3798 unsigned int out_width, unsigned int out_height,
3799 unsigned int factor, unsigned int *buf_in,
3800 unsigned int *buf_out, unsigned char *mask,
3801 unsigned int x, unsigned int y, unsigned int ox,
3802 unsigned int oy, unsigned int nd)
3803 {
3804 /* rescaling a DataGrid (monolithic)- UINT32 */
3805 unsigned int row;
3806 unsigned int col;
3807 int nodata = 0;
3808 int valid = 0;
3809 double sum = 0.0;
3810 unsigned int *p_out;
3811 unsigned char *p_msk;
3812
3813 if (ox >= out_width || oy >= out_height)
3814 return;
3815 p_out = buf_out + (out_width * oy) + ox;
3816 p_msk = mask + (out_width * oy) + ox;
3817
3818 for (row = 0; row < factor; row++)
3819 {
3820 const unsigned int *p_in_base;
3821 unsigned int yy = y + row;
3822 if (yy >= tileHeight)
3823 break;
3824 p_in_base = buf_in + (yy * tileWidth);
3825 for (col = 0; col < factor; col++)
3826 {
3827 const unsigned int *p_in;
3828 unsigned int xx = x + col;
3829 if (xx >= tileWidth)
3830 break;
3831 p_in = p_in_base + xx;
3832 if (*p_in == nd)
3833 nodata++;
3834 else
3835 {
3836 valid++;
3837 sum += *p_in;
3838 }
3839 }
3840 }
3841
3842 if (nodata >= valid)
3843 return;
3844 *p_out = (unsigned int) (sum / (double) valid);
3845 *p_msk = 1;
3846 }
3847
3848 static void
rescale_datagrid_flt(unsigned int tileWidth,unsigned int tileHeight,unsigned int out_width,unsigned int out_height,unsigned int factor,float * buf_in,float * buf_out,unsigned char * mask,unsigned int x,unsigned int y,unsigned int ox,unsigned int oy,float nd)3849 rescale_datagrid_flt (unsigned int tileWidth, unsigned int tileHeight,
3850 unsigned int out_width, unsigned int out_height,
3851 unsigned int factor, float *buf_in, float *buf_out,
3852 unsigned char *mask, unsigned int x, unsigned int y,
3853 unsigned int ox, unsigned int oy, float nd)
3854 {
3855 /* rescaling a DataGrid (monolithic)- FLOAT */
3856 unsigned int row;
3857 unsigned int col;
3858 int nodata = 0;
3859 int valid = 0;
3860 double sum = 0.0;
3861 float *p_out;
3862 unsigned char *p_msk;
3863
3864 if (ox >= out_width || oy >= out_height)
3865 return;
3866 p_out = buf_out + (out_width * oy) + ox;
3867 p_msk = mask + (out_width * oy) + ox;
3868
3869 for (row = 0; row < factor; row++)
3870 {
3871 const float *p_in_base;
3872 unsigned int yy = y + row;
3873 if (yy >= tileHeight)
3874 break;
3875 p_in_base = buf_in + (yy * tileWidth);
3876 for (col = 0; col < factor; col++)
3877 {
3878 const float *p_in;
3879 unsigned int xx = x + col;
3880 if (xx >= tileWidth)
3881 break;
3882 p_in = p_in_base + xx;
3883 if (*p_in == nd)
3884 nodata++;
3885 else
3886 {
3887 valid++;
3888 sum += *p_in;
3889 }
3890 }
3891 }
3892
3893 if (nodata >= valid)
3894 return;
3895 *p_out = (float) (sum / (double) valid);
3896 *p_msk = 1;
3897 }
3898
3899 static void
rescale_datagrid_dbl(unsigned int tileWidth,unsigned int tileHeight,unsigned int out_width,unsigned int out_height,unsigned int factor,double * buf_in,double * buf_out,unsigned char * mask,unsigned int x,unsigned int y,unsigned int ox,unsigned int oy,double nd)3900 rescale_datagrid_dbl (unsigned int tileWidth, unsigned int tileHeight,
3901 unsigned int out_width, unsigned int out_height,
3902 unsigned int factor, double *buf_in, double *buf_out,
3903 unsigned char *mask, unsigned int x, unsigned int y,
3904 unsigned int ox, unsigned int oy, double nd)
3905 {
3906 /* rescaling a DataGrid (monolithic)- DOUBLE */
3907 unsigned int row;
3908 unsigned int col;
3909 int nodata = 0;
3910 int valid = 0;
3911 double sum = 0.0;
3912 double *p_out;
3913 unsigned char *p_msk;
3914
3915 if (ox >= out_width || oy >= out_height)
3916 return;
3917 p_out = buf_out + (out_width * oy) + ox;
3918 p_msk = mask + (out_width * oy) + ox;
3919
3920 for (row = 0; row < factor; row++)
3921 {
3922 const double *p_in_base;
3923 unsigned int yy = y + row;
3924 if (yy >= tileHeight)
3925 break;
3926 p_in_base = buf_in + (yy * tileWidth);
3927 for (col = 0; col < factor; col++)
3928 {
3929 const double *p_in;
3930 unsigned int xx = x + col;
3931 if (xx >= tileWidth)
3932 break;
3933 p_in = p_in_base + xx;
3934 if (*p_in == nd)
3935 nodata++;
3936 else
3937 {
3938 valid++;
3939 sum += *p_in;
3940 }
3941 }
3942 }
3943
3944 if (nodata >= valid)
3945 return;
3946 *p_out = (double) (sum / (double) valid);
3947 *p_msk = 1;
3948 }
3949
3950 static rl2RasterPtr
create_rescaled_datagrid_raster(unsigned int factor,unsigned int tileWidth,unsigned int tileHeight,const void * buf_in,unsigned char sample_type,rl2PixelPtr no_data)3951 create_rescaled_datagrid_raster (unsigned int factor, unsigned int tileWidth,
3952 unsigned int tileHeight, const void *buf_in,
3953 unsigned char sample_type, rl2PixelPtr no_data)
3954 {
3955 /* rescaling a Datagrid tile */
3956 rl2PrivPixelPtr pxl;
3957 unsigned int x;
3958 unsigned int y;
3959 unsigned int ox;
3960 unsigned int oy;
3961 rl2RasterPtr raster = NULL;
3962 unsigned char *mask;
3963 void *buf;
3964 unsigned int mask_sz;
3965 unsigned char pix_sz = 1;
3966 unsigned int buf_sz;
3967 unsigned int out_width = tileWidth / factor;
3968 unsigned int out_height = tileHeight / factor;
3969 char no_data_8 = 0;
3970 unsigned char no_data_u8 = 0;
3971 short no_data_16 = 0;
3972 unsigned short no_data_u16 = 0;
3973 int no_data_32 = 0;
3974 unsigned int no_data_u32 = 0;
3975 float no_data_flt = 0.0;
3976 double no_data_dbl = 0.0;
3977
3978 /* retrieving NO-DATA */
3979 pxl = (rl2PrivPixelPtr) no_data;
3980 if (pxl != NULL)
3981 {
3982 if (pxl->nBands == 1 && pxl->pixelType == RL2_PIXEL_DATAGRID
3983 && pxl->sampleType == sample_type)
3984 {
3985 rl2PrivSamplePtr sample = pxl->Samples;
3986 switch (sample_type)
3987 {
3988 case RL2_SAMPLE_INT8:
3989 no_data_8 = sample->int8;
3990 break;
3991 case RL2_SAMPLE_UINT8:
3992 no_data_u8 = sample->uint8;
3993 break;
3994 case RL2_SAMPLE_INT16:
3995 no_data_16 = sample->int16;
3996 break;
3997 case RL2_SAMPLE_UINT16:
3998 no_data_u16 = sample->uint16;
3999 break;
4000 case RL2_SAMPLE_INT32:
4001 no_data_32 = sample->int32;
4002 break;
4003 case RL2_SAMPLE_UINT32:
4004 no_data_u32 = sample->uint32;
4005 break;
4006 case RL2_SAMPLE_FLOAT:
4007 no_data_flt = sample->float32;
4008 break;
4009 case RL2_SAMPLE_DOUBLE:
4010 no_data_dbl = sample->float64;
4011 break;
4012 };
4013 }
4014 }
4015 /* computing sizes */
4016 mask_sz = out_width * out_height;
4017 switch (sample_type)
4018 {
4019 case RL2_SAMPLE_INT16:
4020 case RL2_SAMPLE_UINT16:
4021 pix_sz = 2;
4022 break;
4023 case RL2_SAMPLE_INT32:
4024 case RL2_SAMPLE_UINT32:
4025 case RL2_SAMPLE_FLOAT:
4026 pix_sz = 4;
4027 break;
4028 case RL2_SAMPLE_DOUBLE:
4029 pix_sz = 8;
4030 break;
4031 };
4032 buf_sz = out_width * out_height * pix_sz;
4033 buf = malloc (buf_sz);
4034 if (buf == NULL)
4035 return NULL;
4036 mask = malloc (mask_sz);
4037 if (mask == NULL)
4038 {
4039 free (buf);
4040 return NULL;
4041 }
4042 rl2_prime_void_tile (buf, out_width, out_height, sample_type, 1, no_data);
4043 memset (mask, 0, mask_sz);
4044
4045 oy = 0;
4046 for (y = 0; y < tileHeight; y += factor)
4047 {
4048 ox = 0;
4049 for (x = 0; x < tileWidth; x += factor)
4050 {
4051 switch (sample_type)
4052 {
4053 case RL2_SAMPLE_INT8:
4054 rescale_datagrid_8 (tileWidth, tileHeight, out_width,
4055 out_height, factor, (char *) buf_in,
4056 (char *) buf, mask, x, y, ox, oy,
4057 no_data_8);
4058 break;
4059 case RL2_SAMPLE_UINT8:
4060 rescale_datagrid_u8 (tileWidth, tileHeight, out_width,
4061 out_height, factor,
4062 (unsigned char *) buf_in,
4063 (unsigned char *) buf, mask, x, y,
4064 ox, oy, no_data_u8);
4065 break;
4066 case RL2_SAMPLE_INT16:
4067 rescale_datagrid_16 (tileWidth, tileHeight, out_width,
4068 out_height, factor, (short *) buf_in,
4069 (short *) buf, mask, x, y, ox, oy,
4070 no_data_16);
4071 break;
4072 case RL2_SAMPLE_UINT16:
4073 rescale_datagrid_u16 (tileWidth, tileHeight, out_width,
4074 out_height, factor,
4075 (unsigned short *) buf_in,
4076 (unsigned short *) buf, mask, x, y,
4077 ox, oy, no_data_u16);
4078 break;
4079 case RL2_SAMPLE_INT32:
4080 rescale_datagrid_32 (tileWidth, tileHeight, out_width,
4081 out_height, factor, (int *) buf_in,
4082 (int *) buf, mask, x, y, ox, oy,
4083 no_data_32);
4084 break;
4085 case RL2_SAMPLE_UINT32:
4086 rescale_datagrid_u32 (tileWidth, tileHeight, out_width,
4087 out_height, factor,
4088 (unsigned int *) buf_in,
4089 (unsigned int *) buf, mask, x, y,
4090 ox, oy, no_data_u32);
4091 break;
4092 case RL2_SAMPLE_FLOAT:
4093 rescale_datagrid_flt (tileWidth, tileHeight, out_width,
4094 out_height, factor,
4095 (float *) buf_in, (float *) buf,
4096 mask, x, y, ox, oy, no_data_flt);
4097 break;
4098 case RL2_SAMPLE_DOUBLE:
4099 rescale_datagrid_dbl (tileWidth, tileHeight, out_width,
4100 out_height, factor,
4101 (double *) buf_in, (double *) buf,
4102 mask, x, y, ox, oy, no_data_dbl);
4103 break;
4104 };
4105 ox++;
4106 }
4107 oy++;
4108 }
4109
4110 raster =
4111 rl2_create_raster (out_width, out_height, sample_type,
4112 RL2_PIXEL_DATAGRID, 1, buf, buf_sz, NULL, mask,
4113 mask_sz, NULL);
4114 return raster;
4115 }
4116
4117 static int
rescale_monolithic_multiband(int id_level,unsigned int tileWidth,unsigned int tileHeight,unsigned char sample_type,unsigned char num_bands,int factor,double res_x,double res_y,double minx,double miny,double maxx,double maxy,unsigned char * buffer,int buf_size,unsigned char * mask,int * mask_size,rl2PixelPtr no_data,sqlite3_stmt * stmt_geo,sqlite3_stmt * stmt_data)4118 rescale_monolithic_multiband (int id_level,
4119 unsigned int tileWidth, unsigned int tileHeight,
4120 unsigned char sample_type,
4121 unsigned char num_bands, int factor, double res_x,
4122 double res_y, double minx, double miny,
4123 double maxx, double maxy, unsigned char *buffer,
4124 int buf_size, unsigned char *mask, int *mask_size,
4125 rl2PixelPtr no_data, sqlite3_stmt * stmt_geo,
4126 sqlite3_stmt * stmt_data)
4127 {
4128 /* rescaling monolithic MultiBand */
4129 rl2RasterPtr raster = NULL;
4130 rl2RasterPtr base_tile = NULL;
4131 rl2PrivRasterPtr rst;
4132 unsigned int x;
4133 unsigned int y;
4134 int ret;
4135 double shift_x;
4136 double shift_y;
4137 int valid_mask = 0;
4138 unsigned char *p_in;
4139 unsigned char *p_out;
4140 rl2PixelPtr nd = NULL;
4141
4142 nd = rl2_clone_pixel (no_data);
4143 p_out = mask;
4144 for (y = 0; y < tileHeight; y++)
4145 {
4146 /* priming full transparency */
4147 for (x = 0; x < tileWidth; x++)
4148 *p_out++ = 0;
4149 }
4150 rl2_prime_void_tile (buffer, tileWidth, tileHeight, sample_type, num_bands,
4151 no_data);
4152 /* creating the output raster */
4153 raster =
4154 rl2_create_raster (tileWidth, tileHeight, sample_type,
4155 RL2_PIXEL_MULTIBAND, num_bands, buffer, buf_size,
4156 NULL, mask, *mask_size, nd);
4157 if (raster == NULL)
4158 goto error;
4159
4160 /* binding the BBOX to be queried */
4161 sqlite3_reset (stmt_geo);
4162 sqlite3_clear_bindings (stmt_geo);
4163 sqlite3_bind_int (stmt_geo, 1, id_level);
4164 sqlite3_bind_double (stmt_geo, 2, minx);
4165 sqlite3_bind_double (stmt_geo, 3, miny);
4166 sqlite3_bind_double (stmt_geo, 4, maxx);
4167 sqlite3_bind_double (stmt_geo, 5, maxy);
4168 while (1)
4169 {
4170 /* scrolling the result set rows */
4171 ret = sqlite3_step (stmt_geo);
4172 if (ret == SQLITE_DONE)
4173 break; /* end of result set */
4174 if (ret == SQLITE_ROW)
4175 {
4176 rl2RasterPtr raster_in = NULL;
4177 rl2PrivRasterPtr rst_in;
4178 sqlite3_int64 tile_id = sqlite3_column_int64 (stmt_geo, 0);
4179 double tile_x = sqlite3_column_double (stmt_geo, 1);
4180 double tile_y = sqlite3_column_double (stmt_geo, 2);
4181
4182 raster_in = load_tile_base_generic (stmt_data, tile_id);
4183 rst_in = (rl2PrivRasterPtr) raster_in;
4184 base_tile =
4185 create_rescaled_multiband_raster (factor, tileWidth,
4186 tileHeight,
4187 rst_in->rasterBuffer,
4188 rst_in->maskBuffer,
4189 sample_type, num_bands,
4190 no_data);
4191 rl2_destroy_raster (raster_in);
4192 raster_in = NULL;
4193
4194 if (base_tile == NULL)
4195 goto error;
4196 shift_x = tile_x - minx;
4197 shift_y = maxy - tile_y;
4198 x = (int) (shift_x / res_x);
4199 y = (int) (shift_y / res_y);
4200 copy_multiband_rescaled (raster, base_tile, x, y);
4201 rl2_destroy_raster (base_tile);
4202 }
4203 }
4204
4205 /* releasing buffers ownership */
4206 rst = (rl2PrivRasterPtr) raster;
4207 rst->rasterBuffer = NULL;
4208 rst->maskBuffer = NULL;
4209 rl2_destroy_raster (raster);
4210
4211 p_in = mask;
4212 for (y = 0; y < tileHeight; y++)
4213 {
4214 for (x = 0; x < tileWidth; x++)
4215 {
4216 if (*p_in++ == 0)
4217 valid_mask = 1;
4218 }
4219 }
4220 if (!valid_mask)
4221 {
4222 free (mask);
4223 *mask_size = 0;
4224 }
4225
4226 return 1;
4227 error:
4228 if (raster != NULL)
4229 {
4230 /* releasing buffers ownership */
4231 rst = (rl2PrivRasterPtr) raster;
4232 rst->rasterBuffer = NULL;
4233 rst->maskBuffer = NULL;
4234 rl2_destroy_raster (raster);
4235 }
4236 return 0;
4237 }
4238
4239 static int
rescale_monolithic_datagrid(int id_level,unsigned int tileWidth,unsigned int tileHeight,unsigned char sample_type,int factor,double res_x,double res_y,double minx,double miny,double maxx,double maxy,unsigned char * buffer,int buf_size,unsigned char * mask,int * mask_size,rl2PixelPtr no_data,sqlite3_stmt * stmt_geo,sqlite3_stmt * stmt_data)4240 rescale_monolithic_datagrid (int id_level,
4241 unsigned int tileWidth, unsigned int tileHeight,
4242 unsigned char sample_type, int factor,
4243 double res_x, double res_y, double minx,
4244 double miny, double maxx, double maxy,
4245 unsigned char *buffer, int buf_size,
4246 unsigned char *mask, int *mask_size,
4247 rl2PixelPtr no_data, sqlite3_stmt * stmt_geo,
4248 sqlite3_stmt * stmt_data)
4249 {
4250 /* rescaling monolithic DataGrid */
4251 rl2RasterPtr raster = NULL;
4252 rl2RasterPtr base_tile = NULL;
4253 rl2PrivRasterPtr rst;
4254 unsigned int x;
4255 unsigned int y;
4256 int ret;
4257 double shift_x;
4258 double shift_y;
4259 int valid_mask = 0;
4260 unsigned char *p_in;
4261 unsigned char *p_out;
4262 rl2PixelPtr nd = NULL;
4263
4264 nd = rl2_clone_pixel (no_data);
4265 p_out = mask;
4266 for (y = 0; y < tileHeight; y++)
4267 {
4268 /* priming full transparency */
4269 for (x = 0; x < tileWidth; x++)
4270 *p_out++ = 0;
4271 }
4272 rl2_prime_void_tile (buffer, tileWidth, tileHeight, sample_type, 1,
4273 no_data);
4274 /* creating the output raster */
4275 raster =
4276 rl2_create_raster (tileWidth, tileHeight, sample_type,
4277 RL2_PIXEL_DATAGRID, 1, buffer, buf_size,
4278 NULL, mask, *mask_size, nd);
4279 if (raster == NULL)
4280 goto error;
4281
4282 /* binding the BBOX to be queried */
4283 sqlite3_reset (stmt_geo);
4284 sqlite3_clear_bindings (stmt_geo);
4285 sqlite3_bind_int (stmt_geo, 1, id_level);
4286 sqlite3_bind_double (stmt_geo, 2, minx);
4287 sqlite3_bind_double (stmt_geo, 3, miny);
4288 sqlite3_bind_double (stmt_geo, 4, maxx);
4289 sqlite3_bind_double (stmt_geo, 5, maxy);
4290 while (1)
4291 {
4292 /* scrolling the result set rows */
4293 ret = sqlite3_step (stmt_geo);
4294 if (ret == SQLITE_DONE)
4295 break; /* end of result set */
4296 if (ret == SQLITE_ROW)
4297 {
4298 rl2RasterPtr raster_in = NULL;
4299 rl2PrivRasterPtr rst_in;
4300 sqlite3_int64 tile_id = sqlite3_column_int64 (stmt_geo, 0);
4301 double tile_x = sqlite3_column_double (stmt_geo, 1);
4302 double tile_y = sqlite3_column_double (stmt_geo, 2);
4303
4304 raster_in = load_tile_base_generic (stmt_data, tile_id);
4305 rst_in = (rl2PrivRasterPtr) raster_in;
4306 base_tile =
4307 create_rescaled_datagrid_raster (factor, tileWidth,
4308 tileHeight,
4309 rst_in->rasterBuffer,
4310 sample_type, no_data);
4311 rl2_destroy_raster (raster_in);
4312 raster_in = NULL;
4313
4314 if (base_tile == NULL)
4315 goto error;
4316 shift_x = tile_x - minx;
4317 shift_y = maxy - tile_y;
4318 x = (int) (shift_x / res_x);
4319 y = (int) (shift_y / res_y);
4320 copy_datagrid_rescaled (raster, base_tile, x, y);
4321 rl2_destroy_raster (base_tile);
4322 }
4323 }
4324
4325 /* releasing buffers ownership */
4326 rst = (rl2PrivRasterPtr) raster;
4327 rst->rasterBuffer = NULL;
4328 rst->maskBuffer = NULL;
4329 rl2_destroy_raster (raster);
4330
4331 p_in = mask;
4332 for (y = 0; y < tileHeight; y++)
4333 {
4334 for (x = 0; x < tileWidth; x++)
4335 {
4336 if (*p_in++ == 0)
4337 valid_mask = 1;
4338 }
4339 }
4340 if (!valid_mask)
4341 {
4342 free (mask);
4343 *mask_size = 0;
4344 }
4345
4346 return 1;
4347 error:
4348 if (raster != NULL)
4349 {
4350 /* releasing buffers ownership */
4351 rst = (rl2PrivRasterPtr) raster;
4352 rst->rasterBuffer = NULL;
4353 rst->maskBuffer = NULL;
4354 rl2_destroy_raster (raster);
4355 }
4356 return 0;
4357 }
4358
4359 static int
prepare_section_pyramid_stmts(sqlite3 * handle,const char * coverage,sqlite3_stmt ** xstmt_rd,sqlite3_stmt ** xstmt_levl,sqlite3_stmt ** xstmt_tils,sqlite3_stmt ** xstmt_data)4360 prepare_section_pyramid_stmts (sqlite3 * handle, const char *coverage,
4361 sqlite3_stmt ** xstmt_rd,
4362 sqlite3_stmt ** xstmt_levl,
4363 sqlite3_stmt ** xstmt_tils,
4364 sqlite3_stmt ** xstmt_data)
4365 {
4366 /* preparing the section pyramid related SQL statements */
4367 char *table_tile_data;
4368 char *xtable_tile_data;
4369 char *table;
4370 char *xtable;
4371 char *sql;
4372 sqlite3_stmt *stmt_rd = NULL;
4373 sqlite3_stmt *stmt_levl = NULL;
4374 sqlite3_stmt *stmt_tils = NULL;
4375 sqlite3_stmt *stmt_data = NULL;
4376 int ret;
4377
4378 *xstmt_rd = NULL;
4379 *xstmt_levl = NULL;
4380 *xstmt_tils = NULL;
4381 *xstmt_data = NULL;
4382
4383 table_tile_data = sqlite3_mprintf ("%s_tile_data", coverage);
4384 xtable_tile_data = gaiaDoubleQuotedSql (table_tile_data);
4385 sqlite3_free (table_tile_data);
4386 sql = sqlite3_mprintf ("SELECT tile_data_odd, tile_data_even "
4387 "FROM \"%s\" WHERE tile_id = ?", xtable_tile_data);
4388 free (xtable_tile_data);
4389 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_rd, NULL);
4390 sqlite3_free (sql);
4391 if (ret != SQLITE_OK)
4392 {
4393 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
4394 goto error;
4395 }
4396 table = sqlite3_mprintf ("%s_levels", coverage);
4397 xtable = gaiaDoubleQuotedSql (table);
4398 sqlite3_free (table);
4399 sql =
4400 sqlite3_mprintf
4401 ("INSERT OR IGNORE INTO \"%s\" (pyramid_level, "
4402 "x_resolution_1_1, y_resolution_1_1, "
4403 "x_resolution_1_2, y_resolution_1_2, x_resolution_1_4, "
4404 "y_resolution_1_4, x_resolution_1_8, y_resolution_1_8) "
4405 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", xtable);
4406 free (xtable);
4407 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_levl, NULL);
4408 sqlite3_free (sql);
4409 if (ret != SQLITE_OK)
4410 {
4411 printf ("INSERT INTO levels SQL error: %s\n",
4412 sqlite3_errmsg (handle));
4413 goto error;
4414 }
4415
4416 table = sqlite3_mprintf ("%s_tiles", coverage);
4417 xtable = gaiaDoubleQuotedSql (table);
4418 sqlite3_free (table);
4419 sql =
4420 sqlite3_mprintf
4421 ("INSERT INTO \"%s\" (tile_id, pyramid_level, section_id, geometry) "
4422 "VALUES (NULL, ?, ?, ?)", xtable);
4423 free (xtable);
4424 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_tils, NULL);
4425 sqlite3_free (sql);
4426 if (ret != SQLITE_OK)
4427 {
4428 printf ("INSERT INTO tiles SQL error: %s\n", sqlite3_errmsg (handle));
4429 goto error;
4430 }
4431
4432 table = sqlite3_mprintf ("%s_tile_data", coverage);
4433 xtable = gaiaDoubleQuotedSql (table);
4434 sqlite3_free (table);
4435 sql =
4436 sqlite3_mprintf
4437 ("INSERT INTO \"%s\" (tile_id, tile_data_odd, tile_data_even) "
4438 "VALUES (?, ?, ?)", xtable);
4439 free (xtable);
4440 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_data, NULL);
4441 sqlite3_free (sql);
4442 if (ret != SQLITE_OK)
4443 {
4444 printf ("INSERT INTO tile_data SQL error: %s\n",
4445 sqlite3_errmsg (handle));
4446 goto error;
4447 }
4448
4449 *xstmt_rd = stmt_rd;
4450 *xstmt_levl = stmt_levl;
4451 *xstmt_tils = stmt_tils;
4452 *xstmt_data = stmt_data;
4453 return 1;
4454
4455 error:
4456 if (stmt_rd != NULL)
4457 sqlite3_finalize (stmt_rd);
4458 if (stmt_levl != NULL)
4459 sqlite3_finalize (stmt_levl);
4460 if (stmt_tils != NULL)
4461 sqlite3_finalize (stmt_tils);
4462 if (stmt_data != NULL)
4463 sqlite3_finalize (stmt_data);
4464 return 0;
4465 }
4466
4467 static int
do_build_section_pyramid(sqlite3 * handle,const char * coverage,const char * section,unsigned char sample_type,unsigned char pixel_type,unsigned char num_samples,unsigned char compression,int quality,int srid,unsigned int tileWidth,unsigned int tileHeight)4468 do_build_section_pyramid (sqlite3 * handle, const char *coverage,
4469 const char *section, unsigned char sample_type,
4470 unsigned char pixel_type, unsigned char num_samples,
4471 unsigned char compression, int quality, int srid,
4472 unsigned int tileWidth, unsigned int tileHeight)
4473 {
4474 /* attempting to (re)build a section pyramid from scratch */
4475 char *table_levels;
4476 char *xtable_levels;
4477 char *table_tiles;
4478 char *xtable_tiles;
4479 char *sql;
4480 int id_level = 0;
4481 double new_res_x;
4482 double new_res_y;
4483 sqlite3_int64 sect_id;
4484 unsigned int sect_width;
4485 unsigned int sect_height;
4486 double minx;
4487 double miny;
4488 double maxx;
4489 double maxy;
4490 unsigned int row;
4491 unsigned int col;
4492 double out_minx;
4493 double out_miny;
4494 double out_maxx;
4495 double out_maxy;
4496 sqlite3_stmt *stmt = NULL;
4497 sqlite3_stmt *stmt_rd = NULL;
4498 sqlite3_stmt *stmt_levl = NULL;
4499 sqlite3_stmt *stmt_tils = NULL;
4500 sqlite3_stmt *stmt_data = NULL;
4501 SectionPyramid *pyr = NULL;
4502 int ret;
4503 int first;
4504 int scale;
4505 rl2PalettePtr palette = NULL;
4506 rl2PixelPtr no_data = NULL;
4507
4508 if (!get_section_infos
4509 (handle, coverage, section, §_id, §_width, §_height, &minx,
4510 &miny, &maxx, &maxy, &palette, &no_data))
4511 goto error;
4512
4513 if (!prepare_section_pyramid_stmts
4514 (handle, coverage, &stmt_rd, &stmt_levl, &stmt_tils, &stmt_data))
4515 goto error;
4516
4517 while (1)
4518 {
4519 /* looping on pyramid levels */
4520 table_levels = sqlite3_mprintf ("%s_levels", coverage);
4521 xtable_levels = gaiaDoubleQuotedSql (table_levels);
4522 sqlite3_free (table_levels);
4523 table_tiles = sqlite3_mprintf ("%s_tiles", coverage);
4524 xtable_tiles = gaiaDoubleQuotedSql (table_tiles);
4525 sqlite3_free (table_tiles);
4526 sql =
4527 sqlite3_mprintf ("SELECT l.x_resolution_1_1, l.y_resolution_1_1, "
4528 "t.tile_id, MbrMinX(t.geometry), MbrMinY(t.geometry), "
4529 "MbrMaxX(t.geometry), MbrMaxY(t.geometry) "
4530 "FROM \"%s\" AS l "
4531 "JOIN \"%s\" AS t ON (l.pyramid_level = t.pyramid_level) "
4532 "WHERE l.pyramid_level = %d AND t.section_id = %d",
4533 xtable_levels, xtable_tiles, id_level, sect_id);
4534 free (xtable_levels);
4535 free (xtable_tiles);
4536 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
4537 sqlite3_free (sql);
4538 if (ret != SQLITE_OK)
4539 {
4540 fprintf (stderr, "SQL error: %s\n%s\n", sql,
4541 sqlite3_errmsg (handle));
4542 goto error;
4543 }
4544 first = 1;
4545 while (1)
4546 {
4547 ret = sqlite3_step (stmt);
4548 if (ret == SQLITE_DONE)
4549 break;
4550 if (ret == SQLITE_ROW)
4551 {
4552 double res_x = sqlite3_column_double (stmt, 0);
4553 double res_y = sqlite3_column_double (stmt, 1);
4554 sqlite3_int64 tile_id = sqlite3_column_int64 (stmt, 2);
4555 double tminx = sqlite3_column_double (stmt, 3);
4556 double tminy = sqlite3_column_double (stmt, 4);
4557 double tmaxx = sqlite3_column_double (stmt, 5);
4558 double tmaxy = sqlite3_column_double (stmt, 6);
4559 new_res_x = res_x * 8.0;
4560 new_res_y = res_y * 8.0;
4561 scale = 8;
4562 if (first)
4563 {
4564 pyr =
4565 alloc_sect_pyramid (sect_id, sect_width,
4566 sect_height, sample_type,
4567 pixel_type, num_samples,
4568 compression, quality, srid,
4569 new_res_x, new_res_y,
4570 (double) tileWidth *
4571 new_res_x,
4572 (double) tileHeight *
4573 new_res_y, minx, miny, maxx,
4574 maxy, scale);
4575 first = 0;
4576 if (pyr == NULL)
4577 goto error;
4578 }
4579 if (!insert_tile_into_section_pyramid
4580 (pyr, tile_id, tminx, tminy, tmaxx, tmaxy))
4581 goto error;
4582 }
4583 else
4584 {
4585 fprintf (stderr,
4586 "SELECT base level; sqlite3_step() error: %s\n",
4587 sqlite3_errmsg (handle));
4588 goto error;
4589 }
4590 }
4591 sqlite3_finalize (stmt);
4592 stmt = NULL;
4593 if (pyr == NULL)
4594 goto error;
4595
4596 out_maxy = maxy;
4597 for (row = 0; row < pyr->scaled_height; row += tileHeight)
4598 {
4599 out_miny = out_maxy - pyr->tile_height;
4600 out_minx = minx;
4601 for (col = 0; col < pyr->scaled_width; col += tileWidth)
4602 {
4603 out_maxx = out_minx + pyr->tile_width;
4604 set_pyramid_tile_destination (pyr, out_minx, out_miny,
4605 out_maxx, out_maxy, row,
4606 col);
4607 out_minx += pyr->tile_width;
4608 }
4609 out_maxy -= pyr->tile_height;
4610 }
4611 id_level++;
4612 if (pyr->scaled_width <= tileWidth
4613 && pyr->scaled_height <= tileHeight)
4614 break;
4615 if (!do_insert_pyramid_levels
4616 (handle, id_level, pyr->res_x, pyr->res_y, stmt_levl))
4617 goto error;
4618 if (pixel_type == RL2_PIXEL_DATAGRID)
4619 {
4620 /* DataGrid Pyramid */
4621 if (!update_sect_pyramid_grid
4622 (handle, stmt_rd, stmt_tils, stmt_data, pyr, tileWidth,
4623 tileHeight, id_level, no_data, sample_type))
4624 goto error;
4625 }
4626 else if (pixel_type == RL2_PIXEL_MULTIBAND)
4627 {
4628 /* MultiBand Pyramid */
4629 if (!update_sect_pyramid_multiband
4630 (handle, stmt_rd, stmt_tils, stmt_data, pyr, tileWidth,
4631 tileHeight, id_level, no_data, sample_type, num_samples))
4632 goto error;
4633 }
4634 else
4635 {
4636 /* any other Pyramid [not a DataGrid] */
4637 if (!update_sect_pyramid
4638 (handle, stmt_rd, stmt_tils, stmt_data, pyr, tileWidth,
4639 tileHeight, id_level, palette, no_data))
4640 goto error;
4641 }
4642 delete_sect_pyramid (pyr);
4643 pyr = NULL;
4644 }
4645
4646 if (pyr != NULL)
4647 {
4648 if (!do_insert_pyramid_levels
4649 (handle, id_level, pyr->res_x, pyr->res_y, stmt_levl))
4650 goto error;
4651 if (pixel_type == RL2_PIXEL_DATAGRID)
4652 {
4653 /* DataGrid Pyramid */
4654 if (!update_sect_pyramid_grid
4655 (handle, stmt_rd, stmt_tils, stmt_data, pyr, tileWidth,
4656 tileHeight, id_level, no_data, sample_type))
4657 goto error;
4658 }
4659 else if (pixel_type == RL2_PIXEL_MULTIBAND)
4660 {
4661 /* MultiBand Pyramid */
4662 if (!update_sect_pyramid_multiband
4663 (handle, stmt_rd, stmt_tils, stmt_data, pyr, tileWidth,
4664 tileHeight, id_level, no_data, sample_type, num_samples))
4665 goto error;
4666 }
4667 else
4668 {
4669 /* any other Pyramid [not a DataGrid] */
4670 if (!update_sect_pyramid
4671 (handle, stmt_rd, stmt_tils, stmt_data, pyr, tileWidth,
4672 tileHeight, id_level, palette, no_data))
4673 goto error;
4674 }
4675 delete_sect_pyramid (pyr);
4676 }
4677 sqlite3_finalize (stmt_rd);
4678 sqlite3_finalize (stmt_levl);
4679 sqlite3_finalize (stmt_tils);
4680 sqlite3_finalize (stmt_data);
4681 if (no_data != NULL)
4682 rl2_destroy_pixel (no_data);
4683 return 1;
4684
4685 error:
4686 if (stmt != NULL)
4687 sqlite3_finalize (stmt);
4688 if (stmt_rd != NULL)
4689 sqlite3_finalize (stmt_rd);
4690 if (pyr != NULL)
4691 delete_sect_pyramid (pyr);
4692 if (stmt_levl != NULL)
4693 sqlite3_finalize (stmt_levl);
4694 if (stmt_tils != NULL)
4695 sqlite3_finalize (stmt_tils);
4696 if (stmt_data != NULL)
4697 sqlite3_finalize (stmt_data);
4698 if (no_data != NULL)
4699 rl2_destroy_pixel (no_data);
4700 return 0;
4701 }
4702
4703 static int
get_coverage_extent(sqlite3 * handle,const char * coverage,double * minx,double * miny,double * maxx,double * maxy)4704 get_coverage_extent (sqlite3 * handle, const char *coverage, double *minx,
4705 double *miny, double *maxx, double *maxy)
4706 {
4707 /* attempting to get the Extent from a Coverage Object */
4708 char *sql;
4709 int ret;
4710 sqlite3_stmt *stmt;
4711 double extent_minx;
4712 double extent_miny;
4713 double extent_maxx;
4714 double extent_maxy;
4715 int ok = 0;
4716
4717 /* querying the Coverage metadata defs */
4718 sql =
4719 "SELECT extent_minx, extent_miny, extent_maxx, extent_maxy "
4720 "FROM raster_coverages WHERE Lower(coverage_name) = Lower(?)";
4721 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
4722 if (ret != SQLITE_OK)
4723 {
4724 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
4725 return 0;
4726 }
4727 sqlite3_reset (stmt);
4728 sqlite3_clear_bindings (stmt);
4729 sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
4730 while (1)
4731 {
4732 /* scrolling the result set rows */
4733 ret = sqlite3_step (stmt);
4734 if (ret == SQLITE_DONE)
4735 break; /* end of result set */
4736 if (ret == SQLITE_ROW)
4737 {
4738 int ok_minx = 0;
4739 int ok_miny = 0;
4740 int ok_maxx = 0;
4741 int ok_maxy = 0;
4742 if (sqlite3_column_type (stmt, 0) == SQLITE_FLOAT)
4743 {
4744 extent_minx = sqlite3_column_double (stmt, 0);
4745 ok_minx = 1;
4746 }
4747 if (sqlite3_column_type (stmt, 1) == SQLITE_FLOAT)
4748 {
4749 extent_miny = sqlite3_column_double (stmt, 1);
4750 ok_miny = 1;
4751 }
4752 if (sqlite3_column_type (stmt, 2) == SQLITE_FLOAT)
4753 {
4754 extent_maxx = sqlite3_column_double (stmt, 2);
4755 ok_maxx = 1;
4756 }
4757 if (sqlite3_column_type (stmt, 3) == SQLITE_FLOAT)
4758 {
4759 extent_maxy = sqlite3_column_double (stmt, 3);
4760 ok_maxy = 1;
4761 }
4762 if (ok_minx && ok_miny && ok_maxx && ok_maxy)
4763 ok = 1;
4764 }
4765 }
4766 sqlite3_finalize (stmt);
4767
4768 if (!ok)
4769 return 0;
4770 *minx = extent_minx;
4771 *miny = extent_miny;
4772 *maxx = extent_maxx;
4773 *maxy = extent_maxy;
4774 return 1;
4775 }
4776
4777 static int
find_base_resolution(sqlite3 * handle,const char * coverage,double * x_res,double * y_res)4778 find_base_resolution (sqlite3 * handle, const char *coverage,
4779 double *x_res, double *y_res)
4780 {
4781 /* attempting to identify the base resolution level */
4782 int ret;
4783 int found = 0;
4784 double xx_res;
4785 double yy_res;
4786 char *xcoverage;
4787 char *xxcoverage;
4788 char *sql;
4789 sqlite3_stmt *stmt = NULL;
4790
4791 xcoverage = sqlite3_mprintf ("%s_levels", coverage);
4792 xxcoverage = gaiaDoubleQuotedSql (xcoverage);
4793 sqlite3_free (xcoverage);
4794 sql =
4795 sqlite3_mprintf ("SELECT x_resolution_1_1, y_resolution_1_1 "
4796 "FROM \"%s\" WHERE pyramid_level = 0", xxcoverage);
4797 free (xxcoverage);
4798 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
4799 if (ret != SQLITE_OK)
4800 {
4801 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
4802 goto error;
4803 }
4804 sqlite3_free (sql);
4805
4806 while (1)
4807 {
4808 /* scrolling the result set rows */
4809 ret = sqlite3_step (stmt);
4810 if (ret == SQLITE_DONE)
4811 break; /* end of result set */
4812 if (ret == SQLITE_ROW)
4813 {
4814 if (sqlite3_column_type (stmt, 0) == SQLITE_FLOAT
4815 && sqlite3_column_type (stmt, 1) == SQLITE_FLOAT)
4816 {
4817 found = 1;
4818 xx_res = sqlite3_column_double (stmt, 0);
4819 yy_res = sqlite3_column_double (stmt, 1);
4820 }
4821 }
4822 else
4823 {
4824 fprintf (stderr, "SQL error: %s\n%s\n", sql,
4825 sqlite3_errmsg (handle));
4826 goto error;
4827 }
4828 }
4829 sqlite3_finalize (stmt);
4830 if (found)
4831 {
4832 *x_res = xx_res;
4833 *y_res = yy_res;
4834 return 1;
4835 }
4836 return 0;
4837
4838 error:
4839 if (stmt != NULL)
4840 sqlite3_finalize (stmt);
4841 return 0;
4842 }
4843
4844 static int
get_section_raw_raster_data(sqlite3 * handle,const char * coverage,sqlite3_int64 sect_id,unsigned int width,unsigned int height,unsigned char sample_type,unsigned char pixel_type,unsigned char num_bands,double minx,double maxy,double x_res,double y_res,unsigned char ** buffer,int * buf_size,rl2PalettePtr palette,rl2PixelPtr no_data)4845 get_section_raw_raster_data (sqlite3 * handle, const char *coverage,
4846 sqlite3_int64 sect_id, unsigned int width,
4847 unsigned int height, unsigned char sample_type,
4848 unsigned char pixel_type, unsigned char num_bands,
4849 double minx, double maxy,
4850 double x_res, double y_res, unsigned char **buffer,
4851 int *buf_size, rl2PalettePtr palette,
4852 rl2PixelPtr no_data)
4853 {
4854 /* attempting to return a buffer containing raw pixels from the whole DBMS Section */
4855 unsigned char *bufpix = NULL;
4856 int bufpix_size;
4857 char *xtiles;
4858 char *xxtiles;
4859 char *xdata;
4860 char *xxdata;
4861 char *sql;
4862 sqlite3_stmt *stmt_tiles = NULL;
4863 sqlite3_stmt *stmt_data = NULL;
4864 int ret;
4865
4866 switch (sample_type)
4867 {
4868 case RL2_SAMPLE_1_BIT:
4869 case RL2_SAMPLE_2_BIT:
4870 case RL2_SAMPLE_4_BIT:
4871 break;
4872 case RL2_SAMPLE_UINT8:
4873 if (pixel_type != RL2_PIXEL_PALETTE)
4874 goto error;
4875 break;
4876 default:
4877 goto error;
4878 break;
4879 };
4880 bufpix_size = num_bands * width * height;
4881 bufpix = malloc (bufpix_size);
4882 if (bufpix == NULL)
4883 {
4884 fprintf (stderr,
4885 "get_section_raw_raster_data: Insufficient Memory !!!\n");
4886 goto error;
4887 }
4888 memset (bufpix, 0, bufpix_size);
4889
4890 /* preparing the "tiles" SQL query */
4891 xtiles = sqlite3_mprintf ("%s_tiles", coverage);
4892 xxtiles = gaiaDoubleQuotedSql (xtiles);
4893 sql =
4894 sqlite3_mprintf ("SELECT tile_id, MbrMinX(geometry), MbrMaxY(geometry) "
4895 "FROM \"%s\" "
4896 "WHERE pyramid_level = 0 AND section_id = ?", xxtiles);
4897 sqlite3_free (xtiles);
4898 free (xxtiles);
4899 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_tiles, NULL);
4900 sqlite3_free (sql);
4901 if (ret != SQLITE_OK)
4902 {
4903 printf ("SELECT section raw tiles SQL error: %s\n",
4904 sqlite3_errmsg (handle));
4905 goto error;
4906 }
4907
4908 /* preparing the data SQL query - both ODD and EVEN */
4909 xdata = sqlite3_mprintf ("%s_tile_data", coverage);
4910 xxdata = gaiaDoubleQuotedSql (xdata);
4911 sqlite3_free (xdata);
4912 sql = sqlite3_mprintf ("SELECT tile_data_odd, tile_data_even "
4913 "FROM \"%s\" WHERE tile_id = ?", xxdata);
4914 free (xxdata);
4915 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_data, NULL);
4916 sqlite3_free (sql);
4917 if (ret != SQLITE_OK)
4918 {
4919 printf ("SELECT section raw tiles data(2) SQL error: %s\n",
4920 sqlite3_errmsg (handle));
4921 goto error;
4922 }
4923
4924 /* preparing a raw pixels buffer */
4925 if (pixel_type == RL2_PIXEL_PALETTE)
4926 void_raw_buffer_palette (bufpix, width, height, no_data);
4927 else
4928 void_raw_buffer (bufpix, width, height, sample_type, num_bands,
4929 no_data);
4930 if (!load_dbms_tiles_section
4931 (handle, sect_id, stmt_tiles, stmt_data, bufpix, width, height,
4932 sample_type, num_bands, x_res, y_res, minx, maxy, RL2_SCALE_1, palette,
4933 no_data))
4934 goto error;
4935 sqlite3_finalize (stmt_tiles);
4936 sqlite3_finalize (stmt_data);
4937 *buffer = bufpix;
4938 *buf_size = bufpix_size;
4939 return 1;
4940
4941 error:
4942 if (stmt_tiles != NULL)
4943 sqlite3_finalize (stmt_tiles);
4944 if (stmt_data != NULL)
4945 sqlite3_finalize (stmt_data);
4946 if (bufpix != NULL)
4947 free (bufpix);
4948 return 0;
4949 }
4950
4951 static void
raster_tile_124_rescaled(unsigned char * outbuf,unsigned char pixel_type,const unsigned char * inbuf,unsigned int section_width,unsigned int section_height,unsigned int out_width,unsigned int out_height,rl2PalettePtr palette)4952 raster_tile_124_rescaled (unsigned char *outbuf,
4953 unsigned char pixel_type, const unsigned char *inbuf,
4954 unsigned int section_width,
4955 unsigned int section_height, unsigned int out_width,
4956 unsigned int out_height, rl2PalettePtr palette)
4957 {
4958 /*
4959 / this function builds an high quality rescaled sub-image by applying pixel interpolation
4960 /
4961 / this code is widely inspired by the original GD gdImageCopyResampled() function
4962 */
4963 unsigned int x;
4964 unsigned int y;
4965 double sy1;
4966 double sy2;
4967 double sx1;
4968 double sx2;
4969 unsigned char r;
4970 unsigned char g;
4971 unsigned char b;
4972 const unsigned char *p_in;
4973 unsigned char *p_out;
4974
4975 if (pixel_type == RL2_PIXEL_PALETTE && palette == NULL)
4976 return;
4977
4978 for (y = 0; y < out_height; y++)
4979 {
4980 sy1 = ((double) y) * (double) section_height / (double) out_height;
4981 sy2 =
4982 ((double) (y + 1)) * (double) section_height /
4983 (double) out_height;
4984 for (x = 0; x < out_width; x++)
4985 {
4986 double sx;
4987 double sy;
4988 double spixels = 0;
4989 double red = 0.0;
4990 double green = 0.0;
4991 double blue = 0.0;
4992 sx1 =
4993 ((double) x) * (double) section_width / (double) out_width;
4994 sx2 =
4995 ((double) (x + 1)) * (double) section_width /
4996 (double) out_width;
4997 sy = sy1;
4998 do
4999 {
5000 double yportion;
5001 if (floor2 (sy) == floor2 (sy1))
5002 {
5003 yportion = 1.0 - (sy - floor2 (sy));
5004 if (yportion > sy2 - sy1)
5005 {
5006 yportion = sy2 - sy1;
5007 }
5008 sy = floor2 (sy);
5009 }
5010 else if (sy == floor2 (sy2))
5011 {
5012 yportion = sy2 - floor2 (sy2);
5013 }
5014 else
5015 {
5016 yportion = 1.0;
5017 }
5018 sx = sx1;
5019 do
5020 {
5021 double xportion;
5022 double pcontribution;
5023 if (floor2 (sx) == floor2 (sx1))
5024 {
5025 xportion = 1.0 - (sx - floor2 (sx));
5026 if (xportion > sx2 - sx1)
5027 {
5028 xportion = sx2 - sx1;
5029 }
5030 sx = floor2 (sx);
5031 }
5032 else if (sx == floor2 (sx2))
5033 {
5034 xportion = sx2 - floor2 (sx2);
5035 }
5036 else
5037 {
5038 xportion = 1.0;
5039 }
5040 pcontribution = xportion * yportion;
5041 /* retrieving the origin pixel */
5042 if (pixel_type == RL2_PIXEL_RGB)
5043 p_in =
5044 inbuf +
5045 ((unsigned int) sy * section_width * 3);
5046 else
5047 p_in =
5048 inbuf + ((unsigned int) sy * section_width);
5049 if (pixel_type == RL2_PIXEL_PALETTE)
5050 {
5051 rl2PrivPalettePtr plt =
5052 (rl2PrivPalettePtr) palette;
5053 unsigned char index;
5054 p_in += (unsigned int) sx;
5055 index = *p_in;
5056 if (index < plt->nEntries)
5057 {
5058 /* resolving the Palette color by index */
5059 rl2PrivPaletteEntryPtr entry =
5060 plt->entries + index;
5061 r = entry->red;
5062 g = entry->green;
5063 b = entry->red;
5064 }
5065 else
5066 {
5067 r = 0;
5068 g = 0;
5069 b = 0;
5070 }
5071 }
5072 else
5073 {
5074 p_in += (unsigned int) sx;
5075 if (*p_in == 1)
5076 {
5077 /* black monochrome pixel */
5078 r = 0;
5079 g = 0;
5080 b = 0;
5081 }
5082 else
5083 {
5084 /* white monochrome pixel */
5085 r = 255;
5086 g = 255;
5087 b = 255;
5088 }
5089 }
5090 red += r * pcontribution;
5091 green += g * pcontribution;
5092 blue += b * pcontribution;
5093 spixels += xportion * yportion;
5094 sx += 1.0;
5095 }
5096 while (sx < sx2);
5097 sy += 1.0;
5098 }
5099 while (sy < sy2);
5100 if (spixels != 0.0)
5101 {
5102 red /= spixels;
5103 green /= spixels;
5104 blue /= spixels;
5105 }
5106 if (red > 255.0)
5107 red = 255.0;
5108 if (green > 255.0)
5109 green = 255.0;
5110 if (blue > 255.0)
5111 blue = 255.0;
5112 /* setting the destination pixel */
5113 if (pixel_type == RL2_PIXEL_PALETTE)
5114 p_out = outbuf + (y * out_width * 3);
5115 else
5116 p_out = outbuf + (y * out_width);
5117 if (pixel_type == RL2_PIXEL_PALETTE)
5118 {
5119 p_out += x * 3;
5120 *p_out++ = (unsigned char) red;
5121 *p_out++ = (unsigned char) green;
5122 *p_out = (unsigned char) blue;
5123 }
5124 else
5125 {
5126 if (red <= 224.0)
5127 {
5128 p_out += x;
5129 if (red < *p_out)
5130 *p_out = (unsigned char) red;
5131 }
5132 }
5133 }
5134 }
5135 }
5136
5137 static int
copy_124_tile(unsigned char pixel_type,const unsigned char * outbuf,unsigned char ** tilebuf,int * tilebuf_sz,unsigned char ** tilemask,int * tilemask_sz,unsigned int row,unsigned int col,unsigned int out_width,unsigned int out_height,unsigned int tileWidth,unsigned int tileHeight,rl2PixelPtr no_data)5138 copy_124_tile (unsigned char pixel_type, const unsigned char *outbuf,
5139 unsigned char **tilebuf,
5140 int *tilebuf_sz, unsigned char **tilemask, int *tilemask_sz,
5141 unsigned int row, unsigned int col, unsigned int out_width,
5142 unsigned int out_height, unsigned int tileWidth,
5143 unsigned int tileHeight, rl2PixelPtr no_data)
5144 {
5145 /* allocating and initializing the resized tile buffers */
5146 unsigned char *pixels = NULL;
5147 int pixels_sz = 0;
5148 unsigned char *mask = NULL;
5149 int mask_sz = 0;
5150 int has_mask = 0;
5151 unsigned int x;
5152 unsigned int y;
5153 const unsigned char *p_inp;
5154 unsigned char *p_outp;
5155
5156 if (pixel_type == RL2_PIXEL_RGB)
5157 pixels_sz = tileWidth * tileHeight * 3;
5158 else
5159 pixels_sz = tileWidth * tileHeight;
5160 pixels = malloc (pixels_sz);
5161 if (pixels == NULL)
5162 goto error;
5163
5164 if (pixel_type == RL2_PIXEL_RGB)
5165 rl2_prime_void_tile (pixels, tileWidth, tileHeight, RL2_SAMPLE_UINT8,
5166 3, no_data);
5167 else
5168 rl2_prime_void_tile (pixels, tileWidth, tileHeight, RL2_SAMPLE_UINT8,
5169 1, no_data);
5170
5171 if (row + tileHeight > out_height)
5172 has_mask = 1;
5173 if (col + tileWidth > out_width)
5174 has_mask = 1;
5175 if (has_mask)
5176 {
5177 /* masking the unused portion of this tile */
5178 mask_sz = tileWidth * tileHeight;
5179 mask = malloc (mask_sz);
5180 if (mask == NULL)
5181 goto error;
5182 memset (mask, 0, mask_sz);
5183 for (y = 0; y < tileHeight; y++)
5184 {
5185 unsigned int y_in = y + row;
5186 if (y_in >= out_height)
5187 continue;
5188 for (x = 0; x < tileWidth; x++)
5189 {
5190 unsigned int x_in = x + col;
5191 if (x_in >= out_width)
5192 continue;
5193 p_outp = mask + (y * tileWidth);
5194 p_outp += x;
5195 *p_outp = 1;
5196 }
5197 }
5198 }
5199
5200 for (y = 0; y < tileHeight; y++)
5201 {
5202 unsigned int y_in = y + row;
5203 if (y_in >= out_height)
5204 continue;
5205 for (x = 0; x < tileWidth; x++)
5206 {
5207 unsigned int x_in = x + col;
5208 if (x_in >= out_width)
5209 continue;
5210 if (pixel_type == RL2_PIXEL_RGB)
5211 {
5212 p_inp = outbuf + (y_in * out_width * 3);
5213 p_inp += x_in * 3;
5214 p_outp = pixels + (y * tileWidth * 3);
5215 p_outp += x * 3;
5216 *p_outp++ = *p_inp++;
5217 *p_outp++ = *p_inp++;
5218 *p_outp = *p_inp;
5219 }
5220 else
5221 {
5222 p_inp = outbuf + (y_in * out_width);
5223 p_inp += x_in;
5224 p_outp = pixels + (y * tileWidth);
5225 p_outp += x;
5226 *p_outp = *p_inp;
5227 }
5228 }
5229 }
5230
5231 *tilebuf = pixels;
5232 *tilebuf_sz = pixels_sz;
5233 *tilemask = mask;
5234 *tilemask_sz = mask_sz;
5235 return 1;
5236
5237 error:
5238 if (pixels != NULL)
5239 free (pixels);
5240 return 0;
5241 }
5242
5243 static int
do_build_124_bit_section_pyramid(sqlite3 * handle,const char * coverage,const char * section,unsigned char sample_type,unsigned char pixel_type,unsigned char num_samples,int srid,unsigned int tileWidth,unsigned int tileHeight,unsigned char bgRed,unsigned char bgGreen,unsigned char bgBlue)5244 do_build_124_bit_section_pyramid (sqlite3 * handle, const char *coverage,
5245 const char *section,
5246 unsigned char sample_type,
5247 unsigned char pixel_type,
5248 unsigned char num_samples, int srid,
5249 unsigned int tileWidth,
5250 unsigned int tileHeight,
5251 unsigned char bgRed, unsigned char bgGreen,
5252 unsigned char bgBlue)
5253 {
5254 /* attempting to (re)build a 1,2,4-bit section pyramid from scratch */
5255 double base_res_x;
5256 double base_res_y;
5257 sqlite3_int64 sect_id;
5258 unsigned int sect_width;
5259 unsigned int sect_height;
5260 int id_level = 0;
5261 int scale;
5262 double x_res;
5263 double y_res;
5264 double minx;
5265 double miny;
5266 double maxx;
5267 double maxy;
5268 unsigned int row;
5269 unsigned int col;
5270 sqlite3_stmt *stmt = NULL;
5271 sqlite3_stmt *stmt_rd = NULL;
5272 sqlite3_stmt *stmt_levl = NULL;
5273 sqlite3_stmt *stmt_tils = NULL;
5274 sqlite3_stmt *stmt_data = NULL;
5275 rl2PalettePtr palette = NULL;
5276 rl2PixelPtr no_data = NULL;
5277 rl2PixelPtr nd = NULL;
5278 unsigned char *inbuf = NULL;
5279 int inbuf_size = 0;
5280 unsigned char *outbuf = NULL;
5281 int outbuf_sz = 0;
5282 unsigned char out_pixel_type;
5283 unsigned char out_bands;
5284 unsigned char *tilebuf = NULL;
5285 int tilebuf_sz = 0;
5286 unsigned char *tilemask = NULL;
5287 int tilemask_sz = 0;
5288 unsigned char *blob_odd = NULL;
5289 unsigned char *blob_even = NULL;
5290 int blob_odd_sz;
5291 int blob_even_sz;
5292 unsigned int x;
5293 unsigned int y;
5294 unsigned char *p_out;
5295
5296 if (!get_section_infos
5297 (handle, coverage, section, §_id, §_width, §_height, &minx,
5298 &miny, &maxx, &maxy, &palette, &no_data))
5299 goto error;
5300
5301 if (!find_base_resolution (handle, coverage, &base_res_x, &base_res_y))
5302 goto error;
5303 if (!get_section_raw_raster_data
5304 (handle, coverage, sect_id, sect_width, sect_height, sample_type,
5305 pixel_type, num_samples, minx, maxy, base_res_x,
5306 base_res_y, &inbuf, &inbuf_size, palette, no_data))
5307 goto error;
5308
5309 if (!prepare_section_pyramid_stmts
5310 (handle, coverage, &stmt_rd, &stmt_levl, &stmt_tils, &stmt_data))
5311 goto error;
5312
5313 id_level = 1;
5314 scale = 2;
5315 x_res = base_res_x * 2.0;
5316 y_res = base_res_y * 2.0;
5317 while (1)
5318 {
5319 /* looping on Pyramid levels */
5320 double t_minx;
5321 double t_miny;
5322 double t_maxx;
5323 double t_maxy;
5324 unsigned int out_width = sect_width / scale;
5325 unsigned int out_height = sect_height / scale;
5326 rl2RasterPtr raster = NULL;
5327
5328 if (pixel_type == RL2_PIXEL_MONOCHROME)
5329 {
5330 out_pixel_type = RL2_PIXEL_GRAYSCALE;
5331 out_bands = 1;
5332 outbuf_sz = out_width * out_height;
5333 outbuf = malloc (outbuf_sz);
5334 if (outbuf == NULL)
5335 goto error;
5336 p_out = outbuf;
5337 for (y = 0; y < out_height; y++)
5338 {
5339 /* priming the background color */
5340 for (x = 0; x < out_width; x++)
5341 *p_out++ = bgRed;
5342 }
5343 }
5344 else
5345 {
5346 out_pixel_type = RL2_PIXEL_RGB;
5347 out_bands = 3;
5348 outbuf_sz = out_width * out_height * 3;
5349 outbuf = malloc (outbuf_sz);
5350 if (outbuf == NULL)
5351 goto error;
5352 p_out = outbuf;
5353 for (y = 0; y < out_height; y++)
5354 {
5355 /* priming the background color */
5356 for (x = 0; x < out_width; x++)
5357 {
5358 *p_out++ = bgRed;
5359 *p_out++ = bgGreen;
5360 *p_out++ = bgBlue;
5361 }
5362 }
5363 }
5364 t_maxy = maxy;
5365 raster_tile_124_rescaled (outbuf, pixel_type, inbuf,
5366 sect_width, sect_height, out_width,
5367 out_height, palette);
5368
5369 if (!do_insert_pyramid_levels
5370 (handle, id_level, x_res, y_res, stmt_levl))
5371 goto error;
5372
5373 for (row = 0; row < out_height; row += tileHeight)
5374 {
5375 t_minx = minx;
5376 t_miny = t_maxy - (tileHeight * y_res);
5377 for (col = 0; col < out_width; col += tileWidth)
5378 {
5379 if (pixel_type == RL2_PIXEL_MONOCHROME)
5380 {
5381 if (no_data == NULL)
5382 nd = NULL;
5383 else
5384 {
5385 /* creating a NO-DATA pixel */
5386 nd = rl2_create_pixel (RL2_SAMPLE_UINT8,
5387 RL2_PIXEL_GRAYSCALE,
5388 1);
5389 rl2_set_pixel_sample_uint8 (nd,
5390 RL2_GRAYSCALE_BAND,
5391 bgRed);
5392 }
5393 }
5394 else
5395 {
5396 if (no_data == NULL)
5397 nd = NULL;
5398 else
5399 {
5400 /* converting the NO-DATA pixel */
5401 nd = rl2_create_pixel (RL2_SAMPLE_UINT8,
5402 RL2_PIXEL_RGB, 3);
5403 rl2_set_pixel_sample_uint8 (nd, RL2_RED_BAND,
5404 bgRed);
5405 rl2_set_pixel_sample_uint8 (nd,
5406 RL2_GREEN_BAND,
5407 bgGreen);
5408 rl2_set_pixel_sample_uint8 (nd, RL2_BLUE_BAND,
5409 bgBlue);
5410 }
5411 }
5412 t_maxx = t_minx + (tileWidth * x_res);
5413 if (!copy_124_tile
5414 (out_pixel_type, outbuf, &tilebuf,
5415 &tilebuf_sz, &tilemask, &tilemask_sz, row, col,
5416 out_width, out_height, tileWidth, tileHeight,
5417 no_data))
5418 {
5419 fprintf (stderr,
5420 "ERROR: unable to extract a Pyramid Tile\n");
5421 goto error;
5422 }
5423
5424 raster =
5425 rl2_create_raster (tileWidth, tileHeight,
5426 RL2_SAMPLE_UINT8, out_pixel_type,
5427 out_bands, tilebuf, tilebuf_sz,
5428 NULL, tilemask, tilemask_sz, nd);
5429 tilebuf = NULL;
5430 tilemask = NULL;
5431 if (raster == NULL)
5432 {
5433 fprintf (stderr,
5434 "ERROR: unable to create a Pyramid Tile\n");
5435 goto error;
5436 }
5437 if (rl2_raster_encode
5438 (raster, RL2_COMPRESSION_PNG, &blob_odd, &blob_odd_sz,
5439 &blob_even, &blob_even_sz, 100, 1) != RL2_OK)
5440 {
5441 fprintf (stderr,
5442 "ERROR: unable to encode a Pyramid tile\n");
5443 goto error;
5444 }
5445
5446 /* INSERTing the tile */
5447 if (!do_insert_pyramid_tile
5448 (handle, blob_odd, blob_odd_sz, blob_even,
5449 blob_even_sz, id_level, sect_id, srid, t_minx,
5450 t_miny, t_maxx, t_maxy, stmt_tils, stmt_data))
5451 goto error;
5452 rl2_destroy_raster (raster);
5453 t_minx += (tileWidth * x_res);
5454 }
5455 t_maxy -= (tileHeight * y_res);
5456 }
5457
5458 free (outbuf);
5459 if (out_width < tileWidth && out_height < tileHeight)
5460 break;
5461 x_res *= 2.0;
5462 y_res *= 2.0;
5463 scale *= 2;
5464 id_level++;
5465 }
5466
5467 free (inbuf);
5468 sqlite3_finalize (stmt_rd);
5469 sqlite3_finalize (stmt_levl);
5470 sqlite3_finalize (stmt_tils);
5471 sqlite3_finalize (stmt_data);
5472 if (no_data != NULL)
5473 rl2_destroy_pixel (no_data);
5474 if (palette != NULL)
5475 rl2_destroy_palette (palette);
5476 return 1;
5477
5478 error:
5479 if (outbuf != NULL)
5480 free (outbuf);
5481 if (tilebuf != NULL)
5482 free (tilebuf);
5483 if (tilemask != NULL)
5484 free (tilemask);
5485 if (inbuf != NULL)
5486 free (inbuf);
5487 if (stmt != NULL)
5488 sqlite3_finalize (stmt);
5489 if (stmt_rd != NULL)
5490 sqlite3_finalize (stmt_rd);
5491 if (stmt_levl != NULL)
5492 sqlite3_finalize (stmt_levl);
5493 if (stmt_tils != NULL)
5494 sqlite3_finalize (stmt_tils);
5495 if (stmt_data != NULL)
5496 sqlite3_finalize (stmt_data);
5497 if (no_data != NULL)
5498 rl2_destroy_pixel (no_data);
5499 if (palette != NULL)
5500 rl2_destroy_palette (palette);
5501 return 0;
5502 }
5503
5504 static int
do_build_palette_section_pyramid(sqlite3 * handle,const char * coverage,const char * section,int srid,unsigned int tileWidth,unsigned int tileHeight,unsigned char bgRed,unsigned char bgGreen,unsigned char bgBlue)5505 do_build_palette_section_pyramid (sqlite3 * handle, const char *coverage,
5506 const char *section, int srid,
5507 unsigned int tileWidth,
5508 unsigned int tileHeight,
5509 unsigned char bgRed, unsigned char bgGreen,
5510 unsigned char bgBlue)
5511 {
5512 /* attempting to (re)build a Palette section pyramid from scratch */
5513 double base_res_x;
5514 double base_res_y;
5515 sqlite3_int64 sect_id;
5516 unsigned int sect_width;
5517 unsigned int sect_height;
5518 int id_level = 0;
5519 int scale;
5520 double x_res;
5521 double y_res;
5522 double minx;
5523 double miny;
5524 double maxx;
5525 double maxy;
5526 unsigned int row;
5527 unsigned int col;
5528 sqlite3_stmt *stmt = NULL;
5529 sqlite3_stmt *stmt_rd = NULL;
5530 sqlite3_stmt *stmt_levl = NULL;
5531 sqlite3_stmt *stmt_tils = NULL;
5532 sqlite3_stmt *stmt_data = NULL;
5533 rl2PalettePtr palette = NULL;
5534 rl2PixelPtr no_data = NULL;
5535 rl2PixelPtr nd = NULL;
5536 unsigned char *inbuf = NULL;
5537 int inbuf_size = 0;
5538 unsigned char *outbuf = NULL;
5539 int outbuf_sz = 0;
5540 unsigned char out_pixel_type;
5541 unsigned char out_bands;
5542 unsigned char *tilebuf = NULL;
5543 int tilebuf_sz = 0;
5544 unsigned char *tilemask = NULL;
5545 int tilemask_sz = 0;
5546 unsigned char *blob_odd = NULL;
5547 unsigned char *blob_even = NULL;
5548 int blob_odd_sz;
5549 int blob_even_sz;
5550 unsigned int x;
5551 unsigned int y;
5552 unsigned char *p_out;
5553
5554 if (!get_section_infos
5555 (handle, coverage, section, §_id, §_width, §_height, &minx,
5556 &miny, &maxx, &maxy, &palette, &no_data))
5557 goto error;
5558 if (palette == NULL)
5559 goto error;
5560
5561 if (!find_base_resolution (handle, coverage, &base_res_x, &base_res_y))
5562 goto error;
5563 if (!get_section_raw_raster_data
5564 (handle, coverage, sect_id, sect_width, sect_height, RL2_SAMPLE_UINT8,
5565 RL2_PIXEL_PALETTE, 1, minx, maxy, base_res_x,
5566 base_res_y, &inbuf, &inbuf_size, palette, no_data))
5567 goto error;
5568
5569 if (!prepare_section_pyramid_stmts
5570 (handle, coverage, &stmt_rd, &stmt_levl, &stmt_tils, &stmt_data))
5571 goto error;
5572
5573 id_level = 1;
5574 scale = 2;
5575 x_res = base_res_x * 2.0;
5576 y_res = base_res_y * 2.0;
5577 while (1)
5578 {
5579 /* looping on Pyramid levels */
5580 double t_minx;
5581 double t_miny;
5582 double t_maxx;
5583 double t_maxy;
5584 unsigned int out_width = sect_width / scale;
5585 unsigned int out_height = sect_height / scale;
5586 rl2RasterPtr raster = NULL;
5587
5588 out_pixel_type = RL2_PIXEL_RGB;
5589 out_bands = 3;
5590 outbuf_sz = out_width * out_height * 3;
5591 outbuf = malloc (outbuf_sz);
5592 if (outbuf == NULL)
5593 goto error;
5594 p_out = outbuf;
5595 for (y = 0; y < out_height; y++)
5596 {
5597 /* priming the background color */
5598 for (x = 0; x < out_width; x++)
5599 {
5600 *p_out++ = bgRed;
5601 *p_out++ = bgGreen;
5602 *p_out++ = bgBlue;
5603 }
5604 }
5605 t_maxy = maxy;
5606 raster_tile_124_rescaled (outbuf, RL2_PIXEL_PALETTE, inbuf,
5607 sect_width, sect_height, out_width,
5608 out_height, palette);
5609
5610 if (!do_insert_pyramid_levels
5611 (handle, id_level, x_res, y_res, stmt_levl))
5612 goto error;
5613
5614 for (row = 0; row < out_height; row += tileHeight)
5615 {
5616 t_minx = minx;
5617 t_miny = t_maxy - (tileHeight * y_res);
5618 for (col = 0; col < out_width; col += tileWidth)
5619 {
5620 if (no_data == NULL)
5621 nd = NULL;
5622 else
5623 {
5624 /* converting the NO-DATA pixel */
5625 nd = rl2_create_pixel (RL2_SAMPLE_UINT8,
5626 RL2_PIXEL_RGB, 3);
5627 rl2_set_pixel_sample_uint8 (nd, RL2_RED_BAND,
5628 bgRed);
5629 rl2_set_pixel_sample_uint8 (nd,
5630 RL2_GREEN_BAND,
5631 bgGreen);
5632 rl2_set_pixel_sample_uint8 (nd, RL2_BLUE_BAND,
5633 bgBlue);
5634 }
5635 t_maxx = t_minx + (tileWidth * x_res);
5636 if (!copy_124_tile (out_pixel_type, outbuf, &tilebuf,
5637 &tilebuf_sz, &tilemask, &tilemask_sz,
5638 row, col, out_width, out_height,
5639 tileWidth, tileHeight, no_data))
5640 {
5641 fprintf (stderr,
5642 "ERROR: unable to extract a Pyramid Tile\n");
5643 goto error;
5644 }
5645
5646 raster =
5647 rl2_create_raster (tileWidth, tileHeight,
5648 RL2_SAMPLE_UINT8, out_pixel_type,
5649 out_bands, tilebuf, tilebuf_sz,
5650 NULL, tilemask, tilemask_sz, nd);
5651 tilebuf = NULL;
5652 tilemask = NULL;
5653 if (raster == NULL)
5654 {
5655 fprintf (stderr,
5656 "ERROR: unable to create a Pyramid Tile\n");
5657 goto error;
5658 }
5659 if (rl2_raster_encode
5660 (raster, RL2_COMPRESSION_JPEG, &blob_odd,
5661 &blob_odd_sz, &blob_even, &blob_even_sz, 100,
5662 1) != RL2_OK)
5663 {
5664 fprintf (stderr,
5665 "ERROR: unable to encode a Pyramid tile\n");
5666 goto error;
5667 }
5668
5669 /* INSERTing the tile */
5670 if (!do_insert_pyramid_tile
5671 (handle, blob_odd, blob_odd_sz, blob_even,
5672 blob_even_sz, id_level, sect_id, srid, t_minx,
5673 t_miny, t_maxx, t_maxy, stmt_tils, stmt_data))
5674 goto error;
5675 rl2_destroy_raster (raster);
5676 t_minx += (tileWidth * x_res);
5677 }
5678 t_maxy -= (tileHeight * y_res);
5679 }
5680
5681 free (outbuf);
5682 if (out_width < tileWidth && out_height < tileHeight)
5683 break;
5684 x_res *= 4.0;
5685 y_res *= 4.0;
5686 scale *= 4;
5687 id_level++;
5688 }
5689
5690 free (inbuf);
5691 sqlite3_finalize (stmt_rd);
5692 sqlite3_finalize (stmt_levl);
5693 sqlite3_finalize (stmt_tils);
5694 sqlite3_finalize (stmt_data);
5695 if (no_data != NULL)
5696 rl2_destroy_pixel (no_data);
5697 if (palette != NULL)
5698 rl2_destroy_palette (palette);
5699 return 1;
5700
5701 error:
5702 if (outbuf != NULL)
5703 free (outbuf);
5704 if (tilebuf != NULL)
5705 free (tilebuf);
5706 if (tilemask != NULL)
5707 free (tilemask);
5708 if (inbuf != NULL)
5709 free (inbuf);
5710 if (stmt != NULL)
5711 sqlite3_finalize (stmt);
5712 if (stmt_rd != NULL)
5713 sqlite3_finalize (stmt_rd);
5714 if (stmt_levl != NULL)
5715 sqlite3_finalize (stmt_levl);
5716 if (stmt_tils != NULL)
5717 sqlite3_finalize (stmt_tils);
5718 if (stmt_data != NULL)
5719 sqlite3_finalize (stmt_data);
5720 if (no_data != NULL)
5721 rl2_destroy_pixel (no_data);
5722 if (palette != NULL)
5723 rl2_destroy_palette (palette);
5724 return 0;
5725 }
5726
5727 static void
get_background_color(sqlite3 * handle,rl2CoveragePtr coverage,unsigned char * bgRed,unsigned char * bgGreen,unsigned char * bgBlue)5728 get_background_color (sqlite3 * handle, rl2CoveragePtr coverage,
5729 unsigned char *bgRed, unsigned char *bgGreen,
5730 unsigned char *bgBlue)
5731 {
5732 /* retrieving the background color for 1,2,4 bit samples */
5733 sqlite3_stmt *stmt = NULL;
5734 char *sql;
5735 int ret;
5736 rl2PrivPalettePtr plt;
5737 rl2PalettePtr palette = NULL;
5738 rl2PrivSamplePtr smp;
5739 rl2PrivPixelPtr pxl;
5740 rl2PrivCoveragePtr cvg = (rl2PrivCoveragePtr) coverage;
5741 unsigned char index;
5742 *bgRed = 255;
5743 *bgGreen = 255;
5744 *bgBlue = 255;
5745
5746 if (cvg == NULL)
5747 return;
5748 if (cvg->noData == NULL)
5749 return;
5750 pxl = (rl2PrivPixelPtr) (cvg->noData);
5751 smp = pxl->Samples;
5752 index = smp->uint8;
5753
5754 if (cvg->pixelType == RL2_PIXEL_MONOCHROME)
5755 {
5756 if (index == 1)
5757 {
5758 *bgRed = 0;
5759 *bgGreen = 0;
5760 *bgBlue = 0;
5761 }
5762 return;
5763 }
5764
5765 /* Coverage's palette */
5766 sql = sqlite3_mprintf ("SELECT palette FROM raster_coverages "
5767 "WHERE Lower(coverage_name) = Lower(%Q)",
5768 cvg->coverageName);
5769 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
5770 sqlite3_free (sql);
5771 if (ret != SQLITE_OK)
5772 {
5773 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
5774 goto error;
5775 }
5776 while (1)
5777 {
5778 ret = sqlite3_step (stmt);
5779 if (ret == SQLITE_DONE)
5780 break;
5781 if (ret == SQLITE_ROW)
5782 {
5783 if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
5784 {
5785 const unsigned char *blob = sqlite3_column_blob (stmt, 0);
5786 int blob_sz = sqlite3_column_bytes (stmt, 0);
5787 palette = rl2_deserialize_dbms_palette (blob, blob_sz);
5788 }
5789 }
5790 else
5791 {
5792 fprintf (stderr,
5793 "SELECT section_info; sqlite3_step() error: %s\n",
5794 sqlite3_errmsg (handle));
5795 goto error;
5796 }
5797 }
5798 sqlite3_finalize (stmt);
5799 if (palette == NULL)
5800 goto error;
5801
5802 plt = (rl2PrivPalettePtr) palette;
5803 if (index < plt->nEntries)
5804 {
5805 rl2PrivPaletteEntryPtr rgb = plt->entries + index;
5806 *bgRed = rgb->red;
5807 *bgGreen = rgb->green;
5808 *bgBlue = rgb->blue;
5809 }
5810 rl2_destroy_palette (palette);
5811 return;
5812
5813 error:
5814 if (stmt != NULL)
5815 sqlite3_finalize (stmt);
5816 if (palette != NULL)
5817 rl2_destroy_palette (palette);
5818 }
5819
5820 RL2_DECLARE int
rl2_build_section_pyramid(sqlite3 * handle,const char * coverage,const char * section,int forced_rebuild)5821 rl2_build_section_pyramid (sqlite3 * handle, const char *coverage,
5822 const char *section, int forced_rebuild)
5823 {
5824 /* (re)building section-level pyramid for a single Section */
5825 rl2CoveragePtr cvg = NULL;
5826 unsigned char sample_type;
5827 unsigned char pixel_type;
5828 unsigned char num_bands;
5829 unsigned char compression;
5830 int quality;
5831 unsigned int tileWidth;
5832 unsigned int tileHeight;
5833 int srid;
5834 int build = 0;
5835 unsigned char bgRed;
5836 unsigned char bgGreen;
5837 unsigned char bgBlue;
5838
5839 cvg = rl2_create_coverage_from_dbms (handle, coverage);
5840 if (cvg == NULL)
5841 goto error;
5842
5843 if (rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands) !=
5844 RL2_OK)
5845 goto error;
5846 if (rl2_get_coverage_compression (cvg, &compression, &quality) != RL2_OK)
5847 goto error;
5848 if (rl2_get_coverage_tile_size (cvg, &tileWidth, &tileHeight) != RL2_OK)
5849 goto error;
5850 if (rl2_get_coverage_srid (cvg, &srid) != RL2_OK)
5851 goto error;
5852
5853 if (!forced_rebuild)
5854 {
5855 /* checking if the section pyramid already exists */
5856 build = check_section_pyramid (handle, coverage, section);
5857 }
5858 else
5859 {
5860 /* unconditional rebuilding */
5861 build = 1;
5862 }
5863
5864 if (build)
5865 {
5866 /* attempting to delete the section pyramid */
5867 if (!delete_section_pyramid (handle, coverage, section))
5868 goto error;
5869 /* attempting to (re)build the section pyramid */
5870 if ((sample_type == RL2_SAMPLE_1_BIT
5871 && pixel_type == RL2_PIXEL_MONOCHROME && num_bands == 1)
5872 || (sample_type == RL2_SAMPLE_1_BIT
5873 && pixel_type == RL2_PIXEL_PALETTE && num_bands == 1)
5874 || (sample_type == RL2_SAMPLE_2_BIT
5875 && pixel_type == RL2_PIXEL_PALETTE && num_bands == 1)
5876 || (sample_type == RL2_SAMPLE_4_BIT
5877 && pixel_type == RL2_PIXEL_PALETTE && num_bands == 1))
5878 {
5879 /* special case: 1,2,4 bit Pyramid */
5880 get_background_color (handle, cvg, &bgRed, &bgGreen, &bgBlue);
5881 if (!do_build_124_bit_section_pyramid
5882 (handle, coverage, section, sample_type, pixel_type,
5883 num_bands, srid, tileWidth, tileHeight, bgRed, bgGreen,
5884 bgBlue))
5885 goto error;
5886 }
5887 else if (sample_type == RL2_SAMPLE_UINT8
5888 && pixel_type == RL2_PIXEL_PALETTE && num_bands == 1)
5889 {
5890 /* special case: 8 bit Palette Pyramid */
5891 get_background_color (handle, cvg, &bgRed, &bgGreen, &bgBlue);
5892 if (!do_build_palette_section_pyramid
5893 (handle, coverage, section, srid, tileWidth, tileHeight,
5894 bgRed, bgGreen, bgBlue))
5895 goto error;
5896 }
5897 else
5898 {
5899 /* ordinary RGB, Grayscale, MultiBand or DataGrid Pyramid */
5900 if (!do_build_section_pyramid
5901 (handle, coverage, section, sample_type, pixel_type,
5902 num_bands, compression, quality, srid, tileWidth,
5903 tileHeight))
5904 goto error;
5905 }
5906 printf (" ----------\n");
5907 printf (" Pyramid levels successfully built for: %s\n", section);
5908 }
5909 rl2_destroy_coverage (cvg);
5910
5911 return RL2_OK;
5912
5913 error:
5914 if (cvg != NULL)
5915 rl2_destroy_coverage (cvg);
5916 return RL2_ERROR;
5917 }
5918
5919 RL2_DECLARE int
rl2_build_all_section_pyramids(sqlite3 * handle,const char * coverage,int forced_rebuild)5920 rl2_build_all_section_pyramids (sqlite3 * handle, const char *coverage,
5921 int forced_rebuild)
5922 {
5923 /* (re)building section-level pyramids for a whole Coverage */
5924 char *table;
5925 char *xtable;
5926 int ret;
5927 int i;
5928 char **results;
5929 int rows;
5930 int columns;
5931 char *sql;
5932
5933 table = sqlite3_mprintf ("%s_sections", coverage);
5934 xtable = gaiaDoubleQuotedSql (table);
5935 sqlite3_free (table);
5936 sql = sqlite3_mprintf ("SELECT section_name FROM \"%s\"", xtable);
5937 free (xtable);
5938 ret = sqlite3_get_table (handle, sql, &results, &rows, &columns, NULL);
5939 sqlite3_free (sql);
5940 if (ret != SQLITE_OK)
5941 goto error;
5942 if (rows < 1)
5943 ;
5944 else
5945 {
5946 for (i = 1; i <= rows; i++)
5947 {
5948 const char *section = results[(i * columns) + 0];
5949 if (rl2_build_section_pyramid
5950 (handle, coverage, section, forced_rebuild) != RL2_OK)
5951 goto error;
5952 }
5953 }
5954 sqlite3_free_table (results);
5955 return RL2_OK;
5956
5957 error:
5958 return RL2_ERROR;
5959 }
5960
5961 static int
is_full_mask(const unsigned char * mask,int mask_size)5962 is_full_mask (const unsigned char *mask, int mask_size)
5963 {
5964 /* testing for a completely transparent mask */
5965 const unsigned char *p = mask;
5966 int i;
5967 int count = 0;
5968 if (mask == NULL)
5969 return 0;
5970 for (i = 0; i < mask_size; i++)
5971 {
5972 if (*p++ == 0)
5973 count++;
5974 }
5975 if (count == mask_size)
5976 return 1;
5977 return 0;
5978 }
5979
5980 RL2_DECLARE int
rl2_build_monolithic_pyramid(sqlite3 * handle,const char * coverage,int virt_levels)5981 rl2_build_monolithic_pyramid (sqlite3 * handle, const char *coverage,
5982 int virt_levels)
5983 {
5984 /* (re)building monolithic pyramid for a whole coverage */
5985 rl2CoveragePtr cvg = NULL;
5986 rl2PrivCoveragePtr cov;
5987 unsigned char sample_type;
5988 unsigned char pixel_type;
5989 unsigned char num_bands;
5990 unsigned char compression;
5991 int quality;
5992 unsigned int tileWidth;
5993 unsigned int tileHeight;
5994 int srid;
5995 double minx;
5996 double miny;
5997 double maxx;
5998 double maxy;
5999 unsigned int row;
6000 unsigned int col;
6001 unsigned int tot_rows;
6002 double res_x;
6003 double res_y;
6004 int factor;
6005 int resize_factor;
6006 int id_level = 0;
6007 unsigned char out_sample_type;
6008 unsigned char out_pixel_type;
6009 unsigned char out_num_bands;
6010 unsigned char out_compression;
6011 int out_quality;
6012 rl2PixelPtr no_data = NULL;
6013 rl2PixelPtr nd = NULL;
6014 rl2PalettePtr palette = NULL;
6015 unsigned char *buffer = NULL;
6016 int buf_size;
6017 int sample_sz;
6018 unsigned char *mask = NULL;
6019 int mask_size;
6020 rl2RasterPtr raster = NULL;
6021 unsigned char *blob_odd = NULL;
6022 unsigned char *blob_even = NULL;
6023 int blob_odd_sz;
6024 int blob_even_sz;
6025 sqlite3_stmt *stmt_geo = NULL;
6026 sqlite3_stmt *stmt_rd = NULL;
6027 sqlite3_stmt *stmt_levl = NULL;
6028 sqlite3_stmt *stmt_tils = NULL;
6029 sqlite3_stmt *stmt_data = NULL;
6030 char *xtiles;
6031 char *xxtiles;
6032 int ret;
6033 char *sql;
6034 double tile_minx;
6035 double tile_miny;
6036 double tile_maxx;
6037 double tile_maxy;
6038 double end_x;
6039 double end_y;
6040 int stop = 0;
6041
6042 /* preparing the "tiles" SQL query */
6043 xtiles = sqlite3_mprintf ("%s_tiles", coverage);
6044 xxtiles = gaiaDoubleQuotedSql (xtiles);
6045 sql =
6046 sqlite3_mprintf
6047 ("SELECT tile_id, MbrMinX(geometry), MbrMaxY(geometry) FROM \"%s\" "
6048 "WHERE pyramid_level = ? AND ROWID IN (SELECT ROWID FROM SpatialIndex "
6049 "WHERE f_table_name = %Q AND search_frame = BuildMBR(?, ?, ?, ?)) "
6050 "ORDER BY ST_Area(geometry)", xxtiles, xtiles);
6051 sqlite3_free (xtiles);
6052 free (xxtiles);
6053 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_geo, NULL);
6054 sqlite3_free (sql);
6055 if (ret != SQLITE_OK)
6056 {
6057 printf ("SELECT monolithic RGBA tiles SQL error: %s\n",
6058 sqlite3_errmsg (handle));
6059 goto error;
6060 }
6061
6062 cvg = rl2_create_coverage_from_dbms (handle, coverage);
6063 if (cvg == NULL)
6064 goto error;
6065 cov = (rl2PrivCoveragePtr) cvg;
6066
6067 if (rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands) !=
6068 RL2_OK)
6069 goto error;
6070 if (rl2_get_coverage_compression (cvg, &compression, &quality) != RL2_OK)
6071 goto error;
6072 if (rl2_get_coverage_tile_size (cvg, &tileWidth, &tileHeight) != RL2_OK)
6073 goto error;
6074 if (rl2_get_coverage_srid (cvg, &srid) != RL2_OK)
6075 goto error;
6076 if (!get_coverage_extent (handle, coverage, &minx, &miny, &maxx, &maxy))
6077 goto error;
6078 no_data = rl2_get_coverage_no_data (cvg);
6079 palette = rl2_get_dbms_palette (handle, coverage);
6080 if (!prepare_section_pyramid_stmts
6081 (handle, coverage, &stmt_rd, &stmt_levl, &stmt_tils, &stmt_data))
6082 goto error;
6083
6084 if (sample_type == RL2_SAMPLE_1_BIT
6085 && pixel_type == RL2_PIXEL_MONOCHROME && num_bands == 1)
6086 {
6087 /* monochrome: output colorspace is Grayscale */
6088 out_sample_type = RL2_SAMPLE_UINT8;
6089 out_pixel_type = RL2_PIXEL_GRAYSCALE;
6090 out_num_bands = 1;
6091 out_compression = RL2_COMPRESSION_PNG;
6092 out_quality = 100;
6093 factor = 2;
6094 resize_factor = 2;
6095 }
6096 else if ((sample_type == RL2_SAMPLE_1_BIT
6097 && pixel_type == RL2_PIXEL_PALETTE && num_bands == 1)
6098 || (sample_type == RL2_SAMPLE_2_BIT
6099 && pixel_type == RL2_PIXEL_PALETTE && num_bands == 1)
6100 || (sample_type == RL2_SAMPLE_4_BIT))
6101 {
6102 /* palette 1,2,4: output colorspace is RGB */
6103 out_sample_type = RL2_SAMPLE_UINT8;
6104 out_pixel_type = RL2_PIXEL_RGB;
6105 out_num_bands = 3;
6106 out_compression = RL2_COMPRESSION_PNG;
6107 out_quality = 100;
6108 factor = 2;
6109 resize_factor = 2;
6110 }
6111 else if (sample_type == RL2_SAMPLE_UINT8 && pixel_type == RL2_PIXEL_PALETTE
6112 && num_bands == 1)
6113 {
6114 /* palette 8: RGB JPEG pyramid level */
6115 out_sample_type = RL2_SAMPLE_UINT8;
6116 out_pixel_type = RL2_PIXEL_RGB;
6117 out_num_bands = 3;
6118 out_compression = RL2_COMPRESSION_JPEG;
6119 out_quality = 80;
6120 }
6121 else
6122 {
6123 /* unaltered output colorspace */
6124 out_sample_type = sample_type;
6125 out_pixel_type = pixel_type;
6126 out_num_bands = num_bands;
6127 if (sample_type == RL2_SAMPLE_UINT8
6128 && ((pixel_type == RL2_PIXEL_RGB && num_bands == 3)
6129 || (pixel_type == RL2_PIXEL_GRAYSCALE && num_bands == 1)))
6130 {
6131 out_compression = RL2_COMPRESSION_JPEG;
6132 out_quality = quality;
6133 }
6134 else
6135 {
6136 out_compression = RL2_COMPRESSION_DEFLATE;
6137 out_quality = 100;
6138 }
6139 /* setting the requested virt_levels */
6140 switch (virt_levels)
6141 {
6142 case 1: /* separating each physical level */
6143 resize_factor = 2;
6144 break;
6145 case 2: /* one physical + one virtual */
6146 resize_factor = 4;
6147 break;
6148 case 3: /* one physical + two virtuals */
6149 resize_factor = 8;
6150 break;
6151 default:
6152 resize_factor = 8;
6153 break;
6154 };
6155 factor = resize_factor;
6156 }
6157
6158 /* computing output tile buffers */
6159 switch (out_sample_type)
6160 {
6161 case RL2_SAMPLE_INT16:
6162 case RL2_SAMPLE_UINT16:
6163 sample_sz = 2;
6164 break;
6165 case RL2_SAMPLE_INT32:
6166 case RL2_SAMPLE_UINT32:
6167 case RL2_SAMPLE_FLOAT:
6168 sample_sz = 4;
6169 break;
6170 case RL2_SAMPLE_DOUBLE:
6171 sample_sz = 8;
6172 break;
6173 default:
6174 sample_sz = 1;
6175 break;
6176 }
6177 buf_size = tileWidth * tileHeight * out_num_bands * sample_sz;
6178
6179 /* attempting to delete the section pyramid */
6180 if (rl2_delete_all_pyramids (handle, coverage) != RL2_OK)
6181 goto error;
6182
6183 /* attempting to (re)build the section pyramid */
6184 while (1)
6185 {
6186 /* looping on pyramid levels */
6187 tile_maxy = maxy;
6188 row = 0;
6189 res_x = cov->hResolution * (double) factor;
6190 res_y = cov->vResolution * (double) factor;
6191 if (!do_insert_pyramid_levels
6192 (handle, id_level + 1, res_x, res_y, stmt_levl))
6193 goto error;
6194 tot_rows = 0;
6195 while (1)
6196 {
6197 /* pre-computing the max row-number */
6198 tile_miny = tile_maxy - ((double) tileHeight * res_y);
6199 tile_minx = minx;
6200 if (tile_maxy < miny)
6201 break;
6202 tot_rows++;
6203 tile_maxy = tile_miny;
6204 }
6205
6206 tile_maxy = maxy;
6207 while (1)
6208 {
6209 /* looping on rows */
6210 tile_miny = tile_maxy - ((double) tileHeight * res_y);
6211 tile_minx = minx;
6212 if (tile_maxy < miny)
6213 break;
6214 col = 0;
6215 while (1)
6216 {
6217 /* looping on columns */
6218 tile_maxx = tile_minx + ((double) tileWidth * res_x);
6219 if (tile_minx > maxx)
6220 break;
6221 /* allocating output tile buffers */
6222 buffer = malloc (buf_size);
6223 if (buffer == NULL)
6224 goto error;
6225 mask_size = tileWidth * tileHeight;
6226 mask = malloc (mask_size);
6227 if (mask == NULL)
6228 goto error;
6229 end_x = tile_maxx;
6230 if (tile_maxx > maxx)
6231 end_x = maxx;
6232 end_y = tile_miny;
6233 if (tile_miny < miny)
6234 end_y = miny;
6235
6236 if ((sample_type == RL2_SAMPLE_UINT8
6237 && pixel_type == RL2_PIXEL_GRAYSCALE
6238 && num_bands == 1)
6239 || (sample_type == RL2_SAMPLE_UINT8
6240 && pixel_type == RL2_PIXEL_RGB && num_bands == 3)
6241 || (sample_type == RL2_SAMPLE_UINT8
6242 && pixel_type == RL2_PIXEL_PALETTE
6243 && num_bands == 1))
6244 {
6245 /* RGB, PALETTE or GRAYSCALE datasource (UINT8) */
6246 if (!rescale_monolithic_rgba
6247 (id_level, tileWidth, tileHeight, resize_factor,
6248 res_x, res_y, tile_minx, tile_miny,
6249 tile_maxx, tile_maxy, buffer, buf_size, mask,
6250 &mask_size, palette, no_data, stmt_geo,
6251 stmt_rd))
6252 goto error;
6253 if (mask_size == 0)
6254 mask = NULL;
6255 }
6256 else if (((sample_type == RL2_SAMPLE_1_BIT
6257 || sample_type == RL2_SAMPLE_2_BIT
6258 || sample_type == RL2_SAMPLE_4_BIT)
6259 && pixel_type == RL2_PIXEL_PALETTE
6260 && num_bands == 1)
6261 || (sample_type == RL2_SAMPLE_1_BIT
6262 && pixel_type == RL2_PIXEL_MONOCHROME
6263 && num_bands == 1))
6264 {
6265 /* MONOCHROME and 1,2,4 bit PALETTE */
6266 if (!rescale_monolithic_124
6267 (id_level, tileWidth,
6268 tileHeight, resize_factor, pixel_type,
6269 res_x, res_y, tile_minx, tile_miny,
6270 tile_maxx, tile_maxy, buffer, buf_size, mask,
6271 &mask_size, palette, no_data, stmt_geo,
6272 stmt_rd))
6273 goto error;
6274 if (mask_size == 0)
6275 mask = NULL;
6276 }
6277 else if (pixel_type == RL2_PIXEL_MULTIBAND)
6278 {
6279 /* MultiBand */
6280 if (!rescale_monolithic_multiband
6281 (id_level, tileWidth, tileHeight, sample_type,
6282 num_bands, resize_factor, res_x, res_y,
6283 tile_minx, tile_miny, tile_maxx, tile_maxy,
6284 buffer, buf_size, mask, &mask_size, no_data,
6285 stmt_geo, stmt_rd))
6286 goto error;
6287 if (mask_size == 0)
6288 mask = NULL;
6289 }
6290 else if (pixel_type == RL2_PIXEL_DATAGRID)
6291 {
6292 /* DataGrid */
6293 if (!rescale_monolithic_datagrid
6294 (id_level, tileWidth, tileHeight, sample_type,
6295 resize_factor, res_x, res_y, tile_minx,
6296 tile_miny, tile_maxx, tile_maxy, buffer,
6297 buf_size, mask, &mask_size, no_data, stmt_geo,
6298 stmt_rd))
6299 goto error;
6300 if (mask_size == 0)
6301 mask = NULL;
6302 }
6303 else
6304 {
6305 /* unknown */
6306 fprintf (stderr,
6307 "ERROR: unsupported Monolithic pyramid type\n");
6308 goto error;
6309 }
6310 if (is_full_mask (mask, mask_size))
6311 {
6312 /* skipping a completely void tile */
6313 free (buffer);
6314 free (mask);
6315 buffer = NULL;
6316 mask = NULL;
6317 goto done;
6318 }
6319
6320 if (pixel_type == RL2_PIXEL_MONOCHROME)
6321 {
6322 if (no_data == NULL)
6323 nd = NULL;
6324 else
6325 {
6326 rl2PrivPixelPtr pxl =
6327 (rl2PrivPixelPtr) no_data;
6328 rl2PrivSamplePtr sample = pxl->Samples + 0;
6329 nd = rl2_create_pixel (RL2_SAMPLE_UINT8,
6330 RL2_PIXEL_GRAYSCALE,
6331 1);
6332 if (sample->uint8 == 0)
6333 rl2_set_pixel_sample_uint8 (nd,
6334 RL2_GRAYSCALE_BAND,
6335 255);
6336 else
6337 rl2_set_pixel_sample_uint8 (nd,
6338 RL2_GRAYSCALE_BAND,
6339 0);
6340 }
6341 }
6342 else if (pixel_type == RL2_PIXEL_PALETTE)
6343 {
6344 if (no_data == NULL)
6345 nd = NULL;
6346 else
6347 {
6348 nd = rl2_create_pixel (RL2_SAMPLE_UINT8,
6349 RL2_PIXEL_RGB, 3);
6350 rl2_set_pixel_sample_uint8 (nd, RL2_RED_BAND,
6351 255);
6352 rl2_set_pixel_sample_uint8 (nd,
6353 RL2_GREEN_BAND,
6354 255);
6355 rl2_set_pixel_sample_uint8 (nd, RL2_BLUE_BAND,
6356 255);
6357 }
6358 }
6359 else
6360 nd = rl2_clone_pixel (no_data);
6361
6362 raster =
6363 rl2_create_raster (tileWidth, tileHeight,
6364 out_sample_type, out_pixel_type,
6365 out_num_bands, buffer, buf_size,
6366 NULL, mask, mask_size, nd);
6367 buffer = NULL;
6368 mask = NULL;
6369 if (raster == NULL)
6370 {
6371 fprintf (stderr,
6372 "ERROR: unable to create a Pyramid Tile\n");
6373 goto error;
6374 }
6375 if (rl2_raster_encode
6376 (raster, out_compression, &blob_odd, &blob_odd_sz,
6377 &blob_even, &blob_even_sz, out_quality, 1) != RL2_OK)
6378 {
6379 fprintf (stderr,
6380 "ERROR: unable to encode a Pyramid tile\n");
6381 goto error;
6382 }
6383
6384 /* INSERTing the tile */
6385 if (!do_insert_pyramid_tile
6386 (handle, blob_odd, blob_odd_sz, blob_even,
6387 blob_even_sz, id_level + 1, -1, srid, tile_minx,
6388 end_y, end_x, tile_maxy, stmt_tils, stmt_data))
6389 goto error;
6390 rl2_destroy_raster (raster);
6391 raster = NULL;
6392
6393 done:
6394 tile_minx = tile_maxx;
6395 col++;
6396 }
6397 tile_maxy = tile_miny;
6398 row++;
6399 printf (" ----------\n");
6400 printf
6401 (" %s: Monolithic Pyramid Level %d - Row %d of %d successfully built\n",
6402 coverage, id_level + 1, row, tot_rows);
6403 }
6404 if (stop)
6405 break;
6406 if ((minx +
6407 ((double) tileWidth * res_x) > maxx)
6408 && (maxy - ((double) tileHeight * res_y) < maxy))
6409 stop = 1;
6410 /* setting the requested virt_levels */
6411 switch (virt_levels)
6412 {
6413 case 1: /* separating each physical level */
6414 resize_factor = 2;
6415 break;
6416 case 2: /* one physical + one virtual */
6417 resize_factor = 4;
6418 break;
6419 case 3: /* one physical + two virtuals */
6420 resize_factor = 8;
6421 break;
6422 };
6423 factor *= resize_factor;
6424 id_level++;
6425 if (palette != NULL)
6426 {
6427 /* destroying an eventual Palette after completing the first level */
6428 rl2_destroy_palette (palette);
6429 palette = NULL;
6430 }
6431 }
6432 sqlite3_finalize (stmt_geo);
6433 sqlite3_finalize (stmt_rd);
6434 sqlite3_finalize (stmt_levl);
6435 sqlite3_finalize (stmt_tils);
6436 sqlite3_finalize (stmt_data);
6437 printf (" ----------\n");
6438 printf (" Monolithic Pyramid levels successfully built for: %s\n",
6439 coverage);
6440 free (buffer);
6441 free (mask);
6442 rl2_destroy_coverage (cvg);
6443
6444 return RL2_OK;
6445
6446 error:
6447 if (stmt_geo != NULL)
6448 sqlite3_finalize (stmt_geo);
6449 if (stmt_rd != NULL)
6450 sqlite3_finalize (stmt_rd);
6451 if (stmt_levl != NULL)
6452 sqlite3_finalize (stmt_levl);
6453 if (stmt_tils != NULL)
6454 sqlite3_finalize (stmt_tils);
6455 if (stmt_data != NULL)
6456 sqlite3_finalize (stmt_data);
6457 if (buffer != NULL)
6458 free (buffer);
6459 if (mask != NULL)
6460 free (mask);
6461 if (cvg != NULL)
6462 rl2_destroy_coverage (cvg);
6463 if (palette != NULL)
6464 rl2_destroy_palette (palette);
6465 if (raster != NULL)
6466 rl2_destroy_raster (raster);
6467 return RL2_ERROR;
6468 }
6469
6470 RL2_DECLARE int
rl2_delete_all_pyramids(sqlite3 * handle,const char * coverage)6471 rl2_delete_all_pyramids (sqlite3 * handle, const char *coverage)
6472 {
6473 /* deleting all pyramids for a whole Coverage */
6474 char *sql;
6475 char *table;
6476 char *xtable;
6477 int ret;
6478 char *err_msg = NULL;
6479
6480 table = sqlite3_mprintf ("%s_tiles", coverage);
6481 xtable = gaiaDoubleQuotedSql (table);
6482 sqlite3_free (table);
6483 sql =
6484 sqlite3_mprintf ("DELETE FROM \"%s\" WHERE pyramid_level > 0", xtable);
6485 free (xtable);
6486 ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
6487 sqlite3_free (sql);
6488 if (ret != SQLITE_OK)
6489 {
6490 fprintf (stderr, "DELETE FROM \"%s_tiles\" error: %s\n", coverage,
6491 err_msg);
6492 sqlite3_free (err_msg);
6493 return RL2_ERROR;
6494 }
6495
6496 table = sqlite3_mprintf ("%s_levels", coverage);
6497 xtable = gaiaDoubleQuotedSql (table);
6498 sqlite3_free (table);
6499 sql =
6500 sqlite3_mprintf ("DELETE FROM \"%s\" WHERE pyramid_level > 0", xtable);
6501 free (xtable);
6502 ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
6503 sqlite3_free (sql);
6504 if (ret != SQLITE_OK)
6505 {
6506 fprintf (stderr, "DELETE FROM \"%s_levels\" error: %s\n", coverage,
6507 err_msg);
6508 sqlite3_free (err_msg);
6509 return RL2_ERROR;
6510 }
6511 return RL2_OK;
6512 }
6513
6514 RL2_DECLARE int
rl2_delete_section_pyramid(sqlite3 * handle,const char * coverage,const char * section)6515 rl2_delete_section_pyramid (sqlite3 * handle, const char *coverage,
6516 const char *section)
6517 {
6518 /* deleting section-level pyramid for a single Section */
6519 if (!delete_section_pyramid (handle, coverage, section))
6520 return RL2_ERROR;
6521 return RL2_OK;
6522 }
6523