1 /*
2
3 rl2sqlaux -- private SQL helper methods
4
5 version 0.1, 2014 February 28
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 #include <limits.h>
49 #include <stdint.h>
50 #include <inttypes.h>
51
52 #ifdef _WIN32
53 #include <io.h>
54 #else
55 #include <unistd.h>
56 #endif
57
58 #include "config.h"
59
60 #ifdef LOADABLE_EXTENSION
61 #include "rasterlite2/sqlite.h"
62 #endif
63
64 #include "rasterlite2/rasterlite2.h"
65 #include "rasterlite2/rl2wms.h"
66 #include "rasterlite2/rl2graphics.h"
67 #include "rasterlite2_private.h"
68
69 #include <spatialite/gaiaaux.h>
70
71 #define RL2_UNUSED() if (argc || argv) argc = argc;
72
73 RL2_PRIVATE int
get_coverage_sample_bands(sqlite3 * sqlite,const char * coverage,unsigned char * sample_type,unsigned char * num_bands)74 get_coverage_sample_bands (sqlite3 * sqlite, const char *coverage,
75 unsigned char *sample_type, unsigned char *num_bands)
76 {
77 /* attempting to retrieve the SampleType and NumBands from a Coverage */
78 int i;
79 char **results;
80 int rows;
81 int columns;
82 char *sql;
83 int ret;
84 const char *sample;
85 int bands;
86 unsigned char xsample_type = RL2_SAMPLE_UNKNOWN;
87 unsigned char xnum_bands = RL2_BANDS_UNKNOWN;
88
89 sql =
90 sqlite3_mprintf ("SELECT sample_type, num_bands FROM raster_coverages "
91 "WHERE Lower(coverage_name) = Lower(%Q)", coverage);
92 ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, NULL);
93 sqlite3_free (sql);
94 if (ret != SQLITE_OK)
95 return 0;
96 if (rows < 1)
97 ;
98 else
99 {
100 for (i = 1; i <= rows; i++)
101 {
102 sample = results[(i * columns) + 0];
103 if (strcmp (sample, "1-BIT") == 0)
104 xsample_type = RL2_SAMPLE_1_BIT;
105 if (strcmp (sample, "2-BIT") == 0)
106 xsample_type = RL2_SAMPLE_2_BIT;
107 if (strcmp (sample, "4-BIT") == 0)
108 xsample_type = RL2_SAMPLE_4_BIT;
109 if (strcmp (sample, "INT8") == 0)
110 xsample_type = RL2_SAMPLE_INT8;
111 if (strcmp (sample, "UINT8") == 0)
112 xsample_type = RL2_SAMPLE_UINT8;
113 if (strcmp (sample, "INT16") == 0)
114 xsample_type = RL2_SAMPLE_INT16;
115 if (strcmp (sample, "UINT16") == 0)
116 xsample_type = RL2_SAMPLE_UINT16;
117 if (strcmp (sample, "INT32") == 0)
118 xsample_type = RL2_SAMPLE_INT32;
119 if (strcmp (sample, "UINT32") == 0)
120 xsample_type = RL2_SAMPLE_UINT32;
121 if (strcmp (sample, "FLOAT") == 0)
122 xsample_type = RL2_SAMPLE_FLOAT;
123 if (strcmp (sample, "DOUBLE") == 0)
124 xsample_type = RL2_SAMPLE_DOUBLE;
125 bands = atoi (results[(i * columns) + 1]);
126 if (bands > 0 && bands < 256)
127 xnum_bands = bands;
128 }
129 }
130 sqlite3_free_table (results);
131 if (xsample_type == RL2_SAMPLE_UNKNOWN || xnum_bands == RL2_BANDS_UNKNOWN)
132 return 0;
133 *sample_type = xsample_type;
134 *num_bands = xnum_bands;
135 return 1;
136 }
137
138 RL2_PRIVATE int
get_coverage_defs(sqlite3 * sqlite,const char * coverage,unsigned int * tile_width,unsigned int * tile_height,unsigned char * sample_type,unsigned char * pixel_type,unsigned char * num_bands,unsigned char * compression)139 get_coverage_defs (sqlite3 * sqlite, const char *coverage,
140 unsigned int *tile_width, unsigned int *tile_height,
141 unsigned char *sample_type, unsigned char *pixel_type,
142 unsigned char *num_bands, unsigned char *compression)
143 {
144 /* attempting to retrieve the main definitions from a Coverage */
145 int i;
146 char **results;
147 int rows;
148 int columns;
149 char *sql;
150 int ret;
151 const char *sample;
152 const char *pixel;
153 const char *compr;
154 int bands;
155 unsigned char xsample_type = RL2_SAMPLE_UNKNOWN;
156 unsigned char xpixel_type = RL2_PIXEL_UNKNOWN;
157 unsigned char xnum_bands = RL2_BANDS_UNKNOWN;
158 unsigned char xcompression = RL2_COMPRESSION_UNKNOWN;
159 unsigned short xtile_width = RL2_TILESIZE_UNDEFINED;
160 unsigned short xtile_height = RL2_TILESIZE_UNDEFINED;
161
162 sql = sqlite3_mprintf ("SELECT sample_type, pixel_type, num_bands, "
163 "compression, tile_width, tile_height FROM raster_coverages "
164 "WHERE Lower(coverage_name) = Lower(%Q)", coverage);
165 ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, NULL);
166 sqlite3_free (sql);
167 if (ret != SQLITE_OK)
168 return 0;
169 if (rows < 1)
170 ;
171 else
172 {
173 for (i = 1; i <= rows; i++)
174 {
175 sample = results[(i * columns) + 0];
176 if (strcmp (sample, "1-BIT") == 0)
177 xsample_type = RL2_SAMPLE_1_BIT;
178 if (strcmp (sample, "2-BIT") == 0)
179 xsample_type = RL2_SAMPLE_2_BIT;
180 if (strcmp (sample, "4-BIT") == 0)
181 xsample_type = RL2_SAMPLE_4_BIT;
182 if (strcmp (sample, "INT8") == 0)
183 xsample_type = RL2_SAMPLE_INT8;
184 if (strcmp (sample, "UINT8") == 0)
185 xsample_type = RL2_SAMPLE_UINT8;
186 if (strcmp (sample, "INT16") == 0)
187 xsample_type = RL2_SAMPLE_INT16;
188 if (strcmp (sample, "UINT16") == 0)
189 xsample_type = RL2_SAMPLE_UINT16;
190 if (strcmp (sample, "INT32") == 0)
191 xsample_type = RL2_SAMPLE_INT32;
192 if (strcmp (sample, "UINT32") == 0)
193 xsample_type = RL2_SAMPLE_UINT32;
194 if (strcmp (sample, "FLOAT") == 0)
195 xsample_type = RL2_SAMPLE_FLOAT;
196 if (strcmp (sample, "DOUBLE") == 0)
197 xsample_type = RL2_SAMPLE_DOUBLE;
198 pixel = results[(i * columns) + 1];
199 if (strcmp (pixel, "MONOCHROME") == 0)
200 xpixel_type = RL2_PIXEL_MONOCHROME;
201 if (strcmp (pixel, "PALETTE") == 0)
202 xpixel_type = RL2_PIXEL_PALETTE;
203 if (strcmp (pixel, "GRAYSCALE") == 0)
204 xpixel_type = RL2_PIXEL_GRAYSCALE;
205 if (strcmp (pixel, "RGB") == 0)
206 xpixel_type = RL2_PIXEL_RGB;
207 if (strcmp (pixel, "MULTIBAND") == 0)
208 xpixel_type = RL2_PIXEL_MULTIBAND;
209 if (strcmp (pixel, "DATAGRID") == 0)
210 xpixel_type = RL2_PIXEL_DATAGRID;
211 bands = atoi (results[(i * columns) + 2]);
212 if (bands > 0 && bands < 256)
213 xnum_bands = bands;
214 compr = results[(i * columns) + 3];
215 if (strcmp (compr, "NONE") == 0)
216 xcompression = RL2_COMPRESSION_NONE;
217 if (strcmp (compr, "DEFLATE") == 0)
218 xcompression = RL2_COMPRESSION_DEFLATE;
219 if (strcmp (compr, "LZMA") == 0)
220 xcompression = RL2_COMPRESSION_LZMA;
221 if (strcmp (compr, "GIF") == 0)
222 xcompression = RL2_COMPRESSION_GIF;
223 if (strcmp (compr, "PNG") == 0)
224 xcompression = RL2_COMPRESSION_PNG;
225 if (strcmp (compr, "JPEG") == 0)
226 xcompression = RL2_COMPRESSION_JPEG;
227 if (strcmp (compr, "LOSSY_WEBP") == 0)
228 xcompression = RL2_COMPRESSION_LOSSY_WEBP;
229 if (strcmp (compr, "LOSSLESS_WEBP") == 0)
230 xcompression = RL2_COMPRESSION_LOSSLESS_WEBP;
231 if (strcmp (compr, "CCITTFAX4") == 0)
232 xcompression = RL2_COMPRESSION_CCITTFAX4;
233 xtile_width = atoi (results[(i * columns) + 4]);
234 xtile_height = atoi (results[(i * columns) + 5]);
235 }
236 }
237 sqlite3_free_table (results);
238 if (xsample_type == RL2_SAMPLE_UNKNOWN || xpixel_type == RL2_PIXEL_UNKNOWN
239 || xnum_bands == RL2_BANDS_UNKNOWN
240 || xcompression == RL2_COMPRESSION_UNKNOWN
241 || xtile_width == RL2_TILESIZE_UNDEFINED
242 || xtile_height == RL2_TILESIZE_UNDEFINED)
243 return 0;
244 *sample_type = xsample_type;
245 *pixel_type = xpixel_type;
246 *num_bands = xnum_bands;
247 *compression = xcompression;
248 *tile_width = xtile_width;
249 *tile_height = xtile_height;
250 return 1;
251 }
252
253 RL2_PRIVATE rl2PixelPtr
default_nodata(unsigned char sample,unsigned char pixel,unsigned char num_bands)254 default_nodata (unsigned char sample, unsigned char pixel,
255 unsigned char num_bands)
256 {
257 /* creating a default NO-DATA value */
258 int nb;
259 rl2PixelPtr pxl = rl2_create_pixel (sample, pixel, num_bands);
260 if (pxl == NULL)
261 return NULL;
262 switch (pixel)
263 {
264 case RL2_PIXEL_MONOCHROME:
265 rl2_set_pixel_sample_1bit (pxl, 0);
266 break;
267 case RL2_PIXEL_PALETTE:
268 switch (sample)
269 {
270 case RL2_SAMPLE_1_BIT:
271 rl2_set_pixel_sample_1bit (pxl, 0);
272 break;
273 case RL2_SAMPLE_2_BIT:
274 rl2_set_pixel_sample_2bit (pxl, 0);
275 break;
276 case RL2_SAMPLE_4_BIT:
277 rl2_set_pixel_sample_4bit (pxl, 0);
278 break;
279 case RL2_SAMPLE_UINT8:
280 rl2_set_pixel_sample_uint8 (pxl, 0, 0);
281 break;
282 };
283 break;
284 case RL2_PIXEL_GRAYSCALE:
285 switch (sample)
286 {
287 case RL2_SAMPLE_1_BIT:
288 rl2_set_pixel_sample_1bit (pxl, 1);
289 break;
290 case RL2_SAMPLE_2_BIT:
291 rl2_set_pixel_sample_2bit (pxl, 3);
292 break;
293 case RL2_SAMPLE_4_BIT:
294 rl2_set_pixel_sample_4bit (pxl, 15);
295 break;
296 case RL2_SAMPLE_UINT8:
297 rl2_set_pixel_sample_uint8 (pxl, 0, 255);
298 break;
299 case RL2_SAMPLE_UINT16:
300 rl2_set_pixel_sample_uint16 (pxl, 0, 0);
301 break;
302 };
303 break;
304 case RL2_PIXEL_RGB:
305 switch (sample)
306 {
307 case RL2_SAMPLE_UINT8:
308 rl2_set_pixel_sample_uint8 (pxl, 0, 255);
309 rl2_set_pixel_sample_uint8 (pxl, 1, 255);
310 rl2_set_pixel_sample_uint8 (pxl, 2, 255);
311 break;
312 case RL2_SAMPLE_UINT16:
313 rl2_set_pixel_sample_uint16 (pxl, 0, 0);
314 rl2_set_pixel_sample_uint16 (pxl, 1, 0);
315 rl2_set_pixel_sample_uint16 (pxl, 2, 0);
316 break;
317 };
318 break;
319 case RL2_PIXEL_DATAGRID:
320 switch (sample)
321 {
322 case RL2_SAMPLE_INT8:
323 rl2_set_pixel_sample_int8 (pxl, 0);
324 break;
325 case RL2_SAMPLE_UINT8:
326 rl2_set_pixel_sample_uint8 (pxl, 0, 0);
327 break;
328 case RL2_SAMPLE_INT16:
329 rl2_set_pixel_sample_int16 (pxl, 0);
330 break;
331 case RL2_SAMPLE_UINT16:
332 rl2_set_pixel_sample_uint16 (pxl, 0, 0);
333 break;
334 case RL2_SAMPLE_INT32:
335 rl2_set_pixel_sample_int32 (pxl, 0);
336 break;
337 case RL2_SAMPLE_UINT32:
338 rl2_set_pixel_sample_uint32 (pxl, 0);
339 break;
340 case RL2_SAMPLE_FLOAT:
341 rl2_set_pixel_sample_float (pxl, 0.0);
342 break;
343 case RL2_SAMPLE_DOUBLE:
344 rl2_set_pixel_sample_double (pxl, 0.0);
345 break;
346 };
347 break;
348 case RL2_PIXEL_MULTIBAND:
349 switch (sample)
350 {
351 case RL2_SAMPLE_UINT8:
352 for (nb = 0; nb < num_bands; nb++)
353 rl2_set_pixel_sample_uint8 (pxl, nb, 255);
354 break;
355 case RL2_SAMPLE_UINT16:
356 for (nb = 0; nb < num_bands; nb++)
357 rl2_set_pixel_sample_uint16 (pxl, nb, 0);
358 break;
359 };
360 break;
361 };
362 return pxl;
363 }
364
365 RL2_PRIVATE WmsRetryListPtr
alloc_retry_list()366 alloc_retry_list ()
367 {
368 /* initializing an empty WMS retry-list */
369 WmsRetryListPtr lst = malloc (sizeof (WmsRetryList));
370 lst->first = NULL;
371 lst->last = NULL;
372 return lst;
373 }
374
375 RL2_PRIVATE void
free_retry_list(WmsRetryListPtr lst)376 free_retry_list (WmsRetryListPtr lst)
377 {
378 /* memory cleanup - destroying a list of WMS retry requests */
379 WmsRetryItemPtr p;
380 WmsRetryItemPtr pn;
381 if (lst == NULL)
382 return;
383 p = lst->first;
384 while (p != NULL)
385 {
386 pn = p->next;
387 free (p);
388 p = pn;
389 }
390 free (lst);
391 }
392
393 RL2_PRIVATE void
add_retry(WmsRetryListPtr lst,double minx,double miny,double maxx,double maxy)394 add_retry (WmsRetryListPtr lst, double minx, double miny, double maxx,
395 double maxy)
396 {
397 /* inserting a WMS retry request into the list */
398 WmsRetryItemPtr p;
399 if (lst == NULL)
400 return;
401 p = malloc (sizeof (WmsRetryItem));
402 p->done = 0;
403 p->count = 0;
404 p->minx = minx;
405 p->miny = miny;
406 p->maxx = maxx;
407 p->maxy = maxy;
408 p->next = NULL;
409 if (lst->first == NULL)
410 lst->first = p;
411 if (lst->last != NULL)
412 lst->last->next = p;
413 lst->last = p;
414 }
415
416 RL2_PRIVATE gaiaGeomCollPtr
build_extent(int srid,double minx,double miny,double maxx,double maxy)417 build_extent (int srid, double minx, double miny, double maxx, double maxy)
418 {
419 /* building an MBR (Envelope) */
420 gaiaPolygonPtr pg;
421 gaiaRingPtr rng;
422 gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
423 geom->Srid = srid;
424 pg = gaiaAddPolygonToGeomColl (geom, 5, 0);
425 rng = pg->Exterior;
426 gaiaSetPoint (rng->Coords, 0, minx, miny);
427 gaiaSetPoint (rng->Coords, 1, maxx, miny);
428 gaiaSetPoint (rng->Coords, 2, maxx, maxy);
429 gaiaSetPoint (rng->Coords, 3, minx, maxy);
430 gaiaSetPoint (rng->Coords, 4, minx, miny);
431 return geom;
432 }
433
434 RL2_PRIVATE int
do_insert_wms_tile(sqlite3 * handle,unsigned char * blob_odd,int blob_odd_sz,unsigned char * blob_even,int blob_even_sz,sqlite3_int64 section_id,int srid,double res_x,double res_y,unsigned int tile_w,unsigned int tile_h,double miny,double maxx,double tile_minx,double tile_miny,double tile_maxx,double tile_maxy,rl2PalettePtr aux_palette,rl2PixelPtr no_data,sqlite3_stmt * stmt_tils,sqlite3_stmt * stmt_data,rl2RasterStatisticsPtr section_stats)435 do_insert_wms_tile (sqlite3 * handle, unsigned char *blob_odd, int blob_odd_sz,
436 unsigned char *blob_even, int blob_even_sz,
437 sqlite3_int64 section_id, int srid, double res_x,
438 double res_y, unsigned int tile_w, unsigned int tile_h,
439 double miny, double maxx, double tile_minx,
440 double tile_miny, double tile_maxx, double tile_maxy,
441 rl2PalettePtr aux_palette, rl2PixelPtr no_data,
442 sqlite3_stmt * stmt_tils, sqlite3_stmt * stmt_data,
443 rl2RasterStatisticsPtr section_stats)
444 {
445 /* INSERTing the tile */
446 int ret;
447 sqlite3_int64 tile_id;
448 unsigned char *blob;
449 int blob_size;
450 gaiaGeomCollPtr geom;
451 rl2RasterStatisticsPtr stats = NULL;
452
453 stats = rl2_get_raster_statistics
454 (blob_odd, blob_odd_sz, blob_even, blob_even_sz, aux_palette, no_data);
455 if (stats == NULL)
456 goto error;
457 rl2_aggregate_raster_statistics (stats, section_stats);
458 sqlite3_reset (stmt_tils);
459 sqlite3_clear_bindings (stmt_tils);
460 sqlite3_bind_int64 (stmt_tils, 1, section_id);
461 tile_maxx = tile_minx + ((double) tile_w * res_x);
462 if (tile_maxx > maxx)
463 tile_maxx = maxx;
464 tile_miny = tile_maxy - ((double) tile_h * res_y);
465 if (tile_miny < miny)
466 tile_miny = miny;
467 geom = build_extent (srid, tile_minx, tile_miny, tile_maxx, tile_maxy);
468 gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
469 gaiaFreeGeomColl (geom);
470 sqlite3_bind_blob (stmt_tils, 2, blob, blob_size, free);
471 ret = sqlite3_step (stmt_tils);
472 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
473 ;
474 else
475 {
476 fprintf (stderr,
477 "INSERT INTO tiles; sqlite3_step() error: %s\n",
478 sqlite3_errmsg (handle));
479 goto error;
480 }
481 tile_id = sqlite3_last_insert_rowid (handle);
482 /* INSERTing tile data */
483 sqlite3_reset (stmt_data);
484 sqlite3_clear_bindings (stmt_data);
485 sqlite3_bind_int64 (stmt_data, 1, tile_id);
486 sqlite3_bind_blob (stmt_data, 2, blob_odd, blob_odd_sz, free);
487 if (blob_even == NULL)
488 sqlite3_bind_null (stmt_data, 3);
489 else
490 sqlite3_bind_blob (stmt_data, 3, blob_even, blob_even_sz, free);
491 ret = sqlite3_step (stmt_data);
492 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
493 ;
494 else
495 {
496 fprintf (stderr,
497 "INSERT INTO tile_data; sqlite3_step() error: %s\n",
498 sqlite3_errmsg (handle));
499 goto error;
500 }
501 rl2_destroy_raster_statistics (stats);
502 return 1;
503 error:
504 if (stats != NULL)
505 rl2_destroy_raster_statistics (stats);
506 return 0;
507 }
508
509 RL2_PRIVATE int
do_insert_levels(sqlite3 * handle,double base_res_x,double base_res_y,double factor,unsigned char sample_type,sqlite3_stmt * stmt_levl)510 do_insert_levels (sqlite3 * handle, double base_res_x, double base_res_y,
511 double factor, unsigned char sample_type,
512 sqlite3_stmt * stmt_levl)
513 {
514 /* INSERTing the base-levels */
515 int ret;
516 double res_x = base_res_x * factor;
517 double res_y = base_res_y * factor;
518 sqlite3_reset (stmt_levl);
519 sqlite3_clear_bindings (stmt_levl);
520 sqlite3_bind_double (stmt_levl, 1, res_x);
521 sqlite3_bind_double (stmt_levl, 2, res_y);
522 if (sample_type == RL2_SAMPLE_1_BIT || sample_type == RL2_SAMPLE_2_BIT
523 || sample_type == RL2_SAMPLE_4_BIT)
524 {
525 sqlite3_bind_null (stmt_levl, 3);
526 sqlite3_bind_null (stmt_levl, 4);
527 sqlite3_bind_null (stmt_levl, 5);
528 sqlite3_bind_null (stmt_levl, 6);
529 sqlite3_bind_null (stmt_levl, 7);
530 sqlite3_bind_null (stmt_levl, 8);
531 }
532 else
533 {
534 sqlite3_bind_double (stmt_levl, 3, res_x * 2.0);
535 sqlite3_bind_double (stmt_levl, 4, res_y * 2.0);
536 sqlite3_bind_double (stmt_levl, 5, res_x * 4.0);
537 sqlite3_bind_double (stmt_levl, 6, res_y * 4.0);
538 sqlite3_bind_double (stmt_levl, 7, res_x * 8.0);
539 sqlite3_bind_double (stmt_levl, 8, res_y * 8.0);
540 }
541 ret = sqlite3_step (stmt_levl);
542 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
543 ;
544 else
545 {
546 fprintf (stderr,
547 "INSERT INTO levels; sqlite3_step() error: %s\n",
548 sqlite3_errmsg (handle));
549 goto error;
550 }
551 return 1;
552 error:
553 return 0;
554 }
555
556 RL2_PRIVATE int
do_insert_stats(sqlite3 * handle,rl2RasterStatisticsPtr section_stats,sqlite3_int64 section_id,sqlite3_stmt * stmt_upd_sect)557 do_insert_stats (sqlite3 * handle, rl2RasterStatisticsPtr section_stats,
558 sqlite3_int64 section_id, sqlite3_stmt * stmt_upd_sect)
559 {
560 /* updating the Section's Statistics */
561 unsigned char *blob_stats;
562 int blob_stats_sz;
563 int ret;
564
565 sqlite3_reset (stmt_upd_sect);
566 sqlite3_clear_bindings (stmt_upd_sect);
567 rl2_serialize_dbms_raster_statistics (section_stats, &blob_stats,
568 &blob_stats_sz);
569 sqlite3_bind_blob (stmt_upd_sect, 1, blob_stats, blob_stats_sz, free);
570 sqlite3_bind_int64 (stmt_upd_sect, 2, section_id);
571 ret = sqlite3_step (stmt_upd_sect);
572 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
573 ;
574 else
575 {
576 fprintf (stderr,
577 "UPDATE sections; sqlite3_step() error: %s\n",
578 sqlite3_errmsg (handle));
579 goto error;
580 }
581 return 1;
582 error:
583 return 0;
584 }
585
586 RL2_PRIVATE char *
get_section_name(const char * src_path)587 get_section_name (const char *src_path)
588 {
589 /* attempting to extract the section name from source path */
590 int pos1 = 0;
591 int pos2 = 0;
592 int xpos2;
593 int len;
594 char *name;
595 const char *p;
596 if (src_path == NULL)
597 return NULL;
598 pos2 = strlen (src_path) - 1;
599 xpos2 = pos2;
600 pos1 = 0;
601 p = src_path + pos2;
602 while (p >= src_path)
603 {
604 if (*p == '.' && pos2 == xpos2)
605 pos2 = (p - 1) - src_path;
606 if (*p == '/')
607 {
608 pos1 = (p + 1) - src_path;
609 break;
610 }
611 p--;
612 }
613 len = pos2 - pos1 + 1;
614 name = malloc (len + 1);
615 memset (name, '\0', len + 1);
616 memcpy (name, src_path + pos1, len);
617 return name;
618 }
619
620 RL2_PRIVATE int
do_insert_section(sqlite3 * handle,const char * src_path,const char * section,int srid,unsigned int width,unsigned int height,double minx,double miny,double maxx,double maxy,sqlite3_stmt * stmt_sect,sqlite3_int64 * id)621 do_insert_section (sqlite3 * handle, const char *src_path,
622 const char *section, int srid, unsigned int width,
623 unsigned int height, double minx, double miny,
624 double maxx, double maxy, sqlite3_stmt * stmt_sect,
625 sqlite3_int64 * id)
626 {
627 /* INSERTing the section */
628 int ret;
629 unsigned char *blob;
630 int blob_size;
631 gaiaGeomCollPtr geom;
632 sqlite3_int64 section_id;
633
634 sqlite3_reset (stmt_sect);
635 sqlite3_clear_bindings (stmt_sect);
636 if (section != NULL)
637 sqlite3_bind_text (stmt_sect, 1, section, strlen (section),
638 SQLITE_STATIC);
639 else
640 {
641 char *sect_name = get_section_name (src_path);
642 if (sect_name != NULL)
643 sqlite3_bind_text (stmt_sect, 1, sect_name, strlen (sect_name),
644 free);
645 }
646 sqlite3_bind_text (stmt_sect, 2, src_path, strlen (src_path),
647 SQLITE_STATIC);
648 sqlite3_bind_int (stmt_sect, 3, width);
649 sqlite3_bind_int (stmt_sect, 4, height);
650 geom = build_extent (srid, minx, miny, maxx, maxy);
651 gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
652 gaiaFreeGeomColl (geom);
653 sqlite3_bind_blob (stmt_sect, 5, blob, blob_size, free);
654 ret = sqlite3_step (stmt_sect);
655 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
656 section_id = sqlite3_last_insert_rowid (handle);
657 else
658 {
659 fprintf (stderr,
660 "INSERT INTO sections; sqlite3_step() error: %s\n",
661 sqlite3_errmsg (handle));
662 goto error;
663 }
664 *id = section_id;
665 return 1;
666 error:
667 return 0;
668 }
669
670 RL2_PRIVATE rl2RasterPtr
build_wms_tile(rl2CoveragePtr coverage,const unsigned char * rgba_tile)671 build_wms_tile (rl2CoveragePtr coverage, const unsigned char *rgba_tile)
672 {
673 /* building a raster starting from an RGBA buffer */
674 rl2PrivCoveragePtr cvg = (rl2PrivCoveragePtr) coverage;
675 rl2RasterPtr raster = NULL;
676 rl2PalettePtr palette = NULL;
677 unsigned char *pixels = NULL;
678 int pixels_sz = 0;
679 unsigned char *mask = NULL;
680 int mask_size = 0;
681 const unsigned char *p_in;
682 unsigned char *p_out;
683 unsigned char *p_msk;
684 int requires_mask = 0;
685 unsigned int x;
686 unsigned int y;
687
688 if (coverage == NULL || rgba_tile == NULL)
689 return NULL;
690
691 /* supporting only RGB, GRAYSCALE or MONOCHROME coverages */
692 if (cvg->pixelType == RL2_PIXEL_RGB && cvg->nBands == 3)
693 pixels_sz = cvg->tileWidth * cvg->tileHeight * 3;
694 if (cvg->pixelType == RL2_PIXEL_GRAYSCALE && cvg->nBands == 1)
695 pixels_sz = cvg->tileWidth * cvg->tileHeight;
696 if (cvg->pixelType == RL2_PIXEL_MONOCHROME && cvg->nBands == 1)
697 pixels_sz = cvg->tileWidth * cvg->tileHeight;
698 if (pixels_sz <= 0)
699 return NULL;
700 mask_size = cvg->tileWidth * cvg->tileHeight;
701
702 /* allocating the raster and mask buffers */
703 pixels = malloc (pixels_sz);
704 if (pixels == NULL)
705 return NULL;
706 mask = malloc (mask_size);
707 if (mask == NULL)
708 {
709 free (pixels);
710 return NULL;
711 }
712
713 p_msk = mask;
714 for (x = 0; x < (unsigned int) mask_size; x++)
715 {
716 /* priming a full opaque mask */
717 *p_msk++ = 1;
718 }
719
720 /* copying pixels */
721 p_in = rgba_tile;
722 p_out = pixels;
723 p_msk = mask;
724 if (cvg->pixelType == RL2_PIXEL_RGB && cvg->nBands == 3)
725 {
726 for (y = 0; y < cvg->tileHeight; y++)
727 {
728 for (x = 0; x < cvg->tileWidth; x++)
729 {
730 unsigned char red = *p_in++;
731 unsigned char green = *p_in++;
732 unsigned char blue = *p_in++;
733 *p_out++ = red;
734 *p_out++ = green;
735 *p_out++ = blue;
736 }
737 }
738 }
739 if (cvg->pixelType == RL2_PIXEL_GRAYSCALE && cvg->nBands == 1)
740 {
741 for (y = 0; y < cvg->tileHeight; y++)
742 {
743 for (x = 0; x < cvg->tileWidth; x++)
744 {
745 unsigned char red = *p_in++;
746 p_in += 3;
747 *p_out++ = red;
748 }
749 }
750 }
751 if (cvg->pixelType == RL2_PIXEL_MONOCHROME && cvg->nBands == 1)
752 {
753 for (y = 0; y < cvg->tileHeight; y++)
754 {
755 for (x = 0; x < cvg->tileWidth; x++)
756 {
757 unsigned char red = *p_in++;
758 p_in += 3;
759 if (red == 255)
760 *p_out++ = 0;
761 else
762 *p_out++ = 1;
763 }
764 }
765 }
766
767 if (!requires_mask)
768 {
769 /* no mask required */
770 free (mask);
771 mask = NULL;
772 mask_size = 0;
773 }
774
775 raster =
776 rl2_create_raster (cvg->tileWidth, cvg->tileHeight,
777 cvg->sampleType, cvg->pixelType,
778 cvg->nBands, pixels, pixels_sz, NULL, mask,
779 mask_size, NULL);
780 if (raster == NULL)
781 goto error;
782 return raster;
783
784 error:
785 if (palette != NULL)
786 rl2_destroy_palette (palette);
787 if (pixels != NULL)
788 free (pixels);
789 if (mask != NULL)
790 free (mask);
791 return NULL;
792 }
793
794 RL2_PRIVATE int
insert_wms_tile(InsertWmsPtr ptr,int * first,rl2RasterStatisticsPtr * section_stats,sqlite3_int64 * section_id)795 insert_wms_tile (InsertWmsPtr ptr, int *first,
796 rl2RasterStatisticsPtr * section_stats,
797 sqlite3_int64 * section_id)
798 {
799 double tile_minx;
800 double tile_miny;
801 double tile_maxx;
802 double tile_maxy;
803 unsigned char *blob_odd;
804 int blob_odd_sz;
805 unsigned char *blob_even;
806 int blob_even_sz;
807 rl2RasterPtr raster = NULL;
808 double base_res_x;
809 double base_res_y;
810
811 if (rl2_get_coverage_resolution (ptr->coverage, &base_res_x, &base_res_y) !=
812 RL2_OK)
813 goto error;
814 if (*first)
815 {
816 /* INSERTing the section */
817 *first = 0;
818 if (!do_insert_section
819 (ptr->sqlite, "WMS Service", ptr->sect_name, ptr->srid,
820 ptr->width, ptr->height, ptr->minx, ptr->miny, ptr->maxx,
821 ptr->maxy, ptr->stmt_sect, section_id))
822 goto error;
823 *section_stats =
824 rl2_create_raster_statistics (ptr->sample_type, ptr->num_bands);
825 if (*section_stats == NULL)
826 goto error;
827 /* INSERTing the base-levels */
828 if (!do_insert_levels
829 (ptr->sqlite, base_res_x, base_res_y, 1.0, RL2_SAMPLE_UNKNOWN,
830 ptr->stmt_levl))
831 goto error;
832 }
833
834 /* building the raster tile */
835 raster = build_wms_tile (ptr->coverage, ptr->rgba_tile);
836 if (raster == NULL)
837 {
838 fprintf (stderr, "ERROR: unable to get a WMS tile\n");
839 goto error;
840 }
841 if (rl2_raster_encode
842 (raster, ptr->compression, &blob_odd, &blob_odd_sz, &blob_even,
843 &blob_even_sz, 100, 1) != RL2_OK)
844 {
845 fprintf (stderr, "ERROR: unable to encode a WMS tile\n");
846 goto error;
847 }
848
849 /* INSERTing the tile */
850 tile_minx = ptr->x;
851 tile_maxx = tile_minx + ptr->tilew;
852 tile_maxy = ptr->y;
853 tile_miny = tile_maxy - ptr->tileh;
854 if (!do_insert_wms_tile
855 (ptr->sqlite, blob_odd, blob_odd_sz, blob_even, blob_even_sz,
856 *section_id, ptr->srid, ptr->horz_res, ptr->vert_res, ptr->tile_width,
857 ptr->tile_height, ptr->minx, ptr->maxy, tile_minx, tile_miny,
858 tile_maxx, tile_maxy, NULL, ptr->no_data, ptr->stmt_tils,
859 ptr->stmt_data, *section_stats))
860 goto error;
861 blob_odd = NULL;
862 blob_even = NULL;
863 rl2_destroy_raster (raster);
864 free (ptr->rgba_tile);
865 ptr->rgba_tile = NULL;
866 return 1;
867 error:
868 if (raster != NULL)
869 rl2_destroy_raster (raster);
870 if (blob_odd != NULL)
871 free (blob_odd);
872 if (blob_even != NULL)
873 free (blob_even);
874 free (ptr->rgba_tile);
875 ptr->rgba_tile = NULL;
876 return 0;
877 }
878
879 RL2_PRIVATE int
is_point(gaiaGeomCollPtr geom)880 is_point (gaiaGeomCollPtr geom)
881 {
882 /* checking if the Geom is a simple Point */
883 int pts = 0;
884 int lns = 0;
885 int pgs = 0;
886 gaiaPointPtr pt;
887 gaiaLinestringPtr ln;
888 gaiaPolygonPtr pg;
889 pt = geom->FirstPoint;
890 while (pt != NULL)
891 {
892 pts++;
893 pt = pt->Next;
894 }
895 ln = geom->FirstLinestring;
896 while (ln != NULL)
897 {
898 lns++;
899 ln = ln->Next;
900 }
901 pg = geom->FirstPolygon;
902 while (pg != NULL)
903 {
904 pgs++;
905 pg = pg->Next;
906 }
907 if (pts == 1 && lns == 0 && pgs == 0)
908 return 1;
909 return 0;
910 }
911
912 RL2_PRIVATE ResolutionsListPtr
alloc_resolutions_list()913 alloc_resolutions_list ()
914 {
915 /* allocating an empty list */
916 ResolutionsListPtr list = malloc (sizeof (ResolutionsList));
917 if (list == NULL)
918 return NULL;
919 list->first = NULL;
920 list->last = NULL;
921 return list;
922 }
923
924 RL2_PRIVATE void
destroy_resolutions_list(ResolutionsListPtr list)925 destroy_resolutions_list (ResolutionsListPtr list)
926 {
927 /* memory cleanup - destroying a list */
928 ResolutionLevelPtr res;
929 ResolutionLevelPtr resn;
930 if (list == NULL)
931 return;
932 res = list->first;
933 while (res != NULL)
934 {
935 resn = res->next;
936 free (res);
937 res = resn;
938 }
939 free (list);
940 }
941
942 RL2_PRIVATE void
add_base_resolution(ResolutionsListPtr list,int level,int scale,double x_res,double y_res)943 add_base_resolution (ResolutionsListPtr list, int level, int scale,
944 double x_res, double y_res)
945 {
946 /* inserting a base resolution into the list */
947 ResolutionLevelPtr res;
948 if (list == NULL)
949 return;
950
951 res = list->first;
952 while (res != NULL)
953 {
954 if (res->x_resolution == x_res && res->y_resolution == y_res)
955 {
956 /* already defined: skipping */
957 return;
958 }
959 res = res->next;
960 }
961
962 /* inserting */
963 res = malloc (sizeof (ResolutionLevel));
964 res->level = level;
965 res->scale = scale;
966 res->x_resolution = x_res;
967 res->y_resolution = y_res;
968 res->prev = list->last;
969 res->next = NULL;
970 if (list->first == NULL)
971 list->first = res;
972 if (list->last != NULL)
973 list->last->next = res;
974 list->last = res;
975 }
976
977 RL2_PRIVATE int
find_best_resolution_level(sqlite3 * handle,const char * coverage,double x_res,double y_res,int * level_id,int * scale,int * real_scale,double * xx_res,double * yy_res)978 find_best_resolution_level (sqlite3 * handle, const char *coverage,
979 double x_res, double y_res, int *level_id,
980 int *scale, int *real_scale, double *xx_res,
981 double *yy_res)
982 {
983 /* attempting to identify the optimal resolution level */
984 int ret;
985 int found = 0;
986 int z_level;
987 int z_scale;
988 int z_real;
989 double z_x_res;
990 double z_y_res;
991 char *xcoverage;
992 char *xxcoverage;
993 char *sql;
994 sqlite3_stmt *stmt = NULL;
995 ResolutionsListPtr list = NULL;
996 ResolutionLevelPtr res;
997
998 if (coverage == NULL)
999 return 0;
1000
1001 xcoverage = sqlite3_mprintf ("%s_levels", coverage);
1002 xxcoverage = gaiaDoubleQuotedSql (xcoverage);
1003 sqlite3_free (xcoverage);
1004 sql =
1005 sqlite3_mprintf
1006 ("SELECT pyramid_level, x_resolution_1_8, y_resolution_1_8, "
1007 "x_resolution_1_4, y_resolution_1_4, x_resolution_1_2, y_resolution_1_2, "
1008 "x_resolution_1_1, y_resolution_1_1 FROM \"%s\" "
1009 "ORDER BY pyramid_level DESC", xxcoverage);
1010 free (xxcoverage);
1011 ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
1012 if (ret != SQLITE_OK)
1013 {
1014 fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
1015 goto error;
1016 }
1017 sqlite3_free (sql);
1018
1019 list = alloc_resolutions_list ();
1020 if (list == NULL)
1021 goto error;
1022
1023 while (1)
1024 {
1025 /* scrolling the result set rows */
1026 ret = sqlite3_step (stmt);
1027 if (ret == SQLITE_DONE)
1028 break; /* end of result set */
1029 if (ret == SQLITE_ROW)
1030 {
1031 int lvl = sqlite3_column_int (stmt, 0);
1032 if (sqlite3_column_type (stmt, 1) == SQLITE_FLOAT
1033 && sqlite3_column_type (stmt, 2) == SQLITE_FLOAT)
1034 {
1035 z_x_res = sqlite3_column_double (stmt, 1);
1036 z_y_res = sqlite3_column_double (stmt, 2);
1037 add_base_resolution (list, lvl, RL2_SCALE_8, z_x_res,
1038 z_y_res);
1039 }
1040 if (sqlite3_column_type (stmt, 3) == SQLITE_FLOAT
1041 && sqlite3_column_type (stmt, 4) == SQLITE_FLOAT)
1042 {
1043 z_x_res = sqlite3_column_double (stmt, 3);
1044 z_y_res = sqlite3_column_double (stmt, 4);
1045 add_base_resolution (list, lvl, RL2_SCALE_4, z_x_res,
1046 z_y_res);
1047 }
1048 if (sqlite3_column_type (stmt, 5) == SQLITE_FLOAT
1049 && sqlite3_column_type (stmt, 6) == SQLITE_FLOAT)
1050 {
1051 z_x_res = sqlite3_column_double (stmt, 5);
1052 z_y_res = sqlite3_column_double (stmt, 6);
1053 add_base_resolution (list, lvl, RL2_SCALE_2, z_x_res,
1054 z_y_res);
1055 }
1056 if (sqlite3_column_type (stmt, 7) == SQLITE_FLOAT
1057 && sqlite3_column_type (stmt, 8) == SQLITE_FLOAT)
1058 {
1059 z_x_res = sqlite3_column_double (stmt, 7);
1060 z_y_res = sqlite3_column_double (stmt, 8);
1061 add_base_resolution (list, lvl, RL2_SCALE_1, z_x_res,
1062 z_y_res);
1063 }
1064 }
1065 else
1066 {
1067 fprintf (stderr, "SQL error: %s\n%s\n", sql,
1068 sqlite3_errmsg (handle));
1069 goto error;
1070 }
1071 }
1072 sqlite3_finalize (stmt);
1073
1074 /* adjusting real scale factors */
1075 z_real = 1;
1076 res = list->last;
1077 while (res != NULL)
1078 {
1079 res->real_scale = z_real;
1080 z_real *= 2;
1081 res = res->prev;
1082 }
1083 /* retrieving the best resolution level */
1084 found = 0;
1085 res = list->last;
1086 while (res != NULL)
1087 {
1088 if (res->x_resolution <= x_res && res->y_resolution <= y_res)
1089 {
1090 found = 1;
1091 z_level = res->level;
1092 z_scale = res->scale;
1093 z_real = res->real_scale;
1094 z_x_res = res->x_resolution;
1095 z_y_res = res->y_resolution;
1096 }
1097 res = res->prev;
1098 }
1099 if (found)
1100 {
1101 *level_id = z_level;
1102 *scale = z_scale;
1103 *real_scale = z_real;
1104 *xx_res = z_x_res;
1105 *yy_res = z_y_res;
1106 }
1107 else if (list->last != NULL)
1108 {
1109 res = list->last;
1110 *level_id = res->level;
1111 *scale = res->scale;
1112 *xx_res = res->x_resolution;
1113 *yy_res = res->y_resolution;
1114 }
1115 else
1116 goto error;
1117 destroy_resolutions_list (list);
1118 return 1;
1119
1120 error:
1121 if (stmt != NULL)
1122 sqlite3_finalize (stmt);
1123 if (list != NULL)
1124 destroy_resolutions_list (list);
1125 return 0;
1126 }
1127
1128 RL2_PRIVATE unsigned char
get_palette_format(rl2PrivPalettePtr plt)1129 get_palette_format (rl2PrivPalettePtr plt)
1130 {
1131 /* testing for a Grayscale or RGB palette */
1132 int is_gray = 0;
1133 int i;
1134 for (i = 0; i < plt->nEntries; i++)
1135 {
1136 rl2PrivPaletteEntryPtr entry = plt->entries + i;
1137 if (entry->red == entry->green && entry->red == entry->blue)
1138 is_gray++;
1139 }
1140 if (is_gray == plt->nEntries)
1141 return RL2_PIXEL_GRAYSCALE;
1142 else
1143 return RL2_PIXEL_RGB;
1144 }
1145
1146 static unsigned char *
gray_to_rgba(unsigned short width,unsigned short height,unsigned char * gray)1147 gray_to_rgba (unsigned short width, unsigned short height, unsigned char *gray)
1148 {
1149 /* transforming an RGB buffer to RGBA */
1150 unsigned char *rgba = NULL;
1151 unsigned char *p_out;
1152 const unsigned char *p_in;
1153 int x;
1154 int y;
1155
1156 rgba = malloc (width * height * 4);
1157 if (rgba == NULL)
1158 return NULL;
1159 p_in = gray;
1160 p_out = rgba;
1161 for (y = 0; y < height; y++)
1162 {
1163 for (x = 0; x < width; x++)
1164 {
1165 unsigned char x = *p_in++;
1166 *p_out++ = x; /* red */
1167 *p_out++ = x; /* green */
1168 *p_out++ = x; /* blue */
1169 *p_out++ = 255; /* alpha */
1170 }
1171 }
1172 return rgba;
1173 }
1174
1175 static unsigned char *
rgb_to_rgba(unsigned int width,unsigned int height,unsigned char * rgb)1176 rgb_to_rgba (unsigned int width, unsigned int height, unsigned char *rgb)
1177 {
1178 /* transforming an RGB buffer to RGBA */
1179 unsigned char *rgba = NULL;
1180 unsigned char *p_out;
1181 const unsigned char *p_in;
1182 unsigned int x;
1183 unsigned int y;
1184
1185 rgba = malloc (width * height * 4);
1186 if (rgba == NULL)
1187 return NULL;
1188 p_in = rgb;
1189 p_out = rgba;
1190 for (y = 0; y < height; y++)
1191 {
1192 for (x = 0; x < width; x++)
1193 {
1194 *p_out++ = *p_in++; /* red */
1195 *p_out++ = *p_in++; /* green */
1196 *p_out++ = *p_in++; /* blue */
1197 *p_out++ = 255; /* alpha */
1198 }
1199 }
1200 return rgba;
1201 }
1202
1203 RL2_PRIVATE int
get_payload_from_monochrome_opaque(unsigned int width,unsigned int height,sqlite3 * handle,double minx,double miny,double maxx,double maxy,int srid,unsigned char * pixels,unsigned char format,int quality,unsigned char ** image,int * image_sz)1204 get_payload_from_monochrome_opaque (unsigned int width, unsigned int height,
1205 sqlite3 * handle, double minx, double miny,
1206 double maxx, double maxy, int srid,
1207 unsigned char *pixels, unsigned char format,
1208 int quality, unsigned char **image,
1209 int *image_sz)
1210 {
1211 /* input: Monochrome output: Grayscale */
1212 int ret;
1213 unsigned char *p_in;
1214 unsigned char *p_out;
1215 unsigned char *gray = NULL;
1216 unsigned int row;
1217 unsigned int col;
1218 unsigned char *rgba = NULL;
1219
1220 gray = malloc (width * height);
1221 if (gray == NULL)
1222 goto error;
1223 p_in = pixels;
1224 p_out = gray;
1225 for (row = 0; row < height; row++)
1226 {
1227 for (col = 0; col < width; col++)
1228 {
1229 if (*p_in++ == 1)
1230 *p_out++ = 0; /* Black */
1231 else
1232 *p_out++ = 255; /* White */
1233 }
1234 }
1235 free (pixels);
1236 pixels = NULL;
1237 if (format == RL2_OUTPUT_FORMAT_JPEG)
1238 {
1239 if (rl2_gray_to_jpeg (width, height, gray, quality, image, image_sz)
1240 != RL2_OK)
1241 goto error;
1242 }
1243 else if (format == RL2_OUTPUT_FORMAT_PNG)
1244 {
1245 if (rl2_gray_to_png (width, height, gray, image, image_sz) != RL2_OK)
1246 goto error;
1247 }
1248 else if (format == RL2_OUTPUT_FORMAT_TIFF)
1249 {
1250 if (srid > 0)
1251 {
1252 if (rl2_gray_to_geotiff
1253 (width, height, handle, minx, miny, maxx, maxy, srid, gray,
1254 image, image_sz) != RL2_OK)
1255 goto error;
1256 }
1257 else
1258 {
1259 if (rl2_gray_to_tiff (width, height, gray, image, image_sz) !=
1260 RL2_OK)
1261 goto error;
1262 }
1263 }
1264 else if (format == RL2_OUTPUT_FORMAT_PDF)
1265 {
1266 rgba = gray_to_rgba (width, height, gray);
1267 if (rgba == NULL)
1268 goto error;
1269 ret = rl2_rgba_to_pdf (width, height, rgba, image, image_sz);
1270 rgba = NULL;
1271 if (ret != RL2_OK)
1272 goto error;
1273 }
1274 else
1275 goto error;
1276 free (gray);
1277 return 1;
1278
1279 error:
1280 if (pixels != NULL)
1281 free (pixels);
1282 if (gray != NULL)
1283 free (gray);
1284 if (rgba != NULL)
1285 free (rgba);
1286 return 0;
1287 }
1288
1289 RL2_PRIVATE int
get_payload_from_monochrome_transparent(unsigned int width,unsigned int height,unsigned char * pixels,unsigned char format,int quality,unsigned char ** image,int * image_sz,double opacity)1290 get_payload_from_monochrome_transparent (unsigned int width,
1291 unsigned int height,
1292 unsigned char *pixels,
1293 unsigned char format, int quality,
1294 unsigned char **image, int *image_sz,
1295 double opacity)
1296 {
1297 /* input: Monochrome output: Grayscale */
1298 unsigned char *p_in;
1299 unsigned char *p_out;
1300 unsigned char *p_msk;
1301 unsigned char *gray = NULL;
1302 unsigned char *mask = NULL;
1303 unsigned int row;
1304 unsigned int col;
1305
1306 if (quality > 100)
1307 quality = 100;
1308 gray = malloc (width * height);
1309 if (gray == NULL)
1310 goto error;
1311 mask = malloc (width * height);
1312 if (mask == NULL)
1313 goto error;
1314 p_in = pixels;
1315 p_out = gray;
1316 p_msk = mask;
1317 for (row = 0; row < height; row++)
1318 {
1319 for (col = 0; col < width; col++)
1320 {
1321 if (*p_in++ == 1)
1322 {
1323 *p_out++ = 0; /* Black */
1324 *p_msk++ = 1; /* Opaque */
1325 }
1326 else
1327 {
1328 *p_out++ = 1; /* White */
1329 *p_msk++ = 0; /* Transparent */
1330 }
1331 }
1332 }
1333 free (pixels);
1334 pixels = NULL;
1335 if (format == RL2_OUTPUT_FORMAT_PNG)
1336 {
1337 if (rl2_gray_alpha_to_png
1338 (width, height, gray, mask, image, image_sz, opacity) != RL2_OK)
1339 goto error;
1340 }
1341 else
1342 goto error;
1343 free (gray);
1344 free (mask);
1345 return 1;
1346
1347 error:
1348 if (pixels != NULL)
1349 free (pixels);
1350 if (gray != NULL)
1351 free (gray);
1352 if (mask != NULL)
1353 free (mask);
1354 return 0;
1355 }
1356
1357 RL2_PRIVATE int
get_payload_from_palette_opaque(unsigned int width,unsigned int height,sqlite3 * handle,double minx,double miny,double maxx,double maxy,int srid,unsigned char * pixels,rl2PalettePtr palette,unsigned char format,int quality,unsigned char ** image,int * image_sz)1358 get_payload_from_palette_opaque (unsigned int width, unsigned int height,
1359 sqlite3 * handle, double minx, double miny,
1360 double maxx, double maxy, int srid,
1361 unsigned char *pixels, rl2PalettePtr palette,
1362 unsigned char format, int quality,
1363 unsigned char **image, int *image_sz)
1364 {
1365 /* input: Palette output: Grayscale or RGB */
1366 int ret;
1367 rl2PrivPalettePtr plt = (rl2PrivPalettePtr) palette;
1368 unsigned char *p_in;
1369 unsigned char *p_out;
1370 unsigned char *gray = NULL;
1371 unsigned char *rgb = NULL;
1372 unsigned int row;
1373 unsigned int col;
1374 unsigned char out_format;
1375 unsigned char *rgba = NULL;
1376
1377 out_format = get_palette_format (plt);
1378 if (out_format == RL2_PIXEL_RGB)
1379 {
1380 /* converting from Palette to RGB */
1381 rgb = malloc (width * height * 3);
1382 p_in = pixels;
1383 p_out = rgb;
1384 for (row = 0; row < height; row++)
1385 {
1386 for (col = 0; col < width; col++)
1387 {
1388 unsigned char red = 0;
1389 unsigned char green = 0;
1390 unsigned char blue = 0;
1391 unsigned char index = *p_in++;
1392 if (index < plt->nEntries)
1393 {
1394 rl2PrivPaletteEntryPtr entry = plt->entries + index;
1395 red = entry->red;
1396 green = entry->green;
1397 blue = entry->blue;
1398 }
1399 *p_out++ = red; /* red */
1400 *p_out++ = green; /* green */
1401 *p_out++ = blue; /* blue */
1402 }
1403 }
1404 free (pixels);
1405 if (format == RL2_OUTPUT_FORMAT_JPEG)
1406 {
1407 if (rl2_rgb_to_jpeg
1408 (width, height, rgb, quality, image, image_sz) != RL2_OK)
1409 goto error;
1410 }
1411 else if (format == RL2_OUTPUT_FORMAT_PNG)
1412 {
1413 if (rl2_rgb_to_png (width, height, rgb, image, image_sz) !=
1414 RL2_OK)
1415 goto error;
1416 }
1417 else if (format == RL2_OUTPUT_FORMAT_TIFF)
1418 {
1419 if (srid > 0)
1420 {
1421 if (rl2_rgb_to_geotiff
1422 (width, height, handle, minx, miny, maxx, maxy, srid,
1423 rgb, image, image_sz) != RL2_OK)
1424 goto error;
1425 }
1426 else
1427 {
1428 if (rl2_rgb_to_tiff (width, height, rgb, image, image_sz)
1429 != RL2_OK)
1430 goto error;
1431 }
1432 }
1433 else if (format == RL2_OUTPUT_FORMAT_PDF)
1434 {
1435 rgba = rgb_to_rgba (width, height, rgb);
1436 if (rgba == NULL)
1437 goto error;
1438 ret = rl2_rgba_to_pdf (width, height, rgba, image, image_sz);
1439 rgba = NULL;
1440 if (ret != RL2_OK)
1441 goto error;
1442 }
1443 else
1444 goto error;
1445 free (rgb);
1446 }
1447 else if (out_format == RL2_PIXEL_GRAYSCALE)
1448 {
1449 /* converting from Palette to Grayscale */
1450 gray = malloc (width * height);
1451 p_in = pixels;
1452 p_out = gray;
1453 for (row = 0; row < height; row++)
1454 {
1455 for (col = 0; col < width; col++)
1456 {
1457 unsigned char value = 0;
1458 unsigned char index = *p_in++;
1459 if (index < plt->nEntries)
1460 {
1461 rl2PrivPaletteEntryPtr entry = plt->entries + index;
1462 value = entry->red;
1463 }
1464 *p_out++ = value; /* gray */
1465 }
1466 }
1467 free (pixels);
1468 if (format == RL2_OUTPUT_FORMAT_JPEG)
1469 {
1470 if (rl2_gray_to_jpeg
1471 (width, height, gray, quality, image, image_sz) != RL2_OK)
1472 goto error;
1473 }
1474 else if (format == RL2_OUTPUT_FORMAT_PNG)
1475 {
1476 if (rl2_gray_to_png (width, height, gray, image, image_sz) !=
1477 RL2_OK)
1478 goto error;
1479 }
1480 else if (format == RL2_OUTPUT_FORMAT_TIFF)
1481 {
1482 if (srid > 0)
1483 {
1484 if (rl2_gray_to_geotiff
1485 (width, height, handle, minx, miny, maxx, maxy, srid,
1486 gray, image, image_sz) != RL2_OK)
1487 goto error;
1488 }
1489 else
1490 {
1491 if (rl2_gray_to_tiff
1492 (width, height, gray, image, image_sz) != RL2_OK)
1493 goto error;
1494 }
1495 }
1496 else if (format == RL2_OUTPUT_FORMAT_PDF)
1497 {
1498 rgba = gray_to_rgba (width, height, gray);
1499 if (rgba == NULL)
1500 goto error;
1501 ret = rl2_rgba_to_pdf (width, height, rgba, image, image_sz);
1502 rgba = NULL;
1503 if (ret != RL2_OK)
1504 goto error;
1505 }
1506 else
1507 goto error;
1508 free (gray);
1509 }
1510 else
1511 goto error;
1512 return 1;
1513
1514 error:
1515 if (pixels != NULL)
1516 free (pixels);
1517 if (gray != NULL)
1518 free (gray);
1519 if (rgb != NULL)
1520 free (rgb);
1521 if (rgba != NULL)
1522 free (rgba);
1523 return 0;
1524 }
1525
1526 RL2_PRIVATE int
get_payload_from_palette_transparent(unsigned int width,unsigned int height,unsigned char * pixels,rl2PalettePtr palette,unsigned char format,int quality,unsigned char ** image,int * image_sz,unsigned char bg_red,unsigned char bg_green,unsigned char bg_blue,double opacity)1527 get_payload_from_palette_transparent (unsigned int width,
1528 unsigned int height,
1529 unsigned char *pixels,
1530 rl2PalettePtr palette,
1531 unsigned char format, int quality,
1532 unsigned char **image, int *image_sz,
1533 unsigned char bg_red,
1534 unsigned char bg_green,
1535 unsigned char bg_blue, double opacity)
1536 {
1537 /* input: Palette output: Grayscale or RGB */
1538 rl2PrivPalettePtr plt = (rl2PrivPalettePtr) palette;
1539 unsigned char *p_in;
1540 unsigned char *p_out;
1541 unsigned char *p_msk;
1542 unsigned char *gray = NULL;
1543 unsigned char *rgb = NULL;
1544 unsigned char *mask = NULL;
1545 unsigned int row;
1546 unsigned int col;
1547 unsigned char out_format;
1548
1549 if (quality > 100)
1550 quality = 100;
1551 out_format = get_palette_format (plt);
1552 if (out_format == RL2_PIXEL_RGB)
1553 {
1554 /* converting from Palette to RGB */
1555 rgb = malloc (width * height * 3);
1556 if (rgb == NULL)
1557 goto error;
1558 mask = malloc (width * height);
1559 if (mask == NULL)
1560 goto error;
1561 p_in = pixels;
1562 p_out = rgb;
1563 p_msk = mask;
1564 for (row = 0; row < height; row++)
1565 {
1566 for (col = 0; col < width; col++)
1567 {
1568 unsigned char red = 0;
1569 unsigned char green = 0;
1570 unsigned char blue = 0;
1571 unsigned char index = *p_in++;
1572 if (index < plt->nEntries)
1573 {
1574 rl2PrivPaletteEntryPtr entry = plt->entries + index;
1575 red = entry->red;
1576 green = entry->green;
1577 blue = entry->blue;
1578 }
1579 *p_out++ = red; /* red */
1580 *p_out++ = green; /* green */
1581 *p_out++ = blue; /* blue */
1582 if (red == bg_red && green == bg_green && blue == bg_blue)
1583 *p_msk++ = 0; /* Transparent */
1584 else
1585 *p_msk++ = 1; /* Opaque */
1586 }
1587 }
1588 free (pixels);
1589 if (format == RL2_OUTPUT_FORMAT_PNG)
1590 {
1591 if (rl2_rgb_to_png (width, height, rgb, image, image_sz) !=
1592 RL2_OK)
1593 goto error;
1594 }
1595 else
1596 goto error;
1597 free (rgb);
1598 free (mask);
1599 }
1600 else if (out_format == RL2_PIXEL_GRAYSCALE)
1601 {
1602 /* converting from Palette to Grayscale */
1603 gray = malloc (width * height);
1604 if (gray == NULL)
1605 goto error;
1606 mask = malloc (width * height);
1607 if (mask == NULL)
1608 goto error;
1609 p_in = pixels;
1610 p_out = gray;
1611 p_msk = mask;
1612 for (row = 0; row < height; row++)
1613 {
1614 for (col = 0; col < width; col++)
1615 {
1616 unsigned char value = 0;
1617 unsigned char index = *p_in++;
1618 if (index < plt->nEntries)
1619 {
1620 rl2PrivPaletteEntryPtr entry = plt->entries + index;
1621 value = entry->red;
1622 }
1623 *p_out++ = value; /* gray */
1624 if (value == bg_red)
1625 *p_msk++ = 0; /* Transparent */
1626 else
1627 *p_msk++ = 1; /* Opaque */
1628 }
1629 }
1630 free (pixels);
1631 if (format == RL2_OUTPUT_FORMAT_PNG)
1632 {
1633 if (rl2_gray_alpha_to_png
1634 (width, height, gray, mask, image, image_sz,
1635 opacity) != RL2_OK)
1636 goto error;
1637 }
1638 else
1639 goto error;
1640 free (gray);
1641 free (mask);
1642 }
1643 else
1644 goto error;
1645 return 1;
1646
1647 error:
1648 if (pixels != NULL)
1649 free (pixels);
1650 if (gray != NULL)
1651 free (gray);
1652 if (rgb != NULL)
1653 free (rgb);
1654 if (mask != NULL)
1655 free (mask);
1656 return 0;
1657 }
1658
1659 RL2_PRIVATE int
get_payload_from_grayscale_opaque(unsigned int width,unsigned int height,sqlite3 * handle,double minx,double miny,double maxx,double maxy,int srid,unsigned char * pixels,unsigned char format,int quality,unsigned char ** image,int * image_sz)1660 get_payload_from_grayscale_opaque (unsigned int width, unsigned int height,
1661 sqlite3 * handle, double minx, double miny,
1662 double maxx, double maxy, int srid,
1663 unsigned char *pixels, unsigned char format,
1664 int quality, unsigned char **image,
1665 int *image_sz)
1666 {
1667 /* input: Grayscale output: Grayscale */
1668 int ret;
1669 unsigned char *rgba = NULL;
1670
1671 if (format == RL2_OUTPUT_FORMAT_JPEG)
1672 {
1673 if (rl2_gray_to_jpeg (width, height, pixels, quality, image, image_sz)
1674 != RL2_OK)
1675 goto error;
1676 }
1677 else if (format == RL2_OUTPUT_FORMAT_PNG)
1678 {
1679 if (rl2_gray_to_png (width, height, pixels, image, image_sz) !=
1680 RL2_OK)
1681 goto error;
1682 }
1683 else if (format == RL2_OUTPUT_FORMAT_TIFF)
1684 {
1685 if (srid > 0)
1686 {
1687 if (rl2_gray_to_geotiff
1688 (width, height, handle, minx, miny, maxx, maxy, srid,
1689 pixels, image, image_sz) != RL2_OK)
1690 goto error;
1691 }
1692 else
1693 {
1694 if (rl2_gray_to_tiff (width, height, pixels, image, image_sz) !=
1695 RL2_OK)
1696 goto error;
1697 }
1698 }
1699 else if (format == RL2_OUTPUT_FORMAT_PDF)
1700 {
1701 rgba = gray_to_rgba (width, height, pixels);
1702 if (rgba == NULL)
1703 goto error;
1704 ret = rl2_rgba_to_pdf (width, height, rgba, image, image_sz);
1705 rgba = NULL;
1706 if (ret != RL2_OK)
1707 goto error;
1708 }
1709 else
1710 goto error;
1711 free (pixels);
1712 if (rgba != NULL)
1713 free (rgba);
1714 return 1;
1715
1716 error:
1717 free (pixels);
1718 return 0;
1719 }
1720
1721 RL2_PRIVATE int
get_payload_from_grayscale_transparent(unsigned int width,unsigned int height,unsigned char * pixels,unsigned char format,int quality,unsigned char ** image,int * image_sz,unsigned char bg_gray,double opacity)1722 get_payload_from_grayscale_transparent (unsigned int width,
1723 unsigned int height,
1724 unsigned char *pixels,
1725 unsigned char format, int quality,
1726 unsigned char **image, int *image_sz,
1727 unsigned char bg_gray, double opacity)
1728 {
1729 /* input: Grayscale output: Grayscale */
1730 unsigned char *p_in;
1731 unsigned char *p_msk;
1732 unsigned char *mask = NULL;
1733 unsigned short row;
1734 unsigned short col;
1735
1736 if (quality > 100)
1737 quality = 100;
1738 mask = malloc (width * height);
1739 if (mask == NULL)
1740 goto error;
1741 p_in = pixels;
1742 p_msk = mask;
1743 for (row = 0; row < height; row++)
1744 {
1745 for (col = 0; col < width; col++)
1746 {
1747 if (*p_in++ == bg_gray)
1748 *p_msk++ = 0; /* Transparent */
1749 else
1750 *p_msk++ = 255; /* Opaque */
1751 }
1752 }
1753 if (format == RL2_OUTPUT_FORMAT_PNG)
1754 {
1755 if (rl2_gray_alpha_to_png
1756 (width, height, pixels, mask, image, image_sz, opacity) != RL2_OK)
1757 goto error;
1758 }
1759 else
1760 goto error;
1761 free (pixels);
1762 free (mask);
1763 return 1;
1764
1765 error:
1766 free (pixels);
1767 if (mask != NULL)
1768 free (mask);
1769 return 0;
1770 }
1771
1772 RL2_PRIVATE int
get_payload_from_rgb_opaque(unsigned int width,unsigned int height,sqlite3 * handle,double minx,double miny,double maxx,double maxy,int srid,unsigned char * pixels,unsigned char format,int quality,unsigned char ** image,int * image_sz)1773 get_payload_from_rgb_opaque (unsigned int width, unsigned int height,
1774 sqlite3 * handle, double minx, double miny,
1775 double maxx, double maxy, int srid,
1776 unsigned char *pixels, unsigned char format,
1777 int quality, unsigned char **image, int *image_sz)
1778 {
1779 /* input: RGB output: RGB */
1780 int ret;
1781 unsigned char *rgba = NULL;
1782
1783 if (format == RL2_OUTPUT_FORMAT_JPEG)
1784 {
1785 if (rl2_rgb_to_jpeg (width, height, pixels, quality, image, image_sz)
1786 != RL2_OK)
1787 goto error;
1788 }
1789 else if (format == RL2_OUTPUT_FORMAT_PNG)
1790 {
1791 if (rl2_rgb_to_png (width, height, pixels, image, image_sz) != RL2_OK)
1792 goto error;
1793 }
1794 else if (format == RL2_OUTPUT_FORMAT_TIFF)
1795 {
1796 if (srid > 0)
1797 {
1798 if (rl2_rgb_to_geotiff
1799 (width, height, handle, minx, miny, maxx, maxy, srid,
1800 pixels, image, image_sz) != RL2_OK)
1801 goto error;
1802 }
1803 else
1804 {
1805 if (rl2_rgb_to_tiff (width, height, pixels, image, image_sz) !=
1806 RL2_OK)
1807 goto error;
1808 }
1809 }
1810 else if (format == RL2_OUTPUT_FORMAT_PDF)
1811 {
1812 rgba = rgb_to_rgba (width, height, pixels);
1813 if (rgba == NULL)
1814 goto error;
1815 ret = rl2_rgba_to_pdf (width, height, rgba, image, image_sz);
1816 rgba = NULL;
1817 if (ret != RL2_OK)
1818 goto error;
1819 }
1820 else
1821 goto error;
1822 free (pixels);
1823 return 1;
1824
1825 error:
1826 free (pixels);
1827 if (rgba != NULL)
1828 free (rgba);
1829 return 0;
1830 }
1831
1832 RL2_PRIVATE int
get_payload_from_rgb_transparent(unsigned int width,unsigned int height,unsigned char * pixels,unsigned char format,int quality,unsigned char ** image,int * image_sz,unsigned char bg_red,unsigned char bg_green,unsigned char bg_blue,double opacity)1833 get_payload_from_rgb_transparent (unsigned int width, unsigned int height,
1834 unsigned char *pixels, unsigned char format,
1835 int quality, unsigned char **image,
1836 int *image_sz, unsigned char bg_red,
1837 unsigned char bg_green, unsigned char bg_blue,
1838 double opacity)
1839 {
1840 /* input: RGB output: RGB */
1841 unsigned char *p_in;
1842 unsigned char *p_msk;
1843 unsigned char *mask = NULL;
1844 unsigned int row;
1845 unsigned int col;
1846
1847 if (quality > 100)
1848 quality = 100;
1849 mask = malloc (width * height);
1850 if (mask == NULL)
1851 goto error;
1852 p_in = pixels;
1853 p_msk = mask;
1854 for (row = 0; row < height; row++)
1855 {
1856 for (col = 0; col < width; col++)
1857 {
1858 unsigned char red = *p_in++;
1859 unsigned char green = *p_in++;
1860 unsigned char blue = *p_in++;
1861 if (red == bg_red && green == bg_green && blue == bg_blue)
1862 *p_msk++ = 0; /* Transparent */
1863 else
1864 *p_msk++ = 1; /* Opaque */
1865 }
1866 }
1867 if (format == RL2_OUTPUT_FORMAT_PNG)
1868 {
1869 if (rl2_rgb_alpha_to_png
1870 (width, height, pixels, mask, image, image_sz, opacity) != RL2_OK)
1871 goto error;
1872 }
1873 else
1874 goto error;
1875 free (pixels);
1876 free (mask);
1877 return 1;
1878
1879 error:
1880 free (pixels);
1881 if (mask != NULL)
1882 free (mask);
1883 return 0;
1884 }
1885
1886 static int
test_no_data_8(rl2PrivPixelPtr no_data,unsigned char * p_in)1887 test_no_data_8 (rl2PrivPixelPtr no_data, unsigned char *p_in)
1888 {
1889 /* testing for NO-DATA */
1890 if (no_data != NULL)
1891 {
1892 unsigned char band;
1893 int match = 0;
1894 rl2PrivSamplePtr sample;
1895 for (band = 0; band < no_data->nBands; band++)
1896 {
1897 sample = no_data->Samples + band;
1898 if (*(p_in + band) == sample->uint8)
1899 match++;
1900 }
1901 if (match == no_data->nBands)
1902 return 1;
1903 }
1904 return 0;
1905 }
1906
1907 RL2_PRIVATE int
get_rgba_from_monochrome_mask(unsigned int width,unsigned int height,unsigned char * pixels,unsigned char * mask,rl2PrivPixelPtr no_data,unsigned char * rgba)1908 get_rgba_from_monochrome_mask (unsigned int width, unsigned int height,
1909 unsigned char *pixels, unsigned char *mask,
1910 rl2PrivPixelPtr no_data, unsigned char *rgba)
1911 {
1912 /* input: Monochrome output: Grayscale */
1913 unsigned char *p_in;
1914 unsigned char *p_out;
1915 unsigned char *p_msk;
1916 unsigned int row;
1917 unsigned int col;
1918 int transparent;
1919
1920 p_in = pixels;
1921 p_out = rgba;
1922 p_msk = mask;
1923 for (row = 0; row < height; row++)
1924 {
1925 for (col = 0; col < width; col++)
1926 {
1927 unsigned char value = 255;
1928 transparent = 0;
1929 if (p_msk != NULL)
1930 {
1931 if (*p_msk++ == 0)
1932 transparent = 1;
1933 }
1934 if (!transparent)
1935 transparent = test_no_data_8 (no_data, p_in);
1936 if (transparent)
1937 {
1938 p_out += 4;
1939 p_in++;
1940 }
1941 else
1942 {
1943 if (*p_in++ == 1)
1944 value = 0;
1945 *p_out++ = value;
1946 *p_out++ = value;
1947 *p_out++ = value;
1948 *p_out++ = 255; /* opaque */
1949 }
1950 }
1951 }
1952 free (pixels);
1953 if (mask != NULL)
1954 free (mask);
1955 return 1;
1956 }
1957
1958 RL2_PRIVATE int
get_rgba_from_monochrome_opaque(unsigned int width,unsigned int height,unsigned char * pixels,unsigned char * rgba)1959 get_rgba_from_monochrome_opaque (unsigned int width, unsigned int height,
1960 unsigned char *pixels, unsigned char *rgba)
1961 {
1962 /* input: Monochrome output: Grayscale */
1963 unsigned char *p_in;
1964 unsigned char *p_out;
1965 unsigned int row;
1966 unsigned int col;
1967 p_in = pixels;
1968 p_out = rgba;
1969 for (row = 0; row < height; row++)
1970 {
1971 for (col = 0; col < width; col++)
1972 {
1973 if (*p_in++ == 1)
1974 {
1975 *p_out++ = 0; /* Black */
1976 *p_out++ = 0;
1977 *p_out++ = 0;
1978 *p_out++ = 255; /* alpha */
1979 }
1980 else
1981 {
1982 *p_out++ = 255; /* White */
1983 *p_out++ = 255;
1984 *p_out++ = 255;
1985 *p_out++ = 255; /* alpha */
1986 }
1987 }
1988 }
1989 free (pixels);
1990 return 1;
1991 }
1992
1993 RL2_PRIVATE int
get_rgba_from_monochrome_transparent(unsigned int width,unsigned int height,unsigned char * pixels,unsigned char * rgba)1994 get_rgba_from_monochrome_transparent (unsigned int width,
1995 unsigned int height,
1996 unsigned char *pixels,
1997 unsigned char *rgba)
1998 {
1999 /* input: Monochrome output: Grayscale */
2000 unsigned char *p_in;
2001 unsigned char *p_out;
2002 unsigned int row;
2003 unsigned int col;
2004
2005 p_in = pixels;
2006 p_out = rgba;
2007 for (row = 0; row < height; row++)
2008 {
2009 for (col = 0; col < width; col++)
2010 {
2011 if (*p_in++ == 1)
2012 {
2013 *p_out++ = 0; /* Black */
2014 *p_out++ = 0;
2015 *p_out++ = 0;
2016 *p_out++ = 255; /* alpha */
2017 }
2018 else
2019 {
2020 *p_out++ = 255; /* White */
2021 *p_out++ = 255;
2022 *p_out++ = 255;
2023 *p_out++ = 0; /* alpha */
2024 }
2025 }
2026 }
2027 free (pixels);
2028 return 1;
2029 }
2030
2031 RL2_PRIVATE int
get_rgba_from_palette_mask(unsigned int width,unsigned int height,unsigned char * pixels,unsigned char * mask,rl2PalettePtr palette,rl2PrivPixelPtr no_data,unsigned char * rgba)2032 get_rgba_from_palette_mask (unsigned int width, unsigned int height,
2033 unsigned char *pixels, unsigned char *mask,
2034 rl2PalettePtr palette, rl2PrivPixelPtr no_data,
2035 unsigned char *rgba)
2036 {
2037 /* input: Palette output: Grayscale or RGB */
2038 rl2PrivPalettePtr plt = (rl2PrivPalettePtr) palette;
2039 unsigned char *p_in;
2040 unsigned char *p_out;
2041 unsigned char *p_msk;
2042 unsigned int row;
2043 unsigned int col;
2044 unsigned char out_format;
2045 int transparent;
2046
2047 p_in = pixels;
2048 p_out = rgba;
2049 p_msk = mask;
2050 out_format = get_palette_format (plt);
2051 if (out_format == RL2_PIXEL_RGB)
2052 {
2053 /* converting from Palette to RGB */
2054 for (row = 0; row < height; row++)
2055 {
2056 for (col = 0; col < width; col++)
2057 {
2058 unsigned char red = 0;
2059 unsigned char green = 0;
2060 unsigned char blue = 0;
2061 unsigned char index;
2062 transparent = 0;
2063 if (p_msk != NULL)
2064 {
2065 if (*p_msk++ == 0)
2066 transparent = 1;
2067 }
2068 if (!transparent)
2069 transparent = test_no_data_8 (no_data, p_in);
2070 if (transparent)
2071 {
2072 p_out += 4;
2073 p_in++;
2074 }
2075 else
2076 {
2077 index = *p_in++;
2078 if (index < plt->nEntries)
2079 {
2080 rl2PrivPaletteEntryPtr entry =
2081 plt->entries + index;
2082 red = entry->red;
2083 green = entry->green;
2084 blue = entry->blue;
2085 }
2086 *p_out++ = red; /* red */
2087 *p_out++ = green; /* green */
2088 *p_out++ = blue; /* blue */
2089 *p_out++ = 255; /* opaque */
2090 }
2091 }
2092 }
2093 }
2094 else if (out_format == RL2_PIXEL_GRAYSCALE)
2095 {
2096 /* converting from Palette to Grayscale */
2097 for (row = 0; row < height; row++)
2098 {
2099 for (col = 0; col < width; col++)
2100 {
2101 unsigned char value = 0;
2102 unsigned char index = *p_in++;
2103 if (index < plt->nEntries)
2104 {
2105 rl2PrivPaletteEntryPtr entry = plt->entries + index;
2106 value = entry->red;
2107 }
2108 transparent = 0;
2109 if (p_msk != NULL)
2110 {
2111 if (*p_msk++ == 0)
2112 transparent = 1;
2113 }
2114 if (transparent)
2115 p_out += 4;
2116 else
2117 {
2118 *p_out++ = value; /* red */
2119 *p_out++ = value; /* green */
2120 *p_out++ = value; /* blue */
2121 *p_out++ = 255; /* opaque */
2122 }
2123 }
2124 }
2125 }
2126 else
2127 goto error;
2128 free (pixels);
2129 if (mask)
2130 free (mask);
2131 return 1;
2132
2133 error:
2134 free (pixels);
2135 if (mask)
2136 free (mask);
2137 return 0;
2138 }
2139
2140 RL2_PRIVATE int
get_rgba_from_palette_opaque(unsigned int width,unsigned int height,unsigned char * pixels,rl2PalettePtr palette,unsigned char * rgba)2141 get_rgba_from_palette_opaque (unsigned int width, unsigned int height,
2142 unsigned char *pixels, rl2PalettePtr palette,
2143 unsigned char *rgba)
2144 {
2145 /* input: Palette output: Grayscale or RGB */
2146 rl2PrivPalettePtr plt = (rl2PrivPalettePtr) palette;
2147 unsigned char *p_in;
2148 unsigned char *p_out;
2149 unsigned int row;
2150 unsigned int col;
2151 unsigned char out_format;
2152
2153 p_in = pixels;
2154 p_out = rgba;
2155 out_format = get_palette_format (plt);
2156 if (out_format == RL2_PIXEL_RGB)
2157 {
2158 /* converting from Palette to RGB */
2159 for (row = 0; row < height; row++)
2160 {
2161 for (col = 0; col < width; col++)
2162 {
2163 unsigned char red = 0;
2164 unsigned char green = 0;
2165 unsigned char blue = 0;
2166 unsigned char index = *p_in++;
2167 if (index < plt->nEntries)
2168 {
2169 rl2PrivPaletteEntryPtr entry = plt->entries + index;
2170 red = entry->red;
2171 green = entry->green;
2172 blue = entry->blue;
2173 }
2174 *p_out++ = red; /* red */
2175 *p_out++ = green; /* green */
2176 *p_out++ = blue; /* blue */
2177 *p_out++ = 255; /* alpha */
2178 }
2179 }
2180 }
2181 else if (out_format == RL2_PIXEL_GRAYSCALE)
2182 {
2183 /* converting from Palette to Grayscale */
2184 for (row = 0; row < height; row++)
2185 {
2186 for (col = 0; col < width; col++)
2187 {
2188 unsigned char value = 0;
2189 unsigned char index = *p_in++;
2190 if (index < plt->nEntries)
2191 {
2192 rl2PrivPaletteEntryPtr entry = plt->entries + index;
2193 value = entry->red;
2194 }
2195 *p_out++ = value; /* red */
2196 *p_out++ = value; /* green */
2197 *p_out++ = value; /* blue */
2198 *p_out++ = 255; /* alpha */
2199 }
2200 }
2201 }
2202 else
2203 goto error;
2204 free (pixels);
2205 return 1;
2206
2207 error:
2208 free (pixels);
2209 return 0;
2210 }
2211
2212 RL2_PRIVATE int
get_rgba_from_palette_transparent(unsigned int width,unsigned int height,unsigned char * pixels,rl2PalettePtr palette,unsigned char * rgba,unsigned char bg_red,unsigned char bg_green,unsigned char bg_blue)2213 get_rgba_from_palette_transparent (unsigned int width, unsigned int height,
2214 unsigned char *pixels, rl2PalettePtr palette,
2215 unsigned char *rgba, unsigned char bg_red,
2216 unsigned char bg_green,
2217 unsigned char bg_blue)
2218 {
2219 /* input: Palette output: Grayscale or RGB */
2220 rl2PrivPalettePtr plt = (rl2PrivPalettePtr) palette;
2221 unsigned char *p_in;
2222 unsigned char *p_out;
2223 unsigned int row;
2224 unsigned int col;
2225 unsigned char out_format;
2226
2227 p_in = pixels;
2228 p_out = rgba;
2229 out_format = get_palette_format (plt);
2230 if (out_format == RL2_PIXEL_RGB)
2231 {
2232 /* converting from Palette to RGB */
2233 for (row = 0; row < height; row++)
2234 {
2235 for (col = 0; col < width; col++)
2236 {
2237 unsigned char red = 0;
2238 unsigned char green = 0;
2239 unsigned char blue = 0;
2240 unsigned char index = *p_in++;
2241 if (index < plt->nEntries)
2242 {
2243 rl2PrivPaletteEntryPtr entry = plt->entries + index;
2244 red = entry->red;
2245 green = entry->green;
2246 blue = entry->blue;
2247 }
2248 *p_out++ = red; /* red */
2249 *p_out++ = green; /* green */
2250 *p_out++ = blue; /* blue */
2251 if (red == bg_red && green == bg_green && blue == bg_blue)
2252 *p_out++ = 0; /* Transparent */
2253 else
2254 *p_out++ = 255; /* Opaque */
2255 }
2256 }
2257 }
2258 else if (out_format == RL2_PIXEL_GRAYSCALE)
2259 {
2260 /* converting from Palette to Grayscale */
2261 for (row = 0; row < height; row++)
2262 {
2263 for (col = 0; col < width; col++)
2264 {
2265 unsigned char value = 0;
2266 unsigned char index = *p_in++;
2267 if (index < plt->nEntries)
2268 {
2269 rl2PrivPaletteEntryPtr entry = plt->entries + index;
2270 value = entry->red;
2271 }
2272 *p_out++ = value; /* red */
2273 *p_out++ = value; /* green */
2274 *p_out++ = value; /* blue */
2275 if (value == bg_red)
2276 *p_out++ = 0; /* Transparent */
2277 else
2278 *p_out++ = 255; /* Opaque */
2279 }
2280 }
2281 }
2282 else
2283 goto error;
2284 free (pixels);
2285 return 1;
2286
2287 error:
2288 free (pixels);
2289 return 0;
2290 }
2291
2292 RL2_PRIVATE int
get_rgba_from_grayscale_mask(unsigned int width,unsigned int height,unsigned char * pixels,unsigned char * mask,rl2PrivPixelPtr no_data,unsigned char * rgba)2293 get_rgba_from_grayscale_mask (unsigned int width, unsigned int height,
2294 unsigned char *pixels, unsigned char *mask,
2295 rl2PrivPixelPtr no_data, unsigned char *rgba)
2296 {
2297 /* input: Grayscale output: Grayscale */
2298 unsigned char *p_in;
2299 unsigned char *p_out;
2300 unsigned char *p_msk;
2301 unsigned int row;
2302 unsigned int col;
2303 int transparent;
2304
2305 p_in = pixels;
2306 p_out = rgba;
2307 p_msk = mask;
2308 for (row = 0; row < height; row++)
2309 {
2310 for (col = 0; col < width; col++)
2311 {
2312 transparent = 0;
2313 if (p_msk != NULL)
2314 {
2315 if (*p_msk++ == 0)
2316 transparent = 1;
2317 }
2318 if (!transparent)
2319 transparent = test_no_data_8 (no_data, p_in);
2320 if (transparent)
2321 {
2322 p_out += 4;
2323 p_in++;
2324 }
2325 else
2326 {
2327 unsigned char gray = *p_in++;
2328 *p_out++ = gray; /* red */
2329 *p_out++ = gray; /* green */
2330 *p_out++ = gray; /* blue */
2331 *p_out++ = 255; /* opaque */
2332 }
2333 }
2334 }
2335 free (pixels);
2336 if (mask != NULL)
2337 free (mask);
2338 return 1;
2339 }
2340
2341 RL2_PRIVATE int
get_rgba_from_grayscale_opaque(unsigned int width,unsigned int height,unsigned char * pixels,unsigned char * rgba)2342 get_rgba_from_grayscale_opaque (unsigned int width, unsigned int height,
2343 unsigned char *pixels, unsigned char *rgba)
2344 {
2345 /* input: Grayscale output: Grayscale */
2346 unsigned char *p_in;
2347 unsigned char *p_out;
2348 unsigned int row;
2349 unsigned int col;
2350
2351 p_in = pixels;
2352 p_out = rgba;
2353 for (row = 0; row < height; row++)
2354 {
2355 for (col = 0; col < width; col++)
2356 {
2357 unsigned char gray = *p_in++;
2358 *p_out++ = gray; /* red */
2359 *p_out++ = gray; /* green */
2360 *p_out++ = gray; /* blue */
2361 *p_out++ = 255; /* alpha */
2362 }
2363 }
2364 free (pixels);
2365 return 1;
2366 }
2367
2368 RL2_PRIVATE int
get_rgba_from_grayscale_transparent(unsigned int width,unsigned int height,unsigned char * pixels,unsigned char * rgba,unsigned char bg_gray)2369 get_rgba_from_grayscale_transparent (unsigned int width,
2370 unsigned int height,
2371 unsigned char *pixels, unsigned char *rgba,
2372 unsigned char bg_gray)
2373 {
2374 /* input: Grayscale output: Grayscale */
2375 unsigned char *p_in;
2376 unsigned char *p_out;
2377 unsigned int row;
2378 unsigned int col;
2379
2380 p_in = pixels;
2381 p_out = rgba;
2382 for (row = 0; row < height; row++)
2383 {
2384 for (col = 0; col < width; col++)
2385 {
2386 unsigned char gray = *p_in++;
2387 *p_out++ = gray; /* red */
2388 *p_out++ = gray; /* green */
2389 *p_out++ = gray; /* blue */
2390 if (gray == bg_gray)
2391 *p_out++ = 0; /* Transparent */
2392 else
2393 *p_out++ = 255; /* Opaque */
2394 }
2395 }
2396 free (pixels);
2397 return 1;
2398 }
2399
2400 RL2_PRIVATE int
get_rgba_from_rgb_mask(unsigned int width,unsigned int height,unsigned char * pixels,unsigned char * mask,rl2PrivPixelPtr no_data,unsigned char * rgba)2401 get_rgba_from_rgb_mask (unsigned int width, unsigned int height,
2402 unsigned char *pixels, unsigned char *mask,
2403 rl2PrivPixelPtr no_data, unsigned char *rgba)
2404 {
2405 /* input: RGB output: RGB */
2406 unsigned char *p_in;
2407 unsigned char *p_out;
2408 unsigned char *p_msk;
2409 unsigned int row;
2410 unsigned int col;
2411 int transparent;
2412
2413 p_in = pixels;
2414 p_out = rgba;
2415 p_msk = mask;
2416 for (row = 0; row < height; row++)
2417 {
2418 for (col = 0; col < width; col++)
2419 {
2420 transparent = 0;
2421 if (p_msk != NULL)
2422 {
2423 if (*p_msk++ == 0)
2424 transparent = 1;
2425 }
2426 if (!transparent)
2427 transparent = test_no_data_8 (no_data, p_in);
2428 if (transparent)
2429 {
2430 p_out += 4;
2431 p_in += 3;
2432 }
2433 else
2434 {
2435 *p_out++ = *p_in++; /* red */
2436 *p_out++ = *p_in++; /* green */
2437 *p_out++ = *p_in++; /* blue */
2438 *p_out++ = 255; /* opaque */
2439 }
2440 }
2441 }
2442 free (pixels);
2443 if (mask != NULL)
2444 free (mask);
2445 return 1;
2446 }
2447
2448 RL2_PRIVATE int
get_rgba_from_rgb_opaque(unsigned int width,unsigned int height,unsigned char * pixels,unsigned char * rgba)2449 get_rgba_from_rgb_opaque (unsigned int width, unsigned int height,
2450 unsigned char *pixels, unsigned char *rgba)
2451 {
2452 /* input: RGB output: RGB */
2453 unsigned char *p_in;
2454 unsigned char *p_out;
2455 unsigned int row;
2456 unsigned int col;
2457
2458 p_in = pixels;
2459 p_out = rgba;
2460 for (row = 0; row < height; row++)
2461 {
2462 for (col = 0; col < width; col++)
2463 {
2464 *p_out++ = *p_in++; /* red */
2465 *p_out++ = *p_in++; /* green */
2466 *p_out++ = *p_in++; /* blue */
2467 *p_out++ = 255; /* alpha */
2468 }
2469 }
2470 free (pixels);
2471 return 1;
2472 }
2473
2474 RL2_PRIVATE int
get_rgba_from_rgb_transparent(unsigned int width,unsigned int height,unsigned char * pixels,unsigned char * rgba,unsigned char bg_red,unsigned char bg_green,unsigned char bg_blue)2475 get_rgba_from_rgb_transparent (unsigned int width, unsigned int height,
2476 unsigned char *pixels, unsigned char *rgba,
2477 unsigned char bg_red, unsigned char bg_green,
2478 unsigned char bg_blue)
2479 {
2480 /* input: RGB output: RGB */
2481 unsigned char *p_in;
2482 unsigned char *p_out;
2483 unsigned int row;
2484 unsigned int col;
2485
2486 p_in = pixels;
2487 p_out = rgba;
2488 for (row = 0; row < height; row++)
2489 {
2490 for (col = 0; col < width; col++)
2491 {
2492 unsigned char red = *p_in++;
2493 unsigned char green = *p_in++;
2494 unsigned char blue = *p_in++;
2495 *p_out++ = red;
2496 *p_out++ = green;
2497 *p_out++ = blue;
2498 if (red == bg_red && green == bg_green && blue == bg_blue)
2499 *p_out++ = 0; /* Transparent */
2500 else
2501 *p_out++ = 255; /* Opaque */
2502 }
2503 }
2504 free (pixels);
2505 return 1;
2506 }
2507
2508 RL2_PRIVATE int
rgba_from_int8(unsigned int width,unsigned int height,char * pixels,unsigned char * mask,unsigned char * rgba)2509 rgba_from_int8 (unsigned int width, unsigned int height,
2510 char *pixels, unsigned char *mask, unsigned char *rgba)
2511 {
2512 /* input: DataGrid INT8 output: Grayscale */
2513 char *p_in;
2514 unsigned char *p_out;
2515 unsigned char *p_msk;
2516 unsigned int row;
2517 unsigned int col;
2518 int transparent;
2519
2520 p_in = pixels;
2521 p_out = rgba;
2522 p_msk = mask;
2523 for (row = 0; row < height; row++)
2524 {
2525 for (col = 0; col < width; col++)
2526 {
2527 char gray = 128 + *p_in++;
2528 transparent = 0;
2529 if (p_msk != NULL)
2530 {
2531 if (*p_msk++ == 0)
2532 transparent = 1;
2533 }
2534 if (transparent)
2535 p_out += 4;
2536 else
2537 {
2538 *p_out++ = gray; /* red */
2539 *p_out++ = gray; /* green */
2540 *p_out++ = gray; /* blue */
2541 *p_out++ = 255; /* opaque */
2542 }
2543 }
2544 }
2545 free (pixels);
2546 if (mask != NULL)
2547 free (mask);
2548 return 1;
2549 }
2550
2551 RL2_PRIVATE int
rgba_from_uint8(unsigned int width,unsigned int height,unsigned char * pixels,unsigned char * mask,unsigned char * rgba)2552 rgba_from_uint8 (unsigned int width, unsigned int height,
2553 unsigned char *pixels, unsigned char *mask,
2554 unsigned char *rgba)
2555 {
2556 /* input: DataGrid UINT8 output: Grayscale */
2557 unsigned char *p_in;
2558 unsigned char *p_out;
2559 unsigned char *p_msk;
2560 unsigned int row;
2561 unsigned int col;
2562 int transparent;
2563
2564 p_in = pixels;
2565 p_out = rgba;
2566 p_msk = mask;
2567 for (row = 0; row < height; row++)
2568 {
2569 for (col = 0; col < width; col++)
2570 {
2571 unsigned char gray = *p_in++;
2572 transparent = 0;
2573 if (p_msk != NULL)
2574 {
2575 if (*p_msk++ == 0)
2576 transparent = 1;
2577 }
2578 if (transparent)
2579 p_out += 4;
2580 else
2581 {
2582 *p_out++ = gray; /* red */
2583 *p_out++ = gray; /* green */
2584 *p_out++ = gray; /* blue */
2585 *p_out++ = 255; /* opaque */
2586 }
2587 }
2588 }
2589 free (pixels);
2590 if (mask != NULL)
2591 free (mask);
2592 return 1;
2593 }
2594
2595 RL2_PRIVATE int
rgba_from_int16(unsigned int width,unsigned int height,short * pixels,unsigned char * mask,unsigned char * rgba)2596 rgba_from_int16 (unsigned int width, unsigned int height,
2597 short *pixels, unsigned char *mask, unsigned char *rgba)
2598 {
2599 /* input: DataGrid INT16 output: Grayscale */
2600 short *p_in;
2601 unsigned char *p_out;
2602 unsigned char *p_msk;
2603 unsigned int row;
2604 unsigned int col;
2605 short min = SHRT_MAX;
2606 short max = SHRT_MIN;
2607 double min2;
2608 double max2;
2609 double tic;
2610 double tic2;
2611 int transparent;
2612 int i;
2613 int sum;
2614 int total;
2615 double percentile2;
2616 int histogram[1024];
2617
2618 /* identifying Min/Max values */
2619 total = 0;
2620 p_in = pixels;
2621 p_msk = mask;
2622 for (row = 0; row < height; row++)
2623 {
2624 for (col = 0; col < width; col++)
2625 {
2626 short gray = *p_in++;
2627 if (p_msk != NULL)
2628 {
2629 if (*p_msk++ == 0)
2630 continue;
2631 }
2632 if (min > gray)
2633 min = gray;
2634 if (max < gray)
2635 max = gray;
2636 total++;
2637 }
2638 }
2639 tic = (double) (max - min) / 1024.0;
2640 percentile2 = ((double) total / 100.0) * 2.0;
2641
2642 /* building an histogram */
2643 for (i = 0; i < 1024; i++)
2644 histogram[i] = 0;
2645 p_in = pixels;
2646 p_msk = mask;
2647 for (row = 0; row < height; row++)
2648 {
2649 for (col = 0; col < width; col++)
2650 {
2651 double gray = (double) (*p_in++ - min) / tic;
2652 if (p_msk != NULL)
2653 {
2654 if (*p_msk++ == 0)
2655 continue;
2656 }
2657 if (gray < 0.0)
2658 gray = 0.0;
2659 if (gray > 1023.0)
2660 gray = 1023.0;
2661 histogram[(int) gray] += 1;
2662 }
2663 }
2664 sum = 0;
2665 for (i = 0; i < 1024; i++)
2666 {
2667 sum += histogram[i];
2668 if (sum >= percentile2)
2669 {
2670 min2 = (double) min + ((double) i * tic);
2671 break;
2672 }
2673 }
2674 sum = 0;
2675 for (i = 1023; i >= 0; i--)
2676 {
2677 sum += histogram[i];
2678 if (sum >= percentile2)
2679 {
2680 max2 = (double) min + ((double) (i + 1) * tic);
2681 break;
2682 }
2683 }
2684 tic2 = (double) (max2 - min2) / 254.0;
2685
2686 /* rescaling gray-values 0-255 */
2687 p_in = pixels;
2688 p_out = rgba;
2689 p_msk = mask;
2690 for (row = 0; row < height; row++)
2691 {
2692 for (col = 0; col < width; col++)
2693 {
2694 transparent = 0;
2695 if (p_msk != NULL)
2696 {
2697 if (*p_msk++ == 0)
2698 transparent = 1;
2699 }
2700 if (transparent)
2701 {
2702 p_in++;
2703 p_out += 4;
2704 }
2705 else
2706 {
2707 double gray;
2708 short val = *p_in++;
2709 if (val <= min2)
2710 gray = 0.0;
2711 else if (val >= max2)
2712 gray = 255.0;
2713 else
2714 gray = 1.0 + (((double) val - min2) / tic2);
2715 if (gray < 0.0)
2716 gray = 0.0;
2717 if (gray > 255.0)
2718 gray = 255.0;
2719 *p_out++ = (unsigned char) gray; /* red */
2720 *p_out++ = (unsigned char) gray; /* green */
2721 *p_out++ = (unsigned char) gray; /* blue */
2722 *p_out++ = 255; /* opaque */
2723 }
2724 }
2725 }
2726 free (pixels);
2727 if (mask != NULL)
2728 free (mask);
2729 return 1;
2730 }
2731
2732 RL2_PRIVATE int
rgba_from_uint16(unsigned int width,unsigned int height,unsigned short * pixels,unsigned char * mask,unsigned char * rgba)2733 rgba_from_uint16 (unsigned int width, unsigned int height,
2734 unsigned short *pixels, unsigned char *mask,
2735 unsigned char *rgba)
2736 {
2737 /* input: DataGrid UINT16 output: Grayscale */
2738 unsigned short *p_in;
2739 unsigned char *p_out;
2740 unsigned char *p_msk;
2741 unsigned int row;
2742 unsigned int col;
2743 unsigned short min = USHRT_MAX;
2744 unsigned short max = 0;
2745 double min2;
2746 double max2;
2747 double tic;
2748 double tic2;
2749 int transparent;
2750 int i;
2751 int sum;
2752 int total;
2753 double percentile2;
2754 int histogram[1024];
2755
2756 /* identifying Min/Max values */
2757 total = 0;
2758 p_in = pixels;
2759 p_msk = mask;
2760 for (row = 0; row < height; row++)
2761 {
2762 for (col = 0; col < width; col++)
2763 {
2764 unsigned short gray = *p_in++;
2765 if (p_msk != NULL)
2766 {
2767 if (*p_msk++ == 0)
2768 continue;
2769 }
2770 if (min > gray)
2771 min = gray;
2772 if (max < gray)
2773 max = gray;
2774 total++;
2775 }
2776 }
2777 tic = (double) (max - min) / 1024.0;
2778 percentile2 = ((double) total / 100.0) * 2.0;
2779
2780 /* building an histogram */
2781 for (i = 0; i < 1024; i++)
2782 histogram[i] = 0;
2783 p_in = pixels;
2784 p_msk = mask;
2785 for (row = 0; row < height; row++)
2786 {
2787 for (col = 0; col < width; col++)
2788 {
2789 double gray = (double) (*p_in++ - min) / tic;
2790 if (p_msk != NULL)
2791 {
2792 if (*p_msk++ == 0)
2793 continue;
2794 }
2795 if (gray < 0.0)
2796 gray = 0.0;
2797 if (gray > 1023.0)
2798 gray = 1023.0;
2799 histogram[(int) gray] += 1;
2800 }
2801 }
2802 sum = 0;
2803 for (i = 0; i < 1024; i++)
2804 {
2805 sum += histogram[i];
2806 if (sum >= percentile2)
2807 {
2808 min2 = (double) min + ((double) i * tic);
2809 break;
2810 }
2811 }
2812 sum = 0;
2813 for (i = 1023; i >= 0; i--)
2814 {
2815 sum += histogram[i];
2816 if (sum >= percentile2)
2817 {
2818 max2 = (double) min + ((double) (i + 1) * tic);
2819 break;
2820 }
2821 }
2822 tic2 = (double) (max2 - min2) / 254.0;
2823
2824 /* rescaling gray-values 0-255 */
2825 p_in = pixels;
2826 p_out = rgba;
2827 p_msk = mask;
2828 for (row = 0; row < height; row++)
2829 {
2830 for (col = 0; col < width; col++)
2831 {
2832 transparent = 0;
2833 if (p_msk != NULL)
2834 {
2835 if (*p_msk++ == 0)
2836 transparent = 1;
2837 }
2838 if (transparent)
2839 {
2840 p_in++;
2841 p_out += 4;
2842 }
2843 else
2844 {
2845 double gray;
2846 unsigned short val = *p_in++;
2847 if (val <= min2)
2848 gray = 0.0;
2849 else if (val >= max2)
2850 gray = 255.0;
2851 else
2852 gray = 1.0 + (((double) val - min2) / tic2);
2853 if (gray < 0.0)
2854 gray = 0.0;
2855 if (gray > 255.0)
2856 gray = 255.0;
2857 *p_out++ = (unsigned char) gray; /* red */
2858 *p_out++ = (unsigned char) gray; /* green */
2859 *p_out++ = (unsigned char) gray; /* blue */
2860 *p_out++ = 255; /* opaque */
2861 }
2862 }
2863 }
2864 free (pixels);
2865 if (mask != NULL)
2866 free (mask);
2867 return 1;
2868 }
2869
2870 RL2_PRIVATE int
rgba_from_int32(unsigned int width,unsigned int height,int * pixels,unsigned char * mask,unsigned char * rgba)2871 rgba_from_int32 (unsigned int width, unsigned int height,
2872 int *pixels, unsigned char *mask, unsigned char *rgba)
2873 {
2874 /* input: DataGrid INT32 output: Grayscale */
2875 int *p_in;
2876 unsigned char *p_out;
2877 unsigned char *p_msk;
2878 unsigned int row;
2879 unsigned int col;
2880 int min = INT_MAX;
2881 int max = INT_MIN;
2882 double min2;
2883 double max2;
2884 double tic;
2885 double tic2;
2886 int transparent;
2887 int i;
2888 int sum;
2889 int total;
2890 double percentile2;
2891 int histogram[1024];
2892
2893 /* identifying Min/Max values */
2894 total = 0;
2895 p_in = pixels;
2896 p_msk = mask;
2897 for (row = 0; row < height; row++)
2898 {
2899 for (col = 0; col < width; col++)
2900 {
2901 int gray = *p_in++;
2902 if (p_msk != NULL)
2903 {
2904 if (*p_msk++ == 0)
2905 continue;
2906 }
2907 if (min > gray)
2908 min = gray;
2909 if (max < gray)
2910 max = gray;
2911 total++;
2912 }
2913 }
2914 tic = (double) (max - min) / 1024.0;
2915 percentile2 = ((double) total / 100.0) * 2.0;
2916
2917 /* building an histogram */
2918 for (i = 0; i < 1024; i++)
2919 histogram[i] = 0;
2920 p_in = pixels;
2921 p_msk = mask;
2922 for (row = 0; row < height; row++)
2923 {
2924 for (col = 0; col < width; col++)
2925 {
2926 double gray = (double) (*p_in++ - min) / tic;
2927 if (p_msk != NULL)
2928 {
2929 if (*p_msk++ == 0)
2930 continue;
2931 }
2932 if (gray < 0.0)
2933 gray = 0.0;
2934 if (gray > 1023.0)
2935 gray = 1023.0;
2936 histogram[(int) gray] += 1;
2937 }
2938 }
2939 sum = 0;
2940 for (i = 0; i < 1024; i++)
2941 {
2942 sum += histogram[i];
2943 if (sum >= percentile2)
2944 {
2945 min2 = (double) min + ((double) i * tic);
2946 break;
2947 }
2948 }
2949 sum = 0;
2950 for (i = 1023; i >= 0; i--)
2951 {
2952 sum += histogram[i];
2953 if (sum >= percentile2)
2954 {
2955 max2 = (double) min + ((double) (i + 1) * tic);
2956 break;
2957 }
2958 }
2959 tic2 = (double) (max2 - min2) / 254.0;
2960
2961 /* rescaling gray-values 0-255 */
2962 p_in = pixels;
2963 p_out = rgba;
2964 p_msk = mask;
2965 for (row = 0; row < height; row++)
2966 {
2967 for (col = 0; col < width; col++)
2968 {
2969 transparent = 0;
2970 if (p_msk != NULL)
2971 {
2972 if (*p_msk++ == 0)
2973 transparent = 1;
2974 }
2975 if (transparent)
2976 {
2977 p_in++;
2978 p_out += 4;
2979 }
2980 else
2981 {
2982 double gray;
2983 int val = *p_in++;
2984 if (val <= min2)
2985 gray = 0.0;
2986 else if (val >= max2)
2987 gray = 255.0;
2988 else
2989 gray = 1.0 + (((double) val - min2) / tic2);
2990 if (gray < 0.0)
2991 gray = 0.0;
2992 if (gray > 255.0)
2993 gray = 255.0;
2994 *p_out++ = (unsigned char) gray; /* red */
2995 *p_out++ = (unsigned char) gray; /* green */
2996 *p_out++ = (unsigned char) gray; /* blue */
2997 *p_out++ = 255; /* opaque */
2998 }
2999 }
3000 }
3001 free (pixels);
3002 if (mask != NULL)
3003 free (mask);
3004 return 1;
3005 }
3006
3007 RL2_PRIVATE int
rgba_from_uint32(unsigned int width,unsigned int height,unsigned int * pixels,unsigned char * mask,unsigned char * rgba)3008 rgba_from_uint32 (unsigned int width, unsigned int height,
3009 unsigned int *pixels, unsigned char *mask,
3010 unsigned char *rgba)
3011 {
3012 /* input: DataGrid UINT32 output: Grayscale */
3013 unsigned int *p_in;
3014 unsigned char *p_out;
3015 unsigned char *p_msk;
3016 unsigned int row;
3017 unsigned int col;
3018 unsigned int min = UINT_MAX;
3019 unsigned int max = 0;
3020 double min2;
3021 double max2;
3022 double tic;
3023 double tic2;
3024 int transparent;
3025 int i;
3026 int sum;
3027 int total;
3028 double percentile2;
3029 int histogram[1024];
3030
3031 /* identifying Min/Max values */
3032 total = 0;
3033 p_in = pixels;
3034 p_msk = mask;
3035 for (row = 0; row < height; row++)
3036 {
3037 for (col = 0; col < width; col++)
3038 {
3039 unsigned int gray = *p_in++;
3040 if (p_msk != NULL)
3041 {
3042 if (*p_msk++ == 0)
3043 continue;
3044 }
3045 if (min > gray)
3046 min = gray;
3047 if (max < gray)
3048 max = gray;
3049 total++;
3050 }
3051 }
3052 tic = (double) (max - min) / 1024.0;
3053 percentile2 = ((double) total / 100.0) * 2.0;
3054
3055 /* building an histogram */
3056 for (i = 0; i < 1024; i++)
3057 histogram[i] = 0;
3058 p_in = pixels;
3059 p_msk = mask;
3060 for (row = 0; row < height; row++)
3061 {
3062 for (col = 0; col < width; col++)
3063 {
3064 double gray = (double) (*p_in++ - min) / tic;
3065 if (p_msk != NULL)
3066 {
3067 if (*p_msk++ == 0)
3068 continue;
3069 }
3070 if (gray < 0.0)
3071 gray = 0.0;
3072 if (gray > 1023.0)
3073 gray = 1023.0;
3074 histogram[(int) gray] += 1;
3075 }
3076 }
3077 sum = 0;
3078 for (i = 0; i < 1024; i++)
3079 {
3080 sum += histogram[i];
3081 if (sum >= percentile2)
3082 {
3083 min2 = (double) min + ((double) i * tic);
3084 break;
3085 }
3086 }
3087 sum = 0;
3088 for (i = 1023; i >= 0; i--)
3089 {
3090 sum += histogram[i];
3091 if (sum >= percentile2)
3092 {
3093 max2 = (double) min + ((double) (i + 1) * tic);
3094 break;
3095 }
3096 }
3097 tic2 = (double) (max2 - min2) / 254.0;
3098
3099 /* rescaling gray-values 0-255 */
3100 p_in = pixels;
3101 p_out = rgba;
3102 p_msk = mask;
3103 for (row = 0; row < height; row++)
3104 {
3105 for (col = 0; col < width; col++)
3106 {
3107 transparent = 0;
3108 if (p_msk != NULL)
3109 {
3110 if (*p_msk++ == 0)
3111 transparent = 1;
3112 }
3113 if (transparent)
3114 {
3115 p_in++;
3116 p_out += 4;
3117 }
3118 else
3119 {
3120 double gray;
3121 unsigned int val = *p_in++;
3122 if (val <= min2)
3123 gray = 0.0;
3124 else if (val >= max2)
3125 gray = 255.0;
3126 else
3127 gray = 1.0 + (((double) val - min2) / tic2);
3128 if (gray < 0.0)
3129 gray = 0.0;
3130 if (gray > 255.0)
3131 gray = 255.0;
3132 *p_out++ = (unsigned char) gray; /* red */
3133 *p_out++ = (unsigned char) gray; /* green */
3134 *p_out++ = (unsigned char) gray; /* blue */
3135 *p_out++ = 255; /* opaque */
3136 }
3137 }
3138 }
3139 free (pixels);
3140 if (mask != NULL)
3141 free (mask);
3142 return 1;
3143 }
3144
3145 RL2_PRIVATE int
rgba_from_float(unsigned int width,unsigned int height,float * pixels,unsigned char * mask,unsigned char * rgba)3146 rgba_from_float (unsigned int width, unsigned int height,
3147 float *pixels, unsigned char *mask, unsigned char *rgba)
3148 {
3149 /* input: DataGrid FLOAT output: Grayscale */
3150 float *p_in;
3151 unsigned char *p_out;
3152 unsigned char *p_msk;
3153 unsigned int row;
3154 unsigned int col;
3155 float min = FLT_MAX;
3156 float max = 0.0 - FLT_MAX;
3157 double min2;
3158 double max2;
3159 double tic;
3160 double tic2;
3161 int transparent;
3162 int i;
3163 int sum;
3164 int total;
3165 double percentile2;
3166 int histogram[1024];
3167
3168 /* identifying Min/Max values */
3169 total = 0;
3170 p_in = pixels;
3171 p_msk = mask;
3172 for (row = 0; row < height; row++)
3173 {
3174 for (col = 0; col < width; col++)
3175 {
3176 float gray = *p_in++;
3177 if (p_msk != NULL)
3178 {
3179 if (*p_msk++ == 0)
3180 continue;
3181 }
3182 if (min > gray)
3183 min = gray;
3184 if (max < gray)
3185 max = gray;
3186 total++;
3187 }
3188 }
3189 tic = (double) (max - min) / 1024.0;
3190 percentile2 = ((double) total / 100.0) * 2.0;
3191
3192 /* building an histogram */
3193 for (i = 0; i < 1024; i++)
3194 histogram[i] = 0;
3195 p_in = pixels;
3196 p_msk = mask;
3197 for (row = 0; row < height; row++)
3198 {
3199 for (col = 0; col < width; col++)
3200 {
3201 double gray = (double) (*p_in++ - min) / tic;
3202 if (p_msk != NULL)
3203 {
3204 if (*p_msk++ == 0)
3205 continue;
3206 }
3207 if (gray < 0.0)
3208 gray = 0.0;
3209 if (gray > 1023.0)
3210 gray = 1023.0;
3211 histogram[(int) gray] += 1;
3212 }
3213 }
3214 sum = 0;
3215 for (i = 0; i < 1024; i++)
3216 {
3217 sum += histogram[i];
3218 if (sum >= percentile2)
3219 {
3220 min2 = (double) min + ((double) i * tic);
3221 break;
3222 }
3223 }
3224 sum = 0;
3225 for (i = 1023; i >= 0; i--)
3226 {
3227 sum += histogram[i];
3228 if (sum >= percentile2)
3229 {
3230 max2 = (double) min + ((double) (i + 1) * tic);
3231 break;
3232 }
3233 }
3234 tic2 = (double) (max2 - min2) / 254.0;
3235
3236 /* rescaling gray-values 0-255 */
3237 p_in = pixels;
3238 p_out = rgba;
3239 p_msk = mask;
3240 for (row = 0; row < height; row++)
3241 {
3242 for (col = 0; col < width; col++)
3243 {
3244 transparent = 0;
3245 if (p_msk != NULL)
3246 {
3247 if (*p_msk++ == 0)
3248 transparent = 1;
3249 }
3250 if (transparent)
3251 {
3252 p_in++;
3253 p_out += 4;
3254 }
3255 else
3256 {
3257 double gray;
3258 float val = *p_in++;
3259 if (val <= min2)
3260 gray = 0.0;
3261 else if (val >= max2)
3262 gray = 255.0;
3263 else
3264 gray = 1.0 + (((double) val - min2) / tic2);
3265 if (gray < 0.0)
3266 gray = 0.0;
3267 if (gray > 255.0)
3268 gray = 255.0;
3269 *p_out++ = (unsigned char) gray; /* red */
3270 *p_out++ = (unsigned char) gray; /* green */
3271 *p_out++ = (unsigned char) gray; /* blue */
3272 *p_out++ = 255; /* opaque */
3273 }
3274 }
3275 }
3276 free (pixels);
3277 if (mask != NULL)
3278 free (mask);
3279 return 1;
3280 }
3281
3282 RL2_PRIVATE int
rgba_from_double(unsigned int width,unsigned int height,double * pixels,unsigned char * mask,unsigned char * rgba)3283 rgba_from_double (unsigned int width, unsigned int height,
3284 double *pixels, unsigned char *mask, unsigned char *rgba)
3285 {
3286 /* input: DataGrid DOUBLE output: Grayscale */
3287 double *p_in;
3288 unsigned char *p_out;
3289 unsigned char *p_msk;
3290 unsigned int row;
3291 unsigned int col;
3292 double min = DBL_MAX;
3293 double max = 0.0 - DBL_MAX;
3294 double min2;
3295 double max2;
3296 double tic;
3297 double tic2;
3298 int transparent;
3299 int i;
3300 int sum;
3301 int total;
3302 double percentile2;
3303 int histogram[1024];
3304
3305 /* identifying Min/Max values */
3306 total = 0;
3307 p_in = pixels;
3308 p_msk = mask;
3309 for (row = 0; row < height; row++)
3310 {
3311 for (col = 0; col < width; col++)
3312 {
3313 double gray = *p_in++;
3314 if (p_msk != NULL)
3315 {
3316 if (*p_msk++ == 0)
3317 continue;
3318 }
3319 if (min > gray)
3320 min = gray;
3321 if (max < gray)
3322 max = gray;
3323 total++;
3324 }
3325 }
3326 tic = (double) (max - min) / 1024.0;
3327 percentile2 = ((double) total / 100.0) * 2.0;
3328
3329 /* building an histogram */
3330 for (i = 0; i < 1024; i++)
3331 histogram[i] = 0;
3332 p_in = pixels;
3333 p_msk = mask;
3334 for (row = 0; row < height; row++)
3335 {
3336 for (col = 0; col < width; col++)
3337 {
3338 double gray = (double) (*p_in++ - min) / tic;
3339 if (p_msk != NULL)
3340 {
3341 if (*p_msk++ == 0)
3342 continue;
3343 }
3344 if (gray < 0.0)
3345 gray = 0.0;
3346 if (gray > 1023.0)
3347 gray = 1023.0;
3348 histogram[(int) gray] += 1;
3349 }
3350 }
3351 sum = 0;
3352 for (i = 0; i < 1024; i++)
3353 {
3354 sum += histogram[i];
3355 if (sum >= percentile2)
3356 {
3357 min2 = (double) min + ((double) i * tic);
3358 break;
3359 }
3360 }
3361 sum = 0;
3362 for (i = 1023; i >= 0; i--)
3363 {
3364 sum += histogram[i];
3365 if (sum >= percentile2)
3366 {
3367 max2 = (double) min + ((double) (i + 1) * tic);
3368 break;
3369 }
3370 }
3371 tic2 = (double) (max2 - min2) / 254.0;
3372
3373 /* rescaling gray-values 0-255 */
3374 p_in = pixels;
3375 p_out = rgba;
3376 p_msk = mask;
3377 for (row = 0; row < height; row++)
3378 {
3379 for (col = 0; col < width; col++)
3380 {
3381 transparent = 0;
3382 if (p_msk != NULL)
3383 {
3384 if (*p_msk++ == 0)
3385 transparent = 1;
3386 }
3387 if (transparent)
3388 {
3389 p_in++;
3390 p_out += 4;
3391 }
3392 else
3393 {
3394 double gray;
3395 double val = *p_in++;
3396 if (val <= min2)
3397 gray = 0.0;
3398 else if (val >= max2)
3399 gray = 255.0;
3400 else
3401 gray = 1.0 + (((double) val - min2) / tic2);
3402 if (gray < 0.0)
3403 gray = 0.0;
3404 if (gray > 255.0)
3405 gray = 255.0;
3406 *p_out++ = (unsigned char) gray; /* red */
3407 *p_out++ = (unsigned char) gray; /* green */
3408 *p_out++ = (unsigned char) gray; /* blue */
3409 *p_out++ = 255; /* opaque */
3410 }
3411 }
3412 }
3413 free (pixels);
3414 if (mask != NULL)
3415 free (mask);
3416 return 1;
3417 }
3418
3419 RL2_PRIVATE int
get_rgba_from_datagrid_mask(unsigned int width,unsigned int height,unsigned char sample_type,void * pixels,unsigned char * mask,rl2PrivPixelPtr no_data,unsigned char * rgba)3420 get_rgba_from_datagrid_mask (unsigned int width, unsigned int height,
3421 unsigned char sample_type, void *pixels,
3422 unsigned char *mask, rl2PrivPixelPtr no_data,
3423 unsigned char *rgba)
3424 {
3425 /* input: DataGrid output: Grayscale */
3426 int ret = 0;
3427 switch (sample_type)
3428 {
3429 case RL2_SAMPLE_INT8:
3430 ret = rgba_from_int8 (width, height, (char *) pixels, mask, rgba);
3431 break;
3432 case RL2_SAMPLE_UINT8:
3433 ret =
3434 rgba_from_uint8 (width, height, (unsigned char *) pixels, mask,
3435 rgba);
3436 break;
3437 case RL2_SAMPLE_INT16:
3438 ret = rgba_from_int16 (width, height, (short *) pixels, mask, rgba);
3439 break;
3440 case RL2_SAMPLE_UINT16:
3441 ret =
3442 rgba_from_uint16 (width, height, (unsigned short *) pixels, mask,
3443 rgba);
3444 break;
3445 case RL2_SAMPLE_INT32:
3446 ret = rgba_from_int32 (width, height, (int *) pixels, mask, rgba);
3447 break;
3448 case RL2_SAMPLE_UINT32:
3449 ret =
3450 rgba_from_uint32 (width, height, (unsigned int *) pixels, mask,
3451 rgba);
3452 break;
3453 case RL2_SAMPLE_FLOAT:
3454 ret = rgba_from_float (width, height, (float *) pixels, mask, rgba);
3455 break;
3456 case RL2_SAMPLE_DOUBLE:
3457 ret = rgba_from_double (width, height, (double *) pixels, mask, rgba);
3458 break;
3459 };
3460 return ret;
3461 }
3462
3463 RL2_PRIVATE int
get_payload_from_gray_rgba_opaque(unsigned int width,unsigned int height,sqlite3 * handle,double minx,double miny,double maxx,double maxy,int srid,unsigned char * rgb,unsigned char format,int quality,unsigned char ** image,int * image_sz)3464 get_payload_from_gray_rgba_opaque (unsigned int width, unsigned int height,
3465 sqlite3 * handle, double minx, double miny,
3466 double maxx, double maxy, int srid,
3467 unsigned char *rgb, unsigned char format,
3468 int quality, unsigned char **image,
3469 int *image_sz)
3470 {
3471 /* Grayscale, Opaque */
3472 int ret;
3473 unsigned char *p_in;
3474 unsigned char *p_out;
3475 unsigned int row;
3476 unsigned int col;
3477 unsigned char *rgba = NULL;
3478 unsigned char *gray = malloc (width * height);
3479
3480 if (gray == NULL)
3481 goto error;
3482 p_in = rgb;
3483 p_out = gray;
3484 for (row = 0; row < height; row++)
3485 {
3486 for (col = 0; col < width; col++)
3487 {
3488 *p_out++ = *p_in++;
3489 p_in += 2;
3490 }
3491 }
3492 free (rgb);
3493 rgb = NULL;
3494 if (format == RL2_OUTPUT_FORMAT_JPEG)
3495 {
3496 if (rl2_gray_to_jpeg (width, height, gray, quality, image, image_sz)
3497 != RL2_OK)
3498 goto error;
3499 }
3500 else if (format == RL2_OUTPUT_FORMAT_PNG)
3501 {
3502 if (rl2_gray_to_png (width, height, gray, image, image_sz) != RL2_OK)
3503 goto error;
3504 }
3505 else if (format == RL2_OUTPUT_FORMAT_TIFF)
3506 {
3507 if (srid > 0)
3508 {
3509 if (rl2_gray_to_geotiff
3510 (width, height, handle, minx, miny, maxx, maxy, srid, gray,
3511 image, image_sz) != RL2_OK)
3512 goto error;
3513 }
3514 else
3515 {
3516 if (rl2_gray_to_tiff (width, height, gray, image, image_sz) !=
3517 RL2_OK)
3518 goto error;
3519 }
3520 }
3521 else if (format == RL2_OUTPUT_FORMAT_PDF)
3522 {
3523 rgba = gray_to_rgba (width, height, gray);
3524 if (rgba == NULL)
3525 goto error;
3526 ret = rl2_rgba_to_pdf (width, height, rgba, image, image_sz);
3527 rgba = NULL;
3528 if (ret != RL2_OK)
3529 goto error;
3530 }
3531 else
3532 goto error;
3533 free (gray);
3534 return 1;
3535 error:
3536 free (rgb);
3537 if (gray != NULL)
3538 free (gray);
3539 if (rgba != NULL)
3540 free (rgba);
3541 return 0;
3542 }
3543
3544 RL2_PRIVATE int
get_payload_from_gray_rgba_transparent(unsigned int width,unsigned int height,unsigned char * rgb,unsigned char * alpha,unsigned char format,int quality,unsigned char ** image,int * image_sz,double opacity)3545 get_payload_from_gray_rgba_transparent (unsigned int width,
3546 unsigned int height,
3547 unsigned char *rgb,
3548 unsigned char *alpha,
3549 unsigned char format, int quality,
3550 unsigned char **image, int *image_sz,
3551 double opacity)
3552 {
3553 /* Grayscale, Transparent */
3554 unsigned char *p_in;
3555 unsigned char *p_out;
3556 unsigned char *p_msk;
3557 unsigned char *p_alpha;
3558 unsigned short row;
3559 unsigned short col;
3560 unsigned char *gray = malloc (width * height);
3561 unsigned char *mask = malloc (width * height);
3562
3563 if (quality > 100)
3564 quality = 100;
3565 if (gray == NULL)
3566 goto error;
3567 if (mask == NULL)
3568 goto error;
3569 p_in = rgb;
3570 p_out = gray;
3571 p_msk = mask;
3572 p_alpha = alpha;
3573 for (row = 0; row < height; row++)
3574 {
3575 for (col = 0; col < width; col++)
3576 {
3577 *p_out++ = *p_in++;
3578 p_in += 2;
3579 if (*p_alpha++ >= 128)
3580 *p_msk++ = 1; /* Opaque */
3581 else
3582 *p_msk++ = 0; /* Transparent */
3583 }
3584 }
3585 free (rgb);
3586 rgb = NULL;
3587 free (alpha);
3588 alpha = NULL;
3589 if (format == RL2_OUTPUT_FORMAT_PNG)
3590 {
3591 if (rl2_gray_alpha_to_png
3592 (width, height, gray, mask, image, image_sz, opacity) != RL2_OK)
3593 goto error;
3594 }
3595 else
3596 goto error;
3597 free (gray);
3598 free (mask);
3599 return 1;
3600 error:
3601 free (rgb);
3602 if (gray != NULL)
3603 free (gray);
3604 if (mask != NULL)
3605 free (mask);
3606 return 0;
3607 }
3608
3609 RL2_PRIVATE int
get_payload_from_rgb_rgba_opaque(unsigned int width,unsigned int height,sqlite3 * handle,double minx,double miny,double maxx,double maxy,int srid,unsigned char * rgb,unsigned char format,int quality,unsigned char ** image,int * image_sz)3610 get_payload_from_rgb_rgba_opaque (unsigned int width, unsigned int height,
3611 sqlite3 * handle, double minx, double miny,
3612 double maxx, double maxy, int srid,
3613 unsigned char *rgb, unsigned char format,
3614 int quality, unsigned char **image,
3615 int *image_sz)
3616 {
3617 /* RGB, Opaque */
3618 int ret;
3619 unsigned char *rgba = NULL;
3620
3621 if (format == RL2_OUTPUT_FORMAT_JPEG)
3622 {
3623 if (rl2_rgb_to_jpeg (width, height, rgb, quality, image, image_sz) !=
3624 RL2_OK)
3625 goto error;
3626 }
3627 else if (format == RL2_OUTPUT_FORMAT_PNG)
3628 {
3629 if (rl2_rgb_to_png (width, height, rgb, image, image_sz) != RL2_OK)
3630 goto error;
3631 }
3632 else if (format == RL2_OUTPUT_FORMAT_TIFF)
3633 {
3634 if (srid > 0)
3635 {
3636 if (rl2_rgb_to_geotiff
3637 (width, height, handle, minx, miny, maxx, maxy, srid, rgb,
3638 image, image_sz) != RL2_OK)
3639 goto error;
3640 }
3641 else
3642 {
3643 if (rl2_rgb_to_tiff (width, height, rgb, image, image_sz) !=
3644 RL2_OK)
3645 goto error;
3646 }
3647 }
3648 else if (format == RL2_OUTPUT_FORMAT_PDF)
3649 {
3650 rgba = rgb_to_rgba (width, height, rgb);
3651 if (rgba == NULL)
3652 goto error;
3653 ret = rl2_rgba_to_pdf (width, height, rgba, image, image_sz);
3654 rgba = NULL;
3655 if (ret != RL2_OK)
3656 goto error;
3657 }
3658 else
3659 goto error;
3660 free (rgb);
3661 return 1;
3662 error:
3663 free (rgb);
3664 if (rgba != NULL)
3665 free (rgba);
3666 return 0;
3667 }
3668
3669 RL2_PRIVATE int
get_payload_from_rgb_rgba_transparent(unsigned int width,unsigned int height,unsigned char * rgb,unsigned char * alpha,unsigned char format,int quality,unsigned char ** image,int * image_sz,double opacity)3670 get_payload_from_rgb_rgba_transparent (unsigned int width,
3671 unsigned int height,
3672 unsigned char *rgb, unsigned char *alpha,
3673 unsigned char format, int quality,
3674 unsigned char **image, int *image_sz,
3675 double opacity)
3676 {
3677 /* RGB, Transparent */
3678 unsigned char *p_msk;
3679 unsigned char *p_alpha;
3680 unsigned int row;
3681 unsigned int col;
3682 unsigned char *mask = malloc (width * height);
3683
3684 if (quality > 100)
3685 quality = 100;
3686 if (mask == NULL)
3687 goto error;
3688 p_msk = mask;
3689 p_alpha = alpha;
3690 for (row = 0; row < height; row++)
3691 {
3692 for (col = 0; col < width; col++)
3693 {
3694 if (*p_alpha++ >= 128)
3695 *p_msk++ = 1; /* Opaque */
3696 else
3697 *p_msk++ = 0; /* Transparent */
3698 }
3699 }
3700 free (alpha);
3701 alpha = NULL;
3702 if (format == RL2_OUTPUT_FORMAT_PNG)
3703 {
3704 if (rl2_rgb_alpha_to_png
3705 (width, height, rgb, mask, image, image_sz, opacity) != RL2_OK)
3706 goto error;
3707 }
3708 else
3709 goto error;
3710 free (rgb);
3711 free (mask);
3712 return 1;
3713 error:
3714 free (rgb);
3715 if (mask != NULL)
3716 free (mask);
3717 return 0;
3718 }
3719
3720 RL2_PRIVATE int
build_rgb_alpha(unsigned int width,unsigned int height,unsigned char * rgba,unsigned char ** rgb,unsigned char ** alpha,unsigned char bg_red,unsigned char bg_green,unsigned char bg_blue)3721 build_rgb_alpha (unsigned int width, unsigned int height,
3722 unsigned char *rgba, unsigned char **rgb,
3723 unsigned char **alpha, unsigned char bg_red,
3724 unsigned char bg_green, unsigned char bg_blue)
3725 {
3726 /* creating separate RGB and Alpha buffers from RGBA */
3727 unsigned int row;
3728 unsigned int col;
3729 unsigned char *p_in = rgba;
3730 unsigned char *p_out;
3731 unsigned char *p_msk;
3732
3733 *rgb = NULL;
3734 *alpha = NULL;
3735 *rgb = malloc (width * height * 3);
3736 if (*rgb == NULL)
3737 goto error;
3738 *alpha = malloc (width * height);
3739 if (*alpha == NULL)
3740 goto error;
3741
3742 p_out = *rgb;
3743 p_msk = *alpha;
3744 for (row = 0; row < height; row++)
3745 {
3746 for (col = 0; col < width; col++)
3747 {
3748 unsigned char r = *p_in++;
3749 unsigned char g = *p_in++;
3750 unsigned char b = *p_in++;
3751 unsigned char alpha = *p_in++;
3752 *p_out++ = r;
3753 *p_out++ = g;
3754 *p_out++ = b;
3755 if (r == bg_red && g == bg_green && b == bg_blue)
3756 alpha = 0;
3757 *p_msk++ = alpha;
3758 }
3759 }
3760 return 1;
3761
3762 error:
3763 if (*rgb != NULL)
3764 free (*rgb);
3765 if (*alpha != NULL)
3766 free (*alpha);
3767 *rgb = NULL;
3768 *alpha = NULL;
3769 return 0;
3770 }
3771
3772 RL2_PRIVATE int
get_rgba_from_multiband8(unsigned int width,unsigned int height,unsigned char red_band,unsigned char green_band,unsigned char blue_band,unsigned char num_bands,unsigned char * pixels,unsigned char * mask,rl2PrivPixelPtr no_data,unsigned char * rgba)3773 get_rgba_from_multiband8 (unsigned int width, unsigned int height,
3774 unsigned char red_band, unsigned char green_band,
3775 unsigned char blue_band, unsigned char num_bands,
3776 unsigned char *pixels, unsigned char *mask,
3777 rl2PrivPixelPtr no_data, unsigned char *rgba)
3778 {
3779 /* input: MULTIBAND UINT8 output: RGB */
3780 unsigned char *p_in;
3781 unsigned char *p_out;
3782 unsigned char *p_msk;
3783 unsigned int row;
3784 unsigned int col;
3785 int transparent;
3786
3787 p_in = pixels;
3788 p_out = rgba;
3789 p_msk = mask;
3790 for (row = 0; row < height; row++)
3791 {
3792 for (col = 0; col < width; col++)
3793 {
3794 transparent = 0;
3795 if (p_msk != NULL)
3796 {
3797 if (*p_msk++ == 0)
3798 transparent = 1;
3799 }
3800 if (!transparent && no_data != NULL)
3801 {
3802 /* testing for NO-DATA */
3803 int match = 0;
3804 rl2PrivSamplePtr sample;
3805 unsigned char value;
3806 if (red_band < no_data->nBands)
3807 {
3808 sample = no_data->Samples + red_band;
3809 value = sample->uint8;
3810 if (*(p_in + red_band) == value)
3811 match++;
3812 }
3813 if (green_band < no_data->nBands)
3814 {
3815 sample = no_data->Samples + green_band;
3816 value = sample->uint8;
3817 if (*(p_in + green_band) == value)
3818 match++;
3819 }
3820 if (blue_band < no_data->nBands)
3821 {
3822 sample = no_data->Samples + blue_band;
3823 value = sample->uint8;
3824 if (*(p_in + blue_band) == value)
3825 match++;
3826 }
3827 if (match == 3)
3828 transparent = 1;
3829 }
3830 if (transparent)
3831 {
3832 p_out += 4;
3833 p_in += num_bands;
3834 }
3835 else
3836 {
3837 *p_out++ = *(p_in + red_band); /* red */
3838 *p_out++ = *(p_in + green_band); /* green */
3839 *p_out++ = *(p_in + blue_band); /* blue */
3840 *p_out++ = 255; /* opaque */
3841 p_in += num_bands;
3842 }
3843 }
3844 }
3845 free (pixels);
3846 if (mask != NULL)
3847 free (mask);
3848 return 1;
3849 }
3850
3851 static int
test_no_data_16(rl2PrivPixelPtr no_data,unsigned short * p_in)3852 test_no_data_16 (rl2PrivPixelPtr no_data, unsigned short *p_in)
3853 {
3854 /* testing for NO-DATA */
3855 if (no_data != NULL)
3856 {
3857 unsigned char band;
3858 int match = 0;
3859 rl2PrivSamplePtr sample;
3860 for (band = 0; band < no_data->nBands; band++)
3861 {
3862 sample = no_data->Samples + band;
3863 if (*(p_in + band) == sample->uint16)
3864 match++;
3865 }
3866 if (match == no_data->nBands)
3867 return 1;
3868 }
3869 return 0;
3870 }
3871
3872 RL2_PRIVATE int
get_rgba_from_multiband16(unsigned int width,unsigned int height,unsigned char red_band,unsigned char green_band,unsigned char blue_band,unsigned char num_bands,unsigned short * pixels,unsigned char * mask,rl2PrivPixelPtr no_data,unsigned char * rgba)3873 get_rgba_from_multiband16 (unsigned int width, unsigned int height,
3874 unsigned char red_band, unsigned char green_band,
3875 unsigned char blue_band, unsigned char num_bands,
3876 unsigned short *pixels, unsigned char *mask,
3877 rl2PrivPixelPtr no_data, unsigned char *rgba)
3878 {
3879 /* input: MULTIBAND UINT16 output: RGB */
3880 unsigned short *p_in;
3881 unsigned char *p_out;
3882 unsigned char *p_msk;
3883 unsigned int row;
3884 unsigned int col;
3885 int transparent;
3886 unsigned short min = USHRT_MAX;
3887 unsigned short max = 0;
3888 double tic;
3889 double red_min;
3890 double red_max;
3891 double red_tic;
3892 double green_min;
3893 double green_max;
3894 double green_tic;
3895 double blue_min;
3896 double blue_max;
3897 double blue_tic;
3898 int i;
3899 int sum;
3900 int total;
3901 int band;
3902 double percentile2;
3903 int histogram[1024];
3904
3905 /* identifying RED Min/Max values */
3906 total = 0;
3907 p_in = pixels;
3908 p_msk = mask;
3909 for (row = 0; row < height; row++)
3910 {
3911 for (col = 0; col < width; col++)
3912 {
3913 if (p_msk != NULL)
3914 {
3915 if (*p_msk++ == 0)
3916 {
3917 p_in += num_bands;
3918 continue;
3919 }
3920 }
3921 if (test_no_data_16 (no_data, p_in))
3922 {
3923 p_in += num_bands;
3924 continue;
3925 }
3926 for (band = 0; band < num_bands; band++)
3927 {
3928 unsigned short gray = *p_in++;
3929 if (band != red_band)
3930 continue;
3931 if (min > gray)
3932 min = gray;
3933 if (max < gray)
3934 max = gray;
3935 total++;
3936 }
3937 }
3938 }
3939 tic = (double) (max - min) / 1024.0;
3940 percentile2 = ((double) total / 100.0) * 2.0;
3941
3942 /* building the RED histogram */
3943 for (i = 0; i < 1024; i++)
3944 histogram[i] = 0;
3945 p_in = pixels;
3946 p_msk = mask;
3947 for (row = 0; row < height; row++)
3948 {
3949 for (col = 0; col < width; col++)
3950 {
3951 if (p_msk != NULL)
3952 {
3953 if (*p_msk++ == 0)
3954 {
3955 p_in += num_bands;
3956 continue;
3957 }
3958 }
3959 if (test_no_data_16 (no_data, p_in))
3960 {
3961 p_in += num_bands;
3962 continue;
3963 }
3964 for (band = 0; band < num_bands; band++)
3965 {
3966 double gray = (double) (*p_in++ - min) / tic;
3967 if (band != red_band)
3968 continue;
3969 if (gray < 0.0)
3970 gray = 0.0;
3971 if (gray > 1023.0)
3972 gray = 1023.0;
3973 histogram[(int) gray] += 1;
3974 }
3975 }
3976 }
3977 sum = 0;
3978 for (i = 0; i < 1024; i++)
3979 {
3980 sum += histogram[i];
3981 if (sum >= percentile2)
3982 {
3983 red_min = (double) min + ((double) i * tic);
3984 break;
3985 }
3986 }
3987 sum = 0;
3988 for (i = 1023; i >= 0; i--)
3989 {
3990 sum += histogram[i];
3991 if (sum >= percentile2)
3992 {
3993 red_max = (double) min + ((double) (i + 1) * tic);
3994 break;
3995 }
3996 }
3997 red_tic = (double) (red_max - red_min) / 254.0;
3998
3999 /* identifying GREEN Min/Max values */
4000 total = 0;
4001 p_in = pixels;
4002 p_msk = mask;
4003 for (row = 0; row < height; row++)
4004 {
4005 for (col = 0; col < width; col++)
4006 {
4007 if (p_msk != NULL)
4008 {
4009 if (*p_msk++ == 0)
4010 {
4011 p_in += num_bands;
4012 continue;
4013 }
4014 }
4015 if (test_no_data_16 (no_data, p_in))
4016 {
4017 p_in += num_bands;
4018 continue;
4019 }
4020 for (band = 0; band < num_bands; band++)
4021 {
4022 unsigned short gray = *p_in++;
4023 if (band != green_band)
4024 continue;
4025 if (min > gray)
4026 min = gray;
4027 if (max < gray)
4028 max = gray;
4029 total++;
4030 }
4031 }
4032 }
4033 tic = (double) (max - min) / 1024.0;
4034 percentile2 = ((double) total / 100.0) * 2.0;
4035
4036 /* building the GREEN histogram */
4037 for (i = 0; i < 1024; i++)
4038 histogram[i] = 0;
4039 p_in = pixels;
4040 p_msk = mask;
4041 for (row = 0; row < height; row++)
4042 {
4043 for (col = 0; col < width; col++)
4044 {
4045 if (p_msk != NULL)
4046 {
4047 if (*p_msk++ == 0)
4048 {
4049 p_in += num_bands;
4050 continue;
4051 }
4052 }
4053 if (test_no_data_16 (no_data, p_in))
4054 {
4055 p_in += num_bands;
4056 continue;
4057 }
4058 for (band = 0; band < num_bands; band++)
4059 {
4060 double gray = (double) (*p_in++ - min) / tic;
4061 if (band != green_band)
4062 continue;
4063 if (gray < 0.0)
4064 gray = 0.0;
4065 if (gray > 1023.0)
4066 gray = 1023.0;
4067 histogram[(int) gray] += 1;
4068 }
4069 }
4070 }
4071 sum = 0;
4072 for (i = 0; i < 1024; i++)
4073 {
4074 sum += histogram[i];
4075 if (sum >= percentile2)
4076 {
4077 green_min = (double) min + ((double) i * tic);
4078 break;
4079 }
4080 }
4081 sum = 0;
4082 for (i = 1023; i >= 0; i--)
4083 {
4084 sum += histogram[i];
4085 if (sum >= percentile2)
4086 {
4087 green_max = (double) min + ((double) (i + 1) * tic);
4088 break;
4089 }
4090 }
4091 green_tic = (double) (green_max - green_min) / 254.0;
4092
4093 /* identifying BLUE Min/Max values */
4094 total = 0;
4095 p_in = pixels;
4096 p_msk = mask;
4097 for (row = 0; row < height; row++)
4098 {
4099 for (col = 0; col < width; col++)
4100 {
4101 if (p_msk != NULL)
4102 {
4103 if (*p_msk++ == 0)
4104 {
4105 p_in += num_bands;
4106 continue;
4107 }
4108 }
4109 if (test_no_data_16 (no_data, p_in))
4110 {
4111 p_in += num_bands;
4112 continue;
4113 }
4114 for (band = 0; band < num_bands; band++)
4115 {
4116 unsigned short gray = *p_in++;
4117 if (band != blue_band)
4118 continue;
4119 if (min > gray)
4120 min = gray;
4121 if (max < gray)
4122 max = gray;
4123 total++;
4124 }
4125 }
4126 }
4127 tic = (double) (max - min) / 1024.0;
4128 percentile2 = ((double) total / 100.0) * 2.0;
4129
4130 /* building the BLUE histogram */
4131 for (i = 0; i < 1024; i++)
4132 histogram[i] = 0;
4133 p_in = pixels;
4134 p_msk = mask;
4135 for (row = 0; row < height; row++)
4136 {
4137 for (col = 0; col < width; col++)
4138 {
4139 if (p_msk != NULL)
4140 {
4141 if (*p_msk++ == 0)
4142 {
4143 p_in += num_bands;
4144 continue;
4145 }
4146 }
4147 if (test_no_data_16 (no_data, p_in))
4148 {
4149 p_in += num_bands;
4150 continue;
4151 }
4152 for (band = 0; band < num_bands; band++)
4153 {
4154 double gray = (double) (*p_in++ - min) / tic;
4155 if (band != blue_band)
4156 continue;
4157 if (gray < 0.0)
4158 gray = 0.0;
4159 if (gray > 1023.0)
4160 gray = 1023.0;
4161 histogram[(int) gray] += 1;
4162 }
4163 }
4164 }
4165 sum = 0;
4166 for (i = 0; i < 1024; i++)
4167 {
4168 sum += histogram[i];
4169 if (sum >= percentile2)
4170 {
4171 blue_min = (double) min + ((double) i * tic);
4172 break;
4173 }
4174 }
4175 sum = 0;
4176 for (i = 1023; i >= 0; i--)
4177 {
4178 sum += histogram[i];
4179 if (sum >= percentile2)
4180 {
4181 blue_max = (double) min + ((double) (i + 1) * tic);
4182 break;
4183 }
4184 }
4185 blue_tic = (double) (blue_max - blue_min) / 254.0;
4186
4187 /* rescaling RGB-values 0-255 */
4188 p_in = pixels;
4189 p_out = rgba;
4190 p_msk = mask;
4191 for (row = 0; row < height; row++)
4192 {
4193 for (col = 0; col < width; col++)
4194 {
4195 transparent = 0;
4196 if (p_msk != NULL)
4197 {
4198 if (*p_msk++ == 0)
4199 transparent = 1;
4200 }
4201 if (test_no_data_16 (no_data, p_in))
4202 transparent = 1;
4203 if (transparent)
4204 {
4205 p_out += 4;
4206 p_in += num_bands;
4207 }
4208 else
4209 {
4210 double r;
4211 double g;
4212 double b;
4213 unsigned short red = *(p_in + red_band);
4214 unsigned short green = *(p_in + green_band);
4215 unsigned short blue = *(p_in + blue_band);
4216 if (red <= red_min)
4217 r = 0.0;
4218 else if (red >= red_max)
4219 r = 255.0;
4220 else
4221 r = 1.0 + (((double) red - red_min) / red_tic);
4222 if (r < 0.0)
4223 r = 0.0;
4224 if (r > 255.0)
4225 r = 255.0;
4226 if (green <= green_min)
4227 g = 0.0;
4228 else if (green >= green_max)
4229 g = 255.0;
4230 else
4231 g = 1.0 + (((double) green - green_min) / green_tic);
4232 if (g < 0.0)
4233 g = 0.0;
4234 if (g > 255.0)
4235 g = 255.0;
4236 if (blue <= blue_min)
4237 b = 0.0;
4238 else if (blue >= blue_max)
4239 b = 255.0;
4240 else
4241 b = 1.0 + (((double) blue - blue_min) / blue_tic);
4242 if (b < 0.0)
4243 b = 0.0;
4244 if (b > 255.0)
4245 b = 255.0;
4246 *p_out++ = (unsigned char) r; /* red */
4247 *p_out++ = (unsigned char) g; /* green */
4248 *p_out++ = (unsigned char) b; /* blue */
4249 *p_out++ = 255; /* opaque */
4250 p_in += num_bands;
4251 }
4252 }
4253 }
4254 free (pixels);
4255 if (mask != NULL)
4256 free (mask);
4257 return 1;
4258 }
4259
4260 RL2_PRIVATE int
get_raster_band_histogram(rl2PrivBandStatisticsPtr band,unsigned char ** image,int * image_sz)4261 get_raster_band_histogram (rl2PrivBandStatisticsPtr band,
4262 unsigned char **image, int *image_sz)
4263 {
4264 /* attempting to create an in-memory PNG image representing a Band Histogram */
4265 int r;
4266 int c;
4267 int j;
4268 int h;
4269 double count = 0.0;
4270 double max = 0.0;
4271 unsigned short width = 512;
4272 unsigned short height = 128 + 32;
4273 double scale;
4274 unsigned char *raster = malloc (width * height);
4275 unsigned char *p = raster;
4276 for (r = 0; r < height; r++)
4277 {
4278 /* priming a WHITE background */
4279 for (c = 0; c < width; c++)
4280 *p++ = 255;
4281 }
4282 for (j = 1; j < 256; j++)
4283 {
4284 /* computing optimal height */
4285 double value = *(band->histogram + j);
4286 count += value;
4287 if (max < value)
4288 max = value;
4289 }
4290 scale = 1.0 / (max / count);
4291 for (j = 1; j < 256; j++)
4292 {
4293 /* drawing the histogram */
4294 double freq = *(band->histogram + j);
4295 double high = (height - 32.0) * scale * freq / count;
4296 r = (j - 1) * 2;
4297 for (c = 0, h = height - 32; c < high; c++, h--)
4298 {
4299 p = raster + (h * width) + r;
4300 *p++ = 128;
4301 *p = 128;
4302 }
4303 }
4304 for (j = 1; j < 256; j++)
4305 {
4306 /* drawing the scale-bar */
4307 r = (j - 1) * 2;
4308 for (c = 0, h = height - 1; c < 25; c++, h--)
4309 {
4310 p = raster + (h * width) + r;
4311 *p++ = j;
4312 *p = j;
4313 }
4314 }
4315 if (rl2_data_to_png
4316 (raster, NULL, 1.0, NULL, width, height, RL2_SAMPLE_UINT8,
4317 RL2_PIXEL_GRAYSCALE, image, image_sz) == RL2_OK)
4318 return RL2_OK;
4319 free (raster);
4320 return RL2_ERROR;
4321 }
4322
4323 RL2_PRIVATE int
set_coverage_infos(sqlite3 * sqlite,const char * coverage_name,const char * title,const char * abstract)4324 set_coverage_infos (sqlite3 * sqlite, const char *coverage_name,
4325 const char *title, const char *abstract)
4326 {
4327 /* auxiliary function: updates the Coverage descriptive infos */
4328 int ret;
4329 const char *sql;
4330 sqlite3_stmt *stmt;
4331 int exists = 0;
4332 int retval = 0;
4333
4334 /* checking if the Group already exists */
4335 sql = "SELECT coverage_name FROM raster_coverages "
4336 "WHERE coverage_name = Lower(?)";
4337 ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
4338 if (ret != SQLITE_OK)
4339 {
4340 fprintf (stderr, "SetCoverageInfos: \"%s\"\n",
4341 sqlite3_errmsg (sqlite));
4342 goto stop;
4343 }
4344 sqlite3_reset (stmt);
4345 sqlite3_clear_bindings (stmt);
4346 sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
4347 SQLITE_STATIC);
4348 while (1)
4349 {
4350 /* scrolling the result set rows */
4351 ret = sqlite3_step (stmt);
4352 if (ret == SQLITE_DONE)
4353 break; /* end of result set */
4354 if (ret == SQLITE_ROW)
4355 exists = 1;
4356 }
4357 sqlite3_finalize (stmt);
4358
4359 if (!exists)
4360 return 0;
4361 /* update Coverage */
4362 sql =
4363 "UPDATE raster_coverages SET title = ?, abstract = ? WHERE coverage_name = ?";
4364 ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
4365 if (ret != SQLITE_OK)
4366 {
4367 fprintf (stderr, "SetCoverageInfos: \"%s\"\n",
4368 sqlite3_errmsg (sqlite));
4369 goto stop;
4370 }
4371 sqlite3_reset (stmt);
4372 sqlite3_clear_bindings (stmt);
4373 sqlite3_bind_text (stmt, 1, title, strlen (title), SQLITE_STATIC);
4374 sqlite3_bind_text (stmt, 2, abstract, strlen (abstract), SQLITE_STATIC);
4375 sqlite3_bind_text (stmt, 3, coverage_name, strlen (coverage_name),
4376 SQLITE_STATIC);
4377 ret = sqlite3_step (stmt);
4378 if (ret == SQLITE_DONE || ret == SQLITE_ROW)
4379 retval = 1;
4380 else
4381 fprintf (stderr, "SetCoverageInfos() error: \"%s\"\n",
4382 sqlite3_errmsg (sqlite));
4383 sqlite3_finalize (stmt);
4384 return retval;
4385 stop:
4386 return 0;
4387 }
4388
4389 RL2_PRIVATE int
rl2_test_layer_group(sqlite3 * handle,const char * name)4390 rl2_test_layer_group (sqlite3 * handle, const char *name)
4391 {
4392 /* testing for an eventual Layer Group */
4393 int ret;
4394 char **results;
4395 int rows;
4396 int columns;
4397 int i;
4398 int ok = 0;
4399 /* testing if Layer Group exists */
4400 char *sql = sqlite3_mprintf ("SELECT group_name FROM SE_styled_groups "
4401 "WHERE Lower(group_name) = Lower(%Q)", name);
4402 ret = sqlite3_get_table (handle, sql, &results, &rows, &columns, NULL);
4403 sqlite3_free (sql);
4404 if (ret != SQLITE_OK)
4405 return 0;
4406 for (i = 1; i <= rows; i++)
4407 ok = 1;
4408 sqlite3_free_table (results);
4409 return ok;
4410 }
4411