1 /*
2 
3  rl2import -- DBMS import functions
4 
5  version 0.1, 2014 January 9
6 
7  Author: Sandro Furieri a.furieri@lqt.it
8 
9  -----------------------------------------------------------------------------
10 
11  Version: MPL 1.1/GPL 2.0/LGPL 2.1
12 
13  The contents of this file are subject to the Mozilla Public License Version
14  1.1 (the "License"); you may not use this file except in compliance with
15  the License. You may obtain a copy of the License at
16  http://www.mozilla.org/MPL/
17 
18 Software distributed under the License is distributed on an "AS IS" basis,
19 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
20 for the specific language governing rights and limitations under the
21 License.
22 
23 The Original Code is the SpatiaLite library
24 
25 The Initial Developer of the Original Code is Alessandro Furieri
26 
27 Portions created by the Initial Developer are Copyright (C) 2008-2013
28 the Initial Developer. All Rights Reserved.
29 
30 Alternatively, the contents of this file may be used under the terms of
31 either the GNU General Public License Version 2 or later (the "GPL"), or
32 the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
33 in which case the provisions of the GPL or the LGPL are applicable instead
34 of those above. If you wish to allow use of your version of this file only
35 under the terms of either the GPL or the LGPL, and not to allow others to
36 use your version of this file under the terms of the MPL, indicate your
37 decision by deleting the provisions above and replace them with the notice
38 and other provisions required by the GPL or the LGPL. If you do not delete
39 the provisions above, a recipient may use your version of this file under
40 the terms of any one of the MPL, the GPL or the LGPL.
41 
42 */
43 
44 #include <stdlib.h>
45 #include <stdio.h>
46 #include <string.h>
47 #include <float.h>
48 
49 #include <sys/types.h>
50 #if defined(_WIN32) && !defined(__MINGW32__)
51 #include <io.h>
52 #include <direct.h>
53 #else
54 #include <dirent.h>
55 #endif
56 
57 #include "config.h"
58 
59 #ifdef LOADABLE_EXTENSION
60 #include "rasterlite2/sqlite.h"
61 #endif
62 
63 #include "rasterlite2/rasterlite2.h"
64 #include "rasterlite2/rl2tiff.h"
65 #include "rasterlite2/rl2graphics.h"
66 #include "rasterlite2_private.h"
67 
68 #include <spatialite/gaiaaux.h>
69 
70 static char *
formatFloat(double value)71 formatFloat (double value)
72 {
73 /* nicely formatting a float value */
74     int i;
75     int len;
76     char *fmt = sqlite3_mprintf ("%1.24f", value);
77     len = strlen (fmt);
78     for (i = len - 1; i >= 0; i--)
79       {
80 	  if (fmt[i] == '0')
81 	      fmt[i] = '\0';
82 	  else
83 	      break;
84       }
85     len = strlen (fmt);
86     if (fmt[len - 1] == '.')
87 	fmt[len] = '0';
88     return fmt;
89 }
90 
91 static char *
formatFloat2(double value)92 formatFloat2 (double value)
93 {
94 /* nicely formatting a float value (2 decimals) */
95     char *fmt = sqlite3_mprintf ("%1.2f", value);
96     return fmt;
97 }
98 
99 static char *
formatFloat6(double value)100 formatFloat6 (double value)
101 {
102 /* nicely formatting a float value (6 decimals) */
103     char *fmt = sqlite3_mprintf ("%1.2f", value);
104     return fmt;
105 }
106 
107 static char *
formatLong(double value)108 formatLong (double value)
109 {
110 /* nicely formatting a Longitude */
111     if (value >= -180.0 && value <= 180.0)
112 	return formatFloat6 (value);
113     return formatFloat2 (value);
114 }
115 
116 static char *
formatLat(double value)117 formatLat (double value)
118 {
119 /* nicely formatting a Latitude */
120     if (value >= -90.0 && value <= 90.0)
121 	return formatFloat6 (value);
122     return formatFloat2 (value);
123 }
124 
125 static int
do_insert_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)126 do_insert_tile (sqlite3 * handle, unsigned char *blob_odd, int blob_odd_sz,
127 		unsigned char *blob_even, int blob_even_sz,
128 		sqlite3_int64 section_id, int srid, double res_x, double res_y,
129 		unsigned int tile_w, unsigned int tile_h, double miny,
130 		double maxx, double *tile_minx, double *tile_miny,
131 		double *tile_maxx, double *tile_maxy, rl2PalettePtr aux_palette,
132 		rl2PixelPtr no_data, sqlite3_stmt * stmt_tils,
133 		sqlite3_stmt * stmt_data, rl2RasterStatisticsPtr section_stats)
134 {
135 /* INSERTing the tile */
136     int ret;
137     sqlite3_int64 tile_id;
138     unsigned char *blob;
139     int blob_size;
140     gaiaGeomCollPtr geom;
141     rl2RasterStatisticsPtr stats = NULL;
142 
143     stats = rl2_get_raster_statistics
144 	(blob_odd, blob_odd_sz, blob_even, blob_even_sz, aux_palette, no_data);
145     if (stats == NULL)
146 	goto error;
147     rl2_aggregate_raster_statistics (stats, section_stats);
148     sqlite3_reset (stmt_tils);
149     sqlite3_clear_bindings (stmt_tils);
150     sqlite3_bind_int64 (stmt_tils, 1, section_id);
151     *tile_maxx = *tile_minx + ((double) tile_w * res_x);
152     if (*tile_maxx > maxx)
153 	*tile_maxx = maxx;
154     *tile_miny = *tile_maxy - ((double) tile_h * res_y);
155     if (*tile_miny < miny)
156 	*tile_miny = miny;
157     geom = build_extent (srid, *tile_minx, *tile_miny, *tile_maxx, *tile_maxy);
158     gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
159     gaiaFreeGeomColl (geom);
160     sqlite3_bind_blob (stmt_tils, 2, blob, blob_size, free);
161     ret = sqlite3_step (stmt_tils);
162     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
163 	;
164     else
165       {
166 	  fprintf (stderr,
167 		   "INSERT INTO tiles; sqlite3_step() error: %s\n",
168 		   sqlite3_errmsg (handle));
169 	  goto error;
170       }
171     tile_id = sqlite3_last_insert_rowid (handle);
172     /* INSERTing tile data */
173     sqlite3_reset (stmt_data);
174     sqlite3_clear_bindings (stmt_data);
175     sqlite3_bind_int64 (stmt_data, 1, tile_id);
176     sqlite3_bind_blob (stmt_data, 2, blob_odd, blob_odd_sz, free);
177     if (blob_even == NULL)
178 	sqlite3_bind_null (stmt_data, 3);
179     else
180 	sqlite3_bind_blob (stmt_data, 3, blob_even, blob_even_sz, free);
181     ret = sqlite3_step (stmt_data);
182     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
183 	;
184     else
185       {
186 	  fprintf (stderr,
187 		   "INSERT INTO tile_data; sqlite3_step() error: %s\n",
188 		   sqlite3_errmsg (handle));
189 	  goto error;
190       }
191     rl2_destroy_raster_statistics (stats);
192     return 1;
193   error:
194     if (stats != NULL)
195 	rl2_destroy_raster_statistics (stats);
196     return 0;
197 }
198 
199 RL2_PRIVATE void
compute_aggregate_sq_diff(rl2RasterStatisticsPtr section_stats)200 compute_aggregate_sq_diff (rl2RasterStatisticsPtr section_stats)
201 {
202 /* updating aggregate sum_sq_diff */
203     int ib;
204     rl2PoolVariancePtr pV;
205     rl2PrivBandStatisticsPtr st_band;
206     rl2PrivRasterStatisticsPtr st = (rl2PrivRasterStatisticsPtr) section_stats;
207     if (st == NULL)
208 	return;
209 
210     for (ib = 0; ib < st->nBands; ib++)
211       {
212 	  double sum_var = 0.0;
213 	  st_band = st->band_stats + ib;
214 	  pV = st_band->first;
215 	  while (pV != NULL)
216 	    {
217 		sum_var += (pV->count - 1.0) * pV->variance;
218 		pV = pV->next;
219 	    }
220 	  st_band->sum_sq_diff = sum_var;
221       }
222 }
223 
224 static int
do_import_ascii_grid(sqlite3 * handle,const char * src_path,rl2CoveragePtr cvg,const char * section,int srid,unsigned int tile_w,unsigned int tile_h,int pyramidize,unsigned char sample_type,unsigned char compression,sqlite3_stmt * stmt_data,sqlite3_stmt * stmt_tils,sqlite3_stmt * stmt_sect,sqlite3_stmt * stmt_levl,sqlite3_stmt * stmt_upd_sect)225 do_import_ascii_grid (sqlite3 * handle, const char *src_path,
226 		      rl2CoveragePtr cvg, const char *section, int srid,
227 		      unsigned int tile_w, unsigned int tile_h,
228 		      int pyramidize, unsigned char sample_type,
229 		      unsigned char compression, sqlite3_stmt * stmt_data,
230 		      sqlite3_stmt * stmt_tils, sqlite3_stmt * stmt_sect,
231 		      sqlite3_stmt * stmt_levl, sqlite3_stmt * stmt_upd_sect)
232 {
233 /* importing an ASCII Data Grid file */
234     int ret;
235     rl2AsciiGridOriginPtr origin = NULL;
236     rl2RasterPtr raster = NULL;
237     rl2RasterStatisticsPtr section_stats = NULL;
238     rl2PixelPtr no_data = NULL;
239     unsigned int row;
240     unsigned int col;
241     unsigned int width;
242     unsigned int height;
243     unsigned char *blob_odd = NULL;
244     unsigned char *blob_even = NULL;
245     int blob_odd_sz;
246     int blob_even_sz;
247     double tile_minx;
248     double tile_miny;
249     double tile_maxx;
250     double tile_maxy;
251     double minx;
252     double miny;
253     double maxx;
254     double maxy;
255     double res_x;
256     double res_y;
257     double base_res_x;
258     double base_res_y;
259     char *dumb1;
260     char *dumb2;
261     sqlite3_int64 section_id;
262 
263     if (rl2_get_coverage_resolution (cvg, &base_res_x, &base_res_y) != RL2_OK)
264 	goto error;
265     origin = rl2_create_ascii_grid_origin (src_path, srid, sample_type);
266     if (origin == NULL)
267 	goto error;
268 
269     printf ("Importing: %s\n", rl2_get_ascii_grid_origin_path (origin));
270     printf ("------------------\n");
271     ret = rl2_get_ascii_grid_origin_size (origin, &width, &height);
272     if (ret == RL2_OK)
273 	printf ("    Image Size (pixels): %d x %d\n", width, height);
274     ret = rl2_get_ascii_grid_origin_srid (origin, &srid);
275     if (ret == RL2_OK)
276 	printf ("                   SRID: %d\n", srid);
277     ret = rl2_get_ascii_grid_origin_extent (origin, &minx, &miny, &maxx, &maxy);
278     if (ret == RL2_OK)
279       {
280 	  dumb1 = formatLong (minx);
281 	  dumb2 = formatLat (miny);
282 	  printf ("       LowerLeft Corner: X=%s Y=%s\n", dumb1, dumb2);
283 	  sqlite3_free (dumb1);
284 	  sqlite3_free (dumb2);
285 	  dumb1 = formatLong (maxx);
286 	  dumb2 = formatLat (maxy);
287 	  printf ("      UpperRight Corner: X=%s Y=%s\n", dumb1, dumb2);
288 	  sqlite3_free (dumb1);
289 	  sqlite3_free (dumb2);
290       }
291     ret = rl2_get_ascii_grid_origin_resolution (origin, &res_x, &res_y);
292     if (ret == RL2_OK)
293       {
294 	  dumb1 = formatFloat (res_x);
295 	  dumb2 = formatFloat (res_y);
296 	  printf ("       Pixel resolution: X=%s Y=%s\n", dumb1, dumb2);
297 	  sqlite3_free (dumb1);
298 	  sqlite3_free (dumb2);
299       }
300 
301     if (rl2_eval_ascii_grid_origin_compatibility (cvg, origin) != RL2_TRUE)
302       {
303 	  fprintf (stderr, "Coverage/ASCII mismatch\n");
304 	  goto error;
305       }
306     no_data = rl2_get_coverage_no_data (cvg);
307 
308 /* INSERTing the section */
309     if (!do_insert_section
310 	(handle, src_path, section, srid, width, height, minx, miny, maxx, maxy,
311 	 stmt_sect, &section_id))
312 	goto error;
313     section_stats = rl2_create_raster_statistics (sample_type, 1);
314     if (section_stats == NULL)
315 	goto error;
316 /* INSERTing the base-levels */
317     if (!do_insert_levels
318 	(handle, base_res_x, base_res_y, 1.0, sample_type, stmt_levl))
319 	goto error;
320 
321     tile_maxy = maxy;
322     for (row = 0; row < height; row += tile_h)
323       {
324 	  tile_minx = minx;
325 	  for (col = 0; col < width; col += tile_w)
326 	    {
327 		raster =
328 		    rl2_get_tile_from_ascii_grid_origin (cvg, origin, row, col);
329 		if (raster == NULL)
330 		  {
331 		      fprintf (stderr,
332 			       "ERROR: unable to get a tile [Row=%d Col=%d]\n",
333 			       row, col);
334 		      goto error;
335 		  }
336 		if (rl2_raster_encode
337 		    (raster, compression, &blob_odd, &blob_odd_sz, &blob_even,
338 		     &blob_even_sz, 100, 1) != RL2_OK)
339 		  {
340 		      fprintf (stderr,
341 			       "ERROR: unable to encode a tile [Row=%d Col=%d]\n",
342 			       row, col);
343 		      goto error;
344 		  }
345 
346 		/* INSERTing the tile */
347 		if (!do_insert_tile
348 		    (handle, blob_odd, blob_odd_sz, blob_even, blob_even_sz,
349 		     section_id, srid, res_x, res_y, tile_w, tile_h, miny,
350 		     maxx, &tile_minx, &tile_miny, &tile_maxx, &tile_maxy,
351 		     NULL, no_data, stmt_tils, stmt_data, section_stats))
352 		    goto error;
353 		blob_odd = NULL;
354 		blob_even = NULL;
355 		rl2_destroy_raster (raster);
356 		raster = NULL;
357 		tile_minx += (double) tile_w *res_x;
358 	    }
359 	  tile_maxy -= (double) tile_h *res_y;
360       }
361 
362 /* updating the Section's Statistics */
363     compute_aggregate_sq_diff (section_stats);
364     if (!do_insert_stats (handle, section_stats, section_id, stmt_upd_sect))
365 	goto error;
366 
367     rl2_destroy_ascii_grid_origin (origin);
368     rl2_destroy_raster_statistics (section_stats);
369     origin = NULL;
370     section_stats = NULL;
371 
372     if (pyramidize)
373       {
374 	  /* immediately building the Section's Pyramid */
375 	  const char *coverage_name = rl2_get_coverage_name (cvg);
376 	  const char *section_name = section;
377 	  char *sect_name = NULL;
378 	  if (coverage_name == NULL)
379 	      goto error;
380 	  if (section_name == NULL)
381 	    {
382 		sect_name = get_section_name (src_path);
383 		section_name = sect_name;
384 	    }
385 	  if (section_name == NULL)
386 	      goto error;
387 	  if (rl2_build_section_pyramid (handle, coverage_name, section_name, 1)
388 	      != RL2_OK)
389 	    {
390 		if (sect_name != NULL)
391 		    free (sect_name);
392 		fprintf (stderr, "unable to build the Section's Pyramid\n");
393 		goto error;
394 	    }
395 	  if (sect_name != NULL)
396 	      free (sect_name);
397       }
398 
399     return 1;
400 
401   error:
402     if (blob_odd != NULL)
403 	free (blob_odd);
404     if (blob_even != NULL)
405 	free (blob_even);
406     if (origin != NULL)
407 	rl2_destroy_ascii_grid_origin (origin);
408     if (raster != NULL)
409 	rl2_destroy_raster (raster);
410     if (section_stats != NULL)
411 	rl2_destroy_raster_statistics (section_stats);
412     return 0;
413 }
414 
415 static int
check_jpeg_origin_compatibility(rl2RasterPtr raster,rl2CoveragePtr coverage,unsigned int * width,unsigned int * height,unsigned char * forced_conversion)416 check_jpeg_origin_compatibility (rl2RasterPtr raster, rl2CoveragePtr coverage,
417 				 unsigned int *width, unsigned int *height,
418 				 unsigned char *forced_conversion)
419 {
420 /* checking if the JPEG and the Coverage are mutually compatible */
421     rl2PrivRasterPtr rst = (rl2PrivRasterPtr) raster;
422     rl2PrivCoveragePtr cvg = (rl2PrivCoveragePtr) coverage;
423     if (rst == NULL || cvg == NULL)
424 	return 0;
425     if (rst->sampleType == RL2_SAMPLE_UINT8
426 	&& rst->pixelType == RL2_PIXEL_GRAYSCALE && rst->nBands == 1)
427       {
428 	  if (cvg->sampleType == RL2_SAMPLE_UINT8
429 	      && cvg->pixelType == RL2_PIXEL_GRAYSCALE && cvg->nBands == 1)
430 	    {
431 		*width = rst->width;
432 		*height = rst->height;
433 		*forced_conversion = RL2_CONVERT_NO;
434 		return 1;
435 	    }
436 	  if (cvg->sampleType == RL2_SAMPLE_UINT8
437 	      && cvg->pixelType == RL2_PIXEL_RGB && cvg->nBands == 3)
438 	    {
439 		*width = rst->width;
440 		*height = rst->height;
441 		*forced_conversion = RL2_CONVERT_GRAYSCALE_TO_RGB;
442 		return 1;
443 	    }
444       }
445     if (rst->sampleType == RL2_SAMPLE_UINT8 && rst->pixelType == RL2_PIXEL_RGB
446 	&& rst->nBands == 3)
447       {
448 	  if (cvg->sampleType == RL2_SAMPLE_UINT8
449 	      && cvg->pixelType == RL2_PIXEL_RGB && cvg->nBands == 3)
450 	    {
451 		*width = rst->width;
452 		*height = rst->height;
453 		*forced_conversion = RL2_CONVERT_NO;
454 		return 1;
455 	    }
456 	  if (cvg->sampleType == RL2_SAMPLE_UINT8
457 	      && cvg->pixelType == RL2_PIXEL_GRAYSCALE && cvg->nBands == 1)
458 	    {
459 		*width = rst->width;
460 		*height = rst->height;
461 		*forced_conversion = RL2_CONVERT_RGB_TO_GRAYSCALE;
462 		return 1;
463 	    }
464       }
465     return 0;
466 }
467 
468 static char *
build_worldfile_path(const char * path,const char * suffix)469 build_worldfile_path (const char *path, const char *suffix)
470 {
471 /* building the JGW path (WorldFile) */
472     char *wf_path;
473     const char *x = NULL;
474     const char *p = path;
475     int len;
476 
477     if (path == NULL || suffix == NULL)
478 	return NULL;
479     len = strlen (path);
480     len -= 1;
481     while (*p != '\0')
482       {
483 	  if (*p == '.')
484 	      x = p;
485 	  p++;
486       }
487     if (x > path)
488 	len = x - path;
489     wf_path = malloc (len + strlen (suffix) + 1);
490     memcpy (wf_path, path, len);
491     strcpy (wf_path + len, suffix);
492     return wf_path;
493 }
494 
495 static int
read_jgw_worldfile(const char * src_path,double * minx,double * maxy,double * pres_x,double * pres_y)496 read_jgw_worldfile (const char *src_path, double *minx, double *maxy,
497 		    double *pres_x, double *pres_y)
498 {
499 /* attempting to retrieve georeferencing from a JPEG+JGW origin */
500     FILE *jgw = NULL;
501     double res_x;
502     double res_y;
503     double x;
504     double y;
505     char *jgw_path = NULL;
506 
507     jgw_path = build_worldfile_path (src_path, ".jgw");
508     if (jgw_path == NULL)
509 	goto error;
510     jgw = fopen (jgw_path, "r");
511     free (jgw_path);
512     jgw_path = NULL;
513     if (jgw == NULL)
514 	goto error;
515     if (!parse_worldfile (jgw, &x, &y, &res_x, &res_y))
516 	goto error;
517     fclose (jgw);
518     *pres_x = res_x;
519     *pres_y = res_y;
520     *minx = x;
521     *maxy = y;
522     return 1;
523 
524   error:
525     if (jgw_path != NULL)
526 	free (jgw_path);
527     if (jgw != NULL)
528 	fclose (jgw);
529     return 0;
530 }
531 
532 static void
write_jgw_worldfile(const char * path,double minx,double maxy,double x_res,double y_res)533 write_jgw_worldfile (const char *path, double minx, double maxy, double x_res,
534 		     double y_res)
535 {
536 /* exporting a JGW WorldFile */
537     FILE *jgw = NULL;
538     char *jgw_path = NULL;
539 
540     jgw_path = build_worldfile_path (path, ".jgw");
541     if (jgw_path == NULL)
542 	goto error;
543     jgw = fopen (jgw_path, "w");
544     free (jgw_path);
545     jgw_path = NULL;
546     if (jgw == NULL)
547 	goto error;
548     fprintf (jgw, "        %1.16f\n", x_res);
549     fprintf (jgw, "        0.0\n");
550     fprintf (jgw, "        0.0\n");
551     fprintf (jgw, "        -%1.16f\n", y_res);
552     fprintf (jgw, "        %1.16f\n", minx);
553     fprintf (jgw, "        %1.16f\n", maxy);
554     fclose (jgw);
555     return;
556 
557   error:
558     if (jgw_path != NULL)
559 	free (jgw_path);
560     if (jgw != NULL)
561 	fclose (jgw);
562 }
563 
564 static int
do_import_jpeg_image(sqlite3 * handle,const char * src_path,rl2CoveragePtr cvg,const char * section,int srid,unsigned int tile_w,unsigned int tile_h,int pyramidize,unsigned char sample_type,unsigned char num_bands,unsigned char compression,sqlite3_stmt * stmt_data,sqlite3_stmt * stmt_tils,sqlite3_stmt * stmt_sect,sqlite3_stmt * stmt_levl,sqlite3_stmt * stmt_upd_sect)565 do_import_jpeg_image (sqlite3 * handle, const char *src_path,
566 		      rl2CoveragePtr cvg, const char *section, int srid,
567 		      unsigned int tile_w, unsigned int tile_h,
568 		      int pyramidize, unsigned char sample_type,
569 		      unsigned char num_bands, unsigned char compression,
570 		      sqlite3_stmt * stmt_data, sqlite3_stmt * stmt_tils,
571 		      sqlite3_stmt * stmt_sect, sqlite3_stmt * stmt_levl,
572 		      sqlite3_stmt * stmt_upd_sect)
573 {
574 /* importing a JPEG image file [with optional WorldFile */
575     rl2SectionPtr origin;
576     rl2RasterPtr rst_in;
577     rl2RasterPtr raster = NULL;
578     rl2RasterStatisticsPtr section_stats = NULL;
579     rl2PixelPtr no_data = NULL;
580     unsigned int row;
581     unsigned int col;
582     unsigned int width;
583     unsigned int height;
584     unsigned char *blob_odd = NULL;
585     unsigned char *blob_even = NULL;
586     int blob_odd_sz;
587     int blob_even_sz;
588     double tile_minx;
589     double tile_miny;
590     double tile_maxx;
591     double tile_maxy;
592     double minx;
593     double miny;
594     double maxx;
595     double maxy;
596     double res_x;
597     double res_y;
598     char *dumb1;
599     char *dumb2;
600     sqlite3_int64 section_id;
601     unsigned char forced_conversion = RL2_CONVERT_NO;
602     double base_res_x;
603     double base_res_y;
604 
605     if (rl2_get_coverage_resolution (cvg, &base_res_x, &base_res_y) != RL2_OK)
606 	goto error;
607     origin = rl2_section_from_jpeg (src_path);
608     if (origin == NULL)
609 	goto error;
610     rst_in = rl2_get_section_raster (origin);
611     if (!check_jpeg_origin_compatibility
612 	(rst_in, cvg, &width, &height, &forced_conversion))
613 	goto error;
614     if (read_jgw_worldfile (src_path, &minx, &maxy, &res_x, &res_y))
615       {
616 	  /* georeferenced JPEG */
617 	  maxx = minx + ((double) width * res_x);
618 	  miny = maxy - ((double) height * res_y);
619       }
620     else
621       {
622 	  /* not georeferenced JPEG */
623 	  if (srid != -1)
624 	      goto error;
625 	  minx = 0.0;
626 	  miny = 0.0;
627 	  maxx = width - 1.0;
628 	  maxy = height - 1.0;
629 	  res_x = 1.0;
630 	  res_y = 1.0;
631       }
632 
633     printf ("Importing: %s\n", src_path);
634     printf ("------------------\n");
635     printf ("    Image Size (pixels): %d x %d\n", width, height);
636     printf ("                   SRID: %d\n", srid);
637     dumb1 = formatLong (minx);
638     dumb2 = formatLat (miny);
639     printf ("       LowerLeft Corner: X=%s Y=%s\n", dumb1, dumb2);
640     sqlite3_free (dumb1);
641     sqlite3_free (dumb2);
642     dumb1 = formatLong (maxx);
643     dumb2 = formatLat (maxy);
644     printf ("      UpperRight Corner: X=%s Y=%s\n", dumb1, dumb2);
645     sqlite3_free (dumb1);
646     sqlite3_free (dumb2);
647     dumb1 = formatFloat (res_x);
648     dumb2 = formatFloat (res_y);
649     printf ("       Pixel resolution: X=%s Y=%s\n", dumb1, dumb2);
650     sqlite3_free (dumb1);
651     sqlite3_free (dumb2);
652 
653     no_data = rl2_get_coverage_no_data (cvg);
654 
655 /* INSERTing the section */
656     if (!do_insert_section
657 	(handle, src_path, section, srid, width, height, minx, miny, maxx, maxy,
658 	 stmt_sect, &section_id))
659 	goto error;
660     section_stats = rl2_create_raster_statistics (sample_type, num_bands);
661     if (section_stats == NULL)
662 	goto error;
663 /* INSERTing the base-levels */
664     if (!do_insert_levels
665 	(handle, base_res_x, base_res_y, 1.0, sample_type, stmt_levl))
666 	goto error;
667 
668     tile_maxy = maxy;
669     for (row = 0; row < height; row += tile_h)
670       {
671 	  tile_minx = minx;
672 	  for (col = 0; col < width; col += tile_w)
673 	    {
674 		raster =
675 		    rl2_get_tile_from_jpeg_origin (cvg, rst_in, row, col,
676 						   forced_conversion);
677 		if (raster == NULL)
678 		  {
679 		      fprintf (stderr,
680 			       "ERROR: unable to get a tile [Row=%d Col=%d]\n",
681 			       row, col);
682 		      goto error;
683 		  }
684 		if (rl2_raster_encode
685 		    (raster, compression, &blob_odd, &blob_odd_sz, &blob_even,
686 		     &blob_even_sz, 100, 1) != RL2_OK)
687 		  {
688 		      fprintf (stderr,
689 			       "ERROR: unable to encode a tile [Row=%d Col=%d]\n",
690 			       row, col);
691 		      goto error;
692 		  }
693 
694 		/* INSERTing the tile */
695 		if (!do_insert_tile
696 		    (handle, blob_odd, blob_odd_sz, blob_even, blob_even_sz,
697 		     section_id, srid, res_x, res_y, tile_w, tile_h, miny,
698 		     maxx, &tile_minx, &tile_miny, &tile_maxx, &tile_maxy,
699 		     NULL, no_data, stmt_tils, stmt_data, section_stats))
700 		    goto error;
701 		blob_odd = NULL;
702 		blob_even = NULL;
703 		rl2_destroy_raster (raster);
704 		raster = NULL;
705 		tile_minx += (double) tile_w *res_x;
706 	    }
707 	  tile_maxy -= (double) tile_h *res_y;
708       }
709 
710 /* updating the Section's Statistics */
711     compute_aggregate_sq_diff (section_stats);
712     if (!do_insert_stats (handle, section_stats, section_id, stmt_upd_sect))
713 	goto error;
714 
715     rl2_destroy_section (origin);
716     rl2_destroy_raster_statistics (section_stats);
717     origin = NULL;
718     section_stats = NULL;
719 
720     if (pyramidize)
721       {
722 	  /* immediately building the Section's Pyramid */
723 	  const char *coverage_name = rl2_get_coverage_name (cvg);
724 	  const char *section_name = section;
725 	  char *sect_name = NULL;
726 	  if (coverage_name == NULL)
727 	      goto error;
728 	  if (section_name == NULL)
729 	    {
730 		sect_name = get_section_name (src_path);
731 		section_name = sect_name;
732 	    }
733 	  if (section_name == NULL)
734 	      goto error;
735 	  if (rl2_build_section_pyramid (handle, coverage_name, section_name, 1)
736 	      != RL2_OK)
737 	    {
738 		if (sect_name != NULL)
739 		    free (sect_name);
740 		fprintf (stderr, "unable to build the Section's Pyramid\n");
741 		goto error;
742 	    }
743 	  if (sect_name != NULL)
744 	      free (sect_name);
745       }
746 
747     return 1;
748 
749   error:
750     if (blob_odd != NULL)
751 	free (blob_odd);
752     if (blob_even != NULL)
753 	free (blob_even);
754     if (origin != NULL)
755 	rl2_destroy_section (origin);
756     if (raster != NULL)
757 	rl2_destroy_raster (raster);
758     if (section_stats != NULL)
759 	rl2_destroy_raster_statistics (section_stats);
760     return 0;
761 }
762 
763 static int
is_ascii_grid(const char * path)764 is_ascii_grid (const char *path)
765 {
766 /* testing for an ASCII Grid */
767     int len = strlen (path);
768     if (len > 4)
769       {
770 	  if (strcasecmp (path + len - 4, ".asc") == 0)
771 	      return 1;
772       }
773     return 0;
774 }
775 
776 static int
is_jpeg_image(const char * path)777 is_jpeg_image (const char *path)
778 {
779 /* testing for a JPEG image */
780     int len = strlen (path);
781     if (len > 4)
782       {
783 	  if (strcasecmp (path + len - 4, ".jpg") == 0)
784 	      return 1;
785       }
786     return 0;
787 }
788 
789 static int
do_import_file(sqlite3 * handle,const char * src_path,rl2CoveragePtr cvg,const char * section,int worldfile,int force_srid,int pyramidize,unsigned char sample_type,unsigned char pixel_type,unsigned char num_bands,unsigned int tile_w,unsigned int tile_h,unsigned char compression,int quality,sqlite3_stmt * stmt_data,sqlite3_stmt * stmt_tils,sqlite3_stmt * stmt_sect,sqlite3_stmt * stmt_levl,sqlite3_stmt * stmt_upd_sect)790 do_import_file (sqlite3 * handle, const char *src_path,
791 		rl2CoveragePtr cvg, const char *section, int worldfile,
792 		int force_srid, int pyramidize, unsigned char sample_type,
793 		unsigned char pixel_type, unsigned char num_bands,
794 		unsigned int tile_w, unsigned int tile_h,
795 		unsigned char compression, int quality,
796 		sqlite3_stmt * stmt_data, sqlite3_stmt * stmt_tils,
797 		sqlite3_stmt * stmt_sect, sqlite3_stmt * stmt_levl,
798 		sqlite3_stmt * stmt_upd_sect)
799 {
800 /* importing a single Source file */
801     int ret;
802     rl2TiffOriginPtr origin = NULL;
803     rl2RasterPtr raster = NULL;
804     rl2PalettePtr aux_palette = NULL;
805     rl2RasterStatisticsPtr section_stats = NULL;
806     rl2PixelPtr no_data = NULL;
807     unsigned int row;
808     unsigned int col;
809     unsigned int width;
810     unsigned int height;
811     unsigned char *blob_odd = NULL;
812     unsigned char *blob_even = NULL;
813     int blob_odd_sz;
814     int blob_even_sz;
815     int srid;
816     int xsrid;
817     double tile_minx;
818     double tile_miny;
819     double tile_maxx;
820     double tile_maxy;
821     double minx;
822     double miny;
823     double maxx;
824     double maxy;
825     double res_x;
826     double res_y;
827     char *dumb1;
828     char *dumb2;
829     sqlite3_int64 section_id;
830     double base_res_x;
831     double base_res_y;
832 
833     if (is_ascii_grid (src_path))
834 	return do_import_ascii_grid (handle, src_path, cvg, section, force_srid,
835 				     tile_w, tile_h, pyramidize, sample_type,
836 				     compression, stmt_data, stmt_tils,
837 				     stmt_sect, stmt_levl, stmt_upd_sect);
838 
839     if (is_jpeg_image (src_path))
840 	return do_import_jpeg_image (handle, src_path, cvg, section, force_srid,
841 				     tile_w, tile_h, pyramidize, sample_type,
842 				     num_bands, compression, stmt_data,
843 				     stmt_tils, stmt_sect, stmt_levl,
844 				     stmt_upd_sect);
845 
846     if (rl2_get_coverage_resolution (cvg, &base_res_x, &base_res_y) != RL2_OK)
847 	goto error;
848     if (worldfile)
849 	origin =
850 	    rl2_create_tiff_origin (src_path, RL2_TIFF_WORLDFILE, force_srid,
851 				    sample_type, pixel_type, num_bands);
852     else
853 	origin =
854 	    rl2_create_tiff_origin (src_path, RL2_TIFF_GEOTIFF, force_srid,
855 				    sample_type, pixel_type, num_bands);
856     if (origin == NULL)
857 	goto error;
858     if (rl2_get_coverage_srid (cvg, &xsrid) == RL2_OK)
859       {
860 	  if (xsrid == RL2_GEOREFERENCING_NONE)
861 	      rl2_set_tiff_origin_not_referenced (origin);
862       }
863 
864     printf ("Importing: %s\n", rl2_get_tiff_origin_path (origin));
865     printf ("------------------\n");
866     ret = rl2_get_tiff_origin_size (origin, &width, &height);
867     if (ret == RL2_OK)
868 	printf ("    Image Size (pixels): %d x %d\n", width, height);
869     ret = rl2_get_tiff_origin_srid (origin, &srid);
870     if (ret == RL2_OK)
871       {
872 	  if (force_srid > 0 && force_srid != srid)
873 	    {
874 		printf ("                   SRID: %d (forced to %d)\n", srid,
875 			force_srid);
876 		srid = force_srid;
877 	    }
878 	  else
879 	      printf ("                   SRID: %d\n", srid);
880       }
881     ret = rl2_get_tiff_origin_extent (origin, &minx, &miny, &maxx, &maxy);
882     if (ret == RL2_OK)
883       {
884 	  dumb1 = formatLong (minx);
885 	  dumb2 = formatLat (miny);
886 	  printf ("       LowerLeft Corner: X=%s Y=%s\n", dumb1, dumb2);
887 	  sqlite3_free (dumb1);
888 	  sqlite3_free (dumb2);
889 	  dumb1 = formatLong (maxx);
890 	  dumb2 = formatLat (maxy);
891 	  printf ("      UpperRight Corner: X=%s Y=%s\n", dumb1, dumb2);
892 	  sqlite3_free (dumb1);
893 	  sqlite3_free (dumb2);
894       }
895     ret = rl2_get_tiff_origin_resolution (origin, &res_x, &res_y);
896     if (ret == RL2_OK)
897       {
898 	  dumb1 = formatFloat (res_x);
899 	  dumb2 = formatFloat (res_y);
900 	  printf ("       Pixel resolution: X=%s Y=%s\n", dumb1, dumb2);
901 	  sqlite3_free (dumb1);
902 	  sqlite3_free (dumb2);
903       }
904 
905     if (pixel_type == RL2_PIXEL_PALETTE)
906       {
907 	  /* remapping the Palette */
908 	  if (rl2_check_dbms_palette (handle, cvg, origin) != RL2_OK)
909 	    {
910 		fprintf (stderr, "Mismatching Palette !!!\n");
911 		goto error;
912 	    }
913       }
914 
915     if (rl2_eval_tiff_origin_compatibility (cvg, origin, force_srid) !=
916 	RL2_TRUE)
917       {
918 	  fprintf (stderr, "Coverage/TIFF mismatch\n");
919 	  goto error;
920       }
921     no_data = rl2_get_coverage_no_data (cvg);
922 
923 /* INSERTing the section */
924     if (!do_insert_section
925 	(handle, src_path, section, srid, width, height, minx, miny, maxx, maxy,
926 	 stmt_sect, &section_id))
927 	goto error;
928     section_stats = rl2_create_raster_statistics (sample_type, num_bands);
929     if (section_stats == NULL)
930 	goto error;
931 /* INSERTing the base-levels */
932     if (!do_insert_levels
933 	(handle, base_res_x, base_res_y, 1.0, sample_type, stmt_levl))
934 	goto error;
935 
936     tile_maxy = maxy;
937     for (row = 0; row < height; row += tile_h)
938       {
939 	  tile_minx = minx;
940 	  for (col = 0; col < width; col += tile_w)
941 	    {
942 		raster =
943 		    rl2_get_tile_from_tiff_origin (cvg, origin, row, col, srid);
944 		if (raster == NULL)
945 		  {
946 		      fprintf (stderr,
947 			       "ERROR: unable to get a tile [Row=%d Col=%d]\n",
948 			       row, col);
949 		      goto error;
950 		  }
951 		if (rl2_raster_encode
952 		    (raster, compression, &blob_odd, &blob_odd_sz, &blob_even,
953 		     &blob_even_sz, quality, 1) != RL2_OK)
954 		  {
955 		      fprintf (stderr,
956 			       "ERROR: unable to encode a tile [Row=%d Col=%d]\n",
957 			       row, col);
958 		      goto error;
959 		  }
960 		/* INSERTing the tile */
961 		aux_palette =
962 		    rl2_clone_palette (rl2_get_raster_palette (raster));
963 
964 		if (!do_insert_tile
965 		    (handle, blob_odd, blob_odd_sz, blob_even, blob_even_sz,
966 		     section_id, srid, res_x, res_y, tile_w, tile_h, miny,
967 		     maxx, &tile_minx, &tile_miny, &tile_maxx, &tile_maxy,
968 		     aux_palette, no_data, stmt_tils, stmt_data, section_stats))
969 		    goto error;
970 		blob_odd = NULL;
971 		blob_even = NULL;
972 		rl2_destroy_raster (raster);
973 		raster = NULL;
974 		tile_minx += (double) tile_w *res_x;
975 	    }
976 	  tile_maxy -= (double) tile_h *res_y;
977       }
978 
979 /* updating the Section's Statistics */
980     compute_aggregate_sq_diff (section_stats);
981     if (!do_insert_stats (handle, section_stats, section_id, stmt_upd_sect))
982 	goto error;
983 
984     rl2_destroy_tiff_origin (origin);
985     rl2_destroy_raster_statistics (section_stats);
986     origin = NULL;
987     section_stats = NULL;
988 
989     if (pyramidize)
990       {
991 	  /* immediately building the Section's Pyramid */
992 	  const char *coverage_name = rl2_get_coverage_name (cvg);
993 	  const char *section_name = section;
994 	  char *sect_name = NULL;
995 	  if (coverage_name == NULL)
996 	      goto error;
997 	  if (section_name == NULL)
998 	    {
999 		sect_name = get_section_name (src_path);
1000 		section_name = sect_name;
1001 	    }
1002 	  if (section_name == NULL)
1003 	      goto error;
1004 	  if (rl2_build_section_pyramid (handle, coverage_name, section_name, 1)
1005 	      != RL2_OK)
1006 	    {
1007 		if (sect_name != NULL)
1008 		    free (sect_name);
1009 		fprintf (stderr, "unable to build the Section's Pyramid\n");
1010 		goto error;
1011 	    }
1012 	  if (sect_name != NULL)
1013 	      free (sect_name);
1014       }
1015 
1016     return 1;
1017 
1018   error:
1019     if (blob_odd != NULL)
1020 	free (blob_odd);
1021     if (blob_even != NULL)
1022 	free (blob_even);
1023     if (origin != NULL)
1024 	rl2_destroy_tiff_origin (origin);
1025     if (raster != NULL)
1026 	rl2_destroy_raster (raster);
1027     if (section_stats != NULL)
1028 	rl2_destroy_raster_statistics (section_stats);
1029     return 0;
1030 }
1031 
1032 static int
check_extension_match(const char * file_name,const char * file_ext)1033 check_extension_match (const char *file_name, const char *file_ext)
1034 {
1035 /* checks the file extension */
1036     const char *mark = NULL;
1037     const char *p = file_name;
1038     int len;
1039     char *ext;
1040     int match = 0;
1041     if (file_ext == NULL)
1042 	return 0;
1043 
1044     len = strlen (file_ext);
1045     if (*file_ext == '.')
1046       {
1047 	  /* file extension starts with dot */
1048 	  ext = malloc (len + 1);
1049 	  strcpy (ext, file_ext);
1050       }
1051     else
1052       {
1053 	  /* file extension doesn't start with dot */
1054 	  ext = malloc (len + 2);
1055 	  *ext = '.';
1056 	  strcpy (ext + 1, file_ext);
1057       }
1058     while (*p != '\0')
1059       {
1060 	  if (*p == '.')
1061 	      mark = p;
1062 	  p++;
1063       }
1064     if (mark == NULL)
1065       {
1066 	  free (ext);
1067 	  return 0;
1068       }
1069     match = strcasecmp (mark, ext);
1070     free (ext);
1071     if (match == 0)
1072 	return 1;
1073     return 0;
1074 }
1075 
1076 static int
do_import_dir(sqlite3 * handle,const char * dir_path,const char * file_ext,rl2CoveragePtr cvg,const char * section,int worldfile,int force_srid,int pyramidize,unsigned char sample_type,unsigned char pixel_type,unsigned char num_bands,unsigned int tile_w,unsigned int tile_h,unsigned char compression,int quality,sqlite3_stmt * stmt_data,sqlite3_stmt * stmt_tils,sqlite3_stmt * stmt_sect,sqlite3_stmt * stmt_levl,sqlite3_stmt * stmt_upd_sect)1077 do_import_dir (sqlite3 * handle, const char *dir_path, const char *file_ext,
1078 	       rl2CoveragePtr cvg, const char *section, int worldfile,
1079 	       int force_srid, int pyramidize, unsigned char sample_type,
1080 	       unsigned char pixel_type, unsigned char num_bands,
1081 	       unsigned int tile_w, unsigned int tile_h,
1082 	       unsigned char compression, int quality, sqlite3_stmt * stmt_data,
1083 	       sqlite3_stmt * stmt_tils, sqlite3_stmt * stmt_sect,
1084 	       sqlite3_stmt * stmt_levl, sqlite3_stmt * stmt_upd_sect)
1085 {
1086 /* importing a whole directory */
1087 #if defined(_WIN32) && !defined(__MINGW32__)
1088 /* Visual Studio .NET */
1089     struct _finddata_t c_file;
1090     intptr_t hFile;
1091     int cnt = 0;
1092     char *search;
1093     char *path;
1094     int ret;
1095     if (_chdir (dir_path) < 0)
1096 	return 0;
1097     search = sqlite3_mprintf ("*%s", file_ext);
1098     if ((hFile = _findfirst (search, &c_file)) == -1L)
1099 	;
1100     else
1101       {
1102 	  while (1)
1103 	    {
1104 		if ((c_file.attrib & _A_RDONLY) == _A_RDONLY
1105 		    || (c_file.attrib & _A_NORMAL) == _A_NORMAL)
1106 		  {
1107 		      path = sqlite3_mprintf ("%s/%s", dir_path, c_file.name);
1108 		      ret =
1109 			  do_import_file (handle, path, cvg, section, worldfile,
1110 					  force_srid, pyramidize, sample_type,
1111 					  pixel_type, num_bands, tile_w, tile_h,
1112 					  compression, quality, stmt_data,
1113 					  stmt_tils, stmt_sect, stmt_levl,
1114 					  stmt_upd_sect);
1115 		      sqlite3_free (path);
1116 		      if (!ret)
1117 			  goto error;
1118 		      cnt++;
1119 		  }
1120 		if (_findnext (hFile, &c_file) != 0)
1121 		    break;
1122 	    };
1123 	error:
1124 	  _findclose (hFile);
1125       }
1126     sqlite3_free (search);
1127     return cnt;
1128 #else
1129 /* not Visual Studio .NET */
1130     int cnt = 0;
1131     char *path;
1132     struct dirent *entry;
1133     int ret;
1134     DIR *dir = opendir (dir_path);
1135     if (!dir)
1136 	return 0;
1137     while (1)
1138       {
1139 	  /* scanning dir-entries */
1140 	  entry = readdir (dir);
1141 	  if (!entry)
1142 	      break;
1143 	  if (!check_extension_match (entry->d_name, file_ext))
1144 	      continue;
1145 	  path = sqlite3_mprintf ("%s/%s", dir_path, entry->d_name);
1146 	  ret =
1147 	      do_import_file (handle, path, cvg, section, worldfile, force_srid,
1148 			      pyramidize, sample_type, pixel_type, num_bands,
1149 			      tile_w, tile_h, compression, quality, stmt_data,
1150 			      stmt_tils, stmt_sect, stmt_levl, stmt_upd_sect);
1151 	  sqlite3_free (path);
1152 	  if (!ret)
1153 	      goto error;
1154 	  cnt++;
1155       }
1156   error:
1157     closedir (dir);
1158     return cnt;
1159 #endif
1160 }
1161 
1162 static int
do_import_common(sqlite3 * handle,const char * src_path,const char * dir_path,const char * file_ext,rl2CoveragePtr cvg,const char * section,int worldfile,int force_srid,int pyramidize)1163 do_import_common (sqlite3 * handle, const char *src_path, const char *dir_path,
1164 		  const char *file_ext, rl2CoveragePtr cvg, const char *section,
1165 		  int worldfile, int force_srid, int pyramidize)
1166 {
1167 /* main IMPORT Raster function */
1168     int ret;
1169     char *sql;
1170     const char *coverage;
1171     unsigned char sample_type;
1172     unsigned char pixel_type;
1173     unsigned char num_bands;
1174     unsigned int tile_w;
1175     unsigned int tile_h;
1176     unsigned char compression;
1177     int quality;
1178     char *table;
1179     char *xtable;
1180     unsigned int tileWidth;
1181     unsigned int tileHeight;
1182     sqlite3_stmt *stmt_data = NULL;
1183     sqlite3_stmt *stmt_tils = NULL;
1184     sqlite3_stmt *stmt_sect = NULL;
1185     sqlite3_stmt *stmt_levl = NULL;
1186     sqlite3_stmt *stmt_upd_sect = NULL;
1187 
1188     if (cvg == NULL)
1189 	goto error;
1190 
1191     if (rl2_get_coverage_tile_size (cvg, &tileWidth, &tileHeight) != RL2_OK)
1192 	goto error;
1193 
1194     tile_w = tileWidth;
1195     tile_h = tileHeight;
1196     rl2_get_coverage_compression (cvg, &compression, &quality);
1197     rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands);
1198     coverage = rl2_get_coverage_name (cvg);
1199 
1200     table = sqlite3_mprintf ("%s_sections", coverage);
1201     xtable = gaiaDoubleQuotedSql (table);
1202     sqlite3_free (table);
1203     sql =
1204 	sqlite3_mprintf
1205 	("INSERT INTO \"%s\" (section_id, section_name, file_path, "
1206 	 "width, height, geometry) VALUES (NULL, ?, ?, ?, ?, ?)", xtable);
1207     free (xtable);
1208     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_sect, NULL);
1209     sqlite3_free (sql);
1210     if (ret != SQLITE_OK)
1211       {
1212 	  printf ("INSERT INTO sections SQL error: %s\n",
1213 		  sqlite3_errmsg (handle));
1214 	  goto error;
1215       }
1216 
1217     table = sqlite3_mprintf ("%s_sections", coverage);
1218     xtable = gaiaDoubleQuotedSql (table);
1219     sqlite3_free (table);
1220     sql =
1221 	sqlite3_mprintf
1222 	("UPDATE \"%s\" SET statistics = ? WHERE section_id = ?", xtable);
1223     free (xtable);
1224     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_upd_sect, NULL);
1225     sqlite3_free (sql);
1226     if (ret != SQLITE_OK)
1227       {
1228 	  printf ("UPDATE sections SQL error: %s\n", sqlite3_errmsg (handle));
1229 	  goto error;
1230       }
1231 
1232     table = sqlite3_mprintf ("%s_levels", coverage);
1233     xtable = gaiaDoubleQuotedSql (table);
1234     sqlite3_free (table);
1235     sql =
1236 	sqlite3_mprintf
1237 	("INSERT OR IGNORE INTO \"%s\" (pyramid_level, "
1238 	 "x_resolution_1_1, y_resolution_1_1, "
1239 	 "x_resolution_1_2, y_resolution_1_2, x_resolution_1_4, "
1240 	 "y_resolution_1_4, x_resolution_1_8, y_resolution_1_8) "
1241 	 "VALUES (0, ?, ?, ?, ?, ?, ?, ?, ?)", xtable);
1242     free (xtable);
1243     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_levl, NULL);
1244     sqlite3_free (sql);
1245     if (ret != SQLITE_OK)
1246       {
1247 	  printf ("INSERT INTO levels SQL error: %s\n",
1248 		  sqlite3_errmsg (handle));
1249 	  goto error;
1250       }
1251 
1252     table = sqlite3_mprintf ("%s_tiles", coverage);
1253     xtable = gaiaDoubleQuotedSql (table);
1254     sqlite3_free (table);
1255     sql =
1256 	sqlite3_mprintf
1257 	("INSERT INTO \"%s\" (tile_id, pyramid_level, section_id, geometry) "
1258 	 "VALUES (NULL, 0, ?, ?)", xtable);
1259     free (xtable);
1260     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_tils, NULL);
1261     sqlite3_free (sql);
1262     if (ret != SQLITE_OK)
1263       {
1264 	  printf ("INSERT INTO tiles SQL error: %s\n", sqlite3_errmsg (handle));
1265 	  goto error;
1266       }
1267 
1268     table = sqlite3_mprintf ("%s_tile_data", coverage);
1269     xtable = gaiaDoubleQuotedSql (table);
1270     sqlite3_free (table);
1271     sql =
1272 	sqlite3_mprintf
1273 	("INSERT INTO \"%s\" (tile_id, tile_data_odd, tile_data_even) "
1274 	 "VALUES (?, ?, ?)", xtable);
1275     free (xtable);
1276     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_data, NULL);
1277     sqlite3_free (sql);
1278     if (ret != SQLITE_OK)
1279       {
1280 	  printf ("INSERT INTO tile_data SQL error: %s\n",
1281 		  sqlite3_errmsg (handle));
1282 	  goto error;
1283       }
1284 
1285     if (dir_path == NULL)
1286       {
1287 	  /* importing a single Image file */
1288 	  if (!do_import_file
1289 	      (handle, src_path, cvg, section, worldfile, force_srid,
1290 	       pyramidize, sample_type, pixel_type, num_bands, tile_w, tile_h,
1291 	       compression, quality, stmt_data, stmt_tils, stmt_sect,
1292 	       stmt_levl, stmt_upd_sect))
1293 	      goto error;
1294       }
1295     else
1296       {
1297 	  /* importing all Image files from a whole directory */
1298 	  if (!do_import_dir
1299 	      (handle, dir_path, file_ext, cvg, section, worldfile, force_srid,
1300 	       pyramidize, sample_type, pixel_type, num_bands, tile_w, tile_h,
1301 	       compression, quality, stmt_data, stmt_tils, stmt_sect,
1302 	       stmt_levl, stmt_upd_sect))
1303 	      goto error;
1304       }
1305 
1306     sqlite3_finalize (stmt_upd_sect);
1307     sqlite3_finalize (stmt_sect);
1308     sqlite3_finalize (stmt_levl);
1309     sqlite3_finalize (stmt_tils);
1310     sqlite3_finalize (stmt_data);
1311     stmt_upd_sect = NULL;
1312     stmt_sect = NULL;
1313     stmt_levl = NULL;
1314     stmt_tils = NULL;
1315     stmt_data = NULL;
1316 
1317     if (rl2_update_dbms_coverage (handle, coverage) != RL2_OK)
1318       {
1319 	  fprintf (stderr, "unable to update the Coverage\n");
1320 	  goto error;
1321       }
1322 
1323     return 1;
1324 
1325   error:
1326     if (stmt_upd_sect != NULL)
1327 	sqlite3_finalize (stmt_upd_sect);
1328     if (stmt_sect != NULL)
1329 	sqlite3_finalize (stmt_sect);
1330     if (stmt_levl != NULL)
1331 	sqlite3_finalize (stmt_levl);
1332     if (stmt_tils != NULL)
1333 	sqlite3_finalize (stmt_tils);
1334     if (stmt_data != NULL)
1335 	sqlite3_finalize (stmt_data);
1336     return 0;
1337 }
1338 
1339 RL2_DECLARE int
rl2_load_raster_into_dbms(sqlite3 * handle,const char * src_path,rl2CoveragePtr coverage,int worldfile,int force_srid,int pyramidize)1340 rl2_load_raster_into_dbms (sqlite3 * handle, const char *src_path,
1341 			   rl2CoveragePtr coverage, int worldfile,
1342 			   int force_srid, int pyramidize)
1343 {
1344 /* importing a single Raster file */
1345     if (!do_import_common
1346 	(handle, src_path, NULL, NULL, coverage, NULL, worldfile, force_srid,
1347 	 pyramidize))
1348 	return RL2_ERROR;
1349     return RL2_OK;
1350 }
1351 
1352 RL2_DECLARE int
rl2_load_mrasters_into_dbms(sqlite3 * handle,const char * dir_path,const char * file_ext,rl2CoveragePtr coverage,int worldfile,int force_srid,int pyramidize)1353 rl2_load_mrasters_into_dbms (sqlite3 * handle, const char *dir_path,
1354 			     const char *file_ext,
1355 			     rl2CoveragePtr coverage, int worldfile,
1356 			     int force_srid, int pyramidize)
1357 {
1358 /* importing multiple Raster files from dir */
1359     if (!do_import_common
1360 	(handle, NULL, dir_path, file_ext, coverage, NULL, worldfile,
1361 	 force_srid, pyramidize))
1362 	return RL2_ERROR;
1363     return RL2_OK;
1364 }
1365 
1366 static int
mismatching_size(unsigned int width,unsigned int height,double x_res,double y_res,double minx,double miny,double maxx,double maxy)1367 mismatching_size (unsigned int width, unsigned int height, double x_res,
1368 		  double y_res, double minx, double miny, double maxx,
1369 		  double maxy)
1370 {
1371 /* checking if the image size and the map extent do match */
1372     double ext_x = (double) width * x_res;
1373     double ext_y = (double) height * y_res;
1374     double img_x = maxx - minx;
1375     double img_y = maxy = miny;
1376     double confidence;
1377     confidence = ext_x / 100.0;
1378     if (img_x < (ext_x - confidence) || img_x > (ext_x + confidence))
1379 	return 0;
1380     confidence = ext_y / 100.0;
1381     if (img_y < (ext_y - confidence) || img_y > (ext_y + confidence))
1382 	return 0;
1383     return 1;
1384 }
1385 
1386 static void
copy_int8_outbuf_to_tile(const char * outbuf,char * tile,unsigned int width,unsigned int height,unsigned int tile_width,unsigned int tile_height,unsigned int base_y,unsigned int base_x)1387 copy_int8_outbuf_to_tile (const char *outbuf, char *tile,
1388 			  unsigned int width,
1389 			  unsigned int height,
1390 			  unsigned int tile_width,
1391 			  unsigned int tile_height, unsigned int base_y,
1392 			  unsigned int base_x)
1393 {
1394 /* copying INT8 pixels from the output buffer into the tile */
1395     unsigned int x;
1396     unsigned int y;
1397     const char *p_in;
1398     char *p_out = tile;
1399 
1400     for (y = 0; y < tile_height; y++)
1401       {
1402 	  if ((base_y + y) >= height)
1403 	      break;
1404 	  p_in = outbuf + ((base_y + y) * width) + base_x;
1405 	  for (x = 0; x < tile_width; x++)
1406 	    {
1407 		if ((base_x + x) >= width)
1408 		  {
1409 		      p_out++;
1410 		      p_in++;
1411 		      continue;
1412 		  }
1413 		*p_out++ = *p_in++;
1414 	    }
1415       }
1416 }
1417 
1418 static void
copy_uint8_outbuf_to_tile(const unsigned char * outbuf,unsigned char * tile,unsigned char num_bands,unsigned int width,unsigned int height,unsigned int tile_width,unsigned int tile_height,unsigned int base_y,unsigned int base_x)1419 copy_uint8_outbuf_to_tile (const unsigned char *outbuf, unsigned char *tile,
1420 			   unsigned char num_bands, unsigned int width,
1421 			   unsigned int height,
1422 			   unsigned int tile_width,
1423 			   unsigned int tile_height, unsigned int base_y,
1424 			   unsigned int base_x)
1425 {
1426 /* copying UINT8 pixels from the output buffer into the tile */
1427     unsigned int x;
1428     unsigned int y;
1429     int b;
1430     const unsigned char *p_in;
1431     unsigned char *p_out = tile;
1432 
1433     for (y = 0; y < tile_height; y++)
1434       {
1435 	  if ((base_y + y) >= height)
1436 	      break;
1437 	  p_in =
1438 	      outbuf + ((base_y + y) * width * num_bands) +
1439 	      (base_x * num_bands);
1440 	  for (x = 0; x < tile_width; x++)
1441 	    {
1442 		if ((base_x + x) >= width)
1443 		  {
1444 		      p_out += num_bands;
1445 		      p_in += num_bands;
1446 		      continue;
1447 		  }
1448 		for (b = 0; b < num_bands; b++)
1449 		    *p_out++ = *p_in++;
1450 	    }
1451       }
1452 }
1453 
1454 static void
copy_int16_outbuf_to_tile(const short * outbuf,short * tile,unsigned int width,unsigned int height,unsigned int tile_width,unsigned int tile_height,unsigned int base_y,unsigned int base_x)1455 copy_int16_outbuf_to_tile (const short *outbuf, short *tile,
1456 			   unsigned int width,
1457 			   unsigned int height,
1458 			   unsigned int tile_width,
1459 			   unsigned int tile_height, unsigned int base_y,
1460 			   unsigned int base_x)
1461 {
1462 /* copying INT16 pixels from the output buffer into the tile */
1463     unsigned int x;
1464     unsigned int y;
1465     const short *p_in;
1466     short *p_out = tile;
1467 
1468     for (y = 0; y < tile_height; y++)
1469       {
1470 	  if ((base_y + y) >= height)
1471 	      break;
1472 	  p_in = outbuf + ((base_y + y) * width) + base_x;
1473 	  for (x = 0; x < tile_width; x++)
1474 	    {
1475 		if ((base_x + x) >= width)
1476 		  {
1477 		      p_out++;
1478 		      p_in++;
1479 		      continue;
1480 		  }
1481 		*p_out++ = *p_in++;
1482 	    }
1483       }
1484 }
1485 
1486 static void
copy_uint16_outbuf_to_tile(const unsigned short * outbuf,unsigned short * tile,unsigned char num_bands,unsigned int width,unsigned int height,unsigned int tile_width,unsigned int tile_height,unsigned int base_y,unsigned int base_x)1487 copy_uint16_outbuf_to_tile (const unsigned short *outbuf, unsigned short *tile,
1488 			    unsigned char num_bands, unsigned int width,
1489 			    unsigned int height,
1490 			    unsigned int tile_width,
1491 			    unsigned int tile_height, unsigned int base_y,
1492 			    unsigned int base_x)
1493 {
1494 /* copying UINT16 pixels from the output buffer into the tile */
1495     unsigned int x;
1496     unsigned int y;
1497     int b;
1498     const unsigned short *p_in;
1499     unsigned short *p_out = tile;
1500 
1501     for (y = 0; y < tile_height; y++)
1502       {
1503 	  if ((base_y + y) >= height)
1504 	      break;
1505 	  p_in =
1506 	      outbuf + ((base_y + y) * width * num_bands) +
1507 	      (base_x * num_bands);
1508 	  for (x = 0; x < tile_width; x++)
1509 	    {
1510 		if ((base_x + x) >= width)
1511 		  {
1512 		      p_out += num_bands;
1513 		      p_in += num_bands;
1514 		      continue;
1515 		  }
1516 		for (b = 0; b < num_bands; b++)
1517 		    *p_out++ = *p_in++;
1518 	    }
1519       }
1520 }
1521 
1522 static void
copy_int32_outbuf_to_tile(const int * outbuf,int * tile,unsigned int width,unsigned int height,unsigned int tile_width,unsigned int tile_height,unsigned int base_y,unsigned int base_x)1523 copy_int32_outbuf_to_tile (const int *outbuf, int *tile,
1524 			   unsigned int width,
1525 			   unsigned int height,
1526 			   unsigned int tile_width,
1527 			   unsigned int tile_height, unsigned int base_y,
1528 			   unsigned int base_x)
1529 {
1530 /* copying INT32 pixels from the output buffer into the tile */
1531     unsigned int x;
1532     unsigned int y;
1533     const int *p_in;
1534     int *p_out = tile;
1535 
1536     for (y = 0; y < tile_height; y++)
1537       {
1538 	  if ((base_y + y) >= height)
1539 	      break;
1540 	  p_in = outbuf + ((base_y + y) * width) + base_x;
1541 	  for (x = 0; x < tile_width; x++)
1542 	    {
1543 		if ((base_x + x) >= width)
1544 		  {
1545 		      p_out++;
1546 		      p_in++;
1547 		      continue;
1548 		  }
1549 		*p_out++ = *p_in++;
1550 	    }
1551       }
1552 }
1553 
1554 static void
copy_uint32_outbuf_to_tile(const unsigned int * outbuf,unsigned int * tile,unsigned int width,unsigned int height,unsigned int tile_width,unsigned int tile_height,int base_y,int base_x)1555 copy_uint32_outbuf_to_tile (const unsigned int *outbuf, unsigned int *tile,
1556 			    unsigned int width,
1557 			    unsigned int height,
1558 			    unsigned int tile_width,
1559 			    unsigned int tile_height, int base_y, int base_x)
1560 {
1561 /* copying UINT32 pixels from the output buffer into the tile */
1562     unsigned int x;
1563     unsigned int y;
1564     const unsigned int *p_in;
1565     unsigned int *p_out = tile;
1566 
1567     for (y = 0; y < tile_height; y++)
1568       {
1569 	  if ((base_y + y) >= height)
1570 	      break;
1571 	  p_in = outbuf + ((base_y + y) * width) + base_x;
1572 	  for (x = 0; x < tile_width; x++)
1573 	    {
1574 		if ((base_x + x) >= width)
1575 		  {
1576 		      p_out++;
1577 		      p_in++;
1578 		      continue;
1579 		  }
1580 		*p_out++ = *p_in++;
1581 	    }
1582       }
1583 }
1584 
1585 static void
copy_float_outbuf_to_tile(const float * outbuf,float * tile,unsigned int width,unsigned int height,unsigned int tile_width,unsigned int tile_height,unsigned int base_y,unsigned int base_x)1586 copy_float_outbuf_to_tile (const float *outbuf, float *tile,
1587 			   unsigned int width,
1588 			   unsigned int height,
1589 			   unsigned int tile_width,
1590 			   unsigned int tile_height, unsigned int base_y,
1591 			   unsigned int base_x)
1592 {
1593 /* copying FLOAT pixels from the output buffer into the tile */
1594     unsigned int x;
1595     unsigned int y;
1596     const float *p_in;
1597     float *p_out = tile;
1598 
1599     for (y = 0; y < tile_height; y++)
1600       {
1601 	  if ((base_y + y) >= height)
1602 	      break;
1603 	  p_in = outbuf + ((base_y + y) * width) + base_x;
1604 	  for (x = 0; x < tile_width; x++)
1605 	    {
1606 		if ((base_x + x) >= width)
1607 		  {
1608 		      p_out++;
1609 		      p_in++;
1610 		      continue;
1611 		  }
1612 		*p_out++ = *p_in++;
1613 	    }
1614       }
1615 }
1616 
1617 static void
copy_double_outbuf_to_tile(const double * outbuf,double * tile,unsigned int width,unsigned int height,unsigned int tile_width,unsigned int tile_height,unsigned int base_y,unsigned int base_x)1618 copy_double_outbuf_to_tile (const double *outbuf, double *tile,
1619 			    unsigned int width,
1620 			    unsigned int height,
1621 			    unsigned int tile_width,
1622 			    unsigned int tile_height, unsigned int base_y,
1623 			    unsigned int base_x)
1624 {
1625 /* copying DOUBLE pixels from the output buffer into the tile */
1626     unsigned int x;
1627     unsigned int y;
1628     const double *p_in;
1629     double *p_out = tile;
1630 
1631     for (y = 0; y < tile_height; y++)
1632       {
1633 	  if ((base_y + y) >= height)
1634 	      break;
1635 	  p_in = outbuf + ((base_y + y) * width) + base_x;
1636 	  for (x = 0; x < tile_width; x++)
1637 	    {
1638 		if ((base_x + x) >= width)
1639 		  {
1640 		      p_out++;
1641 		      p_in++;
1642 		      continue;
1643 		  }
1644 		*p_out++ = *p_in++;
1645 	    }
1646       }
1647 }
1648 
1649 static void
copy_from_outbuf_to_tile(const unsigned char * outbuf,unsigned char * tile,unsigned char sample_type,unsigned char num_bands,unsigned int width,unsigned int height,unsigned int tile_width,unsigned int tile_height,unsigned int base_y,unsigned int base_x)1650 copy_from_outbuf_to_tile (const unsigned char *outbuf, unsigned char *tile,
1651 			  unsigned char sample_type, unsigned char num_bands,
1652 			  unsigned int width, unsigned int height,
1653 			  unsigned int tile_width, unsigned int tile_height,
1654 			  unsigned int base_y, unsigned int base_x)
1655 {
1656 /* copying pixels from the output buffer into the tile */
1657     switch (sample_type)
1658       {
1659       case RL2_SAMPLE_INT8:
1660 	  copy_int8_outbuf_to_tile ((char *) outbuf,
1661 				    (char *) tile, width, height, tile_width,
1662 				    tile_height, base_y, base_x);
1663 	  break;
1664       case RL2_SAMPLE_INT16:
1665 	  copy_int16_outbuf_to_tile ((short *) outbuf,
1666 				     (short *) tile, width, height, tile_width,
1667 				     tile_height, base_y, base_x);
1668 	  break;
1669       case RL2_SAMPLE_UINT16:
1670 	  copy_uint16_outbuf_to_tile ((unsigned short *) outbuf,
1671 				      (unsigned short *) tile, num_bands,
1672 				      width, height, tile_width, tile_height,
1673 				      base_y, base_x);
1674 	  break;
1675       case RL2_SAMPLE_INT32:
1676 	  copy_int32_outbuf_to_tile ((int *) outbuf,
1677 				     (int *) tile, width, height, tile_width,
1678 				     tile_height, base_y, base_x);
1679 	  break;
1680       case RL2_SAMPLE_UINT32:
1681 	  copy_uint32_outbuf_to_tile ((unsigned int *) outbuf,
1682 				      (unsigned int *) tile, width, height,
1683 				      tile_width, tile_height, base_y, base_x);
1684 	  break;
1685       case RL2_SAMPLE_FLOAT:
1686 	  copy_float_outbuf_to_tile ((float *) outbuf,
1687 				     (float *) tile, width, height, tile_width,
1688 				     tile_height, base_y, base_x);
1689 	  break;
1690       case RL2_SAMPLE_DOUBLE:
1691 	  copy_double_outbuf_to_tile ((double *) outbuf,
1692 				      (double *) tile, width, height,
1693 				      tile_width, tile_height, base_y, base_x);
1694 	  break;
1695       default:
1696 	  copy_uint8_outbuf_to_tile ((unsigned char *) outbuf,
1697 				     (unsigned char *) tile, num_bands, width,
1698 				     height, tile_width, tile_height, base_y,
1699 				     base_x);
1700 	  break;
1701       };
1702 }
1703 
1704 RL2_DECLARE int
rl2_export_geotiff_from_dbms(sqlite3 * handle,const char * dst_path,rl2CoveragePtr cvg,double x_res,double y_res,double minx,double miny,double maxx,double maxy,unsigned int width,unsigned int height,unsigned char compression,unsigned int tile_sz,int with_worldfile)1705 rl2_export_geotiff_from_dbms (sqlite3 * handle, const char *dst_path,
1706 			      rl2CoveragePtr cvg, double x_res, double y_res,
1707 			      double minx, double miny, double maxx,
1708 			      double maxy, unsigned int width,
1709 			      unsigned int height, unsigned char compression,
1710 			      unsigned int tile_sz, int with_worldfile)
1711 {
1712 /* exporting a GeoTIFF from the DBMS into the file-system */
1713     rl2RasterPtr raster = NULL;
1714     rl2PalettePtr palette = NULL;
1715     rl2PalettePtr plt2 = NULL;
1716     rl2TiffDestinationPtr tiff = NULL;
1717     rl2PixelPtr no_data = NULL;
1718     unsigned char level;
1719     unsigned char scale;
1720     double xx_res = x_res;
1721     double yy_res = y_res;
1722     unsigned char sample_type;
1723     unsigned char pixel_type;
1724     unsigned char num_bands;
1725     int srid;
1726     unsigned char *outbuf = NULL;
1727     int outbuf_size;
1728     unsigned char *bufpix = NULL;
1729     int bufpix_size;
1730     int pix_sz = 1;
1731     unsigned int base_x;
1732     unsigned int base_y;
1733 
1734     if (rl2_find_matching_resolution
1735 	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
1736 	return RL2_ERROR;
1737 
1738     if (mismatching_size
1739 	(width, height, xx_res, yy_res, minx, miny, maxx, maxy))
1740 	goto error;
1741 
1742     if (rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands) !=
1743 	RL2_OK)
1744 	goto error;
1745     if (rl2_get_coverage_srid (cvg, &srid) != RL2_OK)
1746 	goto error;
1747     no_data = rl2_get_coverage_no_data (cvg);
1748 
1749     if (level > 0)
1750       {
1751 	  /* special handling for Pyramid tiles */
1752 	  if (sample_type == RL2_SAMPLE_1_BIT
1753 	      && pixel_type == RL2_PIXEL_MONOCHROME && num_bands == 1)
1754 	    {
1755 		/* expecting a Grayscale/PNG Pyramid tile */
1756 		sample_type = RL2_SAMPLE_UINT8;
1757 		pixel_type = RL2_PIXEL_GRAYSCALE;
1758 		num_bands = 1;
1759 	    }
1760 	  if ((sample_type == RL2_SAMPLE_1_BIT
1761 	       && pixel_type == RL2_PIXEL_PALETTE && num_bands == 1) ||
1762 	      (sample_type == RL2_SAMPLE_2_BIT
1763 	       && pixel_type == RL2_PIXEL_PALETTE && num_bands == 1) ||
1764 	      (sample_type == RL2_SAMPLE_4_BIT
1765 	       && pixel_type == RL2_PIXEL_PALETTE && num_bands == 1))
1766 	    {
1767 		/* expecting an RGB/PNG Pyramid tile */
1768 		sample_type = RL2_SAMPLE_UINT8;
1769 		pixel_type = RL2_PIXEL_RGB;
1770 		num_bands = 3;
1771 	    }
1772       }
1773 
1774     if (rl2_get_raw_raster_data
1775 	(handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
1776 	 yy_res, &outbuf, &outbuf_size, &palette, pixel_type) != RL2_OK)
1777 	goto error;
1778 
1779 /* computing the sample size */
1780     switch (sample_type)
1781       {
1782       case RL2_SAMPLE_INT16:
1783       case RL2_SAMPLE_UINT16:
1784 	  pix_sz = 2;
1785 	  break;
1786       case RL2_SAMPLE_INT32:
1787       case RL2_SAMPLE_UINT32:
1788       case RL2_SAMPLE_FLOAT:
1789 	  pix_sz = 4;
1790 	  break;
1791       case RL2_SAMPLE_DOUBLE:
1792 	  pix_sz = 8;
1793 	  break;
1794       };
1795 
1796     tiff =
1797 	rl2_create_geotiff_destination (dst_path, handle, width, height,
1798 					sample_type, pixel_type, num_bands,
1799 					palette, compression, 1,
1800 					tile_sz, srid, minx, miny, maxx,
1801 					maxy, xx_res, yy_res, with_worldfile);
1802     if (tiff == NULL)
1803 	goto error;
1804     for (base_y = 0; base_y < height; base_y += tile_sz)
1805       {
1806 	  for (base_x = 0; base_x < width; base_x += tile_sz)
1807 	    {
1808 		/* exporting all tiles from the output buffer */
1809 		bufpix_size = pix_sz * num_bands * tile_sz * tile_sz;
1810 		bufpix = malloc (bufpix_size);
1811 		if (bufpix == NULL)
1812 		  {
1813 		      fprintf (stderr,
1814 			       "rl2tool Export: Insufficient Memory !!!\n");
1815 		      goto error;
1816 		  }
1817 		if (pixel_type == RL2_PIXEL_PALETTE && palette != NULL)
1818 		    rl2_prime_void_tile_palette (bufpix, tile_sz, tile_sz,
1819 						 no_data);
1820 		else
1821 		    rl2_prime_void_tile (bufpix, tile_sz, tile_sz, sample_type,
1822 					 num_bands, no_data);
1823 		copy_from_outbuf_to_tile (outbuf, bufpix, sample_type,
1824 					  num_bands, width, height, tile_sz,
1825 					  tile_sz, base_y, base_x);
1826 		plt2 = rl2_clone_palette (palette);
1827 		raster =
1828 		    rl2_create_raster (tile_sz, tile_sz, sample_type,
1829 				       pixel_type, num_bands, bufpix,
1830 				       bufpix_size, plt2, NULL, 0, NULL);
1831 		bufpix = NULL;
1832 		if (raster == NULL)
1833 		    goto error;
1834 		if (rl2_write_tiff_tile (tiff, raster, base_y, base_x) !=
1835 		    RL2_OK)
1836 		    goto error;
1837 		rl2_destroy_raster (raster);
1838 		raster = NULL;
1839 	    }
1840       }
1841 
1842     if (with_worldfile)
1843       {
1844 	  /* exporting the Worldfile */
1845 	  if (rl2_write_tiff_worldfile (tiff) != RL2_OK)
1846 	      goto error;
1847       }
1848 
1849     rl2_destroy_tiff_destination (tiff);
1850     if (palette != NULL)
1851 	rl2_destroy_palette (palette);
1852     free (outbuf);
1853     return RL2_OK;
1854 
1855   error:
1856     if (raster != NULL)
1857 	rl2_destroy_raster (raster);
1858     if (tiff != NULL)
1859 	rl2_destroy_tiff_destination (tiff);
1860     if (outbuf != NULL)
1861 	free (outbuf);
1862     if (bufpix != NULL)
1863 	free (bufpix);
1864     if (palette != NULL)
1865 	rl2_destroy_palette (palette);
1866     return RL2_ERROR;
1867 }
1868 
1869 RL2_DECLARE int
rl2_export_tiff_worldfile_from_dbms(sqlite3 * handle,const char * dst_path,rl2CoveragePtr cvg,double x_res,double y_res,double minx,double miny,double maxx,double maxy,unsigned int width,unsigned int height,unsigned char compression,unsigned int tile_sz)1870 rl2_export_tiff_worldfile_from_dbms (sqlite3 * handle, const char *dst_path,
1871 				     rl2CoveragePtr cvg, double x_res,
1872 				     double y_res, double minx, double miny,
1873 				     double maxx, double maxy,
1874 				     unsigned int width,
1875 				     unsigned int height,
1876 				     unsigned char compression,
1877 				     unsigned int tile_sz)
1878 {
1879 /* exporting a TIFF+TFW from the DBMS into the file-system */
1880     rl2RasterPtr raster = NULL;
1881     rl2PalettePtr palette = NULL;
1882     rl2PalettePtr plt2 = NULL;
1883     rl2PixelPtr no_data = NULL;
1884     rl2TiffDestinationPtr tiff = NULL;
1885     unsigned char level;
1886     unsigned char scale;
1887     double xx_res = x_res;
1888     double yy_res = y_res;
1889     unsigned char sample_type;
1890     unsigned char pixel_type;
1891     unsigned char num_bands;
1892     int srid;
1893     unsigned char *outbuf = NULL;
1894     int outbuf_size;
1895     unsigned char *bufpix = NULL;
1896     int bufpix_size;
1897     int pix_sz = 1;
1898     unsigned int base_x;
1899     unsigned int base_y;
1900 
1901     if (rl2_find_matching_resolution
1902 	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
1903 	return RL2_ERROR;
1904 
1905     if (mismatching_size
1906 	(width, height, xx_res, yy_res, minx, miny, maxx, maxy))
1907 	goto error;
1908 
1909     if (rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands) !=
1910 	RL2_OK)
1911 	goto error;
1912     if (rl2_get_coverage_srid (cvg, &srid) != RL2_OK)
1913 	goto error;
1914     no_data = rl2_get_coverage_no_data (cvg);
1915 
1916     if (level > 0)
1917       {
1918 	  /* special handling for Pyramid tiles */
1919 	  if (sample_type == RL2_SAMPLE_1_BIT
1920 	      && pixel_type == RL2_PIXEL_MONOCHROME && num_bands == 1)
1921 	    {
1922 		/* expecting a Grayscale/PNG Pyramid tile */
1923 		sample_type = RL2_SAMPLE_UINT8;
1924 		pixel_type = RL2_PIXEL_GRAYSCALE;
1925 		num_bands = 1;
1926 	    }
1927 	  if ((sample_type == RL2_SAMPLE_1_BIT
1928 	       && pixel_type == RL2_PIXEL_PALETTE && num_bands == 1) ||
1929 	      (sample_type == RL2_SAMPLE_2_BIT
1930 	       && pixel_type == RL2_PIXEL_PALETTE && num_bands == 1) ||
1931 	      (sample_type == RL2_SAMPLE_4_BIT
1932 	       && pixel_type == RL2_PIXEL_PALETTE && num_bands == 1))
1933 	    {
1934 		/* expecting an RGB/PNG Pyramid tile */
1935 		sample_type = RL2_SAMPLE_UINT8;
1936 		pixel_type = RL2_PIXEL_RGB;
1937 		num_bands = 3;
1938 	    }
1939       }
1940 
1941     if (rl2_get_raw_raster_data
1942 	(handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
1943 	 yy_res, &outbuf, &outbuf_size, &palette, pixel_type) != RL2_OK)
1944 	goto error;
1945 
1946 /* computing the sample size */
1947     switch (sample_type)
1948       {
1949       case RL2_SAMPLE_INT16:
1950       case RL2_SAMPLE_UINT16:
1951 	  pix_sz = 2;
1952 	  break;
1953       case RL2_SAMPLE_INT32:
1954       case RL2_SAMPLE_UINT32:
1955       case RL2_SAMPLE_FLOAT:
1956 	  pix_sz = 4;
1957 	  break;
1958       case RL2_SAMPLE_DOUBLE:
1959 	  pix_sz = 8;
1960 	  break;
1961       };
1962 
1963     tiff =
1964 	rl2_create_tiff_worldfile_destination (dst_path, width, height,
1965 					       sample_type, pixel_type,
1966 					       num_bands, palette, compression,
1967 					       1, tile_sz, srid, minx, miny,
1968 					       maxx, maxy, xx_res, yy_res);
1969     if (tiff == NULL)
1970 	goto error;
1971     for (base_y = 0; base_y < height; base_y += tile_sz)
1972       {
1973 	  for (base_x = 0; base_x < width; base_x += tile_sz)
1974 	    {
1975 		/* exporting all tiles from the output buffer */
1976 		bufpix_size = pix_sz * num_bands * tile_sz * tile_sz;
1977 		bufpix = malloc (bufpix_size);
1978 		if (bufpix == NULL)
1979 		  {
1980 		      fprintf (stderr,
1981 			       "rl2tool Export: Insufficient Memory !!!\n");
1982 		      goto error;
1983 		  }
1984 		if (pixel_type == RL2_PIXEL_PALETTE && palette != NULL)
1985 		    rl2_prime_void_tile_palette (bufpix, tile_sz, tile_sz,
1986 						 no_data);
1987 		else
1988 		    rl2_prime_void_tile (bufpix, tile_sz, tile_sz, sample_type,
1989 					 num_bands, no_data);
1990 		copy_from_outbuf_to_tile (outbuf, bufpix, sample_type,
1991 					  num_bands, width, height, tile_sz,
1992 					  tile_sz, base_y, base_x);
1993 		plt2 = rl2_clone_palette (palette);
1994 		raster =
1995 		    rl2_create_raster (tile_sz, tile_sz, sample_type,
1996 				       pixel_type, num_bands, bufpix,
1997 				       bufpix_size, plt2, NULL, 0, NULL);
1998 		bufpix = NULL;
1999 		if (raster == NULL)
2000 		    goto error;
2001 		if (rl2_write_tiff_tile (tiff, raster, base_y, base_x) !=
2002 		    RL2_OK)
2003 		    goto error;
2004 		rl2_destroy_raster (raster);
2005 		raster = NULL;
2006 	    }
2007       }
2008 
2009 /* exporting the Worldfile */
2010     if (rl2_write_tiff_worldfile (tiff) != RL2_OK)
2011 	goto error;
2012 
2013     rl2_destroy_tiff_destination (tiff);
2014     if (palette != NULL)
2015 	rl2_destroy_palette (palette);
2016     free (outbuf);
2017     return RL2_OK;
2018 
2019   error:
2020     if (raster != NULL)
2021 	rl2_destroy_raster (raster);
2022     if (tiff != NULL)
2023 	rl2_destroy_tiff_destination (tiff);
2024     if (outbuf != NULL)
2025 	free (outbuf);
2026     if (bufpix != NULL)
2027 	free (bufpix);
2028     if (palette != NULL)
2029 	rl2_destroy_palette (palette);
2030     return RL2_ERROR;
2031 }
2032 
2033 RL2_DECLARE int
rl2_export_tiff_from_dbms(sqlite3 * handle,const char * dst_path,rl2CoveragePtr cvg,double x_res,double y_res,double minx,double miny,double maxx,double maxy,unsigned int width,unsigned int height,unsigned char compression,unsigned int tile_sz)2034 rl2_export_tiff_from_dbms (sqlite3 * handle, const char *dst_path,
2035 			   rl2CoveragePtr cvg, double x_res, double y_res,
2036 			   double minx, double miny, double maxx,
2037 			   double maxy, unsigned int width,
2038 			   unsigned int height, unsigned char compression,
2039 			   unsigned int tile_sz)
2040 {
2041 /* exporting a plain TIFF from the DBMS into the file-system */
2042     rl2RasterPtr raster = NULL;
2043     rl2PalettePtr palette = NULL;
2044     rl2PalettePtr plt2 = NULL;
2045     rl2PixelPtr no_data = NULL;
2046     rl2TiffDestinationPtr tiff = NULL;
2047     unsigned char level;
2048     unsigned char scale;
2049     double xx_res = x_res;
2050     double yy_res = y_res;
2051     unsigned char sample_type;
2052     unsigned char pixel_type;
2053     unsigned char num_bands;
2054     int srid;
2055     unsigned char *outbuf = NULL;
2056     int outbuf_size;
2057     unsigned char *bufpix = NULL;
2058     int bufpix_size;
2059     int pix_sz = 1;
2060     unsigned int base_x;
2061     unsigned int base_y;
2062 
2063     if (rl2_find_matching_resolution
2064 	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
2065 	return RL2_ERROR;
2066 
2067     if (mismatching_size
2068 	(width, height, xx_res, yy_res, minx, miny, maxx, maxy))
2069 	goto error;
2070 
2071     if (rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands) !=
2072 	RL2_OK)
2073 	goto error;
2074     if (rl2_get_coverage_srid (cvg, &srid) != RL2_OK)
2075 	goto error;
2076     no_data = rl2_get_coverage_no_data (cvg);
2077 
2078     if (level > 0)
2079       {
2080 	  /* special handling for Pyramid tiles */
2081 	  if (sample_type == RL2_SAMPLE_1_BIT
2082 	      && pixel_type == RL2_PIXEL_MONOCHROME && num_bands == 1)
2083 	    {
2084 		/* expecting a Grayscale/PNG Pyramid tile */
2085 		sample_type = RL2_SAMPLE_UINT8;
2086 		pixel_type = RL2_PIXEL_GRAYSCALE;
2087 		num_bands = 1;
2088 	    }
2089 	  if ((sample_type == RL2_SAMPLE_1_BIT
2090 	       && pixel_type == RL2_PIXEL_PALETTE && num_bands == 1) ||
2091 	      (sample_type == RL2_SAMPLE_2_BIT
2092 	       && pixel_type == RL2_PIXEL_PALETTE && num_bands == 1) ||
2093 	      (sample_type == RL2_SAMPLE_4_BIT
2094 	       && pixel_type == RL2_PIXEL_PALETTE && num_bands == 1) ||
2095 	      (sample_type == RL2_SAMPLE_UINT8
2096 	       && pixel_type == RL2_PIXEL_PALETTE && num_bands == 1))
2097 	    {
2098 		/* expecting an RGB/PNG Pyramid tile */
2099 		sample_type = RL2_SAMPLE_UINT8;
2100 		pixel_type = RL2_PIXEL_RGB;
2101 		num_bands = 3;
2102 	    }
2103       }
2104 
2105     if (rl2_get_raw_raster_data
2106 	(handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
2107 	 yy_res, &outbuf, &outbuf_size, &palette, pixel_type) != RL2_OK)
2108 	goto error;
2109 
2110 /* computing the sample size */
2111     switch (sample_type)
2112       {
2113       case RL2_SAMPLE_INT16:
2114       case RL2_SAMPLE_UINT16:
2115 	  pix_sz = 2;
2116 	  break;
2117       case RL2_SAMPLE_INT32:
2118       case RL2_SAMPLE_UINT32:
2119       case RL2_SAMPLE_FLOAT:
2120 	  pix_sz = 4;
2121 	  break;
2122       case RL2_SAMPLE_DOUBLE:
2123 	  pix_sz = 8;
2124 	  break;
2125       };
2126 
2127     tiff =
2128 	rl2_create_tiff_destination (dst_path, width, height, sample_type,
2129 				     pixel_type, num_bands, palette,
2130 				     compression, 1, tile_sz);
2131     if (tiff == NULL)
2132 	goto error;
2133     for (base_y = 0; base_y < height; base_y += tile_sz)
2134       {
2135 	  for (base_x = 0; base_x < width; base_x += tile_sz)
2136 	    {
2137 		/* exporting all tiles from the output buffer */
2138 		bufpix_size = pix_sz * num_bands * tile_sz * tile_sz;
2139 		bufpix = malloc (bufpix_size);
2140 		if (bufpix == NULL)
2141 		  {
2142 		      fprintf (stderr,
2143 			       "rl2tool Export: Insufficient Memory !!!\n");
2144 		      goto error;
2145 		  }
2146 		if (pixel_type == RL2_PIXEL_PALETTE && palette != NULL)
2147 		    rl2_prime_void_tile_palette (bufpix, tile_sz, tile_sz,
2148 						 no_data);
2149 		else
2150 		    rl2_prime_void_tile (bufpix, tile_sz, tile_sz, sample_type,
2151 					 num_bands, no_data);
2152 		copy_from_outbuf_to_tile (outbuf, bufpix, sample_type,
2153 					  num_bands, width, height, tile_sz,
2154 					  tile_sz, base_y, base_x);
2155 		plt2 = rl2_clone_palette (palette);
2156 		raster =
2157 		    rl2_create_raster (tile_sz, tile_sz, sample_type,
2158 				       pixel_type, num_bands, bufpix,
2159 				       bufpix_size, plt2, NULL, 0, NULL);
2160 		bufpix = NULL;
2161 		if (raster == NULL)
2162 		    goto error;
2163 		if (rl2_write_tiff_tile (tiff, raster, base_y, base_x) !=
2164 		    RL2_OK)
2165 		    goto error;
2166 		rl2_destroy_raster (raster);
2167 		raster = NULL;
2168 	    }
2169       }
2170 
2171     rl2_destroy_tiff_destination (tiff);
2172     if (palette != NULL)
2173 	rl2_destroy_palette (palette);
2174     free (outbuf);
2175     return RL2_OK;
2176 
2177   error:
2178     if (raster != NULL)
2179 	rl2_destroy_raster (raster);
2180     if (tiff != NULL)
2181 	rl2_destroy_tiff_destination (tiff);
2182     if (outbuf != NULL)
2183 	free (outbuf);
2184     if (bufpix != NULL)
2185 	free (bufpix);
2186     if (palette != NULL)
2187 	rl2_destroy_palette (palette);
2188     return RL2_ERROR;
2189 }
2190 
2191 RL2_DECLARE int
rl2_export_triple_band_geotiff_from_dbms(sqlite3 * handle,const char * dst_path,rl2CoveragePtr cvg,double x_res,double y_res,double minx,double miny,double maxx,double maxy,unsigned int width,unsigned int height,unsigned char red_band,unsigned char green_band,unsigned char blue_band,unsigned char compression,unsigned int tile_sz,int with_worldfile)2192 rl2_export_triple_band_geotiff_from_dbms (sqlite3 * handle,
2193 					  const char *dst_path,
2194 					  rl2CoveragePtr cvg, double x_res,
2195 					  double y_res, double minx,
2196 					  double miny, double maxx,
2197 					  double maxy, unsigned int width,
2198 					  unsigned int height,
2199 					  unsigned char red_band,
2200 					  unsigned char green_band,
2201 					  unsigned char blue_band,
2202 					  unsigned char compression,
2203 					  unsigned int tile_sz,
2204 					  int with_worldfile)
2205 {
2206 /* exporting a Band-Composed GeoTIFF from the DBMS into the file-system */
2207     rl2RasterPtr raster = NULL;
2208     rl2TiffDestinationPtr tiff = NULL;
2209     rl2PixelPtr no_data_multi = NULL;
2210     rl2PixelPtr no_data = NULL;
2211     unsigned char level;
2212     unsigned char scale;
2213     double xx_res = x_res;
2214     double yy_res = y_res;
2215     unsigned char sample_type;
2216     unsigned char pixel_type;
2217     unsigned char num_bands;
2218     int srid;
2219     unsigned char *outbuf = NULL;
2220     int outbuf_size;
2221     unsigned char *bufpix = NULL;
2222     int bufpix_size;
2223     unsigned int base_x;
2224     unsigned int base_y;
2225 
2226     if (rl2_find_matching_resolution
2227 	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
2228 	return RL2_ERROR;
2229 
2230     if (mismatching_size
2231 	(width, height, xx_res, yy_res, minx, miny, maxx, maxy))
2232 	goto error;
2233 
2234     if (rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands) !=
2235 	RL2_OK)
2236 	goto error;
2237     if (pixel_type != RL2_PIXEL_RGB && pixel_type != RL2_PIXEL_MULTIBAND)
2238 	goto error;
2239     if (sample_type != RL2_SAMPLE_UINT8 && sample_type != RL2_SAMPLE_UINT16)
2240 	goto error;
2241     if (red_band >= num_bands)
2242 	goto error;
2243     if (green_band >= num_bands)
2244 	goto error;
2245     if (blue_band >= num_bands)
2246 	goto error;
2247     if (rl2_get_coverage_srid (cvg, &srid) != RL2_OK)
2248 	goto error;
2249     no_data_multi = rl2_get_coverage_no_data (cvg);
2250     no_data =
2251 	rl2_create_triple_band_pixel (no_data_multi, red_band, green_band,
2252 				      blue_band);
2253 
2254     if (rl2_get_triple_band_raw_raster_data
2255 	(handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
2256 	 yy_res, red_band, green_band, blue_band, &outbuf, &outbuf_size,
2257 	 no_data) != RL2_OK)
2258 	goto error;
2259 
2260     tiff =
2261 	rl2_create_geotiff_destination (dst_path, handle, width, height,
2262 					sample_type, RL2_PIXEL_RGB, 3,
2263 					NULL, compression, 1, tile_sz, srid,
2264 					minx, miny, maxx, maxy, xx_res, yy_res,
2265 					with_worldfile);
2266     if (tiff == NULL)
2267 	goto error;
2268     for (base_y = 0; base_y < height; base_y += tile_sz)
2269       {
2270 	  for (base_x = 0; base_x < width; base_x += tile_sz)
2271 	    {
2272 		/* exporting all tiles from the output buffer */
2273 		bufpix_size = 3 * tile_sz * tile_sz;
2274 		if (sample_type == RL2_SAMPLE_UINT16)
2275 		    bufpix_size *= 2;
2276 		bufpix = malloc (bufpix_size);
2277 		if (bufpix == NULL)
2278 		  {
2279 		      fprintf (stderr,
2280 			       "rl2tool Export: Insufficient Memory !!!\n");
2281 		      goto error;
2282 		  }
2283 		rl2_prime_void_tile (bufpix, tile_sz, tile_sz, sample_type,
2284 				     3, no_data);
2285 		copy_from_outbuf_to_tile (outbuf, bufpix, sample_type,
2286 					  3, width, height, tile_sz,
2287 					  tile_sz, base_y, base_x);
2288 		raster =
2289 		    rl2_create_raster (tile_sz, tile_sz, sample_type,
2290 				       RL2_PIXEL_RGB, 3, bufpix,
2291 				       bufpix_size, NULL, NULL, 0, NULL);
2292 		bufpix = NULL;
2293 		if (raster == NULL)
2294 		    goto error;
2295 		if (rl2_write_tiff_tile (tiff, raster, base_y, base_x) !=
2296 		    RL2_OK)
2297 		    goto error;
2298 		rl2_destroy_raster (raster);
2299 		raster = NULL;
2300 	    }
2301       }
2302 
2303     if (with_worldfile)
2304       {
2305 	  /* exporting the Worldfile */
2306 	  if (rl2_write_tiff_worldfile (tiff) != RL2_OK)
2307 	      goto error;
2308       }
2309 
2310     rl2_destroy_tiff_destination (tiff);
2311     free (outbuf);
2312     if (no_data != NULL)
2313 	rl2_destroy_pixel (no_data);
2314     return RL2_OK;
2315 
2316   error:
2317     if (raster != NULL)
2318 	rl2_destroy_raster (raster);
2319     if (tiff != NULL)
2320 	rl2_destroy_tiff_destination (tiff);
2321     if (outbuf != NULL)
2322 	free (outbuf);
2323     if (bufpix != NULL)
2324 	free (bufpix);
2325     if (no_data != NULL)
2326 	rl2_destroy_pixel (no_data);
2327     return RL2_ERROR;
2328 }
2329 
2330 RL2_DECLARE int
rl2_export_mono_band_geotiff_from_dbms(sqlite3 * handle,const char * dst_path,rl2CoveragePtr cvg,double x_res,double y_res,double minx,double miny,double maxx,double maxy,unsigned int width,unsigned int height,unsigned char mono_band,unsigned char compression,unsigned int tile_sz,int with_worldfile)2331 rl2_export_mono_band_geotiff_from_dbms (sqlite3 * handle,
2332 					const char *dst_path,
2333 					rl2CoveragePtr cvg, double x_res,
2334 					double y_res, double minx,
2335 					double miny, double maxx,
2336 					double maxy, unsigned int width,
2337 					unsigned int height,
2338 					unsigned char mono_band,
2339 					unsigned char compression,
2340 					unsigned int tile_sz,
2341 					int with_worldfile)
2342 {
2343 /* exporting a Mono-Band GeoTIFF from the DBMS into the file-system */
2344     rl2RasterPtr raster = NULL;
2345     rl2TiffDestinationPtr tiff = NULL;
2346     rl2PixelPtr no_data_mono = NULL;
2347     rl2PixelPtr no_data = NULL;
2348     unsigned char level;
2349     unsigned char scale;
2350     double xx_res = x_res;
2351     double yy_res = y_res;
2352     unsigned char sample_type;
2353     unsigned char pixel_type;
2354     unsigned char num_bands;
2355     int srid;
2356     unsigned char *outbuf = NULL;
2357     int outbuf_size;
2358     unsigned char *bufpix = NULL;
2359     int bufpix_size;
2360     unsigned int base_x;
2361     unsigned int base_y;
2362     unsigned char out_pixel;
2363 
2364     if (rl2_find_matching_resolution
2365 	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
2366 	return RL2_ERROR;
2367 
2368     if (mismatching_size
2369 	(width, height, xx_res, yy_res, minx, miny, maxx, maxy))
2370 	goto error;
2371 
2372     if (rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands) !=
2373 	RL2_OK)
2374 	goto error;
2375     if (pixel_type != RL2_PIXEL_RGB && pixel_type != RL2_PIXEL_MULTIBAND)
2376 	goto error;
2377     if (sample_type != RL2_SAMPLE_UINT8 && sample_type != RL2_SAMPLE_UINT16)
2378 	goto error;
2379     if (mono_band >= num_bands)
2380 	goto error;
2381     if (rl2_get_coverage_srid (cvg, &srid) != RL2_OK)
2382 	goto error;
2383     no_data_mono = rl2_get_coverage_no_data (cvg);
2384     no_data = rl2_create_mono_band_pixel (no_data_mono, mono_band);
2385 
2386     if (rl2_get_mono_band_raw_raster_data
2387 	(handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
2388 	 yy_res, mono_band, &outbuf, &outbuf_size, no_data) != RL2_OK)
2389 	goto error;
2390 
2391     if (sample_type == RL2_SAMPLE_UINT16)
2392 	out_pixel = RL2_PIXEL_DATAGRID;
2393     else
2394 	out_pixel = RL2_PIXEL_GRAYSCALE;
2395 
2396     tiff =
2397 	rl2_create_geotiff_destination (dst_path, handle, width, height,
2398 					sample_type, out_pixel, 1,
2399 					NULL, compression, 1, tile_sz, srid,
2400 					minx, miny, maxx, maxy, xx_res, yy_res,
2401 					with_worldfile);
2402     if (tiff == NULL)
2403 	goto error;
2404     for (base_y = 0; base_y < height; base_y += tile_sz)
2405       {
2406 	  for (base_x = 0; base_x < width; base_x += tile_sz)
2407 	    {
2408 		/* exporting all tiles from the output buffer */
2409 		bufpix_size = tile_sz * tile_sz;
2410 		if (sample_type == RL2_SAMPLE_UINT16)
2411 		    bufpix_size *= 2;
2412 		bufpix = malloc (bufpix_size);
2413 		if (bufpix == NULL)
2414 		  {
2415 		      fprintf (stderr,
2416 			       "rl2tool Export: Insufficient Memory !!!\n");
2417 		      goto error;
2418 		  }
2419 		rl2_prime_void_tile (bufpix, tile_sz, tile_sz, sample_type,
2420 				     1, no_data);
2421 		copy_from_outbuf_to_tile (outbuf, bufpix, sample_type,
2422 					  1, width, height, tile_sz,
2423 					  tile_sz, base_y, base_x);
2424 		raster =
2425 		    rl2_create_raster (tile_sz, tile_sz, sample_type,
2426 				       out_pixel, 1, bufpix,
2427 				       bufpix_size, NULL, NULL, 0, NULL);
2428 		bufpix = NULL;
2429 		if (raster == NULL)
2430 		    goto error;
2431 		if (rl2_write_tiff_tile (tiff, raster, base_y, base_x) !=
2432 		    RL2_OK)
2433 		    goto error;
2434 		rl2_destroy_raster (raster);
2435 		raster = NULL;
2436 	    }
2437       }
2438 
2439     if (with_worldfile)
2440       {
2441 	  /* exporting the Worldfile */
2442 	  if (rl2_write_tiff_worldfile (tiff) != RL2_OK)
2443 	      goto error;
2444       }
2445 
2446     rl2_destroy_tiff_destination (tiff);
2447     free (outbuf);
2448     if (no_data != NULL)
2449 	rl2_destroy_pixel (no_data);
2450     return RL2_OK;
2451 
2452   error:
2453     if (raster != NULL)
2454 	rl2_destroy_raster (raster);
2455     if (tiff != NULL)
2456 	rl2_destroy_tiff_destination (tiff);
2457     if (outbuf != NULL)
2458 	free (outbuf);
2459     if (bufpix != NULL)
2460 	free (bufpix);
2461     if (no_data != NULL)
2462 	rl2_destroy_pixel (no_data);
2463     return RL2_ERROR;
2464 }
2465 
2466 RL2_DECLARE int
rl2_export_triple_band_tiff_worldfile_from_dbms(sqlite3 * handle,const char * dst_path,rl2CoveragePtr cvg,double x_res,double y_res,double minx,double miny,double maxx,double maxy,unsigned int width,unsigned int height,unsigned char red_band,unsigned char green_band,unsigned char blue_band,unsigned char compression,unsigned int tile_sz)2467 rl2_export_triple_band_tiff_worldfile_from_dbms (sqlite3 * handle,
2468 						 const char *dst_path,
2469 						 rl2CoveragePtr cvg,
2470 						 double x_res, double y_res,
2471 						 double minx, double miny,
2472 						 double maxx, double maxy,
2473 						 unsigned int width,
2474 						 unsigned int height,
2475 						 unsigned char red_band,
2476 						 unsigned char green_band,
2477 						 unsigned char blue_band,
2478 						 unsigned char compression,
2479 						 unsigned int tile_sz)
2480 {
2481 /* exporting a Band-Composed TIFF+TFW from the DBMS into the file-system */
2482     rl2RasterPtr raster = NULL;
2483     rl2PixelPtr no_data_multi = NULL;
2484     rl2PixelPtr no_data = NULL;
2485     rl2TiffDestinationPtr tiff = NULL;
2486     unsigned char level;
2487     unsigned char scale;
2488     double xx_res = x_res;
2489     double yy_res = y_res;
2490     unsigned char sample_type;
2491     unsigned char pixel_type;
2492     unsigned char num_bands;
2493     int srid;
2494     unsigned char *outbuf = NULL;
2495     int outbuf_size;
2496     unsigned char *bufpix = NULL;
2497     int bufpix_size;
2498     unsigned int base_x;
2499     unsigned int base_y;
2500 
2501     if (rl2_find_matching_resolution
2502 	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
2503 	return RL2_ERROR;
2504 
2505     if (mismatching_size
2506 	(width, height, xx_res, yy_res, minx, miny, maxx, maxy))
2507 	goto error;
2508 
2509     if (rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands) !=
2510 	RL2_OK)
2511 	goto error;
2512     if (pixel_type != RL2_PIXEL_RGB && pixel_type != RL2_PIXEL_MULTIBAND)
2513 	goto error;
2514     if (sample_type != RL2_SAMPLE_UINT8 && sample_type != RL2_SAMPLE_UINT16)
2515 	goto error;
2516     if (red_band >= num_bands)
2517 	goto error;
2518     if (green_band >= num_bands)
2519 	goto error;
2520     if (blue_band >= num_bands)
2521 	goto error;
2522     if (rl2_get_coverage_srid (cvg, &srid) != RL2_OK)
2523 	goto error;
2524     no_data_multi = rl2_get_coverage_no_data (cvg);
2525     no_data =
2526 	rl2_create_triple_band_pixel (no_data_multi, red_band, green_band,
2527 				      blue_band);
2528 
2529     if (rl2_get_triple_band_raw_raster_data
2530 	(handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
2531 	 yy_res, red_band, green_band, blue_band, &outbuf, &outbuf_size,
2532 	 no_data) != RL2_OK)
2533 	goto error;
2534 
2535     tiff =
2536 	rl2_create_tiff_worldfile_destination (dst_path, width, height,
2537 					       sample_type, RL2_PIXEL_RGB,
2538 					       3, NULL, compression, 1, tile_sz,
2539 					       srid, minx, miny, maxx, maxy,
2540 					       xx_res, yy_res);
2541     if (tiff == NULL)
2542 	goto error;
2543     for (base_y = 0; base_y < height; base_y += tile_sz)
2544       {
2545 	  for (base_x = 0; base_x < width; base_x += tile_sz)
2546 	    {
2547 		/* exporting all tiles from the output buffer */
2548 		bufpix_size = 3 * tile_sz * tile_sz;
2549 		if (sample_type == RL2_SAMPLE_UINT16)
2550 		    bufpix_size *= 2;
2551 		bufpix = malloc (bufpix_size);
2552 		if (bufpix == NULL)
2553 		  {
2554 		      fprintf (stderr,
2555 			       "rl2tool Export: Insufficient Memory !!!\n");
2556 		      goto error;
2557 		  }
2558 		rl2_prime_void_tile (bufpix, tile_sz, tile_sz, sample_type,
2559 				     3, no_data);
2560 		copy_from_outbuf_to_tile (outbuf, bufpix, sample_type,
2561 					  3, width, height, tile_sz,
2562 					  tile_sz, base_y, base_x);
2563 		raster =
2564 		    rl2_create_raster (tile_sz, tile_sz, sample_type,
2565 				       RL2_PIXEL_RGB, 3, bufpix,
2566 				       bufpix_size, NULL, NULL, 0, NULL);
2567 		bufpix = NULL;
2568 		if (raster == NULL)
2569 		    goto error;
2570 		if (rl2_write_tiff_tile (tiff, raster, base_y, base_x) !=
2571 		    RL2_OK)
2572 		    goto error;
2573 		rl2_destroy_raster (raster);
2574 		raster = NULL;
2575 	    }
2576       }
2577 
2578 /* exporting the Worldfile */
2579     if (rl2_write_tiff_worldfile (tiff) != RL2_OK)
2580 	goto error;
2581 
2582     rl2_destroy_tiff_destination (tiff);
2583     free (outbuf);
2584     if (no_data != NULL)
2585 	rl2_destroy_pixel (no_data);
2586     return RL2_OK;
2587 
2588   error:
2589     if (raster != NULL)
2590 	rl2_destroy_raster (raster);
2591     if (tiff != NULL)
2592 	rl2_destroy_tiff_destination (tiff);
2593     if (outbuf != NULL)
2594 	free (outbuf);
2595     if (bufpix != NULL)
2596 	free (bufpix);
2597     if (no_data != NULL)
2598 	rl2_destroy_pixel (no_data);
2599     return RL2_ERROR;
2600 }
2601 
2602 RL2_DECLARE int
rl2_export_mono_band_tiff_worldfile_from_dbms(sqlite3 * handle,const char * dst_path,rl2CoveragePtr cvg,double x_res,double y_res,double minx,double miny,double maxx,double maxy,unsigned int width,unsigned int height,unsigned char mono_band,unsigned char compression,unsigned int tile_sz)2603 rl2_export_mono_band_tiff_worldfile_from_dbms (sqlite3 * handle,
2604 					       const char *dst_path,
2605 					       rl2CoveragePtr cvg,
2606 					       double x_res, double y_res,
2607 					       double minx, double miny,
2608 					       double maxx, double maxy,
2609 					       unsigned int width,
2610 					       unsigned int height,
2611 					       unsigned char mono_band,
2612 					       unsigned char compression,
2613 					       unsigned int tile_sz)
2614 {
2615 /* exporting a Mono-Band TIFF+TFW from the DBMS into the file-system */
2616     rl2RasterPtr raster = NULL;
2617     rl2PixelPtr no_data_multi = NULL;
2618     rl2PixelPtr no_data = NULL;
2619     rl2TiffDestinationPtr tiff = NULL;
2620     unsigned char level;
2621     unsigned char scale;
2622     double xx_res = x_res;
2623     double yy_res = y_res;
2624     unsigned char sample_type;
2625     unsigned char pixel_type;
2626     unsigned char num_bands;
2627     int srid;
2628     unsigned char *outbuf = NULL;
2629     int outbuf_size;
2630     unsigned char *bufpix = NULL;
2631     int bufpix_size;
2632     unsigned int base_x;
2633     unsigned int base_y;
2634     unsigned char out_pixel;
2635 
2636     if (rl2_find_matching_resolution
2637 	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
2638 	return RL2_ERROR;
2639 
2640     if (mismatching_size
2641 	(width, height, xx_res, yy_res, minx, miny, maxx, maxy))
2642 	goto error;
2643 
2644     if (rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands) !=
2645 	RL2_OK)
2646 	goto error;
2647     if (pixel_type != RL2_PIXEL_RGB && pixel_type != RL2_PIXEL_MULTIBAND)
2648 	goto error;
2649     if (sample_type != RL2_SAMPLE_UINT8 && sample_type != RL2_SAMPLE_UINT16)
2650 	goto error;
2651     if (mono_band >= num_bands)
2652 	goto error;
2653     if (rl2_get_coverage_srid (cvg, &srid) != RL2_OK)
2654 	goto error;
2655     no_data_multi = rl2_get_coverage_no_data (cvg);
2656     no_data = rl2_create_mono_band_pixel (no_data_multi, mono_band);
2657 
2658     if (rl2_get_mono_band_raw_raster_data
2659 	(handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
2660 	 yy_res, mono_band, &outbuf, &outbuf_size, no_data) != RL2_OK)
2661 	goto error;
2662 
2663     if (sample_type == RL2_SAMPLE_UINT16)
2664 	out_pixel = RL2_PIXEL_DATAGRID;
2665     else
2666 	out_pixel = RL2_PIXEL_GRAYSCALE;
2667 
2668     tiff =
2669 	rl2_create_tiff_worldfile_destination (dst_path, width, height,
2670 					       sample_type, out_pixel,
2671 					       1, NULL, compression, 1, tile_sz,
2672 					       srid, minx, miny, maxx, maxy,
2673 					       xx_res, yy_res);
2674     if (tiff == NULL)
2675 	goto error;
2676     for (base_y = 0; base_y < height; base_y += tile_sz)
2677       {
2678 	  for (base_x = 0; base_x < width; base_x += tile_sz)
2679 	    {
2680 		/* exporting all tiles from the output buffer */
2681 		bufpix_size = tile_sz * tile_sz;
2682 		if (sample_type == RL2_SAMPLE_UINT16)
2683 		    bufpix_size *= 2;
2684 		bufpix = malloc (bufpix_size);
2685 		if (bufpix == NULL)
2686 		  {
2687 		      fprintf (stderr,
2688 			       "rl2tool Export: Insufficient Memory !!!\n");
2689 		      goto error;
2690 		  }
2691 		rl2_prime_void_tile (bufpix, tile_sz, tile_sz, sample_type,
2692 				     1, no_data);
2693 		copy_from_outbuf_to_tile (outbuf, bufpix, sample_type,
2694 					  1, width, height, tile_sz,
2695 					  tile_sz, base_y, base_x);
2696 		raster =
2697 		    rl2_create_raster (tile_sz, tile_sz, sample_type,
2698 				       out_pixel, 1, bufpix,
2699 				       bufpix_size, NULL, NULL, 0, NULL);
2700 		bufpix = NULL;
2701 		if (raster == NULL)
2702 		    goto error;
2703 		if (rl2_write_tiff_tile (tiff, raster, base_y, base_x) !=
2704 		    RL2_OK)
2705 		    goto error;
2706 		rl2_destroy_raster (raster);
2707 		raster = NULL;
2708 	    }
2709       }
2710 
2711 /* exporting the Worldfile */
2712     if (rl2_write_tiff_worldfile (tiff) != RL2_OK)
2713 	goto error;
2714 
2715     rl2_destroy_tiff_destination (tiff);
2716     free (outbuf);
2717     if (no_data != NULL)
2718 	rl2_destroy_pixel (no_data);
2719     return RL2_OK;
2720 
2721   error:
2722     if (raster != NULL)
2723 	rl2_destroy_raster (raster);
2724     if (tiff != NULL)
2725 	rl2_destroy_tiff_destination (tiff);
2726     if (outbuf != NULL)
2727 	free (outbuf);
2728     if (bufpix != NULL)
2729 	free (bufpix);
2730     if (no_data != NULL)
2731 	rl2_destroy_pixel (no_data);
2732     return RL2_ERROR;
2733 }
2734 
2735 RL2_DECLARE int
rl2_export_triple_band_tiff_from_dbms(sqlite3 * handle,const char * dst_path,rl2CoveragePtr cvg,double x_res,double y_res,double minx,double miny,double maxx,double maxy,unsigned int width,unsigned int height,unsigned char red_band,unsigned char green_band,unsigned char blue_band,unsigned char compression,unsigned int tile_sz)2736 rl2_export_triple_band_tiff_from_dbms (sqlite3 * handle, const char *dst_path,
2737 				       rl2CoveragePtr cvg, double x_res,
2738 				       double y_res, double minx, double miny,
2739 				       double maxx, double maxy,
2740 				       unsigned int width,
2741 				       unsigned int height,
2742 				       unsigned char red_band,
2743 				       unsigned char green_band,
2744 				       unsigned char blue_band,
2745 				       unsigned char compression,
2746 				       unsigned int tile_sz)
2747 {
2748 /* exporting a plain Band-Composed TIFF from the DBMS into the file-system */
2749     rl2RasterPtr raster = NULL;
2750     rl2PixelPtr no_data_multi = NULL;
2751     rl2PixelPtr no_data = NULL;
2752     rl2TiffDestinationPtr tiff = NULL;
2753     unsigned char level;
2754     unsigned char scale;
2755     double xx_res = x_res;
2756     double yy_res = y_res;
2757     unsigned char sample_type;
2758     unsigned char pixel_type;
2759     unsigned char num_bands;
2760     int srid;
2761     unsigned char *outbuf = NULL;
2762     int outbuf_size;
2763     unsigned char *bufpix = NULL;
2764     int bufpix_size;
2765     unsigned int base_x;
2766     unsigned int base_y;
2767 
2768     if (rl2_find_matching_resolution
2769 	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
2770 	return RL2_ERROR;
2771 
2772     if (mismatching_size
2773 	(width, height, xx_res, yy_res, minx, miny, maxx, maxy))
2774 	goto error;
2775 
2776     if (rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands) !=
2777 	RL2_OK)
2778 	goto error;
2779     if (pixel_type != RL2_PIXEL_RGB && pixel_type != RL2_PIXEL_MULTIBAND)
2780 	goto error;
2781     if (sample_type != RL2_SAMPLE_UINT8 && sample_type != RL2_SAMPLE_UINT16)
2782 	goto error;
2783     if (red_band >= num_bands)
2784 	goto error;
2785     if (green_band >= num_bands)
2786 	goto error;
2787     if (blue_band >= num_bands)
2788 	goto error;
2789     if (rl2_get_coverage_srid (cvg, &srid) != RL2_OK)
2790 	goto error;
2791     no_data_multi = rl2_get_coverage_no_data (cvg);
2792     no_data =
2793 	rl2_create_triple_band_pixel (no_data_multi, red_band, green_band,
2794 				      blue_band);
2795 
2796     if (rl2_get_triple_band_raw_raster_data
2797 	(handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
2798 	 yy_res, red_band, green_band, blue_band, &outbuf, &outbuf_size,
2799 	 no_data) != RL2_OK)
2800 	goto error;
2801 
2802     tiff =
2803 	rl2_create_tiff_destination (dst_path, width, height, sample_type,
2804 				     RL2_PIXEL_RGB, 3, NULL,
2805 				     compression, 1, tile_sz);
2806     if (tiff == NULL)
2807 	goto error;
2808     for (base_y = 0; base_y < height; base_y += tile_sz)
2809       {
2810 	  for (base_x = 0; base_x < width; base_x += tile_sz)
2811 	    {
2812 		/* exporting all tiles from the output buffer */
2813 		bufpix_size = 3 * tile_sz * tile_sz;
2814 		if (sample_type == RL2_SAMPLE_UINT16)
2815 		    bufpix_size *= 2;
2816 		bufpix = malloc (bufpix_size);
2817 		if (bufpix == NULL)
2818 		  {
2819 		      fprintf (stderr,
2820 			       "rl2tool Export: Insufficient Memory !!!\n");
2821 		      goto error;
2822 		  }
2823 		rl2_prime_void_tile (bufpix, tile_sz, tile_sz, sample_type,
2824 				     3, no_data);
2825 		copy_from_outbuf_to_tile (outbuf, bufpix, sample_type,
2826 					  3, width, height, tile_sz,
2827 					  tile_sz, base_y, base_x);
2828 		raster =
2829 		    rl2_create_raster (tile_sz, tile_sz, sample_type,
2830 				       RL2_PIXEL_RGB, 3, bufpix,
2831 				       bufpix_size, NULL, NULL, 0, NULL);
2832 		bufpix = NULL;
2833 		if (raster == NULL)
2834 		    goto error;
2835 		if (rl2_write_tiff_tile (tiff, raster, base_y, base_x) !=
2836 		    RL2_OK)
2837 		    goto error;
2838 		rl2_destroy_raster (raster);
2839 		raster = NULL;
2840 	    }
2841       }
2842 
2843     rl2_destroy_tiff_destination (tiff);
2844     if (no_data != NULL)
2845 	rl2_destroy_pixel (no_data);
2846     free (outbuf);
2847     return RL2_OK;
2848 
2849   error:
2850     if (raster != NULL)
2851 	rl2_destroy_raster (raster);
2852     if (tiff != NULL)
2853 	rl2_destroy_tiff_destination (tiff);
2854     if (outbuf != NULL)
2855 	free (outbuf);
2856     if (bufpix != NULL)
2857 	free (bufpix);
2858     if (no_data != NULL)
2859 	rl2_destroy_pixel (no_data);
2860     return RL2_ERROR;
2861 }
2862 
2863 RL2_DECLARE int
rl2_export_mono_band_tiff_from_dbms(sqlite3 * handle,const char * dst_path,rl2CoveragePtr cvg,double x_res,double y_res,double minx,double miny,double maxx,double maxy,unsigned int width,unsigned int height,unsigned char mono_band,unsigned char compression,unsigned int tile_sz)2864 rl2_export_mono_band_tiff_from_dbms (sqlite3 * handle, const char *dst_path,
2865 				     rl2CoveragePtr cvg, double x_res,
2866 				     double y_res, double minx, double miny,
2867 				     double maxx, double maxy,
2868 				     unsigned int width,
2869 				     unsigned int height,
2870 				     unsigned char mono_band,
2871 				     unsigned char compression,
2872 				     unsigned int tile_sz)
2873 {
2874 /* exporting a plain Mono-Band TIFF from the DBMS into the file-system */
2875     rl2RasterPtr raster = NULL;
2876     rl2PixelPtr no_data_multi = NULL;
2877     rl2PixelPtr no_data = NULL;
2878     rl2TiffDestinationPtr tiff = NULL;
2879     unsigned char level;
2880     unsigned char scale;
2881     double xx_res = x_res;
2882     double yy_res = y_res;
2883     unsigned char sample_type;
2884     unsigned char pixel_type;
2885     unsigned char num_bands;
2886     int srid;
2887     unsigned char *outbuf = NULL;
2888     int outbuf_size;
2889     unsigned char *bufpix = NULL;
2890     int bufpix_size;
2891     unsigned int base_x;
2892     unsigned int base_y;
2893     unsigned char out_pixel;
2894 
2895     if (rl2_find_matching_resolution
2896 	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
2897 	return RL2_ERROR;
2898 
2899     if (mismatching_size
2900 	(width, height, xx_res, yy_res, minx, miny, maxx, maxy))
2901 	goto error;
2902 
2903     if (rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands) !=
2904 	RL2_OK)
2905 	goto error;
2906     if (pixel_type != RL2_PIXEL_RGB && pixel_type != RL2_PIXEL_MULTIBAND)
2907 	goto error;
2908     if (sample_type != RL2_SAMPLE_UINT8 && sample_type != RL2_SAMPLE_UINT16)
2909 	goto error;
2910     if (mono_band >= num_bands)
2911 	goto error;
2912     if (rl2_get_coverage_srid (cvg, &srid) != RL2_OK)
2913 	goto error;
2914     no_data_multi = rl2_get_coverage_no_data (cvg);
2915     no_data = rl2_create_mono_band_pixel (no_data_multi, mono_band);
2916 
2917     if (rl2_get_mono_band_raw_raster_data
2918 	(handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
2919 	 yy_res, mono_band, &outbuf, &outbuf_size, no_data) != RL2_OK)
2920 	goto error;
2921 
2922     if (sample_type == RL2_SAMPLE_UINT16)
2923 	out_pixel = RL2_PIXEL_DATAGRID;
2924     else
2925 	out_pixel = RL2_PIXEL_GRAYSCALE;
2926 
2927     tiff =
2928 	rl2_create_tiff_destination (dst_path, width, height, sample_type,
2929 				     out_pixel, 1, NULL,
2930 				     compression, 1, tile_sz);
2931     if (tiff == NULL)
2932 	goto error;
2933     for (base_y = 0; base_y < height; base_y += tile_sz)
2934       {
2935 	  for (base_x = 0; base_x < width; base_x += tile_sz)
2936 	    {
2937 		/* exporting all tiles from the output buffer */
2938 		bufpix_size = tile_sz * tile_sz;
2939 		if (sample_type == RL2_SAMPLE_UINT16)
2940 		    bufpix_size *= 2;
2941 		bufpix = malloc (bufpix_size);
2942 		if (bufpix == NULL)
2943 		  {
2944 		      fprintf (stderr,
2945 			       "rl2tool Export: Insufficient Memory !!!\n");
2946 		      goto error;
2947 		  }
2948 		rl2_prime_void_tile (bufpix, tile_sz, tile_sz, sample_type,
2949 				     1, no_data);
2950 		copy_from_outbuf_to_tile (outbuf, bufpix, sample_type,
2951 					  1, width, height, tile_sz,
2952 					  tile_sz, base_y, base_x);
2953 		raster =
2954 		    rl2_create_raster (tile_sz, tile_sz, sample_type,
2955 				       out_pixel, 1, bufpix,
2956 				       bufpix_size, NULL, NULL, 0, NULL);
2957 		bufpix = NULL;
2958 		if (raster == NULL)
2959 		    goto error;
2960 		if (rl2_write_tiff_tile (tiff, raster, base_y, base_x) !=
2961 		    RL2_OK)
2962 		    goto error;
2963 		rl2_destroy_raster (raster);
2964 		raster = NULL;
2965 	    }
2966       }
2967 
2968     rl2_destroy_tiff_destination (tiff);
2969     if (no_data != NULL)
2970 	rl2_destroy_pixel (no_data);
2971     free (outbuf);
2972     return RL2_OK;
2973 
2974   error:
2975     if (raster != NULL)
2976 	rl2_destroy_raster (raster);
2977     if (tiff != NULL)
2978 	rl2_destroy_tiff_destination (tiff);
2979     if (outbuf != NULL)
2980 	free (outbuf);
2981     if (bufpix != NULL)
2982 	free (bufpix);
2983     if (no_data != NULL)
2984 	rl2_destroy_pixel (no_data);
2985     return RL2_ERROR;
2986 }
2987 
2988 RL2_DECLARE int
rl2_export_ascii_grid_from_dbms(sqlite3 * handle,const char * dst_path,rl2CoveragePtr cvg,double res,double minx,double miny,double maxx,double maxy,unsigned int width,unsigned int height,int is_centered,int decimal_digits)2989 rl2_export_ascii_grid_from_dbms (sqlite3 * handle, const char *dst_path,
2990 				 rl2CoveragePtr cvg, double res,
2991 				 double minx, double miny, double maxx,
2992 				 double maxy, unsigned int width,
2993 				 unsigned int height, int is_centered,
2994 				 int decimal_digits)
2995 {
2996 /* exporting an ASCII Grid from the DBMS into the file-system */
2997     rl2PalettePtr palette = NULL;
2998     rl2AsciiGridDestinationPtr ascii = NULL;
2999     rl2PixelPtr pixel;
3000     unsigned char level;
3001     unsigned char scale;
3002     double xx_res = res;
3003     double yy_res = res;
3004     unsigned char sample_type;
3005     unsigned char pixel_type;
3006     unsigned char num_bands;
3007     double no_data = -9999.0;
3008     unsigned int base_y;
3009     unsigned char *pixels = NULL;
3010     int pixels_size;
3011 
3012     if (rl2_find_matching_resolution
3013 	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
3014 	return RL2_ERROR;
3015 
3016     if (mismatching_size
3017 	(width, height, xx_res, yy_res, minx, miny, maxx, maxy))
3018 	goto error;
3019 
3020     if (rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands) !=
3021 	RL2_OK)
3022 	goto error;
3023 
3024     if (pixel_type != RL2_PIXEL_DATAGRID || num_bands != 1)
3025 	goto error;
3026 
3027     pixel = rl2_get_coverage_no_data (cvg);
3028     if (pixel != NULL)
3029       {
3030 	  /* attempting to retrieve the NO-DATA value */
3031 	  unsigned char st;
3032 	  unsigned char pt;
3033 	  unsigned char nb;
3034 	  if (rl2_get_pixel_type (pixel, &st, &pt, &nb) == RL2_OK)
3035 	    {
3036 		if (st == RL2_SAMPLE_INT8)
3037 		  {
3038 		      char v8;
3039 		      if (rl2_get_pixel_sample_int8 (pixel, &v8) == RL2_OK)
3040 			  no_data = v8;
3041 		  }
3042 		if (st == RL2_SAMPLE_UINT8)
3043 		  {
3044 		      unsigned char vu8;
3045 		      if (rl2_get_pixel_sample_uint8 (pixel, 0, &vu8) == RL2_OK)
3046 			  no_data = vu8;
3047 		  }
3048 		if (st == RL2_SAMPLE_INT16)
3049 		  {
3050 		      short v16;
3051 		      if (rl2_get_pixel_sample_int16 (pixel, &v16) == RL2_OK)
3052 			  no_data = v16;
3053 		  }
3054 		if (st == RL2_SAMPLE_UINT16)
3055 		  {
3056 		      unsigned short vu16;
3057 		      if (rl2_get_pixel_sample_uint16 (pixel, 0, &vu16) ==
3058 			  RL2_OK)
3059 			  no_data = vu16;
3060 		  }
3061 		if (st == RL2_SAMPLE_INT32)
3062 		  {
3063 		      int v32;
3064 		      if (rl2_get_pixel_sample_int32 (pixel, &v32) == RL2_OK)
3065 			  no_data = v32;
3066 		  }
3067 		if (st == RL2_SAMPLE_UINT32)
3068 		  {
3069 		      unsigned int vu32;
3070 		      if (rl2_get_pixel_sample_uint32 (pixel, &vu32) == RL2_OK)
3071 			  no_data = vu32;
3072 		  }
3073 		if (st == RL2_SAMPLE_FLOAT)
3074 		  {
3075 		      float vflt;
3076 		      if (rl2_get_pixel_sample_float (pixel, &vflt) == RL2_OK)
3077 			  no_data = vflt;
3078 		  }
3079 		if (st == RL2_SAMPLE_DOUBLE)
3080 		  {
3081 		      double vdbl;
3082 		      if (rl2_get_pixel_sample_double (pixel, &vdbl) == RL2_OK)
3083 			  no_data = vdbl;
3084 		  }
3085 	    }
3086       }
3087 
3088     if (rl2_get_raw_raster_data
3089 	(handle, cvg, width, height, minx, miny, maxx, maxy, res, res, &pixels,
3090 	 &pixels_size, &palette, RL2_PIXEL_DATAGRID) != RL2_OK)
3091 	goto error;
3092 
3093     ascii =
3094 	rl2_create_ascii_grid_destination (dst_path, width, height,
3095 					   xx_res, minx, miny, is_centered,
3096 					   no_data, decimal_digits, pixels,
3097 					   pixels_size, sample_type);
3098     if (ascii == NULL)
3099 	goto error;
3100     pixels = NULL;		/* pix-buffer ownership now belongs to the ASCII object */
3101 /* writing the ASCII Grid header */
3102     if (rl2_write_ascii_grid_header (ascii) != RL2_OK)
3103 	goto error;
3104     for (base_y = 0; base_y < height; base_y++)
3105       {
3106 	  /* exporting all scanlines from the output buffer */
3107 	  unsigned int line_no;
3108 	  if (rl2_write_ascii_grid_scanline (ascii, &line_no) != RL2_OK)
3109 	      goto error;
3110       }
3111 
3112     rl2_destroy_ascii_grid_destination (ascii);
3113     if (palette != NULL)
3114 	rl2_destroy_palette (palette);
3115     return RL2_OK;
3116 
3117   error:
3118     if (ascii != NULL)
3119 	rl2_destroy_ascii_grid_destination (ascii);
3120     if (pixels != NULL)
3121 	free (pixels);
3122     if (palette != NULL)
3123 	rl2_destroy_palette (palette);
3124     return RL2_ERROR;
3125 }
3126 
3127 RL2_DECLARE int
rl2_export_jpeg_from_dbms(sqlite3 * handle,const char * dst_path,rl2CoveragePtr cvg,double x_res,double y_res,double minx,double miny,double maxx,double maxy,unsigned int width,unsigned int height,int quality,int with_worldfile)3128 rl2_export_jpeg_from_dbms (sqlite3 * handle, const char *dst_path,
3129 			   rl2CoveragePtr cvg, double x_res,
3130 			   double y_res, double minx, double miny,
3131 			   double maxx, double maxy,
3132 			   unsigned int width,
3133 			   unsigned int height, int quality, int with_worldfile)
3134 {
3135 /* exporting a JPEG (with possible JGW) from the DBMS into the file-system */
3136     rl2SectionPtr section = NULL;
3137     rl2RasterPtr raster = NULL;
3138     unsigned char level;
3139     unsigned char scale;
3140     double xx_res = x_res;
3141     double yy_res = y_res;
3142     unsigned char sample_type;
3143     unsigned char pixel_type;
3144     unsigned char num_bands;
3145     unsigned char *outbuf = NULL;
3146     int outbuf_size;
3147 
3148     if (rl2_find_matching_resolution
3149 	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
3150 	return RL2_ERROR;
3151 
3152     if (mismatching_size
3153 	(width, height, xx_res, yy_res, minx, miny, maxx, maxy))
3154 	goto error;
3155 
3156     if (rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands) !=
3157 	RL2_OK)
3158 	goto error;
3159     if (sample_type == RL2_SAMPLE_UINT8 && pixel_type == RL2_PIXEL_GRAYSCALE
3160 	&& num_bands == 1)
3161 	;
3162     else if (sample_type == RL2_SAMPLE_UINT8 && pixel_type == RL2_PIXEL_RGB
3163 	     && num_bands == 3)
3164 	;
3165     else
3166 	goto error;
3167 
3168     if (rl2_get_raw_raster_data
3169 	(handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
3170 	 yy_res, &outbuf, &outbuf_size, NULL, pixel_type) != RL2_OK)
3171 	goto error;
3172 
3173     raster =
3174 	rl2_create_raster (width, height, sample_type, pixel_type, num_bands,
3175 			   outbuf, outbuf_size, NULL, NULL, 0, NULL);
3176     outbuf = NULL;
3177     if (raster == NULL)
3178 	goto error;
3179     section =
3180 	rl2_create_section ("jpeg", RL2_COMPRESSION_JPEG, 256, 256, raster);
3181     raster = NULL;
3182     if (section == NULL)
3183 	goto error;
3184     if (rl2_section_to_jpeg (section, dst_path, quality) != RL2_OK)
3185 	goto error;
3186 
3187     if (with_worldfile)
3188       {
3189 	  /* exporting the JGW WorldFile */
3190 	  write_jgw_worldfile (dst_path, minx, maxy, x_res, y_res);
3191       }
3192 
3193     rl2_destroy_section (section);
3194     return RL2_OK;
3195 
3196   error:
3197     if (section != NULL)
3198 	rl2_destroy_section (section);
3199     if (raster != NULL)
3200 	rl2_destroy_raster (raster);
3201     if (outbuf != NULL)
3202 	free (outbuf);
3203     return RL2_ERROR;
3204 }
3205