[librasterlite2] 01/08: Imported Upstream version 1.0.0~rc0+devel

Sebastiaan Couwenberg sebastic at moszumanska.debian.org
Sun Jun 21 12:58:04 UTC 2015


This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch master
in repository librasterlite2.

commit 4e0111156ddd62e30f5b2897f3e44f73a8ed6778
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Sun Jun 21 13:25:05 2015 +0200

    Imported Upstream version 1.0.0~rc0+devel
---
 Android_R4.2.0.mk                                  |   50 -
 Android_R4.3.0.mk                                  |   54 +
 Makefile-static-MinGW                              |   47 +-
 Makefile.am                                        |    8 +-
 Makefile.in                                        |   60 +-
 aclocal.m4                                         |  175 +-
 compile                                            |  347 +
 config.h.in                                        |   42 +-
 configure                                          |  623 +-
 configure.ac                                       |  114 +-
 examples/Makefile.am                               |    8 -
 examples/Makefile.in                               |  597 --
 examples/examples.doxy                             |  152 -
 examples/sample1.c                                 |   68 -
 headers/Makefile.in                                |   28 +-
 headers/rasterlite2/rasterlite2.h                  | 1993 +++-
 headers/rasterlite2/rl2graphics.h                  |  749 +-
 headers/rasterlite2/rl2tiff.h                      |    6 +-
 headers/rasterlite2/rl2wms.h                       |   25 +-
 headers/rasterlite2/sqlite.h                       |    2 +-
 headers/rasterlite2_private.h                      | 1082 ++-
 headers/rl2svg_private.h                           |   44 +-
 rasterlite2-4.2.0.mk                               |   86 -
 rasterlite2-4.3.0.mk                               |  106 +
 src/Makefile.am                                    |   33 +-
 src/Makefile.in                                    |  152 +-
 src/md5.c                                          |  307 +
 src/md5.h                                          |   65 +
 src/rasterlite2.c                                  |  445 +-
 src/rl2ascii.c                                     |  243 +-
 src/rl2auxfont.c                                   |  796 ++
 src/rl2auxgeom.c                                   | 2189 +++++
 src/rl2auxrender.c                                 | 3459 ++++++-
 src/rl2charls.c                                    |  472 +
 src/rl2codec.c                                     | 1304 ++-
 src/rl2dbms.c                                      | 4189 +++++++--
 src/rl2gif.c                                       |    6 +-
 src/rl2import.c                                    | 4476 +++++++--
 src/rl2jpeg.c                                      |  266 +-
 src/rl2md5.c                                       |  116 +
 src/rl2openjpeg.c                                  | 1642 ++++
 src/rl2paint.c                                     | 2192 ++++-
 src/rl2png.c                                       |  844 +-
 src/rl2pyramid.c                                   | 1033 ++-
 src/rl2rastersym.c                                 | 1522 ++-
 src/rl2raw.c                                       | 1135 ++-
 src/rl2sql.c                                       | 9697 ++++++++++++++------
 src/rl2sqlaux.c                                    | 1717 +++-
 src/rl2svg.c                                       |   52 +-
 src/rl2svgaux.c                                    |    2 +-
 src/rl2svgxml.c                                    |    6 +-
 src/rl2symbaux.c                                   | 4360 +++++++++
 src/rl2symbolizer.c                                | 3934 ++++++--
 src/rl2tiff.c                                      |  714 +-
 src/rl2version.c                                   |    2 +-
 src/rl2webp.c                                      |  227 +-
 src/rl2wms.c                                       |  570 +-
 test/Cevennes2.jp2                                 |  Bin 0 -> 17959 bytes
 test/Karla-BoldItalic.ttf                          |  Bin 0 -> 18672 bytes
 test/Makefile.am                                   |   15 +-
 test/Makefile.in                                   |  207 +-
 test/check_sql_stmt.c                              |   14 +-
 test/coverage_style.xml                            |   83 +
 test/ndvi.xml                                      |   98 +
 test/raster_symbolizer_4.xml                       |   11 +-
 test/raster_symbolizer_5.xml                       |    8 +-
 test/raster_symbolizer_6.xml                       |    6 +-
 test/sql_stmt_security_tests/Makefile.am           |  397 +-
 test/sql_stmt_security_tests/Makefile.in           |  423 +-
 test/sql_stmt_security_tests/exportfont1.testcase  |    7 +
 test/sql_stmt_security_tests/exportfont10.testcase |    7 +
 test/sql_stmt_security_tests/exportfont11.testcase |    7 +
 test/sql_stmt_security_tests/exportfont12.testcase |    7 +
 test/sql_stmt_security_tests/exportfont13.testcase |    7 +
 test/sql_stmt_security_tests/exportfont2.testcase  |    7 +
 test/sql_stmt_security_tests/exportfont3.testcase  |    7 +
 test/sql_stmt_security_tests/exportfont4.testcase  |    7 +
 test/sql_stmt_security_tests/exportfont9.testcase  |    7 +
 test/sql_stmt_security_tests/loadfont1.testcase    |    7 +
 test/sql_stmt_security_tests/loadfont2.testcase    |    7 +
 test/sql_stmt_security_tests/loadfont3.testcase    |    7 +
 test/sql_stmt_security_tests/loadfont4.testcase    |    7 +
 test/sql_stmt_security_tests/loadfont5.testcase    |    7 +
 .../writebandtifftfw1.testcase                     |    7 +
 .../writebandtifftfw10.testcase                    |    7 +
 .../writebandtifftfw11.testcase                    |    7 +
 .../writebandtifftfw12.testcase                    |    7 +
 .../writebandtifftfw13.testcase                    |    7 +
 .../writebandtifftfw14.testcase                    |    7 +
 .../writebandtifftfw15.testcase                    |    7 +
 .../writebandtifftfw16.testcase                    |    7 +
 .../writebandtifftfw17.testcase                    |    7 +
 .../writebandtifftfw18.testcase                    |    7 +
 .../writebandtifftfw19.testcase                    |    7 +
 .../writebandtifftfw2.testcase                     |    7 +
 .../writebandtifftfw20.testcase                    |    7 +
 .../writebandtifftfw21.testcase                    |    7 +
 .../writebandtifftfw22.testcase                    |    7 +
 .../writebandtifftfw23.testcase                    |    7 +
 .../writebandtifftfw24.testcase                    |    7 +
 .../writebandtifftfw25.testcase                    |    7 +
 .../writebandtifftfw26.testcase                    |    7 +
 .../writebandtifftfw27.testcase                    |    7 +
 .../writebandtifftfw3.testcase                     |    7 +
 .../writebandtifftfw4.testcase                     |    7 +
 .../writebandtifftfw5.testcase                     |    7 +
 .../writebandtifftfw6.testcase                     |    7 +
 .../writebandtifftfw7.testcase                     |    7 +
 .../writebandtifftfw8.testcase                     |    7 +
 .../writebandtifftfw9.testcase                     |    7 +
 .../sql_stmt_security_tests/writejpegjgw1.testcase |    7 +
 .../writejpegjgw10.testcase                        |    7 +
 .../writejpegjgw11.testcase                        |    7 +
 .../writejpegjgw12.testcase                        |    7 +
 .../writejpegjgw13.testcase                        |    7 +
 .../writejpegjgw14.testcase                        |    7 +
 .../writejpegjgw15.testcase                        |    7 +
 .../sql_stmt_security_tests/writejpegjgw2.testcase |    7 +
 .../sql_stmt_security_tests/writejpegjgw3.testcase |    7 +
 .../sql_stmt_security_tests/writejpegjgw4.testcase |    7 +
 .../sql_stmt_security_tests/writejpegjgw5.testcase |    7 +
 .../sql_stmt_security_tests/writejpegjgw6.testcase |    7 +
 .../sql_stmt_security_tests/writejpegjgw7.testcase |    7 +
 .../sql_stmt_security_tests/writejpegjgw8.testcase |    7 +
 .../sql_stmt_security_tests/writejpegjgw9.testcase |    7 +
 .../writemonotifftfw1.testcase                     |    7 +
 .../writemonotifftfw10.testcase                    |    7 +
 .../writemonotifftfw11.testcase                    |    7 +
 .../writemonotifftfw12.testcase                    |    7 +
 .../writemonotifftfw13.testcase                    |    7 +
 .../writemonotifftfw14.testcase                    |    7 +
 .../writemonotifftfw15.testcase                    |    7 +
 .../writemonotifftfw16.testcase                    |    7 +
 .../writemonotifftfw17.testcase                    |    7 +
 .../writemonotifftfw18.testcase                    |    7 +
 .../writemonotifftfw19.testcase                    |    7 +
 .../writemonotifftfw2.testcase                     |    7 +
 .../writemonotifftfw20.testcase                    |    7 +
 .../writemonotifftfw21.testcase                    |    7 +
 .../writemonotifftfw3.testcase                     |    7 +
 .../writemonotifftfw4.testcase                     |    7 +
 .../writemonotifftfw5.testcase                     |    7 +
 .../writemonotifftfw6.testcase                     |    7 +
 .../writemonotifftfw7.testcase                     |    7 +
 .../writemonotifftfw8.testcase                     |    7 +
 .../writemonotifftfw9.testcase                     |    7 +
 .../writendviascii1.testcase                       |    7 +
 .../writendviascii10.testcase                      |    7 +
 .../writendviascii11.testcase                      |    7 +
 .../writendviascii12.testcase                      |    7 +
 .../writendviascii13.testcase                      |    7 +
 .../writendviascii14.testcase                      |    7 +
 .../writendviascii15.testcase                      |    7 +
 .../writendviascii16.testcase                      |    7 +
 .../writendviascii17.testcase                      |    7 +
 .../writendviascii18.testcase                      |    7 +
 .../writendviascii2.testcase                       |    7 +
 .../writendviascii3.testcase                       |    7 +
 .../writendviascii4.testcase                       |    7 +
 .../writendviascii5.testcase                       |    7 +
 .../writendviascii6.testcase                       |    7 +
 .../writendviascii7.testcase                       |    7 +
 .../writendviascii8.testcase                       |    7 +
 .../writendviascii9.testcase                       |    7 +
 .../writesectionascii1.testcase                    |    7 +
 .../writesectionascii10.testcase                   |    7 +
 .../writesectionascii11.testcase                   |    7 +
 .../writesectionascii12.testcase                   |    7 +
 .../writesectionascii13.testcase                   |    7 +
 .../writesectionascii14.testcase                   |    7 +
 .../writesectionascii15.testcase                   |    7 +
 .../writesectionascii16.testcase                   |    7 +
 .../writesectionascii17.testcase                   |    7 +
 .../writesectionascii18.testcase                   |    7 +
 .../writesectionascii2.testcase                    |    7 +
 .../writesectionascii3.testcase                    |    7 +
 .../writesectionascii4.testcase                    |    7 +
 .../writesectionascii5.testcase                    |    7 +
 .../writesectionascii6.testcase                    |    7 +
 .../writesectionascii7.testcase                    |    7 +
 .../writesectionascii9.testcase                    |    7 +
 .../writesectionbandgeotiff1.testcase              |    7 +
 .../writesectionbandgeotiff10.testcase             |    7 +
 .../writesectionbandgeotiff11.testcase             |    7 +
 .../writesectionbandgeotiff12.testcase             |    7 +
 .../writesectionbandgeotiff13.testcase             |    7 +
 .../writesectionbandgeotiff14.testcase             |    7 +
 .../writesectionbandgeotiff15.testcase             |    7 +
 .../writesectionbandgeotiff16.testcase             |    7 +
 .../writesectionbandgeotiff17.testcase             |    7 +
 .../writesectionbandgeotiff18.testcase             |    7 +
 .../writesectionbandgeotiff19.testcase             |    7 +
 .../writesectionbandgeotiff2.testcase              |    7 +
 .../writesectionbandgeotiff20.testcase             |    7 +
 .../writesectionbandgeotiff21.testcase             |    7 +
 .../writesectionbandgeotiff22.testcase             |    7 +
 .../writesectionbandgeotiff23.testcase             |    7 +
 .../writesectionbandgeotiff24.testcase             |    7 +
 .../writesectionbandgeotiff25.testcase             |    7 +
 .../writesectionbandgeotiff26.testcase             |    7 +
 .../writesectionbandgeotiff27.testcase             |    7 +
 .../writesectionbandgeotiff28.testcase             |    7 +
 .../writesectionbandgeotiff29.testcase             |    7 +
 .../writesectionbandgeotiff3.testcase              |    7 +
 .../writesectionbandgeotiff4.testcase              |    7 +
 .../writesectionbandgeotiff5.testcase              |    7 +
 .../writesectionbandgeotiff6.testcase              |    7 +
 .../writesectionbandgeotiff7.testcase              |    7 +
 .../writesectionbandgeotiff8.testcase              |    7 +
 .../writesectionbandgeotiff9.testcase              |    7 +
 .../writesectionbandtiff1.testcase                 |    7 +
 .../writesectionbandtiff10.testcase                |    7 +
 .../writesectionbandtiff11.testcase                |    7 +
 .../writesectionbandtiff12.testcase                |    7 +
 .../writesectionbandtiff13.testcase                |    7 +
 .../writesectionbandtiff14.testcase                |    7 +
 .../writesectionbandtiff15.testcase                |    7 +
 .../writesectionbandtiff16.testcase                |    7 +
 .../writesectionbandtiff17.testcase                |    7 +
 .../writesectionbandtiff18.testcase                |    7 +
 .../writesectionbandtiff19.testcase                |    7 +
 .../writesectionbandtiff2.testcase                 |    7 +
 .../writesectionbandtiff20.testcase                |    7 +
 .../writesectionbandtiff21.testcase                |    7 +
 .../writesectionbandtiff22.testcase                |    7 +
 .../writesectionbandtiff23.testcase                |    7 +
 .../writesectionbandtiff24.testcase                |    7 +
 .../writesectionbandtiff25.testcase                |    7 +
 .../writesectionbandtiff26.testcase                |    7 +
 .../writesectionbandtiff27.testcase                |    7 +
 .../writesectionbandtiff28.testcase                |    7 +
 .../writesectionbandtiff3.testcase                 |    7 +
 .../writesectionbandtiff4.testcase                 |    7 +
 .../writesectionbandtiff5.testcase                 |    7 +
 .../writesectionbandtiff6.testcase                 |    7 +
 .../writesectionbandtiff7.testcase                 |    7 +
 .../writesectionbandtiff8.testcase                 |    7 +
 .../writesectionbandtiff9.testcase                 |    7 +
 .../writesectionbandtifftfw1.testcase              |    7 +
 .../writesectionbandtifftfw10.testcase             |    7 +
 .../writesectionbandtifftfw11.testcase             |    7 +
 .../writesectionbandtifftfw12.testcase             |    7 +
 .../writesectionbandtifftfw13.testcase             |    7 +
 .../writesectionbandtifftfw14.testcase             |    7 +
 .../writesectionbandtifftfw15.testcase             |    7 +
 .../writesectionbandtifftfw16.testcase             |    7 +
 .../writesectionbandtifftfw17.testcase             |    7 +
 .../writesectionbandtifftfw18.testcase             |    7 +
 .../writesectionbandtifftfw19.testcase             |    7 +
 .../writesectionbandtifftfw2.testcase              |    7 +
 .../writesectionbandtifftfw20.testcase             |    7 +
 .../writesectionbandtifftfw21.testcase             |    7 +
 .../writesectionbandtifftfw22.testcase             |    7 +
 .../writesectionbandtifftfw23.testcase             |    7 +
 .../writesectionbandtifftfw24.testcase             |    7 +
 .../writesectionbandtifftfw25.testcase             |    7 +
 .../writesectionbandtifftfw26.testcase             |    7 +
 .../writesectionbandtifftfw27.testcase             |    7 +
 .../writesectionbandtifftfw28.testcase             |    7 +
 .../writesectionbandtifftfw3.testcase              |    7 +
 .../writesectionbandtifftfw4.testcase              |    7 +
 .../writesectionbandtifftfw5.testcase              |    7 +
 .../writesectionbandtifftfw6.testcase              |    7 +
 .../writesectionbandtifftfw7.testcase              |    7 +
 .../writesectionbandtifftfw8.testcase              |    7 +
 .../writesectionbandtifftfw9.testcase              |    7 +
 .../writesectiongeotiff1.testcase                  |    7 +
 .../writesectiongeotiff10.testcase                 |    7 +
 .../writesectiongeotiff11.testcase                 |    7 +
 .../writesectiongeotiff12.testcase                 |    7 +
 .../writesectiongeotiff13.testcase                 |    7 +
 .../writesectiongeotiff14.testcase                 |    7 +
 .../writesectiongeotiff15.testcase                 |    7 +
 .../writesectiongeotiff16.testcase                 |    7 +
 .../writesectiongeotiff17.testcase                 |    7 +
 .../writesectiongeotiff18.testcase                 |    7 +
 .../writesectiongeotiff19.testcase                 |    7 +
 .../writesectiongeotiff2.testcase                  |    7 +
 .../writesectiongeotiff20.testcase                 |    7 +
 .../writesectiongeotiff3.testcase                  |    7 +
 .../writesectiongeotiff4.testcase                  |    7 +
 .../writesectiongeotiff5.testcase                  |    7 +
 .../writesectiongeotiff6.testcase                  |    7 +
 .../writesectiongeotiff7.testcase                  |    7 +
 .../writesectiongeotiff8.testcase                  |    7 +
 .../writesectiongeotiff9.testcase                  |    7 +
 .../writesectionjpeg1.testcase                     |    7 +
 .../writesectionjpeg10.testcase                    |    7 +
 .../writesectionjpeg11.testcase                    |    7 +
 .../writesectionjpeg12.testcase                    |    7 +
 .../writesectionjpeg13.testcase                    |    7 +
 .../writesectionjpeg14.testcase                    |    7 +
 .../writesectionjpeg15.testcase                    |    7 +
 .../writesectionjpeg16.testcase                    |    7 +
 .../writesectionjpeg2.testcase                     |    7 +
 .../writesectionjpeg3.testcase                     |    7 +
 .../writesectionjpeg4.testcase                     |    7 +
 .../writesectionjpeg5.testcase                     |    7 +
 .../writesectionjpeg6.testcase                     |    7 +
 .../writesectionjpeg7.testcase                     |    7 +
 .../writesectionjpeg8.testcase                     |    7 +
 .../writesectionjpeg9.testcase                     |    7 +
 .../writesectionjpegjgw1.testcase                  |    7 +
 .../writesectionjpegjgw10.testcase                 |    7 +
 .../writesectionjpegjgw11.testcase                 |    7 +
 .../writesectionjpegjgw12.testcase                 |    7 +
 .../writesectionjpegjgw13.testcase                 |    7 +
 .../writesectionjpegjgw14.testcase                 |    7 +
 .../writesectionjpegjgw15.testcase                 |    7 +
 .../writesectionjpegjgw16.testcase                 |    7 +
 .../writesectionjpegjgw2.testcase                  |    7 +
 .../writesectionjpegjgw3.testcase                  |    7 +
 .../writesectionjpegjgw4.testcase                  |    7 +
 .../writesectionjpegjgw5.testcase                  |    7 +
 .../writesectionjpegjgw6.testcase                  |    7 +
 .../writesectionjpegjgw7.testcase                  |    7 +
 .../writesectionjpegjgw8.testcase                  |    7 +
 .../writesectionjpegjgw9.testcase                  |    7 +
 .../writesectionmonogeotiff1.testcase              |    7 +
 .../writesectionmonogeotiff10.testcase             |    7 +
 .../writesectionmonogeotiff11.testcase             |    7 +
 .../writesectionmonogeotiff12.testcase             |    7 +
 .../writesectionmonogeotiff13.testcase             |    7 +
 .../writesectionmonogeotiff14.testcase             |    7 +
 .../writesectionmonogeotiff15.testcase             |    7 +
 .../writesectionmonogeotiff16.testcase             |    7 +
 .../writesectionmonogeotiff17.testcase             |    7 +
 .../writesectionmonogeotiff18.testcase             |    7 +
 .../writesectionmonogeotiff19.testcase             |    7 +
 .../writesectionmonogeotiff2.testcase              |    7 +
 .../writesectionmonogeotiff20.testcase             |    7 +
 .../writesectionmonogeotiff21.testcase             |    7 +
 .../writesectionmonogeotiff22.testcase             |    7 +
 .../writesectionmonogeotiff23.testcase             |    7 +
 .../writesectionmonogeotiff3.testcase              |    7 +
 .../writesectionmonogeotiff4.testcase              |    7 +
 .../writesectionmonogeotiff5.testcase              |    7 +
 .../writesectionmonogeotiff6.testcase              |    7 +
 .../writesectionmonogeotiff7.testcase              |    7 +
 .../writesectionmonogeotiff8.testcase              |    7 +
 .../writesectionmonogeotiff9.testcase              |    7 +
 .../writesectionmonotiff1.testcase                 |    7 +
 .../writesectionmonotiff10.testcase                |    7 +
 .../writesectionmonotiff11.testcase                |    7 +
 .../writesectionmonotiff12.testcase                |    7 +
 .../writesectionmonotiff13.testcase                |    7 +
 .../writesectionmonotiff14.testcase                |    7 +
 .../writesectionmonotiff15.testcase                |    7 +
 .../writesectionmonotiff16.testcase                |    7 +
 .../writesectionmonotiff17.testcase                |    7 +
 .../writesectionmonotiff18.testcase                |    7 +
 .../writesectionmonotiff19.testcase                |    7 +
 .../writesectionmonotiff2.testcase                 |    7 +
 .../writesectionmonotiff20.testcase                |    7 +
 .../writesectionmonotiff21.testcase                |    7 +
 .../writesectionmonotiff22.testcase                |    7 +
 .../writesectionmonotiff3.testcase                 |    7 +
 .../writesectionmonotiff4.testcase                 |    7 +
 .../writesectionmonotiff5.testcase                 |    7 +
 .../writesectionmonotiff6.testcase                 |    7 +
 .../writesectionmonotiff7.testcase                 |    7 +
 .../writesectionmonotiff8.testcase                 |    7 +
 .../writesectionmonotiff9.testcase                 |    7 +
 .../writesectionmonotifftfw1.testcase              |    7 +
 .../writesectionmonotifftfw10.testcase             |    7 +
 .../writesectionmonotifftfw11.testcase             |    7 +
 .../writesectionmonotifftfw12.testcase             |    7 +
 .../writesectionmonotifftfw13.testcase             |    7 +
 .../writesectionmonotifftfw14.testcase             |    7 +
 .../writesectionmonotifftfw15.testcase             |    7 +
 .../writesectionmonotifftfw16.testcase             |    7 +
 .../writesectionmonotifftfw17.testcase             |    7 +
 .../writesectionmonotifftfw18.testcase             |    7 +
 .../writesectionmonotifftfw19.testcase             |    7 +
 .../writesectionmonotifftfw2.testcase              |    7 +
 .../writesectionmonotifftfw20.testcase             |    7 +
 .../writesectionmonotifftfw21.testcase             |    7 +
 .../writesectionmonotifftfw22.testcase             |    7 +
 .../writesectionmonotifftfw3.testcase              |    7 +
 .../writesectionmonotifftfw4.testcase              |    7 +
 .../writesectionmonotifftfw5.testcase              |    7 +
 .../writesectionmonotifftfw6.testcase              |    7 +
 .../writesectionmonotifftfw7.testcase              |    7 +
 .../writesectionmonotifftfw8.testcase              |    7 +
 .../writesectionmonotifftfw9.testcase              |    7 +
 .../writesectionndviascii1.testcase                |    7 +
 .../writesectionndviascii10.testcase               |    7 +
 .../writesectionndviascii11.testcase               |    7 +
 .../writesectionndviascii12.testcase               |    7 +
 .../writesectionndviascii13.testcase               |    7 +
 .../writesectionndviascii14.testcase               |    7 +
 .../writesectionndviascii15.testcase               |    7 +
 .../writesectionndviascii16.testcase               |    7 +
 .../writesectionndviascii17.testcase               |    7 +
 .../writesectionndviascii18.testcase               |    7 +
 .../writesectionndviascii19.testcase               |    7 +
 .../writesectionndviascii2.testcase                |    7 +
 .../writesectionndviascii20.testcase               |    7 +
 .../writesectionndviascii3.testcase                |    7 +
 .../writesectionndviascii4.testcase                |    7 +
 .../writesectionndviascii5.testcase                |    7 +
 .../writesectionndviascii6.testcase                |    7 +
 .../writesectionndviascii7.testcase                |    7 +
 .../writesectionndviascii8.testcase                |    7 +
 .../writesectionndviascii9.testcase                |    7 +
 .../writesectiontiff1.testcase                     |    7 +
 .../writesectiontiff10.testcase                    |    7 +
 .../writesectiontiff11.testcase                    |    7 +
 .../writesectiontiff12.testcase                    |    7 +
 .../writesectiontiff13.testcase                    |    7 +
 .../writesectiontiff14.testcase                    |    7 +
 .../writesectiontiff15.testcase                    |    7 +
 .../writesectiontiff16.testcase                    |    7 +
 .../writesectiontiff17.testcase                    |    7 +
 .../writesectiontiff18.testcase                    |    7 +
 .../writesectiontiff19.testcase                    |    7 +
 .../writesectiontiff2.testcase                     |    7 +
 .../writesectiontiff3.testcase                     |    7 +
 .../writesectiontiff4.testcase                     |    7 +
 .../writesectiontiff5.testcase                     |    7 +
 .../writesectiontiff6.testcase                     |    7 +
 .../writesectiontiff7.testcase                     |    7 +
 .../writesectiontiff8.testcase                     |    7 +
 .../writesectiontiff9.testcase                     |    7 +
 .../writesectiontifftfw1.testcase                  |    7 +
 .../writesectiontifftfw10.testcase                 |    7 +
 .../writesectiontifftfw11.testcase                 |    7 +
 .../writesectiontifftfw12.testcase                 |    7 +
 .../writesectiontifftfw13.testcase                 |    7 +
 .../writesectiontifftfw14.testcase                 |    7 +
 .../writesectiontifftfw15.testcase                 |    7 +
 .../writesectiontifftfw16.testcase                 |    7 +
 .../writesectiontifftfw17.testcase                 |    7 +
 .../writesectiontifftfw18.testcase                 |    7 +
 .../writesectiontifftfw19.testcase                 |    7 +
 .../writesectiontifftfw2.testcase                  |    7 +
 .../writesectiontifftfw3.testcase                  |    7 +
 .../writesectiontifftfw4.testcase                  |    7 +
 .../writesectiontifftfw5.testcase                  |    7 +
 .../writesectiontifftfw6.testcase                  |    7 +
 .../writesectiontifftfw7.testcase                  |    7 +
 .../writesectiontifftfw8.testcase                  |    7 +
 .../writesectiontifftfw9.testcase                  |    7 +
 .../sql_stmt_security_tests/writetifftfw1.testcase |    7 +
 .../writetifftfw10.testcase                        |    7 +
 .../writetifftfw11.testcase                        |    7 +
 .../writetifftfw12.testcase                        |    7 +
 .../writetifftfw13.testcase                        |    7 +
 .../writetifftfw14.testcase                        |    7 +
 .../writetifftfw15.testcase                        |    7 +
 .../writetifftfw16.testcase                        |    7 +
 .../writetifftfw17.testcase                        |    7 +
 .../writetifftfw18.testcase                        |    7 +
 .../sql_stmt_security_tests/writetifftfw2.testcase |    7 +
 .../sql_stmt_security_tests/writetifftfw3.testcase |    7 +
 .../sql_stmt_security_tests/writetifftfw4.testcase |    7 +
 .../sql_stmt_security_tests/writetifftfw5.testcase |    7 +
 .../sql_stmt_security_tests/writetifftfw6.testcase |    7 +
 .../sql_stmt_security_tests/writetifftfw7.testcase |    7 +
 .../sql_stmt_security_tests/writetifftfw8.testcase |    7 +
 .../sql_stmt_security_tests/writetifftfw9.testcase |    7 +
 test/sql_stmt_tests/Makefile.am                    |  162 +-
 test/sql_stmt_tests/Makefile.in                    |  188 +-
 test/sql_stmt_tests/copyrastercov1.testcase        |    7 +
 test/sql_stmt_tests/copyrastercov10.testcase       |    7 +
 test/sql_stmt_tests/copyrastercov11.testcase       |    7 +
 test/sql_stmt_tests/copyrastercov12.testcase       |    7 +
 test/sql_stmt_tests/copyrastercov13.testcase       |    7 +
 test/sql_stmt_tests/copyrastercov14.testcase       |    7 +
 test/sql_stmt_tests/copyrastercov2.testcase        |    7 +
 test/sql_stmt_tests/copyrastercov3.testcase        |    7 +
 test/sql_stmt_tests/copyrastercov4.testcase        |    7 +
 test/sql_stmt_tests/copyrastercov5.testcase        |    7 +
 test/sql_stmt_tests/copyrastercov6.testcase        |    7 +
 test/sql_stmt_tests/copyrastercov7.testcase        |    7 +
 test/sql_stmt_tests/copyrastercov8.testcase        |    7 +
 test/sql_stmt_tests/copyrastercov9.testcase        |    7 +
 test/sql_stmt_tests/createcov_16_mband.testcase    |    6 +-
 test/sql_stmt_tests/createcov_16_mband1.testcase   |    6 +-
 .../createcov_16_mband_deflate.testcase            |    6 +-
 .../createcov_16_mband_deflateno.testcase          |    7 +
 .../createcov_16_mband_fax3.testcase               |    6 +-
 .../createcov_16_mband_fax4.testcase               |    6 +-
 .../sql_stmt_tests/createcov_16_mband_gif.testcase |    6 +-
 .../createcov_16_mband_jpeg.testcase               |    6 +-
 .../createcov_16_mband_lzma.testcase               |    6 +-
 .../createcov_16_mband_lzmano.testcase             |    7 +
 .../sql_stmt_tests/createcov_16_mband_png.testcase |    8 +-
 .../createcov_16_mband_webp1.testcase              |    6 +-
 .../createcov_16_mband_webp2.testcase              |    6 +-
 test/sql_stmt_tests/createcov_1bit_mono.testcase   |    6 +-
 test/sql_stmt_tests/createcov_1bit_mono1.testcase  |    6 +-
 .../createcov_1bit_mono_deflate.testcase           |    8 +-
 .../createcov_1bit_mono_deflateno.testcase         |    7 +
 .../createcov_1bit_mono_fax3.testcase              |    6 +-
 .../createcov_1bit_mono_fax4.testcase              |    6 +-
 .../createcov_1bit_mono_gif.testcase               |    6 +-
 .../createcov_1bit_mono_jpeg.testcase              |    6 +-
 .../createcov_1bit_mono_lzma.testcase              |    8 +-
 .../createcov_1bit_mono_lzmano.testcase            |    7 +
 .../createcov_1bit_mono_png.testcase               |    6 +-
 .../createcov_1bit_mono_webp1.testcase             |    6 +-
 .../createcov_1bit_mono_webp2.testcase             |    6 +-
 .../sql_stmt_tests/createcov_1bit_palette.testcase |    6 +-
 .../createcov_1bit_palette1.testcase               |    6 +-
 .../createcov_1bit_palette_gif.testcase            |    6 +-
 .../createcov_1bit_palette_png.testcase            |    6 +-
 test/sql_stmt_tests/createcov_2bit_gray.testcase   |    6 +-
 test/sql_stmt_tests/createcov_2bit_gray1.testcase  |    6 +-
 .../createcov_2bit_gray_gif.testcase               |    6 +-
 .../createcov_2bit_gray_jpeg.testcase              |    6 +-
 .../createcov_2bit_gray_png.testcase               |    6 +-
 .../createcov_2bit_gray_webp1.testcase             |    6 +-
 .../createcov_2bit_gray_webp2.testcase             |    6 +-
 .../sql_stmt_tests/createcov_2bit_palette.testcase |    6 +-
 .../createcov_2bit_palette1.testcase               |    6 +-
 .../createcov_2bit_palette_gif.testcase            |    6 +-
 .../createcov_2bit_palette_png.testcase            |    6 +-
 test/sql_stmt_tests/createcov_4bit_gray.testcase   |    6 +-
 test/sql_stmt_tests/createcov_4bit_gray1.testcase  |    6 +-
 .../createcov_4bit_gray_gif.testcase               |    6 +-
 .../createcov_4bit_gray_jpeg.testcase              |    6 +-
 .../createcov_4bit_gray_png.testcase               |    6 +-
 .../createcov_4bit_gray_webp1.testcase             |    6 +-
 .../createcov_4bit_gray_webp2.testcase             |    6 +-
 .../sql_stmt_tests/createcov_4bit_palette.testcase |    6 +-
 .../createcov_4bit_palette1.testcase               |    6 +-
 .../createcov_4bit_palette_gif.testcase            |    6 +-
 .../createcov_4bit_palette_png.testcase            |    6 +-
 test/sql_stmt_tests/createcov_8_mband.testcase     |    6 +-
 test/sql_stmt_tests/createcov_8_mband1.testcase    |    6 +-
 .../createcov_8_mband_deflate.testcase             |    6 +-
 .../createcov_8_mband_deflateno.testcase           |    7 +
 .../sql_stmt_tests/createcov_8_mband_fax3.testcase |    6 +-
 .../sql_stmt_tests/createcov_8_mband_fax4.testcase |    6 +-
 test/sql_stmt_tests/createcov_8_mband_gif.testcase |    6 +-
 .../sql_stmt_tests/createcov_8_mband_jpeg.testcase |    6 +-
 .../sql_stmt_tests/createcov_8_mband_lzma.testcase |    6 +-
 .../createcov_8_mband_lzmano.testcase              |    7 +
 test/sql_stmt_tests/createcov_8_mband_png.testcase |    8 +-
 .../createcov_8_mband_webp1.testcase               |    8 +-
 .../createcov_8_mband_webp2.testcase               |    8 +-
 test/sql_stmt_tests/createcov_double_grid.testcase |    6 +-
 .../sql_stmt_tests/createcov_double_grid1.testcase |    6 +-
 .../createcov_double_grid_deflate.testcase         |    6 +-
 .../createcov_double_grid_deflateno.testcase       |    7 +
 .../createcov_double_grid_lzma.testcase            |    6 +-
 .../createcov_double_grid_lzmano.testcase          |    7 +
 test/sql_stmt_tests/createcov_err1.testcase        |    6 +-
 test/sql_stmt_tests/createcov_err10.testcase       |    6 +-
 test/sql_stmt_tests/createcov_err11.testcase       |    6 +-
 test/sql_stmt_tests/createcov_err12.testcase       |    6 +-
 test/sql_stmt_tests/createcov_err13.testcase       |    7 +
 test/sql_stmt_tests/createcov_err14.testcase       |    7 +
 test/sql_stmt_tests/createcov_err15.testcase       |    7 +
 test/sql_stmt_tests/createcov_err16.testcase       |    7 +
 test/sql_stmt_tests/createcov_err17.testcase       |    7 +
 test/sql_stmt_tests/createcov_err2.testcase        |    6 +-
 test/sql_stmt_tests/createcov_err3.testcase        |    6 +-
 test/sql_stmt_tests/createcov_err4.testcase        |    6 +-
 test/sql_stmt_tests/createcov_err5.testcase        |    6 +-
 test/sql_stmt_tests/createcov_err6.testcase        |    6 +-
 test/sql_stmt_tests/createcov_err7.testcase        |    6 +-
 test/sql_stmt_tests/createcov_err8.testcase        |    6 +-
 test/sql_stmt_tests/createcov_err9.testcase        |    6 +-
 test/sql_stmt_tests/createcov_float_grid.testcase  |    6 +-
 test/sql_stmt_tests/createcov_float_grid1.testcase |    6 +-
 .../createcov_float_grid_deflate.testcase          |    6 +-
 .../createcov_float_grid_deflateno.testcase        |    7 +
 .../createcov_float_grid_lzma.testcase             |    6 +-
 .../createcov_float_grid_lzmano.testcase           |    7 +
 test/sql_stmt_tests/createcov_int16_grid.testcase  |    6 +-
 test/sql_stmt_tests/createcov_int16_grid1.testcase |    6 +-
 .../createcov_int16_grid_deflate.testcase          |    6 +-
 .../createcov_int16_grid_deflateno.testcase        |    7 +
 .../createcov_int16_grid_lzma.testcase             |    6 +-
 .../createcov_int16_grid_lzmano.testcase           |    7 +
 test/sql_stmt_tests/createcov_int32_grid.testcase  |    6 +-
 test/sql_stmt_tests/createcov_int32_grid1.testcase |    6 +-
 .../createcov_int32_grid_deflate.testcase          |    6 +-
 .../createcov_int32_grid_deflateno.testcase        |    7 +
 .../createcov_int32_grid_gif.testcase              |    6 +-
 .../createcov_int32_grid_jpeg.testcase             |    6 +-
 .../createcov_int32_grid_lzma.testcase             |    6 +-
 .../createcov_int32_grid_lzmano.testcase           |    7 +
 .../createcov_int32_grid_png.testcase              |    6 +-
 .../createcov_int32_grid_webp1.testcase            |    6 +-
 .../createcov_int32_grid_webp2.testcase            |    6 +-
 test/sql_stmt_tests/createcov_int8_grid.testcase   |    6 +-
 test/sql_stmt_tests/createcov_int8_grid1.testcase  |    6 +-
 .../createcov_int8_grid_deflate.testcase           |    6 +-
 .../createcov_int8_grid_deflateno.testcase         |    7 +
 .../createcov_int8_grid_lzma.testcase              |    6 +-
 .../createcov_int8_grid_lzmano.testcase            |    7 +
 test/sql_stmt_tests/createcov_uint16_grid.testcase |    6 +-
 .../sql_stmt_tests/createcov_uint16_grid1.testcase |    6 +-
 .../createcov_uint16_grid_deflate.testcase         |    6 +-
 .../createcov_uint16_grid_deflateno.testcase       |    7 +
 .../createcov_uint16_grid_lzma.testcase            |    6 +-
 .../createcov_uint16_grid_lzmano.testcase          |    7 +
 test/sql_stmt_tests/createcov_uint32_grid.testcase |    6 +-
 .../sql_stmt_tests/createcov_uint32_grid1.testcase |    6 +-
 .../createcov_uint32_grid_deflate.testcase         |    6 +-
 .../createcov_uint32_grid_deflateno.testcase       |    7 +
 .../createcov_uint32_grid_lzma.testcase            |    6 +-
 .../createcov_uint32_grid_lzmano.testcase          |    7 +
 test/sql_stmt_tests/createcov_uint8_gray.testcase  |    6 +-
 .../createcov_uint8_gray_deflate.testcase          |    8 +-
 .../createcov_uint8_gray_deflateno.testcase        |    7 +
 .../createcov_uint8_gray_fax3.testcase             |    6 +-
 .../createcov_uint8_gray_fax4.testcase             |    6 +-
 .../createcov_uint8_gray_gif.testcase              |    6 +-
 .../createcov_uint8_gray_jpeg.testcase             |    6 +-
 .../createcov_uint8_gray_lzma.testcase             |    8 +-
 .../createcov_uint8_gray_lzmano.testcase           |    7 +
 .../createcov_uint8_gray_png.testcase              |    6 +-
 .../createcov_uint8_gray_webp1.testcase            |    6 +-
 .../createcov_uint8_gray_webp2.testcase            |    6 +-
 test/sql_stmt_tests/createcov_uint8_grid.testcase  |    6 +-
 test/sql_stmt_tests/createcov_uint8_grid1.testcase |    6 +-
 .../createcov_uint8_grid_deflate.testcase          |    6 +-
 .../createcov_uint8_grid_deflateno.testcase        |    7 +
 .../createcov_uint8_grid_lzma.testcase             |    6 +-
 .../createcov_uint8_grid_lzmano.testcase           |    7 +
 .../createcov_uint8_palette.testcase               |    6 +-
 .../createcov_uint8_palette_deflate.testcase       |    8 +-
 .../createcov_uint8_palette_deflateno.testcase     |    7 +
 .../createcov_uint8_palette_fax3.testcase          |    6 +-
 .../createcov_uint8_palette_fax4.testcase          |    6 +-
 .../createcov_uint8_palette_gif.testcase           |    6 +-
 .../createcov_uint8_palette_jpeg.testcase          |    6 +-
 .../createcov_uint8_palette_lzma.testcase          |    8 +-
 .../createcov_uint8_palette_lzmano.testcase        |    7 +
 .../createcov_uint8_palette_png.testcase           |    6 +-
 .../createcov_uint8_palette_webp1.testcase         |    6 +-
 .../createcov_uint8_palette_webp2.testcase         |    6 +-
 test/sql_stmt_tests/createcov_uint8_rgb.testcase   |    6 +-
 test/sql_stmt_tests/createcov_uint8_rgb1.testcase  |    6 +-
 .../createcov_uint8_rgb_deflate.testcase           |    8 +-
 .../createcov_uint8_rgb_deflateno.testcase         |    7 +
 .../createcov_uint8_rgb_fax3.testcase              |    6 +-
 .../createcov_uint8_rgb_fax4.testcase              |    6 +-
 .../createcov_uint8_rgb_gif.testcase               |    6 +-
 .../createcov_uint8_rgb_jpeg.testcase              |    6 +-
 .../createcov_uint8_rgb_lzma.testcase              |    8 +-
 .../createcov_uint8_rgb_lzmano.testcase            |    7 +
 .../createcov_uint8_rgb_png.testcase               |    6 +-
 .../createcov_uint8_rgb_webp1.testcase             |    6 +-
 .../createcov_uint8_rgb_webp2.testcase             |    6 +-
 test/sql_stmt_tests/deletesection3.testcase        |    4 +-
 test/sql_stmt_tests/deletesection4.testcase        |    4 +-
 test/sql_stmt_tests/depyramidize10.testcase        |    4 +-
 test/sql_stmt_tests/depyramidize11.testcase        |    4 +-
 test/sql_stmt_tests/depyramidize12.testcase        |    4 +-
 test/sql_stmt_tests/depyramidize6.testcase         |    6 +-
 test/sql_stmt_tests/depyramidize9.testcase         |    4 +-
 test/sql_stmt_tests/dropcoverage1.testcase         |    6 +-
 test/sql_stmt_tests/dropcoverage2.testcase         |    6 +-
 test/sql_stmt_tests/dropcoverage3.testcase         |    6 +-
 test/sql_stmt_tests/enableautondvi1.testcase       |    7 +
 test/sql_stmt_tests/enableautondvi2.testcase       |    7 +
 test/sql_stmt_tests/enableautondvi3.testcase       |    7 +
 test/sql_stmt_tests/exportraw1.testcase            |    7 +
 test/sql_stmt_tests/exportraw2.testcase            |    7 +
 test/sql_stmt_tests/exportraw3.testcase            |    7 +
 test/sql_stmt_tests/exportraw4.testcase            |    7 +
 test/sql_stmt_tests/exportraw5.testcase            |    7 +
 test/sql_stmt_tests/exportraw6.testcase            |    7 +
 test/sql_stmt_tests/exportraw7.testcase            |    7 +
 test/sql_stmt_tests/exportraw8.testcase            |    7 +
 test/sql_stmt_tests/exportsectraw1.testcase        |    7 +
 test/sql_stmt_tests/exportsectraw2.testcase        |    7 +
 test/sql_stmt_tests/exportsectraw3.testcase        |    7 +
 test/sql_stmt_tests/exportsectraw4.testcase        |    7 +
 test/sql_stmt_tests/exportsectraw5.testcase        |    7 +
 test/sql_stmt_tests/exportsectraw6.testcase        |    7 +
 test/sql_stmt_tests/exportsectraw7.testcase        |    7 +
 test/sql_stmt_tests/exportsectraw8.testcase        |    7 +
 test/sql_stmt_tests/exportsectraw9.testcase        |    7 +
 test/sql_stmt_tests/getfontfacename1.testcase      |    7 +
 test/sql_stmt_tests/getfontfacename2.testcase      |    7 +
 test/sql_stmt_tests/getfontfacename3.testcase      |    7 +
 test/sql_stmt_tests/getfontfacename4.testcase      |    7 +
 test/sql_stmt_tests/getfontfacename5.testcase      |    7 +
 test/sql_stmt_tests/getfontfamily1.testcase        |    7 +
 test/sql_stmt_tests/getfontfamily2.testcase        |    7 +
 test/sql_stmt_tests/getfontfamily3.testcase        |    7 +
 test/sql_stmt_tests/getfontfamily4.testcase        |    7 +
 test/sql_stmt_tests/getfontfamily5.testcase        |    7 +
 test/sql_stmt_tests/getmapimage1.testcase          |    6 +-
 test/sql_stmt_tests/getmapimage10.testcase         |    6 +-
 test/sql_stmt_tests/getmapimage11.testcase         |    7 +
 test/sql_stmt_tests/getmapimage12.testcase         |    6 +-
 test/sql_stmt_tests/getmapimage13.testcase         |    6 +-
 test/sql_stmt_tests/getmapimage14.testcase         |    6 +-
 test/sql_stmt_tests/getmapimage15.testcase         |    6 +-
 test/sql_stmt_tests/getmapimage16.testcase         |    6 +-
 test/sql_stmt_tests/getmapimage17.testcase         |    6 +-
 test/sql_stmt_tests/getmapimage18.testcase         |    6 +-
 test/sql_stmt_tests/getmapimage19.testcase         |    6 +-
 test/sql_stmt_tests/getmapimage2.testcase          |    6 +-
 test/sql_stmt_tests/getmapimage20.testcase         |    6 +-
 test/sql_stmt_tests/getmapimage3.testcase          |    6 +-
 test/sql_stmt_tests/getmapimage4.testcase          |    6 +-
 test/sql_stmt_tests/getmapimage5.testcase          |    6 +-
 test/sql_stmt_tests/getmapimage6.testcase          |    6 +-
 test/sql_stmt_tests/getmapimage7.testcase          |    6 +-
 test/sql_stmt_tests/getmapimage8.testcase          |    6 +-
 test/sql_stmt_tests/getmapimage9.testcase          |    6 +-
 test/sql_stmt_tests/getmaxthreads1.testcase        |    7 +
 test/sql_stmt_tests/getvectorimage1.testcase       |    7 +
 test/sql_stmt_tests/getvectorimage10.testcase      |    7 +
 test/sql_stmt_tests/getvectorimage11.testcase      |    7 +
 test/sql_stmt_tests/getvectorimage12.testcase      |    7 +
 test/sql_stmt_tests/getvectorimage13.testcase      |    7 +
 test/sql_stmt_tests/getvectorimage14.testcase      |    7 +
 test/sql_stmt_tests/getvectorimage15.testcase      |    7 +
 test/sql_stmt_tests/getvectorimage16.testcase      |    7 +
 test/sql_stmt_tests/getvectorimage17.testcase      |    7 +
 test/sql_stmt_tests/getvectorimage18.testcase      |    7 +
 test/sql_stmt_tests/getvectorimage19.testcase      |    7 +
 test/sql_stmt_tests/getvectorimage2.testcase       |    7 +
 test/sql_stmt_tests/getvectorimage20.testcase      |    7 +
 test/sql_stmt_tests/getvectorimage3.testcase       |    7 +
 test/sql_stmt_tests/getvectorimage4.testcase       |    7 +
 test/sql_stmt_tests/getvectorimage5.testcase       |    7 +
 test/sql_stmt_tests/getvectorimage6.testcase       |    7 +
 test/sql_stmt_tests/getvectorimage7.testcase       |    7 +
 test/sql_stmt_tests/getvectorimage8.testcase       |    7 +
 test/sql_stmt_tests/getvectorimage9.testcase       |    7 +
 test/sql_stmt_tests/importraw1.testcase            |    7 +
 test/sql_stmt_tests/importraw10.testcase           |    7 +
 test/sql_stmt_tests/importraw2.testcase            |    7 +
 test/sql_stmt_tests/importraw3.testcase            |    7 +
 test/sql_stmt_tests/importraw4.testcase            |    7 +
 test/sql_stmt_tests/importraw5.testcase            |    7 +
 test/sql_stmt_tests/importraw6.testcase            |    7 +
 test/sql_stmt_tests/importraw7.testcase            |    7 +
 test/sql_stmt_tests/importraw8.testcase            |    7 +
 test/sql_stmt_tests/importraw9.testcase            |    7 +
 test/sql_stmt_tests/isautondvienabled1.testcase    |    7 +
 test/sql_stmt_tests/isautondvienabled2.testcase    |    7 +
 test/sql_stmt_tests/isautondvienabled3.testcase    |    7 +
 test/sql_stmt_tests/isautondvienabled4.testcase    |    7 +
 test/sql_stmt_tests/isautondvienabled5.testcase    |    7 +
 test/sql_stmt_tests/isfontbold1.testcase           |    7 +
 test/sql_stmt_tests/isfontbold2.testcase           |    7 +
 test/sql_stmt_tests/isfontbold3.testcase           |    7 +
 test/sql_stmt_tests/isfontbold4.testcase           |    7 +
 test/sql_stmt_tests/isfontbold5.testcase           |    7 +
 test/sql_stmt_tests/isfontitalic1.testcase         |    7 +
 test/sql_stmt_tests/isfontitalic2.testcase         |    7 +
 test/sql_stmt_tests/isfontitalic3.testcase         |    7 +
 test/sql_stmt_tests/isfontitalic4.testcase         |    7 +
 test/sql_stmt_tests/isfontitalic5.testcase         |    7 +
 test/sql_stmt_tests/isvalidfont1.testcase          |    7 +
 test/sql_stmt_tests/isvalidfont2.testcase          |    7 +
 test/sql_stmt_tests/isvalidfont3.testcase          |    7 +
 test/sql_stmt_tests/isvalidfont4.testcase          |    7 +
 test/sql_stmt_tests/isvalidfont5.testcase          |    7 +
 test/sql_stmt_tests/pyramidize10.testcase          |    4 +-
 test/sql_stmt_tests/pyramidize11.testcase          |    4 +-
 test/sql_stmt_tests/pyramidize12.testcase          |    4 +-
 test/sql_stmt_tests/pyramidize13.testcase          |    4 +-
 test/sql_stmt_tests/pyramidize14.testcase          |    4 +-
 test/sql_stmt_tests/pyramidize15.testcase          |    4 +-
 test/sql_stmt_tests/pyramidize16.testcase          |    4 +-
 test/sql_stmt_tests/pyramidize17.testcase          |    7 +
 test/sql_stmt_tests/pyramidize18.testcase          |    7 +
 test/sql_stmt_tests/pyramidize19.testcase          |    7 +
 test/sql_stmt_tests/pyramidize6.testcase           |    6 +-
 test/sql_stmt_tests/pyramidize9.testcase           |    4 +-
 test/sql_stmt_tests/setcoverageinfos1.testcase     |    6 +-
 test/sql_stmt_tests/setcoverageinfos2.testcase     |    6 +-
 test/sql_stmt_tests/setcoverageinfos3.testcase     |    6 +-
 test/sql_stmt_tests/setcoverageinfos4.testcase     |    6 +-
 test/sql_stmt_tests/setdefaultbands1.testcase      |    7 +
 test/sql_stmt_tests/setdefaultbands10.testcase     |    7 +
 test/sql_stmt_tests/setdefaultbands11.testcase     |    7 +
 test/sql_stmt_tests/setdefaultbands12.testcase     |    7 +
 test/sql_stmt_tests/setdefaultbands13.testcase     |    7 +
 test/sql_stmt_tests/setdefaultbands14.testcase     |    7 +
 test/sql_stmt_tests/setdefaultbands15.testcase     |    7 +
 test/sql_stmt_tests/setdefaultbands16.testcase     |    7 +
 test/sql_stmt_tests/setdefaultbands17.testcase     |    7 +
 test/sql_stmt_tests/setdefaultbands18.testcase     |    7 +
 test/sql_stmt_tests/setdefaultbands19.testcase     |    7 +
 test/sql_stmt_tests/setdefaultbands2.testcase      |    7 +
 test/sql_stmt_tests/setdefaultbands20.testcase     |    7 +
 test/sql_stmt_tests/setdefaultbands3.testcase      |    7 +
 test/sql_stmt_tests/setdefaultbands4.testcase      |    7 +
 test/sql_stmt_tests/setdefaultbands5.testcase      |    7 +
 test/sql_stmt_tests/setdefaultbands6.testcase      |    7 +
 test/sql_stmt_tests/setdefaultbands7.testcase      |    7 +
 test/sql_stmt_tests/setdefaultbands8.testcase      |    7 +
 test/sql_stmt_tests/setdefaultbands9.testcase      |    7 +
 test/sql_stmt_tests/setmaxthreads1.testcase        |    7 +
 test/sql_stmt_tests/setmaxthreads2.testcase        |    7 +
 test/sql_stmt_tests/setmaxthreads3.testcase        |    7 +
 test/sql_stmt_tests/setmaxthreads4.testcase        |    7 +
 test/sql_stmt_tests/setmaxthreads5.testcase        |    7 +
 test/sql_stmt_tests/setmaxthreads6.testcase        |    7 +
 test/sql_stmt_tests/setmaxthreads7.testcase        |    7 +
 test/symbolizers.sqlite                            |  Bin 0 -> 581632 bytes
 test/test1.c                                       |   37 +-
 test/test10.c                                      |    2 +-
 test/test11.c                                      |    2 +-
 test/test12.c                                      |    2 +-
 test/test13.c                                      |    2 +-
 test/test14.c                                      |    2 +-
 test/test15.c                                      |    2 +-
 test/test16.c                                      |    2 +-
 test/test17.c                                      |    2 +-
 test/test18.c                                      |    2 +-
 test/test19.c                                      |    2 +-
 test/test2.c                                       |   65 +-
 test/test20.c                                      |    2 +-
 test/test3.c                                       |   26 +-
 test/test4.c                                       |   44 +-
 test/test5.c                                       |   42 +-
 test/test6.c                                       |    2 +-
 test/test7.c                                       |    2 +-
 test/test8.c                                       |    2 +-
 test/test9.c                                       |    2 +-
 test/test_copy_rastercov.c                         |  309 +
 test/test_coverage.c                               |    9 +-
 test/test_font.c                                   |  325 +
 test/test_gif.c                                    |    2 +-
 test/test_line_symbolizer.c                        | 1551 ++++
 test/test_load_wms.c                               |   31 +-
 test/test_map_ascii.c                              |  267 +-
 test/test_map_gray.c                               |  281 +-
 test/test_map_indiana.c                            |  224 +-
 test/test_map_infrared.c                           | 1441 ++-
 test/test_map_mono.c                               |  284 +-
 test/test_map_nile_32.c                            |   26 +-
 test/test_map_nile_8.c                             |   26 +-
 test/test_map_nile_dbl.c                           |   26 +-
 test/test_map_nile_flt.c                           |   26 +-
 test/test_map_nile_u16.c                           |   26 +-
 test/test_map_nile_u32.c                           |   26 +-
 test/test_map_nile_u8.c                            |   26 +-
 test/test_map_noref.c                              |   47 +-
 test/test_map_orbetello.c                          |  856 +-
 test/test_map_rgb.c                                |   48 +-
 test/test_map_srtm.c                               |  391 +-
 test/test_map_trento.c                             |  313 +-
 test/test_map_trieste.c                            |  218 +-
 test/test_mask.c                                   |    8 +-
 test/test_openjpeg.c                               |  783 ++
 test/test_paint.c                                  |  790 +-
 test/test_palette.c                                |   14 +-
 test/test_point_symbolizer.c                       | 2137 +++++
 test/test_polygon_symbolizer.c                     | 1765 ++++
 test/test_raster.c                                 |   19 +-
 test/test_raster_symbolizer.c                      |  962 +-
 test/test_raw.c                                    | 1526 +++
 test/test_section.c                                |    2 +-
 test/test_svg.c                                    |    2 +-
 test/test_text_symbolizer.c                        | 1488 +++
 test/test_tifin.c                                  |   35 +-
 test/test_vectors.c                                |  199 +
 test/test_webp.c                                   |   10 +-
 test/test_wms1.c                                   |   56 +-
 test/test_wms2.c                                   |   15 +-
 test/test_wr_tiff.c                                |    9 +-
 tools/Makefile.am                                  |   15 +-
 tools/Makefile.in                                  |   64 +-
 tools/rl2sniff.c                                   | 1487 +++
 tools/rl2tool.c                                    | 2186 ++++-
 tools/wmslite.c                                    | 1376 ++-
 871 files changed, 71767 insertions(+), 11388 deletions(-)

diff --git a/Android_R4.2.0.mk b/Android_R4.2.0.mk
deleted file mode 100644
index 37e6bfc..0000000
--- a/Android_R4.2.0.mk
+++ /dev/null
@@ -1,50 +0,0 @@
-# -------------------
-# Android_R4.2.0.mk
-# ndk-build clean
-# ndk-build
-# -------------------
-LOCAL_PATH := $(call my-dir)
-JSQLITE_PATH := javasqlite-20120209
-SPATIALITE_PATH := libspatialite-4.2.0-rc1
-GEOS_PATH := geos-3.4.2
-PROJ4_PATH := proj-4.8.0
-SQLITE_PATH := sqlite-amalgamation-3080403
-ICONV_PATH := libiconv-1.13.1
-RASTERLITE2_PATH := librasterlite2-4.2.0
-GEOTIFF_PATH := libgeotiff-1.4.0
-TIFF_PATH := tiff-4.0.3/libtiff
-JPEG_PATH := jpeg-8d
-GIF_PATH := giflib-5.0.6/lib
-CAIRO_PATH := cairo-1.12.14/src
-FREETYPE_PATH := freetype-2.5.3
-FONTCONFIG_PATH := fontconfig-2.11.1
-EXPAT_PATH := expat-2.1.0
-PIXMAN_PATH := pixman-0.32.4
-PNG_PATH := libpng-1.6.10
-WEBP_PATH := libwebp-0.4.0
-XML2_PATH := libxml2-2.9.1
-CURL_PATH := curl-7.36.0
-LZMA_PATH := xz-5.1.3alpha
-
-include $(LOCAL_PATH)/jsqlite-R4.2.0.mk
-include $(LOCAL_PATH)/iconv-1.13.1.mk
-include $(LOCAL_PATH)/sqlite-3080403.mk
-include $(LOCAL_PATH)/proj4-4.8.0.mk
-include $(LOCAL_PATH)/geos-3.4.2.mk
-include $(LOCAL_PATH)/spatialite-4.2.0.mk
-include $(LOCAL_PATH)/libjpeg-8d.mk
-include $(LOCAL_PATH)/giflib-5.0.6.mk
-include $(LOCAL_PATH)/libpng-1.6.10.mk
-include $(LOCAL_PATH)/libtiff-4.0.3.mk
-include $(LOCAL_PATH)/libwebp-0.4.0.mk
-include $(LOCAL_PATH)/pixman-0.32.4.mk
-include $(LOCAL_PATH)/freetype-2.5.3.mk
-include $(LOCAL_PATH)/fontconfig-2.11.1.mk
-include $(LOCAL_PATH)/expat-2.1.0.mk
-include $(LOCAL_PATH)/cairo-1.12.14.mk
-include $(LOCAL_PATH)/libgeotiff-1.4.0.mk
-include $(LOCAL_PATH)/libxml2-2.9.1.mk
-include $(LOCAL_PATH)/libcurl-7.36.0.mk
-include $(LOCAL_PATH)/lzma-xz-5.1.3a.mk
-include $(LOCAL_PATH)/rasterlite2-4.2.0.mk
-$(call import-module,android/cpufeatures)
diff --git a/Android_R4.3.0.mk b/Android_R4.3.0.mk
new file mode 100644
index 0000000..b8feafe
--- /dev/null
+++ b/Android_R4.3.0.mk
@@ -0,0 +1,54 @@
+# -------------------
+# Android_R4.3.0.mk
+# ndk-build clean
+# ndk-build
+# -------------------
+LOCAL_PATH := $(call my-dir)
+JSQLITE_PATH := javasqlite-20120209
+SPATIALITE_PATH := libspatialite-4.3.0
+GEOS_PATH := geos-3.4.2
+PROJ4_PATH := proj-4.9.1
+SQLITE_PATH := sqlite-amalgamation-3081002
+ICONV_PATH := libiconv-1.13.1
+RASTERLITE2_PATH := librasterlite2-4.3.0
+GEOTIFF_PATH := libgeotiff-1.4.0
+TIFF_PATH := tiff-4.0.3/libtiff
+JPEG_PATH := jpeg-8d
+GIF_PATH := giflib-5.0.6/lib
+CAIRO_PATH := cairo-1.12.14/src
+FREETYPE_PATH := freetype-2.5.3
+FONTCONFIG_PATH := fontconfig-2.11.1
+EXPAT_PATH := expat-2.1.0
+PIXMAN_PATH := pixman-0.32.4
+PNG_PATH := libpng-1.6.10
+WEBP_PATH := libwebp-0.4.0
+XML2_PATH := libxml2-2.9.1
+CURL_PATH := curl-7.36.0
+LZMA_PATH := xz-5.1.3alpha
+CHARLS_PATH := charls-1.0
+OPENJPEG_PATH := openjpeg-2.0.0
+
+include $(LOCAL_PATH)/charls-1.0.mk
+include $(LOCAL_PATH)/jsqlite-R4.2.0.mk
+include $(LOCAL_PATH)/iconv-1.13.1.mk
+include $(LOCAL_PATH)/sqlite-3081002.mk
+include $(LOCAL_PATH)/proj4-4.9.1.mk
+include $(LOCAL_PATH)/geos-3.4.2.mk
+include $(LOCAL_PATH)/spatialite-4.3.0.mk
+include $(LOCAL_PATH)/libjpeg-8d.mk
+include $(LOCAL_PATH)/openjpeg-2.0.0.mk
+include $(LOCAL_PATH)/giflib-5.0.6.mk
+include $(LOCAL_PATH)/libpng-1.6.10.mk
+include $(LOCAL_PATH)/libtiff-4.0.3.mk
+include $(LOCAL_PATH)/libwebp-0.4.0.mk
+include $(LOCAL_PATH)/pixman-0.32.4.mk
+include $(LOCAL_PATH)/freetype-2.5.3.mk
+include $(LOCAL_PATH)/fontconfig-2.11.1.mk
+include $(LOCAL_PATH)/expat-2.1.0.mk
+include $(LOCAL_PATH)/cairo-1.12.14.mk
+include $(LOCAL_PATH)/libgeotiff-1.4.0.mk
+include $(LOCAL_PATH)/libxml2-2.9.1.mk
+include $(LOCAL_PATH)/libcurl-7.36.0.mk
+include $(LOCAL_PATH)/lzma-xz-5.1.3a.mk
+include $(LOCAL_PATH)/rasterlite2-4.3.0.mk
+$(call import-module,android/cpufeatures)
diff --git a/Makefile-static-MinGW b/Makefile-static-MinGW
index 8e593e9..fd77f98 100644
--- a/Makefile-static-MinGW
+++ b/Makefile-static-MinGW
@@ -5,8 +5,42 @@ CFLAGS = -Wall -Wextra -Wunused -pedantic -I/usr/local/include
 GG = g++
 CC = gcc
 
-all: ./static_bin/rl2tool.exe ./static_bin/wmslite.exe
+all: ./static_bin/rl2sniff.exe ./static_bin/rl2tool.exe \
+	./static_bin/wmslite.exe
 
+./static_bin/rl2sniff.exe: ./tools/rl2sniff.o 
+	$(GG) ./tools/rl2sniff.o -o ./static_bin/rl2sniff.exe \
+	/usr/local/lib/librasterlite2.a \
+	/usr/local/lib/libspatialite.a \
+	/usr/local/lib/libsqlite3.a \
+	/usr/local/lib/liblwgeom.a \
+	/usr/local/lib/libproj.a \
+	/usr/local/lib/libgeos_c.a \
+	/usr/local/lib/libgeos.a \
+	/usr/local/lib/libfreexl.a \
+	/usr/local/lib/libcairo.a \
+	/usr/local/lib/libpixman-1.a \
+	/usr/local/lib/libfontconfig.a \
+	/usr/local/lib/libfreetype.a \
+	/usr/local/lib/libgif.a \
+	/usr/local/lib/libwebp.a \
+	/usr/local/lib/libjpeg.a \
+	/usr/local/lib/libgeotiff.a \
+	/usr/local/lib/libtiff.a \
+	/usr/local/lib/libpng.a \
+	/usr/local/lib/libCharLS.a \
+	/usr/local/lib/libopenjp2.a \
+	/usr/local/lib/libcurl.a \
+	/usr/local/lib/libssl.a \
+	/usr/local/lib/libcrypto.a \
+	/usr/local/lib/libxml2.a \
+	/usr/local/lib/libexpat.a \
+	/usr/local/lib/liblzma.a \
+	/usr/local/lib/libz.a \
+	/usr/local/lib/libiconv.a \
+	-lm -lmsimg32 -lws2_32 -lgdi32 -lwldap32 -static-libstdc++ -static-libgcc
+	strip --strip-all ./static_bin/rl2sniff.exe
+	
 ./static_bin/rl2tool.exe: ./tools/rl2tool.o 
 	$(GG) ./tools/rl2tool.o -o ./static_bin/rl2tool.exe \
 	/usr/local/lib/librasterlite2.a \
@@ -27,6 +61,8 @@ all: ./static_bin/rl2tool.exe ./static_bin/wmslite.exe
 	/usr/local/lib/libgeotiff.a \
 	/usr/local/lib/libtiff.a \
 	/usr/local/lib/libpng.a \
+	/usr/local/lib/libCharLS.a \
+	/usr/local/lib/libopenjp2.a \
 	/usr/local/lib/libcurl.a \
 	/usr/local/lib/libssl.a \
 	/usr/local/lib/libcrypto.a \
@@ -58,6 +94,8 @@ all: ./static_bin/rl2tool.exe ./static_bin/wmslite.exe
 	/usr/local/lib/libgeotiff.a \
 	/usr/local/lib/libtiff.a \
 	/usr/local/lib/libpng.a \
+	/usr/local/lib/libCharLS.a \
+	/usr/local/lib/libopenjp2.a \
 	/usr/local/lib/libcurl.a \
 	/usr/local/lib/libssl.a \
 	/usr/local/lib/libcrypto.a \
@@ -69,8 +107,11 @@ all: ./static_bin/rl2tool.exe ./static_bin/wmslite.exe
 	-lm -lmsimg32 -lws2_32 -lgdi32 -lwldap32 -static-libstdc++ -static-libgcc
 	strip --strip-all ./static_bin/wmslite.exe
 
+./tools/rl2sniff.o: 
+	$(CC) $(CFLAGS) ./tools/rlsniff.c -c
+	
 ./tools/rl2tool.o: 
 	$(CC) $(CFLAGS) ./tools/rl2tool.c -c
-	
-./tools/wmslite.o:
+
+	./tools/wmslite.o:
 	$(CC) $(CFLAGS) ./tools/wmslite.c -c
\ No newline at end of file
diff --git a/Makefile.am b/Makefile.am
index dba724a..3428c56 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,8 +1,8 @@
 ACLOCAL_AMFLAGS = -I m4
 
-SUBDIRS = headers src test tools examples
+SUBDIRS = headers src test tools
 
-EXTRA_DIST = mainpage.doxy Android_R4.2.0.mk rasterlite2-4.2.0.mk \
+EXTRA_DIST = mainpage.doxy Android_R4.3.0.mk rasterlite2-4.3.0.mk \
 	Makefile-static-MinGW
 
 AUTOMAKE_OPTIONS = dist-zip
@@ -14,7 +14,7 @@ coverage-init:
 	lcov --directory src --capture --initial --output-file rasterlite2_cov.info
 
 coverage::
-	lcov --directory src --output-file rasterlite2_cov.info --capture
-	genhtml -o covresults rasterlite2_cov.info
+	lcov --rc lcov_branch_coverage=1 --directory src --output-file rasterlite2_cov.info --capture
+	genhtml --rc lcov_branch_coverage=1 -o covresults rasterlite2_cov.info
 
 MOSTLYCLEANFILES = rasterlite2_cov.info 
diff --git a/Makefile.in b/Makefile.in
index 2e54ff3..bd4ecf4 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# Makefile.in generated by automake 1.15 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -15,7 +15,17 @@
 @SET_MAKE@
 
 VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -79,12 +89,6 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = .
-DIST_COMMON = INSTALL NEWS README AUTHORS ChangeLog \
-	$(srcdir)/Makefile.in $(srcdir)/Makefile.am \
-	$(top_srcdir)/configure $(am__configure_deps) \
-	$(srcdir)/config.h.in $(srcdir)/Doxyfile.in \
-	$(srcdir)/rasterlite2.pc.in COPYING config.guess config.sub \
-	depcomp install-sh missing ltmain.sh
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
@@ -92,6 +96,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
+	$(am__configure_deps) $(am__DIST_COMMON)
 am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
  configure.lineno config.status.lineno
 mkinstalldirs = $(install_sh) -d
@@ -184,6 +190,10 @@ ETAGS = etags
 CTAGS = ctags
 CSCOPE = cscope
 DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(srcdir)/Doxyfile.in $(srcdir)/Makefile.in \
+	$(srcdir)/config.h.in $(srcdir)/rasterlite2.pc.in AUTHORS \
+	COPYING ChangeLog INSTALL NEWS README compile config.guess \
+	config.sub depcomp install-sh ltmain.sh missing
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 distdir = $(PACKAGE)-$(VERSION)
 top_distdir = $(distdir)
@@ -256,6 +266,8 @@ ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
+FREETYPE2_CFLAGS = @FREETYPE2_CFLAGS@
+FREETYPE2_LIBS = @FREETYPE2_LIBS@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
@@ -268,6 +280,8 @@ LIBCAIRO_CFLAGS = @LIBCAIRO_CFLAGS@
 LIBCAIRO_LIBS = @LIBCAIRO_LIBS@
 LIBCURL_CFLAGS = @LIBCURL_CFLAGS@
 LIBCURL_LIBS = @LIBCURL_LIBS@
+LIBFREETYPE2_CFLAGS = @LIBFREETYPE2_CFLAGS@
+LIBFREETYPE2_LIBS = @LIBFREETYPE2_LIBS@
 LIBLZMA_CFLAGS = @LIBLZMA_CFLAGS@
 LIBLZMA_LIBS = @LIBLZMA_LIBS@
 LIBOBJS = @LIBOBJS@
@@ -365,8 +379,8 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 ACLOCAL_AMFLAGS = -I m4
-SUBDIRS = headers src test tools examples
-EXTRA_DIST = mainpage.doxy Android_R4.2.0.mk rasterlite2-4.2.0.mk \
+SUBDIRS = headers src test tools
+EXTRA_DIST = mainpage.doxy Android_R4.3.0.mk rasterlite2-4.3.0.mk \
 	Makefile-static-MinGW
 
 AUTOMAKE_OPTIONS = dist-zip
@@ -392,7 +406,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__confi
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu Makefile
-.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -413,8 +426,8 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
 $(am__aclocal_m4_deps):
 
 config.h: stamp-h1
-	@if test ! -f $@; then rm -f stamp-h1; else :; fi
-	@if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi
+	@test -f $@ || rm -f stamp-h1
+	@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
 
 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
 	@rm -f stamp-h1
@@ -648,10 +661,16 @@ dist-xz: distdir
 	$(am__post_remove_distdir)
 
 dist-tarZ: distdir
+	@echo WARNING: "Support for distribution archives compressed with" \
+		       "legacy program 'compress' is deprecated." >&2
+	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
 	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
 	$(am__post_remove_distdir)
 
 dist-shar: distdir
+	@echo WARNING: "Support for shar distribution archives is" \
+	               "deprecated." >&2
+	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
 	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
 	$(am__post_remove_distdir)
 dist-zip: distdir
@@ -685,16 +704,17 @@ distcheck: dist
 	esac
 	chmod -R a-w $(distdir)
 	chmod u+w $(distdir)
-	mkdir $(distdir)/_build $(distdir)/_inst
+	mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
 	chmod a-w $(distdir)
 	test -d $(distdir)/_build || exit 0; \
 	dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
 	  && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
 	  && am__cwd=`pwd` \
-	  && $(am__cd) $(distdir)/_build \
-	  && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+	  && $(am__cd) $(distdir)/_build/sub \
+	  && ../../configure \
 	    $(AM_DISTCHECK_CONFIGURE_FLAGS) \
 	    $(DISTCHECK_CONFIGURE_FLAGS) \
+	    --srcdir=../.. --prefix="$$dc_install_base" \
 	  && $(MAKE) $(AM_MAKEFLAGS) \
 	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
 	  && $(MAKE) $(AM_MAKEFLAGS) check \
@@ -875,13 +895,15 @@ uninstall-am: uninstall-pkgconfigDATA
 	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
 	uninstall-am uninstall-pkgconfigDATA
 
+.PRECIOUS: Makefile
+
 
 coverage-init:
 	lcov --directory src --capture --initial --output-file rasterlite2_cov.info
 
 coverage::
-	lcov --directory src --output-file rasterlite2_cov.info --capture
-	genhtml -o covresults rasterlite2_cov.info
+	lcov --rc lcov_branch_coverage=1 --directory src --output-file rasterlite2_cov.info --capture
+	genhtml --rc lcov_branch_coverage=1 -o covresults rasterlite2_cov.info
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/aclocal.m4 b/aclocal.m4
index f209970..a482529 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.13.4 -*- Autoconf -*-
+# generated automatically by aclocal 1.15 -*- Autoconf -*-
 
-# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -235,7 +235,7 @@ AS_VAR_COPY([$1], [pkg_cv_][$1])
 AS_VAR_IF([$1], [""], [$5], [$4])dnl
 ])# PKG_CHECK_VAR
 
-# Copyright (C) 2002-2013 Free Software Foundation, Inc.
+# Copyright (C) 2002-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -247,10 +247,10 @@ AS_VAR_IF([$1], [""], [$5], [$4])dnl
 # generated from the m4 files accompanying Automake X.Y.
 # (This private macro should not be called outside this file.)
 AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.13'
+[am__api_version='1.15'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.13.4], [],
+m4_if([$1], [1.15], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -266,14 +266,14 @@ m4_define([_AM_AUTOCONF_VERSION], [])
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.13.4])dnl
+[AM_AUTOMAKE_VERSION([1.15])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -318,15 +318,14 @@ _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 # configured tree to be moved without reconfiguration.
 
 AC_DEFUN([AM_AUX_DIR_EXPAND],
-[dnl Rely on autoconf to set up CDPATH properly.
-AC_PREREQ([2.50])dnl
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
+[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
 ])
 
 # AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# Copyright (C) 1997-2013 Free Software Foundation, Inc.
+# Copyright (C) 1997-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -357,7 +356,7 @@ AC_CONFIG_COMMANDS_PRE(
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -548,7 +547,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
 
 # Generate code to set up dependency tracking.              -*- Autoconf -*-
 
-# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -624,7 +623,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
 
 # Do all the work for Automake.                             -*- Autoconf -*-
 
-# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -633,6 +632,12 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
 # This macro actually does too much.  Some checks are only needed if
 # your package does certain things.  But this isn't really a big deal.
 
+dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
+m4_define([AC_PROG_CC],
+m4_defn([AC_PROG_CC])
+[_AM_PROG_CC_C_O
+])
+
 # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
 # AM_INIT_AUTOMAKE([OPTIONS])
 # -----------------------------------------------
@@ -708,8 +713,8 @@ AC_REQUIRE([AC_PROG_MKDIR_P])dnl
 # <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
 # <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
 AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
-# We need awk for the "check" target.  The system "awk" is bad on
-# some platforms.
+# We need awk for the "check" target (and possibly the TAP driver).  The
+# system "awk" is bad on some platforms.
 AC_REQUIRE([AC_PROG_AWK])dnl
 AC_REQUIRE([AC_PROG_MAKE_SET])dnl
 AC_REQUIRE([AM_SET_LEADING_DOT])dnl
@@ -741,6 +746,51 @@ dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
 AC_CONFIG_COMMANDS_PRE(dnl
 [m4_provide_if([_AM_COMPILER_EXEEXT],
   [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes.  So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+  cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present.  This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake at gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message.  This
+can help us improve future automake versions.
+
+END
+  if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+    echo 'Configuration will proceed anyway, since you have set the' >&2
+    echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+    echo >&2
+  else
+    cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+    AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
+  fi
+fi
+dnl The trailing newline in this macro's definition is deliberate, for
+dnl backward compatibility and to allow trailing 'dnl'-style comments
+dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
 ])
 
 dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion.  Do not
@@ -749,7 +799,6 @@ dnl mangled by Autoconf and run in a shell conditional statement.
 m4_define([_AC_COMPILER_EXEEXT],
 m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
 
-
 # When config.status generates a header, we must update the stamp-h file.
 # This file resides in the same directory as the config header
 # that is generated.  The stamp files are numbered to have different names.
@@ -771,7 +820,7 @@ for _am_header in $config_headers :; do
 done
 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
 
-# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -782,7 +831,7 @@ echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_co
 # Define $install_sh.
 AC_DEFUN([AM_PROG_INSTALL_SH],
 [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-if test x"${install_sh}" != xset; then
+if test x"${install_sh+set}" != xset; then
   case $am_aux_dir in
   *\ * | *\	*)
     install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
@@ -792,7 +841,7 @@ if test x"${install_sh}" != xset; then
 fi
 AC_SUBST([install_sh])])
 
-# Copyright (C) 2003-2013 Free Software Foundation, Inc.
+# Copyright (C) 2003-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -814,7 +863,7 @@ AC_SUBST([am__leading_dot])])
 # Add --enable-maintainer-mode option to configure.         -*- Autoconf -*-
 # From Jim Meyering
 
-# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -849,7 +898,7 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
 
 # Check to see how 'make' treats includes.	            -*- Autoconf -*-
 
-# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -899,7 +948,7 @@ rm -f confinc confmf
 
 # Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
-# Copyright (C) 1997-2013 Free Software Foundation, Inc.
+# Copyright (C) 1997-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -940,7 +989,7 @@ fi
 # Obsolete and "removed" macros, that must however still report explicit
 # error messages when used, to smooth transition.
 #
-# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -967,7 +1016,7 @@ AU_DEFUN([fp_C_PROTOTYPES], [AM_C_PROTOTYPES])
 
 # Helper functions for option handling.                     -*- Autoconf -*-
 
-# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -996,9 +1045,73 @@ AC_DEFUN([_AM_SET_OPTIONS],
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_CC_C_O
+# ---------------
+# Like AC_PROG_CC_C_O, but changed for automake.  We rewrite AC_PROG_CC
+# to automatically call this.
+AC_DEFUN([_AM_PROG_CC_C_O],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+AC_LANG_PUSH([C])dnl
+AC_CACHE_CHECK(
+  [whether $CC understands -c and -o together],
+  [am_cv_prog_cc_c_o],
+  [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
+  # Make sure it works both with $CC and with simple cc.
+  # Following AC_PROG_CC_C_O, we do the test twice because some
+  # compilers refuse to overwrite an existing .o file with -o,
+  # though they will create one.
+  am_cv_prog_cc_c_o=yes
+  for am_i in 1 2; do
+    if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
+         && test -f conftest2.$ac_objext; then
+      : OK
+    else
+      am_cv_prog_cc_c_o=no
+      break
+    fi
+  done
+  rm -f core conftest*
+  unset am_i])
+if test "$am_cv_prog_cc_c_o" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+AC_LANG_POP([C])])
+
+# For backward compatibility.
+AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
+
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_RUN_LOG(COMMAND)
+# -------------------
+# Run COMMAND, save the exit status in ac_status, and log it.
+# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
+AC_DEFUN([AM_RUN_LOG],
+[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
+   ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   (exit $ac_status); }])
+
 # Check to make sure that the build environment is sane.    -*- Autoconf -*-
 
-# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1079,7 +1192,7 @@ AC_CONFIG_COMMANDS_PRE(
 rm -f conftest.file
 ])
 
-# Copyright (C) 2009-2013 Free Software Foundation, Inc.
+# Copyright (C) 2009-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1139,7 +1252,7 @@ AC_SUBST([AM_BACKSLASH])dnl
 _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
 ])
 
-# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+# Copyright (C) 2001-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1167,7 +1280,7 @@ fi
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
-# Copyright (C) 2006-2013 Free Software Foundation, Inc.
+# Copyright (C) 2006-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1186,7 +1299,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004-2013 Free Software Foundation, Inc.
+# Copyright (C) 2004-2014 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
diff --git a/compile b/compile
new file mode 100755
index 0000000..531136b
--- /dev/null
+++ b/compile
@@ -0,0 +1,347 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand '-c -o'.
+
+scriptversion=2012-10-14.11; # UTC
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey at cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake at gnu.org> or send patches to
+# <automake-patches at gnu.org>.
+
+nl='
+'
+
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent tools from complaining about whitespace usage.
+IFS=" ""	$nl"
+
+file_conv=
+
+# func_file_conv build_file lazy
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts. If the determined conversion
+# type is listed in (the comma separated) LAZY, no conversion will
+# take place.
+func_file_conv ()
+{
+  file=$1
+  case $file in
+    / | /[!/]*) # absolute file, and not a UNC file
+      if test -z "$file_conv"; then
+	# lazily determine how to convert abs files
+	case `uname -s` in
+	  MINGW*)
+	    file_conv=mingw
+	    ;;
+	  CYGWIN*)
+	    file_conv=cygwin
+	    ;;
+	  *)
+	    file_conv=wine
+	    ;;
+	esac
+      fi
+      case $file_conv/,$2, in
+	*,$file_conv,*)
+	  ;;
+	mingw/*)
+	  file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+	  ;;
+	cygwin/*)
+	  file=`cygpath -m "$file" || echo "$file"`
+	  ;;
+	wine/*)
+	  file=`winepath -w "$file" || echo "$file"`
+	  ;;
+      esac
+      ;;
+  esac
+}
+
+# func_cl_dashL linkdir
+# Make cl look for libraries in LINKDIR
+func_cl_dashL ()
+{
+  func_file_conv "$1"
+  if test -z "$lib_path"; then
+    lib_path=$file
+  else
+    lib_path="$lib_path;$file"
+  fi
+  linker_opts="$linker_opts -LIBPATH:$file"
+}
+
+# func_cl_dashl library
+# Do a library search-path lookup for cl
+func_cl_dashl ()
+{
+  lib=$1
+  found=no
+  save_IFS=$IFS
+  IFS=';'
+  for dir in $lib_path $LIB
+  do
+    IFS=$save_IFS
+    if $shared && test -f "$dir/$lib.dll.lib"; then
+      found=yes
+      lib=$dir/$lib.dll.lib
+      break
+    fi
+    if test -f "$dir/$lib.lib"; then
+      found=yes
+      lib=$dir/$lib.lib
+      break
+    fi
+    if test -f "$dir/lib$lib.a"; then
+      found=yes
+      lib=$dir/lib$lib.a
+      break
+    fi
+  done
+  IFS=$save_IFS
+
+  if test "$found" != yes; then
+    lib=$lib.lib
+  fi
+}
+
+# func_cl_wrapper cl arg...
+# Adjust compile command to suit cl
+func_cl_wrapper ()
+{
+  # Assume a capable shell
+  lib_path=
+  shared=:
+  linker_opts=
+  for arg
+  do
+    if test -n "$eat"; then
+      eat=
+    else
+      case $1 in
+	-o)
+	  # configure might choose to run compile as 'compile cc -o foo foo.c'.
+	  eat=1
+	  case $2 in
+	    *.o | *.[oO][bB][jJ])
+	      func_file_conv "$2"
+	      set x "$@" -Fo"$file"
+	      shift
+	      ;;
+	    *)
+	      func_file_conv "$2"
+	      set x "$@" -Fe"$file"
+	      shift
+	      ;;
+	  esac
+	  ;;
+	-I)
+	  eat=1
+	  func_file_conv "$2" mingw
+	  set x "$@" -I"$file"
+	  shift
+	  ;;
+	-I*)
+	  func_file_conv "${1#-I}" mingw
+	  set x "$@" -I"$file"
+	  shift
+	  ;;
+	-l)
+	  eat=1
+	  func_cl_dashl "$2"
+	  set x "$@" "$lib"
+	  shift
+	  ;;
+	-l*)
+	  func_cl_dashl "${1#-l}"
+	  set x "$@" "$lib"
+	  shift
+	  ;;
+	-L)
+	  eat=1
+	  func_cl_dashL "$2"
+	  ;;
+	-L*)
+	  func_cl_dashL "${1#-L}"
+	  ;;
+	-static)
+	  shared=false
+	  ;;
+	-Wl,*)
+	  arg=${1#-Wl,}
+	  save_ifs="$IFS"; IFS=','
+	  for flag in $arg; do
+	    IFS="$save_ifs"
+	    linker_opts="$linker_opts $flag"
+	  done
+	  IFS="$save_ifs"
+	  ;;
+	-Xlinker)
+	  eat=1
+	  linker_opts="$linker_opts $2"
+	  ;;
+	-*)
+	  set x "$@" "$1"
+	  shift
+	  ;;
+	*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
+	  func_file_conv "$1"
+	  set x "$@" -Tp"$file"
+	  shift
+	  ;;
+	*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
+	  func_file_conv "$1" mingw
+	  set x "$@" "$file"
+	  shift
+	  ;;
+	*)
+	  set x "$@" "$1"
+	  shift
+	  ;;
+      esac
+    fi
+    shift
+  done
+  if test -n "$linker_opts"; then
+    linker_opts="-link$linker_opts"
+  fi
+  exec "$@" $linker_opts
+  exit 1
+}
+
+eat=
+
+case $1 in
+  '')
+     echo "$0: No command.  Try '$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand '-c -o'.
+Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file 'INSTALL'.
+
+Report bugs to <bug-automake at gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "compile $scriptversion"
+    exit $?
+    ;;
+  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+    func_cl_wrapper "$@"      # Doesn't return...
+    ;;
+esac
+
+ofile=
+cfile=
+
+for arg
+do
+  if test -n "$eat"; then
+    eat=
+  else
+    case $1 in
+      -o)
+	# configure might choose to run compile as 'compile cc -o foo foo.c'.
+	# So we strip '-o arg' only if arg is an object.
+	eat=1
+	case $2 in
+	  *.o | *.obj)
+	    ofile=$2
+	    ;;
+	  *)
+	    set x "$@" -o "$2"
+	    shift
+	    ;;
+	esac
+	;;
+      *.c)
+	cfile=$1
+	set x "$@" "$1"
+	shift
+	;;
+      *)
+	set x "$@" "$1"
+	shift
+	;;
+    esac
+  fi
+  shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+  # If no '-o' option was seen then we might have been invoked from a
+  # pattern rule where we don't need one.  That is ok -- this is a
+  # normal compilation that the losing compiler can handle.  If no
+  # '.c' file was seen then we are probably linking.  That is also
+  # ok.
+  exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use '[/\\:.-]' here to ensure that we don't use the same name
+# that we are using for the .o file.  Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
+while true; do
+  if mkdir "$lockdir" >/dev/null 2>&1; then
+    break
+  fi
+  sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+  test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+  test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/config.h.in b/config.h.in
index ff3f40c..85ee3dd 100644
--- a/config.h.in
+++ b/config.h.in
@@ -1,5 +1,8 @@
 /* config.h.in.  Generated from configure.ac by autoheader.  */
 
+/* Define to 1 if you have the <CharLS/interface.h> header file. */
+#undef HAVE_CHARLS_INTERFACE_H
+
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #undef HAVE_DLFCN_H
 
@@ -24,6 +27,9 @@
 /* Define to 1 if you have the <jpeglib.h> header file. */
 #undef HAVE_JPEGLIB_H
 
+/* Define to 1 if you have the `CharLS' library (-lCharLS). */
+#undef HAVE_LIBCHARLS
+
 /* Define to 1 if you have the `geotiff' library (-lgeotiff). */
 #undef HAVE_LIBGEOTIFF
 
@@ -36,6 +42,12 @@
 /* Define to 1 if you have the `jpeg' library (-ljpeg). */
 #undef HAVE_LIBJPEG
 
+/* Define to 1 if you have the `openjp2' library (-lopenjp2). */
+#undef HAVE_LIBOPENJP2
+
+/* Define to 1 if you have the `sqlite3' library (-lsqlite3). */
+#undef HAVE_LIBSQLITE3
+
 /* Define to 1 if you have the `tiff' library (-ltiff). */
 #undef HAVE_LIBTIFF
 
@@ -46,18 +58,27 @@
    zero-length file name argument. */
 #undef HAVE_LSTAT_EMPTY_STRING_BUG
 
-/* Define to 1 if you have the <lzma.h> header file. */
-#undef HAVE_LZMA_H
-
 /* Define to 1 if you have the <math.h> header file. */
 #undef HAVE_MATH_H
 
 /* Define to 1 if you have the <memory.h> header file. */
 #undef HAVE_MEMORY_H
 
+/* Define to 1 if you have the <openjpeg-2.0/openjpeg.h> header file. */
+#undef HAVE_OPENJPEG_2_0_OPENJPEG_H
+
+/* Define to 1 if you have the <openjpeg-2.1/openjpeg.h> header file. */
+#undef HAVE_OPENJPEG_2_1_OPENJPEG_H
+
 /* Define to 1 if you have the <png.h> header file. */
 #undef HAVE_PNG_H
 
+/* Define to 1 if you have the <sqlite3ext.h> header file. */
+#undef HAVE_SQLITE3EXT_H
+
+/* Define to 1 if you have the <sqlite3.h> header file. */
+#undef HAVE_SQLITE3_H
+
 /* Define to 1 if you have the `sqrt' function. */
 #undef HAVE_SQRT
 
@@ -118,6 +139,21 @@
 /* Must be defined in order to disable debug mode. */
 #undef NDEBUG
 
+/* Should be defined in order to disable CharLS support. */
+#undef OMIT_CHARLS
+
+/* Should be defined in order to disable LZMA support. */
+#undef OMIT_LZMA
+
+/* Should be defined in order to disable OpenJpeg support. */
+#undef OMIT_OPENJPEG
+
+/* Should be defined in order to disable WebP support. */
+#undef OMIT_WEBP
+
+/* testing for OpenJpeg 2.1 */
+#undef OPENJPEG_2_1
+
 /* Name of package */
 #undef PACKAGE
 
diff --git a/configure b/configure
index 143bf13..9486ad5 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for librasterlite2 1.0.0-rc0.
+# Generated by GNU Autoconf 2.69 for librasterlite2 1.0.0-devel.
 #
 # Report bugs to <a.furieri at lqt.it>.
 #
@@ -590,8 +590,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='librasterlite2'
 PACKAGE_TARNAME='librasterlite2'
-PACKAGE_VERSION='1.0.0-rc0'
-PACKAGE_STRING='librasterlite2 1.0.0-rc0'
+PACKAGE_VERSION='1.0.0-devel'
+PACKAGE_STRING='librasterlite2 1.0.0-devel'
 PACKAGE_BUGREPORT='a.furieri at lqt.it'
 PACKAGE_URL=''
 
@@ -636,6 +636,10 @@ am__EXEEXT_TRUE
 LTLIBOBJS
 MINGW_FALSE
 MINGW_TRUE
+LIBFREETYPE2_LIBS
+LIBFREETYPE2_CFLAGS
+FREETYPE2_LIBS
+FREETYPE2_CFLAGS
 LIBXML2_LIBS
 LIBXML2_CFLAGS
 LIBCURL_LIBS
@@ -791,6 +795,10 @@ with_gnu_ld
 with_sysroot
 enable_libtool_lock
 enable_gcov
+enable_openjpeg
+enable_webp
+enable_lzma
+enable_charls
 '
       ac_precious_vars='build_alias
 host_alias
@@ -821,7 +829,9 @@ LIBCAIRO_LIBS
 LIBCURL_CFLAGS
 LIBCURL_LIBS
 LIBXML2_CFLAGS
-LIBXML2_LIBS'
+LIBXML2_LIBS
+FREETYPE2_CFLAGS
+FREETYPE2_LIBS'
 
 
 # Initialize some variables set by options.
@@ -1362,7 +1372,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures librasterlite2 1.0.0-rc0 to adapt to many kinds of systems.
+\`configure' configures librasterlite2 1.0.0-devel to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1432,7 +1442,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of librasterlite2 1.0.0-rc0:";;
+     short | recursive ) echo "Configuration of librasterlite2 1.0.0-devel:";;
    esac
   cat <<\_ACEOF
 
@@ -1455,6 +1465,10 @@ Optional Features:
                           optimize for fast installation [default=yes]
   --disable-libtool-lock  avoid locking (might break parallel builds)
   --enable-gcov           turn on code coverage analysis tools
+  --enable-openjpeg       enables OpenJpeg inclusion [default=yes]
+  --enable-webp           enables WebP inclusion [default=yes]
+  --enable-lzma           enables LZMA inclusion [default=yes]
+  --enable-charls         enables CharLS inclusion [default=yes]
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -1509,6 +1523,10 @@ Some influential environment variables:
               C compiler flags for LIBXML2, overriding pkg-config
   LIBXML2_LIBS
               linker flags for LIBXML2, overriding pkg-config
+  FREETYPE2_CFLAGS
+              C compiler flags for FREETYPE2, overriding pkg-config
+  FREETYPE2_LIBS
+              linker flags for FREETYPE2, overriding pkg-config
 
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
@@ -1576,7 +1594,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-librasterlite2 configure 1.0.0-rc0
+librasterlite2 configure 1.0.0-devel
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2120,7 +2138,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by librasterlite2 $as_me 1.0.0-rc0, which was
+It was created by librasterlite2 $as_me 1.0.0-devel, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2505,7 +2523,7 @@ ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
 
 
 
-am__api_version='1.13'
+am__api_version='1.15'
 
 # Find a good install program.  We prefer a C program (faster),
 # so one script is as good as another.  But avoid the broken or
@@ -2677,8 +2695,8 @@ test "$program_suffix" != NONE &&
 ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
 program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
 
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
+# Expand $ac_aux_dir to an absolute path.
+am_aux_dir=`cd "$ac_aux_dir" && pwd`
 
 if test x"${MISSING+set}" != xset; then
   case $am_aux_dir in
@@ -2697,7 +2715,7 @@ else
 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
 fi
 
-if test x"${install_sh}" != xset; then
+if test x"${install_sh+set}" != xset; then
   case $am_aux_dir in
   *\ * | *\	*)
     install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
@@ -2991,7 +3009,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='librasterlite2'
- VERSION='1.0.0-rc0'
+ VERSION='1.0.0-devel'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -3025,8 +3043,8 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
 # <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
 mkdir_p='$(MKDIR_P)'
 
-# We need awk for the "check" target.  The system "awk" is bad on
-# some platforms.
+# We need awk for the "check" target (and possibly the TAP driver).  The
+# system "awk" is bad on some platforms.
 # Always define AMTAR for backward compatibility.  Yes, it's still used
 # in the wild :-(  We should find a proper way to deprecate it ...
 AMTAR='$${TAR-tar}'
@@ -3042,6 +3060,48 @@ am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
 
 
 
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes.  So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+  cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present.  This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake at gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message.  This
+can help us improve future automake versions.
+
+END
+  if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+    echo 'Configuration will proceed anyway, since you have set the' >&2
+    echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+    echo >&2
+  else
+    cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+    as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
+  fi
+fi
+
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
 $as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
@@ -3086,6 +3146,12 @@ $as_echo "#define NDEBUG 1" >>confdefs.h
 
 
 
+# config depending options
+
+
+
+
+
 # Checks for header files.
 DEPDIR="${am__leading_dot}deps"
 
@@ -3939,6 +4005,65 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+  # Make sure it works both with $CC and with simple cc.
+  # Following AC_PROG_CC_C_O, we do the test twice because some
+  # compilers refuse to overwrite an existing .o file with -o,
+  # though they will create one.
+  am_cv_prog_cc_c_o=yes
+  for am_i in 1 2; do
+    if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+   ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } \
+         && test -f conftest2.$ac_objext; then
+      : OK
+    else
+      am_cv_prog_cc_c_o=no
+      break
+    fi
+  done
+  rm -f core conftest*
+  unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
 depcc="$CC"   am_compiler_list=
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
@@ -4591,6 +4716,34 @@ fi
 
 done
 
+for ac_header in sqlite3.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "sqlite3.h" "ac_cv_header_sqlite3_h" "$ac_includes_default"
+if test "x$ac_cv_header_sqlite3_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SQLITE3_H 1
+_ACEOF
+
+else
+  as_fn_error $? "cannot find sqlite3.h, bailing out" "$LINENO" 5
+fi
+
+done
+
+for ac_header in sqlite3ext.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "sqlite3ext.h" "ac_cv_header_sqlite3ext_h" "$ac_includes_default"
+if test "x$ac_cv_header_sqlite3ext_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SQLITE3EXT_H 1
+_ACEOF
+
+else
+  as_fn_error $? "cannot find sqlite3ext.h, bailing out" "$LINENO" 5
+fi
+
+done
+
 for ac_header in zlib.h
 do :
   ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
@@ -4619,19 +4772,6 @@ fi
 
 done
 
-for ac_header in lzma.h
-do :
-  ac_fn_c_check_header_mongrel "$LINENO" "lzma.h" "ac_cv_header_lzma_h" "$ac_includes_default"
-if test "x$ac_cv_header_lzma_h" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_LZMA_H 1
-_ACEOF
-
-else
-  as_fn_error $? "cannot find lzma.h, bailing out" "$LINENO" 5
-fi
-
-done
 
 
 #
@@ -5612,6 +5752,65 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+  # Make sure it works both with $CC and with simple cc.
+  # Following AC_PROG_CC_C_O, we do the test twice because some
+  # compilers refuse to overwrite an existing .o file with -o,
+  # though they will create one.
+  am_cv_prog_cc_c_o=yes
+  for am_i in 1 2; do
+    if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+   ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } \
+         && test -f conftest2.$ac_objext; then
+      : OK
+    else
+      am_cv_prog_cc_c_o=no
+      break
+    fi
+  done
+  rm -f core conftest*
+  unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
 depcc="$CC"   am_compiler_list=
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
@@ -17163,7 +17362,7 @@ if test "x$enable_gcov" = "xyes"; then
     GCOV_FLAGS="-lgcov"
 fi
 
-ac_config_files="$ac_config_files Makefile headers/Makefile src/Makefile test/Makefile test/sql_stmt_tests/Makefile test/sql_stmt_security_tests/Makefile tools/Makefile examples/Makefile Doxyfile rasterlite2.pc"
+ac_config_files="$ac_config_files Makefile headers/Makefile src/Makefile test/Makefile test/sql_stmt_tests/Makefile test/sql_stmt_security_tests/Makefile tools/Makefile Doxyfile rasterlite2.pc"
 
 
 # exporting the TARGET_CPU string
@@ -17174,6 +17373,53 @@ _ACEOF
 
 
 # Checks for installed libraries
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_prepare_v2 in -lsqlite3" >&5
+$as_echo_n "checking for sqlite3_prepare_v2 in -lsqlite3... " >&6; }
+if ${ac_cv_lib_sqlite3_sqlite3_prepare_v2+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsqlite3 -lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char sqlite3_prepare_v2 ();
+int
+main ()
+{
+return sqlite3_prepare_v2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_sqlite3_sqlite3_prepare_v2=yes
+else
+  ac_cv_lib_sqlite3_sqlite3_prepare_v2=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_prepare_v2" >&5
+$as_echo "$ac_cv_lib_sqlite3_sqlite3_prepare_v2" >&6; }
+if test "x$ac_cv_lib_sqlite3_sqlite3_prepare_v2" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBSQLITE3 1
+_ACEOF
+
+  LIBS="-lsqlite3 $LIBS"
+
+else
+  as_fn_error $? "'libsqlite3' is required but it doesn't seem to be installed on this system." "$LINENO" 5
+fi
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inflateInit_ in -lz" >&5
 $as_echo_n "checking for inflateInit_ in -lz... " >&6; }
 if ${ac_cv_lib_z_inflateInit_+:} false; then :
@@ -17312,7 +17558,7 @@ _ACEOF
   LIBS="-lgif $LIBS"
 
 else
-  as_fn_error $? "'libpng' is required but it doesn't seems to be installed on this system." "$LINENO" 5
+  as_fn_error $? "'libgif' is required but it doesn't seems to be installed on this system." "$LINENO" 5
 fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TIFFClientOpen in -ltiff" >&5
@@ -17605,6 +17851,145 @@ fi
 
 
 
+#-----------------------------------------------------------------------
+#   --enable-openjpeg
+#
+# Check whether --enable-openjpeg was given.
+if test "${enable_openjpeg+set}" = set; then :
+  enableval=$enable_openjpeg;
+else
+  enable_openjpeg=yes
+fi
+
+    if test x"$enable_openjpeg" != "xno"; then
+    #
+    # testing OpenJpeg-2 headers
+    # they could be either on -/include/openjpeg-2.0
+    #                   or on -/include/openjpeg-2.1
+    #
+    for ac_header in openjpeg-2.0/openjpeg.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "openjpeg-2.0/openjpeg.h" "ac_cv_header_openjpeg_2_0_openjpeg_h" "$ac_includes_default"
+if test "x$ac_cv_header_openjpeg_2_0_openjpeg_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_OPENJPEG_2_0_OPENJPEG_H 1
+_ACEOF
+
+fi
+
+done
+
+    for ac_header in openjpeg-2.1/openjpeg.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "openjpeg-2.1/openjpeg.h" "ac_cv_header_openjpeg_2_1_openjpeg_h" "$ac_includes_default"
+if test "x$ac_cv_header_openjpeg_2_1_openjpeg_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_OPENJPEG_2_1_OPENJPEG_H 1
+_ACEOF
+
+fi
+
+done
+
+    if test x"$ac_cv_header_openjpeg_2_0_openjpeg_h" != x"yes" &&
+        test x"$ac_cv_header_openjpeg_2_1_openjpeg_h" != x"yes";
+    then
+        as_fn_error $? "'OpenJpeg-2' is required but the header (openjpeg.h) doesn't seem to be installed on this system" "$LINENO" 5
+    fi
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for opj_create_decompress in -lopenjp2" >&5
+$as_echo_n "checking for opj_create_decompress in -lopenjp2... " >&6; }
+if ${ac_cv_lib_openjp2_opj_create_decompress+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lopenjp2 -lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opj_create_decompress ();
+int
+main ()
+{
+return opj_create_decompress ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_openjp2_opj_create_decompress=yes
+else
+  ac_cv_lib_openjp2_opj_create_decompress=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_openjp2_opj_create_decompress" >&5
+$as_echo "$ac_cv_lib_openjp2_opj_create_decompress" >&6; }
+if test "x$ac_cv_lib_openjp2_opj_create_decompress" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBOPENJP2 1
+_ACEOF
+
+  LIBS="-lopenjp2 $LIBS"
+
+else
+  as_fn_error $? "'libopenjp2' is required but it doesn't seems to be installed on this system." "$LINENO" 5
+fi
+
+    # testing for OpenJpeg 2.0 or 2.1
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef HAVE_OPENJPEG_2_1_OPENJPEG_H
+                                       #include <openjpeg-2.1/openjpeg.h>
+                                       #else
+                                       #include <openjpeg-2.0/openjpeg.h>
+                                       #endif
+int
+main ()
+{
+void *d; opj_stream_t *s; opj_stream_set_user_data (s, &d, NULL);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+                      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+                      $as_echo "#define OPENJPEG_2_1 1" >>confdefs.h
+
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  $as_echo "#define OMIT_OPENJPEG 1" >>confdefs.h
+
+fi
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+#   --enable-webp
+#
+# Check whether --enable-webp was given.
+if test "${enable_webp+set}" = set; then :
+  enableval=$enable_webp;
+else
+  enable_webp=yes
+fi
+
+if test x"$enable_webp" != "xno"; then
+
 pkg_failed=no
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBWEBP" >&5
 $as_echo_n "checking for LIBWEBP... " >&6; }
@@ -17677,7 +18062,23 @@ $as_echo "yes" >&6; }
 fi
 
 
+else
+  $as_echo "#define OMIT_WEBP 1" >>confdefs.h
+
+fi
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+#   --enable-lzma
+#
+# Check whether --enable-lzma was given.
+if test "${enable_lzma+set}" = set; then :
+  enableval=$enable_lzma;
+else
+  enable_lzma=yes
+fi
 
+if test x"$enable_lzma" != "xno"; then
 
 pkg_failed=no
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBLZMA" >&5
@@ -17751,6 +18152,89 @@ $as_echo "yes" >&6; }
 fi
 
 
+else
+  $as_echo "#define OMIT_LZMA 1" >>confdefs.h
+
+fi
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+#   --enable-charls
+#
+# Check whether --enable-charls was given.
+if test "${enable_charls+set}" = set; then :
+  enableval=$enable_charls;
+else
+  enable_charls=yes
+fi
+
+if test x"$enable_charls" != "xno"; then
+    for ac_header in CharLS/interface.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "CharLS/interface.h" "ac_cv_header_CharLS_interface_h" "$ac_includes_default"
+if test "x$ac_cv_header_CharLS_interface_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_CHARLS_INTERFACE_H 1
+_ACEOF
+
+else
+  as_fn_error $? "cannot find CharLS/interface.h, bailing out" "$LINENO" 5
+fi
+
+done
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for JpegLsEncode in -lCharLS" >&5
+$as_echo_n "checking for JpegLsEncode in -lCharLS... " >&6; }
+if ${ac_cv_lib_CharLS_JpegLsEncode+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lCharLS -lm $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char JpegLsEncode ();
+int
+main ()
+{
+return JpegLsEncode ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_CharLS_JpegLsEncode=yes
+else
+  ac_cv_lib_CharLS_JpegLsEncode=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_CharLS_JpegLsEncode" >&5
+$as_echo "$ac_cv_lib_CharLS_JpegLsEncode" >&6; }
+if test "x$ac_cv_lib_CharLS_JpegLsEncode" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBCHARLS 1
+_ACEOF
+
+  LIBS="-lCharLS $LIBS"
+
+else
+  as_fn_error $? "'libCharLS' is required but it doesn't seems to be installed on this system." "$LINENO" 5
+fi
+
+else
+  $as_echo "#define OMIT_CHARLS 1" >>confdefs.h
+
+fi
+#-----------------------------------------------------------------------
 
 
 pkg_failed=no
@@ -18048,6 +18532,80 @@ fi
 
 
 
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for FREETYPE2" >&5
+$as_echo_n "checking for FREETYPE2... " >&6; }
+
+if test -n "$FREETYPE2_CFLAGS"; then
+    pkg_cv_FREETYPE2_CFLAGS="$FREETYPE2_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"freetype2\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "freetype2") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_FREETYPE2_CFLAGS=`$PKG_CONFIG --cflags "freetype2" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$FREETYPE2_LIBS"; then
+    pkg_cv_FREETYPE2_LIBS="$FREETYPE2_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"freetype2\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "freetype2") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_FREETYPE2_LIBS=`$PKG_CONFIG --libs "freetype2" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        FREETYPE2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "freetype2" 2>&1`
+        else
+	        FREETYPE2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "freetype2" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$FREETYPE2_PKG_ERRORS" >&5
+
+	as_fn_error $? "'freetype2' is required but it doesn't seem to be installed on this system." "$LINENO" 5
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	as_fn_error $? "'freetype2' is required but it doesn't seem to be installed on this system." "$LINENO" 5
+else
+	FREETYPE2_CFLAGS=$pkg_cv_FREETYPE2_CFLAGS
+	FREETYPE2_LIBS=$pkg_cv_FREETYPE2_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+
+
+
 # Checking for MinGW
  if test "$target_alias" = "mingw32"; then
   MINGW_TRUE=
@@ -18603,7 +19161,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by librasterlite2 $as_me 1.0.0-rc0, which was
+This file was extended by librasterlite2 $as_me 1.0.0-devel, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -18669,7 +19227,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-librasterlite2 config.status 1.0.0-rc0
+librasterlite2 config.status 1.0.0-devel
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -19185,7 +19743,6 @@ do
     "test/sql_stmt_tests/Makefile") CONFIG_FILES="$CONFIG_FILES test/sql_stmt_tests/Makefile" ;;
     "test/sql_stmt_security_tests/Makefile") CONFIG_FILES="$CONFIG_FILES test/sql_stmt_security_tests/Makefile" ;;
     "tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;;
-    "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;;
     "Doxyfile") CONFIG_FILES="$CONFIG_FILES Doxyfile" ;;
     "rasterlite2.pc") CONFIG_FILES="$CONFIG_FILES rasterlite2.pc" ;;
 
diff --git a/configure.ac b/configure.ac
index 14723ec..376bfa9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ(2.61)
-AC_INIT(librasterlite2, 1.0.0-rc0, a.furieri at lqt.it)
+AC_INIT(librasterlite2, 1.0.0-devel, a.furieri at lqt.it)
 AC_LANG(C)
 AC_CONFIG_AUX_DIR([.])
 AC_CONFIG_MACRO_DIR([m4])
@@ -28,7 +28,18 @@ AH_TEMPLATE([NDEBUG],
 AC_DEFINE(NDEBUG)
 AH_TEMPLATE([TARGET_CPU],
             [Should contain a text-string describing the intended target CPU])
-
+AH_TEMPLATE([OPENJPEG_2_1],
+            [testing for OpenJpeg 2.1])
+            
+# config depending options
+AH_TEMPLATE([OMIT_LZMA],
+            [Should be defined in order to disable LZMA support.])
+AH_TEMPLATE([OMIT_WEBP],
+            [Should be defined in order to disable WebP support.])
+AH_TEMPLATE([OMIT_OPENJPEG],
+            [Should be defined in order to disable OpenJpeg support.])
+AH_TEMPLATE([OMIT_CHARLS],
+            [Should be defined in order to disable CharLS support.])
 
 # Checks for header files.
 AC_CHECK_HEADERS(stdlib.h,, [AC_MSG_ERROR([cannot find stdlib.h, bailing out])])
@@ -40,9 +51,11 @@ AC_CHECK_HEADERS(float.h,,[AC_MSG_ERROR([cannot find float.h, bailing out])])
 AC_CHECK_HEADERS(jpeglib.h,, [AC_MSG_ERROR([cannot find jpeglib.h, bailing out])])
 AC_CHECK_HEADERS(jerror.h,, [AC_MSG_ERROR([cannot find jerror.h, bailing out])])
 AC_CHECK_HEADERS(png.h,, [AC_MSG_ERROR([cannot find png.h, bailing out])])
+AC_CHECK_HEADERS(sqlite3.h,, [AC_MSG_ERROR([cannot find sqlite3.h, bailing out])])
+AC_CHECK_HEADERS(sqlite3ext.h,, [AC_MSG_ERROR([cannot find sqlite3ext.h, bailing out])])
 AC_CHECK_HEADERS(zlib.h,, [AC_MSG_ERROR([cannot find zlib.h, bailing out])])
 AC_CHECK_HEADERS(gif_lib.h,, [AC_MSG_ERROR([cannot find gif_lib.h, bailing out])])
-AC_CHECK_HEADERS(lzma.h,, [AC_MSG_ERROR([cannot find lzma.h, bailing out])])
+
 
 #
 # testing GeoTiff headers
@@ -105,7 +118,6 @@ AC_CONFIG_FILES([Makefile \
 		test/sql_stmt_tests/Makefile \
 		test/sql_stmt_security_tests/Makefile \
 		tools/Makefile \
-		examples/Makefile \
 		Doxyfile \
 		rasterlite2.pc])
 
@@ -114,9 +126,10 @@ rl2_cpu=`$CC -dumpmachine`
 AC_DEFINE_UNQUOTED([TARGET_CPU], ["$rl2_cpu"])
 
 # Checks for installed libraries
+AC_CHECK_LIB(sqlite3,sqlite3_prepare_v2,,AC_MSG_ERROR(['libsqlite3' is required but it doesn't seem to be installed on this system.]),-lm)
 AC_CHECK_LIB(z,inflateInit_,,AC_MSG_ERROR(['libz' is required but it doesn't seems to be installed on this system.]),-lm)
 AC_CHECK_LIB(jpeg,jpeg_start_compress,,AC_MSG_ERROR(['libjpeg' is required but it doesn't seems to be installed on this system.]),-lm)
-AC_CHECK_LIB(gif,DGifSlurp,,AC_MSG_ERROR(['libpng' is required but it doesn't seems to be installed on this system.]),-lm)
+AC_CHECK_LIB(gif,DGifSlurp,,AC_MSG_ERROR(['libgif' is required but it doesn't seems to be installed on this system.]),-lm)
 AC_CHECK_LIB(tiff,TIFFClientOpen,,AC_MSG_ERROR(['libtiff' is required but it doesn't seems to be installed on this system.]),-lm)
 AC_CHECK_LIB(geotiff,GTIFSetFromProj4,,AC_MSG_ERROR(['libgeotiff' [>= v.1.2.5] is required but it doesn't seems to be installed on this system.]),-lm)
 
@@ -124,13 +137,88 @@ PKG_CHECK_MODULES([LIBPNG], [libpng], , AC_MSG_ERROR(['libpng' is required but i
 AC_SUBST(LIBPNG_CFLAGS)
 AC_SUBST(LIBPNG_LIBS)
 
-PKG_CHECK_MODULES([LIBWEBP], [libwebp], , AC_MSG_ERROR(['libwebp' is required but it doesn't seems to be installed on this system.]))
-AC_SUBST(LIBWEBP_CFLAGS)
-AC_SUBST(LIBWEBP_LIBS)
 
-PKG_CHECK_MODULES([LIBLZMA], [liblzma], , AC_MSG_ERROR(['liblzma' is required but it doesn't seems to be installed on this system.]))
-AC_SUBST(LIBLZMA_CFLAGS)
-AC_SUBST(LIBLZMA_LIBS)
+#-----------------------------------------------------------------------
+#   --enable-openjpeg
+#
+AC_ARG_ENABLE(openjpeg, [AS_HELP_STRING(
+  [--enable-openjpeg], [enables OpenJpeg inclusion [default=yes]])],
+  [], [enable_openjpeg=yes])
+    if test x"$enable_openjpeg" != "xno"; then
+    #
+    # testing OpenJpeg-2 headers
+    # they could be either on -/include/openjpeg-2.0
+    #                   or on -/include/openjpeg-2.1
+    #
+    AC_CHECK_HEADERS(openjpeg-2.0/openjpeg.h)
+    AC_CHECK_HEADERS(openjpeg-2.1/openjpeg.h)
+    if test x"$ac_cv_header_openjpeg_2_0_openjpeg_h" != x"yes" &&
+        test x"$ac_cv_header_openjpeg_2_1_openjpeg_h" != x"yes";
+    then
+        AC_MSG_ERROR(['OpenJpeg-2' is required but the header (openjpeg.h) doesn't seem to be installed on this system])
+    fi 
+    AC_CHECK_LIB(openjp2,opj_create_decompress,,AC_MSG_ERROR(['libopenjp2' is required but it doesn't seems to be installed on this system.]),-lm)
+    # testing for OpenJpeg 2.0 or 2.1
+    AC_COMPILE_IFELSE(  [AC_LANG_PROGRAM([[#ifdef HAVE_OPENJPEG_2_1_OPENJPEG_H
+                                       #include <openjpeg-2.1/openjpeg.h>
+                                       #else
+                                       #include <openjpeg-2.0/openjpeg.h>
+                                       #endif]],
+                                     [[void *d; opj_stream_t *s; opj_stream_set_user_data (s, &d, NULL);]])],
+                    [
+                      AC_MSG_RESULT([yes])
+                      AC_DEFINE(OPENJPEG_2_1)
+                    ],
+                    [AC_MSG_RESULT([no])]
+                 )
+else
+  AC_DEFINE(OMIT_OPENJPEG)
+fi
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+#   --enable-webp
+#
+AC_ARG_ENABLE(webp, [AS_HELP_STRING(
+  [--enable-webp], [enables WebP inclusion [default=yes]])],
+  [], [enable_webp=yes])
+if test x"$enable_webp" != "xno"; then
+    PKG_CHECK_MODULES([LIBWEBP], [libwebp], , AC_MSG_ERROR(['libwebp' is required but it doesn't seems to be installed on this system.]))
+    AC_SUBST(LIBWEBP_CFLAGS)
+    AC_SUBST(LIBWEBP_LIBS)
+else
+  AC_DEFINE(OMIT_WEBP)
+fi
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+#   --enable-lzma
+#
+AC_ARG_ENABLE(lzma, [AS_HELP_STRING(
+  [--enable-lzma], [enables LZMA inclusion [default=yes]])],
+  [], [enable_lzma=yes])
+if test x"$enable_lzma" != "xno"; then
+    PKG_CHECK_MODULES([LIBLZMA], [liblzma], , AC_MSG_ERROR(['liblzma' is required but it doesn't seems to be installed on this system.]))
+    AC_SUBST(LIBLZMA_CFLAGS)
+    AC_SUBST(LIBLZMA_LIBS)
+else
+  AC_DEFINE(OMIT_LZMA)
+fi
+#-----------------------------------------------------------------------
+
+#-----------------------------------------------------------------------
+#   --enable-charls
+#
+AC_ARG_ENABLE(charls, [AS_HELP_STRING(
+  [--enable-charls], [enables CharLS inclusion [default=yes]])],
+  [], [enable_charls=yes])
+if test x"$enable_charls" != "xno"; then
+    AC_CHECK_HEADERS(CharLS/interface.h,, [AC_MSG_ERROR([cannot find CharLS/interface.h, bailing out])])
+    AC_CHECK_LIB(CharLS,JpegLsEncode,,AC_MSG_ERROR(['libCharLS' is required but it doesn't seems to be installed on this system.]),-lm)
+else
+  AC_DEFINE(OMIT_CHARLS)
+fi
+#-----------------------------------------------------------------------
 
 PKG_CHECK_MODULES([LIBSPATIALITE], [spatialite], , AC_MSG_ERROR(['libspatialite' is required but it doesn't seem to be installed on this system.]))
 AC_SUBST(LIBSPATIALITE_CFLAGS)
@@ -148,6 +236,10 @@ PKG_CHECK_MODULES([LIBXML2], [libxml-2.0], , AC_MSG_ERROR(['libxml2' is required
 AC_SUBST(LIBXML2_CFLAGS)
 AC_SUBST(LIBXML2_LIBS)
 
+PKG_CHECK_MODULES([FREETYPE2], [freetype2], , AC_MSG_ERROR(['freetype2' is required but it doesn't seem to be installed on this system.]))
+AC_SUBST(LIBFREETYPE2_CFLAGS)
+AC_SUBST(LIBFREETYPE2_LIBS)
+
 # Checking for MinGW
 AM_CONDITIONAL([MINGW], [test "$target_alias" = "mingw32"])
 
diff --git a/examples/Makefile.am b/examples/Makefile.am
deleted file mode 100644
index c1dfd5d..0000000
--- a/examples/Makefile.am
+++ /dev/null
@@ -1,8 +0,0 @@
-noinst_PROGRAMS = sample1
-
-AM_CFLAGS = -I at srcdir@/../headers
-AM_LDFLAGS = -L../src -lrasterlite2 -ljpeg -lpng -lm $(GCOV_FLAGS)
-
-MOSTLYCLEANFILES = *.gcna *.gcno *.gcda
-
-EXTRA_DIST = examples.doxy
diff --git a/examples/Makefile.in b/examples/Makefile.in
deleted file mode 100644
index c729f4b..0000000
--- a/examples/Makefile.in
+++ /dev/null
@@ -1,597 +0,0 @@
-# Makefile.in generated by automake 1.13.4 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
-
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
- at SET_MAKE@
-
-VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
-am__make_running_with_option = \
-  case $${target_option-} in \
-      ?) ;; \
-      *) echo "am__make_running_with_option: internal error: invalid" \
-              "target option '$${target_option-}' specified" >&2; \
-         exit 1;; \
-  esac; \
-  has_opt=no; \
-  sane_makeflags=$$MAKEFLAGS; \
-  if $(am__is_gnu_make); then \
-    sane_makeflags=$$MFLAGS; \
-  else \
-    case $$MAKEFLAGS in \
-      *\\[\ \	]*) \
-        bs=\\; \
-        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
-          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
-    esac; \
-  fi; \
-  skip_next=no; \
-  strip_trailopt () \
-  { \
-    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
-  }; \
-  for flg in $$sane_makeflags; do \
-    test $$skip_next = yes && { skip_next=no; continue; }; \
-    case $$flg in \
-      *=*|--*) continue;; \
-        -*I) strip_trailopt 'I'; skip_next=yes;; \
-      -*I?*) strip_trailopt 'I';; \
-        -*O) strip_trailopt 'O'; skip_next=yes;; \
-      -*O?*) strip_trailopt 'O';; \
-        -*l) strip_trailopt 'l'; skip_next=yes;; \
-      -*l?*) strip_trailopt 'l';; \
-      -[dEDm]) skip_next=yes;; \
-      -[JT]) skip_next=yes;; \
-    esac; \
-    case $$flg in \
-      *$$target_option*) has_opt=yes; break;; \
-    esac; \
-  done; \
-  test $$has_opt = yes
-am__make_dryrun = (target_option=n; $(am__make_running_with_option))
-am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
-pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-noinst_PROGRAMS = sample1$(EXEEXT)
-subdir = examples
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
-	$(top_srcdir)/depcomp
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
-	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
-	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
-	$(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-	$(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
-PROGRAMS = $(noinst_PROGRAMS)
-sample1_SOURCES = sample1.c
-sample1_OBJECTS = sample1.$(OBJEXT)
-sample1_LDADD = $(LDADD)
-AM_V_lt = $(am__v_lt_ at AM_V@)
-am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
-am__v_lt_0 = --silent
-am__v_lt_1 = 
-AM_V_P = $(am__v_P_ at AM_V@)
-am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
-am__v_P_0 = false
-am__v_P_1 = :
-AM_V_GEN = $(am__v_GEN_ at AM_V@)
-am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
-am__v_GEN_0 = @echo "  GEN     " $@;
-am__v_GEN_1 = 
-AM_V_at = $(am__v_at_ at AM_V@)
-am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
-am__v_at_0 = @
-am__v_at_1 = 
-DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
-am__mv = mv -f
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
-	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
-	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
-	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
-	$(AM_CFLAGS) $(CFLAGS)
-AM_V_CC = $(am__v_CC_ at AM_V@)
-am__v_CC_ = $(am__v_CC_ at AM_DEFAULT_V@)
-am__v_CC_0 = @echo "  CC      " $@;
-am__v_CC_1 = 
-CCLD = $(CC)
-LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
-	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
-	$(AM_LDFLAGS) $(LDFLAGS) -o $@
-AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
-am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
-am__v_CCLD_0 = @echo "  CCLD    " $@;
-am__v_CCLD_1 = 
-SOURCES = sample1.c
-DIST_SOURCES = sample1.c
-am__can_run_installinfo = \
-  case $$AM_UPDATE_INFO_DIR in \
-    n|no|NO) false;; \
-    *) (install-info --version) >/dev/null 2>&1;; \
-  esac
-am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-# Read a list of newline-separated strings from the standard input,
-# and print each of them once, without duplicates.  Input order is
-# *not* preserved.
-am__uniquify_input = $(AWK) '\
-  BEGIN { nonempty = 0; } \
-  { items[$$0] = 1; nonempty = 1; } \
-  END { if (nonempty) { for (i in items) print i; }; } \
-'
-# Make sure the list of sources is unique.  This is necessary because,
-# e.g., the same source file might be shared among _SOURCES variables
-# for different programs/libraries.
-am__define_uniq_tagged_files = \
-  list='$(am__tagged_files)'; \
-  unique=`for i in $$list; do \
-    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-  done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-AR = @AR@
-AS = @AS@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CXX = @CXX@
-CXXCPP = @CXXCPP@
-CXXDEPMODE = @CXXDEPMODE@
-CXXFLAGS = @CXXFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DLLTOOL = @DLLTOOL@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-GREP = @GREP@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LIBCAIRO_CFLAGS = @LIBCAIRO_CFLAGS@
-LIBCAIRO_LIBS = @LIBCAIRO_LIBS@
-LIBCURL_CFLAGS = @LIBCURL_CFLAGS@
-LIBCURL_LIBS = @LIBCURL_LIBS@
-LIBLZMA_CFLAGS = @LIBLZMA_CFLAGS@
-LIBLZMA_LIBS = @LIBLZMA_LIBS@
-LIBOBJS = @LIBOBJS@
-LIBPNG_CFLAGS = @LIBPNG_CFLAGS@
-LIBPNG_LIBS = @LIBPNG_LIBS@
-LIBS = @LIBS@
-LIBSPATIALITE_CFLAGS = @LIBSPATIALITE_CFLAGS@
-LIBSPATIALITE_LIBS = @LIBSPATIALITE_LIBS@
-LIBTOOL = @LIBTOOL@
-LIBWEBP_CFLAGS = @LIBWEBP_CFLAGS@
-LIBWEBP_LIBS = @LIBWEBP_LIBS@
-LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
-LIBXML2_LIBS = @LIBXML2_LIBS@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
-MAKEINFO = @MAKEINFO@
-MANIFEST_TOOL = @MANIFEST_TOOL@
-MKDIR_P = @MKDIR_P@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PKG_CONFIG = @PKG_CONFIG@
-PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
-PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
-RANLIB = @RANLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-VERSION = @VERSION@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_AR = @ac_ct_AR@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_CXX = @ac_ct_CXX@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-AM_CFLAGS = -I at srcdir@/../headers
-AM_LDFLAGS = -L../src -lrasterlite2 -ljpeg -lpng -lm $(GCOV_FLAGS)
-MOSTLYCLEANFILES = *.gcna *.gcno *.gcda
-EXTRA_DIST = examples.doxy
-all: all-am
-
-.SUFFIXES:
-.SUFFIXES: .c .lo .o .obj
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
-	@for dep in $?; do \
-	  case '$(am__configure_deps)' in \
-	    *$$dep*) \
-	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
-	        && { if test -f $@; then exit 0; else break; fi; }; \
-	      exit 1;; \
-	  esac; \
-	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu examples/Makefile'; \
-	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --gnu examples/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-	@case '$?' in \
-	  *config.status*) \
-	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
-	  *) \
-	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
-	esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(am__aclocal_m4_deps):
-
-clean-noinstPROGRAMS:
-	@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
-	echo " rm -f" $$list; \
-	rm -f $$list || exit $$?; \
-	test -n "$(EXEEXT)" || exit 0; \
-	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
-	echo " rm -f" $$list; \
-	rm -f $$list
-
-sample1$(EXEEXT): $(sample1_OBJECTS) $(sample1_DEPENDENCIES) $(EXTRA_sample1_DEPENDENCIES) 
-	@rm -f sample1$(EXEEXT)
-	$(AM_V_CCLD)$(LINK) $(sample1_OBJECTS) $(sample1_LDADD) $(LIBS)
-
-mostlyclean-compile:
-	-rm -f *.$(OBJEXT)
-
-distclean-compile:
-	-rm -f *.tab.c
-
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/sample1.Po at am__quote@
-
-.c.o:
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c $<
-
-.c.obj:
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
-
-.c.lo:
- at am__fastdepCC_TRUE@	$(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
- at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LTCOMPILE) -c -o $@ $<
-
-mostlyclean-libtool:
-	-rm -f *.lo
-
-clean-libtool:
-	-rm -rf .libs _libs
-
-ID: $(am__tagged_files)
-	$(am__define_uniq_tagged_files); mkid -fID $$unique
-tags: tags-am
-TAGS: tags
-
-tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
-	set x; \
-	here=`pwd`; \
-	$(am__define_uniq_tagged_files); \
-	shift; \
-	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
-	  test -n "$$unique" || unique=$$empty_fix; \
-	  if test $$# -gt 0; then \
-	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	      "$$@" $$unique; \
-	  else \
-	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-	      $$unique; \
-	  fi; \
-	fi
-ctags: ctags-am
-
-CTAGS: ctags
-ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
-	$(am__define_uniq_tagged_files); \
-	test -z "$(CTAGS_ARGS)$$unique" \
-	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
-	     $$unique
-
-GTAGS:
-	here=`$(am__cd) $(top_builddir) && pwd` \
-	  && $(am__cd) $(top_srcdir) \
-	  && gtags -i $(GTAGS_ARGS) "$$here"
-cscopelist: cscopelist-am
-
-cscopelist-am: $(am__tagged_files)
-	list='$(am__tagged_files)'; \
-	case "$(srcdir)" in \
-	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
-	  *) sdir=$(subdir)/$(srcdir) ;; \
-	esac; \
-	for i in $$list; do \
-	  if test -f "$$i"; then \
-	    echo "$(subdir)/$$i"; \
-	  else \
-	    echo "$$sdir/$$i"; \
-	  fi; \
-	done >> $(top_builddir)/cscope.files
-
-distclean-tags:
-	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
-	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-	list='$(DISTFILES)'; \
-	  dist_files=`for file in $$list; do echo $$file; done | \
-	  sed -e "s|^$$srcdirstrip/||;t" \
-	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
-	case $$dist_files in \
-	  */*) $(MKDIR_P) `echo "$$dist_files" | \
-			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
-			   sort -u` ;; \
-	esac; \
-	for file in $$dist_files; do \
-	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-	  if test -d $$d/$$file; then \
-	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
-	    if test -d "$(distdir)/$$file"; then \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-	    fi; \
-	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-	    fi; \
-	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
-	  else \
-	    test -f "$(distdir)/$$file" \
-	    || cp -p $$d/$$file "$(distdir)/$$file" \
-	    || exit 1; \
-	  fi; \
-	done
-check-am: all-am
-check: check-am
-all-am: Makefile $(PROGRAMS)
-installdirs:
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
-	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
-	if test -z '$(STRIP)'; then \
-	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	      install; \
-	else \
-	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
-	fi
-mostlyclean-generic:
-	-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
-
-clean-generic:
-
-distclean-generic:
-	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-
-maintainer-clean-generic:
-	@echo "This command is intended for maintainers to use"
-	@echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
-	mostlyclean-am
-
-distclean: distclean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
-	distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-html-am:
-
-info: info-am
-
-info-am:
-
-install-data-am:
-
-install-dvi: install-dvi-am
-
-install-dvi-am:
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-html-am:
-
-install-info: install-info-am
-
-install-info-am:
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-pdf-am:
-
-install-ps: install-ps-am
-
-install-ps-am:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
-	-rm -rf ./$(DEPDIR)
-	-rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am:
-
-.MAKE: install-am install-strip
-
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
-	clean-libtool clean-noinstPROGRAMS cscopelist-am ctags \
-	ctags-am distclean distclean-compile distclean-generic \
-	distclean-libtool distclean-tags distdir dvi dvi-am html \
-	html-am info info-am install install-am install-data \
-	install-data-am install-dvi install-dvi-am install-exec \
-	install-exec-am install-html install-html-am install-info \
-	install-info-am install-man install-pdf install-pdf-am \
-	install-ps install-ps-am install-strip installcheck \
-	installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-compile \
-	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
-	tags tags-am uninstall uninstall-am
-
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/examples/examples.doxy b/examples/examples.doxy
deleted file mode 100644
index 7275914..0000000
--- a/examples/examples.doxy
+++ /dev/null
@@ -1,152 +0,0 @@
-/** \example test_xl.c
-
-test_xl.c is a simple demonstration and diagnostic tool for the Excel (.xls)
-file format.
-
-This sample code provides an example of:
- - opening the .xls file
- - querying general information
- - querying Workbooks, SST entries and FAT entries
- - error handling
- - closing the .xls file when no further operations are required
- 
-Here is an example of a typical run:
-\verbatim
-./test_xl multi.xls
-
-Excel document: multi.xls
-==========================================================
-CFBF Version ........: 3
-CFBF Sector size ....: 512
-CFBF FAT entries ....: 128
-BIFF Version ........: 8 [Excel 98/XP/2003/2007/2010]
-BIFF Max record size : 8224
-BIFF DateMode .......: 0 [day#1 = '1900-01-01']
-BIFF Password/Crypted: NO, clear data
-BIFF CodePage .......: UTF-16LE [Unicode]
-BIFF Worksheets .....: 2
-BIFF SST entries ....: 24
-BIFF Formats ........: 2
-BIFF eXtendedFormats : 24
-
-Worksheets:
-=========================================================
-  0] I'm a Worsheet
-        ok, Worksheet succesfully selected: currently active: 0
-        12 Rows X 7 Columns
-
-  1] Yet another
-        ok, Worksheet succesfully selected: currently active: 1
-        302 Rows X 4 Columns
-\endverbatim
-
-Here is another example. Note that this earlier version (Excel 3.0) format
-does not use the CFBF container, so no information is provided for the first
-three entries.
-\verbatim
-# ./test_xl v3sample.xls
-
-Excel document: v3sample.xls
-==========================================================
-CFBF Version ........: UNKNOWN
-CFBF Sector size ....: UNKNOWN
-CFBF FAT entries ....: 0
-BIFF Version ........: 3 [Excel 3.0]
-BIFF Max record size : UNKNOWN
-BIFF DateMode .......: 0 [day#1 = '1900-01-01']
-BIFF Password/Crypted: NO, clear data
-BIFF CodePage .......: CP1252 [Windows Latin 1]
-BIFF Worksheets .....: 1
-BIFF Formats ........: 21
-BIFF eXtendedFormats : 25
-
-Worksheets:
-=========================================================
-  0] Worksheet
-        ok, Worksheet succesfully selected: currently active: 0
-        17 Rows X 6 Columns
-\endverbatim
-
-For more information, or to aid with debugging, you can specify a -verbose
-flag, as shown in this example:
-\verbatim
-# ./test_xl multi.xls -verbose
-
-Excel document: multi.xls
-==========================================================
-...
-
-Worksheets:
-=========================================================
-...
-
-SST [Shared String Table]:
-=========================================================
-       0] uno
-       1] one
-       2] due
-       3] two
-       4] tre
-       5] three
-...
-      18] dieci
-      19] ten
-      20] undici
-      21] eleven
-      22] dodici
-      23] twelve
-
-FAT entries [File Allocation Table]:
-=========================================================
-       0 -> 0xfffffffe FATSECT
-       1 -> 0xffffffff FREESECT
-       2 ->        3
-       3 ->        4
-...      
-      36 ->       37
-      37 ->       38
-      38 -> 0xfffffffe ENDOFCHAIN
-      39 -> 0xfffffffe ENDOFCHAIN
-      40 ->       41
-      41 -> 0xfffffffe ENDOFCHAIN
-      42 ->       43
-      43 -> 0xfffffffe ENDOFCHAIN
-      44 -> 0xffffffff FREESECT
-...
-     127 -> 0xffffffff FREESECT
-\endverbatim
-
-*/
-
-/** \example xl2sql.c
-
-xl2sql a simple tool that takes an .xls file as input, and generates a SQL
-script as output. You can then use the SQL script to load the extracted data
-info a SQLite / SpatiaLite database.
-
-Here is a typical usage example:
-\verbatim
-./xl2sql comuni_italiani.xls >comuni.sql
-spatialite italy.sqlite <comuni.sql
-\endverbatim
-
-The first command will parse the .xls document, extracting any data and
-generating the corresponding SQL script. The second command will create and
-populate a database from the SQL script. When using xl2sql this way, the first
-worksheet will become database table xl_table_00, the second worksheet will
-become database table xl_table_01 and so on.
-
-As an alternative, if you pass a second argument to xl2sql, this argument will
-be used as the table prefix. For example:
-\verbatim
-./xl2sql comuni_italiani.xls italia >comuni.sql
-spatialite italy2.sqlite <comuni.sql
-\endverbatim
-
-This will result in the tables being named italia_00, italia_01 and so on.
-
-This sample code provides an example of:
- - selecting a worksheet to be active
- - retrieving cell values 
-
-*/
\ No newline at end of file
diff --git a/examples/sample1.c b/examples/sample1.c
deleted file mode 100644
index f235b13..0000000
--- a/examples/sample1.c
+++ /dev/null
@@ -1,68 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "rasterlite2/rasterlite2.h" 
-
-static void
-test_rgb_jpeg(const char *path)
-{
-	rl2SectionPtr img = rl2_section_from_jpeg(path);
-fprintf(stderr, "read=%d\n", img);
-	if (img == NULL)
-		return;
-
-	if (rl2_section_to_png(img, "./dsc_1470.png") != RL2_OK)
-fprintf(stderr, "png-out-error\n");
-
-	rl2_destroy_section(img);
-}
-
-static void
-test_gray_jpeg(const char *path)
-{
-	rl2SectionPtr img = rl2_section_from_jpeg(path);
-fprintf(stderr, "read=%d\n", img);
-	if (img == NULL)
-		return;
-
-	if (rl2_section_to_png(img, "./dsc_1470gray.png") != RL2_OK)
-fprintf(stderr, "png-out-error\n");
-
-	rl2_destroy_section(img);
-}
-
-static void
-test_palette_png(const char *path)
-{
-	rl2SectionPtr img = rl2_section_from_png(path);
-fprintf(stderr, "read=%d\n", img);
-	if (img == NULL)
-		return;
-
-	if (rl2_section_to_jpeg(img, "./fig-8.jpg", 20) != RL2_OK)
-fprintf(stderr, "jpg-out-error\n");
-
-	rl2_destroy_section(img);
-}
-
-static void
-test_gray_png(const char *path)
-{
-	rl2SectionPtr img = rl2_section_from_png(path);
-fprintf(stderr, "read=%d\n", img);
-	if (img == NULL)
-		return;
-
-	if (rl2_section_to_jpeg(img, "./dsc_1470gr16.jpg", 70) != RL2_OK)
-fprintf(stderr, "jpg-out-error\n");
-
-	rl2_destroy_section(img);
-}
-
-int main(int argc, char *argv[])
-{
-	test_rgb_jpeg("./DSC_1470.JPG");
-	test_gray_jpeg("./DSC_1470gray.jpg");
-	test_palette_png("./fig-8.png");
-	return 0;
-}
diff --git a/headers/Makefile.in b/headers/Makefile.in
index cf95b82..a0946e2 100644
--- a/headers/Makefile.in
+++ b/headers/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# Makefile.in generated by automake 1.15 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -15,7 +15,17 @@
 @SET_MAKE@
 
 VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -79,8 +89,6 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = headers
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
-	$(nobase_include_HEADERS) $(noinst_HEADERS)
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
@@ -88,6 +96,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(nobase_include_HEADERS) \
+	$(noinst_HEADERS) $(am__DIST_COMMON)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -159,6 +169,7 @@ am__define_uniq_tagged_files = \
   done | $(am__uniquify_input)`
 ETAGS = etags
 CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -190,6 +201,8 @@ ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
+FREETYPE2_CFLAGS = @FREETYPE2_CFLAGS@
+FREETYPE2_LIBS = @FREETYPE2_LIBS@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
@@ -202,6 +215,8 @@ LIBCAIRO_CFLAGS = @LIBCAIRO_CFLAGS@
 LIBCAIRO_LIBS = @LIBCAIRO_LIBS@
 LIBCURL_CFLAGS = @LIBCURL_CFLAGS@
 LIBCURL_LIBS = @LIBCURL_LIBS@
+LIBFREETYPE2_CFLAGS = @LIBFREETYPE2_CFLAGS@
+LIBFREETYPE2_LIBS = @LIBFREETYPE2_LIBS@
 LIBLZMA_CFLAGS = @LIBLZMA_CFLAGS@
 LIBLZMA_LIBS = @LIBLZMA_LIBS@
 LIBOBJS = @LIBOBJS@
@@ -321,7 +336,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__confi
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu headers/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu headers/Makefile
-.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -571,6 +585,8 @@ uninstall-am: uninstall-nobase_includeHEADERS
 	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
 	uninstall-am uninstall-nobase_includeHEADERS
 
+.PRECIOUS: Makefile
+
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/headers/rasterlite2/rasterlite2.h b/headers/rasterlite2/rasterlite2.h
index fb5ea05..289396a 100644
--- a/headers/rasterlite2/rasterlite2.h
+++ b/headers/rasterlite2/rasterlite2.h
@@ -70,13 +70,7 @@ extern "C"
 {
 #endif
 
-#ifdef SPATIALITE_AMALGAMATION
-#include <spatialite/sqlite3.h>
-#else
-#include <sqlite3.h>
-#endif
-
-#include <spatialite/gaiageo.h>
+#include "rasterlite2/sqlite.h"
 
 /** RasterLite2 flag: FALSE */
 #define RL2_FALSE			0
@@ -140,10 +134,14 @@ extern "C"
 #define RL2_COMPRESSION_UNKNOWN		0x20
 /** RasterLite2 constant: Compression None */
 #define RL2_COMPRESSION_NONE		0x21
-/** RasterLite2 constant: Compression Deflate (zip) */
+/** RasterLite2 constant: Compression Deflate Delta (zip) */
 #define RL2_COMPRESSION_DEFLATE		0x22
-/** RasterLite2 constant: Compression LZMA */
+/** RasterLite2 constant: Compression Deflate noDelta (zip) */
+#define RL2_COMPRESSION_DEFLATE_NO	0xd2
+/** RasterLite2 constant: Compression LZMA Delta */
 #define RL2_COMPRESSION_LZMA		0x23
+/** RasterLite2 constant: Compression LZMA noDelta */
+#define RL2_COMPRESSION_LZMA_NO		0xd3
 /** RasterLite2 constant: Compression GIF */
 #define RL2_COMPRESSION_GIF		0x24
 /** RasterLite2 constant: Compression PNG */
@@ -160,6 +158,12 @@ extern "C"
 #define RL2_COMPRESSION_CCITTFAX4	0x30
 /** RasterLite2 constant: Compression LZW */
 #define RL2_COMPRESSION_LZW		0x31
+/** RasterLite2 constant: Compression CHARLS */
+#define RL2_COMPRESSION_CHARLS		0x32
+/** RasterLite2 constant: Compression JPEG2000 (lossy mode) */
+#define RL2_COMPRESSION_LOSSY_JP2	0x33
+/** RasterLite2 constant: Compression JPEG2000 (lossless mode) */
+#define RL2_COMPRESSION_LOSSLESS_JP2	0x34
 
 /** RasterLite2 constant: UNKNOWN number of Bands */
 #define RL2_BANDS_UNKNOWN		0x00
@@ -214,11 +218,73 @@ extern "C"
 /** RasterLite2 constant: contrast enhancement GAMMA-VALUE */
 #define RL2_CONTRAST_ENHANCEMENT_GAMMA		0x93
 
-/** ResterLite2 constant: GroupRenderer - RasterLayer */
+/** RasterLite2 constant: GroupRenderer - RasterLayer */
 #define RL2_GROUP_RENDERER_RASTER_LAYER	0xba
 /** ResterLite2 constant: GroupRenderer - VectorLayer */
 #define RL2_GROUP_RENDERER_VECTOR_LAYER	0xbb
 
+/** RasterLite2 constants: unknown Symbolizer type */
+#define RL2_UNKNOWN_SYMBOLIZER	0xa0
+/** RasterLite2 constants: Point Symbolizer type */
+#define RL2_POINT_SYMBOLIZER	0xa1
+/** RasterLite2 constants: Line Symbolizer type */
+#define RL2_LINE_SYMBOLIZER	0xa2
+/** RasterLite2 constants: Polygon Symbolizer type */
+#define RL2_POLYGON_SYMBOLIZER	0xa3
+/** RasterLite2 constants: Text Symbolizer type */
+#define RL2_TEXT_SYMBOLIZER	0xa4
+
+/** RasterLite2 constants: unknown Stroke Linejoin */
+#define RL2_STROKE_LINEJOIN_UNKNOWN	0x50
+/** RasterLite2 constants: Stroke Linejoin - Mitre */
+#define RL2_STROKE_LINEJOIN_MITRE	0x51
+/** RasterLite2 constants: Stroke Linejoin - Round */
+#define RL2_STROKE_LINEJOIN_ROUND	0x52
+/** RasterLite2 constants: Stroke Linejoin - Bevel */
+#define RL2_STROKE_LINEJOIN_BEVEL	0x53
+
+/** RasterLite2 constants: unknown Stroke Linecap */
+#define RL2_STROKE_LINECAP_UNKNOWN	0x60
+/** RasterLite2 constants: Stroke Linecap - Butt */
+#define RL2_STROKE_LINECAP_BUTT		0x61
+/** RasterLite2 constants: Stroke Linecap - Round */
+#define RL2_STROKE_LINECAP_ROUND	0x62
+/** RasterLite2 constants: Stroke Linecap - Square */
+#define RL2_STROKE_LINECAP_SQUARE	0x63
+
+/** RasterLite2 constants: unknown Mark */
+#define RL2_GRAPHIC_MARK_UNKNOWN	0x70
+/** RasterLite2 constants: the well-known Square Mark */
+#define RL2_GRAPHIC_MARK_SQUARE		0x71
+/** RasterLite2 constants: the well-known Circle Mark */
+#define RL2_GRAPHIC_MARK_CIRCLE		0x72
+/** RasterLite2 constants: the well-known Triangle Mark */
+#define RL2_GRAPHIC_MARK_TRIANGLE	0x73
+/** RasterLite2 constants: the well-known Star Mark */
+#define RL2_GRAPHIC_MARK_STAR		0x74
+/** RasterLite2 constants: the well-known Cross Mark */
+#define RL2_GRAPHIC_MARK_CROSS		0x75
+/** RasterLite2 constants: the well-known X Mark */
+#define RL2_GRAPHIC_MARK_X		0x76
+
+/** Rasterlite2 constants: Font Style Normal */
+#define RL2_FONT_STYLE_NORMAL	0x30
+/** Rasterlite2 constants: Font Style Italic */
+#define RL2_FONT_STYLE_ITALIC	0x31
+/** Rasterlite2 constants: Font Style Oblique */
+#define RL2_FONT_STYLE_OBLIQUE	0x32
+/** Rasterlite2 constants: Font Weight Normal */
+#define RL2_FONT_WEIGHT_NORMAL	0x40
+/** Rasterlite2 constants: Font Weight Bold */
+#define RL2_FONT_WEIGHT_BOLD	0x41
+
+/** Rasterlite2 constants: LabelPlacement: Unknwn */
+#define RL2_LABEL_PLACEMENT_UNKNOWN	0x53
+/** Rasterlite2 constants: LabelPlacement: PointPlacement */
+#define RL2_LABEL_PLACEMENT_POINT	0x54
+/** Rasterlite2 constants: LabelPlacement: LinePlacement */
+#define RL2_LABEL_PLACEMENT_LINE	0x55
+
 /**
  Typedef for RL2 Pixel object (opaque, hidden)
 
@@ -285,17 +351,186 @@ extern "C"
     typedef rl2Coverage *rl2CoveragePtr;
 
 /**
- Typedef for RL2 RasterStyle object (opaque, hidden)
+ Typedef for RL2 Vector Layer object (opaque, hidden)
+
+ \sa rl2VectorLayerPtr
+ */
+    typedef struct rl2_vector_layer rl2VectorLayer;
+/**
+ Typedef for RL2 Vector Layer object pointer (opaque, hidden)
+
+ \sa rl2VectorLayer
+ */
+    typedef rl2VectorLayer *rl2VectorLayerPtr;
+
+/**
+ Typedef for RL2 CoverageStyle object (opaque, hidden)
+
+ \sa rl2CoverageStylePtr
+ */
+    typedef struct rl2_coverage_style rl2CoverageStyle;
+/**
+ Typedef for RL2 CoverageStyle object pointer (opaque, hidden)
+
+ \sa rl2CoverageStyle
+ */
+    typedef rl2CoverageStyle *rl2CoverageStylePtr;
+
+/**
+ Typedef for RL2 RasterSymbolizer object (opaque, hidden)
+
+ \sa rl2RasterSymbolizerPtr
+ */
+    typedef struct rl2_raster_symbolizer rl2RasterSymbolizer;
+/**
+ Typedef for RL2 RasterSymbolizer object pointer (opaque, hidden)
+
+ \sa rl2RasterSymbolizer
+ */
+    typedef rl2RasterSymbolizer *rl2RasterSymbolizerPtr;
+
+/**
+ Typedef for RL2 Rule Like Arguments object (opaque, hidden)
+
+ \sa rl2SRuleLikeArgsPtr
+ */
+    typedef struct rl2_rule_like_args rl2RuleLikeArgs;
+/**
+ Typedef for RL2 RuleLikeArgs object pointer (opaque, hidden)
+
+ \sa rl2RuleLikeArgs
+ */
+    typedef rl2RuleLikeArgs *rl2RuleLikeArgsPtr;
+
+/**
+ Typedef for RL2 Rule Between Arguments object (opaque, hidden)
+
+ \sa rl2SRuleBetweenArgsPtr
+ */
+    typedef struct rl2_rule_between_args rl2RuleBetweenArgs;
+/**
+ Typedef for RL2 RuleBetweenArgs object pointer (opaque, hidden)
+
+ \sa rl2RuleBetweenArgs
+ */
+    typedef rl2RuleBetweenArgs *rl2RuleBetweenArgsPtr;
+
+/**
+ Typedef for RL2 Rule Single Argument object (opaque, hidden)
+
+ \sa rl2SRuleSingleArgPtr
+ */
+    typedef struct rl2_rule_single_arg rl2RuleSingleArg;
+/**
+ Typedef for RL2 RuleSingleArg object pointer (opaque, hidden)
+
+ \sa rl2RuleSingleArg
+ */
+    typedef rl2RuleSingleArg *rl2RuleSingleArgPtr;
+
+/**
+ Typedef for RL2 VariantArray object (opaque, hidden)
+
+ \sa rl2VariantArrayPtr
+ */
+    typedef struct rl2_variant_array rl2VariantArray;
+/**
+ Typedef for RL2 VariantArray object pointer (opaque, hidden)
+
+ \sa rl2VariantArray
+ */
+    typedef rl2VariantArray *rl2VariantArrayPtr;
+
+/**
+ Typedef for RL2 StyleRule object (opaque, hidden)
+
+ \sa rl2StyleRulePtr
+ */
+    typedef struct rl2_style_rule rl2StyleRule;
+/**
+ Typedef for RL2 StyleRule object pointer (opaque, hidden)
+
+ \sa rl2StyleRule
+ */
+    typedef rl2StyleRule *rl2StyleRulePtr;
+
+/**
+ Typedef for RL2 FeatureTypeStyle object (opaque, hidden)
+
+ \sa rl2FeatureTypeStylePtr
+ */
+    typedef struct rl2_feature_type_style rl2FeatureTypeStyle;
+/**
+ Typedef for RL2 FeatureTypeStyle object pointer (opaque, hidden)
+
+ \sa rl2FeatureTypeStyle
+ */
+    typedef rl2FeatureTypeStyle *rl2FeatureTypeStylePtr;
+
+/**
+ Typedef for RL2 VectorSymbolizer object (opaque, hidden)
+
+ \sa rl2VectorSymbolizerPtr
+ */
+    typedef struct rl2_vector_symbolizer rl2VectorSymbolizer;
+/**
+ Typedef for RL2 VectorSymbolizer object pointer (opaque, hidden)
+
+ \sa rl2VectorSymbolizer
+ */
+    typedef rl2VectorSymbolizer *rl2VectorSymbolizerPtr;
+
+/**
+ Typedef for RL2 PointSymbolizer object (opaque, hidden)
+
+ \sa rl2PointSymbolizerPtr
+ */
+    typedef struct rl2_point_symbolizer rl2PointSymbolizer;
+/**
+ Typedef for RL2 PointSymbolizer object pointer (opaque, hidden)
+
+ \sa rl2PointSymbolizer
+ */
+    typedef rl2PointSymbolizer *rl2PointSymbolizerPtr;
+
+/**
+ Typedef for RL2 LineSymbolizer object (opaque, hidden)
+
+ \sa rl2LineSymbolizerPtr
+ */
+    typedef struct rl2_line_symbolizer rl2LineSymbolizer;
+/**
+ Typedef for RL2 LineSymbolizer object pointer (opaque, hidden)
+
+ \sa rl2LineSymbolizer
+ */
+    typedef rl2LineSymbolizer *rl2LineSymbolizerPtr;
+
+/**
+ Typedef for RL2 PolygonSymbolizer object (opaque, hidden)
 
- \sa rl2RasterStylePtr
+ \sa rl2PolygonSymbolizerPtr
  */
-    typedef struct rl2_raster_style rl2RasterStyle;
+    typedef struct rl2_polygon_symbolizer rl2PolygonSymbolizer;
 /**
- Typedef for RL2 RasterStyle object pointer (opaque, hidden)
+ Typedef for RL2 PolygonSymbolizer object pointer (opaque, hidden)
 
- \sa rl2RasterStyle
+ \sa rl2PolygonSymbolizer
  */
-    typedef rl2RasterStyle *rl2RasterStylePtr;
+    typedef rl2PolygonSymbolizer *rl2PolygonSymbolizerPtr;
+
+/**
+ Typedef for RL2 TextSymbolizer object (opaque, hidden)
+
+ \sa rl2TextSymbolizerPtr
+ */
+    typedef struct rl2_text_symbolizer rl2TextSymbolizer;
+/**
+ Typedef for RL2 TextSymbolizer object pointer (opaque, hidden)
+
+ \sa rl2TextSymbolizer
+ */
+    typedef rl2TextSymbolizer *rl2TextSymbolizerPtr;
 
 /**
  Typedef for RL2 GroupStyle object (opaque, hidden)
@@ -432,15 +667,48 @@ extern "C"
 #endif
 
 /**
+ Initializes the internal private memory block supporting each RL2 connection
+
+ \sa rl2_init, rl2_private_cleanup
+
+ */
+    RL2_DECLARE void *rl2_alloc_private (void);
+
+/**
  Initializes the library
  
  \param db_handle handle to the current SQLite connection
+ \param ptr a memory pointer returned by rl2_alloc_private()
  \param verbose if TRUE a short start-up message is shown on stderr
 
  \note you are always expected to explicitly call this function
  before attempting to call any RasterLite-2 own function.
  */
-    RL2_DECLARE void rl2_init (sqlite3 * db_handle, int verbose);
+    RL2_DECLARE void rl2_init (sqlite3 * db_handle, const void *ptr,
+			       int verbose);
+
+/**
+ Cleanup the internal private memory block supporting each RL2 connection
+
+ This function performs general cleanup, essentially undoing the effect
+ of rl2_init().
+
+ \param ptr the same memory pointer passed to the corresponding call to
+ rl2_init() and rl2_alloc_private()
+
+ \sa rl2_init_ex, rl2_alloc_private
+*/
+    RL2_DECLARE void rl2_cleanup_private (const void *ptr);
+
+/**
+ Testing if a given codec/compressor is actually supported by the library
+
+ \param compression e.g. RL2_COMPRESSION_NONE or RL2_COMPRESSION_DEFLATE
+ 
+ \return  RL2_TRUE or RL2_FALSE on success: RL2_ERROR on invalid/unknown
+ compriosson.
+ */
+    RL2_DECLARE int rl2_is_supported_codec (unsigned char compression);
 
 /**
  Allocates and initializes a new Pixel object
@@ -452,7 +720,7 @@ extern "C"
 		RL2_PIXEL_RGB, RL2_PIXEL_MULTIBAND, RL2_PIXEL_DATAGRID.
  \param num_samples number of samples per pixel (aka Bands)
  
- \return the pointer to newly created Coverage Object: NULL on failure.
+ \return the pointer to newly created Pixel Object: NULL on failure.
  
  \sa rl2_destroy_pixel, rl2_compare_pixels, rl2_get_pixel_type, 
 		rl2_get_pixel_sample_1bit,
@@ -1044,10 +1312,7 @@ extern "C"
  \param pixel_type one of RL2_PIXEL_MONOCHROME, RL2_PIXEL_PALETTE, RL2_PIXEL_GRAYSCALE,
 		RL2_PIXEL_RGB, RL2_PIXEL_MULTIBAND, RL2_PIXEL_DATAGRID.
  \param num_samples number of samples per pixel (aka Bands)
- \param compression one of RL2_COMPRESSION_NONE, RL2_COMPRESSION_DEFLATE,
-		RL2_COMPRESSION_LZMA, RL2_COMPRESSION_GIF, RL2_COMPRESSION_PNG,
-		RL2_COMPRESSION_JPEG, RL2_COMPRESSION_LOSSY_WEBP or
- 		RL2_COMPRESSION_LOSSLESS_WEBP
+ \param compression e.g. RL2_COMPRESSION_NONE or RL2_COMPRESSION_DEFLATE
  \param quality compression quality factor (0-100); only meaningfull for
 		JPEG or WEBP lossy compressions, ignored in any other case.
  \param tile_width the individual tile width in pixels.
@@ -1103,6 +1368,49 @@ extern "C"
 				   double horz_res, double vert_res);
 
 /**
+ Gets the Policies from a Coverage Object
+
+ \param cvg pointer to the Coverage Object.
+ \param strict_resolution on completion the BOOLEAN variable referenced
+  by this pointer will contain the StrictResolution flag.
+ \param mixed_resolutions on completion the BOOLEAN variable referenced
+  by this pointer will contain the MixedResolutions flag.
+ \param section_paths on completion the BOOLEAN variable referenced
+  by this pointer will contain the SectionPaths flag.
+ \param section_md5 on completion the BOOLEAN variable referenced
+  by this pointer will contain the SectionMD5 flag.
+ \param section_summary on completion the BOOLEAN variable referenced
+  by this pointer will contain the SectionSummary flag.
+ 
+ \return RL2_OK on success: RL2_ERROR on failure.
+
+ \sa rl2_create_coverage, rl2_set_coverage_policies
+ */
+    RL2_DECLARE int
+	rl2_get_coverage_policies (rl2CoveragePtr cvg, int *stric_resolution,
+				   int *mixed_resolutions, int *section_paths,
+				   int *section_md5, int *section_summary);
+
+/**
+ Sets the Policies for a Coverage Object
+
+ \param cvg pointer to the Coverage Object.
+ \param strict_resolution the StrictResolution BOOLEAN flag.
+ \param mixed_resolutions the MixedResolutions BOOLEAN flag.
+ \param section_paths the SectionPaths BOOLEAN flag.
+ \param section_md5 the SectionMD5 BOOLEAN flag.
+ \param section_summary the SectionSummary BOOLEAN flag.
+ 
+ \return RL2_OK on success: RL2_ERROR on failure.
+
+ \sa rl2_create_coverage, rl2_get_coverage_policies
+ */
+    RL2_DECLARE int
+	rl2_set_coverage_policies (rl2CoveragePtr cvg, int stric_resolution,
+				   int mixed_resolutions, int section_paths,
+				   int section_md5, int section_summary);
+
+/**
  Retrieving the Name from a Coverage Object
 
  \param cvg pointer to the Coverage Object.
@@ -1266,13 +1574,113 @@ extern "C"
 						 double *vResolution);
 
 /**
+ Allocates and initializes a new Vector Layer object
+
+ \param f_table_name a text string containing the Table name.
+ \param f_geometry_column a text string containing the Geometry Column name
+ \param geometry_type the numeric ID of some Geometry class; one between 
+  GAIA_POINT, GAIA_LINESTRING, GAIA_POLYGON and alike.
+ \param srid the SRID value
+ \param spatial_index one of GAIA_SPATIAL_INDEX_NONE, GAIA_SPATIAL_INDEX_RTREE
+ or GAIA_SPATIAL_INDEX_MBRCACHE
+ 
+ \return the pointer to newly created Vector Layer Object: NULL on failure.
+ 
+ \sa rl2_destroy_vector_layer, rl2_get_vector_table_name, 
+		rl2_get_vector_geometry_name, rl2_get_vector_geometry_type, 
+		rl2_get_vector_srid, rl2_get_vector_spatial_index
+ 
+ \note you are responsible to destroy (before or after) any allocated 
+ Vector Layer object.
+ */
+    RL2_DECLARE rl2VectorLayerPtr
+	rl2_create_vector_layer (const char *f_table_name,
+				 const char *f_geometry_column,
+				 unsigned short geometry_type, int srid,
+				 unsigned char spatial_index);
+
+/**
+ Destroys a Vector Layer Object
+
+ \param vector pointer to object to be destroyed
+
+ \sa rl2_create_vector_layer
+ */
+    RL2_DECLARE void rl2_destroy_vector_layer (rl2VectorLayerPtr vector);
+
+/**
+ Retrieving the Table name from a Vector Layer Object
+
+ \param vector pointer to the Vector Layer Object.
+ 
+ \return pointer to the Table name text string; NULL if any error is 
+ encountered.
+
+ \sa rl2_create_vector_layer, rl2_get_vector_geometry_name
+ */
+    RL2_DECLARE const char *rl2_get_vector_table_name (rl2VectorLayerPtr
+						       vector);
+
+/**
+ Retrieving the Geometry Column name from a Vector Layer Object
+
+ \param vector pointer to the Vector Layer Object.
+ 
+ \return pointer to the Geometry Column name text string; NULL if any 
+ error is encountered.
+
+ \sa rl2_create_vector_layer, rl2_get_vector_table_name
+ */
+    RL2_DECLARE const char *rl2_get_vector_geometry_name (rl2VectorLayerPtr
+							  vector);
+
+/**
+ Retrieving the Geometry Type from a Vector Layer Object
+
+ \param vector pointer to the Vector Layer Object.
+ \param geometry_type on completion the variable referenced by this
+ pointer will contain the Geometry Type.
+ 
+ \return  RL2_OK on success: RL2_ERROR on failure.
+
+ \sa rl2_create_vector_layer
+ */
+    RL2_DECLARE int rl2_get_vector_geometry_type (rl2VectorLayerPtr vector,
+						  unsigned short
+						  *geometry_type);
+
+/**
+ Retrieving the SRID from a Vector Layer Object
+
+ \param vector pointer to the Vector Layer Object.
+ \param srid on completion the variable referenced by this
+ pointer will contain the SRID.
+ 
+ \return  RL2_OK on success: RL2_ERROR on failure.
+
+ \sa rl2_create_vector_layer
+ */
+    RL2_DECLARE int rl2_get_vector_srid (rl2VectorLayerPtr vector, int *srid);
+
+/**
+ Retrieving the Spatial Index type from a Vector Layer Object
+
+ \param vector pointer to the Vector Layer Object.
+ \param idx on completion the variable referenced by this
+ pointer will contain the Spatial Index type.
+ 
+ \return  RL2_OK on success: RL2_ERROR on failure.
+
+ \sa rl2_create_vector_layer
+ */
+    RL2_DECLARE int rl2_get_vector_spatial_index (rl2VectorLayerPtr vector,
+						  unsigned char *idx);
+
+/**
  Allocates and initializes a new Section object
 
  \param name a text string intended to be the symbolic Section name.
- \param compression one of RL2_COMPRESSION_NONE, RL2_COMPRESSION_DEFLATE,
-		RL2_COMPRESSION_LZMA, RL2_COMPRESSION_GIF, RL2_COMPRESSION_PNG,
-		RL2_COMPRESSION_JPEG, RL2_COMPRESSION_LOSSY_WEBP or
- 		RL2_COMPRESSION_LOSSLESS_WEBP
+ \param compression e.g. RL2_COMPRESSION_NONE or RL2_COMPRESSION_DEFLATE
  \param tile_width the individual tile width in pixels.
  \param tile_height the individual tile height in pixels.
  \param rst pointer to a Raster Object.
@@ -1354,6 +1762,32 @@ extern "C"
     RL2_DECLARE rl2SectionPtr rl2_section_from_webp (const char *path);
 
 /**
+ Allocates and initializes a new Section object from an external 
+ Jpeg2000 image
+
+ \param path pathname leading to the external Jpeg2000 image.
+ \param sample_type one of RL2_SAMPLE_UINT8 or RL2_SAMPLE_INT16.
+ \param pixel_type one of RL2_PIXEL_GRAYSCALE, RL2_PIXEL_RGB, 
+ RL2_PIXEL_MULTIBAND, RL2_PIXEL_DATAGRID.
+ \param num_samples number of samples per pixel (aka Bands).
+ 
+ \return the pointer to newly created Section Object: NULL on failure.
+ 
+ \sa rl2_destroy_section, rl2_create_section, rl2_section_to_lossy_jpeg2000,
+	rl2_section_to_lossless_jpeg2000
+ 
+ \note you are responsible to destroy (before or after) any allocated 
+ Section object.
+ */
+    RL2_DECLARE rl2SectionPtr rl2_section_from_jpeg2000 (const char *path,
+							 unsigned char
+							 sample_type,
+							 unsigned char
+							 pixel_type,
+							 unsigned char
+							 num_samples);
+
+/**
  Exports a Section object as an external GIF image
 
  \param scn pointer to the Section Object.
@@ -1395,7 +1829,7 @@ extern "C"
  Exports a Section object as an external WEBP (lossy) image
 
  \param scn pointer to the Section Object.
- \param path pathname leading to the external JPEG image.
+ \param path pathname leading to the external WEBP image.
  \param quality compression quality factor (0-100).
  
  \return RL2_OK on success: RL2_ERROR on failure.
@@ -1419,6 +1853,34 @@ extern "C"
 						  const char *path);
 
 /**
+ Exports a Section object as an external Jpeg2000 (lossy) image
+
+ \param scn pointer to the Section Object.
+ \param path pathname leading to the external Jpeg2000 image.
+ \param quality compression quality factor (0-100).
+ 
+ \return RL2_OK on success: RL2_ERROR on failure.
+ 
+ \sa rl2_create_section, rl2_section_from_jpeg
+ */
+    RL2_DECLARE int rl2_section_to_lossy_jpeg2000 (rl2SectionPtr scn,
+						   const char *path,
+						   int quality);
+
+/**
+ Exports a Section object as an external Jpeg2000 (lossless) image
+
+ \param scn pointer to the Section Object.
+ \param path pathname leading to the external Jpeg2000 image.
+ 
+ \return RL2_OK on success: RL2_ERROR on failure.
+ 
+ \sa rl2_create_section, rl2_section_from_webp
+ */
+    RL2_DECLARE int rl2_section_to_lossless_jpeg2000 (rl2SectionPtr scn,
+						      const char *path);
+
+/**
  Destroys a Section Object
 
  \param scn pointer to object to be destroyed
@@ -1576,6 +2038,57 @@ extern "C"
 			   rl2PixelPtr no_data);
 
 /**
+ Allocates and initializes a new Raster object
+
+ \param width Raster Width (in pixels).
+ \param height Raster Height (in pixels).
+ \param sample_type one of RL2_SAMPLE_1_BIT, RL2_SAMPLE_2_BIT, RL2_SAMPLE_4_BIT,
+        RL2_SAMPLE_INT8, RL2_SAMPLE_UINT8, RL2_SAMPLE_INT16, RL2_SAMPLE_UINT16,
+		RL2_SAMPLE_INT32, RL2_SAMPLE_UINT32, RL2_SAMPLE_FLOAT or RL2_SAMPLE_DOUBLE.
+ \param pixel_type one of RL2_PIXEL_MONOCHROME, RL2_PIXEL_PALETTE, RL2_PIXEL_GRAYSCALE,
+		RL2_PIXEL_RGB, RL2_PIXEL_MULTIBAND, RL2_PIXEL_DATAGRID.
+ \param num_samples number of samples per pixel (aka Bands)
+ \param bufpix pointer to the Buffer containing all Pixels
+ \param bufpix_size size (in bytes) of the above Buffer
+ \param palette pointer to a Palette object (NULL is the Pixel Type doesn't require a Palette)
+ \param alpha pointer to an optional Alpha Mask (may be NULL if no Mask is required)
+ \param alpha_size size (in bytes) of the above Mask (ZERO if no Mask is required)
+ \param no_data pointer to a Pixel Object indented as NO-DATA value;
+		could be eventually NULL if not required.
+ 
+ \return the pointer to newly created Raster Object: NULL on failure.
+ 
+ \sa rl2_destroy_raster, rl2_get_raster_size,
+		rl2_get_raster_raster_type, rl2_get_raster_pixel_type,
+		rl2_get_raster_bands, rl2_get_raster_no_data, rl2_get_raster_srid,
+		rl2_get_raster_horizontal_resolution, rl2_get_raster_vertical_resolution,
+		rl2_get_raster_minX, rl2_get_raster_minY, rl2_get_raster_maxX,
+		rl2_get_raster_maxY, rl2_create_raster_pixel,
+		rl2_raster_georeference_center, rl2_raster_georeference_upper_left,
+		rl2_raster_georeference_lower_left, rl2_raster_georeference_upper_right,
+		rl2_raster_georeference_lower_right, rl2_raster_georeference_frame,
+		rl2_raster_data_to_1bit, rl2_raster_data_to_2bit, rl2_raster_data_to_4bit,
+		rl2_raster_data_to_int8, rl2_raster_data_to_uint8, rl2_raster_data_to_int16, 
+		rl2_raster_data_to_uint16, rl2_raster_data_to_int32, rl2_raster_data_to_uint32,
+		rl2_raster_data_to_float, rl2_raster_data_to_double, rl2_raster_band_to_uint8, 
+		rl2_raster_band_to_uint16, rl2_raster_bands_to_RGB, rl2_raster_to_gif,
+		rl2_raster_to_png, rl2_raster_to_jpeg, rl2_raster_to_lossless_webp,
+		rl2_raster_to_lossy_webp, rl2_raster_from_gif, rl2_raster_from_png, 
+		rl2_raster_from_jpeg, rl2_raster_from_webp, rl2_raster_from_tiff
+ 
+ \note you are responsible to destroy (before or after) any allocated 
+ Raster object.
+ */
+    RL2_DECLARE rl2RasterPtr
+	rl2_create_raster_alpha (unsigned int width, unsigned int height,
+				 unsigned char sample_type,
+				 unsigned char pixel_type,
+				 unsigned char num_samples,
+				 unsigned char *bufpix, int bufpix_size,
+				 rl2PalettePtr palette, unsigned char *alpha,
+				 int alpha_size, rl2PixelPtr no_data);
+
+/**
  Destroys a Raster Object
 
  \param rst pointer to object to be destroyed
@@ -1698,19 +2211,7 @@ extern "C"
 					   double *maxX, double *maxY);
 
 /**
- Retrieving the bounding box from a Raster Object
-
- \param rst pointer to the Raster Object.
- 
- \return a Geometry Object (rectangle) corresponding to the Raster's BBox; 
-	NULL if any error is encountered or if the Raster doesn't support any GeoReferencing.
-
- \sa rl2_create_raster
- */
-    RL2_DECLARE gaiaGeomCollPtr rl2_get_raster_bbox (rl2RasterPtr rst);
-
-/**
- Creates a new Pixel Object suitable for a given Raster Object
+ Creates a new Pixel Object suitable for a given Raster Object
 
  \param rst pointer to the Raster Object.
  
@@ -1898,10 +2399,7 @@ extern "C"
  Encodes a Raster Object into the corresponding BLOB serialized format
 
  \param rst pointer to the Raster Object.
- \param compression one of RL2_COMPRESSION_NONE, RL2_COMPRESSION_DEFLATE,
-		RL2_COMPRESSION_LZMA, RL2_COMPRESSION_GIF, RL2_COMPRESSION_PNG,
-		RL2_COMPRESSION_JPEG, RL2_COMPRESSION_LOSSY_WEBP or
- 		RL2_COMPRESSION_LOSSLESS_WEBP
+ \param compression e.g. RL2_COMPRESSION_NONE or RL2_COMPRESSION_DEFLATE
  \param blob_odd on completion will point to the created encoded BLOB ("odd" half).
  \param blob_odd_sz on completion the variable referenced by this
  pointer will contain the size (in bytes) of the "odd" BLOB.
@@ -2770,6 +3268,8 @@ extern "C"
 
  \param png pointer to the memory block storing the input PNG image.
  \param png_size size (in bytes) of the PNG image.
+ \param alpha_mask set to TRUE if an eventual ALPHA mask should be
+ carefully preserved; otherwise a transparency mask will be assumed.
  
  \return the pointer to newly created Raster Object: NULL on failure.
  
@@ -2779,7 +3279,7 @@ extern "C"
  Raster object.
  */
     RL2_DECLARE rl2RasterPtr rl2_raster_from_png (const unsigned char *png,
-						  int png_size);
+						  int png_size, int alpha_mask);
 
 /**
  Exports a Raster object as an in-memory stored JPEG image
@@ -2818,8 +3318,8 @@ extern "C"
  Exports a Raster object as an in-memory stored WEBP image (lossy compressed)
 
  \param rst pointer to the Raster Object.
- \param buffer on completion will point to the memory block storing the created WEBP image.
- \param buf_size on completion the variable referenced by this
+ \param webp on completion will point to the memory block storing the created WEBP image.
+ \param webp_size on completion the variable referenced by this
  pointer will contain the size (in bytes) of the WEBP image.
  \param quality compression quality factor (0-100)
  
@@ -2835,8 +3335,8 @@ extern "C"
  Exports a Raster object as an in-memory stored WEBP image (lossless compressed)
 
  \param rst pointer to the Raster Object.
- \param buffer on completion will point to the memory block storing the created WEBP image.
- \param buf_size on completion the variable referenced by this
+ \param webp on completion will point to the memory block storing the created WEBP image.
+ \param webp_size on completion the variable referenced by this
  pointer will contain the size (in bytes) of the WEBP image.
  
  \return RL2_OK on success: RL2_ERROR on failure.
@@ -2865,6 +3365,68 @@ extern "C"
 	rl2_raster_from_webp (const unsigned char *webp, int webp_size);
 
 /**
+ Exports a Raster object as an in-memory stored Jpeg2000 image (lossy compressed)
+
+ \param rst pointer to the Raster Object.
+ \param jpeg2000 on completion will point to the memory block storing the created
+ Jpeg2000 image.
+ \param jpeg2000_size on completion the variable referenced by this
+ pointer will contain the size (in bytes) of the Jpeg2000 image.
+ \param quality compression quality factor (0-100)
+ 
+ \return RL2_OK on success: RL2_ERROR on failure.
+ 
+ \sa rl2_create_raster, rl2_raster_from_jpeg2000, rl2_raster_to_lossless_jpeg2000
+ */
+    RL2_DECLARE int
+	rl2_raster_to_lossy_jpeg2000 (rl2RasterPtr rst,
+				      unsigned char **jpeg2000,
+				      int *jpeg2000_size, int quality);
+
+/**
+ Exports a Raster object as an in-memory stored Jpeg2000 image (lossless compressed)
+
+ \param rst pointer to the Raster Object.
+ \param jpeg2000 on completion will point to the memory block storing the created
+ Jpeg2000 image.
+ \param jpeg2000_size on completion the variable referenced by this
+ pointer will contain the size (in bytes) of the WEBP image.
+ 
+ \return RL2_OK on success: RL2_ERROR on failure.
+ 
+ \sa rl2_create_raster, rl2_raster_from_jpeg2000, rl2_raster_to_lossy_jpeg2000
+ */
+    RL2_DECLARE int
+	rl2_raster_to_lossless_jpeg2000 (rl2RasterPtr rst,
+					 unsigned char **jpeg2000,
+					 int *jpeg20000_size);
+
+/**
+ Allocates and initializes a new Raster object from an in-memory stored
+ Jpeg2000 image
+
+ \param jpeg2000 pointer to the memory block storing the input Jpeg2000 image.
+ \param jpeg2000_size size (in bytes) of the Jpeg2000 image.
+ \param sample_type one of RL2_SAMPLE_UINT8 or RL2_SAMPLE_INT16.
+ \param pixel_type one of RL2_PIXEL_GRAYSCALE, RL2_PIXEL_RGB, 
+ RL2_PIXEL_MULTIBAND, RL2_PIXEL_DATAGRID.
+ \param num_samples number of samples per pixel (aka Bands).
+ 
+ \return the pointer to newly created Raster Object: NULL on failure.
+ 
+ \sa rl2_destroy_raster, rl2_create_raster, rl2_raster_to_lossy_jpeg2000,
+	rl2_raster_to_lossless_jpeg2000
+ 
+ \note you are responsible to destroy (before or after) any allocated 
+ Raster object.
+ */
+    RL2_DECLARE rl2RasterPtr
+	rl2_raster_from_jpeg2000 (const unsigned char *jpeg2000,
+				  int jpeg2000_size, unsigned char sample_type,
+				  unsigned char pixel_type,
+				  unsigned char num_samples);
+
+/**
  Allocates and initializes a new Raster object from an in-memory stored TIFF image
 
  \param webp pointer to the memory block storing the input TIFF image.
@@ -2889,22 +3451,46 @@ extern "C"
     RL2_DECLARE rl2CoveragePtr
 	rl2_create_coverage_from_dbms (sqlite3 * handle, const char *coverage);
 
+    RL2_DECLARE rl2VectorLayerPtr
+	rl2_create_vector_layer_from_dbms (sqlite3 * handle,
+					   const char *coverage);
+
     RL2_DECLARE int
 	rl2_find_matching_resolution (sqlite3 * handle, rl2CoveragePtr cvg,
+				      int by_section, sqlite3_int64 section_id,
 				      double *x_res, double *y_res,
 				      unsigned char *level,
 				      unsigned char *scale);
 
+    RL2_DECLARE int rl2_load_raw_raster_into_dbms (sqlite3 * sqlite,
+						   int max_threads,
+						   rl2CoveragePtr cvg,
+						   const char *sctn_name,
+						   rl2RasterPtr rst,
+						   int pyramidize);
+
     RL2_DECLARE int
-	rl2_get_raw_raster_data (sqlite3 * handle, rl2CoveragePtr cvg,
-				 unsigned int width, unsigned int height,
-				 double minx, double miny, double maxx,
-				 double maxy, double x_res, double y_res,
-				 unsigned char **buffer, int *buf_size,
-				 rl2PalettePtr * palette,
+	rl2_get_raw_raster_data (sqlite3 * handle, int max_threads,
+				 rl2CoveragePtr cvg, unsigned int width,
+				 unsigned int height, double minx, double miny,
+				 double maxx, double maxy, double x_res,
+				 double y_res, unsigned char **buffer,
+				 int *buf_size, rl2PalettePtr * palette,
 				 unsigned char out_pixel);
 
     RL2_DECLARE int
+	rl2_get_section_raw_raster_data (sqlite3 * handle, int max_threads,
+					 rl2CoveragePtr cvg,
+					 sqlite3_int64 section_id,
+					 unsigned int width,
+					 unsigned int height, double minx,
+					 double miny, double maxx, double maxy,
+					 double x_res, double y_res,
+					 unsigned char **buffer, int *buf_size,
+					 rl2PalettePtr * palette,
+					 unsigned char out_pixel);
+
+    RL2_DECLARE int
 	rl2_get_triple_band_raw_raster_data (sqlite3 * handle,
 					     rl2CoveragePtr cvg,
 					     unsigned int width,
@@ -2920,6 +3506,22 @@ extern "C"
 					     rl2PixelPtr no_data);
 
     RL2_DECLARE int
+	rl2_get_section_triple_band_raw_raster_data (sqlite3 * handle,
+						     rl2CoveragePtr cvg,
+						     sqlite3_int64 section_id,
+						     unsigned int width,
+						     unsigned int height,
+						     double minx, double miny,
+						     double maxx, double maxy,
+						     double x_res, double y_res,
+						     unsigned char red_band,
+						     unsigned char green_band,
+						     unsigned char blue_band,
+						     unsigned char **buffer,
+						     int *buf_size,
+						     rl2PixelPtr no_data);
+
+    RL2_DECLARE int
 	rl2_get_mono_band_raw_raster_data (sqlite3 * handle,
 					   rl2CoveragePtr cvg,
 					   unsigned int width,
@@ -2932,8 +3534,22 @@ extern "C"
 					   int *buf_size, rl2PixelPtr no_data);
 
     RL2_DECLARE int
-	rl2_get_raw_raster_data_bgcolor (sqlite3 * handle, rl2CoveragePtr cvg,
-					 unsigned int width,
+	rl2_get_section_mono_band_raw_raster_data (sqlite3 * handle,
+						   rl2CoveragePtr cvg,
+						   sqlite3_int64 section_id,
+						   unsigned int width,
+						   unsigned int height,
+						   double minx, double miny,
+						   double maxx, double maxy,
+						   double x_res, double y_res,
+						   unsigned char mono_band,
+						   unsigned char **buffer,
+						   int *buf_size,
+						   rl2PixelPtr no_data);
+
+    RL2_DECLARE int
+	rl2_get_raw_raster_data_bgcolor (sqlite3 * handle, int max_threads,
+					 rl2CoveragePtr cvg, unsigned int width,
 					 unsigned int height, double minx,
 					 double miny, double maxx, double maxy,
 					 double x_res, double y_res,
@@ -2943,10 +3559,30 @@ extern "C"
 					 unsigned char bg_red,
 					 unsigned char bg_green,
 					 unsigned char bg_blue,
-					 rl2RasterStylePtr style,
+					 rl2RasterSymbolizerPtr style,
 					 rl2RasterStatisticsPtr stats);
 
     RL2_DECLARE int
+	rl2_get_raw_raster_data_mixed_resolutions (sqlite3 * handle,
+						   int max_threads,
+						   rl2CoveragePtr cvg,
+						   unsigned int width,
+						   unsigned int height,
+						   double minx, double miny,
+						   double maxx, double maxy,
+						   double x_res, double y_res,
+						   unsigned char **buffer,
+						   int *buf_size,
+						   rl2PalettePtr * palette,
+						   unsigned char *out_pixel,
+						   unsigned char bg_red,
+						   unsigned char bg_green,
+						   unsigned char bg_blue,
+						   rl2RasterSymbolizerPtr style,
+						   rl2RasterStatisticsPtr
+						   stats);
+
+    RL2_DECLARE int
 	rl2_create_dbms_coverage (sqlite3 * handle, const char *coverage,
 				  unsigned char sample, unsigned char pixel,
 				  unsigned char num_bands,
@@ -2954,7 +3590,34 @@ extern "C"
 				  unsigned int tile_width,
 				  unsigned int tile_height, int srid,
 				  double x_res, double y_res,
-				  rl2PixelPtr no_data, rl2PalettePtr palette);
+				  rl2PixelPtr no_data, rl2PalettePtr palette,
+				  int strict_resolution, int mixed_resolutions,
+				  int section_paths, int section_md5,
+				  int section_summary);
+
+    RL2_DECLARE int
+	rl2_set_dbms_coverage_default_bands (sqlite3 * handle,
+					     const char *coverage,
+					     unsigned char red_band,
+					     unsigned char green_band,
+					     unsigned char blue_band,
+					     unsigned char nir_band);
+
+    RL2_DECLARE int
+	rl2_get_dbms_coverage_default_bands (sqlite3 * handle,
+					     const char *coverage,
+					     unsigned char *red_band,
+					     unsigned char *green_band,
+					     unsigned char *blue_band,
+					     unsigned char *nir_band);
+
+    RL2_DECLARE int
+	rl2_enable_dbms_coverage_auto_ndvi (sqlite3 * handle,
+					    const char *coverage, int on_off);
+
+    RL2_DECLARE int
+	rl2_is_dbms_coverage_auto_ndvi_enabled (sqlite3 * handle,
+						const char *coverage);
 
     RL2_DECLARE int
 	rl2_delete_dbms_section (sqlite3 * handle, const char *coverage,
@@ -2963,7 +3626,25 @@ extern "C"
     RL2_DECLARE int
 	rl2_get_dbms_section_id (sqlite3 * handle, const char *coverage,
 				 const char *section,
-				 sqlite3_int64 * section_id);
+				 sqlite3_int64 * section_id, int *duplicate);
+
+    RL2_DECLARE int
+	rl2_resolve_full_section_from_dbms (sqlite3 * handle,
+					    const char *coverage,
+					    sqlite3_int64 section_id,
+					    double x_res, double y_res,
+					    double *minx, double *miny,
+					    double *maxx, double *maxy,
+					    unsigned int *width,
+					    unsigned int *height);
+
+    RL2_DECLARE int
+	rl2_resolve_base_resolution_from_dbms (sqlite3 * handle,
+					       const char *coverage,
+					       int by_section,
+					       sqlite3_int64
+					       section_id,
+					       double *x_res, double *y_res);
 
     RL2_DECLARE int
 	rl2_drop_dbms_coverage (sqlite3 * handle, const char *coverage);
@@ -3020,7 +3701,8 @@ extern "C"
 
     RL2_DECLARE int
 	rl2_eval_ascii_grid_origin_compatibility (rl2CoveragePtr cvg,
-						  rl2AsciiGridOriginPtr ascii);
+						  rl2AsciiGridOriginPtr ascii,
+						  int verbose);
 
     RL2_DECLARE const char
 	*rl2_get_ascii_grid_origin_path (rl2AsciiGridOriginPtr ascii);
@@ -3054,11 +3736,14 @@ extern "C"
 					 double *hResolution,
 					 double *vResolution);
 
+    RL2_DECLARE char *rl2_build_ascii_xml_summary (rl2AsciiGridOriginPtr ascii);
+
     RL2_DECLARE rl2RasterPtr
 	rl2_get_tile_from_ascii_grid_origin (rl2CoveragePtr cvg,
 					     rl2AsciiGridOriginPtr ascii,
 					     unsigned int startRow,
-					     unsigned int startCol);
+					     unsigned int startCol,
+					     int verbose);
 
     RL2_DECLARE rl2AsciiGridDestinationPtr
 	rl2_create_ascii_grid_destination (const char *path,
@@ -3106,31 +3791,76 @@ extern "C"
 	rl2_get_tile_from_jpeg_origin (rl2CoveragePtr cvg, rl2RasterPtr rst,
 				       unsigned int startRow,
 				       unsigned int startCol,
-				       unsigned char forced_conversion);
+				       unsigned char forced_conversion,
+				       int verbose);
+
+    RL2_DECLARE char *rl2_build_jpeg_xml_summary (unsigned int width,
+						  unsigned int height,
+						  unsigned char pixel_type,
+						  int is_georeferenced,
+						  double res_x, double res_y,
+						  double minx, double miny,
+						  double maxx, double maxy);
+
+    RL2_DECLARE rl2RasterPtr
+	rl2_get_tile_from_jpeg2000_origin (rl2CoveragePtr cvg, rl2RasterPtr rst,
+					   unsigned int startRow,
+					   unsigned int startCol,
+					   unsigned char forced_conversion,
+					   int verbose);
+
+    RL2_DECLARE char *rl2_build_jpeg2000_xml_summary (unsigned int width,
+						      unsigned int height,
+						      unsigned char sample_type,
+						      unsigned char pixel_type,
+						      unsigned char num_bands,
+						      int is_georeferenced,
+						      double res_x,
+						      double res_y, double minx,
+						      double miny, double maxx,
+						      double maxy,
+						      unsigned int tile_width,
+						      unsigned int tile_height);
 
     RL2_DECLARE int
-	rl2_load_raster_into_dbms (sqlite3 * handle, const char *src_path,
+	rl2_load_raster_into_dbms (sqlite3 * handle, int max_threads,
+				   const char *src_path,
 				   rl2CoveragePtr coverage, int worldfile,
-				   int force_srid, int pyramidize);
+				   int force_srid, int pyramidize, int verbose);
 
     RL2_DECLARE int
-	rl2_load_mrasters_into_dbms (sqlite3 * handle, const char *dir_path,
-				     const char *file_ext,
+	rl2_load_mrasters_into_dbms (sqlite3 * handle, int max_threads,
+				     const char *dir_path, const char *file_ext,
 				     rl2CoveragePtr coverage, int worldfile,
-				     int force_srid, int pyramidize);
+				     int force_srid, int pyramidize,
+				     int verbose);
 
     RL2_DECLARE int
-	rl2_export_geotiff_from_dbms (sqlite3 * handle, const char *dst_path,
+	rl2_export_geotiff_from_dbms (sqlite3 * handle, int max_threads,
+				      const char *dst_path,
 				      rl2CoveragePtr coverage, double x_res,
 				      double y_res, double minx, double miny,
 				      double maxx, double maxy,
-				      unsigned int width,
-				      unsigned int height,
+				      unsigned int width, unsigned int height,
 				      unsigned char compression,
 				      unsigned int tile_sz, int with_worldfile);
 
     RL2_DECLARE int
-	rl2_export_tiff_worldfile_from_dbms (sqlite3 * handle,
+	rl2_export_section_geotiff_from_dbms (sqlite3 * handle, int max_threads,
+					      const char *dst_path,
+					      rl2CoveragePtr coverage,
+					      sqlite3_int64 section_id,
+					      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);
+
+    RL2_DECLARE int
+	rl2_export_tiff_worldfile_from_dbms (sqlite3 * handle, int max_threads,
 					     const char *dst_path,
 					     rl2CoveragePtr coverage,
 					     double x_res, double y_res,
@@ -3142,16 +3872,43 @@ extern "C"
 					     unsigned int tile_sz);
 
     RL2_DECLARE int
-	rl2_export_tiff_from_dbms (sqlite3 * handle, const char *dst_path,
+	rl2_export_tiff_from_dbms (sqlite3 * handle, int max_threads,
+				   const char *dst_path,
 				   rl2CoveragePtr coverage, double x_res,
 				   double y_res, double minx, double miny,
-				   double maxx, double maxy,
-				   unsigned int width,
+				   double maxx, double maxy, unsigned int width,
 				   unsigned int height,
 				   unsigned char compression,
 				   unsigned int tile_sz);
 
     RL2_DECLARE int
+	rl2_export_section_tiff_worldfile_from_dbms (sqlite3 * handle,
+						     int max_threads,
+						     const char *dst_path,
+						     rl2CoveragePtr coverage,
+						     sqlite3_int64 section_id,
+						     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);
+
+    RL2_DECLARE int
+	rl2_export_section_tiff_from_dbms (sqlite3 * handle, int max_threads,
+					   const char *dst_path,
+					   rl2CoveragePtr coverage,
+					   sqlite3_int64 section_id,
+					   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);
+
+    RL2_DECLARE int
 	rl2_export_triple_band_geotiff_from_dbms (sqlite3 * handle,
 						  const char *dst_path,
 						  rl2CoveragePtr coverage,
@@ -3168,6 +3925,32 @@ extern "C"
 						  int with_worldfile);
 
     RL2_DECLARE int
+	rl2_export_section_triple_band_geotiff_from_dbms (sqlite3 * handle,
+							  const char *dst_path,
+							  rl2CoveragePtr
+							  coverage,
+							  sqlite3_int64
+							  section_id,
+							  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);
+
+    RL2_DECLARE int
 	rl2_export_mono_band_geotiff_from_dbms (sqlite3 * handle,
 						const char *dst_path,
 						rl2CoveragePtr coverage,
@@ -3182,21 +3965,38 @@ extern "C"
 						int with_worldfile);
 
     RL2_DECLARE int
+	rl2_export_section_mono_band_geotiff_from_dbms (sqlite3 * handle,
+							const char *dst_path,
+							rl2CoveragePtr coverage,
+							sqlite3_int64
+							section_id,
+							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);
+
+    RL2_DECLARE int
 	rl2_export_triple_band_tiff_worldfile_from_dbms (sqlite3 * handle,
 							 const char *dst_path,
 							 rl2CoveragePtr
-							 coverage,
-							 double x_res,
+							 coverage, 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 int height,
+							 unsigned char red_band,
 							 unsigned char
 							 green_band,
 							 unsigned char
@@ -3206,10 +4006,39 @@ extern "C"
 							 unsigned int tile_sz);
 
     RL2_DECLARE int
+	rl2_export_section_triple_band_tiff_worldfile_from_dbms (sqlite3 *
+								 handle,
+								 const char
+								 *dst_path,
+								 rl2CoveragePtr
+								 coverage,
+								 sqlite3_int64
+								 section_id,
+								 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);
+
+    RL2_DECLARE int
 	rl2_export_mono_band_tiff_worldfile_from_dbms (sqlite3 * handle,
 						       const char *dst_path,
-						       rl2CoveragePtr
-						       coverage,
+						       rl2CoveragePtr coverage,
 						       double x_res,
 						       double y_res,
 						       double minx,
@@ -3226,6 +4055,31 @@ extern "C"
 						       unsigned int tile_sz);
 
     RL2_DECLARE int
+	rl2_export_section_mono_band_tiff_worldfile_from_dbms (sqlite3 * handle,
+							       const char
+							       *dst_path,
+							       rl2CoveragePtr
+							       coverage,
+							       sqlite3_int64
+							       section_id,
+							       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);
+
+    RL2_DECLARE int
 	rl2_export_triple_band_tiff_from_dbms (sqlite3 * handle,
 					       const char *dst_path,
 					       rl2CoveragePtr coverage,
@@ -3241,6 +4095,24 @@ extern "C"
 					       unsigned int tile_sz);
 
     RL2_DECLARE int
+	rl2_export_section_triple_band_tiff_from_dbms (sqlite3 * handle,
+						       const char *dst_path,
+						       rl2CoveragePtr coverage,
+						       sqlite3_int64 section_id,
+						       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);
+
+    RL2_DECLARE int
 	rl2_export_mono_band_tiff_from_dbms (sqlite3 * handle,
 					     const char *dst_path,
 					     rl2CoveragePtr coverage,
@@ -3254,7 +4126,22 @@ extern "C"
 					     unsigned int tile_sz);
 
     RL2_DECLARE int
-	rl2_export_ascii_grid_from_dbms (sqlite3 * handle, const char *dst_path,
+	rl2_export_section_mono_band_tiff_from_dbms (sqlite3 * handle,
+						     const char *dst_path,
+						     rl2CoveragePtr coverage,
+						     sqlite3_int64 section_id,
+						     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);
+
+    RL2_DECLARE int
+	rl2_export_ascii_grid_from_dbms (sqlite3 * handle, int max_threads,
+					 const char *dst_path,
 					 rl2CoveragePtr coverage, double res,
 					 double minx, double miny, double maxx,
 					 double maxy, unsigned int width,
@@ -3262,28 +4149,108 @@ extern "C"
 					 int decimal_digits);
 
     RL2_DECLARE int
-	rl2_export_jpeg_from_dbms (sqlite3 * handle, const char *dst_path,
+	rl2_export_section_ascii_grid_from_dbms (sqlite3 * handle,
+						 int max_threads,
+						 const char *dst_path,
+						 rl2CoveragePtr coverage,
+						 sqlite3_int64 section_id,
+						 double res, double minx,
+						 double miny, double maxx,
+						 double maxy,
+						 unsigned int width,
+						 unsigned int height,
+						 int is_centered,
+						 int decimal_digits);
+
+    RL2_DECLARE int
+	rl2_export_ndvi_ascii_grid_from_dbms (sqlite3 * handle, int max_threads,
+					      const char *dst_path,
+					      rl2CoveragePtr coverage,
+					      double res, double minx,
+					      double miny, double maxx,
+					      double maxy, unsigned int width,
+					      unsigned int height, int red_band,
+					      int nir_band, int is_centered,
+					      int decimal_digits);
+
+    RL2_DECLARE int
+	rl2_export_section_ndvi_ascii_grid_from_dbms (sqlite3 * handle,
+						      int max_threads,
+						      const char *dst_path,
+						      rl2CoveragePtr coverage,
+						      sqlite3_int64 section_id,
+						      double res, double minx,
+						      double miny, double maxx,
+						      double maxy,
+						      unsigned int width,
+						      unsigned int height,
+						      int red_band,
+						      int nir_band,
+						      int is_centered,
+						      int decimal_digits);
+
+    RL2_DECLARE int
+	rl2_export_jpeg_from_dbms (sqlite3 * handle, int max_threads,
+				   const char *dst_path,
 				   rl2CoveragePtr coverage, 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);
+				   double maxx, double maxy, unsigned int width,
+				   unsigned int height, int quality,
+				   int with_worldfile);
+
+    RL2_DECLARE int
+	rl2_export_section_jpeg_from_dbms (sqlite3 * handle, int max_threads,
+					   const char *dst_path,
+					   rl2CoveragePtr coverage,
+					   sqlite3_int64 section_id,
+					   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);
 
     RL2_DECLARE int
-	rl2_build_section_pyramid (sqlite3 * handle, const char *coverage,
-				   const char *section, int forced_rebuild);
+	rl2_export_raw_pixels_from_dbms (sqlite3 * handle, int max_threads,
+					 rl2CoveragePtr coverage, double x_res,
+					 double y_res, double minx, double miny,
+					 double maxx, double maxy,
+					 unsigned int width,
+					 unsigned int height, int big_endian,
+					 unsigned char **blob, int *blob_size);
+
+    RL2_DECLARE int
+	rl2_export_section_raw_pixels_from_dbms (sqlite3 * handle,
+						 int max_threads,
+						 rl2CoveragePtr coverage,
+						 sqlite3_int64 section_id,
+						 double x_res, double y_res,
+						 double minx, double miny,
+						 double maxx, double maxy,
+						 unsigned int width,
+						 unsigned int height,
+						 int big_endian,
+						 unsigned char **blob,
+						 int *blob_size);
+
+    RL2_DECLARE int
+	rl2_build_section_pyramid (sqlite3 * handle, int max_threads,
+				   const char *coverage,
+				   sqlite3_int64 section_id, int forced_rebuild,
+				   int verbose);
 
     RL2_DECLARE int
 	rl2_build_monolithic_pyramid (sqlite3 * handle, const char *coverage,
-				      int virtual_levels);
+				      int virtual_levels, int verbose);
 
     RL2_DECLARE int
-	rl2_build_all_section_pyramids (sqlite3 * handle, const char *coverage,
-					int forced_rebuild);
+	rl2_build_all_section_pyramids (sqlite3 * handle, int max_threads,
+					const char *coverage,
+					int forced_rebuild, int verbose);
 
     RL2_DECLARE int
 	rl2_delete_section_pyramid (sqlite3 * handle, const char *coverage,
-				    const char *section);
+				    sqlite3_int64 section_id);
 
     RL2_DECLARE int
 	rl2_delete_all_pyramids (sqlite3 * handle, const char *coverage);
@@ -3314,10 +4281,11 @@ extern "C"
  \param width the PNG image width.
  \param height the PNG image height.
  \param rgb pointer to the RGB buffer.
- \param alpha pointer to the Alpha channel buffer.
+ \param mask pointer to the transparency mask.
  \param png on completion will point to the memory block storing the created PNG image.
  \param png_size on completion the variable referenced by this
  pointer will contain the size (in bytes) of the PNG image.
+ \param opacity standard opacity level (0.0 to 1.0)
  
  \return RL2_OK on success: RL2_ERROR on failure.
  
@@ -3326,10 +4294,31 @@ extern "C"
     RL2_DECLARE int
 	rl2_rgb_alpha_to_png (unsigned int width, unsigned int height,
 			      const unsigned char *rgb,
-			      const unsigned char *alpha, unsigned char **png,
+			      const unsigned char *mask, unsigned char **png,
 			      int *png_size, double opacity);
 
 /**
+ Exports two separate RGB + Alpha buffers as an in-memory stored PNG image
+
+ \param width the PNG image width.
+ \param height the PNG image height.
+ \param rgb pointer to the RGB buffer.
+ \param alpha pointer to the Alpha channel buffer.
+ \param png on completion will point to the memory block storing the created PNG image.
+ \param png_size on completion the variable referenced by this
+ pointer will contain the size (in bytes) of the PNG image.
+ 
+ \return RL2_OK on success: RL2_ERROR on failure.
+ 
+ \sa rl2_rgb_to_png, rl2_rgb_to_jpeg, rl2_rgb_to_tiff, rl2_rgb_to_geotiff
+ */
+    RL2_DECLARE int
+	rl2_rgb_real_alpha_to_png (unsigned int width, unsigned int height,
+				   const unsigned char *rgb,
+				   const unsigned char *alpha,
+				   unsigned char **png, int *png_size);
+
+/**
  Exports an RGB buffer as an in-memory stored JPEG image
 
  \param width the JPEG image width.
@@ -3547,128 +4536,724 @@ extern "C"
 	rl2_gray_pdf (unsigned int width, unsigned int height,
 		      unsigned char **pdf, int *pdf_size);
 
+/**
+ Encodes a Font into the corresponding BLOB serialized format
+
+ \param font pointer to a memory block containig the Font.
+ \param font_sz the size (in bytes) of the in-memory Font,
+ \param blob on completion will point to the created encoded BLOB.
+ \param blob_sz on completion the variable referenced by this
+ pointer will contain the size (in bytes) of the BLOB.
+ 
+ \return RL2_OK on success: RL2_ERROR on failure.
+
+ \sa rl2_font_decode, rl2_is_valid_encoded_font,
+ rl2_get_encoded_font_facename, rl2_get_encoded_font_family, 
+ rl2_get_encoded_font_style, rl2_is_encoded_font_bold, 
+ rl2_is_encoded_font_italic
+ 
+ \note you are responsible to destroy (before or after) any allocated 
+ BLOB serialized Font.
+ */
+    RL2_DECLARE int
+	rl2_font_encode (const unsigned char *font, int font_sz,
+			 unsigned char **blob, int *blob_sz);
+
+/**
+ Tests a BLOB serialized Font for validity
+
+ \param blob pointer to the BLOB serialized Font.
+ \param blob_sz size (in bytes) of the BLOB.
+ 
+ \return RL2_OK on success: RL2_ERROR on failure.
+
+ \sa rl2_font_encode, rl2_font_decode, rl2_get_encoded_font_facename,
+ rl2_get_encoded_font_family, rl2_get_encoded_font_style, 
+ rl2_is_encoded_font_bold, rl2_is_encoded_font_italic
+ */
+    RL2_DECLARE int
+	rl2_is_valid_encoded_font (const unsigned char *blob, int blob_sz);
+
+/**
+ Decodes a Font from the corresponding BLOB serialized format
+
+ \param blob pointer to the BLOB serialized Font.
+ \param blob_sz size (in bytes) of the BLOB.
+ \param font on completion will point to a memory block containing the
+ decoded Font.
+ \param font_sz on completion the variable referenced by this
+ pointer will contain the size (in bytes) of in-memory Font.
+ 
+ \return RL2_OK on success: RL2_ERROR on failure.
+
+ \sa rl2_font_encode, rl2_is_valid_encoded_font,
+ rl2_get_encoded_font_facename, rl2_get_encoded_font_family, 
+ rl2_get_encoded_font_style, rl2_is_encoded_font_bold, 
+ rl2_is_encoded_font_italic
+ 
+ \note you are responsible to destroy (before or after) the memory 
+ block created by this function and containing the Font.
+ */
+    RL2_DECLARE int
+	rl2_font_decode (const unsigned char *blob, int blob_sz,
+			 unsigned char **font, int *font_sz);
+
+/**
+ Returns the Facename from a BLOB serialized Font
+
+ \param blob pointer to the BLOB serialized Font.
+ \param blob_sz size (in bytes) of the BLOB.
+ 
+ \return the Facename; or NULL on invalid args.
+
+ \sa rl2_font_encode, rl2_font_decode, rl2_is_valid_encoded_font,
+ rl2_get_encoded_font_family, rl2_get_encoded_font_style, 
+ rl2_is_encoded_font_bold, rl2_is_encoded_font_italic
+ 
+ \note you are responsible to destroy (before or after) the text
+ string returned by this function.
+ */
+    RL2_DECLARE char *rl2_get_encoded_font_facename (const unsigned char
+						     *blob, int blob_sz);
+
+/**
+ Returns the Family name from a BLOB serialized Font
+
+ \param blob pointer to the BLOB serialized Font.
+ \param blob_sz size (in bytes) of the BLOB.
+ 
+ \return the Family name; or NULL on invalid args.
+
+ \sa rl2_font_encode, rl2_font_decode, rl2_is_valid_encoded_font,
+ rl2_get_encode_font_facename, rl2_get_encoded_font_style, 
+ rl2_is_encoded_font_bold, rl2_is_encoded_font_italic
+ 
+ \note you are responsible to destroy (before or after) the text
+ string returned by this function.
+ */
+    RL2_DECLARE char *rl2_get_encoded_font_family (const unsigned char
+						   *blob, int blob_sz);
+
+/**
+ Returns the Style name from a BLOB serialized Font
+
+ \param blob pointer to the BLOB serialized Font.
+ \param blob_sz size (in bytes) of the BLOB.
+ 
+ \return the Style name (could be eventually NULL for some valid fonts).
+
+ \sa rl2_font_encode, rl2_font_decode, rl2_is_valid_encoded_font, 
+ rl2_get_encoded_font_facename, rl2_get_encoded_font_family, 
+ rl2_is_encoded_font_bold, rl2_is_encoded_font_italic
+ 
+ \note you are responsible to destroy (before or after) the text
+ string returned by this function.
+ */
+    RL2_DECLARE char *rl2_get_encoded_font_style (const unsigned char
+						  *blob, int blob_sz);
+
+/**
+ Tests if a BLOB serialized Font is Bold
+
+ \param blob pointer to the BLOB serialized Font.
+ \param blob_sz size (in bytes) of the BLOB.
+ 
+ \return FALSE (0) if the Font isn't Bold, any otherpositive value 
+ if it's Bold. a negative value will be returned on invalid args.
+
+ \sa rl2_font_encode, rl2_font_decode, rl2_is_valid_encoded_font, 
+ rl2_get_encoded_font_family, rl2_get_encoded_font_style, 
+ rl2_is_encoded_font_italic
+ */
+    RL2_DECLARE int rl2_is_encoded_font_bold (const unsigned char *blob,
+					      int blob_sz);
+
+/**
+ Tests if a BLOB serialized Font is Italic
+
+ \param blob pointer to the BLOB serialized Font.
+ \param blob_sz size (in bytes) of the BLOB.
+ 
+ \return FALSE (0) if the Font isn't Italic, any other positive value 
+ if it's Italic. a negative value will be returned on invalid args.
+
+ \sa rl2_font_encode, rl2_font_decode, rl2_is_valid_encoded_font, 
+ rl2_get_encoded_font_family, rl2_get_encoded_font_style, 
+ rl2_is_encoded_font_bold
+ */
+    RL2_DECLARE int rl2_is_encoded_font_italic (const unsigned char
+						*blob, int blob_sz);
+
+
     RL2_DECLARE int
 	rl2_parse_hexrgb (const char *hex, unsigned char *red,
 			  unsigned char *green, unsigned char *blue);
 
-    RL2_DECLARE rl2RasterStylePtr
-	rl2_create_raster_style_from_dbms (sqlite3 * handle,
-					   const char *coverage,
-					   const char *style);
+    RL2_DECLARE rl2CoverageStylePtr
+	rl2_create_coverage_style_from_dbms (sqlite3 * handle,
+					     const char *coverage,
+					     const char *style);
+
+    RL2_DECLARE rl2FeatureTypeStylePtr
+	rl2_create_feature_type_style_from_dbms (sqlite3 * handle,
+						 const char *coverage,
+						 const char *style);
 
     RL2_DECLARE rl2RasterStatisticsPtr
 	rl2_create_raster_statistics_from_dbms (sqlite3 * handle,
 						const char *coverage);
 
-    RL2_DECLARE void rl2_destroy_raster_style (rl2RasterStylePtr style);
+    RL2_DECLARE void rl2_destroy_coverage_style (rl2CoverageStylePtr style);
+
+    RL2_DECLARE const char *rl2_get_coverage_style_name (rl2CoverageStylePtr
+							 style);
 
-    RL2_DECLARE const char *rl2_get_raster_style_name (rl2RasterStylePtr style);
+    RL2_DECLARE rl2RasterSymbolizerPtr
+	rl2_get_symbolizer_from_coverage_style (rl2CoverageStylePtr style,
+						double scale);
 
-    RL2_DECLARE const char *rl2_get_raster_style_title (rl2RasterStylePtr
-							style);
+    RL2_DECLARE const char *rl2_get_rule_like_wild_card (rl2RuleLikeArgsPtr
+							 args);
 
-    RL2_DECLARE const char *rl2_get_raster_style_abstract (rl2RasterStylePtr
-							   style);
+    RL2_DECLARE const char *rl2_get_rule_like_single_char (rl2RuleLikeArgsPtr
+							   args);
 
-    RL2_DECLARE int rl2_get_raster_style_opacity (rl2RasterStylePtr style,
-						  double *opacity);
+    RL2_DECLARE const char *rl2_get_rule_like_value (rl2RuleLikeArgsPtr args);
 
-    RL2_DECLARE int rl2_is_raster_style_mono_band_selected (rl2RasterStylePtr
-							    style,
-							    int *selected);
+    RL2_DECLARE const char *rl2_get_rule_like_escape_char (rl2RuleLikeArgsPtr
+							   args);
 
-    RL2_DECLARE int rl2_get_raster_style_mono_band_selection (rl2RasterStylePtr
-							      style,
-							      unsigned char
-							      *gray_band);
+    RL2_DECLARE const char *rl2_get_rule_between_lower (rl2RuleBetweenArgsPtr
+							args);
 
-    RL2_DECLARE int rl2_is_raster_style_triple_band_selected (rl2RasterStylePtr
-							      style,
-							      int *selected);
+    RL2_DECLARE const char *rl2_get_rule_between_upper (rl2RuleBetweenArgsPtr
+							args);
+
+    RL2_DECLARE const char *rl2_get_rule_value (rl2RuleSingleArgPtr arg);
+
+    RL2_DECLARE int rl2_get_raster_symbolizer_opacity (rl2RasterSymbolizerPtr
+						       style, double *opacity);
 
     RL2_DECLARE int
-	rl2_get_raster_style_triple_band_selection (rl2RasterStylePtr style,
-						    unsigned char *red_band,
-						    unsigned char *green_band,
-						    unsigned char *blue_band);
+	rl2_is_raster_symbolizer_mono_band_selected (rl2RasterSymbolizerPtr
+						     style, int *selected,
+						     int *categorize,
+						     int *interpolate);
 
     RL2_DECLARE int
-	rl2_get_raster_style_overall_contrast_enhancement (rl2RasterStylePtr
-							   style,
-							   unsigned char
-							   *contrast_enhancement,
-							   double *gamma_value);
+	rl2_get_raster_symbolizer_mono_band_selection (rl2RasterSymbolizerPtr
+						       style,
+						       unsigned char
+						       *gray_band);
 
     RL2_DECLARE int
-	rl2_get_raster_style_red_band_contrast_enhancement (rl2RasterStylePtr
-							    style,
-							    unsigned char
-							    *contrast_enhancement,
-							    double
-							    *gamma_value);
+	rl2_is_raster_symbolizer_triple_band_selected (rl2RasterSymbolizerPtr
+						       style, int *selected);
+
+    RL2_DECLARE int
+	rl2_get_raster_symbolizer_triple_band_selection (rl2RasterSymbolizerPtr
+							 style,
+							 unsigned char
+							 *red_band,
+							 unsigned char
+							 *green_band,
+							 unsigned char
+							 *blue_band);
+
+    RL2_DECLARE int
+	rl2_get_raster_symbolizer_overall_contrast_enhancement
+	(rl2RasterSymbolizerPtr style, unsigned char *contrast_enhancement,
+	 double *gamma_value);
+
+    RL2_DECLARE int
+	rl2_get_raster_symbolizer_red_band_contrast_enhancement
+	(rl2RasterSymbolizerPtr style, unsigned char *contrast_enhancement,
+	 double *gamma_value);
+
+    RL2_DECLARE int
+	rl2_get_raster_symbolizer_green_band_contrast_enhancement
+	(rl2RasterSymbolizerPtr style, unsigned char *contrast_enhancement,
+	 double *gamma_value);
+
+    RL2_DECLARE int
+	rl2_get_raster_symbolizer_blue_band_contrast_enhancement
+	(rl2RasterSymbolizerPtr style, unsigned char *contrast_enhancement,
+	 double *gamma_value);
+
+    RL2_DECLARE int
+	rl2_get_raster_symbolizer_gray_band_contrast_enhancement
+	(rl2RasterSymbolizerPtr style, unsigned char *contrast_enhancement,
+	 double *gamma_value);
+
+    RL2_DECLARE int
+	rl2_has_raster_symbolizer_color_map_interpolated (rl2RasterSymbolizerPtr
+							  style,
+							  int *interpolated);
+
+    RL2_DECLARE int
+	rl2_has_raster_symbolizer_color_map_categorized (rl2RasterSymbolizerPtr
+							 style,
+							 int *categorized);
+
+    RL2_DECLARE int
+	rl2_get_raster_symbolizer_color_map_default (rl2RasterSymbolizerPtr
+						     style, unsigned char *red,
+						     unsigned char *green,
+						     unsigned char *blue);
+
+    RL2_DECLARE int
+	rl2_get_raster_symbolizer_color_map_category_base
+	(rl2RasterSymbolizerPtr style, unsigned char *red, unsigned char *green,
+	 unsigned char *blue);
+
+    RL2_DECLARE int
+	rl2_get_raster_symbolizer_color_map_count (rl2RasterSymbolizerPtr style,
+						   int *count);
+
+    RL2_DECLARE int
+	rl2_get_raster_symbolizer_color_map_entry (rl2RasterSymbolizerPtr style,
+						   int index, double *value,
+						   unsigned char *red,
+						   unsigned char *green,
+						   unsigned char *blue);
+
+    RL2_DECLARE int
+	rl2_has_raster_symbolizer_shaded_relief (rl2RasterSymbolizerPtr style,
+						 int *shaded_relief);
+
+    RL2_DECLARE int
+	rl2_get_raster_symbolizer_shaded_relief (rl2RasterSymbolizerPtr style,
+						 int *brightness_only,
+						 double *relief_factor);
+
+    RL2_DECLARE void rl2_destroy_feature_type_style (rl2FeatureTypeStylePtr
+						     style);
+
+    RL2_DECLARE const char
+	*rl2_get_feature_type_style_name (rl2FeatureTypeStylePtr style);
+
+    RL2_DECLARE int
+	rl2_get_feature_type_style_columns_count (rl2FeatureTypeStylePtr style);
+
+    RL2_DECLARE const char
+	*rl2_get_feature_type_style_column_name (rl2FeatureTypeStylePtr style,
+						 int index);
+
+    RL2_DECLARE rl2VariantArrayPtr rl2_create_variant_array (int count);
+
+    RL2_DECLARE void rl2_destroy_variant_array (rl2VariantArrayPtr variant);
+
+    RL2_DECLARE int rl2_set_variant_int (rl2VariantArrayPtr variant, int index,
+					 const char *name, sqlite3_int64 value);
+
+    RL2_DECLARE int rl2_set_variant_double (rl2VariantArrayPtr variant,
+					    int index, const char *name,
+					    double value);
+
+    RL2_DECLARE int rl2_set_variant_text (rl2VariantArrayPtr variant, int index,
+					  const char *name, const char *value,
+					  int bytes);
+
+    RL2_DECLARE int rl2_set_variant_blob (rl2VariantArrayPtr variant, int index,
+					  const char *name,
+					  const unsigned char *value,
+					  int bytes);
+
+    RL2_DECLARE int rl2_set_variant_null (rl2VariantArrayPtr variant, int index,
+					  const char *name);
+
+    RL2_DECLARE rl2VectorSymbolizerPtr
+	rl2_get_symbolizer_from_feature_type_style (rl2FeatureTypeStylePtr
+						    style, double scale,
+						    rl2VariantArrayPtr variant,
+						    int *scale_forbidden);
+
+    RL2_DECLARE int
+	rl2_is_visible_style (rl2FeatureTypeStylePtr style, double scale);
+
+    RL2_DECLARE int
+	rl2_is_valid_vector_symbolizer (rl2VectorSymbolizerPtr symbolizer,
+					int *valid);
+
+    RL2_DECLARE int
+	rl2_get_vector_symbolizer_count (rl2VectorSymbolizerPtr symbolizer,
+					 int *count);
+
+    RL2_DECLARE int
+	rl2_get_vector_symbolizer_item_type (rl2VectorSymbolizerPtr symbolizer,
+					     int index, int *type);
+
+    RL2_DECLARE rl2PointSymbolizerPtr
+	rl2_get_point_symbolizer (rl2VectorSymbolizerPtr symbolizer, int index);
+
+    RL2_DECLARE rl2LineSymbolizerPtr
+	rl2_get_line_symbolizer (rl2VectorSymbolizerPtr symbolizer, int index);
+
+    RL2_DECLARE rl2PolygonSymbolizerPtr
+	rl2_get_polygon_symbolizer (rl2VectorSymbolizerPtr symbolizer,
+				    int index);
+
+    RL2_DECLARE rl2TextSymbolizerPtr
+	rl2_get_text_symbolizer (rl2VectorSymbolizerPtr symbolizer, int index);
+
+    RL2_DECLARE int
+	rl2_point_symbolizer_get_count (rl2PointSymbolizerPtr symbolizer,
+					int *count);
+
+    RL2_DECLARE int
+	rl2_point_symbolizer_is_graphic (rl2PointSymbolizerPtr symbolizer,
+					 int index, int *external_graphic);
+
+    RL2_DECLARE const char
+	*rl2_point_symbolizer_get_graphic_href (rl2PointSymbolizerPtr
+						symbolizer, int index);
+
+    RL2_DECLARE int
+	rl2_point_symbolizer_get_graphic_recode_color
+	(rl2PointSymbolizerPtr symbolizer, int index, int repl_index,
+	 int *color_index, unsigned char *red, unsigned char *green,
+	 unsigned char *blue);
+
+    RL2_DECLARE int
+	rl2_point_symbolizer_is_mark (rl2PointSymbolizerPtr symbolizer,
+				      int index, int *mark);
+
+    RL2_DECLARE int
+	rl2_point_symbolizer_mark_get_well_known_type (rl2PointSymbolizerPtr
+						       symbolizer, int index,
+						       unsigned char *type);
+
+    RL2_DECLARE int
+	rl2_point_symbolizer_mark_has_stroke (rl2PointSymbolizerPtr symbolizer,
+					      int index, int *stroke);
 
     RL2_DECLARE int
-	rl2_get_raster_style_green_band_contrast_enhancement (rl2RasterStylePtr
-							      style,
-							      unsigned char
-							      *contrast_enhancement,
-							      double
-							      *gamma_value);
+	rl2_point_symbolizer_mark_get_stroke_color (rl2PointSymbolizerPtr
+						    symbolizer, int index,
+						    unsigned char *red,
+						    unsigned char *green,
+						    unsigned char *blue);
 
     RL2_DECLARE int
-	rl2_get_raster_style_blue_band_contrast_enhancement (rl2RasterStylePtr
-							     style,
-							     unsigned char
-							     *contrast_enhancement,
-							     double
-							     *gamma_value);
+	rl2_point_symbolizer_mark_get_stroke_width (rl2PointSymbolizerPtr
+						    symbolizer, int index,
+						    double *width);
 
     RL2_DECLARE int
-	rl2_get_raster_style_gray_band_contrast_enhancement (rl2RasterStylePtr
-							     style,
-							     unsigned char
-							     *contrast_enhancement,
-							     double
-							     *gamma_value);
+	rl2_point_symbolizer_mark_get_stroke_linejoin (rl2PointSymbolizerPtr
+						       symbolizer, int index,
+						       unsigned char *linejoin);
 
     RL2_DECLARE int
-	rl2_has_raster_style_color_map_interpolated (rl2RasterStylePtr style,
-						     int *interpolated);
+	rl2_point_symbolizer_mark_get_stroke_linecap (rl2PointSymbolizerPtr
+						      symbolizer, int index,
+						      unsigned char *linecap);
 
     RL2_DECLARE int
-	rl2_has_raster_style_color_map_categorized (rl2RasterStylePtr style,
-						    int *categorized);
+	rl2_point_symbolizer_mark_get_stroke_dash_offset (rl2PointSymbolizerPtr
+							  symbolizer, int index,
+							  double *offset);
 
-    RL2_DECLARE int rl2_get_raster_style_color_map_default (rl2RasterStylePtr
-							    style,
-							    unsigned char *red,
-							    unsigned char
-							    *green,
-							    unsigned char
-							    *blue);
+    RL2_DECLARE int
+	rl2_point_symbolizer_mark_get_stroke_dash_count (rl2PointSymbolizerPtr
+							 symbolizer, int index,
+							 int *count);
 
     RL2_DECLARE int
-	rl2_get_raster_style_color_map_category_base (rl2RasterStylePtr style,
-						      unsigned char *red,
-						      unsigned char *green,
-						      unsigned char *blue);
+	rl2_point_symbolizer_mark_get_stroke_dash_item (rl2PointSymbolizerPtr
+							symbolizer, int index,
+							int item_index,
+							double *item);
 
-    RL2_DECLARE int rl2_get_raster_style_color_map_count (rl2RasterStylePtr
-							  style, int *count);
+    RL2_DECLARE int
+	rl2_point_symbolizer_mark_has_fill (rl2PointSymbolizerPtr symbolizer,
+					    int index, int *fill);
 
-    RL2_DECLARE int rl2_get_raster_style_color_map_entry (rl2RasterStylePtr
-							  style, int index,
-							  double *value,
-							  unsigned char *red,
-							  unsigned char *green,
-							  unsigned char *blue);
+    RL2_DECLARE int
+	rl2_point_symbolizer_mark_get_fill_color (rl2PointSymbolizerPtr
+						  symbolizer, int index,
+						  unsigned char *red,
+						  unsigned char *green,
+						  unsigned char *blue);
 
-    RL2_DECLARE int rl2_has_raster_style_shaded_relief (rl2RasterStylePtr style,
-							int *shaded_relief);
+    RL2_DECLARE int
+	rl2_point_symbolizer_get_opacity (rl2PointSymbolizerPtr symbolizer,
+					  double *opacity);
 
-    RL2_DECLARE int rl2_get_raster_style_shaded_relief (rl2RasterStylePtr style,
-							int *brightness_only,
-							double *relief_factor);
+    RL2_DECLARE int
+	rl2_point_symbolizer_get_size (rl2PointSymbolizerPtr symbolizer,
+				       double *size);
+
+    RL2_DECLARE int
+	rl2_point_symbolizer_get_rotation (rl2PointSymbolizerPtr symbolizer,
+					   double *rotation);
+
+    RL2_DECLARE int
+	rl2_point_symbolizer_get_anchor_point (rl2PointSymbolizerPtr symbolizer,
+					       double *x, double *y);
+
+    RL2_DECLARE int
+	rl2_point_symbolizer_get_displacement (rl2PointSymbolizerPtr symbolizer,
+					       double *x, double *y);
+
+    RL2_DECLARE int
+	rl2_line_symbolizer_has_stroke (rl2LineSymbolizerPtr symbolizer,
+					int *stroke);
+
+    RL2_DECLARE int
+	rl2_line_symbolizer_has_graphic_stroke (rl2LineSymbolizerPtr symbolizer,
+						int *stroke);
+
+    RL2_DECLARE const char
+	*rl2_line_symbolizer_get_graphic_stroke_href (rl2LineSymbolizerPtr
+						      symbolizer);
+
+    RL2_DECLARE int
+	rl2_line_symbolizer_get_graphic_stroke_recode_count
+	(rl2LineSymbolizerPtr symbolizer, int *count);
+
+    RL2_DECLARE int
+	rl2_line_symbolizer_get_graphic_stroke_recode_color
+	(rl2LineSymbolizerPtr symbolizer, int index, int *color_index,
+	 unsigned char *red, unsigned char *green, unsigned char *blue);
+
+    RL2_DECLARE int
+	rl2_line_symbolizer_get_stroke_color (rl2LineSymbolizerPtr symbolizer,
+					      unsigned char *red,
+					      unsigned char *green,
+					      unsigned char *blue);
+
+    RL2_DECLARE int
+	rl2_line_symbolizer_get_stroke_opacity (rl2LineSymbolizerPtr symbolizer,
+						double *opacity);
+
+    RL2_DECLARE int
+	rl2_line_symbolizer_get_stroke_width (rl2LineSymbolizerPtr symbolizer,
+					      double *width);
+
+    RL2_DECLARE int
+	rl2_line_symbolizer_get_stroke_linejoin (rl2LineSymbolizerPtr
+						 symbolizer,
+						 unsigned char *linejoin);
+
+    RL2_DECLARE int
+	rl2_line_symbolizer_get_stroke_linecap (rl2LineSymbolizerPtr symbolizer,
+						unsigned char *linecap);
+
+    RL2_DECLARE int
+	rl2_line_symbolizer_get_stroke_dash_offset (rl2LineSymbolizerPtr
+						    symbolizer, double *offset);
+
+    RL2_DECLARE int
+	rl2_line_symbolizer_get_stroke_dash_count (rl2LineSymbolizerPtr
+						   symbolizer, int *count);
+
+    RL2_DECLARE int
+	rl2_line_symbolizer_get_stroke_dash_item (rl2LineSymbolizerPtr
+						  symbolizer, int index,
+						  double *item);
+
+    RL2_DECLARE int
+	rl2_line_symbolizer_get_perpendicular_offset (rl2LineSymbolizerPtr
+						      symbolizer,
+						      double *offset);
+
+    RL2_DECLARE int
+	rl2_polygon_symbolizer_has_stroke (rl2PolygonSymbolizerPtr symbolizer,
+					   int *stroke);
+
+    RL2_DECLARE int
+	rl2_polygon_symbolizer_has_graphic_stroke (rl2PolygonSymbolizerPtr
+						   symbolizer, int *stroke);
+
+    RL2_DECLARE const char
+	*rl2_polygon_symbolizer_get_graphic_stroke_href (rl2PolygonSymbolizerPtr
+							 symbolizer);
+
+    RL2_DECLARE int
+	rl2_polygon_symbolizer_get_graphic_stroke_recode_count
+	(rl2PolygonSymbolizerPtr symbolizer, int *count);
+
+    RL2_DECLARE int
+	rl2_polygon_symbolizer_get_graphic_stroke_recode_color
+	(rl2PolygonSymbolizerPtr symbolizer, int index, int *color_index,
+	 unsigned char *red, unsigned char *green, unsigned char *blue);
+
+    RL2_DECLARE int
+	rl2_polygon_symbolizer_get_stroke_color (rl2PolygonSymbolizerPtr
+						 symbolizer, unsigned char *red,
+						 unsigned char *green,
+						 unsigned char *blue);
+
+    RL2_DECLARE int
+	rl2_polygon_symbolizer_get_stroke_opacity (rl2PolygonSymbolizerPtr
+						   symbolizer, double *opacity);
+
+    RL2_DECLARE int
+	rl2_polygon_symbolizer_get_stroke_width (rl2PolygonSymbolizerPtr
+						 symbolizer, double *width);
+
+    RL2_DECLARE int
+	rl2_polygon_symbolizer_get_stroke_linejoin (rl2PolygonSymbolizerPtr
+						    symbolizer,
+						    unsigned char *linejoin);
+
+    RL2_DECLARE int
+	rl2_polygon_symbolizer_get_stroke_linecap (rl2PolygonSymbolizerPtr
+						   symbolizer,
+						   unsigned char *linecap);
+
+    RL2_DECLARE int
+	rl2_polygon_symbolizer_get_stroke_dash_offset (rl2PolygonSymbolizerPtr
+						       symbolizer,
+						       double *offset);
+
+    RL2_DECLARE int
+	rl2_polygon_symbolizer_get_stroke_dash_count (rl2PolygonSymbolizerPtr
+						      symbolizer, int *count);
+
+    RL2_DECLARE int
+	rl2_polygon_symbolizer_get_stroke_dash_item (rl2PolygonSymbolizerPtr
+						     symbolizer, int index,
+						     double *item);
+
+    RL2_DECLARE int
+	rl2_polygon_symbolizer_has_fill (rl2PolygonSymbolizerPtr symbolizer,
+					 int *fill);
+
+    RL2_DECLARE int
+	rl2_polygon_symbolizer_has_graphic_fill (rl2PolygonSymbolizerPtr
+						 symbolizer, int *fill);
+
+    RL2_DECLARE const char
+	*rl2_polygon_symbolizer_get_graphic_fill_href (rl2PolygonSymbolizerPtr
+						       symbolizer);
+
+    RL2_DECLARE int
+	rl2_polygon_symbolizer_get_graphic_fill_recode_count
+	(rl2PolygonSymbolizerPtr symbolizer, int *count);
+
+    RL2_DECLARE int
+	rl2_polygon_symbolizer_get_graphic_fill_recode_color
+	(rl2PolygonSymbolizerPtr symbolizer, int index, int *color_index,
+	 unsigned char *red, unsigned char *green, unsigned char *blue);
+
+    RL2_DECLARE int
+	rl2_polygon_symbolizer_get_fill_color (rl2PolygonSymbolizerPtr
+					       symbolizer, unsigned char *red,
+					       unsigned char *green,
+					       unsigned char *blue);
+
+    RL2_DECLARE int
+	rl2_polygon_symbolizer_get_fill_opacity (rl2PolygonSymbolizerPtr
+						 symbolizer, double *opacity);
+
+    RL2_DECLARE int
+	rl2_polygon_symbolizer_get_displacement (rl2PolygonSymbolizerPtr
+						 symbolizer, double *x,
+						 double *y);
+
+    RL2_DECLARE int
+	rl2_polygon_symbolizer_get_perpendicular_offset (rl2PolygonSymbolizerPtr
+							 symbolizer,
+							 double *offset);
+
+    RL2_DECLARE const char *rl2_text_symbolizer_get_label (rl2TextSymbolizerPtr
+							   symbolizer);
+
+    RL2_DECLARE int
+	rl2_text_symbolizer_get_font_families_count (rl2TextSymbolizerPtr
+						     symbolizer, int *count);
+
+    RL2_DECLARE const char
+	*rl2_text_symbolizer_get_font_family_name (rl2TextSymbolizerPtr
+						   symbolizer, int index);
+
+    RL2_DECLARE int
+	rl2_text_symbolizer_get_font_style (rl2TextSymbolizerPtr symbolizer,
+					    unsigned char *style);
+
+    RL2_DECLARE int
+	rl2_text_symbolizer_get_font_weight (rl2TextSymbolizerPtr symbolizer,
+					     unsigned char *weight);
+
+    RL2_DECLARE int
+	rl2_text_symbolizer_get_font_size (rl2TextSymbolizerPtr symbolizer,
+					   double *size);
+
+    RL2_DECLARE int
+	rl2_text_symbolizer_get_label_placement_mode (rl2TextSymbolizerPtr
+						      symbolizer,
+						      unsigned char *mode);
+
+    RL2_DECLARE int
+	rl2_text_symbolizer_get_point_placement_anchor_point
+	(rl2TextSymbolizerPtr symbolizer, double *x, double *y);
+
+    RL2_DECLARE int
+	rl2_text_symbolizer_get_point_placement_displacement
+	(rl2TextSymbolizerPtr symbolizer, double *x, double *y);
+
+    RL2_DECLARE int
+	rl2_text_symbolizer_get_point_placement_rotation (rl2TextSymbolizerPtr
+							  symbolizer,
+							  double *rotation);
+
+    RL2_DECLARE int
+	rl2_text_symbolizer_get_line_placement_perpendicular_offset
+	(rl2TextSymbolizerPtr symbolizer, double *offset);
+
+    RL2_DECLARE int
+	rl2_text_symbolizer_get_line_placement_is_repeated (rl2TextSymbolizerPtr
+							    symbolizer,
+							    int *is_repeated);
+
+    RL2_DECLARE int
+	rl2_text_symbolizer_get_line_placement_initial_gap (rl2TextSymbolizerPtr
+							    symbolizer,
+							    double
+							    *initial_gap);
+
+    RL2_DECLARE int
+	rl2_text_symbolizer_get_line_placement_gap (rl2TextSymbolizerPtr
+						    symbolizer, double *gap);
+
+    RL2_DECLARE int
+	rl2_text_symbolizer_get_line_placement_is_aligned (rl2TextSymbolizerPtr
+							   symbolizer,
+							   int *is_aligned);
+
+    RL2_DECLARE int
+	rl2_text_symbolizer_get_line_placement_generalize_line
+	(rl2TextSymbolizerPtr symbolizer, int *generalize_line);
+
+    RL2_DECLARE int
+	rl2_text_symbolizer_has_halo (rl2TextSymbolizerPtr symbolizer,
+				      int *halo);
+
+    RL2_DECLARE int
+	rl2_text_symbolizer_get_halo_radius (rl2TextSymbolizerPtr symbolizer,
+					     double *radius);
+
+    RL2_DECLARE int
+	rl2_text_symbolizer_has_halo_fill (rl2TextSymbolizerPtr symbolizer,
+					   int *fill);
+
+    RL2_DECLARE int
+	rl2_text_symbolizer_get_halo_fill_color (rl2TextSymbolizerPtr
+						 symbolizer, unsigned char *red,
+						 unsigned char *green,
+						 unsigned char *blue);
+
+    RL2_DECLARE int
+	rl2_text_symbolizer_has_fill (rl2TextSymbolizerPtr symbolizer,
+				      int *fill);
+
+    RL2_DECLARE int
+	rl2_text_symbolizer_get_fill_color (rl2TextSymbolizerPtr symbolizer,
+					    unsigned char *red,
+					    unsigned char *green,
+					    unsigned char *blue);
 
     RL2_DECLARE rl2GroupStylePtr
 	rl2_create_group_style_from_dbms (sqlite3 * handle, const char *group,
@@ -3678,11 +5263,6 @@ extern "C"
 
     RL2_DECLARE const char *rl2_get_group_style_name (rl2GroupStylePtr style);
 
-    RL2_DECLARE const char *rl2_get_group_style_title (rl2GroupStylePtr style);
-
-    RL2_DECLARE const char *rl2_get_group_style_abstract (rl2GroupStylePtr
-							  style);
-
     RL2_DECLARE int rl2_is_valid_group_style (rl2GroupStylePtr style,
 					      int *valid);
 
@@ -3707,6 +5287,51 @@ extern "C"
 
     RL2_DECLARE void rl2_destroy_group_renderer (rl2GroupRendererPtr group);
 
+    RL2_DECLARE char *rl2_build_worldfile_path (const char *path,
+						const char *suffix);
+
+    RL2_DECLARE char *rl2_compute_file_md5_checksum (const char *src_path);
+
+    RL2_DECLARE int rl2_get_jpeg_infos (const char *path, unsigned int *width,
+					unsigned int *height,
+					unsigned char *pixel_type);
+
+    RL2_DECLARE int rl2_get_jpeg2000_infos (const char *path,
+					    unsigned int *width,
+					    unsigned int *height,
+					    unsigned char *sample_type,
+					    unsigned char *pixel_type,
+					    unsigned char *num_bands,
+					    unsigned int *tile_width,
+					    unsigned int *tile_height,
+					    unsigned char *num_levels);
+
+    RL2_DECLARE int rl2_get_jpeg2000_blob_type (const unsigned char *blob,
+						int blob_size,
+						unsigned char *sample_type,
+						unsigned char *pixel_type,
+						unsigned char *num_bands);
+
+    RL2_DECLARE char *rl2_build_raw_pixels_xml_summary (rl2RasterPtr rst);
+
+    RL2_DECLARE rl2RasterPtr
+	rl2_get_tile_from_raw_pixels (rl2CoveragePtr cvg, rl2RasterPtr rst,
+				      unsigned int startRow,
+				      unsigned int startCol);
+
+    RL2_DECLARE int
+	rl2_check_raster_coverage_destination (sqlite3 * sqlite,
+					       const char *coverage_name);
+
+    RL2_DECLARE int
+	rl2_check_raster_coverage_origin (sqlite3 * sqlite,
+					  const char *db_prefix,
+					  const char *coverage_name);
+
+    RL2_DECLARE int
+	rl2_copy_raster_coverage (sqlite3 * sqlite, const char *db_prefix,
+				  const char *coverage_name);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/headers/rasterlite2/rl2graphics.h b/headers/rasterlite2/rl2graphics.h
index 97abd0a..5fa9315 100644
--- a/headers/rasterlite2/rl2graphics.h
+++ b/headers/rasterlite2/rl2graphics.h
@@ -59,14 +59,9 @@ extern "C"
 {
 #endif
 
-#define RL2_PENSTYLE_SOLID	5001
-#define RL2_PENSTYLE_DOT	5002
-#define RL2_PENSTYLE_LONG_DASH 	5003
-#define RL2_PENSTYLE_SHORT_DASH	5004
-#define RL2_PENSTYLE_DOT_DASH	5005
-
 #define RL2_FONTSTYLE_NORMAL	5101
 #define RL2_FONTSTYLE_ITALIC	5102
+#define RL2_FONTSTYLE_OBLIQUE	5103
 
 #define RL2_FONTWEIGHT_NORMAL	5201
 #define RL2_FONTWEIGHT_BOLD	5202
@@ -74,6 +69,14 @@ extern "C"
 #define RL2_CLEAR_PATH		5100
 #define RL2_PRESERVE_PATH	5101
 
+#define RL2_PEN_CAP_BUTT	5210
+#define RL2_PEN_CAP_ROUND	5211
+#define RL2_PEN_CAP_SQUARE	5212
+
+#define RL2_PEN_JOIN_MITER	5261
+#define RL2_PEN_JOIN_ROUND	5262
+#define RL2_PEN_JOIN_BEVEL	5263
+
     typedef struct rl2_graphics_context rl2GraphicsContext;
     typedef rl2GraphicsContext *rl2GraphicsContextPtr;
 
@@ -232,7 +235,7 @@ extern "C"
 					    unsigned char **buffer, int *size);
 
 /**
- Selects the currently set Pen for a Graphics Context
+ Selects the currently set Pen for a Graphics Context (solid style)
 
  \param context the pointer to a valid Graphics Context returned by a previous call
  to rl2_graph_create_context(), rl2_graph_create_svg_context() or
@@ -242,20 +245,241 @@ extern "C"
  \param blue Pen color: blue component.
  \param alpha Pen transparency (0 full transparent; 255 full opaque).
  \param width Pen width
- \param style one of RL2_PENSTYLE_SOLID, RL2_PENSTYLE_DOT, RL2_PENSTYLE_LONG_DASH,
- RL2_PENSTYLE_SHORT_DASH, RL2_PENSTYLE_DOT_DASH
+ \param line_cap one of RL2_PEN_CAP_BUTT, RL2_PEN_CAP_ROUND or RL2_PEN_CAP_SQUARE
+ \param line_join one of RL2_PEN_JOIN_MITER, RL2_PEN_JOIN_MITER or RL2_PEN_JOIN_BEVEL
 
  \return 0 (false) on error, any other value on success.
  
  \sa rl2_graph_create_context, rl2_graph_create_svg_context, 
- rl2_graph_create_pdf_context, rl2_graph_set_brush, 
- rl2_graph_set_linear_gradient_brush, rl2_graph_set_pattern_brush,
- rl2_graph_set_font
+ rl2_graph_create_pdf_context, rl2_graph_set_dashed_pen,
+ rl2_graph_set_linear_gradient_solid_pen, rl2_graph_set_linear_gradient_dashed_pen,
+ rl2_graph_set_pattern_solid_pen, rl2_graph_set_pattern_dashed_pen, 
+ rl2_graph_set_brush, rl2_graph_set_font
+ */
+    RL2_DECLARE int rl2_graph_set_solid_pen (rl2GraphicsContextPtr context,
+					     unsigned char red,
+					     unsigned char green,
+					     unsigned char blue,
+					     unsigned char alpha, double width,
+					     int line_cap, int line_join);
+
+/**
+ Selects the currently set Pen for a Graphics Context (dashed style)
+
+ \param context the pointer to a valid Graphics Context returned by a previous call
+ to rl2_graph_create_context(), rl2_graph_create_svg_context() or
+ rl2_graph_create_pdf_context()
+ \param red Pen color: red component.
+ \param green Pen color: green component.
+ \param blue Pen color: blue component.
+ \param alpha Pen transparency (0 full transparent; 255 full opaque).
+ \param width Pen width
+ \param line_cap one of RL2_PEN_CAP_BUTT, RL2_PEN_CAP_ROUND or RL2_PEN_CAP_SQUARE
+ \param line_join one of RL2_PEN_JOIN_MITER, RL2_PEN_JOIN_MITER or RL2_PEN_JOIN_BEVEL
+ \param dash_count the total count of dash_list items
+ \param dash_list an array of dash items 
+ \param dash_offset start offset
+
+ \return 0 (false) on error, any other value on success.
+ 
+ \sa rl2_graph_create_context, rl2_graph_create_svg_context, 
+ rl2_graph_create_pdf_context, rl2_graph_set_solid_pen,
+ rl2_graph_set_linear_gradient_solid_pen, rl2_graph_set_linear_gradient_dashed_pen,
+ rl2_graph_set_pattern_solid_pen, rl2_graph_set_pattern_dashed_pen, 
+ rl2_graph_set_brush, rl2_graph_set_font
+ */
+    RL2_DECLARE int rl2_graph_set_dashed_pen (rl2GraphicsContextPtr context,
+					      unsigned char red,
+					      unsigned char green,
+					      unsigned char blue,
+					      unsigned char alpha, double width,
+					      int line_cap, int line_join,
+					      int dash_count,
+					      double dash_list[],
+					      double dash_offset);
+
+/**
+ Selects the currently set Linear Gradient Pen for a Graphics Context (solid style)
+
+ \param context the pointer to a valid Graphics Context returned by a previous call
+ to rl2_graph_create_context(), rl2_graph_create_svg_context() or
+ rl2_graph_create_pdf_context()
+ \param x start point (X coord, in pixels) of the Gradient.
+ \param y start point (Y coord, in pixels) of the Gradient.
+ \param width the Gradient width.
+ \param height the Gradient height.
+ \param red1 first Gradient color: red component.
+ \param green1 first Gradient color: green component.
+ \param blue1 first Gradient color: blue component.
+ \param alpha1 first Gradient color transparency (0 full transparent; 255 full opaque).
+ \param red2 second Gradient color: red component.
+ \param green2 second Gradient color: green component.
+ \param blue2 second Gradient color: blue component.
+ \param alpha2 second Gradient color transparency (0 full transparent; 255 full opaque).
+ \param width Pen width
+ \param line_cap one of RL2_PEN_CAP_BUTT, RL2_PEN_CAP_ROUND or RL2_PEN_CAP_SQUARE
+ \param line_join one of RL2_PEN_JOIN_MITER, RL2_PEN_JOIN_MITER or RL2_PEN_JOIN_BEVEL
+
+ \return 0 (false) on error, any other value on success.
+ 
+ \sa rl2_graph_create_context, rl2_graph_create_svg_context, 
+ rl2_graph_create_pdf_context, rl2_graph_set_solid_brush, 
+ rl2_graph_set_dashed_pen, rl2_graph_set_linear_gradient_dashed_pen,
+ rl2_graph_set_pattern_solid_pen, rl2_graph_set_pattern_dashed_pen, 
+ rl2_graph_set_brush, rl2_graph_set_font
+
+ \note a Pen created by this function always is a Linear Gradient Pen.
+ */
+    RL2_DECLARE int
+	rl2_graph_set_linear_gradient_solid_pen (rl2GraphicsContextPtr,
+						 double x, double y,
+						 double width, double height,
+						 unsigned char red1,
+						 unsigned char green1,
+						 unsigned char blue1,
+						 unsigned char alpha1,
+						 unsigned char red2,
+						 unsigned char green2,
+						 unsigned char blue2,
+						 unsigned char alpha2,
+						 double pen_width, int line_cap,
+						 int line_join);
+
+/**
+ Selects the currently set Linear Gradient Pen for a Graphics Context (dashed style)
+
+ \param context the pointer to a valid Graphics Context returned by a previous call
+ to rl2_graph_create_context(), rl2_graph_create_svg_context() or
+ rl2_graph_create_pdf_context()
+ \param x start point (X coord, in pixels) of the Gradient.
+ \param y start point (Y coord, in pixels) of the Gradient.
+ \param width the Gradient width.
+ \param height the Gradient height.
+ \param red1 first Gradient color: red component.
+ \param green1 first Gradient color: green component.
+ \param blue1 first Gradient color: blue component.
+ \param alpha1 first Gradient color transparency (0 full transparent; 255 full opaque).
+ \param red2 second Gradient color: red component.
+ \param green2 second Gradient color: green component.
+ \param blue2 second Gradient color: blue component.
+ \param alpha2 second Gradient color transparency (0 full transparent; 255 full opaque).
+ \param width Pen width
+ \param line_cap one of RL2_PEN_CAP_BUTT, RL2_PEN_CAP_ROUND or RL2_PEN_CAP_SQUARE
+ \param line_join one of RL2_PEN_JOIN_MITER, RL2_PEN_JOIN_MITER or RL2_PEN_JOIN_BEVEL
+ \param dash_count the total count of dash_list items
+ \param dash_list an array of dash items 
+ \param dash_offset start offset
+
+ \return 0 (false) on error, any other value on success.
+ 
+ \sa rl2_graph_create_context, rl2_graph_create_svg_context, 
+ rl2_graph_create_pdf_context, rl2_graph_set_solid_pen, 
+ rl2_graph_set_dashed_pen, rl2_graph_set_linear_gradient_solid_pen, 
+ rl2_graph_set_pattern_solid_pen, rl2_graph_set_pattern_dashed_pen, 
+ rl2_graph_set_brush, rl2_graph_set_font
+
+ \note a Pen created by this function always is a Linear Gradient Pen.
+ */
+    RL2_DECLARE int
+	rl2_graph_set_linear_gradient_dashed_pen (rl2GraphicsContextPtr,
+						  double x, double y,
+						  double width, double height,
+						  unsigned char red1,
+						  unsigned char green1,
+						  unsigned char blue1,
+						  unsigned char alpha1,
+						  unsigned char red2,
+						  unsigned char green2,
+						  unsigned char blue2,
+						  unsigned char alpha2,
+						  double pen_width,
+						  int line_cap, int line_join,
+						  int dash_count,
+						  double dash_list[],
+						  double offset);
+
+/**
+ Selects the currently set Pattern Pen for a Graphics Context (solid style)
+
+ \param context the pointer to a valid Graphics Context returned by a previous call
+ to rl2_graph_create_context(), rl2_graph_create_svg_context() or
+ rl2_graph_create_pdf_context()
+ \param pattern the pointer to a valid Graphics Pattern returned by a previous
+ call to rl2_graph_create_pattern().
+ \param pen_width Pen width
+ \param line_cap one of RL2_PEN_CAP_BUTT, RL2_PEN_CAP_ROUND or RL2_PEN_CAP_SQUARE
+ \param line_join one of RL2_PEN_JOIN_MITER, RL2_PEN_JOIN_MITER or RL2_PEN_JOIN_BEVEL
+
+ \return 0 (false) on error, any other value on success.
+ 
+ \sa rl2_graph_create_context, rl2_graph_create_svg_context, 
+ rl2_graph_create_pdf_context, rl2_graph_set_solid_pen, rl2_graph_set_dashed_pen,
+ rl2_graph_set_linear_gradient_solid_pen, rl2_graph_set_linear_gradient_dashed_pen,
+ rl2_graph_set_pattern_dashed_pen, rl2_graph_set_brush, rl2_graph_set_font, 
+ rl2_create_pattern, rl2_graph_realease_pattern_pen
+
+ \note a Pen created by this function always is a Pattern Pen, 
+ i.e. a Pen repeatedly using a small bitmap as a filling source.
  */
-    RL2_DECLARE int rl2_graph_set_pen (rl2GraphicsContextPtr context,
-				       unsigned char red, unsigned char green,
-				       unsigned char blue, unsigned char alpha,
-				       double width, int style);
+    RL2_DECLARE int rl2_graph_set_pattern_solid_pen (rl2GraphicsContextPtr
+						     context,
+						     rl2GraphicsPatternPtr
+						     pattern, double width,
+						     int line_cap,
+						     int line_join);
+
+/**
+ Selects the currently set Pattern Pen for a Graphics Context (dashed style)
+
+ \param context the pointer to a valid Graphics Context returned by a previous call
+ to rl2_graph_create_context(), rl2_graph_create_svg_context() or
+ rl2_graph_create_pdf_context()
+ \param pattern the pointer to a valid Graphics Pattern returned by a previous
+ call to rl2_graph_create_pattern().
+ \param pen_width Pen width
+ \param line_cap one of RL2_PEN_CAP_BUTT, RL2_PEN_CAP_ROUND or RL2_PEN_CAP_SQUARE
+ \param line_join one of RL2_PEN_JOIN_MITER, RL2_PEN_JOIN_MITER or RL2_PEN_JOIN_BEVEL
+ \param dash_count the total count of dash_list items
+ \param dash_list an array of dash items 
+ \param dash_offset start offset
+
+ \return 0 (false) on error, any other value on success.
+ 
+ \sa rl2_graph_create_context, rl2_graph_create_svg_context, 
+ rl2_graph_create_pdf_context, rl2_graph_set_solid_pen, rl2_graph_set_dashed_pen,
+ rl2_graph_set_linear_gradient_solid_pen, rl2_graph_set_linear_gradient_dashed_pen,
+ rl2_graph_set_pattern_solid_pen, rl2_graph_set_brush, rl2_graph_set_font, 
+ rl2_create_pattern, rl2_graph_realease_pattern_pen
+
+ \note a Pen created by this function always is a Pattern Pen, 
+ i.e. a Pen repeatedly using a small bitmap as a filling source.
+ */
+    RL2_DECLARE int rl2_graph_set_pattern_dashed_pen (rl2GraphicsContextPtr
+						      context,
+						      rl2GraphicsPatternPtr
+						      pattern, double width,
+						      int line_cap,
+						      int line_join,
+						      int dash_count,
+						      double dash_list[],
+						      double offset);
+
+/**
+ Releases the currently set Pattern Pen (if any) from a Graphics Context
+
+ \param context the pointer to a valid Graphics Context returned by a previous call
+ to rl2_graph_create_context(), rl2_graph_create_svg_context() or
+ rl2_graph_create_pdf_context()
+
+ \return 0 (false) on error, any other value on success.
+ 
+ \sa rl2_graph_set_pattern_solid_pen, rl2_graph_set_pattern_dashed_pen
+
+ \note you should always release a Pattern Pen before attempting to
+ destroy the corresponding Pattern object.
+ */
+    RL2_DECLARE int rl2_graph_release_pattern_pen (rl2GraphicsContextPtr
+						   context);
 
 /**
  Selects the currently set Brush for a Graphics Context
@@ -271,7 +495,8 @@ extern "C"
  \return 0 (false) on error, any other value on success.
  
  \sa rl2_graph_create_context, rl2_graph_create_svg_context, 
- rl2_graph_create_pdf_context, rl2_graph_set_pen, 
+ rl2_graph_create_pdf_context, rrl2_graph_set_solid_pen, rl2_graph_set_dashed_pen,
+ rl2_graph_set_linear_gradient_pen, rl2_graph_set_pattern_pen,
  rl2_graph_set_linear_gradient_brush, rl2_graph_set_pattern_brush,
  rl2_graph_set_font
 
@@ -305,7 +530,8 @@ extern "C"
  \return 0 (false) on error, any other value on success.
  
  \sa rl2_graph_create_context, rl2_graph_create_svg_context, 
- rl2_graph_create_pdf_context, rl2_graph_set_pen, 
+ rl2_graph_create_pdf_context, rl2_graph_set_solid_pen, rl2_graph_set_dashed_pen,
+ rl2_graph_set_linear_gradient_pen, rl2_graph_set_pattern_pen,
  rl2_graph_set_brush, rl2_graph_set_pattern_brush,
  rl2_graph_set_font
 
@@ -330,21 +556,38 @@ extern "C"
  \param context the pointer to a valid Graphics Context returned by a previous call
  to rl2_graph_create_context(), rl2_graph_create_svg_context() or
  rl2_graph_create_pdf_context()
- \param brush the pointer to a valid Graphics Pattern returned by a previous
+ \param pattern the pointer to a valid Graphics Pattern returned by a previous
  call to rl2_graph_create_pattern().
 
  \return 0 (false) on error, any other value on success.
  
  \sa rl2_graph_create_context, rl2_graph_create_svg_context, 
- rl2_graph_create_pdf_context, rl2_graph_set_pen, 
+ rl2_graph_create_pdf_context, rl2_graph_set_solid_pen, rl2_graph_set_dashed_pen,
  rl2_graph_set_brush, rl2_graph_set_linear_gradient_brush, 
- rl2_graph_set_font, rl2_create_pattern
+ rl2_graph_set_font, rl2_create_pattern, rl2_graph_release_pattern_brush
 
  \note a Brush created by this function always is a Pattern Brush, 
  i.e. a Brush repeatedly using a small bitmap as a filling source.
  */
     RL2_DECLARE int rl2_graph_set_pattern_brush (rl2GraphicsContextPtr context,
-						 rl2GraphicsPatternPtr brush);
+						 rl2GraphicsPatternPtr pattern);
+
+/**
+ Releases the currently set Pattern Brush (if any) from a Graphics Context
+
+ \param context the pointer to a valid Graphics Context returned by a previous call
+ to rl2_graph_create_context(), rl2_graph_create_svg_context() or
+ rl2_graph_create_pdf_context()
+
+ \return 0 (false) on error, any other value on success.
+ 
+ \sa rl2_graph_set_pattern_brush
+
+ \note you should always release a Pattern Brush before attempting to
+ destroy the corresponding Pattern object.
+ */
+    RL2_DECLARE int rl2_graph_release_pattern_brush (rl2GraphicsContextPtr
+						     context);
 
 /**
  Selects the currently set Font for a Graphics Context
@@ -358,24 +601,43 @@ extern "C"
  \return 0 (false) on error, any other value on success.
  
  \sa rl2_graph_create_context, rl2_graph_create_svg_context, 
- rl2_graph_create_pdf_context, rl2_graph_set_pen, rl2_graph_set_brush,
- rl2_graph_set_linear_gradient_brush, rl2_graph_set_pattern_brush,
+ rl2_graph_create_pdf_context, rl2_graph_set_solid_pen, rl2_graph_set_dashed_pen,
+ rl2_graph_set_brush, rl2_graph_set_linear_gradient_brush, rl2_graph_set_pattern_brush,
  rl2_create_font
  */
     RL2_DECLARE int rl2_graph_set_font (rl2GraphicsContextPtr context,
 					rl2GraphicsFontPtr font);
 
 /**
+ Releases the currently set Font out from a Graphics Context
+
+ \param context the pointer to a valid Graphics Context returned by a previous call
+ to rl2_graph_create_context(), rl2_graph_create_svg_context() or
+ rl2_graph_create_pdf_context()
+
+ \return 0 (false) on error, any other value on success.
+ 
+ \sa rl2_graph_set_font, rl2_graph_destroy_font
+ 
+ \note you must always call rl2_graph_release_font() before attempting
+ to destroy a currently selected TrueType Font.
+ */
+    RL2_DECLARE int rl2_graph_release_font (rl2GraphicsContextPtr context);
+
+/**
  Creates a Pattern Brush 
 
  \param rgbaArray pointer to an array of RGBA pixels representing the bitmap
  supporting the Pattern Brush to be created.
  \param width Pattern width (in pixels)
  \param height Pattern height (in pixels)
+ \param extend if TRUE the pattern will be infinitely repeated
+  so to completely fill the plane 
 
  \return the pointer to the corresponding Pattern Brush object: NULL on failure
  
- \sa rl2_graph_set_pattern_brush, rl2_graph_destroy_brush
+ \sa rl2_graph_set_pattern_brush, rl2_graph_destroy_brush,
+ rl2_create_pattern_from_external_graphic, rl2_create_pattern_from_external_svg
  
  \note you are responsible to destroy (before or after) any Pattern Brush
  returned by rl2_graph_create_pattern() by invoking rl2_graph_destroy_pattern().
@@ -383,44 +645,309 @@ extern "C"
     RL2_DECLARE rl2GraphicsPatternPtr rl2_graph_create_pattern (unsigned char
 								*rgbaArray,
 								int width,
-								int height);
+								int height,
+								int extend);
+
+/**
+ Creates a Pattern from an External Graphic resource (PNG, GIF, JPEG)
+
+ \param handle SQLite3 connection handle
+ \param xlink_href unique External Graphic identifier
+ \param extend if TRUE the pattern will be infinitely repeated
+  so to completely fill the plane 
+
+ \return the pointer to the corresponding Pattern Brush object: NULL on failure
+ 
+ \sa rl2_graph_set_pattern_brush, rl2_graph_destroy_brush,
+ rl2_graph_create_pattern, rl2_create_pattern_from_external_svg,
+ rl2_graph_pattern_get_size
+ 
+ \note you are responsible to destroy (before or after) any Pattern Brush
+ returned by rl2_create_pattern_from_external_graphic() by invoking 
+ rl2_graph_destroy_pattern().
+ */
+    RL2_DECLARE rl2GraphicsPatternPtr
+	rl2_create_pattern_from_external_graphic (sqlite3 * handle,
+						  const char *xlink_href,
+						  int extend);
+
+/**
+ Creates a Pattern from an External Graphic resource (SVG)
+
+ \param handle SQLite3 connection handle
+ \param xlink_href unique External Graphic identifier
+ \param size the scaled size of the SVG symbol
+
+ \return the pointer to the corresponding Pattern Brush object: NULL on failure
+ 
+ \sa rl2_graph_set_pattern_brush, rl2_graph_destroy_brush,
+ rl2_graph_create_pattern, rl2_create_pattern_from_external_graphic,
+ rl2_graph_pattern_get_size
+ 
+ \note you are responsible to destroy (before or after) any Pattern Brush
+ returned by rl2_create_pattern_from_external_graphic() by invoking 
+ rl2_graph_destroy_pattern().
+ */
+    RL2_DECLARE rl2GraphicsPatternPtr
+	rl2_create_pattern_from_external_svg (sqlite3 * handle,
+					      const char *xlink_href,
+					      double size);
 
 /**
  Destroys a Pattern Brush object freeing any allocated resource 
 
- \param handle the pointer to a valid Pattern Brush returned by a previous call
- to rl2_graph_create_pattern()
+ \param pattern pointer to a valid Pattern object
  
- \sa rl2_graph_create_pattern
+ \sa rl2_graph_create_pattern, rl2_create_pattern_from_external_graphic
+
+ \note you should always release a Pattern Pen or Pattern Brush from any
+ referencing Graphic Context before attempting to destroy the corresponding
+ Pattern object.
  */
     RL2_DECLARE void rl2_graph_destroy_pattern (rl2GraphicsPatternPtr pattern);
 
 /**
- Creates a Graphics Font Object
+ Retrieving the Dimensions from a Pattern Brush object
+
+ \param pattern pointer to a valid Pattern object
+ \param width on completion the variable referenced by this
+ pointer will contain the Pattern's Width (in pixels).
+ \param height on completion the variable referenced by this
+ pointer will contain the Pattern's Height (in pixels).
+ 
+ \return RL2_OK on success: RL2_ERROR on failure.
+
+ \sa rl2_graph_create_pattern, rl2_create_pattern_from_external_graphic
+ */
+    RL2_DECLARE int rl2_graph_get_pattern_size (rl2GraphicsPatternPtr pattern,
+						unsigned int *width,
+						unsigned int *height);
+
+/**
+ Recolors a Monochrome Pattern object  
+
+ \param handle the pointer to a valid Pattern returned by a previous call
+ to rl2_graph_create_pattern() or rl2_create_pattern_from_external_graphic()
+ \param r the new Red component value to be set
+ \param g the new Green component value
+ \param b the new Blue component value
+ 
+ \return RL2_OK on success: RL2_ERROR on failure. 
+ 
+ \sa rl2_graph_create_pattern, rl2_create_pattern_from_external_graphic,
+ rl2_graph_destroy_pattern, rl2_graph_pattern_transparency,
+ rl2_graph_draw_graphic_symbol
+
+ \note only a Monochrome Pattern can be succesfully recolored.
+ Completely transparent pixels will be ignored; all opaque pixels
+ should declare exactly the same color.
+ */
+    RL2_DECLARE int rl2_graph_pattern_recolor (rl2GraphicsPatternPtr pattern,
+					       unsigned char r, unsigned char g,
+					       unsigned char b);
+
+/**
+ Sets half-transparency for a Pattern object  
+
+ \param handle the pointer to a valid Pattern returned by a previous call
+ to rl2_graph_create_pattern() or rl2_create_pattern_from_external_graphic()
+ \param alpha transparency (0 full transparent; 255 full opaque).
+ 
+ \return RL2_OK on success: RL2_ERROR on failure. 
+ 
+ \sa rl2_graph_create_pattern, rl2_create_pattern_from_external_graphic,
+ rl2_graph_destroy_pattern, rl2_graph_pattern_recolor, 
+ rl2_graph_draw_graphic_symbol
+
+ \note Completely transparent pixels will be always preserved as such; 
+ all other pixels will assume the required transparency.
+ */
+    RL2_DECLARE int rl2_graph_pattern_transparency (rl2GraphicsPatternPtr
+						    pattern,
+						    unsigned char alpha);
+
+/**
+ Draws a Graphic Symbol into the Canvass
 
+ \param context the pointer to a valid Graphics Context (aka Canvass).
+ \param pattern the pointer to a valid  Pattern returned by a previous call
+ \param width of the rendered image.
+ \param height of the rendered image.
+ \param x the X coordinate of the Anchor Point.
+ \param y the Y coordinate of the Anchor Point.
+ \param angle an angle (in decimal degrees) to rotate the image.
+ \param angle an angle (in decimal degrees) to rotate the image.
+ \param anchor_point_x relative X position of the Anchor Point
+  expressed as a percent position within the image bounding box
+  (expected to be a value between 0.0 and 1.0)
+ \param anchor_point_y relative Y position of the Anchor Point
+  expressed as a percent position within the image bounding box
+  (expected to be a value between 0.0 and 1.0)
+
+ \return 0 (false) on error, any other value on success.
+ 
+ \sa rl2_graph_create_pattern, rl2_create_pattern_from_external_graphic,
+ rl2_graph_destroy_pattern, rl2_graph_pattern_transparency, 
+ rl2_graph_pattern_recolor, rl2_graph_draw_mark_symbol
+ */
+    RL2_DECLARE int rl2_graph_draw_graphic_symbol (rl2GraphicsContextPtr
+						   context,
+						   rl2GraphicsPatternPtr
+						   pattern, double width,
+						   double height, double x,
+						   double y, double angle,
+						   double anchor_point_x,
+						   double anchor_point_y);
+
+/**
+ Draws a Mark Symbol into the Canvass
+
+ \param context the pointer to a valid Graphics Context (aka Canvass).
+ \param mark_type expected to be one between RL2_GRAPHIC_MARK_SQUARE,
+  RL2_GRAPHIC_MARK_CIRCLE, RL2_GRAPHIC_MARK_TRIANGLE, 
+  RL2_GRAPHIC_MARK_STAR, RL2_GRAPHIC_MARK_CROSS and RL2_GRAPHIC_MARK_X 
+  (default: RL2_GRAPHIC_MARK_SQUARE).
+ \param size the Mark Symbol size (in pixels).
+ \param x the X coordinate of the Anchor Point.
+ \param y the Y coordinate of the Anchor Point.
+ \param angle an angle (in decimal degrees) to rotate the image.
+ \param angle an angle (in decimal degrees) to rotate the image.
+ \param anchor_point_x relative X position of the Anchor Point
+  expressed as a percent position within the image bounding box
+  (expected to be a value between 0.0 and 1.0)
+ \param anchor_point_y relative Y position of the Anchor Point
+  expressed as a percent position within the image bounding box
+  (expected to be a value between 0.0 and 1.0)
+ \param fill if TRUE the Mark Symboll will be filled using the
+  currently set brush
+ \param stroke if TRUE the Mark Symboll will be stroked using
+  the currently set pen
+
+ \return 0 (false) on error, any other value on success.
+ 
+ \sa rl2_graph_draw_graphic_symbol
+ */
+    RL2_DECLARE int rl2_graph_draw_mark_symbol (rl2GraphicsContextPtr
+						context, int mark_type,
+						double size,
+						double x, double y,
+						double angle,
+						double anchor_point_x,
+						double anchor_point_y, int fill,
+						int stroke);
+
+/**
+ Creates a Graphics Font Object (CAIRO built-in "toy" fonts)
+
+ \param facename the font Facename. Expected to be one of "serif", 
+ "sans-serif" or "monospace". a NULL facename will default to "monospace".
  \param size the Graphics Font size (in points).
- \param style one of RL2_FONTSTYLE_NORMAL or RL2_FONTSTYLE_ITALIC
+ \param style one of RL2_FONTSTYLE_NORMAL, RL2_FONTSTYLE_ITALIC or
+ RL2_FONTSTYLE_OBLIQUE
  \param weight one of RL2_FONTWEIGHT_NORMAL or RL2_FONTWEIGHT_BOLD
 
  \return the pointer to the corresponding Font object: NULL on failure
  
- \sa rl2_graph_set_font, rl2_graph_destroy_font, rl2_graph_font_set_color,
- rl2_graph_font_set_color, rl2_graph_font_set_outline
+ \sa rl2_graph_set_font, 
+ rl2_graph_destroy_font, rl2_graph_font_set_color,
+ rl2_graph_font_set_color, rl2_graph_font_set_halo
  
  \note you are responsible to destroy (before or after) any Pattern Brush
- returned by rl2_graph_create_font() by invoking rl2_graph_destroy_font().
+ returned by rl2_graph_create_toy_font() by invoking rl2_graph_destroy_font().
+ */
+    RL2_DECLARE rl2GraphicsFontPtr rl2_graph_create_toy_font (const char
+							      *facename,
+							      double size,
+							      int style,
+							      int weight);
+
+/**
+ Will retrieve a BLOB-encoded TrueType Font by its FaceName
+ 
+ \param handle SQLite3 connection handle
+ \param fontname name of the required font: e.g. "Roboto-BoldItalic"
+ \param font on completion this variable will point to the a memory block 
+  containing the BLOB-encoded TrueType font (may be NULL if any error occurred).
+ \param font_sz on completion this variable will contain the size (in bytes)
+ of the memory block containing the BLOB-encoded TrueType font.
+ 
+ \return RL2_OK on success; RL2_ERROR if any error is encountered (this
+ including requesting a not existing TrueType font).
+ 
+ \note you are responsible to free (before or after) the BLOB-encode
+ font returned by rl2_get_TrueType_font()
+ */
+
+    RL2_DECLARE int rl2_get_TrueType_font (sqlite3 * handle,
+					   const char *facename,
+					   unsigned char **font, int *font_sz);
+
+/**
+ Creates a Graphics Font Object (TrueType fonts)
+
+ \param priv_data pointer to the opaque internal connection object 
+ returned by a previous call to rl2_alloc_private() 
+ \param ttf the TrueType font definition (internal BLOB format).
+ \param ttf_bytes length (in bytes) of the above TTF definition
+ \param size the Graphics Font size (in points).
+
+ \return the pointer to the corresponding Font object: NULL on failure
+ 
+ \sa rl2_graph_create_toy_font, rl2_get_TrueType_font, 
+ rl2_search_TrueType_font, rl2_graph_set_font, rl2_graph_destroy_font, 
+ rl2_graph_font_set_color, rl2_graph_font_set_color, 
+ rl2_graph_font_set_halo
+ 
+ \note you are responsible to destroy (before or after) any TrueType
+ font returned by rl2_graph_create_TrueType_font() by invoking 
+ rl2_graph_destroy_font().
  */
-    RL2_DECLARE rl2GraphicsFontPtr rl2_graph_create_font (double size,
-							  int style,
-							  int weight);
+    RL2_DECLARE rl2GraphicsFontPtr rl2_graph_create_TrueType_font (const void
+								   *priv_data,
+								   const
+								   unsigned char
+								   *ttf,
+								   int
+								   ttf_bytes,
+								   double size);
+
+/**
+ Searches and creates a Graphics Font Object (TrueType fonts)
+
+ \param handle SQLite3 connection handle
+ \param priv_data pointer to the opaque internal connection object 
+ returned by a previous call to rl2_alloc_private() 
+ \param fontname name of the required font: e.g. "Roboto-BoldItalic"
+ \param size the Graphics Font size (in points).
+
+ \return the pointer to the corresponding Font object: NULL on failure
+ 
+ \sa rl2_graph_create_toy_font, rl2_get_TrueType_font, 
+ rl2_graph_create_TrueType_font, rl2_graph_set_font, 
+ rl2_graph_destroy_font, rl2_graph_font_set_color,
+ rl2_graph_font_set_color, rl2_graph_font_set_halo
+ 
+ \note you are responsible to destroy (before or after) any TrueType
+ font returned by rl2_search_TrueType_font() by invoking 
+ rl2_graph_destroy_font().
+ */
+    RL2_DECLARE rl2GraphicsFontPtr rl2_search_TrueType_font (sqlite3 * handle,
+							     const void
+							     *priv_data,
+							     const char
+							     *facename,
+							     double size);
 
 /**
  Destroys a Graphics Font object freeing any allocated resource 
 
  \param handle the pointer to a valid Font returned by a previous call
- to rl2_graph_create_font()
+ to rl2_graph_create_toy_font() or rl2_graph_create_TrueType_font()
+ 
+ \sa rl2_graph_create_toy_font, rl2_graph_create_TrueType_font
  
- \sa rl2_graph_create_font
+ \note you must always call rl2_graph_release_font() before attempting
+ to destroy the currently selected font if it is of the TrueType class.
  */
     RL2_DECLARE void rl2_graph_destroy_font (rl2GraphicsFontPtr font);
 
@@ -428,7 +955,7 @@ extern "C"
  Selects the currently set Color for a Graphics Font
 
  \param font the pointer to a valid Graphics Font returned by a previous call
- to rl2_graph_create_font()
+ to rl2_graph_create_toy_font() or rl2_graph_create_TrueType_font()
  \param red Font color: red component.
  \param green Font color: green component.
  \param blue Font color: blue component.
@@ -436,8 +963,8 @@ extern "C"
 
  \return 0 (false) on error, any other value on success.
  
- \sa rl2_graph_create_font, rl2_graph_font_set_outline,
- rl2_graph_set_font
+ \sa rl2_graph_create_toy_font, rl2_graph_create_TrueType_font,
+ rl2_graph_font_set_halo, rl2_graph_set_font
  */
     RL2_DECLARE int rl2_graph_font_set_color (rl2GraphicsFontPtr font,
 					      unsigned char red,
@@ -446,20 +973,28 @@ extern "C"
 					      unsigned char alpha);
 
 /**
- Selects the currently set Outline for a Graphics Font
+ Selects the currently set Halo for a Graphics Font
 
  \param font the pointer to a valid Graphics Font returned by a previous call
- to rl2_graph_create_font()
- \param width the outline width (in points); declaring a zero or negative value
- will remove any outline from the Font.
+ to rl2_graph_create_toy_font() or rl2_graph_create_TrueType_font()
+ \param radius the Halo Radius (in points); declaring a zero or negative value
+ will remove the Halo from the Font.
+ \param red Halo color: red component.
+ \param green Halo color: green component.
+ \param blue Halo color: blue component.
+ \param alpha Halo transparency (0 full transparent; 255 full opaque).
 
  \return 0 (false) on error, any other value on success.
  
- \sa rl2_graph_create_font, rl2_graph_font_set_color,
- rl2_graph_set_font
+ \sa rl2_graph_create_toy_font, rl2_graph_create_TrueType_font, 
+ rl2_graph_font_set_color, rl2_graph_set_font
  */
-    RL2_DECLARE int rl2_graph_font_set_outline (rl2GraphicsFontPtr font,
-						double width);
+    RL2_DECLARE int rl2_graph_font_set_halo (rl2GraphicsFontPtr font,
+					     double radius,
+					     unsigned char red,
+					     unsigned char green,
+					     unsigned char blue,
+					     unsigned char alpha);
 
 /**
  Creates a Graphics Bitmap 
@@ -501,9 +1036,9 @@ extern "C"
 
  \return 0 (false) on error, any other value on success.
  
- \sa rl2_graph_set_pen, rl2_graph_set_brush, rl2_graph, draw_rectangle,
- rl2_graph_draw_ellipse, rl2_graph_draw_circle_sector, rl2_graph_stroke_line, 
- rl2_graph_fill_path, rl2_graph_stroke_path
+ \sa rl2_graph_set_solid_pen, rl2_graph_set_dashed_pen, rl2_graph_set_brush,
+ rl2_graph, draw_rectangle, rl2_graph_draw_ellipse, rl2_graph_draw_circle_sector, 
+ rl2_graph_stroke_line, rl2_graph_fill_path, rl2_graph_stroke_path
 
  \note the rectangle will be stroked using the current Pen and will
  be filled using the current Brush.
@@ -524,9 +1059,9 @@ extern "C"
 
  \return 0 (false) on error, any other value on success.
  
- \sa rl2_graph_set_pen, rl2_graph_set_brush, rl2_draw_rectangle,
- rl2_graph_draw_ellipse, rl2_graph_draw_circle_sector, rl2_graph_stroke_line, 
- rl2_graph_fill_path, rl2_graph_stroke_path
+ \sa rl2_graph_set_solid_pen, rl2_graph_set_dashed_pen, rl2_graph_set_brush,
+ rl2_draw_rectangle, rl2_graph_draw_ellipse, rl2_graph_draw_circle_sector, 
+ rl2_graph_stroke_line, rl2_graph_fill_path, rl2_graph_stroke_path
 
  \note the rectangle will be stroked using the current Pen and will
  be filled using the current Brush.
@@ -549,8 +1084,8 @@ extern "C"
 
  \return 0 (false) on error, any other value on success.
  
- \sa rl2_graph_set_pen, rl2_graph_set_brush, rl2_draw_rectangle,
- rl2_graph_draw_rounded_rectangle, rl2_graph_draw_circle_sector, 
+ \sa rl2_graph_set_solid_pen, rl2_graph_set_dashed_pen, rl2_graph_set_brush, 
+ rl2_draw_rectangle, rl2_graph_draw_rounded_rectangle, rl2_graph_draw_circle_sector, 
  rl2_graph_stroke_line, rl2_graph_fill_path, rl2_graph_stroke_path
 
  \note the ellipse will be stroked using the current Pen and will
@@ -572,8 +1107,8 @@ extern "C"
 
  \return 0 (false) on error, any other value on success.
  
- \sa rl2_graph_set_pen, rl2_graph_set_brush, rl2_draw_rectangle,
- rl2_graph_draw_rounded_rectangle, rl2_graph_draw_ellipse, 
+ \sa rl2_graph_set_solid_pen, rl2_graph_set_dashed_pen, rl2_graph_set_brush, 
+ rl2_draw_rectangle, rl2_graph_draw_rounded_rectangle, rl2_graph_draw_ellipse, 
  rl2_graph_stroke_line, rl2_graph_fill_path, rl2_graph_stroke_path
 
  \note the Sector will be stroked using the current Pen and will
@@ -597,8 +1132,8 @@ extern "C"
 
  \return 0 (false) on error, any other value on success.
  
- \sa rl2_graph_set_pen, rl2_graph_set_brush, rl2_draw_rectangle,
- rl2_graph_draw_rounded_rectangle, rl2_graph_draw_ellipse, 
+ \sa rl2_graph_set_solid_pen, rl2_graph_set_dashed_pen, rl2_graph_set_brush, 
+ rl2_draw_rectangle, rl2_graph_draw_rounded_rectangle, rl2_graph_draw_ellipse, 
  rl2_graph_draw_circular_sector, rl2_graph_fill_path, rl2_graph_stroke_path
 
  \note the Sector will be stroked using the current Pen and will
@@ -617,7 +1152,7 @@ extern "C"
 
  \return 0 (false) on error, any other value on success.
  
- \sa rl2_graph_set_pen, rl2_graph_set_brush, rl2_graph_add_line_to_path,
+ \sa rl2_graph_add_line_to_path,
  rl2_graph_close_subpath, rl2_graph_fill_path, rl2_graph_stroke_path
  */
     RL2_DECLARE int rl2_graph_move_to_point (rl2GraphicsContextPtr context,
@@ -632,7 +1167,7 @@ extern "C"
 
  \return 0 (false) on error, any other value on success.
  
- \sa rl2_graph_set_pen, rl2_graph_set_brush, rl2_graph_move_to_point,
+ \sa rl2_graph_set_brush, rl2_graph_move_to_point,
  rl2_graph_close_subpath, rl2_graph_fill_path, rl2_graph_stroke_path
  */
     RL2_DECLARE int rl2_graph_add_line_to_path (rl2GraphicsContextPtr context,
@@ -645,7 +1180,7 @@ extern "C"
 
  \return 0 (false) on error, any other value on success.
  
- \sa rl2_graph_set_pen, rl2_graph_set_brush, rl2_graph_move_to_point,
+ \sa rl2_graph_set_brush, rl2_graph_move_to_point,
  rl2_graph_add_line_to_path, rl2_graph_fill_path, rl2_graph_stroke_path
  */
     RL2_DECLARE int rl2_graph_close_subpath (rl2GraphicsContextPtr context);
@@ -659,7 +1194,7 @@ extern "C"
 
  \return 0 (false) on error, any other value on success.
  
- \sa rl2_graph_set_pen, rl2_graph_set_brush, rl2_graph_move_to_point,
+ \sa rl2_graph_set_brush, rl2_graph_move_to_point,
  rl2_graph_add_line_to_path, rl2_graph_close_subpath, rl2_graph_stroke_path
  */
     RL2_DECLARE int rl2_graph_fill_path (rl2GraphicsContextPtr context,
@@ -674,7 +1209,7 @@ extern "C"
 
  \return 0 (false) on error, any other value on success.
  
- \sa rl2_graph_set_pen, rl2_graph_set_brush, rl2_graph_move_to_point,
+ \sa rl2_graph_set_solid_pen, rl2_graph_set_dashed_pen, rl2_graph_move_to_point,
  rl2_graph_add_line_to_path, rl2_graph_close_subpath, rl2_graph_fill_path
  */
     RL2_DECLARE int rl2_graph_stroke_path (rl2GraphicsContextPtr context,
@@ -687,15 +1222,57 @@ extern "C"
  \param text string to be printed into the canvass.
  \param x the X coordinate of the top left corner of the text.
  \param y the Y coordinate of the top left corner of the text.
- \param angle an angle (in degrees) to rotate the text
+ \param angle an angle (in decimal degrees) to rotate the text.
+ \param anchor_point_x relative X position of the Anchor Point
+  expressed as a percent position within the text bounding box
+  (expected to be a value between 0.0 and 1.0)
+ \param anchor_point_y relative Y position of the Anchor Point
+  expressed as a percent position within the text bounding box
+  (expected to be a value between 0.0 and 1.0)
 
  \return 0 (false) on error, any other value on success.
  
- \sa rl2_graph_set_font, rl2_graph_get_text_extent
+ \sa rl2_graph_set_font, rl2_graph_get_text_extent,
+ rl2_graph_draw_warped_text
  */
     RL2_DECLARE int rl2_graph_draw_text (rl2GraphicsContextPtr context,
 					 const char *text, double x, double y,
-					 double angle);
+					 double angle,
+					 double anchor_point_x,
+					 double anchor_point_y);
+
+/**
+ Draws a text warped along a curve using the currently set Font
+
+ \param handle connection handle
+ \param context the pointer to a valid Graphics Context (aka Canvass).
+ \param text string to be printed into the canvass.
+ \param points number of item in both X and Y arrays
+ \param x array of X coordinates.
+ \param y array of Y coordinates; both X and Y arrays represent
+  the curve modelling the text to be warped. 
+ \param initial_gap white space to be preserved before printing
+ the first label occurrence.
+ \param gap distance separating two cosecutive label occurrences.
+ (both initial_gap and gap are only meaningfull in the repeated case).
+ \param repeated if TRUE the text (aka label) will be repeated
+  as many times as allowed by the modelling curve lenght.
+  If FALSE the text (aka label) will be printed only once near
+  the mid-point of the modelling curve.
+
+ \return 0 (false) on error, any other value on success.
+ 
+ \sa rl2_graph_set_font, rl2_graph_draw_text
+ 
+ \note if the modelling curve length is shorter than the text
+ (aka label) length then no output at all will be printed.
+ */
+    RL2_DECLARE int rl2_graph_draw_warped_text (sqlite3 * handle,
+						rl2GraphicsContextPtr context,
+						const char *text, int points,
+						double *x, double *y,
+						double initial_gap, double gap,
+						int repeated);
 
 /**
  Computes the extent corresponding to a text into the Canvass using the currently set Font
@@ -730,39 +1307,41 @@ extern "C"
 
  \param context the pointer to a valid Graphics Context (aka Canvass).
  \param bitmap the pointer to a valid Graphics Bitmap to be rendered.
- \param x the X coordinate of the top left corner of the image.
- \param y the Y coordinate of the top left corner of the image.
+ \param x the X coordinate of the image's left upper corner.
+ \param y the Y coordinate of the image's left upper corner.
 
  \return 0 (false) on error, any other value on success.
  
  \sa rl2_graph_create_bitmap, rl2_graph_destroy_bitmap,
- rl2_graph_draw_rescaled_bitmap
+ rl2_graph_draw_rescaled_bitmap, rl2_graph_draw_graphic_symbol, 
+ rl2_graph_draw_mark_symbol
  */
     RL2_DECLARE int rl2_graph_draw_bitmap (rl2GraphicsContextPtr context,
-					   rl2GraphicsBitmapPtr bitmap, int x,
-					   int y);
+					   rl2GraphicsBitmapPtr bitmap,
+					   double x, double y);
 
 /**
  Draws a Rescaled Bitmap into the Canvass
 
  \param context the pointer to a valid Graphics Context (aka Canvass).
  \param bitmap the pointer to a valid Graphics Bitmap to be rendered.
- \param scale_x the Scale Factor for X axis
- \param scale_y the Scale Factor for Y axis
- \param x the X coordinate of the top left corner of the image.
- \param y the Y coordinate of the top left corner of the image.
+ \param scale_x the Scale Factor for X axis.
+ \param scale_y the Scale Factor for Y axis.
+ \param x the X coordinate of the image's left upper corner.
+ \param y the Y coordinate of the image's left upper corner.
 
  \return 0 (false) on error, any other value on success.
  
  \sa rl2_graph_create_bitmap, rl2_graph_destroy_bitmap,
- rl2_graph_draw_bitmap
+ rl2_graph_draw_bitmap, rl2_graph_draw_graphic_symbol, 
+ rl2_graph_draw_mark_symbol
  */
     RL2_DECLARE int rl2_graph_draw_rescaled_bitmap (rl2GraphicsContextPtr
 						    context,
 						    rl2GraphicsBitmapPtr bitmap,
 						    double scale_x,
-						    double scale_y, int x,
-						    int y);
+						    double scale_y, double x,
+						    double y);
 
 /**
  Creates an RGB Array corresponding to the current Canvass
@@ -783,6 +1362,9 @@ extern "C"
  Creates an Array of Alpha values corresponding to the current Canvass
 
  \param context the pointer to a valid Graphics Context (aka Canvass).
+ \param half_transparent after successful completion this variable will
+ ontain 1 or 0, accordingly to the presence of half-transparencies 
+ strictly requiring an alpha band.
 
  \return the pointer to the Array of Alpha Values: NULL on failure.
  
@@ -792,7 +1374,8 @@ extern "C"
  returned by rl2_graph_get_context_alpha_array() by invoking free().
  */
     RL2_DECLARE unsigned char
-	*rl2_graph_get_context_alpha_array (rl2GraphicsContextPtr context);
+	*rl2_graph_get_context_alpha_array (rl2GraphicsContextPtr context,
+					    int *half_transparent);
 
 #ifdef __cplusplus
 }
diff --git a/headers/rasterlite2/rl2tiff.h b/headers/rasterlite2/rl2tiff.h
index f96d292..d412004 100644
--- a/headers/rasterlite2/rl2tiff.h
+++ b/headers/rasterlite2/rl2tiff.h
@@ -142,7 +142,7 @@ extern "C"
     RL2_DECLARE int
 	rl2_eval_tiff_origin_compatibility (rl2CoveragePtr cvg,
 					    rl2TiffOriginPtr tiff,
-					    int forced_srid);
+					    int forced_srid, int verbose);
 
     RL2_DECLARE int rl2_is_tiled_tiff_origin (rl2TiffOriginPtr tiff,
 					      int *is_tiled);
@@ -160,7 +160,8 @@ extern "C"
 	rl2_get_tile_from_tiff_origin (rl2CoveragePtr cvg,
 				       rl2TiffOriginPtr tiff,
 				       unsigned int startRow,
-				       unsigned int startCol, int force_srid);
+				       unsigned int startCol, int force_srid,
+				       int verbose);
 
     RL2_DECLARE rl2TiffDestinationPtr
 	rl2_create_tiff_destination (const char *path, unsigned int width,
@@ -282,6 +283,7 @@ extern "C"
 	rl2_raster_to_tiff_mono4 (rl2RasterPtr rst, unsigned char **tiff,
 				  int *tiff_size);
 
+    RL2_DECLARE char *rl2_build_tiff_xml_summary (rl2TiffOriginPtr tiff);
 
 #ifdef __cplusplus
 }
diff --git a/headers/rasterlite2/rl2wms.h b/headers/rasterlite2/rl2wms.h
index 19e98db..5bad253 100644
--- a/headers/rasterlite2/rl2wms.h
+++ b/headers/rasterlite2/rl2wms.h
@@ -1885,7 +1885,7 @@ extern "C"
  \param handle the pointer to a valid WMS-FeatureCollection returned by a previous call
  to do_wms_GetFeatureInfo_get() or do_wms_GetFeatureInfo_post()
  \param index the relative index identifying the required Attribute (the first 
- Attribute supported by a WMS-FeatureMember object has index ZERO). 
+ Attribute supported by a WMS-FeatureMember object has index ZERO).
 
  \return a pointer the Nth AttributeValue string of some WMS-FeatureMember object:
  NULL if any error occurs. (please note: an AttributeValue could eventually correspond
@@ -1902,17 +1902,18 @@ extern "C"
 					  int index);
 
 /**
- Return a pointer to a SpatiaLite's own Geometry object corresponding to the Nth AttributeValue 
- from within some WMS-FeatureMember object
+ Retrieves a SpatiaLite's BLOB binery geometry corresponding to the Nth
+ AttributeValue from within some WMS-FeatureMember object
 
  \param handle the pointer to a valid WMS-FeatureCollection returned by a previous call
  to do_wms_GetFeatureInfo_get() or do_wms_GetFeatureInfo_post()
  \param index the relative index identifying the required Attribute (the first 
  Attribute supported by a WMS-FeatureMember object has index ZERO). 
+ \param blob on completion will point to the BLOB binary Geometry.
+ \param blob_soze on completion the variable referenced by this
+ pointer will contain the size (in bytes) of BLOB. Geometry.
 
- \return a pointer the Nth AttributeValue of some WMS-FeatureMember object if it actually
- corresponds to some GML Geometry:
- NULL if any error occurs or if the AttributeValue isn't a GML Geometry. 
+ \return RL2_OK on success: RL2_ERROR on failure.
  
  \sa do_wms_GetFeatureInfo_get, do_wms_GetFeatureInfo_post,
  destroy_wms_feature_collection, wms_feature_collection_parse_geometries, 
@@ -1920,12 +1921,14 @@ extern "C"
  get_wms_feature_attributes_count, get_wms_feature_attribute_name, 
  get_wms_feature_attribute_value
 
- \note the returned Geometry object simply is a reference, and this must
- absolutely not be destroyed by directly calling gaiaFreeGeomColl().
+ \note the returned BLOB Geometry simply is a reference, and must
+ absolutely not be destroyed by directly calling free().
  */
-    RL2_DECLARE gaiaGeomCollPtr
-	get_wms_feature_attribute_geometry (rl2WmsFeatureMemberPtr handle,
-					    int index);
+    RL2_DECLARE int
+	get_wms_feature_attribute_blob_geometry (rl2WmsFeatureMemberPtr handle,
+						 int index,
+						 const unsigned char **blob,
+						 int *blob_size);
 
 #ifdef __cplusplus
 }
diff --git a/headers/rasterlite2/sqlite.h b/headers/rasterlite2/sqlite.h
index 6b99d13..b7292c9 100644
--- a/headers/rasterlite2/sqlite.h
+++ b/headers/rasterlite2/sqlite.h
@@ -19,7 +19,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
diff --git a/headers/rasterlite2_private.h b/headers/rasterlite2_private.h
index 6ceb6c6..072e7bd 100644
--- a/headers/rasterlite2_private.h
+++ b/headers/rasterlite2_private.h
@@ -99,6 +99,14 @@ extern "C"
 {
 #endif
 
+/* macro handling X,Y coordinates */
+#define rl2GetPoint(xy,v,x,y)	\
+				{*x = xy[(v) * 2]; \
+				 *y = xy[(v) * 2 + 1];}
+#define rl2SetPoint(xy,v,x,y)	\
+				{xy[(v) * 2] = x; \
+				 xy[(v) * 2 + 1] = y;}
+
 /* internal binary format markers */
 #define RL2_ODD_BLOCK_START			0xfa
 #define RL2_ODD_BLOCK_END			0xf0
@@ -122,6 +130,10 @@ extern "C"
 #define RL2_NO_DATA_END				0x23
 #define RL2_SAMPLE_START			0x06
 #define RL2_SAMPLE_END				0x26
+#define RL2_CHARLS_START			0x35
+#define RL2_CHARLS_END				0x79
+#define RL2_FONT_START				0xa7
+#define RL2_FONT_END				0x7b
 
 /* internal ColorSpace forced conversions */
 #define RL2_CONVERT_NO				0x00
@@ -189,10 +201,64 @@ extern "C"
 #define RL2_CONVERT_GRID_DOUBLE_TO_INT32	0x3e
 #define RL2_CONVERT_GRID_DOUBLE_TO_FLOAT	0x3f
 
-/* internal RasterStyle constants */
+/* internal Style Rule constants */
+#define RL2_UNKNOWN_STYLE			0xf0
+#define RL2_VECTOR_STYLE			0xfa
+#define RL2_RASTER_STYLE			0xfb
+
+/* internal Graphic types */
+#define RL2_UNKNOWN_GRAPHIC			0x8a
+#define RL2_EXTERNAL_GRAPHIC			0x8c
+#define RL2_MARK_GRAPHIC			0x8d
+
+/* internal Style Rule comparison Ops */
+#define RL2_COMPARISON_NONE			0xa0
+#define RL2_COMPARISON_EQ			0xa1
+#define RL2_COMPARISON_NE			0xa2
+#define RL2_COMPARISON_LT			0xa3
+#define RL2_COMPARISON_GT			0xa4
+#define RL2_COMPARISON_LE			0xa5
+#define RL2_COMPARISON_GE			0xa6
+#define RL2_COMPARISON_LIKE			0xa7
+#define RL2_COMPARISON_NULL			0xa8
+#define RL2_COMPARISON_BETWEEN			0xa9
+
+/* internal RasterSymbolizer constants */
 #define RL2_BAND_SELECTION_TRIPLE		0xd1
 #define RL2_BAND_SELECTION_MONO			0xd2
 
+/* internal TextSymbolizer constants */
+#define RL2_MAX_FONT_FAMILIES	16
+
+/* internal origin type constants */
+#define RL2_ORIGIN_UNKNOWN		0x4a
+#define RL2_ORIGIN_JPEG			0x4b
+#define RL2_ORIGIN_JPEG2000		0x4c
+#define RL2_ORIGIN_ASCII_GRID	0x4d
+#define RL2_ORIGIN_RAW			0x4e
+#define RL2_ORIGIN_TIFF			0x4f
+
+
+    struct rl2_private_tt_font
+    {
+	char *facename;
+	int is_bold;
+	int is_italic;
+	struct rl2_private_data *container;
+	void *FTface;
+	void *ttf_data;
+	struct rl2_private_tt_font *prev;
+	struct rl2_private_tt_font *next;
+    };
+
+    struct rl2_private_data
+    {
+	int max_threads;
+	void *FTlibrary;
+	struct rl2_private_tt_font *first_font;
+	struct rl2_private_tt_font *last_font;
+    };
+
     typedef union rl2_priv_sample
     {
 	char int8;
@@ -247,6 +313,7 @@ extern "C"
 	double vResolution;
 	unsigned char *rasterBuffer;
 	unsigned char *maskBuffer;
+	int alpha_mask;
 	rl2PrivPalettePtr Palette;
 	rl2PrivPixelPtr noData;
     } rl2PrivRaster;
@@ -285,9 +352,24 @@ extern "C"
 	double hResolution;
 	double vResolution;
 	rl2PrivPixelPtr noData;
+	int strictResolution;
+	int mixedResolutions;
+	int sectionPaths;
+	int sectionMD5;
+	int sectionSummary;
     } rl2PrivCoverage;
     typedef rl2PrivCoverage *rl2PrivCoveragePtr;
 
+    typedef struct rl2_priv_vector_layer
+    {
+	char *f_table_name;
+	char *f_geometry_column;
+	unsigned short geometry_type;
+	int srid;
+	unsigned char spatial_index;
+    } rl2PrivVectorLayer;
+    typedef rl2PrivVectorLayer *rl2PrivVectorLayerPtr;
+
     typedef struct rl2_priv_tiff_origin
     {
 	char *path;
@@ -528,11 +610,8 @@ extern "C"
     } rl2PrivColorMapInterpolate;
     typedef rl2PrivColorMapInterpolate *rl2PrivColorMapInterpolatePtr;
 
-    typedef struct rl2_priv_raster_style
+    typedef struct rl2_priv_raster_symbolizer
     {
-	char *name;
-	char *title;
-	char *abstract;
 	double opacity;
 	unsigned char contrastEnhancement;
 	double gammaValue;
@@ -542,8 +621,238 @@ extern "C"
 	int shadedRelief;
 	int brightnessOnly;
 	double reliefFactor;
-    } rl2PrivRasterStyle;
-    typedef rl2PrivRasterStyle *rl2PrivRasterStylePtr;
+    } rl2PrivRasterSymbolizer;
+    typedef rl2PrivRasterSymbolizer *rl2PrivRasterSymbolizerPtr;
+
+    typedef struct rl2_priv_color_replacement
+    {
+	int index;
+	unsigned char red;
+	unsigned char green;
+	unsigned char blue;
+	struct rl2_priv_color_replacement *next;
+    } rl2PrivColorReplacement;
+    typedef rl2PrivColorReplacement *rl2PrivColorReplacementPtr;
+
+    typedef struct rl2_priv_external_graphic
+    {
+	char *xlink_href;
+	rl2PrivColorReplacementPtr first;
+	rl2PrivColorReplacementPtr last;
+    } rl2PrivExternalGraphic;
+    typedef rl2PrivExternalGraphic *rl2PrivExternalGraphicPtr;
+
+    typedef struct rl2_priv_mark
+    {
+	unsigned char well_known_type;
+	rl2PrivExternalGraphicPtr external_graphic;
+	struct rl2_priv_stroke *stroke;
+	struct rl2_priv_fill *fill;
+    } rl2PrivMark;
+    typedef rl2PrivMark *rl2PrivMarkPtr;
+
+    typedef struct rl2_priv_graphic_item
+    {
+	unsigned char type;
+	void *item;
+	struct rl2_priv_graphic_item *next;
+    } rl2PrivGraphicItem;
+    typedef rl2PrivGraphicItem *rl2PrivGraphicItemPtr;
+
+    typedef struct rl2_priv_graphic
+    {
+	rl2PrivGraphicItemPtr first;
+	rl2PrivGraphicItemPtr last;
+	double opacity;
+	double size;
+	double rotation;
+	double anchor_point_x;
+	double anchor_point_y;
+	double displacement_x;
+	double displacement_y;
+    } rl2PrivGraphic;
+    typedef rl2PrivGraphic *rl2PrivGraphicPtr;
+
+    typedef struct rl2_priv_stroke
+    {
+	rl2PrivGraphicPtr graphic;
+	unsigned char red;
+	unsigned char green;
+	unsigned char blue;
+	double opacity;
+	double width;
+	unsigned char linejoin;
+	unsigned char linecap;
+	int dash_count;
+	double *dash_list;
+	double dash_offset;
+    } rl2PrivStroke;
+    typedef rl2PrivStroke *rl2PrivStrokePtr;
+
+    typedef struct rl2_priv_fill
+    {
+	rl2PrivGraphicPtr graphic;
+	unsigned char red;
+	unsigned char green;
+	unsigned char blue;
+	double opacity;
+    } rl2PrivFill;
+    typedef rl2PrivFill *rl2PrivFillPtr;
+
+    typedef struct rl2_priv_point_symbolizer
+    {
+	rl2PrivGraphicPtr graphic;
+    } rl2PrivPointSymbolizer;
+    typedef rl2PrivPointSymbolizer *rl2PrivPointSymbolizerPtr;
+
+    typedef struct rl2_priv_line_symbolizer
+    {
+	rl2PrivStrokePtr stroke;
+	double perpendicular_offset;
+    } rl2PrivLineSymbolizer;
+    typedef rl2PrivLineSymbolizer *rl2PrivLineSymbolizerPtr;
+
+    typedef struct rl2_priv_polygon_symbolizer
+    {
+	rl2PrivStrokePtr stroke;
+	rl2PrivFillPtr fill;
+	double displacement_x;
+	double displacement_y;
+	double perpendicular_offset;
+    } rl2PrivPolygonSymbolizer;
+    typedef rl2PrivPolygonSymbolizer *rl2PrivPolygonSymbolizerPtr;
+
+    typedef struct rl2_priv_point_placement
+    {
+	double anchor_point_x;
+	double anchor_point_y;
+	double displacement_x;
+	double displacement_y;
+	double rotation;
+    } rl2PrivPointPlacement;
+    typedef rl2PrivPointPlacement *rl2PrivPointPlacementPtr;
+
+    typedef struct rl2_priv_line_placement
+    {
+	double perpendicular_offset;
+	int is_repeated;
+	double initial_gap;
+	double gap;
+	int is_aligned;
+	int generalize_line;
+    } rl2PrivLinePlacement;
+    typedef rl2PrivLinePlacement *rl2PrivLinePlacementPtr;
+
+    typedef struct rl2_priv_halo
+    {
+	double radius;
+	rl2PrivFillPtr fill;
+    } rl2PrivHalo;
+    typedef rl2PrivHalo *rl2PrivHaloPtr;
+
+    typedef struct rl2_priv_text_symbolizer
+    {
+	char *label;
+	int font_families_count;
+	char *font_families[RL2_MAX_FONT_FAMILIES];
+	unsigned char font_style;
+	unsigned char font_weight;
+	double font_size;
+	unsigned char label_placement_type;
+	void *label_placement;
+	rl2PrivHaloPtr halo;
+	rl2PrivFillPtr fill;
+    } rl2PrivTextSymbolizer;
+    typedef rl2PrivTextSymbolizer *rl2PrivTextSymbolizerPtr;
+
+    typedef struct rl2_priv_vector_symbolizer_item
+    {
+	unsigned char symbolizer_type;
+	void *symbolizer;
+	struct rl2_priv_vector_symbolizer_item *next;
+    } rl2PrivVectorSymbolizerItem;
+    typedef rl2PrivVectorSymbolizerItem *rl2PrivVectorSymbolizerItemPtr;
+
+    typedef struct rl2_priv_vector_symbolizer
+    {
+	rl2PrivVectorSymbolizerItemPtr first;
+	rl2PrivVectorSymbolizerItemPtr last;
+    } rl2PrivVectorSymbolizer;
+    typedef rl2PrivVectorSymbolizer *rl2PrivVectorSymbolizerPtr;
+
+    typedef struct rl2_priv_rule_single_arg
+    {
+	char *value;
+    } rl2PrivRuleSingleArg;
+    typedef rl2PrivRuleSingleArg *rl2PrivRuleSingleArgPtr;
+
+    typedef struct rl2_priv_rule_like_args
+    {
+	char *wild_card;
+	char *single_char;
+	char *escape_char;
+	char *value;
+    } rl2PrivRuleLikeArgs;
+    typedef rl2PrivRuleLikeArgs *rl2PrivRuleLikeArgsPtr;
+
+    typedef struct rl2_priv_rule_between_args
+    {
+	char *lower;
+	char *upper;
+    } rl2PrivRuleBetweenArgs;
+    typedef rl2PrivRuleBetweenArgs *rl2PrivRuleBetweenArgsPtr;
+
+    typedef struct rl2_priv_variant_value
+    {
+	char *column_name;
+	sqlite3_int64 int_value;
+	double dbl_value;
+	char *text_value;
+	unsigned char *blob_value;
+	int bytes;
+	int sqlite3_type;
+    } rl2PrivVariantValue;
+    typedef rl2PrivVariantValue *rl2PrivVariantValuePtr;
+
+    typedef struct rl2_priv_variant_array
+    {
+	int count;
+	rl2PrivVariantValuePtr *array;
+    } rl2PrivVariantArray;
+    typedef rl2PrivVariantArray *rl2PrivVariantArrayPtr;
+
+    typedef struct rl2_priv_style_rule
+    {
+	int else_rule;
+	double min_scale;
+	double max_scale;
+	unsigned char comparison_op;
+	void *comparison_args;
+	char *column_name;
+	unsigned char style_type;
+	void *style;
+	struct rl2_priv_style_rule *next;
+    } rl2PrivStyleRule;
+    typedef rl2PrivStyleRule *rl2PrivStyleRulePtr;
+
+    typedef struct rl2_priv_coverage_style
+    {
+	char *name;
+	rl2PrivStyleRulePtr first_rule;
+	rl2PrivStyleRulePtr last_rule;
+    } rl2PrivCoverageStyle;
+    typedef rl2PrivCoverageStyle *rl2PrivCoverageStylePtr;
+
+    typedef struct rl2_priv_feature_type_style
+    {
+	char *name;
+	rl2PrivStyleRulePtr first_rule;
+	rl2PrivStyleRulePtr last_rule;
+	rl2PrivStyleRulePtr else_rule;
+	int columns_count;
+	char **column_names;
+    } rl2PrivFeatureTypeStyle;
+    typedef rl2PrivFeatureTypeStyle *rl2PrivFeatureTypeStylePtr;
 
     typedef struct rl2_priv_child_style
     {
@@ -558,8 +867,6 @@ extern "C"
     typedef struct rl2_priv_group_style
     {
 	char *name;
-	char *title;
-	char *abstract;
 	rl2PrivChildStylePtr first;
 	rl2PrivChildStylePtr last;
 	int valid;
@@ -571,8 +878,8 @@ extern "C"
 	int layer_type;
 	char *layer_name;
 	rl2CoveragePtr coverage;
-	char *style_name;
-	rl2PrivRasterStylePtr raster_symbolizer;
+	sqlite3_int64 raster_style_id;
+	rl2PrivRasterSymbolizerPtr raster_symbolizer;
 	rl2PrivRasterStatisticsPtr raster_stats;
     } rl2PrivGroupRendererLayer;
     typedef rl2PrivGroupRendererLayer *rl2PrivGroupRendererLayerPtr;
@@ -687,6 +994,10 @@ extern "C"
 	unsigned char *rgba_tile;
 	rl2CoveragePtr coverage;
 	const char *sect_name;
+	int mixedResolutions;
+	int sectionPaths;
+	int sectionMD5;
+	int sectionSummary;
 	double x;
 	double y;
 	int width;
@@ -710,6 +1021,7 @@ extern "C"
 	sqlite3_stmt *stmt_levl;
 	sqlite3_stmt *stmt_tils;
 	sqlite3_stmt *stmt_data;
+	char *xml_summary;
     } InsertWms;
     typedef InsertWms *InsertWmsPtr;
 
@@ -725,6 +1037,7 @@ extern "C"
     {
 	/* helper struct for passing arguments to aux_render_image */
 	sqlite3 *sqlite;
+	int max_threads;
 	int width;
 	int height;
 	int base_width;
@@ -734,6 +1047,10 @@ extern "C"
 	double maxx;
 	double maxy;
 	int srid;
+	int by_section;
+	sqlite3_int64 section_id;
+	double x_res;
+	double y_res;
 	double xx_res;
 	double yy_res;
 	int transparent;
@@ -744,7 +1061,7 @@ extern "C"
 	unsigned char bg_green;
 	unsigned char bg_blue;
 	rl2CoveragePtr coverage;
-	rl2RasterStylePtr symbolizer;
+	rl2RasterSymbolizerPtr symbolizer;
 	rl2RasterStatisticsPtr stats;
 	unsigned char *outbuf;
 	rl2PalettePtr palette;
@@ -772,6 +1089,150 @@ extern "C"
 	int reaspect;
     };
 
+    typedef struct rl2_point
+    {
+	double x;
+	double y;
+	struct rl2_point *next;
+    } rl2Point;
+    typedef rl2Point *rl2PointPtr;
+
+    typedef struct rl2_linestring
+    {
+	int points;
+	double *coords;
+	double minx;
+	double miny;
+	double maxx;
+	double maxy;
+	struct rl2_linestring *next;
+    } rl2Linestring;
+    typedef rl2Linestring *rl2LinestringPtr;
+
+    typedef struct rl2_ring
+    {
+	int points;
+	double *coords;
+	double minx;
+	double miny;
+	double maxx;
+	double maxy;
+	struct rl2_ring *next;
+    } rl2Ring;
+    typedef rl2Ring *rl2RingPtr;
+
+    typedef struct rl2_polygon
+    {
+	rl2RingPtr exterior;
+	int num_interiors;
+	rl2RingPtr interiors;
+	struct rl2_polygon *next;
+    } rl2Polygon;
+    typedef rl2Polygon *rl2PolygonPtr;
+
+    typedef struct rl2_geometry
+    {
+	rl2PointPtr first_point;
+	rl2PointPtr last_point;
+	rl2LinestringPtr first_linestring;
+	rl2LinestringPtr last_linestring;
+	rl2PolygonPtr first_polygon;
+	rl2PolygonPtr last_polygon;
+    } rl2Geometry;
+    typedef rl2Geometry *rl2GeometryPtr;
+
+    typedef struct rl2_aux_importer_tile
+    {
+	struct rl2_aux_importer *mother;
+	void *opaque_thread_id;
+	rl2RasterPtr raster;
+	unsigned int row;
+	unsigned int col;
+	double minx;
+	double miny;
+	double maxx;
+	double maxy;
+	int retcode;
+	unsigned char *blob_odd;
+	unsigned char *blob_even;
+	int blob_odd_sz;
+	int blob_even_sz;
+	struct rl2_aux_importer_tile *next;
+    } rl2AuxImporterTile;
+    typedef rl2AuxImporterTile *rl2AuxImporterTilePtr;
+
+    typedef struct rl2_aux_importer
+    {
+	rl2PrivCoveragePtr coverage;
+	int srid;
+	double maxx;
+	double miny;
+	unsigned int tile_w;
+	unsigned int tile_h;
+	double res_x;
+	double res_y;
+	unsigned char origin_type;
+	const void *origin;
+	unsigned char forced_conversion;
+	int verbose;
+	unsigned char compression;
+	int quality;
+	rl2AuxImporterTilePtr first;
+	rl2AuxImporterTilePtr last;
+    } rl2AuxImporter;
+    typedef rl2AuxImporter *rl2AuxImporterPtr;
+
+    typedef struct rl2_aux_decoder
+    {
+	void *opaque_thread_id;
+	sqlite3_int64 tile_id;
+	unsigned char *blob_odd;
+	unsigned char *blob_even;
+	int blob_odd_sz;
+	int blob_even_sz;
+	unsigned char *outbuf;
+	unsigned int width;
+	unsigned int height;
+	unsigned char sample_type;
+	unsigned char num_bands;
+	unsigned char auto_ndvi;
+	unsigned char red_band_index;
+	unsigned char nir_band_index;
+	double x_res;
+	double y_res;
+	int scale;
+	double minx;
+	double maxy;
+	double tile_minx;
+	double tile_maxy;
+	rl2PrivPixelPtr no_data;
+	rl2PrivRasterSymbolizerPtr style;
+	rl2PrivRasterStatisticsPtr stats;
+	rl2PrivRasterPtr raster;
+	rl2PrivPalettePtr palette;
+	int retcode;
+    } rl2AuxDecoder;
+    typedef rl2AuxDecoder *rl2AuxDecoderPtr;
+
+    typedef struct rl2_aux_shadower
+    {
+	void *opaque_thread_id;
+	unsigned int width;
+	unsigned int height;
+	double relief_factor;
+	double scale_factor;
+	double altRadians;
+	double azRadians;
+	void *rawbuf;
+	unsigned short start_row;
+	unsigned short row_increment;
+	unsigned short row_stride;
+	unsigned char sample_type;
+	rl2PrivPixelPtr no_data;
+	float *sr_mask;
+    } rl2AuxShadower;
+    typedef rl2AuxShadower *rl2AuxShadowerPtr;
+
     RL2_PRIVATE int
 	rl2_blob_from_file (const char *path, unsigned char **blob,
 			    int *blob_size);
@@ -795,10 +1256,20 @@ extern "C"
 				unsigned char **mask, int *mask_sz);
 
     RL2_PRIVATE int
-	rl2_data_to_png (const unsigned char *pixels, const unsigned char *mask,
-			 double opacity, rl2PalettePtr plt,
-			 unsigned int width, unsigned int height,
-			 unsigned char sample_type, unsigned char pixel_type,
+	rl2_decode_jpeg2000_scaled (int scale, const unsigned char *jpeg2000,
+				    int jpeg2000_sz, unsigned int *width,
+				    unsigned int *height,
+				    unsigned char sample_type,
+				    unsigned char pixel_type,
+				    unsigned char num_bands,
+				    unsigned char **pixels, int *pixels_sz);
+
+    RL2_PRIVATE int
+	rl2_data_to_png (const unsigned char *pixels,
+			 const unsigned char *mask, double opacity,
+			 rl2PalettePtr plt, unsigned int width,
+			 unsigned int height, unsigned char sample_type,
+			 unsigned char pixel_type, unsigned char num_bands,
 			 unsigned char **compr_data, int *compressed_size);
 
     RL2_PRIVATE int
@@ -807,7 +1278,21 @@ extern "C"
 			unsigned char *sample_type, unsigned char *pixel_type,
 			unsigned char *num_bands, unsigned char **pixels,
 			int *pixels_sz, unsigned char **mask, int *mask_sz,
-			rl2PalettePtr * palette);
+			rl2PalettePtr * palette, int alpha_mask);
+
+    RL2_PRIVATE int
+	rl2_data_to_charls (const unsigned char *pixels, unsigned int width,
+			    unsigned int height, unsigned char sample_type,
+			    unsigned char pixel_type, unsigned char num_bands,
+			    unsigned char **compr_data, int *compressed_size);
+
+    RL2_PRIVATE int
+	rl2_decode_charls (const unsigned char *charls, int charls_sz,
+			   unsigned int *width, unsigned int *height,
+			   unsigned char *sample_type,
+			   unsigned char *pixel_type,
+			   unsigned char *num_bands, unsigned char **pixels,
+			   int *pixels_sz);
 
     RL2_PRIVATE int
 	rl2_data_to_gif (const unsigned char *pixels,
@@ -859,34 +1344,43 @@ extern "C"
 				      unsigned char num_bands,
 				      rl2PixelPtr no_data);
 
-    RL2_PRIVATE int load_dbms_tiles (sqlite3 * handle,
-				     sqlite3_stmt * stmt_tiles,
-				     sqlite3_stmt * stmt_data,
-				     unsigned char *outbuf,
-				     unsigned int width,
-				     unsigned int height,
-				     unsigned char sample_type,
-				     unsigned char num_bands, double x_res,
-				     double y_res, double minx, double miny,
-				     double maxx, double maxy, int level,
-				     int scale, rl2PalettePtr palette,
-				     rl2PixelPtr no_data,
-				     rl2RasterStylePtr style,
-				     rl2RasterStatisticsPtr stats);
-
-    RL2_PRIVATE int load_dbms_tiles_section (sqlite3 * handle,
-					     sqlite3_int64 section_id,
-					     sqlite3_stmt * stmt_tiles,
-					     sqlite3_stmt * stmt_data,
-					     unsigned char *outbuf,
-					     unsigned int width,
-					     unsigned int height,
-					     unsigned char sample_type,
-					     unsigned char num_bands,
-					     double x_res, double y_res,
-					     double minx, double maxy,
-					     int scale, rl2PalettePtr palette,
-					     rl2PixelPtr no_data);
+    RL2_PRIVATE int rl2_load_dbms_tiles (sqlite3 * handle, int max_threads,
+					 sqlite3_stmt * stmt_tiles,
+					 sqlite3_stmt * stmt_data,
+					 unsigned char *outbuf,
+					 unsigned int width,
+					 unsigned int height,
+					 unsigned char sample_type,
+					 unsigned char num_bands,
+					 unsigned char auto_ndvi,
+					 unsigned char red_band_index,
+					 unsigned char nir_band_index,
+					 double x_res, double y_res,
+					 double minx, double miny,
+					 double maxx, double maxy, int level,
+					 int scale, rl2PalettePtr palette,
+					 rl2PixelPtr no_data,
+					 rl2RasterSymbolizerPtr style,
+					 rl2RasterStatisticsPtr stats);
+
+    RL2_PRIVATE int rl2_load_dbms_tiles_section (sqlite3 * handle,
+						 int max_threads,
+						 sqlite3_int64 section_id,
+						 sqlite3_stmt * stmt_tiles,
+						 sqlite3_stmt * stmt_data,
+						 unsigned char *outbuf,
+						 unsigned int width,
+						 unsigned int height,
+						 unsigned char sample_type,
+						 unsigned char num_bands,
+						 unsigned char auto_ndvi,
+						 unsigned char red_band_index,
+						 unsigned char nir_band_index,
+						 double x_res, double y_res,
+						 double minx, double maxy,
+						 int scale,
+						 rl2PalettePtr palette,
+						 rl2PixelPtr no_data);
 
     RL2_PRIVATE void
 	compute_aggregate_sq_diff (rl2RasterStatisticsPtr aggreg_stats);
@@ -915,45 +1409,35 @@ extern "C"
     RL2_PRIVATE void add_retry (WmsRetryListPtr lst, double minx, double miny,
 				double maxx, double maxy);
 
-    RL2_PRIVATE gaiaGeomCollPtr build_extent (int srid, double minx,
-					      double miny, double maxx,
-					      double maxy);
-
-    RL2_PRIVATE int do_insert_wms_tile (sqlite3 * handle,
-					unsigned char *blob_odd,
-					int blob_odd_sz,
-					unsigned char *blob_even,
-					int blob_even_sz,
-					sqlite3_int64 section_id, int srid,
-					double res_x, double res_y,
-					unsigned int tile_w,
-					unsigned int tile_h, double miny,
-					double maxx, double tile_minx,
-					double tile_miny, double tile_maxx,
-					double tile_maxy,
-					rl2PalettePtr aux_palette,
-					rl2PixelPtr no_data,
-					sqlite3_stmt * stmt_tils,
-					sqlite3_stmt * stmt_data,
-					rl2RasterStatisticsPtr section_stats);
-
-    RL2_PRIVATE int do_insert_levels (sqlite3 * handle, double base_res_x,
-				      double base_res_y, double factor,
-				      unsigned char sample_type,
-				      sqlite3_stmt * stmt_levl);
-
-    RL2_PRIVATE int do_insert_stats (sqlite3 * handle,
-				     rl2RasterStatisticsPtr section_stats,
-				     sqlite3_int64 section_id,
-				     sqlite3_stmt * stmt_upd_sect);
-
-    RL2_PRIVATE int do_insert_section (sqlite3 * handle, const char *src_path,
-				       const char *section, int srid,
-				       unsigned int width,
-				       unsigned int height, double minx,
-				       double miny, double maxx, double maxy,
-				       sqlite3_stmt * stmt_sect,
-				       sqlite3_int64 * id);
+    RL2_PRIVATE int rl2_do_insert_levels (sqlite3 * handle, double base_res_x,
+					  double base_res_y, double factor,
+					  unsigned char sample_type,
+					  sqlite3_stmt * stmt_levl);
+
+    RL2_PRIVATE int rl2_do_insert_section_levels (sqlite3 * handle,
+						  sqlite3_int64 section_id,
+						  double base_res_x,
+						  double base_res_y,
+						  double factor,
+						  unsigned char sample_type,
+						  sqlite3_stmt * stmt_levl);
+
+    RL2_PRIVATE int rl2_do_insert_stats (sqlite3 * handle,
+					 rl2RasterStatisticsPtr section_stats,
+					 sqlite3_int64 section_id,
+					 sqlite3_stmt * stmt_upd_sect);
+
+    RL2_PRIVATE int rl2_do_insert_section (sqlite3 * handle,
+					   const char *src_path,
+					   const char *section, int srid,
+					   unsigned int width,
+					   unsigned int height, double minx,
+					   double miny, double maxx,
+					   double maxy, char *xml_summary,
+					   int section_paths, int section_md5,
+					   int section_summary,
+					   sqlite3_stmt * stmt_sect,
+					   sqlite3_int64 * id);
 
     RL2_PRIVATE char *get_section_name (const char *src_path);
 
@@ -964,8 +1448,6 @@ extern "C"
 				     rl2RasterStatisticsPtr * section_stats,
 				     sqlite3_int64 * section_id);
 
-    RL2_PRIVATE int is_point (gaiaGeomCollPtr geom);
-
     RL2_PRIVATE ResolutionsListPtr alloc_resolutions_list ();
 
     RL2_PRIVATE void destroy_resolutions_list (ResolutionsListPtr list);
@@ -974,12 +1456,16 @@ extern "C"
 					  int scale, double x_res,
 					  double y_res);
 
-    RL2_PRIVATE int find_best_resolution_level (sqlite3 * handle,
-						const char *coverage,
-						double x_res, double y_res,
-						int *level_id, int *scale,
-						int *real_scale, double *xx_res,
-						double *yy_res);
+    RL2_PRIVATE int rl2_find_best_resolution_level (sqlite3 * handle,
+						    const char *coverage,
+						    int by_section,
+						    sqlite3_int64 section_id,
+						    double x_res,
+						    double y_res,
+						    int *level_id, int *scale,
+						    int *real_scale,
+						    double *xx_res,
+						    double *yy_res);
 
     RL2_PRIVATE unsigned char get_palette_format (rl2PrivPalettePtr plt);
 
@@ -1025,13 +1511,17 @@ extern "C"
 
     RL2_PRIVATE int get_payload_from_palette_transparent (unsigned int width,
 							  unsigned int height,
-							  unsigned char *pixels,
-							  rl2PalettePtr palette,
-							  unsigned char format,
-							  int quality,
-							  unsigned char **image,
+							  unsigned char
+							  *pixels,
+							  rl2PalettePtr
+							  palette,
+							  unsigned char
+							  format, int quality,
+							  unsigned char
+							  **image,
 							  int *image_sz,
-							  unsigned char bg_red,
+							  unsigned char
+							  bg_red,
 							  unsigned char
 							  bg_green,
 							  unsigned char
@@ -1041,9 +1531,10 @@ extern "C"
     RL2_PRIVATE int get_payload_from_grayscale_opaque (unsigned int width,
 						       unsigned int height,
 						       sqlite3 * handle,
-						       double minx, double miny,
-						       double maxx, double maxy,
-						       int srid,
+						       double minx,
+						       double miny,
+						       double maxx,
+						       double maxy, int srid,
 						       unsigned char *pixels,
 						       unsigned char format,
 						       int quality,
@@ -1057,7 +1548,8 @@ extern "C"
 							    unsigned char
 							    *pixels,
 							    unsigned char
-							    format, int quality,
+							    format,
+							    int quality,
 							    unsigned char
 							    **image,
 							    int *image_sz,
@@ -1067,9 +1559,10 @@ extern "C"
 
     RL2_PRIVATE int get_payload_from_rgb_opaque (unsigned int width,
 						 unsigned int height,
-						 sqlite3 * handle, double minx,
-						 double miny, double maxx,
-						 double maxy, int srid,
+						 sqlite3 * handle,
+						 double minx, double miny,
+						 double maxx, double maxy,
+						 int srid,
 						 unsigned char *pixels,
 						 unsigned char format,
 						 int quality,
@@ -1102,7 +1595,8 @@ extern "C"
 
     RL2_PRIVATE int get_rgba_from_monochrome_transparent (unsigned int width,
 							  unsigned int height,
-							  unsigned char *pixels,
+							  unsigned char
+							  *pixels,
 							  unsigned char *rgba);
 
     RL2_PRIVATE int get_rgba_from_palette_mask (unsigned int base_width,
@@ -1142,7 +1636,8 @@ extern "C"
 
     RL2_PRIVATE int get_rgba_from_grayscale_transparent (unsigned int width,
 							 unsigned int height,
-							 unsigned char *pixels,
+							 unsigned char
+							 *pixels,
 							 unsigned char *rgba,
 							 unsigned char bg_gray);
 
@@ -1174,12 +1669,22 @@ extern "C"
 						 rl2PrivPixelPtr no_made,
 						 unsigned char *rgba);
 
+    RL2_PRIVATE int get_rgba_from_multiband_mask (unsigned int width,
+						  unsigned int height,
+						  unsigned char sample_type,
+						  unsigned char num_bands,
+						  void *pixels,
+						  unsigned char *mask,
+						  rl2PrivPixelPtr no_made,
+						  unsigned char *rgba);
+
     RL2_PRIVATE int get_payload_from_gray_rgba_opaque (unsigned int width,
 						       unsigned int height,
 						       sqlite3 * handle,
-						       double minx, double miny,
-						       double maxx, double maxy,
-						       int srid,
+						       double minx,
+						       double miny,
+						       double maxx,
+						       double maxy, int srid,
 						       unsigned char *rgb,
 						       unsigned char format,
 						       int quality,
@@ -1190,11 +1695,13 @@ extern "C"
 							    width,
 							    unsigned int
 							    height,
-							    unsigned char *rgb,
+							    unsigned char
+							    *rgb,
 							    unsigned char
 							    *alpha,
 							    unsigned char
-							    format, int quality,
+							    format,
+							    int quality,
 							    unsigned char
 							    **image,
 							    int *image_sz,
@@ -1203,9 +1710,10 @@ extern "C"
     RL2_PRIVATE int get_payload_from_rgb_rgba_opaque (unsigned int width,
 						      unsigned int height,
 						      sqlite3 * handle,
-						      double minx, double miny,
-						      double maxx, double maxy,
-						      int srid,
+						      double minx,
+						      double miny,
+						      double maxx,
+						      double maxy, int srid,
 						      unsigned char *rgb,
 						      unsigned char format,
 						      int quality,
@@ -1216,17 +1724,22 @@ extern "C"
 							   unsigned int
 							   height,
 							   unsigned char *rgb,
-							   unsigned char *alpha,
-							   unsigned char format,
+							   unsigned char
+							   *alpha,
+							   unsigned char
+							   format,
 							   int quality,
 							   unsigned char
 							   **image,
 							   int *image_sz,
-							   double opacity);
+							   double opacity,
+							   int
+							   half_transparent);
 
     RL2_PRIVATE int build_rgb_alpha (unsigned int width,
 				     unsigned int height, unsigned char *rgba,
-				     unsigned char **rgb, unsigned char **alpha,
+				     unsigned char **rgb,
+				     unsigned char **alpha,
 				     unsigned char bg_red,
 				     unsigned char bg_green,
 				     unsigned char bg_blue);
@@ -1255,33 +1768,160 @@ extern "C"
     RL2_PRIVATE int parse_worldfile (FILE * in, double *px, double *py,
 				     double *pres_x, double *pres_y);
 
-    RL2_PRIVATE rl2RasterStylePtr raster_style_from_sld_se_xml (char *name,
-								char *title,
-								char *abstract,
-								unsigned char
-								*xml);
+    RL2_PRIVATE rl2CoverageStylePtr coverage_style_from_xml (char *name,
+							     unsigned char
+							     *xml);
+
+    RL2_PRIVATE rl2FeatureTypeStylePtr feature_type_style_from_xml (char
+								    *name,
+								    unsigned
+								    char *xml);
 
     RL2_PRIVATE rl2GroupStylePtr group_style_from_sld_xml (char *name,
-							   char *title,
-							   char *abstract,
 							   unsigned char *xml);
 
+    RL2_PRIVATE rl2PrivCoverageStylePtr
+	rl2_create_default_coverage_style (void);
+
+    RL2_PRIVATE rl2PrivRasterSymbolizerPtr
+	rl2_create_default_raster_symbolizer (void);
+
+    RL2_PRIVATE rl2PrivVectorSymbolizerPtr
+	rl2_create_default_vector_symbolizer (void);
+
+    RL2_PRIVATE rl2PrivStrokePtr rl2_create_default_stroke (void);
+
+    RL2_PRIVATE rl2PrivFillPtr rl2_create_default_fill (void);
+
+    RL2_PRIVATE rl2PrivColorReplacementPtr
+	rl2_create_default_color_replacement (void);
+
+    RL2_PRIVATE rl2PrivGraphicItemPtr
+	rl2_create_default_external_graphic (void);
+
+    RL2_PRIVATE rl2PrivGraphicItemPtr rl2_create_default_mark (void);
+
+    RL2_PRIVATE rl2PrivGraphicPtr rl2_create_default_graphic (void);
+
+    RL2_PRIVATE rl2PrivPointPlacementPtr
+	rl2_create_default_point_placement (void);
+
+    RL2_PRIVATE rl2PrivLinePlacementPtr
+	rl2_create_default_line_placement (void);
+
+    RL2_PRIVATE rl2PrivHaloPtr rl2_create_default_halo (void);
+
+    RL2_PRIVATE rl2PrivVectorSymbolizerItemPtr
+	rl2_create_default_point_symbolizer (void);
+
+    RL2_PRIVATE rl2PrivVectorSymbolizerItemPtr
+	rl2_create_default_line_symbolizer (void);
+
+    RL2_PRIVATE rl2PrivVectorSymbolizerItemPtr
+	rl2_create_default_polygon_symbolizer (void);
+
+    RL2_PRIVATE rl2PrivVectorSymbolizerItemPtr
+	rl2_create_default_text_symbolizer (void);
+
+    RL2_PRIVATE void rl2_destroy_raster_symbolizer (rl2PrivRasterSymbolizerPtr
+						    symbolizer);
+
+    RL2_PRIVATE void rl2_destroy_vector_symbolizer (rl2PrivVectorSymbolizerPtr
+						    symbolizer);
+
+    RL2_PRIVATE void
+	rl2_destroy_vector_symbolizer_item (rl2PrivVectorSymbolizerItemPtr
+					    item);
+
+    RL2_PRIVATE void rl2_destroy_stroke (rl2PrivStrokePtr stroke);
+
+    RL2_PRIVATE void rl2_destroy_fill (rl2PrivFillPtr fill);
+
+    RL2_PRIVATE void rl2_destroy_color_replacement (rl2PrivColorReplacementPtr
+						    repl);
+
+    RL2_PRIVATE void rl2_destroy_external_graphic (rl2PrivExternalGraphicPtr
+						   ext);
+
+    RL2_PRIVATE void rl2_destroy_mark (rl2PrivMarkPtr mark);
+
+    RL2_PRIVATE void rl2_destroy_graphic_item (rl2PrivGraphicItemPtr item);
+
+    RL2_PRIVATE void rl2_destroy_graphic (rl2PrivGraphicPtr graphic);
+
+    RL2_PRIVATE void rl2_destroy_point_placement (rl2PrivPointPlacementPtr
+						  place);
+
+    RL2_PRIVATE void rl2_destroy_line_placement (rl2PrivLinePlacementPtr place);
+
+    RL2_PRIVATE void rl2_destroy_halo (rl2PrivHaloPtr halo);
+
+    RL2_PRIVATE void rl2_destroy_point_symbolizer (rl2PrivPointSymbolizerPtr
+						   symbolizer);
+
+    RL2_PRIVATE void rl2_destroy_line_symbolizer (rl2PrivLineSymbolizerPtr
+						  symbolizer);
+
+    RL2_PRIVATE void
+	rl2_destroy_polygon_symbolizer (rl2PrivPolygonSymbolizerPtr symbolizer);
+
+    RL2_PRIVATE void rl2_destroy_text_symbolizer (rl2PrivTextSymbolizerPtr
+						  symbolizer);
+
+    RL2_PRIVATE rl2PrivRuleSingleArgPtr
+	rl2_create_default_rule_single_arg (void);
+
+    RL2_PRIVATE rl2PrivRuleLikeArgsPtr rl2_create_default_rule_like_args (void);
+
+    RL2_PRIVATE rl2PrivRuleBetweenArgsPtr
+	rl2_create_default_rule_between_args (void);
+
+    RL2_PRIVATE rl2PrivStyleRulePtr rl2_create_default_style_rule (void);
+
+    RL2_PRIVATE void rl2_destroy_style_rule (rl2PrivStyleRulePtr rule);
+
+    RL2_PRIVATE void rl2_destroy_rule_like_args (rl2PrivRuleLikeArgsPtr like);
+
+    RL2_PRIVATE void rl2_destroy_rule_between_args (rl2PrivRuleBetweenArgsPtr
+						    between);
+
+    RL2_PRIVATE void rl2_destroy_rule_single_arg (rl2PrivRuleSingleArgPtr
+						  single);
+
     RL2_PRIVATE int get_raster_band_histogram (rl2PrivBandStatisticsPtr band,
 					       unsigned char **image,
 					       int *image_sz);
 
-    RL2_PRIVATE int copy_raw_pixels (rl2RasterPtr raster, unsigned char *outbuf,
-				     unsigned int width,
-				     unsigned int height,
-				     unsigned char sample_type,
-				     unsigned char num_bands, double x_res,
-				     double y_res, double minx, double maxy,
-				     double tile_minx, double tile_maxy,
-				     rl2PixelPtr no_data,
-				     rl2RasterStylePtr style,
-				     rl2RasterStatisticsPtr stats);
+    RL2_PRIVATE int rl2_copy_raw_pixels (rl2RasterPtr raster,
+					 unsigned char *outbuf,
+					 unsigned int width,
+					 unsigned int height,
+					 unsigned char sample_type,
+					 unsigned char num_bands,
+					 unsigned char auto_ndvi,
+					 unsigned char red_band_index,
+					 unsigned char nir_band_index,
+					 double x_res, double y_res,
+					 double minx, double maxy,
+					 double tile_minx, double tile_maxy,
+					 rl2PixelPtr no_data,
+					 rl2RasterSymbolizerPtr style,
+					 rl2RasterStatisticsPtr stats);
+
+    RL2_PRIVATE unsigned char *rl2_copy_endian_raw_pixels (const unsigned char
+							   *pixels,
+							   int pixels_sz,
+							   unsigned int width,
+							   unsigned int
+							   height,
+							   unsigned char
+							   sample_type,
+							   unsigned char
+							   num_bands,
+							   int big_endian);
 
     RL2_PRIVATE int rl2_build_shaded_relief_mask (sqlite3 * handle,
+						  int max_threads,
 						  rl2CoveragePtr cvg,
 						  double relief_factor,
 						  double scale_factor,
@@ -1302,22 +1942,184 @@ extern "C"
 					  const char *group_name);
 
     RL2_PRIVATE int rl2_rgba_raster_data (sqlite3 * handle,
-					  const char *coverage_name, void *ctx,
-					  int level, double minx, double miny,
-					  double maxx, double maxy,
-					  rl2PalettePtr palette,
+					  const char *coverage_name,
+					  void *ctx, int level, double minx,
+					  double miny, double maxx,
+					  double maxy, rl2PalettePtr palette,
 					  rl2PixelPtr no_data);
 
     RL2_PRIVATE int rl2_aux_render_image (struct aux_renderer *aux,
 					  unsigned char **ximage,
 					  int *ximage_size);
 
+    RL2_PRIVATE int rl2_aux_default_image (unsigned int width,
+					   unsigned int height,
+					   unsigned char red,
+					   unsigned char green,
+					   unsigned char blue, int format_id,
+					   int transparent, int quality,
+					   unsigned char **ximage,
+					   int *ximage_size);
+
     RL2_PRIVATE void rl2_aux_group_renderer (struct aux_group_renderer *auxgrp);
 
     RL2_PRIVATE double rl2_get_shaded_relief_scale_factor (sqlite3 * handle,
 							   const char
 							   *coverage);
 
+    RL2_PRIVATE void *rl2_CreateMD5Checksum (void);
+
+    RL2_PRIVATE void rl2_FreeMD5Checksum (void *p_md5);
+
+    RL2_PRIVATE void rl2_UpdateMD5Checksum (void *p_md5,
+					    const unsigned char *blob,
+					    int blob_len);
+
+    RL2_PRIVATE char *rl2_FinalizeMD5Checksum (void *p_md5);
+
+    RL2_PRIVATE int rl2_is_mixed_resolutions_coverage (sqlite3 * handle,
+						       const char *coverage);
+
+    RL2_PRIVATE int rl2_has_styled_rgb_colors (rl2RasterSymbolizerPtr style);
+
+    RL2_PRIVATE int rl2_get_raw_raster_data_common (sqlite3 * handle,
+						    int max_threads,
+						    rl2CoveragePtr cvg,
+						    int by_section,
+						    sqlite3_int64 section_id,
+						    unsigned int width,
+						    unsigned int height,
+						    double minx, double miny,
+						    double maxx, double maxy,
+						    double x_res,
+						    double y_res,
+						    unsigned char **buffer,
+						    int *buf_size,
+						    rl2PalettePtr * palette,
+						    unsigned char out_pixel,
+						    rl2PixelPtr bgcolor,
+						    rl2RasterSymbolizerPtr
+						    style,
+						    rl2RasterStatisticsPtr
+						    stats);
+
+    RL2_PRIVATE char *rl2_double_quoted_sql (const char *value);
+
+    RL2_PRIVATE int rl2_parse_point (sqlite3 * sqlite,
+				     const unsigned char *blob, int blob_sz,
+				     double *x, double *y);
+
+    RL2_PRIVATE int rl2_parse_point_generic (sqlite3 * sqlite,
+					     const unsigned char *blob,
+					     int blob_sz, double *x, double *y);
+
+    RL2_PRIVATE int rl2_parse_bbox_srid (sqlite3 * sqlite,
+					 const unsigned char *blob,
+					 int blob_sz, int *srid, double *minx,
+					 double *miny, double *maxx,
+					 double *maxy);
+
+    RL2_PRIVATE int rl2_parse_bbox (sqlite3 * sqlite,
+				    const unsigned char *blob, int blob_sz,
+				    double *minx, double *miny, double *maxx,
+				    double *maxy);
+
+    RL2_PRIVATE int rl2_build_bbox (sqlite3 * sqlite, int srid, double minx,
+				    double miny, double maxx, double maxy,
+				    unsigned char **blob, int *blob_sz);
+
+    RL2_PRIVATE int rl2_delta_encode (unsigned char *buffer, int size,
+				      int distance);
+
+    RL2_PRIVATE int rl2_delta_decode (unsigned char *buffer, int size,
+				      int distance);
+
+    RL2_PRIVATE rl2PrivVariantValuePtr rl2_create_variant_int (const char
+							       *name,
+							       sqlite3_int64
+							       value);
+
+    RL2_PRIVATE rl2PrivVariantValuePtr rl2_create_variant_double (const char
+								  *name,
+								  double value);
+
+    RL2_PRIVATE rl2PrivVariantValuePtr
+	rl2_create_variant_text (const char *name, const char *value,
+				 int bytes);
+
+    RL2_PRIVATE rl2PrivVariantValuePtr
+	rl2_create_variant_blob (const char *name, const unsigned char *value,
+				 int bytes);
+
+    RL2_PRIVATE rl2PrivVariantValuePtr rl2_create_variant_null (const char
+								*name);
+
+    RL2_PRIVATE void rl2_destroy_variant_value (rl2PrivVariantValuePtr value);
+
+    RL2_PRIVATE void rl2_draw_vector_feature (void *ctx, sqlite3 * handle,
+					      const void *priv_data,
+					      rl2VectorSymbolizerPtr
+					      symbolizer, int height,
+					      double minx, double miny,
+					      double maxx, double maxy,
+					      double x_res, double y_res,
+					      rl2GeometryPtr geom,
+					      rl2VariantArrayPtr variant);
+
+    RL2_PRIVATE rl2GeometryPtr
+	rl2_geometry_from_blob (const unsigned char *blob, int blob_sz);
+
+    RL2_PRIVATE rl2GeometryPtr
+	rl2_curve_from_XY (int points, double *x, double *y);
+
+    RL2_PRIVATE void rl2_destroy_geometry (rl2GeometryPtr geom);
+
+    RL2_PRIVATE int rl2_serialize_linestring (rl2LinestringPtr line,
+					      unsigned char **blob,
+					      int *blob_sz);
+
+    RL2_PRIVATE int rl2_serialize_ring (rl2RingPtr ring, unsigned char **blob,
+					int *blob_sz);
+
+    RL2_PRIVATE int rl2_serialize_ring_as_linestring (rl2RingPtr ring,
+						      unsigned char **blob,
+						      int *blob_sz);
+
+    RL2_PRIVATE double rl2_compute_curve_length (rl2GeometryPtr geom);
+
+    RL2_PRIVATE rl2GeometryPtr
+	rl2_curve_substring (sqlite3 * handle, rl2GeometryPtr geom,
+			     double from, double to);
+
+    RL2_PRIVATE rl2GeometryPtr rl2_clone_curve (rl2GeometryPtr in);
+
+    RL2_PRIVATE rl2GeometryPtr rl2_clone_linestring (rl2LinestringPtr in);
+
+    RL2_PRIVATE rl2GeometryPtr
+	rl2_build_circle (double x, double y, double radius);
+
+    RL2_PRIVATE int rl2_load_font_into_dbms (sqlite3 * handle,
+					     unsigned char *blob, int blob_sz);
+
+    RL2_PRIVATE int rl2_get_font_from_dbms (sqlite3 * handle,
+					    const char *facename,
+					    unsigned char **font, int *font_sz);
+
+    RL2_PRIVATE rl2LinestringPtr rl2_linestring_to_image (rl2LinestringPtr line,
+							  int height,
+							  double minx,
+							  double miny,
+							  double x_res,
+							  double y_res);
+
+    RL2_PRIVATE rl2RingPtr rl2_ring_to_image (rl2RingPtr ring, int height,
+					      double minx, double miny,
+					      double x_res, double y_res);
+
+    RL2_PRIVATE void rl2DestroyLinestring (rl2LinestringPtr ptr);
+
+    RL2_PRIVATE void rl2DestroyRing (rl2RingPtr ptr);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/headers/rl2svg_private.h b/headers/rl2svg_private.h
index 926fd72..ac56f15 100644
--- a/headers/rl2svg_private.h
+++ b/headers/rl2svg_private.h
@@ -506,11 +506,11 @@ extern "C"
 
     RL2_PRIVATE rl2PrivSvgLinePtr svg_clone_line (rl2PrivSvgLinePtr in);
 
-    RL2_PRIVATE rl2PrivSvgPolylinePtr svg_alloc_polyline (int points, double *x,
-							  double *y);
+    RL2_PRIVATE rl2PrivSvgPolylinePtr svg_alloc_polyline (int points,
+							  double *x, double *y);
 
-    RL2_PRIVATE rl2PrivSvgPolylinePtr svg_clone_polyline (rl2PrivSvgPolylinePtr
-							  in);
+    RL2_PRIVATE rl2PrivSvgPolylinePtr
+	svg_clone_polyline (rl2PrivSvgPolylinePtr in);
 
     RL2_PRIVATE rl2PrivSvgPolygonPtr svg_alloc_polygon (int points, double *x,
 							double *y);
@@ -520,8 +520,8 @@ extern "C"
 
     RL2_PRIVATE rl2PrivSvgPathMovePtr svg_alloc_path_move (double x, double y);
 
-    RL2_PRIVATE rl2PrivSvgPathMovePtr svg_clone_path_move (rl2PrivSvgPathMovePtr
-							   in);
+    RL2_PRIVATE rl2PrivSvgPathMovePtr
+	svg_clone_path_move (rl2PrivSvgPathMovePtr in);
 
     RL2_PRIVATE rl2PrivSvgPathBezierPtr svg_alloc_path_bezier (double x1,
 							       double y1,
@@ -610,8 +610,10 @@ extern "C"
     RL2_PRIVATE rl2PrivSvgGradientStopPtr svg_alloc_gradient_stop (double
 								   offset,
 								   double red,
-								   double green,
-								   double blue,
+								   double
+								   green,
+								   double
+								   blue,
 								   double
 								   opacity);
 
@@ -620,10 +622,9 @@ extern "C"
 
     RL2_PRIVATE rl2PrivSvgGradientPtr svg_alloc_gradient (void);
 
-    RL2_PRIVATE rl2PrivSvgGradientPtr svg_clone_gradient (rl2PrivSvgGradientPtr
-							  in,
-							  rl2PrivSvgGradientPtr
-							  old);
+    RL2_PRIVATE rl2PrivSvgGradientPtr
+	svg_clone_gradient (rl2PrivSvgGradientPtr in,
+			    rl2PrivSvgGradientPtr old);
 
     RL2_PRIVATE rl2PrivSvgDocumentPtr svg_alloc_document (void);
 
@@ -635,13 +636,14 @@ extern "C"
 
     RL2_PRIVATE void svg_insert_clip (rl2PrivSvgDocumentPtr svg_doc);
 
-    RL2_PRIVATE rl2PrivSvgUsePtr svg_insert_use (rl2PrivSvgDocumentPtr svg_doc,
+    RL2_PRIVATE rl2PrivSvgUsePtr svg_insert_use (rl2PrivSvgDocumentPtr
+						 svg_doc,
 						 const char *xlink_href,
 						 double x, double y,
 						 double width, double height);
 
-    RL2_PRIVATE void svg_insert_shape (rl2PrivSvgDocumentPtr svg_doc, int type,
-				       void *data);
+    RL2_PRIVATE void svg_insert_shape (rl2PrivSvgDocumentPtr svg_doc,
+				       int type, void *data);
 
     RL2_PRIVATE void svg_insert_gradient_stop (rl2PrivSvgGradientPtr gradient,
 					       double offset, double red,
@@ -651,20 +653,20 @@ extern "C"
     RL2_PRIVATE rl2PrivSvgGradientPtr
 	svg_insert_linear_gradient (rl2PrivSvgDocumentPtr svg_doc,
 				    const char *id, const char *xlink_href,
-				    double x1, double y1, double x2, double y2,
-				    int units);
+				    double x1, double y1, double x2,
+				    double y2, int units);
 
     RL2_PRIVATE rl2PrivSvgGradientPtr
 	svg_insert_radial_gradient (rl2PrivSvgDocumentPtr svg_doc,
 				    const char *id, const char *xlink_href,
-				    double cx, double cy, double fx, double fy,
-				    double r, int units);
+				    double cx, double cy, double fx,
+				    double fy, double r, int units);
 
     RL2_PRIVATE rl2PrivSvgGradientPtr
 	svg_insert_radial_gradient (rl2PrivSvgDocumentPtr svg_doc,
 				    const char *id, const char *xlink_href,
-				    double cx, double cy, double fx, double fy,
-				    double r, int units);
+				    double cx, double cy, double fx,
+				    double fy, double r, int units);
 
     RL2_PRIVATE void svg_init_style (rl2PrivSvgStylePtr style);
 
diff --git a/rasterlite2-4.2.0.mk b/rasterlite2-4.2.0.mk
deleted file mode 100644
index 581d961..0000000
--- a/rasterlite2-4.2.0.mk
+++ /dev/null
@@ -1,86 +0,0 @@
-include $(CLEAR_VARS)
-# ./configure --build=x86_64-pc-linux-gnu --host=arm-linux-eabi
-LOCAL_MODULE    := rasterlite2
-
-# SQLite flags copied from ASOP [may not be needed for rasterlite2]
-common_sqlite_flags := \
- -DHAVE_USLEEP=1 \
- -DSQLITE_DEFAULT_JOURNAL_SIZE_LIMIT=1048576 \
- -DSQLITE_THREADSAFE=1 \
- -DNDEBUG=1 \
- -DSQLITE_ENABLE_MEMORY_MANAGEMENT=1 \
- -DSQLITE_DEFAULT_AUTOVACUUM=1 \
- -DSQLITE_TEMP_STORE=3 \
- -DSQLITE_ENABLE_FTS3 \
- -DSQLITE_ENABLE_FTS3_BACKWARDS \
- -DSQLITE_ENABLE_RTREE=1 \
- -DSQLITE_DEFAULT_FILE_FORMAT=4
-
-# comment out TARGET_CPU in config.h - will be replaced with TARGET_ARCH_ABI
-spatialite_flags := \
- -DOMIT_FREEXL \
- -DTARGET_CPU=\"$(TARGET_ARCH_ABI)\" \
- -Dfdatasync=fsync \
- -DSQLITE_ENABLE_RTREE=1 \
- -DSQLITE_OMIT_BUILTIN_TEST=1
-
-# comment out TARGET_CPU in config.h - will be replaced with TARGET_ARCH_ABI
-rasterlite2_flags := \
- -DTARGET_CPU=\"$(TARGET_ARCH_ABI)\" \
- -O
-
-LOCAL_CFLAGS    := \
- $(common_sqlite_flags) \
- $(spatialite_flags) \
- $(rasterlite2_flags)
-
-LOCAL_C_INCLUDES := \
- $(SQLITE_PATH) \
- $(GEOTIFF_PATH)/libxtiff \
- $(GEOTIFF_PATH) \
- $(TIFF_PATH) \
- $(JPEG_PATH) \
- $(GIF_PATH) \
- $(PNG_PATH) \
- $(WEBP_PATH)/src/webp \
- $(WEBP_PATH)/src/dec \
- $(WEBP_PATH)/src/dsp \
- $(WEBP_PATH)/src/enc \
- $(WEBP_PATH)/src/utils \
- $(WEBP_PATH)/src \
- $(WEBP_PATH) \
- $(CAIRO_PATH) \
- $(ICONV_PATH)/include \
- $(ICONV_PATH)/libcharset/include \
- $(XML2_PATH)/include \
- $(CURL_PATH) \
- $(CURL_PATH)/include \
- $(CURL_PATH)/lib \
- $(RASTERLITE2_PATH) \
- $(RASTERLITE2_PATH)/headers \
- $(SPATIALITE_PATH)/src/headers \
- $(LZMA_PATH)/src/liblzma/api
-LOCAL_SRC_FILES := \
- $(RASTERLITE2_PATH)/src/rasterlite2.c \
- $(RASTERLITE2_PATH)/src/rl2ascii.c \
- $(RASTERLITE2_PATH)/src/rl2codec.c \
- $(RASTERLITE2_PATH)/src/rl2dbms.c \
- $(RASTERLITE2_PATH)/src/rl2gif.c \
- $(RASTERLITE2_PATH)/src/rl2import.c \
- $(RASTERLITE2_PATH)/src/rl2jpeg.c \
- $(RASTERLITE2_PATH)/src/rl2paint.c \
- $(RASTERLITE2_PATH)/src/rl2png.c \
- $(RASTERLITE2_PATH)/src/rl2rastersym.c \
- $(RASTERLITE2_PATH)/src/rl2raw.c \
- $(RASTERLITE2_PATH)/src/rl2sql.c \
- $(RASTERLITE2_PATH)/src/rl2sqlaux.c \
- $(RASTERLITE2_PATH)/src/rl2svg.c \
- $(RASTERLITE2_PATH)/src/rl2svgaux.c \
- $(RASTERLITE2_PATH)/src/rl2svgxml.c \
- $(RASTERLITE2_PATH)/src/rl2symbolizer.c \
- $(RASTERLITE2_PATH)/src/rl2tiff.c \
- $(RASTERLITE2_PATH)/src/rl2version.c \
- $(RASTERLITE2_PATH)/src/rl2webp.c \
- $(RASTERLITE2_PATH)/src/rl2wms.c
-LOCAL_STATIC_LIBRARIES := libpng libwebp libxml2 spatialite libfreetype libcairo libcurl libgeotiff libtiff libgif libjpeg
-include $(BUILD_STATIC_LIBRARY)
diff --git a/rasterlite2-4.3.0.mk b/rasterlite2-4.3.0.mk
new file mode 100644
index 0000000..491c528
--- /dev/null
+++ b/rasterlite2-4.3.0.mk
@@ -0,0 +1,106 @@
+include $(CLEAR_VARS)
+# ./configure --build=x86_64-pc-linux-gnu --host=arm-linux-eabi
+LOCAL_MODULE    := rasterlite2
+
+# SQLite flags copied from ASOP [may not be needed for rasterlite2]
+common_sqlite_flags := \
+ -DHAVE_USLEEP=1 \
+ -DSQLITE_DEFAULT_JOURNAL_SIZE_LIMIT=1048576 \
+ -DSQLITE_THREADSAFE=1 \
+ -DNDEBUG=1 \
+ -DSQLITE_ENABLE_MEMORY_MANAGEMENT=1 \
+ -DSQLITE_DEFAULT_AUTOVACUUM=1 \
+ -DSQLITE_TEMP_STORE=3 \
+ -DSQLITE_ENABLE_FTS3 \
+ -DSQLITE_ENABLE_FTS3_BACKWARDS \
+ -DSQLITE_ENABLE_RTREE=1 \
+ -DSQLITE_DEFAULT_FILE_FORMAT=4
+
+# comment out TARGET_CPU in config.h - will be replaced with TARGET_ARCH_ABI
+spatialite_flags := \
+ -DOMIT_FREEXL \
+ -DTARGET_CPU=\"$(TARGET_ARCH_ABI)\" \
+ -Dfdatasync=fsync \
+ -DSQLITE_ENABLE_RTREE=1 \
+ -DENABLE_GCP=1 \
+ -DENABLE_GEOPACKAGE=1 \
+ -DENABLE_LIBXML2=1 \
+ -DSQLITE_OMIT_BUILTIN_TEST=1
+
+# comment out TARGET_CPU in config.h - will be replaced with TARGET_ARCH_ABI
+# comment out VERSION in config.h - manually set to avoid conflict with other packages
+rasterlite2_flags := \
+ -DTARGET_CPU=\"$(TARGET_ARCH_ABI)\" \
+ -DVERSION=\"0.9\" \
+ -O
+
+LOCAL_CFLAGS    := \
+ $(common_sqlite_flags) \
+ $(spatialite_flags) \
+ $(rasterlite2_flags)
+
+# 2014-10-03 - adapted based on ls -1 result
+LOCAL_C_INCLUDES := \
+ $(SQLITE_PATH) \
+ $(GEOTIFF_PATH)/libxtiff \
+ $(GEOTIFF_PATH) \
+ $(TIFF_PATH) \
+ $(JPEG_PATH) \
+ $(GIF_PATH) \
+ $(PNG_PATH) \
+ $(WEBP_PATH)/src/webp \
+ $(WEBP_PATH)/src/dec \
+ $(WEBP_PATH)/src/dsp \
+ $(WEBP_PATH)/src/enc \
+ $(WEBP_PATH)/src/utils \
+ $(WEBP_PATH)/src \
+ $(WEBP_PATH) \
+ $(CAIRO_PATH) \
+ $(FONTCONFIG_PATH) \
+ $(ICONV_PATH)/include \
+ $(FREETYPE_PATH)/include \
+ $(ICONV_PATH)/libcharset/include \
+ $(XML2_PATH)/include \
+ $(CURL_PATH) \
+ $(CURL_PATH)/include \
+ $(CURL_PATH)/lib \
+ $(RASTERLITE2_PATH) \
+ $(RASTERLITE2_PATH)/headers \
+ $(SPATIALITE_PATH)/src/headers \
+ $(LZMA_PATH)/src/liblzma/api \
+ $(OPENJPEG_PATH)/src/lib/openjp2 \
+ $(CHARLS_PATH)
+
+LOCAL_SRC_FILES := \
+ $(RASTERLITE2_PATH)/src/md5.c \
+ $(RASTERLITE2_PATH)/src/rasterlite2.c \
+ $(RASTERLITE2_PATH)/src/rl2ascii.c \
+ $(RASTERLITE2_PATH)/src/rl2auxfont.c \
+ $(RASTERLITE2_PATH)/src/rl2auxgeom.c \
+ $(RASTERLITE2_PATH)/src/rl2auxrender.c \
+ $(RASTERLITE2_PATH)/src/rl2charls.c \
+ $(RASTERLITE2_PATH)/src/rl2codec.c \
+ $(RASTERLITE2_PATH)/src/rl2dbms.c \
+ $(RASTERLITE2_PATH)/src/rl2gif.c \
+ $(RASTERLITE2_PATH)/src/rl2import.c \
+ $(RASTERLITE2_PATH)/src/rl2jpeg.c \
+ $(RASTERLITE2_PATH)/src/rl2md5.c \
+ $(RASTERLITE2_PATH)/src/rl2openjpeg.c \
+ $(RASTERLITE2_PATH)/src/rl2paint.c \
+ $(RASTERLITE2_PATH)/src/rl2png.c \
+ $(RASTERLITE2_PATH)/src/rl2pyramid.c \
+ $(RASTERLITE2_PATH)/src/rl2rastersym.c \
+ $(RASTERLITE2_PATH)/src/rl2raw.c \
+ $(RASTERLITE2_PATH)/src/rl2sql.c \
+ $(RASTERLITE2_PATH)/src/rl2sqlaux.c \
+ $(RASTERLITE2_PATH)/src/rl2svg.c \
+ $(RASTERLITE2_PATH)/src/rl2svgaux.c \
+ $(RASTERLITE2_PATH)/src/rl2svgxml.c \
+ $(RASTERLITE2_PATH)/src/rl2symbaux.c \
+ $(RASTERLITE2_PATH)/src/rl2symbolizer.c \
+ $(RASTERLITE2_PATH)/src/rl2tiff.c \
+ $(RASTERLITE2_PATH)/src/rl2version.c \
+ $(RASTERLITE2_PATH)/src/rl2webp.c \
+ $(RASTERLITE2_PATH)/src/rl2wms.c
+LOCAL_STATIC_LIBRARIES := libcharls libopenjpeg libpng libwebp libxml2 spatialite libfreetype libcairo libcurl libgeotiff libtiff libgif libjpeg
+include $(BUILD_STATIC_LIBRARY)
diff --git a/src/Makefile.am b/src/Makefile.am
index a16359b..6398558 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,38 +1,45 @@
 
 AM_CFLAGS = @LIBPNG_CFLAGS@ @LIBWEBP_CFLAGS@ @LIBLZMA_CFLAGS@ \
-	@LIBSPATIALITE_CFLAGS@ @LIBCAIRO_CFLAGS@ @LIBCURL_CFLAGS@ \
-	@LIBXML2_CFLAGS@ 
+	@LIBCAIRO_CFLAGS@ @LIBCURL_CFLAGS@ @LIBXML2_CFLAGS@ \
+	@LIBFREETYPE2_CFLAGS@
 
 AM_CPPFLAGS = @CFLAGS@
 AM_CPPFLAGS += -I$(top_srcdir)/headers
 
+noinst_HEADERS = md5.h
 lib_LTLIBRARIES = librasterlite2.la mod_rasterlite2.la
 
 librasterlite2_la_SOURCES = rasterlite2.c rl2raw.c rl2codec.c \
 	rl2jpeg.c rl2png.c rl2gif.c rl2webp.c rl2tiff.c rl2wms.c \
 	rl2ascii.c rl2paint.c rl2dbms.c rl2import.c rl2pyramid.c \
 	rl2sql.c rl2sqlaux.c rl2auxrender.c rl2svg.c rl2svgxml.c \
-	rl2svgaux.c rl2symbolizer.c rl2rastersym.c rl2version.c
+	rl2svgaux.c rl2symbolizer.c rl2symbaux.c rl2rastersym.c \
+	rl2version.c rl2md5.c md5.c rl2charls.c rl2openjpeg.c \
+	rl2auxgeom.c rl2auxfont.c
+
+librasterlite2_la_LIBADD = @LIBPNG_LIBS@ @LIBWEBP_LIBS@ \
+	@LIBLZMA_LIBS@ @LIBCAIRO_LIBS@	@LIBCURL_LIBS@ \
+	@LIBXML2_LIBS@ @LIBFREETYPE2_LIBS@
 
 if MINGW
 librasterlite2_la_LDFLAGS = -avoid-version -no-undefined
+librasterlite2_la_LIBADD += -lm
 else
-librasterlite2_la_LDFLAGS = -version-info 1:0:0
+librasterlite2_la_LDFLAGS = -version-info 0:0:0
+librasterlite2_la_LIBADD += -lpthread -lm
 endif
 
-librasterlite2_la_LIBADD = @LIBPNG_LIBS@ @LIBWEBP_LIBS@ \
-	@LIBLZMA_LIBS@ @LIBSPATIALITE_LIBS@ @LIBCAIRO_LIBS@ \
-	@LIBCURL_LIBS@ @LIBXML2_LIBS@
-
 mod_rasterlite2_la_SOURCES = rasterlite2.c rl2raw.c rl2codec.c \
 	rl2jpeg.c rl2png.c rl2gif.c rl2webp.c rl2tiff.c rl2wms.c \
 	rl2ascii.c rl2paint.c rl2dbms.c rl2import.c rl2pyramid.c \
 	rl2sql.c rl2sqlaux.c rl2auxrender.c rl2svg.c rl2svgxml.c \
-	rl2svgaux.c rl2symbolizer.c rl2rastersym.c rl2version.c
+	rl2svgaux.c rl2symbolizer.c rl2symbaux.c rl2rastersym.c \
+	rl2version.c rl2md5.c md5.c rl2charls.c rl2openjpeg.c \
+	rl2auxgeom.c rl2auxfont.c
 
 mod_rasterlite2_la_LIBADD = @LIBPNG_LIBS@ @LIBWEBP_LIBS@ \
-	@LIBLZMA_LIBS@ @LIBSPATIALITE_LIBS@ @LIBCAIRO_LIBS@ \
-	@LIBCURL_LIBS@ @LIBXML2_LIBS@
+	@LIBLZMA_LIBS@ @LIBCAIRO_LIBS@ @LIBCURL_LIBS@ \
+	@LIBXML2_LIBS@ @LIBFREETYPE2_LIBS@
 
 mod_rasterlite2_la_CPPFLAGS = @CFLAGS@
 mod_rasterlite2_la_CPPFLAGS += -I$(top_srcdir)/headers -I.
@@ -41,8 +48,10 @@ mod_rasterlite2_la_LIBTOOLFLAGS = --tag=disable-static
 
 if MINGW
 mod_rasterlite2_la_LDFLAGS = -module -avoid-version -no-undefined
+mod_rasterlite2_la_LIBADD += -lm
 else
-mod_rasterlite2_la_LDFLAGS = -module -version-info 1:0:0
+mod_rasterlite2_la_LDFLAGS = -module -version-info 0:0:0
+mod_rasterlite2_la_LIBADD += -lpthread -lm
 endif
 
 MOSTLYCLEANFILES = *.gcna *.gcno *.gcda
diff --git a/src/Makefile.in b/src/Makefile.in
index 439348f..d3acb32 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# Makefile.in generated by automake 1.15 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,8 +14,19 @@
 
 @SET_MAKE@
 
+
 VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -78,9 +89,11 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
+ at MINGW_TRUE@am__append_1 = -lm
+ at MINGW_FALSE@am__append_2 = -lpthread -lm
+ at MINGW_TRUE@am__append_3 = -lm
+ at MINGW_FALSE@am__append_4 = -lpthread -lm
 subdir = src
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
-	$(top_srcdir)/depcomp
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
@@ -88,6 +101,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \
+	$(am__DIST_COMMON)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -121,12 +136,16 @@ am__uninstall_files_from_dir = { \
   }
 am__installdirs = "$(DESTDIR)$(libdir)"
 LTLIBRARIES = $(lib_LTLIBRARIES)
-librasterlite2_la_DEPENDENCIES =
+am__DEPENDENCIES_1 =
+librasterlite2_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
 am_librasterlite2_la_OBJECTS = rasterlite2.lo rl2raw.lo rl2codec.lo \
 	rl2jpeg.lo rl2png.lo rl2gif.lo rl2webp.lo rl2tiff.lo rl2wms.lo \
 	rl2ascii.lo rl2paint.lo rl2dbms.lo rl2import.lo rl2pyramid.lo \
 	rl2sql.lo rl2sqlaux.lo rl2auxrender.lo rl2svg.lo rl2svgxml.lo \
-	rl2svgaux.lo rl2symbolizer.lo rl2rastersym.lo rl2version.lo
+	rl2svgaux.lo rl2symbolizer.lo rl2symbaux.lo rl2rastersym.lo \
+	rl2version.lo rl2md5.lo md5.lo rl2charls.lo rl2openjpeg.lo \
+	rl2auxgeom.lo rl2auxfont.lo
 librasterlite2_la_OBJECTS = $(am_librasterlite2_la_OBJECTS)
 AM_V_lt = $(am__v_lt_ at AM_V@)
 am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
@@ -136,7 +155,8 @@ librasterlite2_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
 	$(AM_CFLAGS) $(CFLAGS) $(librasterlite2_la_LDFLAGS) $(LDFLAGS) \
 	-o $@
-mod_rasterlite2_la_DEPENDENCIES =
+mod_rasterlite2_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
 am_mod_rasterlite2_la_OBJECTS = mod_rasterlite2_la-rasterlite2.lo \
 	mod_rasterlite2_la-rl2raw.lo mod_rasterlite2_la-rl2codec.lo \
 	mod_rasterlite2_la-rl2jpeg.lo mod_rasterlite2_la-rl2png.lo \
@@ -150,8 +170,13 @@ am_mod_rasterlite2_la_OBJECTS = mod_rasterlite2_la-rasterlite2.lo \
 	mod_rasterlite2_la-rl2svg.lo mod_rasterlite2_la-rl2svgxml.lo \
 	mod_rasterlite2_la-rl2svgaux.lo \
 	mod_rasterlite2_la-rl2symbolizer.lo \
+	mod_rasterlite2_la-rl2symbaux.lo \
 	mod_rasterlite2_la-rl2rastersym.lo \
-	mod_rasterlite2_la-rl2version.lo
+	mod_rasterlite2_la-rl2version.lo mod_rasterlite2_la-rl2md5.lo \
+	mod_rasterlite2_la-md5.lo mod_rasterlite2_la-rl2charls.lo \
+	mod_rasterlite2_la-rl2openjpeg.lo \
+	mod_rasterlite2_la-rl2auxgeom.lo \
+	mod_rasterlite2_la-rl2auxfont.lo
 mod_rasterlite2_la_OBJECTS = $(am_mod_rasterlite2_la_OBJECTS)
 mod_rasterlite2_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
 	$(mod_rasterlite2_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \
@@ -199,6 +224,7 @@ am__can_run_installinfo = \
     n|no|NO) false;; \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
+HEADERS = $(noinst_HEADERS)
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
 # Read a list of newline-separated strings from the standard input,
 # and print each of them once, without duplicates.  Input order is
@@ -218,6 +244,7 @@ am__define_uniq_tagged_files = \
   done | $(am__uniquify_input)`
 ETAGS = etags
 CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -249,6 +276,8 @@ ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
+FREETYPE2_CFLAGS = @FREETYPE2_CFLAGS@
+FREETYPE2_LIBS = @FREETYPE2_LIBS@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
@@ -261,6 +290,8 @@ LIBCAIRO_CFLAGS = @LIBCAIRO_CFLAGS@
 LIBCAIRO_LIBS = @LIBCAIRO_LIBS@
 LIBCURL_CFLAGS = @LIBCURL_CFLAGS@
 LIBCURL_LIBS = @LIBCURL_LIBS@
+LIBFREETYPE2_CFLAGS = @LIBFREETYPE2_CFLAGS@
+LIBFREETYPE2_LIBS = @LIBFREETYPE2_LIBS@
 LIBLZMA_CFLAGS = @LIBLZMA_CFLAGS@
 LIBLZMA_LIBS = @LIBLZMA_LIBS@
 LIBOBJS = @LIBOBJS@
@@ -358,37 +389,40 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 AM_CFLAGS = @LIBPNG_CFLAGS@ @LIBWEBP_CFLAGS@ @LIBLZMA_CFLAGS@ \
-	@LIBSPATIALITE_CFLAGS@ @LIBCAIRO_CFLAGS@ @LIBCURL_CFLAGS@ \
-	@LIBXML2_CFLAGS@ 
+	@LIBCAIRO_CFLAGS@ @LIBCURL_CFLAGS@ @LIBXML2_CFLAGS@ \
+	@LIBFREETYPE2_CFLAGS@
 
 AM_CPPFLAGS = @CFLAGS@ -I$(top_srcdir)/headers
+noinst_HEADERS = md5.h
 lib_LTLIBRARIES = librasterlite2.la mod_rasterlite2.la
 librasterlite2_la_SOURCES = rasterlite2.c rl2raw.c rl2codec.c \
 	rl2jpeg.c rl2png.c rl2gif.c rl2webp.c rl2tiff.c rl2wms.c \
 	rl2ascii.c rl2paint.c rl2dbms.c rl2import.c rl2pyramid.c \
 	rl2sql.c rl2sqlaux.c rl2auxrender.c rl2svg.c rl2svgxml.c \
-	rl2svgaux.c rl2symbolizer.c rl2rastersym.c rl2version.c
-
- at MINGW_FALSE@librasterlite2_la_LDFLAGS = -version-info 1:0:0
+	rl2svgaux.c rl2symbolizer.c rl2symbaux.c rl2rastersym.c \
+	rl2version.c rl2md5.c md5.c rl2charls.c rl2openjpeg.c \
+	rl2auxgeom.c rl2auxfont.c
+
+librasterlite2_la_LIBADD = @LIBPNG_LIBS@ @LIBWEBP_LIBS@ @LIBLZMA_LIBS@ \
+	@LIBCAIRO_LIBS@ @LIBCURL_LIBS@ @LIBXML2_LIBS@ \
+	@LIBFREETYPE2_LIBS@ $(am__append_1) $(am__append_2)
+ at MINGW_FALSE@librasterlite2_la_LDFLAGS = -version-info 0:0:0
 @MINGW_TRUE at librasterlite2_la_LDFLAGS = -avoid-version -no-undefined
-librasterlite2_la_LIBADD = @LIBPNG_LIBS@ @LIBWEBP_LIBS@ \
-	@LIBLZMA_LIBS@ @LIBSPATIALITE_LIBS@ @LIBCAIRO_LIBS@ \
-	@LIBCURL_LIBS@ @LIBXML2_LIBS@
-
 mod_rasterlite2_la_SOURCES = rasterlite2.c rl2raw.c rl2codec.c \
 	rl2jpeg.c rl2png.c rl2gif.c rl2webp.c rl2tiff.c rl2wms.c \
 	rl2ascii.c rl2paint.c rl2dbms.c rl2import.c rl2pyramid.c \
 	rl2sql.c rl2sqlaux.c rl2auxrender.c rl2svg.c rl2svgxml.c \
-	rl2svgaux.c rl2symbolizer.c rl2rastersym.c rl2version.c
+	rl2svgaux.c rl2symbolizer.c rl2symbaux.c rl2rastersym.c \
+	rl2version.c rl2md5.c md5.c rl2charls.c rl2openjpeg.c \
+	rl2auxgeom.c rl2auxfont.c
 
 mod_rasterlite2_la_LIBADD = @LIBPNG_LIBS@ @LIBWEBP_LIBS@ \
-	@LIBLZMA_LIBS@ @LIBSPATIALITE_LIBS@ @LIBCAIRO_LIBS@ \
-	@LIBCURL_LIBS@ @LIBXML2_LIBS@
-
+	@LIBLZMA_LIBS@ @LIBCAIRO_LIBS@ @LIBCURL_LIBS@ @LIBXML2_LIBS@ \
+	@LIBFREETYPE2_LIBS@ $(am__append_3) $(am__append_4)
 mod_rasterlite2_la_CPPFLAGS = @CFLAGS@ -I$(top_srcdir)/headers -I. \
 	-DLOADABLE_EXTENSION
 mod_rasterlite2_la_LIBTOOLFLAGS = --tag=disable-static
- at MINGW_FALSE@mod_rasterlite2_la_LDFLAGS = -module -version-info 1:0:0
+ at MINGW_FALSE@mod_rasterlite2_la_LDFLAGS = -module -version-info 0:0:0
 @MINGW_TRUE at mod_rasterlite2_la_LDFLAGS = -module -avoid-version -no-undefined
 MOSTLYCLEANFILES = *.gcna *.gcno *.gcda
 all: all-am
@@ -407,7 +441,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__confi
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu src/Makefile
-.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -473,14 +506,21 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/md5.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_rasterlite2_la-md5.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_rasterlite2_la-rasterlite2.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_rasterlite2_la-rl2ascii.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_rasterlite2_la-rl2auxfont.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_rasterlite2_la-rl2auxgeom.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_rasterlite2_la-rl2auxrender.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_rasterlite2_la-rl2charls.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_rasterlite2_la-rl2codec.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_rasterlite2_la-rl2dbms.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_rasterlite2_la-rl2gif.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_rasterlite2_la-rl2import.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_rasterlite2_la-rl2jpeg.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_rasterlite2_la-rl2md5.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_rasterlite2_la-rl2openjpeg.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_rasterlite2_la-rl2paint.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_rasterlite2_la-rl2png.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_rasterlite2_la-rl2pyramid.Plo at am__quote@
@@ -491,6 +531,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_rasterlite2_la-rl2svg.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_rasterlite2_la-rl2svgaux.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_rasterlite2_la-rl2svgxml.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_rasterlite2_la-rl2symbaux.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_rasterlite2_la-rl2symbolizer.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_rasterlite2_la-rl2tiff.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_rasterlite2_la-rl2version.Plo at am__quote@
@@ -498,12 +539,17 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mod_rasterlite2_la-rl2wms.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rasterlite2.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rl2ascii.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rl2auxfont.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rl2auxgeom.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rl2auxrender.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rl2charls.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rl2codec.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rl2dbms.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rl2gif.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rl2import.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rl2jpeg.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rl2md5.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rl2openjpeg.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rl2paint.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rl2png.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rl2pyramid.Plo at am__quote@
@@ -514,6 +560,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rl2svg.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rl2svgaux.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rl2svgxml.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rl2symbaux.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rl2symbolizer.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rl2tiff.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rl2version.Plo at am__quote@
@@ -525,14 +572,14 @@ distclean-compile:
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c $<
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ $<
 
 .c.obj:
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
 
 .c.lo:
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -688,6 +735,13 @@ mod_rasterlite2_la-rl2symbolizer.lo: rl2symbolizer.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(mod_rasterlite2_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mod_rasterlite2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mod_rasterlite2_la-rl2symbolizer.lo `test -f 'rl2symbolizer.c' || echo '$(srcdir)/'`rl2symbolizer.c
 
+mod_rasterlite2_la-rl2symbaux.lo: rl2symbaux.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(mod_rasterlite2_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mod_rasterlite2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mod_rasterlite2_la-rl2symbaux.lo -MD -MP -MF $(DEPDIR)/mod_rasterlite2_la-rl2symbaux.Tpo -c -o mod_rasterlite2_la-rl2symbaux.lo `test -f 'rl2symbaux.c' || echo '$(srcdir)/'`rl2symbaux.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/mod_rasterlite2_la-rl2symbaux.Tpo $(DEPDIR)/mod_rasterlite2_la-rl2symbaux.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='rl2symbaux.c' object='mod_rasterlite2_la-rl2symbaux.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(mod_rasterlite2_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mod_rasterlite2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mod_rasterlite2_la-rl2symbaux.lo `test -f 'rl2symbaux.c' || echo '$(srcdir)/'`rl2symbaux.c
+
 mod_rasterlite2_la-rl2rastersym.lo: rl2rastersym.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(mod_rasterlite2_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mod_rasterlite2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mod_rasterlite2_la-rl2rastersym.lo -MD -MP -MF $(DEPDIR)/mod_rasterlite2_la-rl2rastersym.Tpo -c -o mod_rasterlite2_la-rl2rastersym.lo `test -f 'rl2rastersym.c' || echo '$(srcdir)/'`rl2rastersym.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/mod_rasterlite2_la-rl2rastersym.Tpo $(DEPDIR)/mod_rasterlite2_la-rl2rastersym.Plo
@@ -702,6 +756,48 @@ mod_rasterlite2_la-rl2version.lo: rl2version.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(mod_rasterlite2_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mod_rasterlite2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mod_rasterlite2_la-rl2version.lo `test -f 'rl2version.c' || echo '$(srcdir)/'`rl2version.c
 
+mod_rasterlite2_la-rl2md5.lo: rl2md5.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(mod_rasterlite2_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mod_rasterlite2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mod_rasterlite2_la-rl2md5.lo -MD -MP -MF $(DEPDIR)/mod_rasterlite2_la-rl2md5.Tpo -c -o mod_rasterlite2_la-rl2md5.lo `test -f 'rl2md5.c' || echo '$(srcdir)/'`rl2md5.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/mod_rasterlite2_la-rl2md5.Tpo $(DEPDIR)/mod_rasterlite2_la-rl2md5.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='rl2md5.c' object='mod_rasterlite2_la-rl2md5.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(mod_rasterlite2_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mod_rasterlite2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mod_rasterlite2_la-rl2md5.lo `test -f 'rl2md5.c' || echo '$(srcdir)/'`rl2md5.c
+
+mod_rasterlite2_la-md5.lo: md5.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(mod_rasterlite2_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mod_rasterlite2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mod_rasterlite2_la-md5.lo -MD -MP -MF $(DEPDIR)/mod_rasterlite2_la-md5.Tpo -c -o mod_rasterlite2_la-md5.lo `test -f 'md5.c' || echo '$(srcdir)/'`md5.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/mod_rasterlite2_la-md5.Tpo $(DEPDIR)/mod_rasterlite2_la-md5.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='md5.c' object='mod_rasterlite2_la-md5.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(mod_rasterlite2_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mod_rasterlite2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mod_rasterlite2_la-md5.lo `test -f 'md5.c' || echo '$(srcdir)/'`md5.c
+
+mod_rasterlite2_la-rl2charls.lo: rl2charls.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(mod_rasterlite2_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mod_rasterlite2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mod_rasterlite2_la-rl2charls.lo -MD -MP -MF $(DEPDIR)/mod_rasterlite2_la-rl2charls.Tpo -c -o mod_rasterlite2_la-rl2charls.lo `test -f 'rl2charls.c' || echo '$(srcdir)/'`rl2charls.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/mod_rasterlite2_la-rl2charls.Tpo $(DEPDIR)/mod_rasterlite2_la-rl2charls.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='rl2charls.c' object='mod_rasterlite2_la-rl2charls.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(mod_rasterlite2_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mod_rasterlite2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mod_rasterlite2_la-rl2charls.lo `test -f 'rl2charls.c' || echo '$(srcdir)/'`rl2charls.c
+
+mod_rasterlite2_la-rl2openjpeg.lo: rl2openjpeg.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(mod_rasterlite2_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mod_rasterlite2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mod_rasterlite2_la-rl2openjpeg.lo -MD -MP -MF $(DEPDIR)/mod_rasterlite2_la-rl2openjpeg.Tpo -c -o mod_rasterlite2_la-rl2openjpeg.lo `test -f 'rl2openjpeg.c' || echo '$(srcdir)/'`rl2openjpeg.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/mod_rasterlite2_la-rl2openjpeg.Tpo $(DEPDIR)/mod_rasterlite2_la-rl2openjpeg.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='rl2openjpeg.c' object='mod_rasterlite2_la-rl2openjpeg.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(mod_rasterlite2_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mod_rasterlite2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mod_rasterlite2_la-rl2openjpeg.lo `test -f 'rl2openjpeg.c' || echo '$(srcdir)/'`rl2openjpeg.c
+
+mod_rasterlite2_la-rl2auxgeom.lo: rl2auxgeom.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(mod_rasterlite2_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mod_rasterlite2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mod_rasterlite2_la-rl2auxgeom.lo -MD -MP -MF $(DEPDIR)/mod_rasterlite2_la-rl2auxgeom.Tpo -c -o mod_rasterlite2_la-rl2auxgeom.lo `test -f 'rl2auxgeom.c' || echo '$(srcdir)/'`rl2auxgeom.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/mod_rasterlite2_la-rl2auxgeom.Tpo $(DEPDIR)/mod_rasterlite2_la-rl2auxgeom.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='rl2auxgeom.c' object='mod_rasterlite2_la-rl2auxgeom.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(mod_rasterlite2_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mod_rasterlite2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mod_rasterlite2_la-rl2auxgeom.lo `test -f 'rl2auxgeom.c' || echo '$(srcdir)/'`rl2auxgeom.c
+
+mod_rasterlite2_la-rl2auxfont.lo: rl2auxfont.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(mod_rasterlite2_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mod_rasterlite2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT mod_rasterlite2_la-rl2auxfont.lo -MD -MP -MF $(DEPDIR)/mod_rasterlite2_la-rl2auxfont.Tpo -c -o mod_rasterlite2_la-rl2auxfont.lo `test -f 'rl2auxfont.c' || echo '$(srcdir)/'`rl2auxfont.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/mod_rasterlite2_la-rl2auxfont.Tpo $(DEPDIR)/mod_rasterlite2_la-rl2auxfont.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='rl2auxfont.c' object='mod_rasterlite2_la-rl2auxfont.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(mod_rasterlite2_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mod_rasterlite2_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o mod_rasterlite2_la-rl2auxfont.lo `test -f 'rl2auxfont.c' || echo '$(srcdir)/'`rl2auxfont.c
+
 mostlyclean-libtool:
 	-rm -f *.lo
 
@@ -792,7 +888,7 @@ distdir: $(DISTFILES)
 	done
 check-am: all-am
 check: check-am
-all-am: Makefile $(LTLIBRARIES)
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
 installdirs:
 	for dir in "$(DESTDIR)$(libdir)"; do \
 	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
@@ -915,6 +1011,8 @@ uninstall-am: uninstall-libLTLIBRARIES
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES
 
+.PRECIOUS: Makefile
+
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/src/md5.c b/src/md5.c
new file mode 100644
index 0000000..7e0174a
--- /dev/null
+++ b/src/md5.c
@@ -0,0 +1,307 @@
+/*
+ * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
+ * MD5 Message-Digest Algorithm (RFC 1321).
+ *
+ * Homepage:
+ * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
+ *
+ * Author:
+ * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
+ *
+ * This software was written by Alexander Peslyak in 2001.  No copyright is
+ * claimed, and the software is hereby placed in the public domain.
+ * In case this attempt to disclaim copyright and place the software in the
+ * public domain is deemed null and void, then the software is
+ * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
+ * general public under the following terms:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
+ *
+ * (This is a heavily cut-down "BSD license".)
+ *
+ * This differs from Colin Plumb's older public domain implementation in that
+ * no exactly 32-bit integer data type is required (any 32-bit or wider
+ * unsigned integer data type will do), there's no compile-time endianness
+ * configuration, and the function prototypes match OpenSSL's.  No code from
+ * Colin Plumb's implementation has been reused; this comment merely compares
+ * the properties of the two independent implementations.
+ *
+ * The primary goals of this implementation are portability and ease of use.
+ * It is meant to be fast, but not as fast as possible.  Some known
+ * optimizations are not included to reduce source code size and avoid
+ * compile-time configuration.
+ */
+
+#ifndef HAVE_OPENSSL
+
+#include <string.h>
+
+#include "md5.h"
+
+/*
+ * The basic MD5 functions.
+ *
+ * F and G are optimized compared to their RFC 1321 definitions for
+ * architectures that lack an AND-NOT instruction, just like in Colin Plumb's
+ * implementation.
+ */
+#define F(x, y, z)			((z) ^ ((x) & ((y) ^ (z))))
+#define G(x, y, z)			((y) ^ ((z) & ((x) ^ (y))))
+#define H(x, y, z)			((x) ^ (y) ^ (z))
+#define I(x, y, z)			((y) ^ ((x) | ~(z)))
+
+/*
+ * The MD5 transformation for all four rounds.
+ */
+#define STEP(f, a, b, c, d, x, t, s) \
+	(a) += f((b), (c), (d)) + (x) + (t); \
+	(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
+	(a) += (b);
+
+/*
+ * SET reads 4 input bytes in little-endian byte order and stores them
+ * in a properly aligned word in host byte order.
+ *
+ * The check for little-endian architectures that tolerate unaligned
+ * memory accesses is just an optimization.  Nothing will break if it
+ * doesn't work.
+ */
+#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
+#define SET(n) \
+	(*(MD5_u32plus *)&ptr[(n) * 4])
+#define GET(n) \
+	SET(n)
+#else
+#define SET(n) \
+	(ctx->block[(n)] = \
+	(MD5_u32plus)ptr[(n) * 4] | \
+	((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
+	((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
+	((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
+#define GET(n) \
+	(ctx->block[(n)])
+#endif
+
+/*
+ * This processes one or more 64-byte data blocks, but does NOT update
+ * the bit counters.  There are no alignment requirements.
+ */
+static void *
+body (MD5_CTX * ctx, void *data, unsigned long size)
+{
+    unsigned char *ptr;
+    MD5_u32plus a, b, c, d;
+    MD5_u32plus saved_a, saved_b, saved_c, saved_d;
+
+    ptr = data;
+
+    a = ctx->a;
+    b = ctx->b;
+    c = ctx->c;
+    d = ctx->d;
+
+    do
+      {
+	  saved_a = a;
+	  saved_b = b;
+	  saved_c = c;
+	  saved_d = d;
+
+/* Round 1 */
+	  STEP (F, a, b, c, d, SET (0), 0xd76aa478, 7)
+	      STEP (F, d, a, b, c, SET (1), 0xe8c7b756, 12)
+	      STEP (F, c, d, a, b, SET (2), 0x242070db, 17)
+	      STEP (F, b, c, d, a, SET (3), 0xc1bdceee, 22)
+	      STEP (F, a, b, c, d, SET (4), 0xf57c0faf, 7)
+	      STEP (F, d, a, b, c, SET (5), 0x4787c62a, 12)
+	      STEP (F, c, d, a, b, SET (6), 0xa8304613, 17)
+	      STEP (F, b, c, d, a, SET (7), 0xfd469501, 22)
+	      STEP (F, a, b, c, d, SET (8), 0x698098d8, 7)
+	      STEP (F, d, a, b, c, SET (9), 0x8b44f7af, 12)
+	      STEP (F, c, d, a, b, SET (10), 0xffff5bb1, 17)
+	      STEP (F, b, c, d, a, SET (11), 0x895cd7be, 22)
+	      STEP (F, a, b, c, d, SET (12), 0x6b901122, 7)
+	      STEP (F, d, a, b, c, SET (13), 0xfd987193, 12)
+	      STEP (F, c, d, a, b, SET (14), 0xa679438e, 17)
+	      STEP (F, b, c, d, a, SET (15), 0x49b40821, 22)
+/* Round 2 */
+	      STEP (G, a, b, c, d, GET (1), 0xf61e2562, 5)
+	      STEP (G, d, a, b, c, GET (6), 0xc040b340, 9)
+	      STEP (G, c, d, a, b, GET (11), 0x265e5a51, 14)
+	      STEP (G, b, c, d, a, GET (0), 0xe9b6c7aa, 20)
+	      STEP (G, a, b, c, d, GET (5), 0xd62f105d, 5)
+	      STEP (G, d, a, b, c, GET (10), 0x02441453, 9)
+	      STEP (G, c, d, a, b, GET (15), 0xd8a1e681, 14)
+	      STEP (G, b, c, d, a, GET (4), 0xe7d3fbc8, 20)
+	      STEP (G, a, b, c, d, GET (9), 0x21e1cde6, 5)
+	      STEP (G, d, a, b, c, GET (14), 0xc33707d6, 9)
+	      STEP (G, c, d, a, b, GET (3), 0xf4d50d87, 14)
+	      STEP (G, b, c, d, a, GET (8), 0x455a14ed, 20)
+	      STEP (G, a, b, c, d, GET (13), 0xa9e3e905, 5)
+	      STEP (G, d, a, b, c, GET (2), 0xfcefa3f8, 9)
+	      STEP (G, c, d, a, b, GET (7), 0x676f02d9, 14)
+	      STEP (G, b, c, d, a, GET (12), 0x8d2a4c8a, 20)
+/* Round 3 */
+	      STEP (H, a, b, c, d, GET (5), 0xfffa3942, 4)
+	      STEP (H, d, a, b, c, GET (8), 0x8771f681, 11)
+	      STEP (H, c, d, a, b, GET (11), 0x6d9d6122, 16)
+	      STEP (H, b, c, d, a, GET (14), 0xfde5380c, 23)
+	      STEP (H, a, b, c, d, GET (1), 0xa4beea44, 4)
+	      STEP (H, d, a, b, c, GET (4), 0x4bdecfa9, 11)
+	      STEP (H, c, d, a, b, GET (7), 0xf6bb4b60, 16)
+	      STEP (H, b, c, d, a, GET (10), 0xbebfbc70, 23)
+	      STEP (H, a, b, c, d, GET (13), 0x289b7ec6, 4)
+	      STEP (H, d, a, b, c, GET (0), 0xeaa127fa, 11)
+	      STEP (H, c, d, a, b, GET (3), 0xd4ef3085, 16)
+	      STEP (H, b, c, d, a, GET (6), 0x04881d05, 23)
+	      STEP (H, a, b, c, d, GET (9), 0xd9d4d039, 4)
+	      STEP (H, d, a, b, c, GET (12), 0xe6db99e5, 11)
+	      STEP (H, c, d, a, b, GET (15), 0x1fa27cf8, 16)
+	      STEP (H, b, c, d, a, GET (2), 0xc4ac5665, 23)
+/* Round 4 */
+	      STEP (I, a, b, c, d, GET (0), 0xf4292244, 6)
+	      STEP (I, d, a, b, c, GET (7), 0x432aff97, 10)
+	      STEP (I, c, d, a, b, GET (14), 0xab9423a7, 15)
+	      STEP (I, b, c, d, a, GET (5), 0xfc93a039, 21)
+	      STEP (I, a, b, c, d, GET (12), 0x655b59c3, 6)
+	      STEP (I, d, a, b, c, GET (3), 0x8f0ccc92, 10)
+	      STEP (I, c, d, a, b, GET (10), 0xffeff47d, 15)
+	      STEP (I, b, c, d, a, GET (1), 0x85845dd1, 21)
+	      STEP (I, a, b, c, d, GET (8), 0x6fa87e4f, 6)
+	      STEP (I, d, a, b, c, GET (15), 0xfe2ce6e0, 10)
+	      STEP (I, c, d, a, b, GET (6), 0xa3014314, 15)
+	      STEP (I, b, c, d, a, GET (13), 0x4e0811a1, 21)
+	      STEP (I, a, b, c, d, GET (4), 0xf7537e82, 6)
+	      STEP (I, d, a, b, c, GET (11), 0xbd3af235, 10)
+	      STEP (I, c, d, a, b, GET (2), 0x2ad7d2bb, 15)
+	      STEP (I, b, c, d, a, GET (9), 0xeb86d391, 21) a += saved_a;
+	  b += saved_b;
+	  c += saved_c;
+	  d += saved_d;
+
+	  ptr += 64;
+      }
+    while (size -= 64);
+
+    ctx->a = a;
+    ctx->b = b;
+    ctx->c = c;
+    ctx->d = d;
+
+    return ptr;
+}
+
+/* 
+  Sandro Furieri - RasterLite2 - 2014-08-05 
+
+  simply re-declaring all these functions as PRIVATE
+  (not externally visible outside librastetlite itself)
+*/
+
+MD5_PRIVATE void
+rl2_MD5_Init (MD5_CTX * ctx)
+{
+    ctx->a = 0x67452301;
+    ctx->b = 0xefcdab89;
+    ctx->c = 0x98badcfe;
+    ctx->d = 0x10325476;
+
+    ctx->lo = 0;
+    ctx->hi = 0;
+}
+
+MD5_PRIVATE void
+rl2_MD5_Update (MD5_CTX * ctx, void *data, unsigned long size)
+{
+    MD5_u32plus saved_lo;
+    unsigned long used, free;
+
+    saved_lo = ctx->lo;
+    if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
+	ctx->hi++;
+    ctx->hi += size >> 29;
+
+    used = saved_lo & 0x3f;
+
+    if (used)
+      {
+	  free = 64 - used;
+
+	  if (size < free)
+	    {
+		memcpy (&ctx->buffer[used], data, size);
+		return;
+	    }
+
+	  memcpy (&ctx->buffer[used], data, free);
+	  data = (unsigned char *) data + free;
+	  size -= free;
+	  body (ctx, ctx->buffer, 64);
+      }
+
+    if (size >= 64)
+      {
+	  data = body (ctx, data, size & ~(unsigned long) 0x3f);
+	  size &= 0x3f;
+      }
+
+    memcpy (ctx->buffer, data, size);
+}
+
+MD5_PRIVATE void
+rl2_MD5_Final (unsigned char *result, MD5_CTX * ctx)
+{
+    unsigned long used, free;
+
+    used = ctx->lo & 0x3f;
+
+    ctx->buffer[used++] = 0x80;
+
+    free = 64 - used;
+
+    if (free < 8)
+      {
+	  memset (&ctx->buffer[used], 0, free);
+	  body (ctx, ctx->buffer, 64);
+	  used = 0;
+	  free = 64;
+      }
+
+    memset (&ctx->buffer[used], 0, free - 8);
+
+    ctx->lo <<= 3;
+    ctx->buffer[56] = ctx->lo;
+    ctx->buffer[57] = ctx->lo >> 8;
+    ctx->buffer[58] = ctx->lo >> 16;
+    ctx->buffer[59] = ctx->lo >> 24;
+    ctx->buffer[60] = ctx->hi;
+    ctx->buffer[61] = ctx->hi >> 8;
+    ctx->buffer[62] = ctx->hi >> 16;
+    ctx->buffer[63] = ctx->hi >> 24;
+
+    body (ctx, ctx->buffer, 64);
+
+    result[0] = ctx->a;
+    result[1] = ctx->a >> 8;
+    result[2] = ctx->a >> 16;
+    result[3] = ctx->a >> 24;
+    result[4] = ctx->b;
+    result[5] = ctx->b >> 8;
+    result[6] = ctx->b >> 16;
+    result[7] = ctx->b >> 24;
+    result[8] = ctx->c;
+    result[9] = ctx->c >> 8;
+    result[10] = ctx->c >> 16;
+    result[11] = ctx->c >> 24;
+    result[12] = ctx->d;
+    result[13] = ctx->d >> 8;
+    result[14] = ctx->d >> 16;
+    result[15] = ctx->d >> 24;
+
+    memset (ctx, 0, sizeof (*ctx));
+}
+
+#endif
diff --git a/src/md5.h b/src/md5.h
new file mode 100644
index 0000000..d756029
--- /dev/null
+++ b/src/md5.h
@@ -0,0 +1,65 @@
+/*
+ * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
+ * MD5 Message-Digest Algorithm (RFC 1321).
+ *
+ * Homepage:
+ * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
+ *
+ * Author:
+ * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
+ *
+ * This software was written by Alexander Peslyak in 2001.  No copyright is
+ * claimed, and the software is hereby placed in the public domain.
+ * In case this attempt to disclaim copyright and place the software in the
+ * public domain is deemed null and void, then the software is
+ * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
+ * general public under the following terms:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted.
+ *
+ * There's ABSOLUTELY NO WARRANTY, express or implied.
+ *
+ * See md5.c for more information.
+ */
+
+#ifdef HAVE_OPENSSL
+#include <openssl/md5.h>
+#elif !defined(_MD5_H)
+#define _MD5_H
+
+/*
+
+ RasterLite2 private MD5 declarations
+
+ Sandro Furieri - 2014-08-05
+*/
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+#ifdef _WIN32
+#ifdef DLL_EXPORT
+#define MD5_PRIVATE
+#else
+#define MD5_PRIVATE
+#endif
+#else
+#define MD5_PRIVATE __attribute__ ((visibility("hidden")))
+#endif
+#endif
+/* end Sandro Furieri - RasterLite2 - 2014-08-05 */
+
+/* Any 32-bit or wider unsigned integer data type will do */
+typedef unsigned int MD5_u32plus;
+
+typedef struct
+{
+    MD5_u32plus lo, hi;
+    MD5_u32plus a, b, c, d;
+    unsigned char buffer[64];
+    MD5_u32plus block[16];
+} MD5_CTX;
+
+MD5_PRIVATE void rl2_MD5_Init (MD5_CTX * ctx);
+MD5_PRIVATE void rl2_MD5_Update (MD5_CTX * ctx, void *data, unsigned long size);
+MD5_PRIVATE void rl2_MD5_Final (unsigned char *result, MD5_CTX * ctx);
+
+#endif
diff --git a/src/rasterlite2.c b/src/rasterlite2.c
index d63465e..1f7e63c 100644
--- a/src/rasterlite2.c
+++ b/src/rasterlite2.c
@@ -20,7 +20,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -102,13 +102,17 @@ is_valid_compression (unsigned char compression)
       {
       case RL2_COMPRESSION_NONE:
       case RL2_COMPRESSION_DEFLATE:
+      case RL2_COMPRESSION_DEFLATE_NO:
       case RL2_COMPRESSION_LZMA:
-      case RL2_COMPRESSION_GIF:
+      case RL2_COMPRESSION_LZMA_NO:
       case RL2_COMPRESSION_PNG:
       case RL2_COMPRESSION_JPEG:
       case RL2_COMPRESSION_LOSSY_WEBP:
       case RL2_COMPRESSION_LOSSLESS_WEBP:
       case RL2_COMPRESSION_CCITTFAX4:
+      case RL2_COMPRESSION_CHARLS:
+      case RL2_COMPRESSION_LOSSY_JP2:
+      case RL2_COMPRESSION_LOSSLESS_JP2:
 	  return 1;
       };
     return 0;
@@ -129,6 +133,10 @@ check_coverage_self_consistency (unsigned char sample_type,
 	  switch (compression)
 	    {
 	    case RL2_COMPRESSION_NONE:
+	    case RL2_COMPRESSION_DEFLATE:
+	    case RL2_COMPRESSION_DEFLATE_NO:
+	    case RL2_COMPRESSION_LZMA:
+	    case RL2_COMPRESSION_LZMA_NO:
 	    case RL2_COMPRESSION_PNG:
 	    case RL2_COMPRESSION_CCITTFAX4:
 		break;
@@ -153,6 +161,10 @@ check_coverage_self_consistency (unsigned char sample_type,
 	    {
 	    case RL2_COMPRESSION_NONE:
 	    case RL2_COMPRESSION_GIF:
+	    case RL2_COMPRESSION_DEFLATE:
+	    case RL2_COMPRESSION_DEFLATE_NO:
+	    case RL2_COMPRESSION_LZMA:
+	    case RL2_COMPRESSION_LZMA_NO:
 	    case RL2_COMPRESSION_PNG:
 		break;
 	    default:
@@ -175,12 +187,16 @@ check_coverage_self_consistency (unsigned char sample_type,
 	    {
 	    case RL2_COMPRESSION_NONE:
 	    case RL2_COMPRESSION_DEFLATE:
+	    case RL2_COMPRESSION_DEFLATE_NO:
 	    case RL2_COMPRESSION_LZMA:
-	    case RL2_COMPRESSION_GIF:
+	    case RL2_COMPRESSION_LZMA_NO:
 	    case RL2_COMPRESSION_PNG:
 	    case RL2_COMPRESSION_JPEG:
 	    case RL2_COMPRESSION_LOSSY_WEBP:
 	    case RL2_COMPRESSION_LOSSLESS_WEBP:
+	    case RL2_COMPRESSION_CHARLS:
+	    case RL2_COMPRESSION_LOSSY_JP2:
+	    case RL2_COMPRESSION_LOSSLESS_JP2:
 		break;
 	    default:
 		return 0;
@@ -203,7 +219,13 @@ check_coverage_self_consistency (unsigned char sample_type,
 		  {
 		  case RL2_COMPRESSION_NONE:
 		  case RL2_COMPRESSION_DEFLATE:
+		  case RL2_COMPRESSION_DEFLATE_NO:
 		  case RL2_COMPRESSION_LZMA:
+		  case RL2_COMPRESSION_LZMA_NO:
+		  case RL2_COMPRESSION_PNG:
+		  case RL2_COMPRESSION_CHARLS:
+		  case RL2_COMPRESSION_LOSSY_JP2:
+		  case RL2_COMPRESSION_LOSSLESS_JP2:
 		      break;
 		  default:
 		      return 0;
@@ -215,11 +237,16 @@ check_coverage_self_consistency (unsigned char sample_type,
 		  {
 		  case RL2_COMPRESSION_NONE:
 		  case RL2_COMPRESSION_DEFLATE:
+		  case RL2_COMPRESSION_DEFLATE_NO:
 		  case RL2_COMPRESSION_LZMA:
+		  case RL2_COMPRESSION_LZMA_NO:
 		  case RL2_COMPRESSION_PNG:
 		  case RL2_COMPRESSION_JPEG:
 		  case RL2_COMPRESSION_LOSSY_WEBP:
 		  case RL2_COMPRESSION_LOSSLESS_WEBP:
+		  case RL2_COMPRESSION_CHARLS:
+		  case RL2_COMPRESSION_LOSSY_JP2:
+		  case RL2_COMPRESSION_LOSSLESS_JP2:
 		      break;
 		  default:
 		      return 0;
@@ -237,15 +264,61 @@ check_coverage_self_consistency (unsigned char sample_type,
 	    };
 	  if (num_samples < 2)
 	      return 0;
-	  switch (compression)
+	  if (num_samples == 3 || num_samples == 4)
 	    {
-	    case RL2_COMPRESSION_NONE:
-	    case RL2_COMPRESSION_DEFLATE:
-	    case RL2_COMPRESSION_LZMA:
-		break;
-	    default:
-		return 0;
-	    };
+		if (sample_type == RL2_SAMPLE_UINT16)
+		  {
+		      switch (compression)
+			{
+			case RL2_COMPRESSION_NONE:
+			case RL2_COMPRESSION_DEFLATE:
+			case RL2_COMPRESSION_DEFLATE_NO:
+			case RL2_COMPRESSION_LZMA:
+			case RL2_COMPRESSION_LZMA_NO:
+			case RL2_COMPRESSION_PNG:
+			case RL2_COMPRESSION_CHARLS:
+			case RL2_COMPRESSION_LOSSY_JP2:
+			case RL2_COMPRESSION_LOSSLESS_JP2:
+			    break;
+			default:
+			    return 0;
+			};
+		  }
+		else
+		  {
+		      switch (compression)
+			{
+			case RL2_COMPRESSION_NONE:
+			case RL2_COMPRESSION_DEFLATE:
+			case RL2_COMPRESSION_DEFLATE_NO:
+			case RL2_COMPRESSION_LZMA:
+			case RL2_COMPRESSION_LZMA_NO:
+			case RL2_COMPRESSION_PNG:
+			case RL2_COMPRESSION_LOSSY_WEBP:
+			case RL2_COMPRESSION_LOSSLESS_WEBP:
+			case RL2_COMPRESSION_CHARLS:
+			case RL2_COMPRESSION_LOSSY_JP2:
+			case RL2_COMPRESSION_LOSSLESS_JP2:
+			    break;
+			default:
+			    return 0;
+			};
+		  }
+	    }
+	  else
+	    {
+		switch (compression)
+		  {
+		  case RL2_COMPRESSION_NONE:
+		  case RL2_COMPRESSION_DEFLATE:
+		  case RL2_COMPRESSION_DEFLATE_NO:
+		  case RL2_COMPRESSION_LZMA:
+		  case RL2_COMPRESSION_LZMA_NO:
+		      break;
+		  default:
+		      return 0;
+		  };
+	    }
 	  break;
       case RL2_PIXEL_DATAGRID:
 	  switch (sample_type)
@@ -264,15 +337,39 @@ check_coverage_self_consistency (unsigned char sample_type,
 	    };
 	  if (num_samples != 1)
 	      return 0;
-	  switch (compression)
+	  if (sample_type == RL2_SAMPLE_UINT8
+	      || sample_type == RL2_SAMPLE_UINT16)
 	    {
-	    case RL2_COMPRESSION_NONE:
-	    case RL2_COMPRESSION_DEFLATE:
-	    case RL2_COMPRESSION_LZMA:
-		break;
-	    default:
-		return 0;
-	    };
+		switch (compression)
+		  {
+		  case RL2_COMPRESSION_NONE:
+		  case RL2_COMPRESSION_DEFLATE:
+		  case RL2_COMPRESSION_DEFLATE_NO:
+		  case RL2_COMPRESSION_LZMA:
+		  case RL2_COMPRESSION_LZMA_NO:
+		  case RL2_COMPRESSION_PNG:
+		  case RL2_COMPRESSION_CHARLS:
+		  case RL2_COMPRESSION_LOSSY_JP2:
+		  case RL2_COMPRESSION_LOSSLESS_JP2:
+		      break;
+		  default:
+		      return 0;
+		  };
+	    }
+	  else
+	    {
+		switch (compression)
+		  {
+		  case RL2_COMPRESSION_NONE:
+		  case RL2_COMPRESSION_DEFLATE:
+		  case RL2_COMPRESSION_DEFLATE_NO:
+		  case RL2_COMPRESSION_LZMA:
+		  case RL2_COMPRESSION_LZMA_NO:
+		      break;
+		  default:
+		      return 0;
+		  };
+	    }
 	  break;
       };
     return 1;
@@ -372,9 +469,54 @@ rl2_free (void *ptr)
 	free (ptr);
 }
 
+RL2_DECLARE int
+rl2_is_supported_codec (unsigned char compression)
+{
+/* Testing if a given codec/compressor is actually supported by the library */
+    switch (compression)
+      {
+      case RL2_COMPRESSION_NONE:
+      case RL2_COMPRESSION_DEFLATE:
+      case RL2_COMPRESSION_DEFLATE_NO:
+      case RL2_COMPRESSION_PNG:
+      case RL2_COMPRESSION_JPEG:
+      case RL2_COMPRESSION_CCITTFAX4:
+	  return RL2_TRUE;
+      case RL2_COMPRESSION_LZMA:
+      case RL2_COMPRESSION_LZMA_NO:
+#ifndef OMIT_LZMA
+	  return RL2_TRUE;
+#else
+	  return RL2_FALSE;
+#endif
+      case RL2_COMPRESSION_LOSSY_WEBP:
+      case RL2_COMPRESSION_LOSSLESS_WEBP:
+#ifndef OMIT_WEBP
+	  return RL2_TRUE;
+#else
+	  return RL2_FALSE;
+#endif
+      case RL2_COMPRESSION_CHARLS:
+#ifndef OMIT_CHARLS
+	  return RL2_TRUE;
+#else
+	  return RL2_FALSE;
+#endif
+      case RL2_COMPRESSION_LOSSY_JP2:
+      case RL2_COMPRESSION_LOSSLESS_JP2:
+#ifndef OMIT_OPENJPEG
+	  return RL2_TRUE;
+#else
+	  return RL2_FALSE;
+#endif
+      };
+    return RL2_ERROR;
+}
+
 static int
-check_coverage_no_data (rl2PrivPixelPtr pxl_no_data, unsigned char sample_type,
-			unsigned char pixel_type, unsigned char num_samples)
+check_coverage_no_data (rl2PrivPixelPtr pxl_no_data,
+			unsigned char sample_type, unsigned char pixel_type,
+			unsigned char num_samples)
 {
 /* checking if the NoData pixel is consistent with the Coverage */
     if (pxl_no_data == NULL)
@@ -444,6 +586,12 @@ rl2_create_coverage (const char *name, unsigned char sample_type,
     cvg->hResolution = 1.0;
     cvg->vResolution = 1.0;
     cvg->noData = pxl_no_data;
+/* applying the default policies */
+    cvg->strictResolution = 0;
+    cvg->mixedResolutions = 0;
+    cvg->sectionPaths = 0;
+    cvg->sectionMD5 = 0;
+    cvg->sectionSummary = 0;
     return (rl2CoveragePtr) cvg;
 }
 
@@ -462,6 +610,50 @@ rl2_destroy_coverage (rl2CoveragePtr ptr)
 }
 
 RL2_DECLARE int
+rl2_set_coverage_policies (rl2CoveragePtr ptr, int strict_resolution,
+			   int mixed_resolutions, int section_paths,
+			   int section_md5, int section_summary)
+{
+/* setting the Coverage's Policies */
+    rl2PrivCoveragePtr cvg = (rl2PrivCoveragePtr) ptr;
+    if (cvg == NULL)
+	return RL2_ERROR;
+    if (strict_resolution)
+	strict_resolution = 1;
+    cvg->strictResolution = strict_resolution;
+    if (mixed_resolutions)
+	mixed_resolutions = 1;
+    cvg->mixedResolutions = mixed_resolutions;
+    if (section_paths)
+	section_paths = 1;
+    cvg->sectionPaths = section_paths;
+    if (section_md5)
+	section_md5 = 1;
+    cvg->sectionMD5 = section_md5;
+    if (section_summary)
+	section_summary = 1;
+    cvg->sectionSummary = section_summary;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_get_coverage_policies (rl2CoveragePtr ptr, int *strict_resolution,
+			   int *mixed_resolutions, int *section_paths,
+			   int *section_md5, int *section_summary)
+{
+/* retrieving the Coverage's Policies */
+    rl2PrivCoveragePtr cvg = (rl2PrivCoveragePtr) ptr;
+    if (cvg == NULL)
+	return RL2_ERROR;
+    *strict_resolution = cvg->strictResolution;
+    *mixed_resolutions = cvg->mixedResolutions;
+    *section_paths = cvg->sectionPaths;
+    *section_md5 = cvg->sectionMD5;
+    *section_summary = cvg->sectionSummary;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
 rl2_coverage_georeference (rl2CoveragePtr ptr, int srid, double horz_res,
 			   double vert_res)
 {
@@ -536,9 +728,13 @@ rl2_is_coverage_compression_lossless (rl2CoveragePtr ptr, int *is_lossless)
     switch (cvg->Compression)
       {
       case RL2_COMPRESSION_DEFLATE:
+      case RL2_COMPRESSION_DEFLATE_NO:
       case RL2_COMPRESSION_LZMA:
-      case RL2_COMPRESSION_GIF:
+      case RL2_COMPRESSION_LZMA_NO:
       case RL2_COMPRESSION_PNG:
+      case RL2_COMPRESSION_LOSSLESS_WEBP:
+      case RL2_COMPRESSION_CHARLS:
+      case RL2_COMPRESSION_LOSSLESS_JP2:
 	  *is_lossless = RL2_TRUE;
 	  break;
       default:
@@ -559,6 +755,7 @@ rl2_is_coverage_compression_lossy (rl2CoveragePtr ptr, int *is_lossy)
       {
       case RL2_COMPRESSION_JPEG:
       case RL2_COMPRESSION_LOSSY_WEBP:
+      case RL2_COMPRESSION_LOSSY_JP2:
 	  *is_lossy = RL2_TRUE;
 	  break;
       default:
@@ -625,6 +822,102 @@ rl2_get_coverage_resolution (rl2CoveragePtr ptr, double *hResolution,
     return RL2_OK;
 }
 
+RL2_DECLARE rl2VectorLayerPtr
+rl2_create_vector_layer (const char *f_table_name,
+			 const char *f_geometry_column,
+			 unsigned short geometry_type, int srid,
+			 unsigned char spatial_index)
+{
+/* allocating and initializing a Coverage object */
+    int len;
+    rl2PrivVectorLayerPtr vector = NULL;
+    if (f_table_name == NULL || f_geometry_column == NULL)
+	return NULL;
+
+    vector = malloc (sizeof (rl2PrivVectorLayer));
+    if (vector == NULL)
+	return NULL;
+    len = strlen (f_table_name);
+    vector->f_table_name = malloc (len + 1);
+    strcpy (vector->f_table_name, f_table_name);
+    len = strlen (f_geometry_column);
+    vector->f_geometry_column = malloc (len + 1);
+    strcpy (vector->f_geometry_column, f_geometry_column);
+    vector->geometry_type = geometry_type;
+    vector->srid = srid;
+    vector->spatial_index = spatial_index;
+    return (rl2VectorLayerPtr) vector;
+}
+
+RL2_DECLARE void
+rl2_destroy_vector_layer (rl2VectorLayerPtr ptr)
+{
+/* memory cleanup - destroying a Vector Layer object */
+    rl2PrivVectorLayerPtr vector = (rl2PrivVectorLayerPtr) ptr;
+    if (vector == NULL)
+	return;
+    if (vector->f_table_name != NULL)
+	free (vector->f_table_name);
+    if (vector->f_geometry_column != NULL)
+	free (vector->f_geometry_column);
+    free (vector);
+}
+
+RL2_DECLARE const char *
+rl2_get_vector_table_name (rl2VectorLayerPtr ptr)
+{
+/* return the Vector Layer Table name */
+    rl2PrivVectorLayerPtr vector = (rl2PrivVectorLayerPtr) ptr;
+    if (vector == NULL)
+	return NULL;
+    return vector->f_table_name;
+}
+
+RL2_DECLARE const char *
+rl2_get_vector_geometry_name (rl2VectorLayerPtr ptr)
+{
+/* return the Vector Layer Geometry name */
+    rl2PrivVectorLayerPtr vector = (rl2PrivVectorLayerPtr) ptr;
+    if (vector == NULL)
+	return NULL;
+    return vector->f_geometry_column;
+}
+
+RL2_DECLARE int
+rl2_get_vector_geometry_type (rl2VectorLayerPtr ptr,
+			      unsigned short *geometry_type)
+{
+/* return the Vector Layer Geometry type */
+    rl2PrivVectorLayerPtr vector = (rl2PrivVectorLayerPtr) ptr;
+    if (vector == NULL)
+	return RL2_ERROR;
+    *geometry_type = vector->geometry_type;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_get_vector_srid (rl2VectorLayerPtr ptr, int *srid)
+{
+/* return the Vector Layer SRID */
+    rl2PrivVectorLayerPtr vector = (rl2PrivVectorLayerPtr) ptr;
+    if (vector == NULL)
+	return RL2_ERROR;
+    *srid = vector->srid;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_get_vector_spatial_index (rl2VectorLayerPtr ptr,
+			      unsigned char *spatial_index)
+{
+/* return the Vector Layer Spatial Index type */
+    rl2PrivVectorLayerPtr vector = (rl2PrivVectorLayerPtr) ptr;
+    if (vector == NULL)
+	return RL2_ERROR;
+    *spatial_index = vector->spatial_index;
+    return RL2_OK;
+}
+
 RL2_DECLARE rl2SectionPtr
 rl2_create_section (const char *name, unsigned char compression,
 		    unsigned int tile_width, unsigned int tile_height,
@@ -728,8 +1021,9 @@ rl2_is_section_compression_lossless (rl2SectionPtr ptr, int *is_lossless)
     switch (scn->Compression)
       {
       case RL2_COMPRESSION_DEFLATE:
+      case RL2_COMPRESSION_DEFLATE_NO:
       case RL2_COMPRESSION_LZMA:
-      case RL2_COMPRESSION_GIF:
+      case RL2_COMPRESSION_LZMA_NO:
       case RL2_COMPRESSION_PNG:
       case RL2_COMPRESSION_LOSSLESS_WEBP:
 	  *is_lossless = RL2_TRUE;
@@ -752,6 +1046,7 @@ rl2_is_section_compression_lossy (rl2SectionPtr ptr, int *is_lossy)
       {
       case RL2_COMPRESSION_JPEG:
       case RL2_COMPRESSION_LOSSY_WEBP:
+      case RL2_COMPRESSION_LOSSY_JP2:
 	  *is_lossy = RL2_TRUE;
 	  break;
       default:
@@ -825,12 +1120,13 @@ check_raster_no_data (rl2PrivPixelPtr pxl_no_data, unsigned char sample_type,
     return 1;
 }
 
-RL2_DECLARE rl2RasterPtr
-rl2_create_raster (unsigned int width, unsigned int height,
-		   unsigned char sample_type, unsigned char pixel_type,
-		   unsigned char num_samples, unsigned char *bufpix,
-		   int bufpix_size, rl2PalettePtr palette, unsigned char *mask,
-		   int mask_size, rl2PixelPtr no_data)
+static rl2RasterPtr
+create_raster_common (unsigned int width, unsigned int height,
+		      unsigned char sample_type, unsigned char pixel_type,
+		      unsigned char num_samples, unsigned char *bufpix,
+		      int bufpix_size, rl2PalettePtr palette,
+		      unsigned char *mask, int mask_size, rl2PixelPtr no_data,
+		      int alpha_mask)
 {
 /* allocating and initializing a Raster object */
     rl2PrivPixelPtr pxl_no_data = (rl2PrivPixelPtr) no_data;
@@ -866,14 +1162,17 @@ rl2_create_raster (unsigned int width, unsigned int height,
 	  /* checking the mask size */
 	  if (width * height != (unsigned int) mask_size)
 	      return NULL;
-	  p = mask;
-	  for (row = 0; row < height; row++)
+	  if (!alpha_mask)
 	    {
-		/* checking if sample doesn't exceed the max value */
-		for (col = 0; col < width; col++)
+		p = mask;
+		for (row = 0; row < height; row++)
 		  {
-		      if (*p++ > 1)
-			  return NULL;
+		      /* checking if sample doesn't exceed the max value */
+		      for (col = 0; col < width; col++)
+			{
+			    if (*p++ > 1)
+				return NULL;
+			}
 		  }
 	    }
       }
@@ -945,11 +1244,41 @@ rl2_create_raster (unsigned int width, unsigned int height,
     rst->maxY = height;
     rst->rasterBuffer = bufpix;
     rst->maskBuffer = mask;
+    rst->alpha_mask = 0;
+    if (alpha_mask)
+	rst->alpha_mask = 1;
     rst->Palette = (rl2PrivPalettePtr) palette;
     rst->noData = pxl_no_data;
     return (rl2RasterPtr) rst;
 }
 
+RL2_DECLARE rl2RasterPtr
+rl2_create_raster (unsigned int width, unsigned int height,
+		   unsigned char sample_type, unsigned char pixel_type,
+		   unsigned char num_samples, unsigned char *bufpix,
+		   int bufpix_size, rl2PalettePtr palette,
+		   unsigned char *mask, int mask_size, rl2PixelPtr no_data)
+{
+/* allocating and initializing a Raster object with an optional Transparency Mask */
+    return create_raster_common (width, height, sample_type, pixel_type,
+				 num_samples, bufpix, bufpix_size, palette,
+				 mask, mask_size, no_data, 0);
+}
+
+RL2_DECLARE rl2RasterPtr
+rl2_create_raster_alpha (unsigned int width, unsigned int height,
+			 unsigned char sample_type, unsigned char pixel_type,
+			 unsigned char num_samples, unsigned char *bufpix,
+			 int bufpix_size, rl2PalettePtr palette,
+			 unsigned char *alpha, int alpha_size,
+			 rl2PixelPtr no_data)
+{
+/* allocating and initializing a Raster object with an optional Alpha Mask */
+    return create_raster_common (width, height, sample_type, pixel_type,
+				 num_samples, bufpix, bufpix_size, palette,
+				 alpha, alpha_size, no_data, 1);
+}
+
 RL2_DECLARE void
 rl2_destroy_raster (rl2RasterPtr ptr)
 {
@@ -1056,30 +1385,6 @@ rl2_get_raster_extent (rl2RasterPtr ptr, double *minX, double *minY,
     return RL2_OK;
 }
 
-RL2_DECLARE gaiaGeomCollPtr
-rl2_get_raster_bbox (rl2RasterPtr ptr)
-{
-/* return the Raster BBox [envelope] */
-    gaiaGeomCollPtr geom;
-    gaiaPolygonPtr pg;
-    gaiaRingPtr rng;
-    rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
-    if (rst == NULL)
-	return NULL;
-    if (rst->Srid == RL2_GEOREFERENCING_NONE)
-	return NULL;
-    geom = gaiaAllocGeomColl ();
-    geom->Srid = rst->Srid;
-    pg = gaiaAddPolygonToGeomColl (geom, 5, 0);
-    rng = pg->Exterior;
-    gaiaSetPoint (rng->Coords, 0, rst->minX, rst->minY);
-    gaiaSetPoint (rng->Coords, 1, rst->maxX, rst->minY);
-    gaiaSetPoint (rng->Coords, 2, rst->maxX, rst->maxY);
-    gaiaSetPoint (rng->Coords, 3, rst->minX, rst->maxY);
-    gaiaSetPoint (rng->Coords, 4, rst->minX, rst->minY);
-    return geom;
-}
-
 RL2_DECLARE int
 rl2_get_raster_resolution (rl2RasterPtr ptr, double *hResolution,
 			   double *vResolution)
@@ -1128,8 +1433,9 @@ rl2_raster_georeference_center (rl2RasterPtr ptr, int srid, double horz_res,
 }
 
 RL2_DECLARE int
-rl2_raster_georeference_upper_left (rl2RasterPtr ptr, int srid, double horz_res,
-				    double vert_res, double x, double y)
+rl2_raster_georeference_upper_left (rl2RasterPtr ptr, int srid,
+				    double horz_res, double vert_res,
+				    double x, double y)
 {
 /* setting the Raster's georeferencing infos - UpperLeft corner */
     rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
@@ -1151,8 +1457,8 @@ rl2_raster_georeference_upper_left (rl2RasterPtr ptr, int srid, double horz_res,
 
 RL2_DECLARE int
 rl2_raster_georeference_upper_right (rl2RasterPtr ptr, int srid,
-				     double horz_res, double vert_res, double x,
-				     double y)
+				     double horz_res, double vert_res,
+				     double x, double y)
 {
 /* setting the Raster's georeferencing infos - UpperRight corner */
     rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
@@ -1173,8 +1479,9 @@ rl2_raster_georeference_upper_right (rl2RasterPtr ptr, int srid,
 }
 
 RL2_DECLARE int
-rl2_raster_georeference_lower_left (rl2RasterPtr ptr, int srid, double horz_res,
-				    double vert_res, double x, double y)
+rl2_raster_georeference_lower_left (rl2RasterPtr ptr, int srid,
+				    double horz_res, double vert_res,
+				    double x, double y)
 {
 /* setting the Raster's georeferencing infos - LowerLeft corner */
     rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
@@ -1196,8 +1503,8 @@ rl2_raster_georeference_lower_left (rl2RasterPtr ptr, int srid, double horz_res,
 
 RL2_DECLARE int
 rl2_raster_georeference_lower_right (rl2RasterPtr ptr, int srid,
-				     double horz_res, double vert_res, double x,
-				     double y)
+				     double horz_res, double vert_res,
+				     double x, double y)
 {
 /* setting the Raster's georeferencing infos - LowerRight corner */
     rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
@@ -1503,8 +1810,8 @@ rl2_set_palette_color (rl2PalettePtr ptr, int index, unsigned char r,
 }
 
 RL2_DECLARE int
-rl2_get_palette_index (rl2PalettePtr ptr, unsigned char *index, unsigned char r,
-		       unsigned char g, unsigned char b)
+rl2_get_palette_index (rl2PalettePtr ptr, unsigned char *index,
+		       unsigned char r, unsigned char g, unsigned char b)
 {
 /* finding the index corresponding to the given color (if any) */
     int i;
diff --git a/src/rl2ascii.c b/src/rl2ascii.c
index 0ef3ec4..b608250 100644
--- a/src/rl2ascii.c
+++ b/src/rl2ascii.c
@@ -20,7 +20,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -259,15 +259,15 @@ rl2_create_ascii_grid_origin (const char *path, int srid,
 {
 /* creating an ASCII Grid Origin */
     FILE *in;
-    unsigned int width;
-    unsigned int height;
-    double minx;
-    double miny;
-    double maxx;
-    double maxy;
-    double xres;
-    double yres;
-    double no_data;
+    unsigned int width = 0;
+    unsigned int height = 0;
+    double minx = 0.0;
+    double miny = 0.0;
+    double maxx = 0.0;
+    double maxy = 0.0;
+    double xres = 0.0;
+    double yres = 0.0;
+    double no_data = 0.0;
     char buf[1024];
     char *p_out = buf;
     unsigned int line_no = 0;
@@ -320,8 +320,8 @@ rl2_create_ascii_grid_origin (const char *path, int srid,
       }
 
     ascii =
-	alloc_ascii_origin (path, srid, sample_type, width, height, minx, miny,
-			    maxx, maxy, xres, yres, no_data);
+	alloc_ascii_origin (path, srid, sample_type, width, height, minx,
+			    miny, maxx, maxy, xres, yres, no_data);
     if (ascii == NULL)
 	goto error;
 
@@ -571,7 +571,8 @@ rl2_get_ascii_grid_origin_type (rl2AsciiGridOriginPtr ascii,
 
 RL2_DECLARE int
 rl2_eval_ascii_grid_origin_compatibility (rl2CoveragePtr cvg,
-					  rl2AsciiGridOriginPtr ascii)
+					  rl2AsciiGridOriginPtr ascii,
+					  int verbose)
 {
 /* testing if a Coverage and an ASCII Grid origin are mutually compatible */
     unsigned char sample_type;
@@ -590,28 +591,52 @@ rl2_eval_ascii_grid_origin_compatibility (rl2CoveragePtr cvg,
 	return RL2_ERROR;
 
     if (coverage->sampleType != sample_type)
-	return RL2_FALSE;
+      {
+	  if (verbose)
+	      fprintf (stderr, "Mismatching SampleType !!!\n");
+	  return RL2_FALSE;
+      }
     if (coverage->pixelType != pixel_type)
-	return RL2_FALSE;
+      {
+	  if (verbose)
+	      fprintf (stderr, "Mismatching PixelType !!!\n");
+	  return RL2_FALSE;
+      }
     if (coverage->nBands != num_bands)
-	return RL2_FALSE;
+      {
+	  if (verbose)
+	      fprintf (stderr, "Mismatching Number of Bands !!!\n");
+	  return RL2_FALSE;
+      }
 
 /* checking for resolution compatibility */
     if (rl2_get_ascii_grid_origin_srid (ascii, &srid) != RL2_OK)
 	return RL2_FALSE;
     if (coverage->Srid != srid)
-	return RL2_FALSE;
-    if (rl2_get_ascii_grid_origin_resolution (ascii, &hResolution, &vResolution)
-	!= RL2_OK)
+      {
+	  if (verbose)
+	      fprintf (stderr, "Mismatching SRID !!!\n");
+	  return RL2_FALSE;
+      }
+    if (rl2_get_ascii_grid_origin_resolution
+	(ascii, &hResolution, &vResolution) != RL2_OK)
 	return RL2_FALSE;
     confidence = coverage->hResolution / 100.0;
     if (hResolution < (coverage->hResolution - confidence)
 	|| hResolution > (coverage->hResolution + confidence))
-	return RL2_FALSE;
+      {
+	  if (verbose)
+	      fprintf (stderr, "Mismatching Horizontal Resolution !!!\n");
+	  return RL2_FALSE;
+      }
     confidence = coverage->vResolution / 100.0;
     if (vResolution < (coverage->vResolution - confidence)
 	|| vResolution > (coverage->vResolution + confidence))
-	return RL2_FALSE;
+      {
+	  if (verbose)
+	      fprintf (stderr, "Mismatching Vertical Resolution !!!\n");
+	  return RL2_FALSE;
+      }
     return RL2_TRUE;
 }
 
@@ -727,8 +752,8 @@ read_ascii_uint16 (rl2PrivAsciiOriginPtr origin, unsigned int width,
 	       x++, col++)
 	    {
 		unsigned short uint16;
-		if (fread (&uint16, sizeof (unsigned short), 1, origin->tmp) <=
-		    0)
+		if (fread (&uint16, sizeof (unsigned short), 1, origin->tmp)
+		    <= 0)
 		    return 0;
 		*p_out++ = uint16;
 	    }
@@ -976,7 +1001,7 @@ RL2_DECLARE rl2RasterPtr
 rl2_get_tile_from_ascii_grid_origin (rl2CoveragePtr cvg,
 				     rl2AsciiGridOriginPtr ascii,
 				     unsigned int startRow,
-				     unsigned int startCol)
+				     unsigned int startCol, int verbose)
 {
 /* attempting to create a Coverage-tile from an ASCII Grid origin */
     unsigned int x;
@@ -992,7 +1017,8 @@ rl2_get_tile_from_ascii_grid_origin (rl2CoveragePtr cvg,
 
     if (coverage == NULL || origin == NULL)
 	return NULL;
-    if (rl2_eval_ascii_grid_origin_compatibility (cvg, ascii) != RL2_TRUE)
+    if (rl2_eval_ascii_grid_origin_compatibility (cvg, ascii, verbose) !=
+	RL2_TRUE)
 	return NULL;
     if (origin->tmp == NULL)
 	return NULL;
@@ -1046,8 +1072,8 @@ rl2_get_tile_from_ascii_grid_origin (rl2CoveragePtr cvg,
       }
     raster =
 	rl2_create_raster (coverage->tileWidth, coverage->tileHeight,
-			   coverage->sampleType, RL2_PIXEL_DATAGRID, 1, pixels,
-			   pixels_sz, NULL, mask, mask_size, NULL);
+			   coverage->sampleType, RL2_PIXEL_DATAGRID, 1,
+			   pixels, pixels_sz, NULL, mask, mask_size, NULL);
     if (raster == NULL)
 	goto error;
     return raster;
@@ -1137,6 +1163,7 @@ rl2_create_ascii_grid_destination (const char *path, unsigned int width,
     if (pixels_size != (int) (width * height * pix_sz))
 	return NULL;
 
+/* creating the output File */
     out = fopen (path, "w");
     if (out == NULL)
       {
@@ -1150,10 +1177,6 @@ rl2_create_ascii_grid_destination (const char *path, unsigned int width,
     if (ascii == NULL)
 	goto error;
 
-/* creating the output File */
-    out = fopen (path, "wb");
-    if (out == NULL)
-	goto error;
     ascii->out = out;
     ascii->pixels = pixels;
     ascii->sampleType = sample_type;
@@ -1299,15 +1322,15 @@ rl2_write_ascii_grid_scanline (rl2AsciiGridDestinationPtr ascii,
 			       unsigned int *line_no)
 {
 /* attempting to write a scanline into an ASCII Grid */
-    char *p8;
-    unsigned char *pu8;
-    short *p16;
-    unsigned short *pu16;
-    int *p32;
-    unsigned int *pu32;
-    float *pflt;
-    double *pdbl;
-    double cell_value;
+    char *p8 = NULL;
+    unsigned char *pu8 = NULL;
+    short *p16 = NULL;
+    unsigned short *pu16 = NULL;
+    int *p32 = NULL;
+    unsigned int *pu32 = NULL;
+    float *pflt = NULL;
+    double *pdbl = NULL;
+    double cell_value = 0.0;
     char *pxl;
     unsigned int x;
     rl2PrivAsciiDestinationPtr dst = (rl2PrivAsciiDestinationPtr) ascii;
@@ -1396,3 +1419,143 @@ rl2_write_ascii_grid_scanline (rl2AsciiGridDestinationPtr ascii,
     *line_no = dst->nextLineNo;
     return RL2_OK;
 }
+
+RL2_DECLARE char *
+rl2_build_ascii_xml_summary (rl2AsciiGridOriginPtr ascii)
+{
+/* attempting to build an XML Summary from an ASCII Grid */
+    char *xml;
+    char *prev;
+    int len;
+    rl2PrivAsciiOriginPtr org = (rl2PrivAsciiOriginPtr) ascii;
+    if (org == NULL)
+	return NULL;
+
+    xml = sqlite3_mprintf ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<ImportedRaster>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<RasterFormat>ASCII Grid</RasterFormat>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<RasterWidth>%u</RasterWidth>", prev, org->width);
+    sqlite3_free (prev);
+    prev = xml;
+    xml =
+	sqlite3_mprintf ("%s<RasterHeight>%u</RasterHeight>", prev,
+			 org->height);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<RowsPerStrip>1</RowsPerStrip>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml =
+	sqlite3_mprintf ("%s<BitsPerSample>unspecified</BitsPerSample>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<SamplesPerPixel>1</SamplesPerPixel>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml =
+	sqlite3_mprintf
+	("%s<PhotometricInterpretation>min-is-black</PhotometricInterpretation>",
+	 prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<Compression>none</Compression>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<SampleFormat>unspecified</SampleFormat>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml =
+	sqlite3_mprintf
+	("%s<PlanarConfiguration>single Raster plane</PlanarConfiguration>",
+	 prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml =
+	sqlite3_mprintf ("%s<NoDataPixel>%1.8f</NoDataPixel>", prev,
+			 org->noData);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<GeoReferencing>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<SpatialReferenceSystem>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<SRID>unspecified</SRID>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<RefSysName>undeclared</RefSysName>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s</SpatialReferenceSystem>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<SpatialResolution>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml =
+	sqlite3_mprintf
+	("%s<HorizontalResolution>%1.10f</HorizontalResolution>", prev,
+	 org->hResolution);
+    sqlite3_free (prev);
+    prev = xml;
+    xml =
+	sqlite3_mprintf
+	("%s<VerticalResolution>%1.10f</VerticalResolution>", prev,
+	 org->vResolution);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s</SpatialResolution>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<BoundingBox>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<MinX>%1.10f</MinX>", prev, org->minX);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<MinY>%1.10f</MinY>", prev, org->minY);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<MaxX>%1.10f</MaxX>", prev, org->maxX);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<MaxY>%1.10f</MaxY>", prev, org->maxY);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s</BoundingBox>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<Extent>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml =
+	sqlite3_mprintf ("%s<HorizontalExtent>%1.10f</HorizontalExtent>",
+			 prev, org->maxX - org->minX);
+    sqlite3_free (prev);
+    prev = xml;
+    xml =
+	sqlite3_mprintf ("%s<VerticalExtent>%1.10f</VerticalExtent>",
+			 prev, org->maxY - org->minY);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s</Extent>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s</GeoReferencing>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s</ImportedRaster>", prev);
+    sqlite3_free (prev);
+    len = strlen (xml);
+    prev = xml;
+    xml = malloc (len + 1);
+    strcpy (xml, prev);
+    sqlite3_free (prev);
+    return xml;
+}
diff --git a/src/rl2auxfont.c b/src/rl2auxfont.c
new file mode 100644
index 0000000..9800d94
--- /dev/null
+++ b/src/rl2auxfont.c
@@ -0,0 +1,796 @@
+/*
+
+ rl2auxfont -- FreeType2 and Font related functions
+
+ version 0.1, 2015 February 12
+
+ Author: Sandro Furieri a.furieri at lqt.it
+
+ -----------------------------------------------------------------------------
+ 
+ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ 
+ The contents of this file are subject to the Mozilla Public License Version
+ 1.1 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+ 
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the
+License.
+
+The Original Code is the RasterLite2 library
+
+The Initial Developer of the Original Code is Alessandro Furieri
+ 
+Portions created by the Initial Developer are Copyright (C) 2015
+the Initial Developer. All Rights Reserved.
+
+Alternatively, the contents of this file may be used under the terms of
+either the GNU General Public License Version 2 or later (the "GPL"), or
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+in which case the provisions of the GPL or the LGPL are applicable instead
+of those above. If you wish to allow use of your version of this file only
+under the terms of either the GPL or the LGPL, and not to allow others to
+use your version of this file under the terms of the MPL, indicate your
+decision by deleting the provisions above and replace them with the notice
+and other provisions required by the GPL or the LGPL. If you do not delete
+the provisions above, a recipient may use your version of this file under
+the terms of any one of the MPL, the GPL or the LGPL.
+ 
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+#include <zlib.h>
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+#include "rasterlite2/sqlite.h"
+
+#include "config.h"
+
+#include "rasterlite2/rasterlite2.h"
+#include "rasterlite2/rl2graphics.h"
+#include "rasterlite2_private.h"
+
+static int
+font_endianArch ()
+{
+/* checking if target CPU is a little-endian one */
+    union cvt
+    {
+	unsigned char byte[4];
+	int int_value;
+    } convert;
+    convert.int_value = 1;
+    if (convert.byte[0] == 0)
+	return 0;
+    return 1;
+}
+
+static void
+font_export16 (unsigned char *p, unsigned short value, int little_endian_arch)
+{
+/* stores a 16bit int into a BLOB respecting declared endiannes */
+    union cvt
+    {
+	unsigned char byte[2];
+	unsigned short int_value;
+    } convert;
+    convert.int_value = value;
+    if (little_endian_arch)
+      {
+	  /* Litte-Endian architecture [e.g. x86] */
+	  *(p + 0) = convert.byte[0];
+	  *(p + 1) = convert.byte[1];
+      }
+    else
+      {
+	  /* Big Endian architecture [e.g. PPC] */
+	  *(p + 1) = convert.byte[0];
+	  *(p + 0) = convert.byte[1];
+      }
+}
+
+static unsigned short
+font_import16 (const unsigned char *p, int little_endian_arch)
+{
+/* fetches a 16bit uint from BLOB respecting declared endiannes */
+    union cvt
+    {
+	unsigned char byte[2];
+	unsigned short int_value;
+    } convert;
+    if (little_endian_arch)
+      {
+	  /* Litte-Endian architecture [e.g. x86] */
+	  convert.byte[0] = *(p + 0);
+	  convert.byte[1] = *(p + 1);
+      }
+    else
+      {
+	  /* Big Endian architecture [e.g. PPC] */
+	  convert.byte[0] = *(p + 1);
+	  convert.byte[1] = *(p + 0);
+      }
+    return convert.int_value;
+}
+
+static void
+font_export32 (unsigned char *p, unsigned int value, int little_endian_arch)
+{
+/* stores a 32bit int into a BLOB respecting declared endiannes */
+    union cvt
+    {
+	unsigned char byte[4];
+	unsigned int int_value;
+    } convert;
+    convert.int_value = value;
+    if (little_endian_arch)
+      {
+	  /* Litte-Endian architecture [e.g. x86] */
+	  *(p + 0) = convert.byte[0];
+	  *(p + 1) = convert.byte[1];
+	  *(p + 2) = convert.byte[2];
+	  *(p + 3) = convert.byte[3];
+      }
+    else
+      {
+	  /* Big Endian architecture [e.g. PPC] */
+	  *(p + 3) = convert.byte[0];
+	  *(p + 2) = convert.byte[1];
+	  *(p + 1) = convert.byte[2];
+	  *(p + 0) = convert.byte[3];
+      }
+}
+
+static unsigned int
+font_import32 (const unsigned char *p, int little_endian_arch)
+{
+/* fetches a 32bit uint from BLOB respecting declared endiannes */
+    union cvt
+    {
+	unsigned char byte[4];
+	unsigned int int_value;
+    } convert;
+    if (little_endian_arch)
+      {
+	  /* Litte-Endian architecture [e.g. x86] */
+	  convert.byte[0] = *(p + 0);
+	  convert.byte[1] = *(p + 1);
+	  convert.byte[2] = *(p + 2);
+	  convert.byte[3] = *(p + 3);
+      }
+    else
+      {
+	  /* Big Endian architecture [e.g. PPC] */
+	  convert.byte[0] = *(p + 3);
+	  convert.byte[1] = *(p + 2);
+	  convert.byte[2] = *(p + 1);
+	  convert.byte[3] = *(p + 0);
+      }
+    return convert.int_value;
+}
+
+static int
+check_font (const unsigned char *buffer, int buf_size, char **family_name,
+	    char **style_name, int *is_bold, int *is_italic)
+{
+/* exploring a FreeType Font */
+    FT_Error error;
+    FT_Library library;
+    FT_Face face;
+    int len;
+
+    if (buffer == NULL || buf_size <= 0)
+	return RL2_ERROR;
+
+/* initializing a FreeType2 library object */
+    error = FT_Init_FreeType (&library);
+    if (error)
+	return RL2_ERROR;
+
+/* attempting to parse the Font */
+    error = FT_New_Memory_Face (library, buffer, buf_size, 0, &face);
+    if (error)
+	goto stop;
+
+    if (face->family_name == NULL)
+	goto stop;
+    len = strlen (face->family_name);
+    *family_name = malloc (len + 1);
+    strcpy (*family_name, face->family_name);
+    if (face->style_name == NULL)
+	*style_name = NULL;
+    else
+      {
+	  len = strlen (face->style_name);
+	  *style_name = malloc (len + 1);
+	  strcpy (*style_name, face->style_name);
+      }
+    if (face->style_flags & FT_STYLE_FLAG_ITALIC)
+	*is_italic = 1;
+    else
+	*is_italic = 0;
+    if (face->style_flags & FT_STYLE_FLAG_BOLD)
+	*is_bold = 1;
+    else
+	*is_bold = 0;
+
+/* releasing all resources */
+    FT_Done_Face (face);
+    FT_Done_FreeType (library);
+    return RL2_OK;
+
+  stop:
+/* invalid Font */
+    FT_Done_FreeType (library);
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_font_encode (const unsigned char *font, int font_sz, unsigned char **blob,
+		 int *blob_sz)
+{
+/* attempting to encode a BLOB serialized Font */
+    char *family_name = NULL;
+    char *style_name = NULL;
+    int is_bold = 0;
+    int is_italic = 0;
+    short family_len;
+    short style_len;
+    uLong zLen;
+    unsigned char *zip_buf = NULL;
+    int compressed;
+    const unsigned char *compr_data = NULL;
+    int ret;
+    unsigned char *block = NULL;
+    int block_size;
+    unsigned char *ptr;
+    uLong crc;
+    int endian_arch = font_endianArch ();
+
+    *blob = NULL;
+    *blob_sz = 0;
+
+    if (font == NULL || font_sz == 0)
+	return RL2_ERROR;
+    if (check_font
+	(font, font_sz, &family_name, &style_name, &is_bold,
+	 &is_italic) != RL2_OK)
+	return RL2_ERROR;
+
+    family_len = strlen (family_name);
+    if (style_name == NULL)
+	style_len = 0;
+    else
+	style_len = strlen (style_name);
+
+/* compressing as ZIP [Deflate] */
+    zLen = font_sz - 1;
+    zip_buf = malloc (zLen);
+    ret = compress (zip_buf, &zLen, (const Bytef *) font, (uLong) font_sz);
+    if (ret == Z_OK)
+      {
+	  /* ok, ZIP compression was successful */
+	  compressed = (int) zLen;
+	  compr_data = zip_buf;
+      }
+    else if (ret == Z_BUF_ERROR)
+      {
+	  /* ZIP compression actually causes inflation: saving uncompressed data */
+	  compressed = font_sz;
+	  compr_data = font;
+	  free (zip_buf);
+	  zip_buf = NULL;
+      }
+    else
+      {
+	  /* compression error */
+	  free (zip_buf);
+	  goto error;
+      }
+
+/* preparing the serialized BLOB */
+    block_size = 26 + compressed + family_len + style_len;
+    block = malloc (block_size);
+    if (block == NULL)
+	goto error;
+    ptr = block;
+    *ptr++ = 0x00;		/* start marker */
+    *ptr++ = RL2_FONT_START;	/* Font Start marker */
+    font_export16 (ptr, family_len, endian_arch);	/* Family name length in bytes */
+    ptr += 2;
+    memcpy (ptr, family_name, family_len);
+    ptr += family_len;
+    *ptr++ = RL2_DATA_END;
+    font_export16 (ptr, style_len, endian_arch);	/* Style name length in bytes */
+    ptr += 2;
+    if (style_name != NULL)
+      {
+	  memcpy (ptr, style_name, style_len);
+	  ptr += style_len;
+      }
+    *ptr++ = RL2_DATA_END;
+    if (is_bold)
+	*ptr++ = 1;
+    else
+	*ptr++ = 0;
+    if (is_italic)
+	*ptr++ = 1;
+    else
+	*ptr++ = 0;
+    *ptr++ = RL2_DATA_END;
+    font_export32 (ptr, font_sz, endian_arch);	/* uncompressed payload size in bytes */
+    ptr += 4;
+    font_export32 (ptr, compressed, endian_arch);	/* compressed payload size in bytes */
+    ptr += 4;
+    *ptr++ = RL2_DATA_START;
+    memcpy (ptr, compr_data, compressed);	/* the payload */
+    ptr += compressed;
+    *ptr++ = RL2_DATA_END;
+/* computing the CRC32 */
+    crc = crc32 (0L, block, ptr - block);
+    font_export32 (ptr, crc, endian_arch);	/* the serialized BLOB own CRC */
+    ptr += 4;
+    *ptr = RL2_FONT_END;
+
+    *blob = block;
+    *blob_sz = block_size;
+
+/* final cleanup */
+    if (zip_buf != NULL)
+	free (zip_buf);
+    free (family_name);
+    if (style_name != NULL)
+	free (style_name);
+    return RL2_OK;
+
+  error:
+/* some error occurred */
+    if (family_name != NULL)
+	free (family_name);
+    if (style_name != NULL)
+	free (style_name);
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_is_valid_encoded_font (const unsigned char *blob, int blob_sz)
+{
+/* checking a serialized BLOB Font for validity */
+    const unsigned char *ptr;
+    int endian_arch = font_endianArch ();
+    unsigned short len;
+    int compressed;
+    uLong crc;
+    uLong oldCrc;
+
+    if (blob == NULL)
+	return RL2_ERROR;
+    ptr = blob;
+
+    if (blob_sz < 5)
+	return RL2_ERROR;
+    if (*ptr++ != 0x00)
+	return RL2_ERROR;	/* invalid start signature */
+    if (*ptr++ != RL2_FONT_START)
+	return RL2_ERROR;	/* invalid start signature */
+    len = font_import16 (ptr, endian_arch);	/* Family name length in bytes */
+    ptr += 2 + len;
+    if ((ptr - blob) >= blob_sz)
+	return RL2_ERROR;
+    if (*ptr++ != RL2_DATA_END)
+	return RL2_ERROR;
+    if (((ptr + 2) - blob) >= blob_sz)
+	return RL2_ERROR;
+    len = font_import16 (ptr, endian_arch);	/* Style name length in bytes */
+    ptr += 2 + len;
+    if ((ptr - blob) >= blob_sz)
+	return RL2_ERROR;
+    if (*ptr++ != RL2_DATA_END)
+	return RL2_ERROR;
+    ptr += 2;			/* skipping Bold and Italic */
+    if (((ptr + 2) - blob) >= blob_sz)
+	return RL2_ERROR;
+    if (*ptr++ != RL2_DATA_END)
+	return RL2_ERROR;
+    if (((ptr + 4) - blob) >= blob_sz)
+	return RL2_ERROR;
+    compressed = font_import32 (ptr, endian_arch);	/* uncompressed size in bytes */
+    ptr += 4;
+    if (((ptr + 4) - blob) >= blob_sz)
+	return RL2_ERROR;
+    compressed = font_import32 (ptr, endian_arch);	/* compressed size in bytes */
+    ptr += 4;
+    if ((ptr - blob) >= blob_sz)
+	return RL2_ERROR;
+    if (*ptr++ != RL2_DATA_START)
+	return RL2_ERROR;
+    ptr += compressed;
+    if ((ptr - blob) >= blob_sz)
+	return RL2_ERROR;
+    if (*ptr++ != RL2_DATA_END)
+	return RL2_ERROR;
+/* computing the CRC32 */
+    crc = crc32 (0L, blob, ptr - blob);
+    if (((ptr + 4) - blob) >= blob_sz)
+	return RL2_ERROR;
+    oldCrc = font_import32 (ptr, endian_arch);
+    ptr += 4;
+    if (crc != oldCrc)
+	return RL2_ERROR;
+    if ((ptr - blob) >= blob_sz)
+	return RL2_ERROR;
+    if (*ptr != RL2_FONT_END)
+	return RL2_ERROR;	/* invalid end signature */
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_font_decode (const unsigned char *blob, int blob_sz,
+		 unsigned char **font, int *font_sz)
+{
+/* attempting to decode a serialized BLOB Font */
+    const unsigned char *ptr;
+    int endian_arch = font_endianArch ();
+    unsigned short len;
+    int compressed;
+    int uncompressed;
+    unsigned char *data = NULL;
+
+    if (rl2_is_valid_encoded_font (blob, blob_sz) != RL2_OK)
+	return RL2_ERROR;
+
+    ptr = blob + 2;
+    len = font_import16 (ptr, endian_arch);	/* Family name length in bytes */
+    ptr += 3 + len;
+    len = font_import16 (ptr, endian_arch);	/* Style name length in bytes */
+    ptr += 3 + len;
+    ptr += 3;			/* skipping Bold and Italic */
+    uncompressed = font_import32 (ptr, endian_arch);	/* uncompressed size in bytes */
+    ptr += 4;
+    if (((ptr + 4) - blob) >= blob_sz)
+	return RL2_ERROR;
+    compressed = font_import32 (ptr, endian_arch);	/* compressed size in bytes */
+    ptr += 5;
+
+    if (uncompressed != compressed)
+      {
+	  /* decompressing from ZIP [Deflate] */
+	  uLong refLen = uncompressed;
+	  const Bytef *in = ptr;
+	  data = malloc (uncompressed);
+	  if (data == NULL)
+	      goto error;
+	  if (uncompress (data, &refLen, in, compressed) != Z_OK)
+	      goto error;
+	  *font = data;
+	  *font_sz = uncompressed;
+      }
+    else
+      {
+	  /* already uncompressed Font */
+	  data = malloc (uncompressed);
+	  if (data == NULL)
+	      goto error;
+	  memcpy (data, ptr, uncompressed);
+	  *font = data;
+	  *font_sz = uncompressed;
+      }
+    return RL2_OK;
+
+  error:
+    if (data != NULL)
+	free (data);
+    return RL2_ERROR;
+}
+
+RL2_DECLARE char *
+rl2_get_encoded_font_facename (const unsigned char *blob, int blob_sz)
+{
+/* attempting to return the Facename from a serialized BLOB Font */
+    const unsigned char *ptr;
+    const unsigned char *family;
+    const unsigned char *style;
+    int endian_arch = font_endianArch ();
+    unsigned short len1;
+    unsigned short len2;
+    char *name = NULL;
+
+    if (rl2_is_valid_encoded_font (blob, blob_sz) != RL2_OK)
+	return NULL;
+
+    ptr = blob + 2;
+    len1 = font_import16 (ptr, endian_arch);	/* Family name length in bytes */
+    family = ptr + 2;
+    ptr += 3 + len1;
+    len2 = font_import16 (ptr, endian_arch);	/* Style name length in bytes */
+    style = ptr + 2;
+    if (len2 == 0)
+	name = malloc (len1 + 1);
+    else
+	name = malloc (len1 + len2 + 2);
+    memcpy (name, family, len1);
+    if (len2 == 0)
+	*(name + len1) = '\0';
+    else
+      {
+	  *(name + len1) = '-';
+	  memcpy (name + len1 + 1, style, len2);
+	  *(name + len1 + len2 + 1) = '\0';
+      }
+    return name;
+}
+
+RL2_DECLARE char *
+rl2_get_encoded_font_family (const unsigned char *blob, int blob_sz)
+{
+/* attempting to return the Family name from a serialized BLOB Font */
+    const unsigned char *ptr;
+    int endian_arch = font_endianArch ();
+    unsigned short len;
+    char *name = NULL;
+
+    if (rl2_is_valid_encoded_font (blob, blob_sz) != RL2_OK)
+	return NULL;
+
+    ptr = blob + 2;
+    len = font_import16 (ptr, endian_arch);	/* Family length in bytes */
+    ptr += 2;
+    name = malloc (len + 1);
+    memcpy (name, ptr, len);
+    *(name + len) = '\0';
+    return name;
+}
+
+RL2_DECLARE char *
+rl2_get_encoded_font_style (const unsigned char *blob, int blob_sz)
+{
+/* attempting to return the  Style name from a serialized BLOB Font */
+    const unsigned char *ptr;
+    int endian_arch = font_endianArch ();
+    unsigned short len;
+    char *name = NULL;
+
+    if (rl2_is_valid_encoded_font (blob, blob_sz) != RL2_OK)
+	return NULL;
+
+    ptr = blob + 2;
+    len = font_import16 (ptr, endian_arch);	/* Family name length in bytes */
+    ptr += 3 + len;
+    len = font_import16 (ptr, endian_arch);	/* Style name length in bytes */
+    if (len == 0)
+	return NULL;		/* this Font has no Style name */
+    ptr += 2;
+    name = malloc (len + 1);
+    memcpy (name, ptr, len);
+    *(name + len) = '\0';
+    return name;
+}
+
+RL2_DECLARE int
+rl2_is_encoded_font_bold (const unsigned char *blob, int blob_sz)
+{
+/* testing if a serialized BLOB Font is Bold */
+    const unsigned char *ptr;
+    int endian_arch = font_endianArch ();
+    unsigned short len;
+
+    if (rl2_is_valid_encoded_font (blob, blob_sz) != RL2_OK)
+	return -1;
+
+    ptr = blob + 2;
+    len = font_import16 (ptr, endian_arch);	/* Family name length in bytes */
+    ptr += 3 + len;
+    len = font_import16 (ptr, endian_arch);	/* Style name length in bytes */
+    ptr += 3 + len;
+    return *ptr++;
+}
+
+RL2_DECLARE int
+rl2_is_encoded_font_italic (const unsigned char *blob, int blob_sz)
+{
+/* testing if a serialized BLOB Font is Italic */
+    const unsigned char *ptr;
+    int endian_arch = font_endianArch ();
+    unsigned short len;
+
+    if (rl2_is_valid_encoded_font (blob, blob_sz) != RL2_OK)
+	return -1;
+
+    ptr = blob + 2;
+    len = font_import16 (ptr, endian_arch);	/* Family name length in bytes */
+    ptr += 3 + len;
+    len = font_import16 (ptr, endian_arch);	/* Style name length in bytes */
+    ptr += 4 + len;
+    return *ptr++;
+}
+
+RL2_PRIVATE int
+rl2_load_font_into_dbms (sqlite3 * handle, unsigned char *blob, int blob_sz)
+{
+/* loading a serialized BLOB Font into the DBMS */
+    char *facename = NULL;
+    const char *sql;
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+
+    if (rl2_is_valid_encoded_font (blob, blob_sz) != RL2_OK)
+	return RL2_ERROR;
+
+    facename = rl2_get_encoded_font_facename (blob, blob_sz);
+    if (facename == NULL)
+	return RL2_ERROR;
+
+/* inserting the Font */
+    sql = "INSERT INTO SE_fonts (font_facename, font) VALUES (?, ?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	goto error;
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, facename, strlen (facename), SQLITE_STATIC);
+    sqlite3_bind_blob (stmt, 2, blob, blob_sz, SQLITE_STATIC);
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+	sqlite3_finalize (stmt);
+    else
+	goto error;
+    free (facename);
+    free (blob);
+    return RL2_OK;
+
+  error:
+    if (facename != NULL)
+	free (facename);
+    free (blob);
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    return RL2_ERROR;
+}
+
+RL2_PRIVATE int
+rl2_get_font_from_dbms (sqlite3 * handle, const char *facename,
+			unsigned char **font, int *font_sz)
+{
+/* attempting to fetch a Font from the DBMS */
+    const char *sql;
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+    unsigned char *xfont = NULL;
+    int xfont_sz;
+
+    *font = NULL;
+    *font_sz = 0;
+
+/* preparing the SQL query statement */
+    sql = "SELECT font FROM SE_fonts WHERE Lower(font_facename) = Lower(?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	goto error;
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, facename, strlen (facename), SQLITE_STATIC);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	    {
+		if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
+		  {
+		      const unsigned char *blob = sqlite3_column_blob (stmt, 0);
+		      int blob_sz = sqlite3_column_bytes (stmt, 0);
+		      if (xfont != NULL)
+			{
+			    free (xfont);
+			    xfont = NULL;
+			}
+		      if (rl2_font_decode (blob, blob_sz, &xfont, &xfont_sz)
+			  == RL2_OK)
+			{
+			    *font = xfont;
+			    *font_sz = xfont_sz;
+			}
+		  }
+	    }
+	  else
+	      goto error;
+      }
+    sqlite3_finalize (stmt);
+    if (*font == NULL)
+	return RL2_ERROR;
+    return RL2_OK;
+
+  error:
+    if (xfont != NULL)
+	free (xfont);
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_get_TrueType_font (sqlite3 * handle, const char *facename,
+		       unsigned char **font, int *font_sz)
+{
+/* attempting to fetch a BLOB-encoded TrueType Font */
+    const char *sql;
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+    unsigned char *xfont = NULL;
+    if (facename == NULL)
+	return RL2_ERROR;
+
+    *font = NULL;
+    *font_sz = 0;
+/* preparing the SQL query statement */
+    sql = "SELECT font FROM SE_fonts WHERE Lower(font_facename) = Lower(?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	goto error;
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, facename, strlen (facename), SQLITE_STATIC);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	    {
+		if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
+		  {
+		      const unsigned char *blob = sqlite3_column_blob (stmt, 0);
+		      int blob_sz = sqlite3_column_bytes (stmt, 0);
+		      if (xfont != NULL)
+			{
+			    free (xfont);
+			    xfont = NULL;
+			}
+		      if (rl2_is_valid_encoded_font (blob, blob_sz) == RL2_OK)
+			{
+			    *font = malloc (blob_sz);
+			    *font_sz = blob_sz;
+			    memcpy (*font, blob, blob_sz);
+			}
+		  }
+	    }
+	  else
+	      goto error;
+      }
+    sqlite3_finalize (stmt);
+    if (*font == NULL)
+	return RL2_ERROR;
+    return RL2_OK;
+
+  error:
+    if (xfont != NULL)
+	free (xfont);
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    return RL2_ERROR;
+}
+
+RL2_DECLARE rl2GraphicsFontPtr
+rl2_search_TrueType_font (sqlite3 * handle, const void *priv_data,
+			  const char *facename, double size)
+{
+/* attempting to fetch and create a TrueType Font */
+    unsigned char *ttf = NULL;
+    int ttf_sz;
+    if (facename == NULL)
+	return NULL;
+
+    if (rl2_get_TrueType_font (handle, facename, &ttf, &ttf_sz) != RL2_OK)
+	return NULL;
+    return rl2_graph_create_TrueType_font (priv_data, ttf, ttf_sz, size);
+}
diff --git a/src/rl2auxgeom.c b/src/rl2auxgeom.c
new file mode 100644
index 0000000..5c61089
--- /dev/null
+++ b/src/rl2auxgeom.c
@@ -0,0 +1,2189 @@
+/*
+
+ rl2auxgeom -- auxiliary methods supporting basic 2D geometries
+
+ version 0.1, 2015 February 2
+
+ Author: Sandro Furieri a.furieri at lqt.it
+
+ -----------------------------------------------------------------------------
+ 
+ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ 
+ The contents of this file are subject to the Mozilla Public License Version
+ 1.1 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+ 
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the
+License.
+
+The Original Code is the RasterLite2 library
+
+The Initial Developer of the Original Code is Alessandro Furieri
+ 
+Portions created by the Initial Developer are Copyright (C) 2015
+the Initial Developer. All Rights Reserved.
+
+Alternatively, the contents of this file may be used under the terms of
+either the GNU General Public License Version 2 or later (the "GPL"), or
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+in which case the provisions of the GPL or the LGPL are applicable instead
+of those above. If you wish to allow use of your version of this file only
+under the terms of either the GPL or the LGPL, and not to allow others to
+use your version of this file under the terms of the MPL, indicate your
+decision by deleting the provisions above and replace them with the notice
+and other provisions required by the GPL or the LGPL. If you do not delete
+the provisions above, a recipient may use your version of this file under
+the terms of any one of the MPL, the GPL or the LGPL.
+ 
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <float.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <limits.h>
+
+#ifdef _WIN32
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
+#include "config.h"
+
+#ifdef LOADABLE_EXTENSION
+#include "rasterlite2/sqlite.h"
+#endif
+
+#include "rasterlite2/rasterlite2.h"
+#include "rasterlite2_private.h"
+
+#include <spatialite/gg_const.h>
+
+/*
+/
+/ PLEASE NOTE: all these functions are roughly equivalent to the 
+/ corresponding APIs implemented in libspatialite.
+/ this odd code duplication is absolutely required in order to carefully
+/ avoid to create any direct reference to link symbols declared by
+/ libspatialite, because such an action will irremediabely introduce
+/ nasty dependencies to libsqlite3 as well.
+/ and this is absolutely not allowed in a "pure" loadable module context.
+/
+/ a very important difference exists between the RasterLite2 and the
+/ SpatiaLite implementations.
+/ in RL2 any XYZ, XYM or XYZM dimension will always be parsed as if it
+/ was just XY; this is fully consintent with RL2 specific requirements
+/ (just rendering 2D geoms via Cairo)
+/
+*/
+
+static int
+rl2GeomEndianArch ()
+{
+/* checking if target CPU is a little-endian one */
+    union cvt
+    {
+	unsigned char byte[4];
+	int int_value;
+    } convert;
+    convert.int_value = 1;
+    if (convert.byte[0] == 0)
+	return 0;
+    return 1;
+}
+
+static rl2PointPtr
+rl2CreatePoint (double x, double y)
+{
+/* POINT object constructor */
+    rl2PointPtr p = malloc (sizeof (rl2Point));
+    p->x = x;
+    p->y = y;
+    p->next = NULL;
+    return p;
+}
+
+static void
+rl2DestroyPoint (rl2PointPtr ptr)
+{
+/* POINT object destructor */
+    if (ptr != NULL)
+	free (ptr);
+}
+
+static rl2LinestringPtr
+rl2CreateLinestring (int vert)
+{
+/* LINESTRING object constructor */
+    rl2LinestringPtr p = malloc (sizeof (rl2Linestring));
+    p->coords = malloc (sizeof (double) * (vert * 2));
+    p->points = vert;
+    p->minx = DBL_MAX;
+    p->miny = DBL_MAX;
+    p->maxx = 0.0 - DBL_MAX;
+    p->maxy = 0.0 - DBL_MAX;
+    p->next = NULL;
+    return p;
+}
+
+RL2_PRIVATE void
+rl2DestroyLinestring (rl2LinestringPtr ptr)
+{
+/* LINESTRING object desctructror */
+    if (ptr)
+      {
+	  if (ptr->coords)
+	      free (ptr->coords);
+	  free (ptr);
+      }
+}
+
+RL2_PRIVATE rl2LinestringPtr
+rl2_linestring_to_image (rl2LinestringPtr line, int height, double minx,
+			 double miny, double x_res, double y_res)
+{
+/* creating a Linestring in image coordinates */
+    rl2LinestringPtr out = NULL;
+    int iv;
+    double x;
+    double y;
+    double dx;
+    double dy;
+
+    if (line == NULL)
+	return NULL;
+    out = rl2CreateLinestring (line->points);
+    if (out == NULL)
+	return out;
+    for (iv = 0; iv < line->points; iv++)
+      {
+	  /* populating the X and Y arrays */
+	  rl2GetPoint (line->coords, iv, &x, &y);
+	  dx = (x - minx) / x_res;
+	  dy = (double) height - ((y - miny) / y_res);
+	  rl2SetPoint (out->coords, iv, dx, dy);
+      }
+    return out;
+}
+
+static rl2RingPtr
+rl2CreateRing (int vert)
+{
+/* ring object constructor */
+    rl2RingPtr p = malloc (sizeof (rl2Ring));
+    p->coords = malloc (sizeof (double) * (vert * 2));
+    p->points = vert;
+    p->minx = DBL_MAX;
+    p->miny = DBL_MAX;
+    p->maxx = 0.0 - DBL_MAX;
+    p->maxy = 0.0 - DBL_MAX;
+    p->next = NULL;
+    return p;
+}
+
+RL2_PRIVATE rl2RingPtr
+rl2_ring_to_image (rl2RingPtr ring, int height, double minx, double miny,
+		   double x_res, double y_res)
+{
+/* creating a Ring in image coordinates */
+    rl2RingPtr out = NULL;
+    int iv;
+    double x;
+    double y;
+    double dx;
+    double dy;
+
+    if (ring == NULL)
+	return NULL;
+    out = rl2CreateRing (ring->points);
+    if (out == NULL)
+	return out;
+    for (iv = 0; iv < ring->points; iv++)
+      {
+	  /* populating the X and Y arrays */
+	  rl2GetPoint (ring->coords, iv, &x, &y);
+	  dx = (x - minx) / x_res;
+	  dy = (double) height - ((y - miny) / y_res);
+	  rl2SetPoint (out->coords, iv, dx, dy);
+      }
+    return out;
+}
+
+RL2_PRIVATE void
+rl2DestroyRing (rl2RingPtr ptr)
+{
+/* ring object destructor */
+    if (ptr)
+      {
+	  if (ptr->coords)
+	      free (ptr->coords);
+	  free (ptr);
+      }
+}
+
+static rl2PolygonPtr
+rl2CreatePolygon (int vert, int excl)
+{
+/* POLYGON object constructor */
+    rl2PolygonPtr p;
+    rl2RingPtr pP;
+    int ind;
+    p = malloc (sizeof (rl2Polygon));
+    p->exterior = rl2CreateRing (vert);
+    p->num_interiors = excl;
+    p->next = NULL;
+    if (excl == 0)
+	p->interiors = NULL;
+    else
+	p->interiors = malloc (sizeof (rl2Ring) * excl);
+    for (ind = 0; ind < p->num_interiors; ind++)
+      {
+	  pP = p->interiors + ind;
+	  pP->points = 0;
+	  pP->coords = NULL;
+      }
+    return p;
+}
+
+static void
+rl2DestroyPolygon (rl2PolygonPtr p)
+{
+/* POLYGON object destructor */
+    rl2RingPtr pP;
+    int ind;
+    if (p->exterior)
+	rl2DestroyRing (p->exterior);
+    for (ind = 0; ind < p->num_interiors; ind++)
+      {
+	  pP = p->interiors + ind;
+	  if (pP->coords)
+	      free (pP->coords);
+      }
+    if (p->interiors)
+	free (p->interiors);
+    free (p);
+}
+
+static rl2GeometryPtr
+rl2CreateGeometry ()
+{
+/* GEOMETRYCOLLECTION object constructor */
+    rl2GeometryPtr p = malloc (sizeof (rl2Geometry));
+    p->first_point = NULL;
+    p->last_point = NULL;
+    p->first_linestring = NULL;
+    p->last_linestring = NULL;
+    p->first_polygon = NULL;
+    p->last_polygon = NULL;
+    return p;
+}
+
+static int
+rl2GeomImport32 (const unsigned char *p, int little_endian,
+		 int little_endian_arch)
+{
+/* fetches a 32bit int from BLOB respecting declared endiannes */
+    union cvt
+    {
+	unsigned char byte[4];
+	int int_value;
+    } convert;
+    if (little_endian_arch)
+      {
+	  /* Litte-Endian architecture [e.g. x86] */
+	  if (!little_endian)
+	    {
+		/* Big Endian data */
+		convert.byte[0] = *(p + 3);
+		convert.byte[1] = *(p + 2);
+		convert.byte[2] = *(p + 1);
+		convert.byte[3] = *(p + 0);
+	    }
+	  else
+	    {
+		/* Little Endian data */
+		convert.byte[0] = *(p + 0);
+		convert.byte[1] = *(p + 1);
+		convert.byte[2] = *(p + 2);
+		convert.byte[3] = *(p + 3);
+	    }
+      }
+    else
+      {
+	  /* Big Endian architecture [e.g. PPC] */
+	  if (!little_endian)
+	    {
+		/* Big Endian data */
+		convert.byte[0] = *(p + 0);
+		convert.byte[1] = *(p + 1);
+		convert.byte[2] = *(p + 2);
+		convert.byte[3] = *(p + 3);
+	    }
+	  else
+	    {
+		/* Little Endian data */
+		convert.byte[0] = *(p + 3);
+		convert.byte[1] = *(p + 2);
+		convert.byte[2] = *(p + 1);
+		convert.byte[3] = *(p + 0);
+	    }
+      }
+    return convert.int_value;
+}
+
+static float
+rl2GeomImportF32 (const unsigned char *p, int little_endian,
+		  int little_endian_arch)
+{
+/* fetches a 32bit float from BLOB respecting declared endiannes */
+    union cvt
+    {
+	unsigned char byte[4];
+	float flt_value;
+    } convert;
+    if (little_endian_arch)
+      {
+	  /* Litte-Endian architecture [e.g. x86] */
+	  if (!little_endian)
+	    {
+		/* Big Endian data */
+		convert.byte[0] = *(p + 3);
+		convert.byte[1] = *(p + 2);
+		convert.byte[2] = *(p + 1);
+		convert.byte[3] = *(p + 0);
+	    }
+	  else
+	    {
+		/* Little Endian data */
+		convert.byte[0] = *(p + 0);
+		convert.byte[1] = *(p + 1);
+		convert.byte[2] = *(p + 2);
+		convert.byte[3] = *(p + 3);
+	    }
+      }
+    else
+      {
+	  /* Big Endian architecture [e.g. PPC] */
+	  if (!little_endian)
+	    {
+		/* Big Endian data */
+		convert.byte[0] = *(p + 0);
+		convert.byte[1] = *(p + 1);
+		convert.byte[2] = *(p + 2);
+		convert.byte[3] = *(p + 3);
+	    }
+	  else
+	    {
+		/* Little Endian data */
+		convert.byte[0] = *(p + 3);
+		convert.byte[1] = *(p + 2);
+		convert.byte[2] = *(p + 1);
+		convert.byte[3] = *(p + 0);
+	    }
+      }
+    return convert.flt_value;
+}
+
+static double
+rl2GeomImport64 (const unsigned char *p, int little_endian,
+		 int little_endian_arch)
+{
+/* fetches a 64bit double from BLOB respecting declared endiannes */
+    union cvt
+    {
+	unsigned char byte[8];
+	double double_value;
+    } convert;
+    if (little_endian_arch)
+      {
+/* Litte-Endian architecture [e.g. x86] */
+	  if (!little_endian)
+	    {
+		/* Big Endian data */
+		convert.byte[0] = *(p + 7);
+		convert.byte[1] = *(p + 6);
+		convert.byte[2] = *(p + 5);
+		convert.byte[3] = *(p + 4);
+		convert.byte[4] = *(p + 3);
+		convert.byte[5] = *(p + 2);
+		convert.byte[6] = *(p + 1);
+		convert.byte[7] = *(p + 0);
+	    }
+	  else
+	    {
+		/* Little Endian data */
+		convert.byte[0] = *(p + 0);
+		convert.byte[1] = *(p + 1);
+		convert.byte[2] = *(p + 2);
+		convert.byte[3] = *(p + 3);
+		convert.byte[4] = *(p + 4);
+		convert.byte[5] = *(p + 5);
+		convert.byte[6] = *(p + 6);
+		convert.byte[7] = *(p + 7);
+	    }
+      }
+    else
+      {
+	  /* Big Endian architecture [e.g. PPC] */
+	  if (!little_endian)
+	    {
+		/* Big Endian data */
+		convert.byte[0] = *(p + 0);
+		convert.byte[1] = *(p + 1);
+		convert.byte[2] = *(p + 2);
+		convert.byte[3] = *(p + 3);
+		convert.byte[4] = *(p + 4);
+		convert.byte[5] = *(p + 5);
+		convert.byte[6] = *(p + 6);
+		convert.byte[7] = *(p + 7);
+	    }
+	  else
+	    {
+		/* Little Endian data */
+		convert.byte[0] = *(p + 7);
+		convert.byte[1] = *(p + 6);
+		convert.byte[2] = *(p + 5);
+		convert.byte[3] = *(p + 4);
+		convert.byte[4] = *(p + 3);
+		convert.byte[5] = *(p + 2);
+		convert.byte[6] = *(p + 1);
+		convert.byte[7] = *(p + 0);
+	    }
+      }
+    return convert.double_value;
+}
+
+static void
+rl2GeomExport32 (unsigned char *p, int value, int little_endian,
+		 int little_endian_arch)
+{
+/* stores a 32bit int into a BLOB respecting declared endiannes */
+    union cvt
+    {
+	unsigned char byte[4];
+	int int_value;
+    } convert;
+    convert.int_value = value;
+    if (little_endian_arch)
+      {
+	  /* Litte-Endian architecture [e.g. x86] */
+	  if (!little_endian)
+	    {
+		/* Big Endian data */
+		*(p + 3) = convert.byte[0];
+		*(p + 2) = convert.byte[1];
+		*(p + 1) = convert.byte[2];
+		*(p + 0) = convert.byte[3];
+	    }
+	  else
+	    {
+		/* Little Endian data */
+		*(p + 0) = convert.byte[0];
+		*(p + 1) = convert.byte[1];
+		*(p + 2) = convert.byte[2];
+		*(p + 3) = convert.byte[3];
+	    }
+      }
+    else
+      {
+	  /* Big Endian architecture [e.g. PPC] */
+	  if (!little_endian)
+	    {
+		/* Big Endian data */
+		*(p + 0) = convert.byte[0];
+		*(p + 1) = convert.byte[1];
+		*(p + 2) = convert.byte[2];
+		*(p + 3) = convert.byte[3];
+	    }
+	  else
+	    {
+		/* Little Endian data */
+		*(p + 3) = convert.byte[0];
+		*(p + 2) = convert.byte[1];
+		*(p + 1) = convert.byte[2];
+		*(p + 0) = convert.byte[3];
+	    }
+      }
+}
+
+static void
+rl2GeomExport64 (unsigned char *p, double value, int little_endian,
+		 int little_endian_arch)
+{
+/* stores a 64bit double into a BLOB respecting declared endiannes */
+    union cvt
+    {
+	unsigned char byte[8];
+	double double_value;
+    } convert;
+    convert.double_value = value;
+    if (little_endian_arch)
+      {
+/* Litte-Endian architecture [e.g. x86] */
+	  if (!little_endian)
+	    {
+		/* Big Endian data */
+		*(p + 7) = convert.byte[0];
+		*(p + 6) = convert.byte[1];
+		*(p + 5) = convert.byte[2];
+		*(p + 4) = convert.byte[3];
+		*(p + 3) = convert.byte[4];
+		*(p + 2) = convert.byte[5];
+		*(p + 1) = convert.byte[6];
+		*(p + 0) = convert.byte[7];
+	    }
+	  else
+	    {
+		/* Little Endian data */
+		*(p + 0) = convert.byte[0];
+		*(p + 1) = convert.byte[1];
+		*(p + 2) = convert.byte[2];
+		*(p + 3) = convert.byte[3];
+		*(p + 4) = convert.byte[4];
+		*(p + 5) = convert.byte[5];
+		*(p + 6) = convert.byte[6];
+		*(p + 7) = convert.byte[7];
+	    }
+      }
+    else
+      {
+	  /* Big Endian architecture [e.g. PPC] */
+	  if (!little_endian)
+	    {
+		/* Big Endian data */
+		*(p + 0) = convert.byte[0];
+		*(p + 1) = convert.byte[1];
+		*(p + 2) = convert.byte[2];
+		*(p + 3) = convert.byte[3];
+		*(p + 4) = convert.byte[4];
+		*(p + 5) = convert.byte[5];
+		*(p + 6) = convert.byte[6];
+		*(p + 7) = convert.byte[7];
+	    }
+	  else
+	    {
+		/* Little Endian data */
+		*(p + 7) = convert.byte[0];
+		*(p + 6) = convert.byte[1];
+		*(p + 5) = convert.byte[2];
+		*(p + 4) = convert.byte[3];
+		*(p + 3) = convert.byte[4];
+		*(p + 2) = convert.byte[5];
+		*(p + 1) = convert.byte[6];
+		*(p + 0) = convert.byte[7];
+	    }
+      }
+}
+
+static void
+rl2AddPointToGeometry (rl2GeometryPtr p, double x, double y)
+{
+/* adding a LINESTRING to this GEOMETRYCOLLECTION */
+    rl2PointPtr point = rl2CreatePoint (x, y);
+    if (p->first_point == NULL)
+	p->first_point = point;
+    if (p->last_point != NULL)
+	p->last_point->next = point;
+    p->last_point = point;
+}
+
+static void
+rl2ParsePoint (rl2GeometryPtr geom, const unsigned char *blob, int size,
+	       int endian, int endian_arch, int *offset)
+{
+/* decodes a POINT from WKB */
+    double x;
+    double y;
+    if (size < *offset + 16)
+	return;
+    x = rl2GeomImport64 (blob + *offset, endian, endian_arch);
+    y = rl2GeomImport64 (blob + (*offset + 8), endian, endian_arch);
+    *offset += 16;
+    rl2AddPointToGeometry (geom, x, y);
+}
+
+static void
+rl2ParsePointZ (rl2GeometryPtr geom, const unsigned char *blob, int size,
+		int endian, int endian_arch, int *offset)
+{
+/* decodes a POINTZ from WKB */
+    double x;
+    double y;
+    if (size < *offset + 24)
+	return;
+    x = rl2GeomImport64 (blob + *offset, endian, endian_arch);
+    y = rl2GeomImport64 (blob + (*offset + 8), endian, endian_arch);
+    *offset += 24;
+    rl2AddPointToGeometry (geom, x, y);
+}
+
+static void
+rl2ParsePointM (rl2GeometryPtr geom, const unsigned char *blob, int size,
+		int endian, int endian_arch, int *offset)
+{
+/* decodes a POINTM from WKB */
+    double x;
+    double y;
+    if (size < *offset + 24)
+	return;
+    x = rl2GeomImport64 (blob + *offset, endian, endian_arch);
+    y = rl2GeomImport64 (blob + (*offset + 8), endian, endian_arch);
+    *offset += 24;
+    rl2AddPointToGeometry (geom, x, y);
+}
+
+static void
+rl2ParsePointZM (rl2GeometryPtr geom, const unsigned char *blob, int size,
+		 int endian, int endian_arch, int *offset)
+{
+/* decodes a POINTZM from WKB */
+    double x;
+    double y;
+    if (size < *offset + 32)
+	return;
+    x = rl2GeomImport64 (blob + *offset, endian, endian_arch);
+    y = rl2GeomImport64 (blob + (*offset + 8), endian, endian_arch);
+    *offset += 32;
+    rl2AddPointToGeometry (geom, x, y);
+}
+
+static rl2LinestringPtr
+rl2AddLinestringToGeometry (rl2GeometryPtr p, int vert)
+{
+/* adding a POINT to this GEOMETRYCOLLECTION */
+    rl2LinestringPtr line = rl2CreateLinestring (vert);
+    if (p->first_linestring == NULL)
+	p->first_linestring = line;
+    if (p->last_linestring != NULL)
+	p->last_linestring->next = line;
+    p->last_linestring = line;
+    return line;
+}
+
+static void
+rl2ParseLine (rl2GeometryPtr geom, const unsigned char *blob, int size,
+	      int endian, int endian_arch, int *offset)
+{
+/* decodes a LINESTRING from WKB */
+    int points;
+    int iv;
+    double x;
+    double y;
+    rl2LinestringPtr line;
+    if (size < *offset + 4)
+	return;
+    points = rl2GeomImport32 (blob + *offset, endian, endian_arch);
+    *offset += 4;
+    if (size < *offset + (16 * points))
+	return;
+    line = rl2AddLinestringToGeometry (geom, points);
+    for (iv = 0; iv < points; iv++)
+      {
+	  x = rl2GeomImport64 (blob + *offset, endian, endian_arch);
+	  y = rl2GeomImport64 (blob + (*offset + 8), endian, endian_arch);
+	  rl2SetPoint (line->coords, iv, x, y);
+	  if (x < line->minx)
+	      line->minx = x;
+	  if (x > line->maxx)
+	      line->maxx = x;
+	  if (y < line->miny)
+	      line->miny = y;
+	  if (y > line->maxy)
+	      line->maxy = y;
+	  *offset += 16;
+      }
+}
+
+static void
+rl2ParseLineZ (rl2GeometryPtr geom, const unsigned char *blob, int size,
+	       int endian, int endian_arch, int *offset)
+{
+/* decodes a LINESTRINGZ from WKB */
+    int points;
+    int iv;
+    double x;
+    double y;
+    rl2LinestringPtr line;
+    if (size < *offset + 4)
+	return;
+    points = rl2GeomImport32 (blob + *offset, endian, endian_arch);
+    *offset += 4;
+    if (size < *offset + (24 * points))
+	return;
+    line = rl2AddLinestringToGeometry (geom, points);
+    for (iv = 0; iv < points; iv++)
+      {
+	  x = rl2GeomImport64 (blob + *offset, endian, endian_arch);
+	  y = rl2GeomImport64 (blob + (*offset + 8), endian, endian_arch);
+	  rl2SetPoint (line->coords, iv, x, y);
+	  if (x < line->minx)
+	      line->minx = x;
+	  if (x > line->maxx)
+	      line->maxx = x;
+	  if (y < line->miny)
+	      line->miny = y;
+	  if (y > line->maxy)
+	      line->maxy = y;
+	  *offset += 24;
+      }
+}
+
+static void
+rl2ParseLineM (rl2GeometryPtr geom, const unsigned char *blob, int size,
+	       int endian, int endian_arch, int *offset)
+{
+/* decodes a LINESTRINGM from WKB */
+    int points;
+    int iv;
+    double x;
+    double y;
+    rl2LinestringPtr line;
+    if (size < *offset + 4)
+	return;
+    points = rl2GeomImport32 (blob + *offset, endian, endian_arch);
+    *offset += 4;
+    if (size < *offset + (24 * points))
+	return;
+    line = rl2AddLinestringToGeometry (geom, points);
+    for (iv = 0; iv < points; iv++)
+      {
+	  x = rl2GeomImport64 (blob + *offset, endian, endian_arch);
+	  y = rl2GeomImport64 (blob + (*offset + 8), endian, endian_arch);
+	  rl2SetPoint (line->coords, iv, x, y);
+	  if (x < line->minx)
+	      line->minx = x;
+	  if (x > line->maxx)
+	      line->maxx = x;
+	  if (y < line->miny)
+	      line->miny = y;
+	  if (y > line->maxy)
+	      line->maxy = y;
+	  *offset += 24;
+      }
+}
+
+static void
+rl2ParseLineZM (rl2GeometryPtr geom, const unsigned char *blob, int size,
+		int endian, int endian_arch, int *offset)
+{
+/* decodes a LINESTRINGZM from WKB */
+    int points;
+    int iv;
+    double x;
+    double y;
+    rl2LinestringPtr line;
+    if (size < *offset + 4)
+	return;
+    points = rl2GeomImport32 (blob + *offset, endian, endian_arch);
+    *offset += 4;
+    if (size < *offset + (32 * points))
+	return;
+    line = rl2AddLinestringToGeometry (geom, points);
+    for (iv = 0; iv < points; iv++)
+      {
+	  x = rl2GeomImport64 (blob + *offset, endian, endian_arch);
+	  y = rl2GeomImport64 (blob + (*offset + 8), endian, endian_arch);
+	  rl2SetPoint (line->coords, iv, x, y);
+	  if (x < line->minx)
+	      line->minx = x;
+	  if (x > line->maxx)
+	      line->maxx = x;
+	  if (y < line->miny)
+	      line->miny = y;
+	  if (y > line->maxy)
+	      line->maxy = y;
+	  *offset += 32;
+      }
+}
+
+static rl2PolygonPtr
+rl2AddPolygonToGeometry (rl2GeometryPtr p, int vert, int interiors)
+{
+/* adding a POLYGON to this GEOMETRYCOLLECTION */
+    rl2PolygonPtr polyg = rl2CreatePolygon (vert, interiors);
+    if (p->first_polygon == NULL)
+	p->first_polygon = polyg;
+    if (p->last_polygon != NULL)
+	p->last_polygon->next = polyg;
+    p->last_polygon = polyg;
+    return polyg;
+}
+
+static rl2RingPtr
+rl2AddInteriorRing (rl2PolygonPtr p, int pos, int vert)
+{
+/* adding an interior ring to some polygon */
+    rl2RingPtr pP = p->interiors + pos;
+    pP->points = vert;
+    pP->coords = malloc (sizeof (double) * (vert * 2));
+    return pP;
+}
+
+static void
+rl2ParsePolygon (rl2GeometryPtr geom, const unsigned char *blob, int size,
+		 int endian, int endian_arch, int *offset)
+{
+/* decodes a POLYGON from WKB */
+    int rings;
+    int nverts;
+    int iv;
+    int ib;
+    double x;
+    double y;
+    rl2PolygonPtr polyg = NULL;
+    rl2RingPtr ring;
+    if (size < *offset + 4)
+	return;
+    rings = rl2GeomImport32 (blob + *offset, endian, endian_arch);
+    *offset += 4;
+    for (ib = 0; ib < rings; ib++)
+      {
+	  if (size < *offset + 4)
+	      return;
+	  nverts = rl2GeomImport32 (blob + *offset, endian, endian_arch);
+	  *offset += 4;
+	  if (size < *offset + (16 * nverts))
+	      return;
+	  if (ib == 0)
+	    {
+		polyg = rl2AddPolygonToGeometry (geom, nverts, rings - 1);
+		ring = polyg->exterior;
+	    }
+	  else
+	      ring = rl2AddInteriorRing (polyg, ib - 1, nverts);
+	  for (iv = 0; iv < nverts; iv++)
+	    {
+		x = rl2GeomImport64 (blob + *offset, endian, endian_arch);
+		y = rl2GeomImport64 (blob + (*offset + 8), endian, endian_arch);
+		*offset += 16;
+		rl2SetPoint (ring->coords, iv, x, y);
+		if (x < ring->minx)
+		    ring->minx = x;
+		if (x > ring->maxx)
+		    ring->maxx = x;
+		if (y < ring->miny)
+		    ring->miny = y;
+		if (y > ring->maxy)
+		    ring->maxy = y;
+	    }
+      }
+}
+
+static void
+rl2ParsePolygonZ (rl2GeometryPtr geom, const unsigned char *blob, int size,
+		  int endian, int endian_arch, int *offset)
+{
+/* decodes a POLYGONZ from WKB */
+    int rings;
+    int nverts;
+    int iv;
+    int ib;
+    double x;
+    double y;
+    rl2PolygonPtr polyg = NULL;
+    rl2RingPtr ring;
+    if (size < *offset + 4)
+	return;
+    rings = rl2GeomImport32 (blob + *offset, endian, endian_arch);
+    *offset += 4;
+    for (ib = 0; ib < rings; ib++)
+      {
+	  if (size < *offset + 4)
+	      return;
+	  nverts = rl2GeomImport32 (blob + *offset, endian, endian_arch);
+	  *offset += 4;
+	  if (size < *offset + (24 * nverts))
+	      return;
+	  if (ib == 0)
+	    {
+		polyg = rl2AddPolygonToGeometry (geom, nverts, rings - 1);
+		ring = polyg->exterior;
+	    }
+	  else
+	      ring = rl2AddInteriorRing (polyg, ib - 1, nverts);
+	  for (iv = 0; iv < nverts; iv++)
+	    {
+		x = rl2GeomImport64 (blob + *offset, endian, endian_arch);
+		y = rl2GeomImport64 (blob + (*offset + 8), endian, endian_arch);
+		*offset += 24;
+		rl2SetPoint (ring->coords, iv, x, y);
+		if (x < ring->minx)
+		    ring->minx = x;
+		if (x > ring->maxx)
+		    ring->maxx = x;
+		if (y < ring->miny)
+		    ring->miny = y;
+		if (y > ring->maxy)
+		    ring->maxy = y;
+	    }
+      }
+}
+
+static void
+rl2ParsePolygonM (rl2GeometryPtr geom, const unsigned char *blob, int size,
+		  int endian, int endian_arch, int *offset)
+{
+/* decodes a POLYGONM from WKB */
+    int rings;
+    int nverts;
+    int iv;
+    int ib;
+    double x;
+    double y;
+    rl2PolygonPtr polyg = NULL;
+    rl2RingPtr ring;
+    if (size < *offset + 4)
+	return;
+    rings = rl2GeomImport32 (blob + *offset, endian, endian_arch);
+    *offset += 4;
+    for (ib = 0; ib < rings; ib++)
+      {
+	  if (size < *offset + 4)
+	      return;
+	  nverts = rl2GeomImport32 (blob + *offset, endian, endian_arch);
+	  *offset += 4;
+	  if (size < *offset + (24 * nverts))
+	      return;
+	  if (ib == 0)
+	    {
+		polyg = rl2AddPolygonToGeometry (geom, nverts, rings - 1);
+		ring = polyg->exterior;
+	    }
+	  else
+	      ring = rl2AddInteriorRing (polyg, ib - 1, nverts);
+	  for (iv = 0; iv < nverts; iv++)
+	    {
+		x = rl2GeomImport64 (blob + *offset, endian, endian_arch);
+		y = rl2GeomImport64 (blob + (*offset + 8), endian, endian_arch);
+		*offset += 24;
+		rl2SetPoint (ring->coords, iv, x, y);
+		if (x < ring->minx)
+		    ring->minx = x;
+		if (x > ring->maxx)
+		    ring->maxx = x;
+		if (y < ring->miny)
+		    ring->miny = y;
+		if (y > ring->maxy)
+		    ring->maxy = y;
+	    }
+      }
+}
+
+static void
+rl2ParsePolygonZM (rl2GeometryPtr geom, const unsigned char *blob, int size,
+		   int endian, int endian_arch, int *offset)
+{
+/* decodes a POLYGONZM from WKB */
+    int rings;
+    int nverts;
+    int iv;
+    int ib;
+    double x;
+    double y;
+    rl2PolygonPtr polyg = NULL;
+    rl2RingPtr ring;
+    if (size < *offset + 4)
+	return;
+    rings = rl2GeomImport32 (blob + *offset, endian, endian_arch);
+    *offset += 4;
+    for (ib = 0; ib < rings; ib++)
+      {
+	  if (size < *offset + 4)
+	      return;
+	  nverts = rl2GeomImport32 (blob + *offset, endian, endian_arch);
+	  *offset += 4;
+	  if (size < *offset + (32 * nverts))
+	      return;
+	  if (ib == 0)
+	    {
+		polyg = rl2AddPolygonToGeometry (geom, nverts, rings - 1);
+		ring = polyg->exterior;
+	    }
+	  else
+	      ring = rl2AddInteriorRing (polyg, ib - 1, nverts);
+	  for (iv = 0; iv < nverts; iv++)
+	    {
+		x = rl2GeomImport64 (blob + *offset, endian, endian_arch);
+		y = rl2GeomImport64 (blob + (*offset + 8), endian, endian_arch);
+		*offset += 32;
+		rl2SetPoint (ring->coords, iv, x, y);
+		if (x < ring->minx)
+		    ring->minx = x;
+		if (x > ring->maxx)
+		    ring->maxx = x;
+		if (y < ring->miny)
+		    ring->miny = y;
+		if (y > ring->maxy)
+		    ring->maxy = y;
+	    }
+      }
+}
+
+static void
+rl2ParseCompressedLine (rl2GeometryPtr geom, const unsigned char *blob,
+			int size, int endian, int endian_arch, int *offset)
+{
+/* decodes a COMPRESSED LINESTRING from WKB */
+    int points;
+    int iv;
+    double x;
+    double y;
+    double last_x = 0.0;
+    double last_y = 0.0;
+    float fx;
+    float fy;
+    rl2LinestringPtr line;
+    if (size < *offset + 4)
+	return;
+    points = rl2GeomImport32 (blob + *offset, endian, endian_arch);
+    *offset += 4;
+    if (size < *offset + (8 * points) + 16)
+	return;
+    line = rl2AddLinestringToGeometry (geom, points);
+    for (iv = 0; iv < points; iv++)
+      {
+	  if (iv == 0 || iv == (points - 1))
+	    {
+		/* first and last vertices are uncompressed */
+		x = rl2GeomImport64 (blob + *offset, endian, endian_arch);
+		y = rl2GeomImport64 (blob + (*offset + 8), endian, endian_arch);
+		*offset += 16;
+	    }
+	  else
+	    {
+		/* any other intermediate vertex is compressed */
+		fx = rl2GeomImportF32 (blob + *offset, endian, endian_arch);
+		fy = rl2GeomImportF32 (blob + (*offset + 4), endian,
+				       endian_arch);
+		x = last_x + fx;
+		y = last_y + fy;
+		*offset += 8;
+	    }
+	  rl2SetPoint (line->coords, iv, x, y);
+	  if (x < line->minx)
+	      line->minx = x;
+	  if (x > line->maxx)
+	      line->maxx = x;
+	  if (y < line->miny)
+	      line->miny = y;
+	  if (y > line->maxy)
+	      line->maxy = y;
+	  last_x = x;
+	  last_y = y;
+      }
+}
+
+static void
+rl2ParseCompressedLineZ (rl2GeometryPtr geom, const unsigned char *blob,
+			 int size, int endian, int endian_arch, int *offset)
+{
+/* decodes a COMPRESSED LINESTRINGZ from WKB */
+    int points;
+    int iv;
+    double x;
+    double y;
+    double last_x = 0.0;
+    double last_y = 0.0;
+    float fx;
+    float fy;
+    rl2LinestringPtr line;
+    if (size < *offset + 4)
+	return;
+    points = rl2GeomImport32 (blob + *offset, endian, endian_arch);
+    *offset += 4;
+    if (size < *offset + (12 * points) + 24)
+	return;
+    line = rl2AddLinestringToGeometry (geom, points);
+    for (iv = 0; iv < points; iv++)
+      {
+	  if (iv == 0 || iv == (points - 1))
+	    {
+		/* first and last vertices are uncompressed */
+		x = rl2GeomImport64 (blob + *offset, endian, endian_arch);
+		y = rl2GeomImport64 (blob + (*offset + 8), endian, endian_arch);
+		*offset += 24;
+	    }
+	  else
+	    {
+		/* any other intermediate vertex is compressed */
+		fx = rl2GeomImportF32 (blob + *offset, endian, endian_arch);
+		fy = rl2GeomImportF32 (blob + (*offset + 4), endian,
+				       endian_arch);
+		x = last_x + fx;
+		y = last_y + fy;
+		*offset += 12;
+	    }
+	  rl2SetPoint (line->coords, iv, x, y);
+	  if (x < line->minx)
+	      line->minx = x;
+	  if (x > line->maxx)
+	      line->maxx = x;
+	  if (y < line->miny)
+	      line->miny = y;
+	  if (y > line->maxy)
+	      line->maxy = y;
+	  last_x = x;
+	  last_y = y;
+      }
+}
+
+static void
+rl2ParseCompressedLineM (rl2GeometryPtr geom, const unsigned char *blob,
+			 int size, int endian, int endian_arch, int *offset)
+{
+/* decodes a COMPRESSED LINESTRINGM from WKB */
+    int points;
+    int iv;
+    double x;
+    double y;
+    double last_x = 0.0;
+    double last_y = 0.0;
+    float fx;
+    float fy;
+    rl2LinestringPtr line;
+    if (size < *offset + 4)
+	return;
+    points = rl2GeomImport32 (blob + *offset, endian, endian_arch);
+    *offset += 4;
+    if (size < *offset + (16 * points) + 16)
+	return;
+    line = rl2AddLinestringToGeometry (geom, points);
+    for (iv = 0; iv < points; iv++)
+      {
+	  if (iv == 0 || iv == (points - 1))
+	    {
+		/* first and last vertices are uncompressed */
+		x = rl2GeomImport64 (blob + *offset, endian, endian_arch);
+		y = rl2GeomImport64 (blob + (*offset + 8), endian, endian_arch);
+		*offset += 24;
+	    }
+	  else
+	    {
+		/* any other intermediate vertex is compressed */
+		fx = rl2GeomImportF32 (blob + *offset, endian, endian_arch);
+		fy = rl2GeomImportF32 (blob + (*offset + 4), endian,
+				       endian_arch);
+		x = last_x + fx;
+		y = last_y + fy;
+		*offset += 16;
+	    }
+	  rl2SetPoint (line->coords, iv, x, y);
+	  if (x < line->minx)
+	      line->minx = x;
+	  if (x > line->maxx)
+	      line->maxx = x;
+	  if (y < line->miny)
+	      line->miny = y;
+	  if (y > line->maxy)
+	      line->maxy = y;
+	  last_x = x;
+	  last_y = y;
+      }
+}
+
+static void
+rl2ParseCompressedLineZM (rl2GeometryPtr geom, const unsigned char *blob,
+			  int size, int endian, int endian_arch, int *offset)
+{
+/* decodes a COMPRESSED LINESTRINGZM from WKB */
+    int points;
+    int iv;
+    double x;
+    double y;
+    double last_x = 0.0;
+    double last_y = 0.0;
+    float fx;
+    float fy;
+    rl2LinestringPtr line;
+    if (size < *offset + 4)
+	return;
+    points = rl2GeomImport32 (blob + *offset, endian, endian_arch);
+    *offset += 4;
+    if (size < *offset + (20 * points) + 24)
+	return;
+    line = rl2AddLinestringToGeometry (geom, points);
+    for (iv = 0; iv < points; iv++)
+      {
+	  if (iv == 0 || iv == (points - 1))
+	    {
+		/* first and last vertices are uncompressed */
+		x = rl2GeomImport64 (blob + *offset, endian, endian_arch);
+		y = rl2GeomImport64 (blob + (*offset + 8), endian, endian_arch);
+		*offset += 32;
+	    }
+	  else
+	    {
+		/* any other intermediate vertex is compressed */
+		fx = rl2GeomImportF32 (blob + *offset, endian, endian_arch);
+		fy = rl2GeomImportF32 (blob + (*offset + 4), endian,
+				       endian_arch);
+		x = last_x + fx;
+		y = last_y + fy;
+		*offset += 20;
+	    }
+	  rl2SetPoint (line->coords, iv, x, y);
+	  if (x < line->minx)
+	      line->minx = x;
+	  if (x > line->maxx)
+	      line->maxx = x;
+	  if (y < line->miny)
+	      line->miny = y;
+	  if (y > line->maxy)
+	      line->maxy = y;
+	  last_x = x;
+	  last_y = y;
+      }
+}
+
+static void
+rl2ParseCompressedPolygon (rl2GeometryPtr geom, const unsigned char *blob,
+			   int size, int endian, int endian_arch, int *offset)
+{
+/* decodes a COMPRESSED POLYGON from WKB */
+    int rings;
+    int nverts;
+    int iv;
+    int ib;
+    double x;
+    double y;
+    double last_x = 0.0;
+    double last_y = 0.0;
+    float fx;
+    float fy;
+    rl2PolygonPtr polyg = NULL;
+    rl2RingPtr ring;
+    if (size < *offset + 4)
+	return;
+    rings = rl2GeomImport32 (blob + *offset, endian, endian_arch);
+    *offset += 4;
+    for (ib = 0; ib < rings; ib++)
+      {
+	  if (size < *offset + 4)
+	      return;
+	  nverts = rl2GeomImport32 (blob + *offset, endian, endian_arch);
+	  *offset += 4;
+	  if (size < *offset + (8 * nverts) + 16)
+	      return;
+	  if (ib == 0)
+	    {
+		polyg = rl2AddPolygonToGeometry (geom, nverts, rings - 1);
+		ring = polyg->exterior;
+	    }
+	  else
+	      ring = rl2AddInteriorRing (polyg, ib - 1, nverts);
+	  for (iv = 0; iv < nverts; iv++)
+	    {
+		if (iv == 0 || iv == (nverts - 1))
+		  {
+		      /* first and last vertices are uncompressed */
+		      x = rl2GeomImport64 (blob + *offset, endian, endian_arch);
+		      y = rl2GeomImport64 (blob + (*offset + 8), endian,
+					   endian_arch);
+		      *offset += 16;
+		  }
+		else
+		  {
+		      /* any other intermediate vertex is compressed */
+		      fx = rl2GeomImportF32 (blob + *offset, endian,
+					     endian_arch);
+		      fy = rl2GeomImportF32 (blob + (*offset + 4), endian,
+					     endian_arch);
+		      x = last_x + fx;
+		      y = last_y + fy;
+		      *offset += 8;
+		  }
+		rl2SetPoint (ring->coords, iv, x, y);
+		if (x < ring->minx)
+		    ring->minx = x;
+		if (x > ring->maxx)
+		    ring->maxx = x;
+		if (y < ring->miny)
+		    ring->miny = y;
+		if (y > ring->maxy)
+		    ring->maxy = y;
+		last_x = x;
+		last_y = y;
+	    }
+      }
+}
+
+static void
+rl2ParseCompressedPolygonZ (rl2GeometryPtr geom, const unsigned char *blob,
+			    int size, int endian, int endian_arch, int *offset)
+{
+/* decodes a COMPRESSED POLYGONZ from WKB */
+    int rings;
+    int nverts;
+    int iv;
+    int ib;
+    double x;
+    double y;
+    double last_x = 0.0;
+    double last_y = 0.0;
+    float fx;
+    float fy;
+    rl2PolygonPtr polyg = NULL;
+    rl2RingPtr ring;
+    if (size < *offset + 4)
+	return;
+    rings = rl2GeomImport32 (blob + *offset, endian, endian_arch);
+    *offset += 4;
+    for (ib = 0; ib < rings; ib++)
+      {
+	  if (size < *offset + 4)
+	      return;
+	  nverts = rl2GeomImport32 (blob + *offset, endian, endian_arch);
+	  *offset += 4;
+	  if (size < *offset + (12 * nverts) + 24)
+	      return;
+	  if (ib == 0)
+	    {
+		polyg = rl2AddPolygonToGeometry (geom, nverts, rings - 1);
+		ring = polyg->exterior;
+	    }
+	  else
+	      ring = rl2AddInteriorRing (polyg, ib - 1, nverts);
+	  for (iv = 0; iv < nverts; iv++)
+	    {
+		if (iv == 0 || iv == (nverts - 1))
+		  {
+		      /* first and last vertices are uncompressed */
+		      x = rl2GeomImport64 (blob + *offset, endian, endian_arch);
+		      y = rl2GeomImport64 (blob + (*offset + 8), endian,
+					   endian_arch);
+		      *offset += 24;
+		  }
+		else
+		  {
+		      /* any other intermediate vertex is compressed */
+		      fx = rl2GeomImportF32 (blob + *offset, endian,
+					     endian_arch);
+		      fy = rl2GeomImportF32 (blob + (*offset + 4), endian,
+					     endian_arch);
+		      x = last_x + fx;
+		      y = last_y + fy;
+		      *offset += 12;
+		  }
+		rl2SetPoint (ring->coords, iv, x, y);
+		if (x < ring->minx)
+		    ring->minx = x;
+		if (x > ring->maxx)
+		    ring->maxx = x;
+		if (y < ring->miny)
+		    ring->miny = y;
+		if (y > ring->maxy)
+		    ring->maxy = y;
+		last_x = x;
+		last_y = y;
+	    }
+      }
+}
+
+static void
+rl2ParseCompressedPolygonM (rl2GeometryPtr geom, const unsigned char *blob,
+			    int size, int endian, int endian_arch, int *offset)
+{
+/* decodes a COMPRESSED POLYGONM from WKB */
+    int rings;
+    int nverts;
+    int iv;
+    int ib;
+    double x;
+    double y;
+    double last_x = 0.0;
+    double last_y = 0.0;
+    float fx;
+    float fy;
+    rl2PolygonPtr polyg = NULL;
+    rl2RingPtr ring;
+    if (size < *offset + 4)
+	return;
+    rings = rl2GeomImport32 (blob + *offset, endian, endian_arch);
+    *offset += 4;
+    for (ib = 0; ib < rings; ib++)
+      {
+	  if (size < *offset + 4)
+	      return;
+	  nverts = rl2GeomImport32 (blob + *offset, endian, endian_arch);
+	  *offset += 4;
+	  if (size < *offset + (16 * nverts) + 16)
+	      return;
+	  if (ib == 0)
+	    {
+		polyg = rl2AddPolygonToGeometry (geom, nverts, rings - 1);
+		ring = polyg->exterior;
+	    }
+	  else
+	      ring = rl2AddInteriorRing (polyg, ib - 1, nverts);
+	  for (iv = 0; iv < nverts; iv++)
+	    {
+		if (iv == 0 || iv == (nverts - 1))
+		  {
+		      /* first and last vertices are uncompressed */
+		      x = rl2GeomImport64 (blob + *offset, endian, endian_arch);
+		      y = rl2GeomImport64 (blob + (*offset + 8), endian,
+					   endian_arch);
+		      *offset += 24;
+		  }
+		else
+		  {
+		      /* any other intermediate vertex is compressed */
+		      fx = rl2GeomImportF32 (blob + *offset, endian,
+					     endian_arch);
+		      fy = rl2GeomImportF32 (blob + (*offset + 4), endian,
+					     endian_arch);
+		      x = last_x + fx;
+		      y = last_y + fy;
+		      *offset += 16;
+		  }
+		rl2SetPoint (ring->coords, iv, x, y);
+		if (x < ring->minx)
+		    ring->minx = x;
+		if (x > ring->maxx)
+		    ring->maxx = x;
+		if (y < ring->miny)
+		    ring->miny = y;
+		if (y > ring->maxy)
+		    ring->maxy = y;
+		last_x = x;
+		last_y = y;
+	    }
+      }
+}
+
+static void
+rl2ParseCompressedPolygonZM (rl2GeometryPtr geom, const unsigned char *blob,
+			     int size, int endian, int endian_arch, int *offset)
+{
+/* decodes a COMPRESSED POLYGONZM from WKB */
+    int rings;
+    int nverts;
+    int iv;
+    int ib;
+    double x;
+    double y;
+    double last_x = 0.0;
+    double last_y = 0.0;
+    float fx;
+    float fy;
+    rl2PolygonPtr polyg = NULL;
+    rl2RingPtr ring;
+    if (size < *offset + 4)
+	return;
+    rings = rl2GeomImport32 (blob + *offset, endian, endian_arch);
+    *offset += 4;
+    for (ib = 0; ib < rings; ib++)
+      {
+	  if (size < *offset + 4)
+	      return;
+	  nverts = rl2GeomImport32 (blob + *offset, endian, endian_arch);
+	  *offset += 4;
+	  if (size < *offset + (20 * nverts) + 24)
+	      return;
+	  if (ib == 0)
+	    {
+		polyg = rl2AddPolygonToGeometry (geom, nverts, rings - 1);
+		ring = polyg->exterior;
+	    }
+	  else
+	      ring = rl2AddInteriorRing (polyg, ib - 1, nverts);
+	  for (iv = 0; iv < nverts; iv++)
+	    {
+		if (iv == 0 || iv == (nverts - 1))
+		  {
+		      /* first and last vertices are uncompressed */
+		      x = rl2GeomImport64 (blob + *offset, endian, endian_arch);
+		      y = rl2GeomImport64 (blob + (*offset + 8), endian,
+					   endian_arch);
+		      *offset += 32;
+		  }
+		else
+		  {
+		      /* any other intermediate vertex is compressed */
+		      fx = rl2GeomImportF32 (blob + *offset, endian,
+					     endian_arch);
+		      fy = rl2GeomImportF32 (blob + (*offset + 4), endian,
+					     endian_arch);
+		      x = last_x + fx;
+		      y = last_y + fy;
+		      *offset += 20;
+		  }
+		rl2SetPoint (ring->coords, iv, x, y);
+		if (x < ring->minx)
+		    ring->minx = x;
+		if (x > ring->maxx)
+		    ring->maxx = x;
+		if (y < ring->miny)
+		    ring->miny = y;
+		if (y > ring->maxy)
+		    ring->maxy = y;
+		last_x = x;
+		last_y = y;
+	    }
+      }
+}
+
+static void
+rl2ParseGeometry (rl2GeometryPtr geom, const unsigned char *blob, int size,
+		  int endian, int endian_arch, int *offset)
+{
+/* decodes a MULTIxx or GEOMETRYCOLLECTION from SpatiaLite BLOB */
+    int entities;
+    int type;
+    int ie;
+    if (size < *offset + 4)
+	return;
+    entities = rl2GeomImport32 (blob + *offset, endian, endian_arch);
+    *offset += 4;
+    for (ie = 0; ie < entities; ie++)
+      {
+	  if (size < *offset + 5)
+	      return;
+	  type = rl2GeomImport32 (blob + *offset + 1, endian, endian_arch);
+	  *offset += 5;
+	  switch (type)
+	    {
+	    case GAIA_POINT:
+		rl2ParsePoint (geom, blob, size, endian, endian_arch, offset);
+		break;
+	    case GAIA_POINTZ:
+		rl2ParsePointZ (geom, blob, size, endian, endian_arch, offset);
+		break;
+	    case GAIA_POINTM:
+		rl2ParsePointM (geom, blob, size, endian, endian_arch, offset);
+		break;
+	    case GAIA_POINTZM:
+		rl2ParsePointZM (geom, blob, size, endian, endian_arch, offset);
+		break;
+	    case GAIA_LINESTRING:
+		rl2ParseLine (geom, blob, size, endian, endian_arch, offset);
+		break;
+	    case GAIA_LINESTRINGZ:
+		rl2ParseLineZ (geom, blob, size, endian, endian_arch, offset);
+		break;
+	    case GAIA_LINESTRINGM:
+		rl2ParseLineM (geom, blob, size, endian, endian_arch, offset);
+		break;
+	    case GAIA_LINESTRINGZM:
+		rl2ParseLineZM (geom, blob, size, endian, endian_arch, offset);
+		break;
+	    case GAIA_POLYGON:
+		rl2ParsePolygon (geom, blob, size, endian, endian_arch, offset);
+		break;
+	    case GAIA_POLYGONZ:
+		rl2ParsePolygonZ (geom, blob, size, endian, endian_arch,
+				  offset);
+		break;
+	    case GAIA_POLYGONM:
+		rl2ParsePolygonM (geom, blob, size, endian, endian_arch,
+				  offset);
+		break;
+	    case GAIA_POLYGONZM:
+		rl2ParsePolygonZM (geom, blob, size, endian, endian_arch,
+				   offset);
+		break;
+	    case GAIA_COMPRESSED_LINESTRING:
+		rl2ParseCompressedLine (geom, blob, size, endian, endian_arch,
+					offset);
+		break;
+	    case GAIA_COMPRESSED_LINESTRINGZ:
+		rl2ParseCompressedLineZ (geom, blob, size, endian,
+					 endian_arch, offset);
+		break;
+	    case GAIA_COMPRESSED_LINESTRINGM:
+		rl2ParseCompressedLineM (geom, blob, size, endian,
+					 endian_arch, offset);
+		break;
+	    case GAIA_COMPRESSED_LINESTRINGZM:
+		rl2ParseCompressedLineZM (geom, blob, size, endian,
+					  endian_arch, offset);
+		break;
+	    case GAIA_COMPRESSED_POLYGON:
+		rl2ParseCompressedPolygon (geom, blob, size, endian,
+					   endian_arch, offset);
+		break;
+	    case GAIA_COMPRESSED_POLYGONZ:
+		rl2ParseCompressedPolygonZ (geom, blob, size, endian,
+					    endian_arch, offset);
+		break;
+	    case GAIA_COMPRESSED_POLYGONM:
+		rl2ParseCompressedPolygonM (geom, blob, size, endian,
+					    endian_arch, offset);
+		break;
+	    case GAIA_COMPRESSED_POLYGONZM:
+		rl2ParseCompressedPolygonZM (geom, blob, size, endian,
+					     endian_arch, offset);
+		break;
+	    default:
+		break;
+	    };
+      }
+}
+
+RL2_PRIVATE rl2GeometryPtr
+rl2_geometry_from_blob (const unsigned char *blob, int size)
+{
+/* decoding from SpatiaLite BLOB to GEOMETRY */
+    int type;
+    int little_endian;
+    int offset;
+    int endian_arch = rl2GeomEndianArch ();
+    rl2GeometryPtr geom = NULL;
+    if (size < 45)
+	return NULL;		/* cannot be an internal BLOB WKB geometry */
+    if (*(blob + 0) != GAIA_MARK_START)
+	return NULL;		/* failed to recognize START signature */
+    if (*(blob + (size - 1)) != GAIA_MARK_END)
+	return NULL;		/* failed to recognize END signature */
+    if (*(blob + 38) != GAIA_MARK_MBR)
+	return NULL;		/* failed to recognize MBR signature */
+    if (*(blob + 1) == GAIA_LITTLE_ENDIAN)
+	little_endian = 1;
+    else if (*(blob + 1) == GAIA_BIG_ENDIAN)
+	little_endian = 0;
+    else
+	return NULL;		/* unknown encoding; nor little-endian neither big-endian */
+    type = rl2GeomImport32 (blob + 39, little_endian, endian_arch);
+    geom = rl2CreateGeometry ();
+    offset = 43;
+    switch (type)
+      {
+	  /* parsing elementary geometries */
+      case GAIA_POINT:
+	  rl2ParsePoint (geom, blob, size, little_endian, endian_arch, &offset);
+	  break;
+      case GAIA_POINTZ:
+	  rl2ParsePointZ (geom, blob, size, little_endian, endian_arch,
+			  &offset);
+	  break;
+      case GAIA_POINTM:
+	  rl2ParsePointM (geom, blob, size, little_endian, endian_arch,
+			  &offset);
+	  break;
+      case GAIA_POINTZM:
+	  rl2ParsePointZM (geom, blob, size, little_endian, endian_arch,
+			   &offset);
+	  break;
+      case GAIA_LINESTRING:
+	  rl2ParseLine (geom, blob, size, little_endian, endian_arch, &offset);
+	  break;
+      case GAIA_LINESTRINGZ:
+	  rl2ParseLineZ (geom, blob, size, little_endian, endian_arch, &offset);
+	  break;
+      case GAIA_LINESTRINGM:
+	  rl2ParseLineM (geom, blob, size, little_endian, endian_arch, &offset);
+	  break;
+      case GAIA_LINESTRINGZM:
+	  rl2ParseLineZM (geom, blob, size, little_endian, endian_arch,
+			  &offset);
+	  break;
+      case GAIA_POLYGON:
+	  rl2ParsePolygon (geom, blob, size, little_endian, endian_arch,
+			   &offset);
+	  break;
+      case GAIA_POLYGONZ:
+	  rl2ParsePolygonZ (geom, blob, size, little_endian, endian_arch,
+			    &offset);
+	  break;
+      case GAIA_POLYGONM:
+	  rl2ParsePolygonM (geom, blob, size, little_endian, endian_arch,
+			    &offset);
+	  break;
+      case GAIA_POLYGONZM:
+	  rl2ParsePolygonZM (geom, blob, size, little_endian, endian_arch,
+			     &offset);
+	  break;
+      case GAIA_COMPRESSED_LINESTRING:
+	  rl2ParseCompressedLine (geom, blob, size, little_endian,
+				  endian_arch, &offset);
+	  break;
+      case GAIA_COMPRESSED_LINESTRINGZ:
+	  rl2ParseCompressedLineZ (geom, blob, size, little_endian,
+				   endian_arch, &offset);
+	  break;
+      case GAIA_COMPRESSED_LINESTRINGM:
+	  rl2ParseCompressedLineM (geom, blob, size, little_endian,
+				   endian_arch, &offset);
+	  break;
+      case GAIA_COMPRESSED_LINESTRINGZM:
+	  rl2ParseCompressedLineZM (geom, blob, size, little_endian,
+				    endian_arch, &offset);
+	  break;
+      case GAIA_COMPRESSED_POLYGON:
+	  rl2ParseCompressedPolygon (geom, blob, size, little_endian,
+				     endian_arch, &offset);
+	  break;
+      case GAIA_COMPRESSED_POLYGONZ:
+	  rl2ParseCompressedPolygonZ (geom, blob, size, little_endian,
+				      endian_arch, &offset);
+	  break;
+      case GAIA_COMPRESSED_POLYGONM:
+	  rl2ParseCompressedPolygonM (geom, blob, size, little_endian,
+				      endian_arch, &offset);
+	  break;
+      case GAIA_COMPRESSED_POLYGONZM:
+	  rl2ParseCompressedPolygonZM (geom, blob, size, little_endian,
+				       endian_arch, &offset);
+	  break;
+      case GAIA_MULTIPOINT:
+      case GAIA_MULTIPOINTZ:
+      case GAIA_MULTIPOINTM:
+      case GAIA_MULTIPOINTZM:
+      case GAIA_MULTILINESTRING:
+      case GAIA_MULTILINESTRINGZ:
+      case GAIA_MULTILINESTRINGM:
+      case GAIA_MULTILINESTRINGZM:
+      case GAIA_MULTIPOLYGON:
+      case GAIA_MULTIPOLYGONZ:
+      case GAIA_MULTIPOLYGONM:
+      case GAIA_MULTIPOLYGONZM:
+      case GAIA_GEOMETRYCOLLECTION:
+      case GAIA_GEOMETRYCOLLECTIONZ:
+      case GAIA_GEOMETRYCOLLECTIONM:
+      case GAIA_GEOMETRYCOLLECTIONZM:
+	  rl2ParseGeometry (geom, blob, size, little_endian, endian_arch,
+			    &offset);
+	  break;
+      default:
+	  break;
+      };
+    return geom;
+}
+
+RL2_PRIVATE void
+rl2_destroy_geometry (rl2GeometryPtr geom)
+{
+/* GEOMETRYCOLLECTION object destructor */
+    rl2PointPtr pP;
+    rl2PointPtr pPn;
+    rl2LinestringPtr pL;
+    rl2LinestringPtr pLn;
+    rl2PolygonPtr pA;
+    rl2PolygonPtr pAn;
+    if (geom == NULL)
+	return;
+    pP = geom->first_point;
+    while (pP != NULL)
+      {
+	  pPn = pP->next;
+	  rl2DestroyPoint (pP);
+	  pP = pPn;
+      }
+    pL = geom->first_linestring;
+    while (pL != NULL)
+      {
+	  pLn = pL->next;
+	  rl2DestroyLinestring (pL);
+	  pL = pLn;
+      }
+    pA = geom->first_polygon;
+    while (pA != NULL)
+      {
+	  pAn = pA->next;
+	  rl2DestroyPolygon (pA);
+	  pA = pAn;
+      }
+    free (geom);
+}
+
+RL2_PRIVATE int
+rl2_serialize_linestring (rl2LinestringPtr line, unsigned char **result,
+			  int *size)
+{
+/* serializing a BLOB Geometry - linestring */
+    int iv;
+    unsigned char *ptr;
+    int endian_arch = rl2GeomEndianArch ();
+    double minx = DBL_MAX;
+    double maxx = 0.0 - DBL_MAX;
+    double miny = DBL_MAX;
+    double maxy = 0.0 - DBL_MAX;
+    double x;
+    double y;
+
+    *result = NULL;
+    *size = 0;
+    if (line == NULL)
+	return 0;
+
+/* computing the MBR */
+    for (iv = 0; iv < line->points; iv++)
+      {
+	  rl2GetPoint (line->coords, iv, &x, &y);
+	  if (x < minx)
+	      minx = x;
+	  if (x > maxx)
+	      maxx = x;
+	  if (y < miny)
+	      miny = y;
+	  if (y > maxy)
+	      maxy = y;
+      }
+/* computing the size of BLOB */
+    *size = 44;			/* header size */
+    *size += (4 + ((sizeof (double) * 2) * line->points));	/* # points + [x,y] for each vertex */
+    *result = malloc (*size);
+    ptr = *result;
+/* building the BLOB */
+    *ptr = GAIA_MARK_START;	/* START signature */
+    *(ptr + 1) = GAIA_LITTLE_ENDIAN;	/* byte ordering */
+    rl2GeomExport32 (ptr + 2, 4326, 1, endian_arch);	/* the SRID */
+    rl2GeomExport64 (ptr + 6, minx, 1, endian_arch);	/* MBR - minimum X */
+    rl2GeomExport64 (ptr + 14, miny, 1, endian_arch);	/* MBR - minimum Y */
+    rl2GeomExport64 (ptr + 22, maxx, 1, endian_arch);	/* MBR - maximum X */
+    rl2GeomExport64 (ptr + 30, maxy, 1, endian_arch);	/* MBR - maximum Y */
+    *(ptr + 38) = GAIA_MARK_MBR;	/* MBR signature */
+    rl2GeomExport32 (ptr + 39, GAIA_LINESTRING, 1, endian_arch);	/* class LINESTRING */
+    rl2GeomExport32 (ptr + 43, line->points, 1, endian_arch);	/* # points */
+    ptr += 47;
+    for (iv = 0; iv < line->points; iv++)
+      {
+	  rl2GetPoint (line->coords, iv, &x, &y);
+	  rl2GeomExport64 (ptr, x, 1, endian_arch);
+	  rl2GeomExport64 (ptr + 8, y, 1, endian_arch);
+	  ptr += 16;
+      }
+    *ptr = GAIA_MARK_END;	/* END signature */
+    return 1;
+}
+
+RL2_PRIVATE int
+rl2_serialize_ring (rl2RingPtr ring, unsigned char **result, int *size)
+{
+/* serializing a BLOB Geometry - polygon ring */
+    int iv;
+    unsigned char *ptr;
+    int endian_arch = rl2GeomEndianArch ();
+    double minx = DBL_MAX;
+    double maxx = 0.0 - DBL_MAX;
+    double miny = DBL_MAX;
+    double maxy = 0.0 - DBL_MAX;
+    double x;
+    double y;
+
+    *result = NULL;
+    *size = 0;
+    if (ring == NULL)
+	return 0;
+
+/* computing the MBR */
+    for (iv = 0; iv < ring->points; iv++)
+      {
+	  rl2GetPoint (ring->coords, iv, &x, &y);
+	  if (x < minx)
+	      minx = x;
+	  if (x > maxx)
+	      maxx = x;
+	  if (y < miny)
+	      miny = y;
+	  if (y > maxy)
+	      maxy = y;
+      }
+/* computing the size of BLOB */
+    *size = 44;			/* header size */
+    *size += (8 + ((sizeof (double) * 2) * ring->points));	/* # rings + # points + [x.y] array - exterior ring */
+    *result = malloc (*size);
+    ptr = *result;
+/* building the BLOB */
+    *ptr = GAIA_MARK_START;	/* START signature */
+    *(ptr + 1) = GAIA_LITTLE_ENDIAN;	/* byte ordering */
+    rl2GeomExport32 (ptr + 2, -1, 1, endian_arch);	/* the SRID */
+    rl2GeomExport64 (ptr + 6, minx, 1, endian_arch);	/* MBR - minimum X */
+    rl2GeomExport64 (ptr + 14, miny, 1, endian_arch);	/* MBR - minimum Y */
+    rl2GeomExport64 (ptr + 22, maxx, 1, endian_arch);	/* MBR - maximum X */
+    rl2GeomExport64 (ptr + 30, maxy, 1, endian_arch);	/* MBR - maximum Y */
+    *(ptr + 38) = GAIA_MARK_MBR;	/* MBR signature */
+    rl2GeomExport32 (ptr + 39, GAIA_POLYGON, 1, endian_arch);	/* class POLYGON */
+    rl2GeomExport32 (ptr + 43, 1, 1, endian_arch);	/* # rings */
+    rl2GeomExport32 (ptr + 47, ring->points, 1, endian_arch);	/* # points - exterior ring */
+    ptr += 51;
+    for (iv = 0; iv < ring->points; iv++)
+      {
+	  rl2GetPoint (ring->coords, iv, &x, &y);
+	  rl2GeomExport64 (ptr, x, 1, endian_arch);	/* X - exterior ring */
+	  rl2GeomExport64 (ptr + 8, y, 1, endian_arch);	/* Y - exterior ring */
+	  ptr += 16;
+      }
+    *ptr = GAIA_MARK_END;	/* END signature */
+    return 1;
+}
+
+RL2_PRIVATE int
+rl2_serialize_ring_as_linestring (rl2RingPtr ring, unsigned char **result,
+				  int *size)
+{
+/* serializing a BLOB Geometry - polygon ring as linestring */
+    int iv;
+    unsigned char *ptr;
+    int endian_arch = rl2GeomEndianArch ();
+    double minx = DBL_MAX;
+    double maxx = 0.0 - DBL_MAX;
+    double miny = DBL_MAX;
+    double maxy = 0.0 - DBL_MAX;
+    double x;
+    double y;
+
+    *result = NULL;
+    *size = 0;
+    if (ring == NULL)
+	return 0;
+
+/* computing the MBR */
+    for (iv = 0; iv < ring->points; iv++)
+      {
+	  rl2GetPoint (ring->coords, iv, &x, &y);
+	  if (x < minx)
+	      minx = x;
+	  if (x > maxx)
+	      maxx = x;
+	  if (y < miny)
+	      miny = y;
+	  if (y > maxy)
+	      maxy = y;
+      }
+/* computing the size of BLOB */
+    *size = 44;			/* header size */
+    *size += (4 + ((sizeof (double) * 2) * ring->points));	/* # points + [x,y] for each vertex */
+    *result = malloc (*size);
+    ptr = *result;
+/* building the BLOB */
+    *ptr = GAIA_MARK_START;	/* START signature */
+    *(ptr + 1) = GAIA_LITTLE_ENDIAN;	/* byte ordering */
+    rl2GeomExport32 (ptr + 2, 4326, 1, endian_arch);	/* the SRID */
+    rl2GeomExport64 (ptr + 6, minx, 1, endian_arch);	/* MBR - minimum X */
+    rl2GeomExport64 (ptr + 14, miny, 1, endian_arch);	/* MBR - minimum Y */
+    rl2GeomExport64 (ptr + 22, maxx, 1, endian_arch);	/* MBR - maximum X */
+    rl2GeomExport64 (ptr + 30, maxy, 1, endian_arch);	/* MBR - maximum Y */
+    *(ptr + 38) = GAIA_MARK_MBR;	/* MBR signature */
+    rl2GeomExport32 (ptr + 39, GAIA_LINESTRING, 1, endian_arch);	/* class LINESTRING */
+    rl2GeomExport32 (ptr + 43, ring->points, 1, endian_arch);	/* # points */
+    ptr += 47;
+    for (iv = 0; iv < ring->points; iv++)
+      {
+	  rl2GetPoint (ring->coords, iv, &x, &y);
+	  rl2GeomExport64 (ptr, x, 1, endian_arch);
+	  rl2GeomExport64 (ptr + 8, y, 1, endian_arch);
+	  ptr += 16;
+      }
+    *ptr = GAIA_MARK_END;	/* END signature */
+    return 1;
+}
+
+RL2_PRIVATE rl2GeometryPtr
+rl2_curve_from_XY (int points, double *x, double *y)
+{
+/* creating a Linestring Geometry from X,Y coordinate arrays */
+    rl2GeometryPtr geom = NULL;
+    rl2LinestringPtr ln;
+    int iv;
+
+    if (points <= 0 || x == NULL || y == NULL)
+	return 0;
+    geom = rl2CreateGeometry ();
+    ln = rl2AddLinestringToGeometry (geom, points);
+    for (iv = 0; iv < points; iv++)
+	rl2SetPoint (ln->coords, iv, *(x + iv), *(y + iv));
+    if (*(x + iv) < ln->minx)
+	ln->minx = *(x + iv);
+    if (*(x + iv) > ln->maxx)
+	ln->maxx = *(x + iv);
+    if (*(y + iv) < ln->miny)
+	ln->miny = *(y + iv);
+    if (*(y + iv) > ln->maxy)
+	ln->maxy = *(y + iv);
+    return geom;
+}
+
+RL2_PRIVATE double
+rl2_compute_curve_length (rl2GeometryPtr geom)
+{
+/* computing the total length of some curve (single linestring expected) */
+    rl2LinestringPtr ln;
+    double length = 0.0;
+    double x0;
+    double y0;
+    double x1;
+    double y1;
+    int iv;
+
+    if (geom == NULL)
+	return 0.0;
+    if (geom->first_point != NULL || geom->first_polygon != NULL)
+	return 0.0;
+    if (geom->first_linestring != geom->last_linestring)
+	return 0.0;
+    ln = geom->first_linestring;
+    if (ln == NULL)
+	return 0.0;
+
+    for (iv = 0; iv < ln->points; iv++)
+      {
+	  rl2GetPoint (ln->coords, iv, &x1, &y1);
+	  if (iv > 0)
+	      length += sqrt ((x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1));
+	  x0 = x1;
+	  y0 = y1;
+      }
+    return length;
+}
+
+RL2_PRIVATE rl2GeometryPtr
+rl2_curve_substring (sqlite3 * handle, rl2GeometryPtr geom, double from,
+		     double to)
+{
+/* extracting a sub-path from some Curve */
+    rl2LinestringPtr ln;
+    rl2GeometryPtr result = NULL;
+    unsigned char *blob;
+    int blob_sz;
+    const char *sql;
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+
+    if (handle == NULL)
+	return NULL;
+    if (geom == NULL)
+	return NULL;
+    if (geom->first_point != NULL || geom->first_polygon != NULL)
+	return NULL;
+    if (geom->first_linestring != geom->last_linestring)
+	return NULL;
+    ln = geom->first_linestring;
+    if (ln == NULL)
+	return NULL;
+
+    if (!rl2_serialize_linestring (ln, &blob, &blob_sz))
+	return NULL;
+
+    sql = "SELECT ST_Line_Substring(?, ?, ?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	goto error;
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_blob (stmt, 1, blob, blob_sz, free);
+    sqlite3_bind_double (stmt, 2, from);
+    sqlite3_bind_double (stmt, 3, to);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	    {
+		if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
+		  {
+		      blob = (unsigned char *) sqlite3_column_blob (stmt, 0);
+		      blob_sz = sqlite3_column_bytes (stmt, 0);
+		      result = rl2_geometry_from_blob (blob, blob_sz);
+		  }
+	    }
+	  else
+	      goto error;
+      }
+    sqlite3_finalize (stmt);
+    return result;
+
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    return NULL;
+}
+
+RL2_PRIVATE rl2GeometryPtr
+rl2_clone_curve (rl2GeometryPtr in)
+{
+/* cloning a Curve geometry */
+    rl2GeometryPtr out;
+    rl2LinestringPtr ln_in = in->first_linestring;
+    rl2LinestringPtr ln_out;
+    int iv;
+
+    out = rl2CreateGeometry ();
+    ln_out = rl2AddLinestringToGeometry (out, ln_in->points);
+    for (iv = 0; iv < ln_in->points; iv++)
+      {
+	  double x;
+	  double y;
+	  rl2GetPoint (ln_in->coords, iv, &x, &y);
+	  rl2SetPoint (ln_out->coords, iv, x, y);
+	  if (x < ln_out->minx)
+	      ln_out->minx = x;
+	  if (x > ln_out->maxx)
+	      ln_out->maxx = x;
+	  if (y < ln_out->miny)
+	      ln_out->miny = y;
+	  if (y > ln_out->maxy)
+	      ln_out->maxy = y;
+      }
+    return out;
+}
+
+RL2_PRIVATE rl2GeometryPtr
+rl2_clone_linestring (rl2LinestringPtr in)
+{
+/* cloning a Curve geometry */
+    rl2GeometryPtr out;
+    rl2LinestringPtr ln_out;
+    int iv;
+
+    out = rl2CreateGeometry ();
+    ln_out = rl2AddLinestringToGeometry (out, in->points);
+    for (iv = 0; iv < in->points; iv++)
+      {
+	  double x;
+	  double y;
+	  rl2GetPoint (in->coords, iv, &x, &y);
+	  rl2SetPoint (ln_out->coords, iv, x, y);
+	  if (x < ln_out->minx)
+	      ln_out->minx = x;
+	  if (x > ln_out->maxx)
+	      ln_out->maxx = x;
+	  if (y < ln_out->miny)
+	      ln_out->miny = y;
+	  if (y > ln_out->maxy)
+	      ln_out->maxy = y;
+      }
+    return out;
+}
+
+RL2_PRIVATE rl2GeometryPtr
+rl2_build_circle (double cx, double cy, double radius)
+{
+/* creating a circle */
+    int iv = 0;
+    double pi = 3.14159265359;
+    double rads;
+    double x;
+    double y;
+    rl2LinestringPtr ln;
+    rl2GeometryPtr out = rl2CreateGeometry ();
+    ln = rl2AddLinestringToGeometry (out, 129);
+    for (rads = 0.0; rads <= (pi * 2.0); rads += pi / 64.0)
+      {
+	  x = cx + (radius * cos (rads));
+	  y = cy + (radius * sin (rads));
+	  rl2SetPoint (ln->coords, iv, x, y);
+	  if (x < ln->minx)
+	      ln->minx = x;
+	  if (x > ln->maxx)
+	      ln->maxx = x;
+	  if (y < ln->miny)
+	      ln->miny = y;
+	  if (y > ln->maxy)
+	      ln->maxy = y;
+	  iv++;
+      }
+    /* closure */
+    rl2GetPoint (ln->coords, 0, &x, &y);
+    rl2SetPoint (ln->coords, 128, x, y);
+    return out;
+}
diff --git a/src/rl2auxrender.c b/src/rl2auxrender.c
index 27ac522..0ecf52c 100644
--- a/src/rl2auxrender.c
+++ b/src/rl2auxrender.c
@@ -20,7 +20,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -65,6 +65,200 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include "rasterlite2/rl2graphics.h"
 #include "rasterlite2_private.h"
 
+typedef struct rl2_multi_stroke_item
+{
+    rl2GraphicsPatternPtr pattern;
+    unsigned char red;
+    unsigned char green;
+    unsigned char blue;
+    double opacity;
+    double width;
+    int dash_count;
+    double *dash_list;
+    double dash_offset;
+    int pen_cap;
+    int pen_join;
+    struct rl2_multi_stroke_item *next;
+} rl2PrivMultiStrokeItem;
+typedef rl2PrivMultiStrokeItem *rl2PrivMultiStrokeItemPtr;
+
+typedef struct rl2_multi_stroke
+{
+    rl2PrivMultiStrokeItemPtr first;
+    rl2PrivMultiStrokeItemPtr last;
+} rl2PrivMultiStroke;
+typedef rl2PrivMultiStroke *rl2PrivMultiStrokePtr;
+
+static void
+rl2_destroy_multi_stroke_item (rl2PrivMultiStrokeItemPtr item)
+{
+/* destroying a MultiStroke Item */
+    if (item == NULL)
+	return;
+    if (item->pattern != NULL)
+	rl2_graph_destroy_pattern (item->pattern);
+    if (item->dash_list != NULL)
+	free (item->dash_list);
+    free (item);
+}
+
+static rl2PrivMultiStrokePtr
+rl2_create_multi_stroke ()
+{
+/* creating an empty MultiStroke container */
+    rl2PrivMultiStrokePtr multi = malloc (sizeof (rl2PrivMultiStroke));
+    if (multi == NULL)
+	return NULL;
+    multi->first = NULL;
+    multi->last = NULL;
+    return multi;
+}
+
+static void
+rl2_destroy_multi_stroke (rl2PrivMultiStrokePtr multi)
+{
+/* destroying a MultiStroke container */
+    rl2PrivMultiStrokeItemPtr item;
+    rl2PrivMultiStrokeItemPtr item_n;
+    if (multi == NULL)
+	return;
+    item = multi->first;
+    while (item != NULL)
+      {
+	  item_n = item->next;
+	  rl2_destroy_multi_stroke_item (item);
+	  item = item_n;
+      }
+    free (multi);
+}
+
+static void
+rl2_add_pattern_to_multi_stroke (rl2PrivMultiStrokePtr multi,
+				 rl2GraphicsPatternPtr pattern, double width,
+				 int pen_cap, int pen_join)
+{
+/* adding a pattern-based stroke to the MultiStroke container */
+    rl2PrivMultiStrokeItemPtr item;
+    if (multi == NULL || pattern == NULL)
+      {
+	  rl2_graph_destroy_pattern (pattern);
+	  return;
+      }
+
+    item = malloc (sizeof (rl2PrivMultiStrokeItem));
+    item->pattern = pattern;
+    item->width = width;
+    item->pen_cap = pen_cap;
+    item->pen_join = pen_join;
+    item->dash_count = 0;
+    item->dash_list = NULL;
+    item->next = NULL;
+    if (multi->first == NULL)
+	multi->first = item;
+    if (multi->last != NULL)
+	multi->last->next = item;
+    multi->last = item;
+}
+
+static void
+rl2_add_pattern_to_multi_stroke_dash (rl2PrivMultiStrokePtr multi,
+				      rl2GraphicsPatternPtr pattern,
+				      double width, int pen_cap, int pen_join,
+				      int dash_count, double *dash_list,
+				      double dash_offset)
+{
+/* adding a pattern-based stroke (dash) to the MultiStroke container */
+    int d;
+    rl2PrivMultiStrokeItemPtr item;
+    if (multi == NULL || pattern == NULL)
+      {
+	  rl2_graph_destroy_pattern (pattern);
+	  return;
+      }
+
+    item = malloc (sizeof (rl2PrivMultiStrokeItem));
+    item->pattern = pattern;
+    item->width = width;
+    item->pen_cap = pen_cap;
+    item->pen_join = pen_join;
+    item->dash_count = dash_count;
+    item->dash_list = malloc (sizeof (double) * dash_count);
+    for (d = 0; d < dash_count; d++)
+	*(item->dash_list + d) = *(dash_list + d);
+    item->dash_offset = dash_offset;
+    item->next = NULL;
+    if (multi->first == NULL)
+	multi->first = item;
+    if (multi->last != NULL)
+	multi->last->next = item;
+    multi->last = item;
+}
+
+static void
+rl2_add_to_multi_stroke (rl2PrivMultiStrokePtr multi, unsigned char red,
+			 unsigned char green, unsigned char blue,
+			 double opacity, double width, int pen_cap,
+			 int pen_join)
+{
+/* adding an RGB stroke to the MultiStroke container */
+    rl2PrivMultiStrokeItemPtr item;
+    if (multi == NULL)
+	return;
+
+    item = malloc (sizeof (rl2PrivMultiStrokeItem));
+    item->pattern = NULL;
+    item->red = red;
+    item->green = green;
+    item->blue = blue;
+    item->opacity = opacity;
+    item->width = width;
+    item->pen_cap = pen_cap;
+    item->pen_join = pen_join;
+    item->dash_count = 0;
+    item->dash_list = NULL;
+    item->next = NULL;
+    if (multi->first == NULL)
+	multi->first = item;
+    if (multi->last != NULL)
+	multi->last->next = item;
+    multi->last = item;
+}
+
+static void
+rl2_add_to_multi_stroke_dash (rl2PrivMultiStrokePtr multi, unsigned char red,
+			      unsigned char green, unsigned char blue,
+			      double opacity, double width, int pen_cap,
+			      int pen_join, int dash_count, double *dash_list,
+			      double dash_offset)
+{
+/* adding an RGB stroke (dash) to the MultiStroke container */
+    int d;
+    rl2PrivMultiStrokeItemPtr item;
+    if (multi == NULL)
+	return;
+
+    item = malloc (sizeof (rl2PrivMultiStrokeItem));
+    item->pattern = NULL;
+    item->red = red;
+    item->green = green;
+    item->blue = blue;
+    item->opacity = opacity;
+    item->width = width;
+    item->pen_cap = pen_cap;
+    item->pen_join = pen_join;
+    item->dash_count = dash_count;
+    item->dash_list = malloc (sizeof (double) * dash_count);
+    for (d = 0; d < dash_count; d++)
+	*(item->dash_list + d) = *(dash_list + d);
+    item->dash_offset = dash_offset;
+    item->next = NULL;
+    if (multi->first == NULL)
+	multi->first = item;
+    if (multi->last != NULL)
+	multi->last->next = item;
+    multi->last = item;
+}
+
 static void
 copy_monochrome (unsigned char *rgba, unsigned int width, unsigned int height,
 		 unsigned char *inbuf)
@@ -98,8 +292,9 @@ copy_monochrome (unsigned char *rgba, unsigned int width, unsigned int height,
 
 static void
 copy_palette (unsigned char *rgba, unsigned int width, unsigned int height,
-	      unsigned char *inbuf, rl2PalettePtr palette, unsigned char bg_red,
-	      unsigned char bg_green, unsigned char bg_blue)
+	      unsigned char *inbuf, rl2PalettePtr palette,
+	      unsigned char bg_red, unsigned char bg_green,
+	      unsigned char bg_blue)
 {
 /* copying from Palette to RGBA */
     unsigned int x;
@@ -246,6 +441,7 @@ aux_render_composed_image (struct aux_renderer *aux, unsigned char *aggreg_rgba)
     unsigned char *rgba = NULL;
     unsigned char *rgb = NULL;
     unsigned char *alpha = NULL;
+    int half_transparent;
     rl2GraphicsBitmapPtr base_img = NULL;
     rl2GraphicsContextPtr ctx = NULL;
     double rescale_x = (double) aux->width / (double) aux->base_width;
@@ -259,8 +455,8 @@ aux_render_composed_image (struct aux_renderer *aux, unsigned char *aggreg_rgba)
 	  if (aux->out_pixel == RL2_PIXEL_MONOCHROME)
 	    {
 		/* Monochrome */
-		copy_monochrome (aggreg_rgba, aux->base_width, aux->base_height,
-				 aux->outbuf);
+		copy_monochrome (aggreg_rgba, aux->base_width,
+				 aux->base_height, aux->outbuf);
 		aux->outbuf = NULL;
 	    }
 	  else if (aux->out_pixel == RL2_PIXEL_PALETTE)
@@ -274,8 +470,8 @@ aux_render_composed_image (struct aux_renderer *aux, unsigned char *aggreg_rgba)
 	  else if (aux->out_pixel == RL2_PIXEL_GRAYSCALE)
 	    {
 		/* Grayscale */
-		copy_grayscale (aggreg_rgba, aux->base_width, aux->base_height,
-				aux->outbuf, aux->bg_red);
+		copy_grayscale (aggreg_rgba, aux->base_width,
+				aux->base_height, aux->outbuf, aux->bg_red);
 		aux->outbuf = NULL;
 	    }
 	  else
@@ -351,7 +547,7 @@ aux_render_composed_image (struct aux_renderer *aux, unsigned char *aggreg_rgba)
 					  0, 0);
 	  rl2_graph_destroy_bitmap (base_img);
 	  rgb = rl2_graph_get_context_rgb_array (ctx);
-	  alpha = rl2_graph_get_context_alpha_array (ctx);
+	  alpha = rl2_graph_get_context_alpha_array (ctx, &half_transparent);
 	  rl2_graph_destroy_context (ctx);
 	  if (rgb == NULL || alpha == NULL)
 	      goto error;
@@ -386,6 +582,7 @@ rl2_aux_render_image (struct aux_renderer *aux, unsigned char **ximage,
     unsigned char *alpha = NULL;
     unsigned char *rgba = NULL;
     unsigned char *gray = NULL;
+    int half_transparent;
     rl2GraphicsBitmapPtr base_img = NULL;
     rl2GraphicsContextPtr ctx = NULL;
     double rescale_x = (double) aux->width / (double) aux->base_width;
@@ -415,8 +612,8 @@ rl2_aux_render_image (struct aux_renderer *aux, unsigned char **ximage,
 		      if (!get_payload_from_monochrome_opaque
 			  (aux->base_width, aux->base_height, aux->sqlite,
 			   aux->minx, aux->miny, aux->maxx, aux->maxy,
-			   aux->srid, aux->outbuf, aux->format_id, aux->quality,
-			   &image, &image_size))
+			   aux->srid, aux->outbuf, aux->format_id,
+			   aux->quality, &image, &image_size))
 			{
 			    aux->outbuf = NULL;
 			    goto error;
@@ -444,8 +641,8 @@ rl2_aux_render_image (struct aux_renderer *aux, unsigned char **ximage,
 		      if (!get_payload_from_palette_opaque
 			  (aux->base_width, aux->base_height, aux->sqlite,
 			   aux->minx, aux->miny, aux->maxx, aux->maxy,
-			   aux->srid, aux->outbuf, aux->palette, aux->format_id,
-			   aux->quality, &image, &image_size))
+			   aux->srid, aux->outbuf, aux->palette,
+			   aux->format_id, aux->quality, &image, &image_size))
 			{
 			    aux->outbuf = NULL;
 			    goto error;
@@ -472,8 +669,8 @@ rl2_aux_render_image (struct aux_renderer *aux, unsigned char **ximage,
 		      if (!get_payload_from_grayscale_opaque
 			  (aux->base_width, aux->base_height, aux->sqlite,
 			   aux->minx, aux->miny, aux->maxx, aux->maxy,
-			   aux->srid, aux->outbuf, aux->format_id, aux->quality,
-			   &image, &image_size))
+			   aux->srid, aux->outbuf, aux->format_id,
+			   aux->quality, &image, &image_size))
 			{
 			    aux->outbuf = NULL;
 			    goto error;
@@ -501,8 +698,8 @@ rl2_aux_render_image (struct aux_renderer *aux, unsigned char **ximage,
 		      if (!get_payload_from_rgb_opaque
 			  (aux->base_width, aux->base_height, aux->sqlite,
 			   aux->minx, aux->miny, aux->maxx, aux->maxy,
-			   aux->srid, aux->outbuf, aux->format_id, aux->quality,
-			   &image, &image_size))
+			   aux->srid, aux->outbuf, aux->format_id,
+			   aux->quality, &image, &image_size))
 			{
 			    aux->outbuf = NULL;
 			    goto error;
@@ -577,8 +774,8 @@ rl2_aux_render_image (struct aux_renderer *aux, unsigned char **ximage,
 		if (aux->transparent && aux->format_id == RL2_OUTPUT_FORMAT_PNG)
 		  {
 		      if (!get_rgba_from_grayscale_transparent
-			  (aux->base_width, aux->base_height, aux->outbuf, rgba,
-			   aux->bg_red))
+			  (aux->base_width, aux->base_height, aux->outbuf,
+			   rgba, aux->bg_red))
 			{
 			    aux->outbuf = NULL;
 			    goto error;
@@ -602,8 +799,8 @@ rl2_aux_render_image (struct aux_renderer *aux, unsigned char **ximage,
 		if (aux->transparent && aux->format_id == RL2_OUTPUT_FORMAT_PNG)
 		  {
 		      if (!get_rgba_from_rgb_transparent
-			  (aux->base_width, aux->base_height, aux->outbuf, rgba,
-			   aux->bg_red, aux->bg_green, aux->bg_blue))
+			  (aux->base_width, aux->base_height, aux->outbuf,
+			   rgba, aux->bg_red, aux->bg_green, aux->bg_blue))
 			{
 			    aux->outbuf = NULL;
 			    goto error;
@@ -632,7 +829,8 @@ rl2_aux_render_image (struct aux_renderer *aux, unsigned char **ximage,
 	  rgb = rl2_graph_get_context_rgb_array (ctx);
 	  alpha = NULL;
 	  if (aux->transparent)
-	      alpha = rl2_graph_get_context_alpha_array (ctx);
+	      alpha =
+		  rl2_graph_get_context_alpha_array (ctx, &half_transparent);
 	  rl2_graph_destroy_context (ctx);
 	  if (rgb == NULL)
 	      goto error;
@@ -645,15 +843,10 @@ rl2_aux_render_image (struct aux_renderer *aux, unsigned char **ximage,
 		      if (alpha == NULL)
 			  goto error;
 		      if (!get_payload_from_gray_rgba_transparent
-			  (aux->width, aux->height, rgb, alpha, aux->format_id,
-			   aux->quality, &image, &image_size, aux->opacity))
-			{
-			    rgb = NULL;
-			    alpha = NULL;
-			    goto error;
-			}
-		      rgb = NULL;
-		      alpha = NULL;
+			  (aux->width, aux->height, rgb, alpha,
+			   aux->format_id, aux->quality, &image, &image_size,
+			   aux->opacity))
+			  goto error;
 		  }
 		else
 		  {
@@ -664,11 +857,7 @@ rl2_aux_render_image (struct aux_renderer *aux, unsigned char **ximage,
 			  (aux->width, aux->height, aux->sqlite, aux->minx,
 			   aux->miny, aux->maxx, aux->maxy, aux->srid, rgb,
 			   aux->format_id, aux->quality, &image, &image_size))
-			{
-			    rgb = NULL;
-			    goto error;
-			}
-		      rgb = NULL;
+			  goto error;
 		  }
 	    }
 	  else
@@ -679,15 +868,10 @@ rl2_aux_render_image (struct aux_renderer *aux, unsigned char **ximage,
 		      if (alpha == NULL)
 			  goto error;
 		      if (!get_payload_from_rgb_rgba_transparent
-			  (aux->width, aux->height, rgb, alpha, aux->format_id,
-			   aux->quality, &image, &image_size, aux->opacity))
-			{
-			    rgb = NULL;
-			    alpha = NULL;
-			    goto error;
-			}
-		      rgb = NULL;
-		      alpha = NULL;
+			  (aux->width, aux->height, rgb, alpha,
+			   aux->format_id, aux->quality, &image, &image_size,
+			   aux->opacity, 0))
+			  goto error;
 		  }
 		else
 		  {
@@ -698,16 +882,16 @@ rl2_aux_render_image (struct aux_renderer *aux, unsigned char **ximage,
 			  (aux->width, aux->height, aux->sqlite, aux->minx,
 			   aux->miny, aux->maxx, aux->maxy, aux->srid, rgb,
 			   aux->format_id, aux->quality, &image, &image_size))
-			{
-			    rgb = NULL;
-			    goto error;
-			}
-		      rgb = NULL;
+			  goto error;
 		  }
 	    }
 	  *ximage = image;
 	  *ximage_size = image_size;
       }
+    if (rgb != NULL)
+	free (rgb);
+    if (alpha != NULL)
+	free (alpha);
     return 1;
 
   error:
@@ -737,7 +921,7 @@ aux_render_final_image (struct aux_group_renderer *aux, sqlite3 * sqlite,
       {
 	  if (!get_payload_from_rgb_rgba_transparent
 	      (aux->width, aux->height, rgb, alpha, aux->format_id,
-	       aux->quality, &image, &image_size, 1.0))
+	       aux->quality, &image, &image_size, 1.0, 0))
 	    {
 		rgb = NULL;
 		alpha = NULL;
@@ -800,9 +984,10 @@ aux_shaded_relief_mask (struct aux_renderer *aux, double relief_factor,
     scale_factor = rl2_get_shaded_relief_scale_factor (aux->sqlite, coverage);
 
     if (rl2_build_shaded_relief_mask
-	(aux->sqlite, aux->coverage, relief_factor, scale_factor,
-	 aux->base_width, aux->base_height, aux->minx, aux->miny, aux->maxx,
-	 aux->maxy, aux->xx_res, aux->yy_res, &shr_mask, &shr_size) != RL2_OK)
+	(aux->sqlite, aux->max_threads, aux->coverage, relief_factor,
+	 scale_factor, aux->base_width, aux->base_height, aux->minx,
+	 aux->miny, aux->maxx, aux->maxy, aux->xx_res, aux->yy_res, &shr_mask,
+	 &shr_size) != RL2_OK)
 	return 0;
 
 /* allocating the RGBA buffer */
@@ -903,8 +1088,20 @@ rl2_aux_group_renderer (struct aux_group_renderer *auxgrp)
     rl2PrivGroupRendererPtr grp;
     struct aux_renderer aux;
     rl2PalettePtr palette = NULL;
-    rl2PrivRasterStylePtr symbolizer = NULL;
+    rl2PrivRasterSymbolizerPtr symbolizer = NULL;
+    int by_section = 0;
     sqlite3 *sqlite = sqlite3_context_db_handle (auxgrp->context);
+    int max_threads = 1;
+    const void *data = sqlite3_user_data (auxgrp->context);
+    if (data != NULL)
+      {
+	  struct rl2_private_data *priv_data = (struct rl2_private_data *) data;
+	  max_threads = priv_data->max_threads;
+	  if (max_threads < 1)
+	      max_threads = 1;
+	  if (max_threads > 64)
+	      max_threads = 64;
+      }
 
     ext_x = auxgrp->maxx - auxgrp->minx;
     ext_y = auxgrp->maxy - auxgrp->miny;
@@ -965,12 +1162,14 @@ rl2_aux_group_renderer (struct aux_group_renderer *auxgrp)
 	    {
 		/* applying a RasterSymbolizer */
 		int yes_no;
+		int categorize;
+		int interpolate;
 		if (lyr->raster_symbolizer->shadedRelief)
 		    is_shaded_relief = 1;
 		if (!is_shaded_relief)
 		  {
-		      if (rl2_is_raster_style_triple_band_selected
-			  ((rl2RasterStylePtr) (lyr->raster_symbolizer),
+		      if (rl2_is_raster_symbolizer_triple_band_selected
+			  ((rl2RasterSymbolizerPtr) (lyr->raster_symbolizer),
 			   &yes_no) == RL2_OK)
 			{
 			    if ((cvg->sampleType == RL2_SAMPLE_UINT8
@@ -980,9 +1179,9 @@ rl2_aux_group_renderer (struct aux_group_renderer *auxgrp)
 				&& yes_no)
 				out_pixel = RL2_PIXEL_RGB;
 			}
-		      if (rl2_is_raster_style_mono_band_selected
-			  ((rl2RasterStylePtr) (lyr->raster_symbolizer),
-			   &yes_no) == RL2_OK)
+		      if (rl2_is_raster_symbolizer_mono_band_selected
+			  ((rl2RasterSymbolizerPtr) (lyr->raster_symbolizer),
+			   &yes_no, &categorize, &interpolate) == RL2_OK)
 			{
 			    if ((cvg->sampleType == RL2_SAMPLE_UINT8
 				 || cvg->sampleType == RL2_SAMPLE_UINT16)
@@ -991,6 +1190,11 @@ rl2_aux_group_renderer (struct aux_group_renderer *auxgrp)
 				    || cvg->pixelType == RL2_PIXEL_GRAYSCALE)
 				&& yes_no)
 				out_pixel = RL2_PIXEL_GRAYSCALE;
+			    if ((cvg->sampleType == RL2_SAMPLE_UINT8
+				 || cvg->sampleType == RL2_SAMPLE_UINT16)
+				&& cvg->pixelType == RL2_PIXEL_MULTIBAND
+				&& yes_no && (categorize || interpolate))
+				out_pixel = RL2_PIXEL_RGB;
 			    if ((cvg->sampleType == RL2_SAMPLE_INT8
 				 || cvg->sampleType == RL2_SAMPLE_UINT8
 				 || cvg->sampleType == RL2_SAMPLE_INT16
@@ -1003,8 +1207,8 @@ rl2_aux_group_renderer (struct aux_group_renderer *auxgrp)
 				&& yes_no)
 				out_pixel = RL2_PIXEL_GRAYSCALE;
 			}
-		      if (rl2_get_raster_style_opacity
-			  ((rl2RasterStylePtr) (lyr->raster_symbolizer),
+		      if (rl2_get_raster_symbolizer_opacity
+			  ((rl2RasterSymbolizerPtr) (lyr->raster_symbolizer),
 			   &opacity) != RL2_OK)
 			  opacity = 1.0;
 		      if (opacity > 1.0)
@@ -1021,11 +1225,23 @@ rl2_aux_group_renderer (struct aux_group_renderer *auxgrp)
 		  }
 	    }
 
-	  /* retrieving the optimal resolution level */
-	  if (!find_best_resolution_level
-	      (sqlite, cvg->coverageName, x_res, y_res, &level_id, &scale,
-	       &xscale, &xx_res, &yy_res))
-	      goto error;
+	  if (rl2_is_mixed_resolutions_coverage (sqlite, cvg->coverageName) > 0)
+	    {
+		/* Mixed Resolutions Coverage */
+		by_section = 1;
+		xx_res = x_res;
+		yy_res = y_res;
+	    }
+	  else
+	    {
+		/* ordinary Coverage */
+		by_section = 0;
+		/* retrieving the optimal resolution level */
+		if (!rl2_find_best_resolution_level
+		    (sqlite, cvg->coverageName, 0, 0, x_res, y_res, &level_id,
+		     &scale, &xscale, &xx_res, &yy_res))
+		    goto error;
+	    }
 	  base_width = (int) (ext_x / xx_res);
 	  base_height = (int) (ext_y / yy_res);
 	  if ((base_width <= 0 && base_width >= USHRT_MAX)
@@ -1060,11 +1276,11 @@ rl2_aux_group_renderer (struct aux_group_renderer *auxgrp)
 		if (rl2_get_coverage_srid (lyr->coverage, &srid) != RL2_OK)
 		    srid = -1;
 		if (rl2_get_raw_raster_data_bgcolor
-		    (sqlite, lyr->coverage, base_width, base_height,
-		     auxgrp->minx, auxgrp->miny, auxgrp->maxx, auxgrp->maxy,
-		     xx_res, yy_res, &outbuf, &outbuf_size, &palette,
-		     &out_pixel, auxgrp->bg_red, auxgrp->bg_green,
-		     auxgrp->bg_blue, (rl2RasterStylePtr) symbolizer,
+		    (sqlite, max_threads, lyr->coverage, base_width,
+		     base_height, auxgrp->minx, auxgrp->miny, auxgrp->maxx,
+		     auxgrp->maxy, xx_res, yy_res, &outbuf, &outbuf_size,
+		     &palette, &out_pixel, auxgrp->bg_red, auxgrp->bg_green,
+		     auxgrp->bg_blue, (rl2RasterSymbolizerPtr) symbolizer,
 		     (rl2RasterStatisticsPtr) (lyr->raster_stats)) != RL2_OK)
 		    goto error;
 		if (out_pixel == RL2_PIXEL_PALETTE && palette == NULL)
@@ -1075,6 +1291,7 @@ rl2_aux_group_renderer (struct aux_group_renderer *auxgrp)
 
 /* preparing the aux struct for passing rendering arguments */
 	  aux.sqlite = sqlite;
+	  aux.max_threads = max_threads;
 	  aux.width = auxgrp->width;
 	  aux.height = auxgrp->height;
 	  aux.base_width = base_width;
@@ -1084,8 +1301,18 @@ rl2_aux_group_renderer (struct aux_group_renderer *auxgrp)
 	  aux.maxx = auxgrp->maxx;
 	  aux.maxy = auxgrp->maxy;
 	  aux.srid = srid;
-	  aux.xx_res = xx_res;
-	  aux.yy_res = yy_res;
+	  if (by_section)
+	    {
+		aux.by_section = 1;
+		aux.x_res = x_res;
+		aux.y_res = y_res;
+	    }
+	  else
+	    {
+		aux.by_section = 0;
+		aux.xx_res = xx_res;
+		aux.yy_res = yy_res;
+	    }
 	  aux.transparent = auxgrp->transparent;
 	  aux.opacity = opacity;
 	  aux.quality = auxgrp->quality;
@@ -1094,7 +1321,7 @@ rl2_aux_group_renderer (struct aux_group_renderer *auxgrp)
 	  aux.bg_green = auxgrp->bg_green;
 	  aux.bg_blue = auxgrp->bg_blue;
 	  aux.coverage = lyr->coverage;
-	  aux.symbolizer = (rl2RasterStylePtr) symbolizer;
+	  aux.symbolizer = (rl2RasterSymbolizerPtr) symbolizer;
 	  aux.stats = (rl2RasterStatisticsPtr) (lyr->raster_stats);
 	  aux.outbuf = outbuf;
 	  aux.palette = palette;
@@ -1211,3 +1438,3087 @@ rl2_aux_group_renderer (struct aux_group_renderer *auxgrp)
 	rl2_destroy_group_renderer (group);
     sqlite3_result_null (auxgrp->context);
 }
+
+static void
+do_copy_rgb (unsigned char *out, const unsigned char *in, unsigned int width,
+	     unsigned int height, unsigned int w, unsigned int h,
+	     int base_x, int base_y, unsigned char bg_red,
+	     unsigned char bg_green, unsigned char bg_blue)
+{
+/* copying RGB pixels */
+    int x;
+    int y;
+    unsigned char r;
+    unsigned char g;
+    unsigned char b;
+    unsigned char *p_out;
+    const unsigned char *p_in = in;
+
+    for (y = 0; y < (int) h; y++)
+      {
+	  if ((base_y + y) >= (int) height)
+	      break;
+	  if ((base_y + y) < 0)
+	    {
+		p_in += w * 3;
+		continue;
+	    }
+	  for (x = 0; x < (int) w; x++)
+	    {
+		if ((base_x + x) < 0 || (base_x + x) >= (int) width)
+		  {
+		      p_in += 3;
+		      continue;
+		  }
+		p_out = out + ((base_y + y) * width * 3) + ((base_x + x) * 3);
+		r = *p_in++;
+		g = *p_in++;
+		b = *p_in++;
+		if (r == bg_red && g == bg_green && b == bg_blue)
+		  {
+		      /* transparent pixel */
+		      p_out += 3;
+		  }
+		else
+		  {
+		      /* opaque pixel */
+		      *p_out++ = r;
+		      *p_out++ = g;
+		      *p_out++ = b;
+		  }
+	    }
+      }
+}
+
+static void
+do_copy_gray (unsigned char *out, const unsigned char *in, unsigned int width,
+	      unsigned int height, unsigned int w, unsigned int h,
+	      int base_x, int base_y, unsigned char bg_gray)
+{
+/* copying Grayscale pixels */
+    int x;
+    int y;
+    unsigned char gray;
+    unsigned char *p_out;
+    const unsigned char *p_in = in;
+
+    for (y = 0; y < (int) h; y++)
+      {
+	  if ((base_y + y) >= (int) height)
+	      break;
+	  if ((base_y + y) < 0)
+	    {
+		p_in += w;
+		continue;
+	    }
+	  for (x = 0; x < (int) w; x++)
+	    {
+		if ((base_x + x) < 0 || (base_x + x) >= (int) width)
+		  {
+		      p_in++;
+		      continue;
+		  }
+		p_out = out + ((base_y + y) * width) + (base_x + x);
+		gray = *p_in++;
+		if (gray == bg_gray)
+		  {
+		      /* transparent pixel */
+		      p_out++;
+		  }
+		else
+		  {
+		      /* opaque pixel */
+		      *p_out++ = gray;
+		  }
+	    }
+      }
+}
+
+RL2_DECLARE int
+rl2_get_raw_raster_data_mixed_resolutions (sqlite3 * handle, int max_threads,
+					   rl2CoveragePtr cvg,
+					   unsigned int width,
+					   unsigned int height, double minx,
+					   double miny, double maxx,
+					   double maxy, double x_res,
+					   double y_res,
+					   unsigned char **buffer,
+					   int *buf_size,
+					   rl2PalettePtr * palette,
+					   unsigned char *out_pixel,
+					   unsigned char bg_red,
+					   unsigned char bg_green,
+					   unsigned char bg_blue,
+					   rl2RasterSymbolizerPtr style,
+					   rl2RasterStatisticsPtr stats)
+{
+/* attempting to return raw pixels from the DBMS Coverage - Mixed Resolutions */
+    int ret;
+    rl2PixelPtr no_data = NULL;
+    const char *coverage;
+    unsigned char sample_type;
+    unsigned char pixel_type;
+    unsigned char num_bands;
+    unsigned char pixel = *out_pixel;
+    unsigned char *outbuf = NULL;
+    int out_size;
+    unsigned char *p;
+    unsigned int x;
+    unsigned int y;
+    rl2RasterSymbolizerPtr xstyle = style;
+    char *xsections;
+    char *xxsections;
+    char *sql;
+    sqlite3_stmt *stmt = NULL;
+
+    if (cvg == NULL || handle == NULL)
+	return RL2_ERROR;
+    if (rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands) !=
+	RL2_OK)
+	return RL2_ERROR;
+    coverage = rl2_get_coverage_name (cvg);
+    if (coverage == NULL)
+	return RL2_ERROR;
+
+    *buffer = NULL;
+    *buf_size = 0;
+    if (pixel == RL2_PIXEL_GRAYSCALE && pixel_type == RL2_PIXEL_DATAGRID)
+      {
+	  if (rl2_has_styled_rgb_colors (style))
+	    {
+		/* RGB RasterSymbolizer: promoting to RGB */
+		pixel = RL2_PIXEL_RGB;
+	    }
+      }
+    if (pixel == RL2_PIXEL_GRAYSCALE)
+      {
+	  /* GRAYSCALE */
+	  no_data = rl2_create_pixel (RL2_SAMPLE_UINT8, RL2_PIXEL_GRAYSCALE, 1);
+	  rl2_set_pixel_sample_uint8 (no_data, RL2_GRAYSCALE_BAND, bg_red);
+      }
+    else if (pixel == RL2_PIXEL_RGB)
+      {
+	  /* RGB */
+	  *out_pixel = RL2_PIXEL_RGB;
+	  no_data = rl2_create_pixel (RL2_SAMPLE_UINT8, RL2_PIXEL_RGB, 3);
+	  rl2_set_pixel_sample_uint8 (no_data, RL2_RED_BAND, bg_red);
+	  rl2_set_pixel_sample_uint8 (no_data, RL2_GREEN_BAND, bg_green);
+	  rl2_set_pixel_sample_uint8 (no_data, RL2_BLUE_BAND, bg_blue);
+      }
+    else
+	return RL2_ERROR;
+    if (pixel_type == RL2_PIXEL_MONOCHROME)
+	xstyle = NULL;
+
+/* preparing the "sections" SQL query */
+    xsections = sqlite3_mprintf ("%s_sections", coverage);
+    xxsections = rl2_double_quoted_sql (xsections);
+    sql =
+	sqlite3_mprintf
+	("SELECT section_id, MbrMinX(geometry), MbrMinY(geometry), "
+	 "MbrMaxX(geometry), MbrMaxY(geometry) "
+	 "FROM \"%s\" WHERE ROWID IN ( "
+	 "SELECT ROWID FROM SpatialIndex WHERE f_table_name = %Q "
+	 "AND search_frame = BuildMBR(?, ?, ?, ?))", xxsections, xsections);
+    sqlite3_free (xsections);
+    free (xxsections);
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("SELECT mixed-res Sections SQL error: %s\n",
+		  sqlite3_errmsg (handle));
+	  goto error;
+      }
+
+/* allocating the output buffer */
+    if (*out_pixel == RL2_PIXEL_RGB)
+	out_size = width * height * 3;
+    else
+	out_size = width * height;
+    outbuf = malloc (out_size);
+    p = outbuf;
+    for (y = 0; y < height; y++)
+      {
+	  /* priming the background color */
+	  for (x = 0; x < width; x++)
+	    {
+		if (*out_pixel == RL2_PIXEL_RGB)
+		  {
+		      *p++ = bg_red;
+		      *p++ = bg_green;
+		      *p++ = bg_blue;
+		  }
+		else
+		    *p++ = bg_red;
+	    }
+      }
+
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_double (stmt, 1, minx);
+    sqlite3_bind_double (stmt, 2, miny);
+    sqlite3_bind_double (stmt, 3, maxx);
+    sqlite3_bind_double (stmt, 4, maxy);
+    while (1)
+      {
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		sqlite3_int64 section_id = sqlite3_column_int64 (stmt, 0);
+		double section_minx = sqlite3_column_double (stmt, 1);
+		double section_miny = sqlite3_column_double (stmt, 2);
+		double section_maxx = sqlite3_column_double (stmt, 3);
+		double section_maxy = sqlite3_column_double (stmt, 4);
+		double xx_res;
+		double yy_res;
+		int level_id;
+		int scale;
+		int xscale;
+		unsigned int w;
+		unsigned int h;
+		int base_x;
+		int base_y;
+		unsigned char *bufpix = NULL;
+		int bufpix_size;
+		double img_res_x = (maxx - minx) / (double) width;
+		double img_res_y = (maxy - miny) / (double) height;
+		double mnx = minx;
+		double mny = miny;
+		double mxx = maxx;
+		double mxy = maxy;
+		if (section_id > 3)
+		    continue;
+		/* normalizing the visible portion of the Section */
+		if (mnx < section_minx)
+		    mnx = section_minx;
+		if (mny < section_miny)
+		    mny = section_miny;
+		if (mxx > section_maxx)
+		    mxx = section_maxx;
+		if (mxy > section_maxy)
+		    mxy = section_maxy;
+		/* retrieving the optimal resolution level */
+		if (!rl2_find_best_resolution_level
+		    (handle, coverage, 1, section_id, x_res, y_res, &level_id,
+		     &scale, &xscale, &xx_res, &yy_res))
+		    goto error;
+		w = (unsigned int) ((mxx - mnx) / xx_res);
+		if (((double) w * xx_res) < (mxx - mnx))
+		    w++;
+		h = (unsigned int) ((mxy - mny) / yy_res);
+		if (((double) h * yy_res) < (mxy - mny))
+		    h++;
+		base_x = (int) ((mnx - minx) / img_res_x);
+		base_y = (int) ((maxy - mxy) / img_res_y);
+		if (rl2_get_raw_raster_data_common
+		    (handle, max_threads, cvg, 1, section_id, w, h, mnx, mny,
+		     mxx, mxy, xx_res, yy_res, &bufpix, &bufpix_size, palette,
+		     *out_pixel, no_data, xstyle, stats) != RL2_OK)
+		    goto error;
+		if (*out_pixel == RL2_PIXEL_RGB)
+		    do_copy_rgb (outbuf, bufpix, width, height, w, h, base_x,
+				 base_y, bg_red, bg_green, bg_blue);
+		else
+		    do_copy_gray (outbuf, bufpix, width, height, w, h, base_x,
+				  base_y, bg_red);
+		free (bufpix);
+	    }
+	  else
+	    {
+		fprintf (stderr, "SQL error: %s\n%s\n", sql,
+			 sqlite3_errmsg (handle));
+		goto error;
+	    }
+      }
+    sqlite3_finalize (stmt);
+
+    if (no_data != NULL)
+	rl2_destroy_pixel (no_data);
+
+    *buffer = outbuf;
+    *buf_size = out_size;
+    return RL2_OK;
+
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    if (no_data != NULL)
+	rl2_destroy_pixel (no_data);
+    if (outbuf != NULL)
+	free (outbuf);
+    return RL2_ERROR;
+}
+
+static int
+point_bbox_matches (rl2PointPtr point, double minx, double miny, double maxx,
+		    double maxy)
+{
+/* checks if the Point is visible */
+    if (minx > point->x)
+	return 0;
+    if (maxx < point->x)
+	return 0;
+    if (miny > point->y)
+	return 0;
+    if (maxy < point->y)
+	return 0;
+    return 1;
+}
+
+static void
+draw_points (rl2GraphicsContextPtr ctx, sqlite3 * handle,
+	     rl2PrivVectorSymbolizerPtr sym, int height, double minx,
+	     double miny, double maxx, double maxy, double x_res,
+	     double y_res, rl2GeometryPtr geom)
+{
+/* drawing Point-type features */
+    rl2PrivVectorSymbolizerItemPtr item;
+    rl2PointPtr point;
+
+    item = sym->first;
+    while (item != NULL)
+      {
+	  if (item->symbolizer_type == RL2_POINT_SYMBOLIZER)
+	    {
+		rl2PrivPointSymbolizerPtr point_sym =
+		    (rl2PrivPointSymbolizerPtr) (item->symbolizer);
+		rl2PrivGraphicPtr gr = point_sym->graphic;
+		rl2PrivGraphicItemPtr graphic;
+		if (gr == NULL)
+		  {
+		      item = item->next;
+		      continue;
+		  }
+		graphic = point_sym->graphic->first;
+		while (graphic != NULL)
+		  {
+		      /* looping on Graphic definitions */
+		      int is_mark = 0;
+		      int is_external = 0;
+		      unsigned char well_known_type;
+		      int fill = 0;
+		      int stroke = 0;
+		      int pen_cap;
+		      int pen_join;
+		      double opacity;
+		      unsigned char norm_opacity;
+		      rl2GraphicsPatternPtr pattern = NULL;
+		      rl2GraphicsPatternPtr pattern_fill = NULL;
+		      rl2GraphicsPatternPtr pattern_stroke = NULL;
+
+		      if (graphic->type == RL2_MARK_GRAPHIC)
+			{
+			    rl2PrivMarkPtr mark =
+				(rl2PrivMarkPtr) (graphic->item);
+			    if (mark != NULL)
+			      {
+				  well_known_type = mark->well_known_type;
+				  is_mark = 1;
+				  if (mark->fill != NULL)
+				    {
+					if (mark->fill->graphic != NULL)
+					  {
+					      /* external Graphic fill */
+					      const char *xlink_href = NULL;
+					      int recolor = 0;
+					      unsigned char red;
+					      unsigned char green;
+					      unsigned char blue;
+					      pattern_fill = NULL;
+					      if (mark->fill->graphic->first !=
+						  NULL)
+						{
+						    if (mark->fill->
+							graphic->first->type ==
+							RL2_EXTERNAL_GRAPHIC)
+						      {
+							  rl2PrivExternalGraphicPtr
+							      ext =
+							      (rl2PrivExternalGraphicPtr)
+							      (mark->
+							       fill->graphic->
+							       first->item);
+							  xlink_href =
+							      ext->xlink_href;
+							  if (ext->first !=
+							      NULL)
+							    {
+								recolor = 1;
+								red =
+								    ext->
+								    first->red;
+								green =
+								    ext->
+								    first->green;
+								blue =
+								    ext->
+								    first->blue;
+							    }
+						      }
+						}
+					      if (xlink_href != NULL)
+						  pattern_fill =
+						      rl2_create_pattern_from_external_graphic
+						      (handle, xlink_href, 1);
+					      if (pattern_fill != NULL)
+						{
+						    if (recolor)
+						      {
+							  /* attempting to recolor the External Graphic resource */
+							  rl2_graph_pattern_recolor
+							      (pattern_fill,
+							       red, green,
+							       blue);
+						      }
+						    if (mark->fill->opacity <=
+							0.0)
+							norm_opacity = 0;
+						    else if (mark->
+							     fill->opacity >=
+							     1.0)
+							norm_opacity = 255;
+						    else
+						      {
+							  opacity =
+							      255.0 *
+							      mark->
+							      fill->opacity;
+							  if (opacity <= 0.0)
+							      norm_opacity = 0;
+							  else if (opacity >=
+								   255.0)
+							      norm_opacity =
+								  255;
+							  else
+							      norm_opacity =
+								  opacity;
+						      }
+						    if (norm_opacity < 1.0)
+							rl2_graph_pattern_transparency
+							    (pattern_fill,
+							     norm_opacity);
+						    rl2_graph_set_pattern_brush
+							(ctx, pattern_fill);
+						}
+					      else
+						{
+						    /* invalid Pattern: defaulting to a Gray brush */
+						    rl2_graph_set_brush (ctx,
+									 128,
+									 128,
+									 128,
+									 255);
+						}
+					      fill = 1;
+					  }
+					else
+					  {
+					      /* solid RGB fill */
+					      if (gr->opacity <= 0.0)
+						  norm_opacity = 0;
+					      else if (gr->opacity >= 1.0)
+						  norm_opacity = 255;
+					      else
+						{
+						    opacity =
+							255.0 * gr->opacity;
+						    if (opacity <= 0.0)
+							norm_opacity = 0;
+						    else if (opacity >= 255.0)
+							norm_opacity = 255;
+						    else
+							norm_opacity = opacity;
+						}
+					      rl2_graph_set_brush (ctx,
+								   mark->
+								   fill->red,
+								   mark->
+								   fill->green,
+								   mark->
+								   fill->blue,
+								   norm_opacity);
+					      fill = 1;
+					  }
+				    }
+				  if (mark->stroke != NULL)
+				    {
+					if (mark->stroke->graphic != NULL)
+					  {
+					      const char *xlink_href = NULL;
+					      int recolor = 0;
+					      unsigned char red;
+					      unsigned char green;
+					      unsigned char blue;
+					      pattern_stroke = NULL;
+					      if (mark->stroke->
+						  graphic->first != NULL)
+						{
+						    if (mark->stroke->
+							graphic->first->type ==
+							RL2_EXTERNAL_GRAPHIC)
+						      {
+							  rl2PrivExternalGraphicPtr
+							      ext =
+							      (rl2PrivExternalGraphicPtr)
+							      (mark->
+							       stroke->graphic->
+							       first->item);
+							  xlink_href =
+							      ext->xlink_href;
+							  if (ext->first !=
+							      NULL)
+							    {
+								recolor = 1;
+								red =
+								    ext->
+								    first->red;
+								green =
+								    ext->
+								    first->green;
+								blue =
+								    ext->
+								    first->blue;
+							    }
+						      }
+						}
+					      if (xlink_href != NULL)
+						  pattern_stroke =
+						      rl2_create_pattern_from_external_graphic
+						      (handle, xlink_href, 1);
+					      if (pattern != NULL)
+						{
+						    if (recolor)
+						      {
+							  /* attempting to recolor the External Graphic resource */
+							  rl2_graph_pattern_recolor
+							      (pattern_stroke,
+							       red, green,
+							       blue);
+						      }
+						    if (mark->stroke->opacity <=
+							0.0)
+							norm_opacity = 0;
+						    else if (mark->
+							     stroke->opacity >=
+							     1.0)
+							norm_opacity = 255;
+						    else
+						      {
+							  opacity =
+							      255.0 *
+							      mark->
+							      stroke->opacity;
+							  if (opacity <= 0.0)
+							      norm_opacity = 0;
+							  else if (opacity >=
+								   255.0)
+							      norm_opacity =
+								  255;
+							  else
+							      norm_opacity =
+								  opacity;
+						      }
+						    if (norm_opacity < 1.0)
+							rl2_graph_pattern_transparency
+							    (pattern_stroke,
+							     norm_opacity);
+						    if (pattern_stroke != NULL)
+						      {
+							  switch
+							      (mark->
+							       stroke->linecap)
+							    {
+							    case RL2_STROKE_LINECAP_ROUND:
+								pen_cap =
+								    RL2_PEN_CAP_ROUND;
+								break;
+							    case RL2_STROKE_LINECAP_SQUARE:
+								pen_cap =
+								    RL2_PEN_CAP_SQUARE;
+								break;
+							    default:
+								pen_cap =
+								    RL2_PEN_CAP_BUTT;
+								break;
+							    };
+							  switch
+							      (mark->
+							       stroke->linejoin)
+							    {
+							    case RL2_STROKE_LINEJOIN_BEVEL:
+								pen_join =
+								    RL2_PEN_JOIN_BEVEL;
+								break;
+							    case RL2_STROKE_LINEJOIN_ROUND:
+								pen_join =
+								    RL2_PEN_JOIN_ROUND;
+								break;
+							    default:
+								pen_join =
+								    RL2_PEN_JOIN_MITER;
+								break;
+							    };
+							  if (mark->
+							      stroke->dash_count
+							      > 0
+							      && mark->
+							      stroke->dash_list
+							      != NULL)
+							      rl2_graph_set_pattern_dashed_pen
+								  (ctx,
+								   pattern_stroke,
+								   mark->
+								   stroke->width,
+								   pen_cap,
+								   pen_join,
+								   mark->
+								   stroke->dash_count,
+								   mark->
+								   stroke->dash_list,
+								   mark->
+								   stroke->dash_offset);
+							  else
+							      rl2_graph_set_pattern_solid_pen
+								  (ctx,
+								   pattern_stroke,
+								   mark->
+								   stroke->width,
+								   pen_cap,
+								   pen_join);
+							  stroke = 1;
+						      }
+						}
+					  }
+					else
+					  {
+					      /* solid RGB stroke */
+					      if (gr->opacity <= 0.0)
+						  norm_opacity = 0;
+					      else if (gr->opacity >= 1.0)
+						  norm_opacity = 255;
+					      else
+						{
+						    opacity =
+							255.0 * gr->opacity;
+						    if (opacity <= 0.0)
+							norm_opacity = 0;
+						    else if (opacity >= 255.0)
+							norm_opacity = 255;
+						    else
+							norm_opacity = opacity;
+						}
+					      switch (mark->stroke->linecap)
+						{
+						case RL2_STROKE_LINECAP_ROUND:
+						    pen_cap = RL2_PEN_CAP_ROUND;
+						    break;
+						case RL2_STROKE_LINECAP_SQUARE:
+						    pen_cap =
+							RL2_PEN_CAP_SQUARE;
+						    break;
+						default:
+						    pen_cap = RL2_PEN_CAP_BUTT;
+						    break;
+						};
+					      switch (mark->stroke->linejoin)
+						{
+						case RL2_STROKE_LINEJOIN_BEVEL:
+						    pen_join =
+							RL2_PEN_JOIN_BEVEL;
+						    break;
+						case RL2_STROKE_LINEJOIN_ROUND:
+						    pen_join =
+							RL2_PEN_JOIN_ROUND;
+						    break;
+						default:
+						    pen_join =
+							RL2_PEN_JOIN_MITER;
+						    break;
+						};
+					      if (mark->stroke->dash_count > 0
+						  && mark->stroke->dash_list !=
+						  NULL)
+						  rl2_graph_set_dashed_pen (ctx,
+									    mark->stroke->red,
+									    mark->stroke->green,
+									    mark->stroke->blue,
+									    norm_opacity,
+									    mark->stroke->width,
+									    pen_cap,
+									    pen_join,
+									    mark->
+									    stroke->dash_count,
+									    mark->
+									    stroke->dash_list,
+									    mark->
+									    stroke->dash_offset);
+					      else
+						  rl2_graph_set_solid_pen
+						      (ctx, mark->stroke->red,
+						       mark->stroke->green,
+						       mark->stroke->blue,
+						       norm_opacity,
+						       mark->stroke->width,
+						       pen_cap, pen_join);
+					      stroke = 1;
+					  }
+				    }
+			      }
+			}
+		      if (graphic->type == RL2_EXTERNAL_GRAPHIC)
+			{
+			    rl2PrivExternalGraphicPtr ext =
+				(rl2PrivExternalGraphicPtr) (graphic->item);
+			    const char *xlink_href = NULL;
+			    int recolor = 0;
+			    unsigned char red;
+			    unsigned char green;
+			    unsigned char blue;
+			    pattern = NULL;
+			    if (ext != NULL)
+			      {
+				  is_external = 1;
+				  if (ext->xlink_href != NULL)
+				      xlink_href = ext->xlink_href;
+				  if (ext->first != NULL)
+				    {
+					recolor = 1;
+					red = ext->first->red;
+					green = ext->first->green;
+					blue = ext->first->blue;
+				    }
+				  if (xlink_href != NULL)
+				    {
+					/* first attempt: Bitmap */
+					pattern =
+					    rl2_create_pattern_from_external_graphic
+					    (handle, xlink_href, 1);
+					if (pattern == NULL)
+					  {
+					      /* second attempt: SVG */
+					      pattern =
+						  rl2_create_pattern_from_external_svg
+						  (handle, xlink_href,
+						   point_sym->graphic->size);
+					  }
+				    }
+			      }
+			    if (pattern != NULL)
+			      {
+				  if (recolor)
+				    {
+					/* attempting to recolor the External Graphic resource */
+					rl2_graph_pattern_recolor (pattern,
+								   red, green,
+								   blue);
+				    }
+				  if (point_sym->graphic->opacity <= 0.0)
+				      norm_opacity = 0;
+				  else if (point_sym->graphic->opacity >= 1.0)
+				      norm_opacity = 255;
+				  else
+				    {
+					opacity =
+					    255.0 * point_sym->graphic->opacity;
+					if (opacity <= 0.0)
+					    norm_opacity = 0;
+					else if (opacity >= 255.0)
+					    norm_opacity = 255;
+					else
+					    norm_opacity = opacity;
+				    }
+				  if (norm_opacity < 1.0)
+				      rl2_graph_pattern_transparency
+					  (pattern, norm_opacity);
+				  rl2_graph_set_pattern_brush (ctx, pattern);
+			      }
+			    else
+			      {
+				  /* invalid Pattern: defaulting to a Gray brush */
+				  rl2_graph_set_brush (ctx, 128, 128, 128, 255);
+			      }
+			}
+
+		      /* actual Point rendering */
+		      point = geom->first_point;
+		      while (point)
+			{
+			    /* drawing a POINT */
+			    if (point_bbox_matches
+				(point, minx, miny, maxx, maxy))
+			      {
+				  double x = (point->x - minx) / x_res;
+				  double y =
+				      (double) height -
+				      ((point->y - miny) / y_res);
+				  double size2 = gr->size / 2.0;
+				  double size4 = gr->size / 4.0;
+				  double size6 = gr->size / 6.0;
+				  double size13 = gr->size / 3.0;
+				  double size23 = (gr->size / 3.0) * 2.0;
+				  int i;
+				  double rads;
+				  if (size2 <= 0.0)
+				      size2 = 1.0;
+				  if (size4 <= 0.0)
+				      size4 = 1.0;
+				  if (size6 <= 0.0)
+				      size6 = 1.0;
+				  if (size13 <= 0.0)
+				      size13 = 1.0;
+				  if (size23 <= 0.0)
+				      size23 = 1.0;
+				  if (is_mark)
+				    {
+					/* drawing a well-known Mark */
+					switch (well_known_type)
+					  {
+					  case RL2_GRAPHIC_MARK_CIRCLE:
+					      rads = 0.0;
+					      for (i = 0; i < 32; i++)
+						{
+						    double tic =
+							6.28318530718 / 32.0;
+						    double cx =
+							x +
+							(size2 * sin (rads));
+						    double cy =
+							y +
+							(size2 * cos (rads));
+						    if (i == 0)
+							rl2_graph_move_to_point
+							    (ctx, cx, cy);
+						    else
+							rl2_graph_add_line_to_path
+							    (ctx, cx, cy);
+						    rads += tic;
+						}
+					      rl2_graph_close_subpath (ctx);
+					      break;
+					  case RL2_GRAPHIC_MARK_TRIANGLE:
+					      rl2_graph_move_to_point (ctx, x,
+								       y -
+								       size23);
+					      rl2_graph_add_line_to_path (ctx,
+									  x -
+									  size2,
+									  y +
+									  size13);
+					      rl2_graph_add_line_to_path (ctx,
+									  x +
+									  size2,
+									  y +
+									  size13);
+					      rl2_graph_close_subpath (ctx);
+					      break;
+					  case RL2_GRAPHIC_MARK_STAR:
+					      rads = 3.14159265359;
+					      for (i = 0; i < 10; i++)
+						{
+						    double tic =
+							(i % 2) ? size6 : size2;
+						    double cx =
+							x + (tic * sin (rads));
+						    double cy =
+							y + (tic * cos (rads));
+						    if (i == 0)
+							rl2_graph_move_to_point
+							    (ctx, cx, cy);
+						    else
+							rl2_graph_add_line_to_path
+							    (ctx, cx, cy);
+						    rads += 0.628318530718;
+						}
+					      rl2_graph_close_subpath (ctx);
+					      break;
+					  case RL2_GRAPHIC_MARK_CROSS:
+					      rl2_graph_move_to_point (ctx,
+								       x -
+								       size6,
+								       y -
+								       size2);
+					      rl2_graph_add_line_to_path (ctx,
+									  x +
+									  size6,
+									  y -
+									  size2);
+					      rl2_graph_add_line_to_path (ctx,
+									  x +
+									  size6,
+									  y -
+									  size6);
+					      rl2_graph_add_line_to_path (ctx,
+									  x +
+									  size2,
+									  y -
+									  size6);
+					      rl2_graph_add_line_to_path (ctx,
+									  x +
+									  size2,
+									  y +
+									  size6);
+					      rl2_graph_add_line_to_path (ctx,
+									  x +
+									  size6,
+									  y +
+									  size6);
+					      rl2_graph_add_line_to_path (ctx,
+									  x +
+									  size6,
+									  y +
+									  size2);
+					      rl2_graph_add_line_to_path (ctx,
+									  x -
+									  size6,
+									  y +
+									  size2);
+					      rl2_graph_add_line_to_path (ctx,
+									  x -
+									  size6,
+									  y +
+									  size6);
+					      rl2_graph_add_line_to_path (ctx,
+									  x -
+									  size2,
+									  y +
+									  size6);
+					      rl2_graph_add_line_to_path (ctx,
+									  x -
+									  size2,
+									  y -
+									  size6);
+					      rl2_graph_add_line_to_path (ctx,
+									  x -
+									  size6,
+									  y -
+									  size6);
+					      rl2_graph_close_subpath (ctx);
+					      break;
+					  case RL2_GRAPHIC_MARK_X:
+					      rl2_graph_move_to_point (ctx,
+								       x -
+								       size2,
+								       y -
+								       size2);
+					      rl2_graph_add_line_to_path (ctx,
+									  x -
+									  size4,
+									  y -
+									  size2);
+					      rl2_graph_add_line_to_path (ctx,
+									  x,
+									  y -
+									  size6);
+					      rl2_graph_add_line_to_path (ctx,
+									  x +
+									  size6,
+									  y -
+									  size2);
+					      rl2_graph_add_line_to_path (ctx,
+									  x +
+									  size2,
+									  y -
+									  size2);
+					      rl2_graph_add_line_to_path (ctx,
+									  x +
+									  size4,
+									  y);
+					      rl2_graph_add_line_to_path (ctx,
+									  x +
+									  size2,
+									  y +
+									  size2);
+					      rl2_graph_add_line_to_path (ctx,
+									  x +
+									  size4,
+									  y +
+									  size2);
+					      rl2_graph_add_line_to_path (ctx,
+									  x,
+									  y +
+									  size6);
+					      rl2_graph_add_line_to_path (ctx,
+									  x -
+									  size6,
+									  y +
+									  size2);
+					      rl2_graph_add_line_to_path (ctx,
+									  x -
+									  size2,
+									  y +
+									  size2);
+					      rl2_graph_add_line_to_path (ctx,
+									  x -
+									  size4,
+									  y);
+					      rl2_graph_close_subpath (ctx);
+					      break;
+					  case RL2_GRAPHIC_MARK_SQUARE:
+					  default:
+					      rl2_graph_move_to_point (ctx,
+								       x -
+								       size2,
+								       y -
+								       size2);
+					      rl2_graph_add_line_to_path (ctx,
+									  x -
+									  size2,
+									  y +
+									  size2);
+					      rl2_graph_add_line_to_path (ctx,
+									  x +
+									  size2,
+									  y +
+									  size2);
+					      rl2_graph_add_line_to_path (ctx,
+									  x +
+									  size2,
+									  y -
+									  size2);
+					      rl2_graph_close_subpath (ctx);
+					      break;
+					  };
+					if (fill)
+					  {
+					      if (stroke)
+						  rl2_graph_fill_path (ctx,
+								       RL2_PRESERVE_PATH);
+					      else
+						  rl2_graph_fill_path (ctx,
+								       RL2_CLEAR_PATH);
+					  }
+					if (stroke)
+					    rl2_graph_stroke_path (ctx,
+								   RL2_CLEAR_PATH);
+				    }
+				  if (is_external && pattern != NULL)
+				    {
+					/* drawing an External Graphic pattern */
+					unsigned int width;
+					unsigned int height;
+					rl2_graph_get_pattern_size (pattern,
+								    &width,
+								    &height);
+					double out_width = width;
+					double out_height = height;
+					rl2_graph_draw_graphic_symbol (ctx,
+								       pattern,
+								       out_width,
+								       out_height,
+								       x +
+								       point_sym->graphic->displacement_x,
+								       y -
+								       point_sym->graphic->displacement_y,
+								       point_sym->graphic->rotation,
+								       point_sym->graphic->anchor_point_x,
+								       point_sym->graphic->anchor_point_y);
+				    }
+			      }
+			    point = point->next;
+			}
+
+		      /* releasing Patterns */
+		      if (pattern != NULL)
+			  rl2_graph_destroy_pattern (pattern);
+		      if (pattern_fill != NULL)
+			{
+			    rl2_graph_release_pattern_pen (ctx);
+			    rl2_graph_destroy_pattern (pattern_fill);
+			}
+		      if (pattern_stroke != NULL)
+			{
+			    rl2_graph_release_pattern_pen (ctx);
+			    rl2_graph_destroy_pattern (pattern_stroke);
+			}
+		      graphic = graphic->next;
+		  }
+	    }
+	  item = item->next;
+      }
+}
+
+static int
+linestring_bbox_matches (rl2LinestringPtr ring, double minx, double miny,
+			 double maxx, double maxy)
+{
+/* checks if the Linestring BBOX is visible */
+    if (minx > ring->maxx)
+	return 0;
+    if (maxx < ring->minx)
+	return 0;
+    if (miny > ring->maxy)
+	return 0;
+    if (maxy < ring->miny)
+	return 0;
+    return 1;
+}
+
+static void
+draw_lines (rl2GraphicsContextPtr ctx, sqlite3 * handle,
+	    rl2PrivVectorSymbolizerPtr sym, int height, double minx,
+	    double miny, double maxx, double maxy, double x_res, double y_res,
+	    rl2GeometryPtr geom)
+{
+/* drawing Linear-type features */
+    rl2PrivVectorSymbolizerItemPtr item;
+    int pen_cap;
+    int pen_join;
+    double opacity;
+    unsigned char norm_opacity;
+    rl2LinestringPtr line;
+    rl2GraphicsPatternPtr pattern = NULL;
+    rl2PrivMultiStrokePtr multi_stroke = rl2_create_multi_stroke ();
+
+    item = sym->first;
+    while (item != NULL)
+      {
+	  if (item->symbolizer_type == RL2_LINE_SYMBOLIZER)
+	    {
+		rl2PrivLineSymbolizerPtr line_sym =
+		    (rl2PrivLineSymbolizerPtr) (item->symbolizer);
+		if (line_sym->stroke != NULL)
+		  {
+		      if (line_sym->stroke->graphic != NULL)
+			{
+			    /* external Graphic stroke */
+			    const char *xlink_href = NULL;
+			    int recolor = 0;
+			    unsigned char red;
+			    unsigned char green;
+			    unsigned char blue;
+			    pattern = NULL;
+			    if (line_sym->stroke->graphic->first != NULL)
+			      {
+				  if (line_sym->stroke->graphic->first->type ==
+				      RL2_EXTERNAL_GRAPHIC)
+				    {
+					rl2PrivExternalGraphicPtr ext =
+					    (rl2PrivExternalGraphicPtr)
+					    (line_sym->stroke->graphic->
+					     first->item);
+					xlink_href = ext->xlink_href;
+					if (ext->first != NULL)
+					  {
+					      recolor = 1;
+					      red = ext->first->red;
+					      green = ext->first->green;
+					      blue = ext->first->blue;
+					  }
+				    }
+			      }
+			    if (xlink_href != NULL)
+				pattern =
+				    rl2_create_pattern_from_external_graphic
+				    (handle, xlink_href, 1);
+			    if (pattern != NULL)
+			      {
+				  if (recolor)
+				    {
+					/* attempting to recolor the External Graphic resource */
+					rl2_graph_pattern_recolor (pattern,
+								   red, green,
+								   blue);
+				    }
+				  if (line_sym->stroke->opacity <= 0.0)
+				      norm_opacity = 0;
+				  else if (line_sym->stroke->opacity >= 1.0)
+				      norm_opacity = 255;
+				  else
+				    {
+					opacity =
+					    255.0 * line_sym->stroke->opacity;
+					if (opacity <= 0.0)
+					    norm_opacity = 0;
+					else if (opacity >= 255.0)
+					    norm_opacity = 255;
+					else
+					    norm_opacity = opacity;
+				    }
+				  if (norm_opacity < 1.0)
+				      rl2_graph_pattern_transparency
+					  (pattern, norm_opacity);
+				  if (line_sym->stroke->dash_count > 0
+				      && line_sym->stroke->dash_list != NULL)
+				      rl2_add_pattern_to_multi_stroke_dash
+					  (multi_stroke, pattern,
+					   line_sym->stroke->width, pen_cap,
+					   pen_join,
+					   line_sym->stroke->dash_count,
+					   line_sym->stroke->dash_list,
+					   line_sym->stroke->dash_offset);
+				  else
+				      rl2_add_pattern_to_multi_stroke
+					  (multi_stroke, pattern,
+					   line_sym->stroke->width, pen_cap,
+					   pen_join);
+			      }
+			    else
+			      {
+				  /* invalid Pattern: defaulting to a Gray brush */
+				  rl2_graph_set_brush (ctx, 128, 128, 128, 255);
+			      }
+			}
+		      else
+			{
+			    /* solid RGB stroke */
+			    if (line_sym->stroke->opacity <= 0.0)
+				norm_opacity = 0;
+			    else if (line_sym->stroke->opacity >= 1.0)
+				norm_opacity = 255;
+			    else
+			      {
+				  opacity = 255.0 * line_sym->stroke->opacity;
+				  if (opacity <= 0.0)
+				      norm_opacity = 0;
+				  else if (opacity >= 255.0)
+				      norm_opacity = 255;
+				  else
+				      norm_opacity = opacity;
+			      }
+			    switch (line_sym->stroke->linecap)
+			      {
+			      case RL2_STROKE_LINECAP_ROUND:
+				  pen_cap = RL2_PEN_CAP_ROUND;
+				  break;
+			      case RL2_STROKE_LINECAP_SQUARE:
+				  pen_cap = RL2_PEN_CAP_SQUARE;
+				  break;
+			      default:
+				  pen_cap = RL2_PEN_CAP_BUTT;
+				  break;
+			      };
+			    switch (line_sym->stroke->linejoin)
+			      {
+			      case RL2_STROKE_LINEJOIN_BEVEL:
+				  pen_join = RL2_PEN_JOIN_BEVEL;
+				  break;
+			      case RL2_STROKE_LINEJOIN_ROUND:
+				  pen_join = RL2_PEN_JOIN_ROUND;
+				  break;
+			      default:
+				  pen_join = RL2_PEN_JOIN_MITER;
+				  break;
+			      };
+			    if (line_sym->stroke->dash_count > 0
+				&& line_sym->stroke->dash_list != NULL)
+				rl2_add_to_multi_stroke_dash (multi_stroke,
+							      line_sym->
+							      stroke->red,
+							      line_sym->
+							      stroke->green,
+							      line_sym->
+							      stroke->blue,
+							      norm_opacity,
+							      line_sym->
+							      stroke->width,
+							      pen_cap, pen_join,
+							      line_sym->
+							      stroke->dash_count,
+							      line_sym->
+							      stroke->dash_list,
+							      line_sym->
+							      stroke->dash_offset);
+			    else
+				rl2_add_to_multi_stroke (multi_stroke,
+							 line_sym->stroke->red,
+							 line_sym->
+							 stroke->green,
+							 line_sym->stroke->blue,
+							 norm_opacity,
+							 line_sym->
+							 stroke->width, pen_cap,
+							 pen_join);
+			}
+		  }
+	    }
+	  item = item->next;
+      }
+    if (multi_stroke == NULL)
+	return;
+
+    line = geom->first_linestring;
+    while (line)
+      {
+	  /* drawing a LINESTRING */
+	  if (linestring_bbox_matches (line, minx, miny, maxx, maxy))
+	    {
+		rl2PrivMultiStrokeItemPtr stroke_item;
+		int iv;
+		double dx;
+		double dy;
+		int x;
+		int y;
+		int lastX = 0;
+		int lastY = 0;
+		for (iv = 0; iv < line->points; iv++)
+		  {
+		      rl2GetPoint (line->coords, iv, &dx, &dy);
+		      x = (int) ((dx - minx) / x_res);
+		      y = height - (int) ((dy - miny) / y_res);
+		      if (iv == 0)
+			{
+			    rl2_graph_move_to_point (ctx, x, y);
+			    lastX = x;
+			    lastY = y;
+			}
+		      else
+			{
+			    if (x == lastX && y == lastY)
+				;
+			    else
+			      {
+				  rl2_graph_add_line_to_path (ctx, x, y);
+				  lastX = x;
+				  lastY = y;
+			      }
+			}
+		  }
+		stroke_item = multi_stroke->first;
+		while (stroke_item != NULL)
+		  {
+		      /* applying all strokes, one after the other */
+		      if (stroke_item->dash_count > 0
+			  && stroke_item->dash_list != NULL)
+			{
+			    if (stroke_item->pattern != NULL)
+				rl2_graph_set_pattern_dashed_pen (ctx,
+								  stroke_item->pattern,
+								  stroke_item->width,
+								  stroke_item->pen_cap,
+								  stroke_item->pen_join,
+								  stroke_item->dash_count,
+								  stroke_item->dash_list,
+								  stroke_item->dash_offset);
+			    else
+				rl2_graph_set_dashed_pen (ctx,
+							  stroke_item->red,
+							  stroke_item->green,
+							  stroke_item->blue,
+							  stroke_item->opacity,
+							  stroke_item->width,
+							  stroke_item->pen_cap,
+							  stroke_item->pen_join,
+							  stroke_item->dash_count,
+							  stroke_item->dash_list,
+							  stroke_item->dash_offset);
+			}
+		      else
+			{
+			    if (stroke_item->pattern != NULL)
+				rl2_graph_set_pattern_solid_pen (ctx,
+								 stroke_item->pattern,
+								 stroke_item->width,
+								 stroke_item->pen_cap,
+								 stroke_item->pen_join);
+			    else
+				rl2_graph_set_solid_pen (ctx,
+							 stroke_item->red,
+							 stroke_item->green,
+							 stroke_item->blue,
+							 stroke_item->opacity,
+							 stroke_item->width,
+							 stroke_item->pen_cap,
+							 stroke_item->pen_join);
+			}
+
+		      if (stroke_item == multi_stroke->last)
+			  rl2_graph_stroke_path (ctx, RL2_CLEAR_PATH);
+		      else
+			  rl2_graph_stroke_path (ctx, RL2_PRESERVE_PATH);
+
+		      stroke_item = stroke_item->next;
+		      if (stroke_item == multi_stroke->last)
+			  rl2_graph_release_pattern_pen (ctx);
+		  }
+	    }
+	  line = line->next;
+      }
+    rl2_destroy_multi_stroke (multi_stroke);
+}
+
+static int
+ring_bbox_matches (rl2RingPtr ring, double minx, double miny, double maxx,
+		   double maxy)
+{
+/* checks if the Ring BBOX is visible */
+    if (minx > ring->maxx)
+	return 0;
+    if (maxx < ring->minx)
+	return 0;
+    if (miny > ring->maxy)
+	return 0;
+    if (maxy < ring->miny)
+	return 0;
+    return 1;
+}
+
+static void
+draw_polygons (rl2GraphicsContextPtr ctx, sqlite3 * handle,
+	       rl2PrivVectorSymbolizerPtr sym, int height, double minx,
+	       double miny, double maxx, double maxy, double x_res,
+	       double y_res, rl2GeometryPtr geom)
+{
+/* drawing Polygonal-type features */
+    rl2PrivVectorSymbolizerItemPtr item;
+    int stroke = 0;
+    int fill = 0;
+    int pen_cap;
+    int pen_join;
+    double opacity;
+    unsigned char norm_opacity;
+    rl2PolygonPtr polyg;
+    rl2GraphicsPatternPtr pattern_fill = NULL;
+    rl2GraphicsPatternPtr pattern_stroke = NULL;
+
+/* selecting the pen and brush requested by the current PolygonSymbolizer */
+    item = sym->first;
+    while (item != NULL)
+      {
+	  stroke = 0;
+	  fill = 0;
+	  if (item->symbolizer_type == RL2_POLYGON_SYMBOLIZER)
+	    {
+		rl2PrivPolygonSymbolizerPtr polyg_sym =
+		    (rl2PrivPolygonSymbolizerPtr) (item->symbolizer);
+		if (polyg_sym->fill != NULL)
+		  {
+		      if (polyg_sym->fill->graphic != NULL)
+			{
+			    /* external Graphic fill */
+			    const char *xlink_href = NULL;
+			    int recolor = 0;
+			    unsigned char red;
+			    unsigned char green;
+			    unsigned char blue;
+			    pattern_fill = NULL;
+			    if (polyg_sym->fill->graphic->first != NULL)
+			      {
+				  if (polyg_sym->fill->graphic->first->type ==
+				      RL2_EXTERNAL_GRAPHIC)
+				    {
+					rl2PrivExternalGraphicPtr ext =
+					    (rl2PrivExternalGraphicPtr)
+					    (polyg_sym->fill->graphic->
+					     first->item);
+					xlink_href = ext->xlink_href;
+					if (ext->first != NULL)
+					  {
+					      recolor = 1;
+					      red = ext->first->red;
+					      green = ext->first->green;
+					      blue = ext->first->blue;
+					  }
+				    }
+			      }
+			    if (xlink_href != NULL)
+				pattern_fill =
+				    rl2_create_pattern_from_external_graphic
+				    (handle, xlink_href, 1);
+			    if (pattern_fill != NULL)
+			      {
+				  if (recolor)
+				    {
+					/* attempting to recolor the External Graphic resource */
+					rl2_graph_pattern_recolor
+					    (pattern_fill, red, green, blue);
+				    }
+				  if (polyg_sym->fill->opacity <= 0.0)
+				      norm_opacity = 0;
+				  else if (polyg_sym->fill->opacity >= 1.0)
+				      norm_opacity = 255;
+				  else
+				    {
+					opacity =
+					    255.0 * polyg_sym->fill->opacity;
+					if (opacity <= 0.0)
+					    norm_opacity = 0;
+					else if (opacity >= 255.0)
+					    norm_opacity = 255;
+					else
+					    norm_opacity = opacity;
+				    }
+				  if (norm_opacity < 1.0)
+				      rl2_graph_pattern_transparency
+					  (pattern_fill, norm_opacity);
+				  rl2_graph_set_pattern_brush (ctx,
+							       pattern_fill);
+			      }
+			    else
+			      {
+				  /* invalid Pattern: defaulting to a Gray brush */
+				  rl2_graph_set_brush (ctx, 128, 128, 128, 255);
+			      }
+			    fill = 1;
+			}
+		      else
+			{
+			    /* solid RGB fill */
+			    if (polyg_sym->fill->opacity <= 0.0)
+				norm_opacity = 0;
+			    else if (polyg_sym->fill->opacity >= 1.0)
+				norm_opacity = 255;
+			    else
+			      {
+				  opacity = 255.0 * polyg_sym->fill->opacity;
+				  if (opacity <= 0.0)
+				      norm_opacity = 0;
+				  else if (opacity >= 255.0)
+				      norm_opacity = 255;
+				  else
+				      norm_opacity = opacity;
+			      }
+			    rl2_graph_set_brush (ctx, polyg_sym->fill->red,
+						 polyg_sym->fill->green,
+						 polyg_sym->fill->blue,
+						 norm_opacity);
+			    fill = 1;
+			}
+		  }
+		if (polyg_sym->stroke != NULL)
+		  {
+		      if (polyg_sym->stroke->graphic != NULL)
+			{
+			    /* external Graphic stroke */
+			    const char *xlink_href = NULL;
+			    int recolor = 0;
+			    unsigned char red;
+			    unsigned char green;
+			    unsigned char blue;
+			    pattern_stroke = NULL;
+			    if (polyg_sym->stroke->graphic->first != NULL)
+			      {
+				  if (polyg_sym->stroke->graphic->first->type ==
+				      RL2_EXTERNAL_GRAPHIC)
+				    {
+					rl2PrivExternalGraphicPtr ext =
+					    (rl2PrivExternalGraphicPtr)
+					    (polyg_sym->stroke->graphic->
+					     first->item);
+					xlink_href = ext->xlink_href;
+					if (ext->first != NULL)
+					  {
+					      recolor = 1;
+					      red = ext->first->red;
+					      green = ext->first->green;
+					      blue = ext->first->blue;
+					  }
+				    }
+			      }
+			    if (xlink_href != NULL)
+				pattern_stroke =
+				    rl2_create_pattern_from_external_graphic
+				    (handle, xlink_href, 1);
+			    if (pattern_stroke != NULL)
+			      {
+				  if (recolor)
+				    {
+					/* attempting to recolor the External Graphic resource */
+					rl2_graph_pattern_recolor
+					    (pattern_stroke, red, green, blue);
+				    }
+				  if (polyg_sym->stroke->opacity <= 0.0)
+				      norm_opacity = 0;
+				  else if (polyg_sym->stroke->opacity >= 1.0)
+				      norm_opacity = 255;
+				  else
+				    {
+					opacity =
+					    255.0 * polyg_sym->stroke->opacity;
+					if (opacity <= 0.0)
+					    norm_opacity = 0;
+					else if (opacity >= 255.0)
+					    norm_opacity = 255;
+					else
+					    norm_opacity = opacity;
+				    }
+				  if (norm_opacity < 1.0)
+				      rl2_graph_pattern_transparency
+					  (pattern_stroke, norm_opacity);
+				  rl2_graph_set_pattern_brush (ctx,
+							       pattern_stroke);
+			      }
+			    else
+			      {
+				  /* invalid Pattern: defaulting to a Gray brush */
+				  rl2_graph_set_brush (ctx, 128, 128, 128, 255);
+			      }
+			    stroke = 1;
+			}
+		      else
+			{
+			    /* solid RGB stroke */
+			    if (polyg_sym->stroke->opacity <= 0.0)
+				norm_opacity = 0;
+			    else if (polyg_sym->stroke->opacity >= 1.0)
+				norm_opacity = 255;
+			    else
+			      {
+				  opacity = 255.0 * polyg_sym->stroke->opacity;
+				  if (opacity <= 0.0)
+				      norm_opacity = 0;
+				  else if (opacity >= 255.0)
+				      norm_opacity = 255;
+				  else
+				      norm_opacity = opacity;
+			      }
+			    switch (polyg_sym->stroke->linecap)
+			      {
+			      case RL2_STROKE_LINECAP_ROUND:
+				  pen_cap = RL2_PEN_CAP_ROUND;
+				  break;
+			      case RL2_STROKE_LINECAP_SQUARE:
+				  pen_cap = RL2_PEN_CAP_SQUARE;
+				  break;
+			      default:
+				  pen_cap = RL2_PEN_CAP_BUTT;
+				  break;
+			      };
+			    switch (polyg_sym->stroke->linejoin)
+			      {
+			      case RL2_STROKE_LINEJOIN_BEVEL:
+				  pen_join = RL2_PEN_JOIN_BEVEL;
+				  break;
+			      case RL2_STROKE_LINEJOIN_ROUND:
+				  pen_join = RL2_PEN_JOIN_ROUND;
+				  break;
+			      default:
+				  pen_join = RL2_PEN_JOIN_MITER;
+				  break;
+			      };
+			    if (polyg_sym->stroke->dash_count > 0
+				&& polyg_sym->stroke->dash_list != NULL)
+				rl2_graph_set_dashed_pen (ctx,
+							  polyg_sym->
+							  stroke->red,
+							  polyg_sym->
+							  stroke->green,
+							  polyg_sym->
+							  stroke->blue,
+							  norm_opacity,
+							  polyg_sym->
+							  stroke->width,
+							  pen_cap, pen_join,
+							  polyg_sym->
+							  stroke->dash_count,
+							  polyg_sym->
+							  stroke->dash_list,
+							  polyg_sym->
+							  stroke->dash_offset);
+			    else
+				rl2_graph_set_solid_pen (ctx,
+							 polyg_sym->stroke->red,
+							 polyg_sym->
+							 stroke->green,
+							 polyg_sym->
+							 stroke->blue,
+							 norm_opacity,
+							 polyg_sym->
+							 stroke->width, pen_cap,
+							 pen_join);
+			    stroke = 1;
+			}
+		  }
+	    }
+	  if (!fill && !stroke)
+	    {
+		item = item->next;
+		continue;
+	    }
+
+	  polyg = geom->first_polygon;
+	  while (polyg)
+	    {
+		/* drawing a POLYGON */
+		int iv;
+		double dx;
+		double dy;
+		int x;
+		int y;
+		int lastX = 0;
+		int lastY = 0;
+		int ib;
+		rl2RingPtr ring = polyg->exterior;
+		/* exterior border */
+		if (ring_bbox_matches (ring, minx, miny, maxx, maxy))
+		  {
+		      for (iv = 0; iv < ring->points; iv++)
+			{
+			    rl2GetPoint (ring->coords, iv, &dx, &dy);
+			    x = (int) ((dx - minx) / x_res);
+			    y = height - (int) ((dy - miny) / y_res);
+			    if (iv == 0)
+			      {
+				  rl2_graph_move_to_point (ctx, x, y);
+				  lastX = x;
+				  lastY = y;
+			      }
+			    else
+			      {
+				  if (x == lastX && y == lastY)
+				      ;
+				  else
+				    {
+					rl2_graph_add_line_to_path (ctx, x, y);
+					lastX = x;
+					lastY = y;
+				    }
+			      }
+			}
+		      rl2_graph_close_subpath (ctx);
+		  }
+		else
+		  {
+		      /* if the exterior ring is invisible we'll ignore all internal rings */
+		      polyg = polyg->next;
+		      continue;
+		  }
+		for (ib = 0; ib < polyg->num_interiors; ib++)
+		  {
+		      /* interior borders */
+		      ring = polyg->interiors + ib;
+		      if (ring_bbox_matches (ring, minx, miny, maxx, maxy))
+			{
+			    for (iv = 0; iv < ring->points; iv++)
+			      {
+				  rl2GetPoint (ring->coords, iv, &dx, &dy);
+				  x = (int) ((dx - minx) / x_res);
+				  y = height - (int) ((dy - miny) / y_res);
+				  if (iv == 0)
+				    {
+					rl2_graph_move_to_point (ctx, x, y);
+					lastX = x;
+					lastY = y;
+				    }
+				  else
+				    {
+					if (x == lastX && y == lastY)
+					    ;
+					else
+					  {
+					      rl2_graph_add_line_to_path (ctx,
+									  x, y);
+					      lastX = x;
+					      lastY = y;
+					  }
+				    }
+			      }
+			    rl2_graph_close_subpath (ctx);
+			}
+		  }
+		if (fill)
+		  {
+		      if (stroke)
+			  rl2_graph_fill_path (ctx, RL2_PRESERVE_PATH);
+		      else
+			  rl2_graph_fill_path (ctx, RL2_CLEAR_PATH);
+		  }
+		if (stroke)
+		    rl2_graph_stroke_path (ctx, RL2_CLEAR_PATH);
+		polyg = polyg->next;
+	    }
+	  if (pattern_fill != NULL)
+	    {
+		rl2_graph_release_pattern_brush (ctx);
+		rl2_graph_destroy_pattern (pattern_fill);
+	    }
+	  if (pattern_stroke != NULL)
+	    {
+		rl2_graph_release_pattern_pen (ctx);
+		rl2_graph_destroy_pattern (pattern_stroke);
+	    }
+	  item = item->next;
+      }
+}
+
+static int
+label_get_xy (sqlite3 * handle, const unsigned char *blob, int size,
+	      double *x, double *y)
+{
+/* resolving Point XY coords */
+    const char *sql;
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+    int ok = 0;
+
+    sql = "SELECT ST_X(?), ST_Y(?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return 0;
+
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_blob (stmt, 1, blob, size, SQLITE_STATIC);
+    sqlite3_bind_blob (stmt, 2, blob, size, SQLITE_STATIC);
+    while (1)
+      {
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		*x = sqlite3_column_double (stmt, 0);
+		*y = sqlite3_column_double (stmt, 1);
+		ok = 1;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    return ok;
+}
+
+static int
+label_get_centroid (sqlite3 * handle, rl2PolygonPtr polyg, double *x, double *y)
+{
+/* computing a Polygon Centroid */
+    unsigned char *blob;
+    int blob_sz;
+    const char *sql;
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+    int ok = 0;
+
+    if (polyg == NULL)
+	return 0;
+    if (polyg->exterior == NULL)
+	return 0;
+    if (!rl2_serialize_ring (polyg->exterior, &blob, &blob_sz))
+	return 0;
+
+    sql = "SELECT ST_Centroid(?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return 0;
+
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_blob (stmt, 1, blob, blob_sz, free);
+    while (1)
+      {
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
+		  {
+		      const unsigned char *g_blob =
+			  (const unsigned char *) sqlite3_column_blob (stmt,
+								       0);
+		      int g_size = sqlite3_column_bytes (stmt, 0);
+		      if (label_get_xy (handle, g_blob, g_size, x, y))
+			  ok = 1;
+		  }
+	    }
+      }
+    sqlite3_finalize (stmt);
+    return ok;
+}
+
+static int
+label_get_midpoint (sqlite3 * handle, rl2LinestringPtr line, double *x,
+		    double *y)
+{
+/* computing a Linestring MidPoint */
+    unsigned char *blob;
+    int blob_sz;
+    const char *sql;
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+    int ok = 0;
+
+    if (line == NULL)
+	return 0;
+    if (!rl2_serialize_linestring (line, &blob, &blob_sz))
+	return 0;
+
+    sql = "SELECT ST_Line_Interpolate_Point(?, 0.5)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return 0;
+
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_blob (stmt, 1, blob, blob_sz, free);
+    while (1)
+      {
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
+		  {
+		      const unsigned char *g_blob =
+			  (const unsigned char *) sqlite3_column_blob (stmt,
+								       0);
+		      int g_size = sqlite3_column_bytes (stmt, 0);
+		      if (label_get_xy (handle, g_blob, g_size, x, y))
+			  ok = 1;
+		  }
+	    }
+      }
+    sqlite3_finalize (stmt);
+    return ok;
+}
+
+static int
+label_get_ring_midpoint (sqlite3 * handle, rl2RingPtr ring, double *x,
+			 double *y)
+{
+/* computing a Ring MidPoint */
+    unsigned char *blob;
+    int blob_sz;
+    const char *sql;
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+    int ok = 0;
+
+    if (ring == NULL)
+	return 0;
+    if (!rl2_serialize_ring_as_linestring (ring, &blob, &blob_sz))
+	return 0;
+
+    sql = "SELECT ST_Line_Interpolate_Point(?, 0.5)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return 0;
+
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_blob (stmt, 1, blob, blob_sz, free);
+    while (1)
+      {
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
+		  {
+		      const unsigned char *g_blob =
+			  (const unsigned char *) sqlite3_column_blob (stmt,
+								       0);
+		      int g_size = sqlite3_column_bytes (stmt, 0);
+		      if (label_get_xy (handle, g_blob, g_size, x, y))
+			  ok = 1;
+		  }
+	    }
+      }
+    sqlite3_finalize (stmt);
+    return ok;
+}
+
+static rl2GeometryPtr
+do_generalize_linestring (sqlite3 * handle, rl2LinestringPtr line,
+			  double generalize_factor)
+{
+/* simplifying a Linestring */
+    rl2GeometryPtr geom = NULL;
+    unsigned char *blob;
+    int blob_sz;
+    const char *sql;
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+
+    if (line == NULL)
+	return NULL;
+    if (line->points < 2)
+	return NULL;
+    if (!rl2_serialize_linestring (line, &blob, &blob_sz))
+	return NULL;
+
+    sql = "SELECT ST_Simplify(?, ?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return NULL;
+
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_blob (stmt, 1, blob, blob_sz, free);
+    sqlite3_bind_double (stmt, 2, generalize_factor);
+    while (1)
+      {
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
+		  {
+		      const unsigned char *g_blob =
+			  (const unsigned char *) sqlite3_column_blob (stmt,
+								       0);
+		      int g_blob_sz = sqlite3_column_bytes (stmt, 0);
+		      geom = rl2_geometry_from_blob (g_blob, g_blob_sz);
+		  }
+	    }
+      }
+    sqlite3_finalize (stmt);
+    return geom;
+}
+
+static rl2GeometryPtr
+do_generalize_ring (sqlite3 * handle, rl2RingPtr ring, double generalize_factor)
+{
+/* simplifying a Ring */
+    rl2GeometryPtr geom = NULL;
+    unsigned char *blob;
+    int blob_sz;
+    const char *sql;
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+
+    if (ring == NULL)
+	return NULL;
+    if (ring->points < 2)
+	return NULL;
+    if (!rl2_serialize_ring (ring, &blob, &blob_sz))
+	return NULL;
+
+    sql = "SELECT ST_SimplifyPreserveTopology(?, ?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return NULL;
+
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_blob (stmt, 1, blob, blob_sz, free);
+    sqlite3_bind_double (stmt, 2, generalize_factor);
+    while (1)
+      {
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
+		  {
+		      const unsigned char *g_blob =
+			  (const unsigned char *) sqlite3_column_blob (stmt,
+								       0);
+		      int g_blob_sz = sqlite3_column_bytes (stmt, 0);
+		      geom = rl2_geometry_from_blob (g_blob, g_blob_sz);
+		  }
+	    }
+      }
+    sqlite3_finalize (stmt);
+    return geom;
+}
+
+static int
+check_valid_line (rl2LinestringPtr line)
+{
+/* testing for a valid linestring */
+    int iv;
+    int pts = 0;
+    double x;
+    double y;
+    double x0;
+    double y0;
+
+    if (line == NULL)
+	return 0;
+    if (line->points < 2)
+	return 0;
+    rl2GetPoint (line->coords, 0, &x0, &y0);
+    for (iv = 1; iv < line->points; iv++)
+      {
+	  rl2GetPoint (line->coords, iv, &x, &y);
+	  if (x != x0 || y != y0)
+	    {
+		pts++;
+		break;
+	    }
+      }
+    if (pts == 0)
+	return 0;
+    return 1;
+}
+
+static rl2GeometryPtr
+do_offset_linestring (sqlite3 * handle, rl2LinestringPtr line,
+		      double perpendicular_offset)
+{
+/* Offest Curve (from Linestring) */
+    rl2GeometryPtr geom = NULL;
+    unsigned char *blob;
+    int blob_sz;
+    const char *sql;
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+
+    if (!check_valid_line (line))
+	return NULL;
+    if (!rl2_serialize_linestring (line, &blob, &blob_sz))
+	return NULL;
+
+    sql = "SELECT ST_OffsetCurve(?, ?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return NULL;
+
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_blob (stmt, 1, blob, blob_sz, free);
+    sqlite3_bind_double (stmt, 2, perpendicular_offset);
+    while (1)
+      {
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
+		  {
+		      const unsigned char *g_blob =
+			  (const unsigned char *) sqlite3_column_blob (stmt,
+								       0);
+		      int g_blob_sz = sqlite3_column_bytes (stmt, 0);
+		      geom = rl2_geometry_from_blob (g_blob, g_blob_sz);
+		  }
+	    }
+      }
+    sqlite3_finalize (stmt);
+    return geom;
+}
+
+static int
+check_valid_ring (rl2RingPtr ring)
+{
+/* testing for a valid ring */
+    int iv;
+    int pts = 0;
+    int last;
+    double x;
+    double y;
+    double x0;
+    double y0;
+    double x1;
+    double y1;
+
+    if (ring == NULL)
+	return 0;
+    if (ring->points < 4)
+	return 0;
+    rl2GetPoint (ring->coords, 0, &x0, &y0);
+    for (iv = 1; iv < ring->points; iv++)
+      {
+	  rl2GetPoint (ring->coords, iv, &x, &y);
+	  if (pts == 0)
+	    {
+		if (x != x0 || y != y0)
+		  {
+		      pts++;
+		      x1 = x;
+		      y1 = y;
+		  }
+	    }
+	  else
+	    {
+		if ((x != x0 || y != y0) && (x != x1 || y != y1))
+		  {
+		      pts++;
+		      break;
+		  }
+	    }
+      }
+    last = ring->points - 1;
+    rl2GetPoint (ring->coords, last, &x1, &y1);
+    if (pts == 2 && x0 == x1 && y0 == y1)
+	return 1;
+    return 0;
+}
+
+static rl2GeometryPtr
+do_buffered_ring (sqlite3 * handle, rl2RingPtr ring,
+		  double perpendicular_offset)
+{
+/* Buffer (from Ring) */
+    rl2GeometryPtr geom = NULL;
+    unsigned char *blob;
+    int blob_sz;
+    const char *sql;
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+
+    if (!check_valid_ring (ring))
+	return NULL;
+    if (!rl2_serialize_ring (ring, &blob, &blob_sz))
+	return NULL;
+
+    sql = "SELECT ST_Buffer(?, ?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return NULL;
+
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_blob (stmt, 1, blob, blob_sz, free);
+    sqlite3_bind_double (stmt, 2, perpendicular_offset);
+    while (1)
+      {
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
+		  {
+		      const unsigned char *g_blob =
+			  (const unsigned char *) sqlite3_column_blob (stmt,
+								       0);
+		      int g_blob_sz = sqlite3_column_bytes (stmt, 0);
+		      geom = rl2_geometry_from_blob (g_blob, g_blob_sz);
+		  }
+	    }
+      }
+    sqlite3_finalize (stmt);
+    return geom;
+}
+
+static void
+create_line_array_from_linestring (sqlite3 * handle, rl2LinestringPtr line,
+				   double perpendicular_offset, int *points,
+				   double **x_array, double **y_array,
+				   int generalize_line,
+				   double generalize_factor, int height,
+				   double minx, double miny, double x_res,
+				   double y_res)
+{
+/* creating the X and Y arrays required by rl2_graph_draw_warped_text() */
+    rl2GeometryPtr geom = NULL;
+    rl2GeometryPtr geom2 = NULL;
+    rl2LinestringPtr aux_line;
+    rl2LinestringPtr in_line;
+    double *xx = NULL;
+    double *yy = NULL;
+    int iv;
+    double x;
+    double y;
+
+    *points = 0;
+    *x_array = NULL;
+    *y_array = NULL;
+    if (line == NULL)
+	goto error;
+
+    aux_line = rl2_linestring_to_image (line, height, minx, miny, x_res, y_res);
+    if (aux_line == NULL)
+	goto error;
+    in_line = aux_line;
+    if (generalize_line)
+      {
+	  geom = do_generalize_linestring (handle, in_line, generalize_factor);
+	  if (geom == NULL)
+	      goto error;
+	  in_line = geom->first_linestring;
+	  if (in_line == NULL)
+	      goto error;
+      }
+    if (perpendicular_offset != 0.0)
+      {
+	  geom2 = do_offset_linestring (handle, in_line, perpendicular_offset);
+	  if (geom2 == NULL)
+	      goto error;
+	  in_line = geom2->first_linestring;
+	  if (in_line == NULL)
+	      goto error;
+      }
+
+/* allocating the X and Y arrays */
+    if (in_line->points < 2)
+	goto error;
+    xx = malloc (sizeof (double) * in_line->points);
+    yy = malloc (sizeof (double) * in_line->points);
+    if (xx == NULL || yy == NULL)
+      {
+	  if (xx != NULL)
+	      free (xx);
+	  if (yy != NULL)
+	      free (yy);
+	  goto error;
+      }
+    for (iv = 0; iv < in_line->points; iv++)
+      {
+	  /* populating the X and Y arrays */
+	  rl2GetPoint (in_line->coords, iv, &x, &y);
+	  *(xx + iv) = x;
+	  *(yy + iv) = y;
+      }
+    *points = in_line->points;
+    *x_array = xx;
+    *y_array = yy;
+
+  error:
+    if (aux_line)
+	rl2DestroyLinestring (aux_line);
+    if (geom)
+	rl2_destroy_geometry (geom);
+    if (geom2)
+	rl2_destroy_geometry (geom2);
+}
+
+static void
+create_line_array_from_ring (sqlite3 * handle, rl2RingPtr ring,
+			     double perpendicular_offset, int *points,
+			     double **x_array, double **y_array,
+			     int generalize_line, double generalize_factor,
+			     int height, double minx, double miny, double x_res,
+			     double y_res)
+{
+/* creating the X and Y arrays required by rl2_graph_draw_warped_text() */
+    rl2GeometryPtr geom = NULL;
+    rl2GeometryPtr geom2 = NULL;
+    rl2PolygonPtr pg;
+    rl2RingPtr aux_ring;
+    rl2RingPtr in_ring;
+    double *xx = NULL;
+    double *yy = NULL;
+    int iv;
+    double x;
+    double y;
+
+    *points = 0;
+    *x_array = NULL;
+    *y_array = NULL;
+    if (ring == NULL)
+	goto error;
+
+    aux_ring = rl2_ring_to_image (ring, height, minx, miny, x_res, y_res);
+    if (aux_ring == NULL)
+	goto error;
+    in_ring = aux_ring;
+    if (generalize_line)
+      {
+	  geom = do_generalize_ring (handle, in_ring, generalize_factor);
+	  if (geom == NULL)
+	      goto error;
+	  pg = geom->first_polygon;
+	  if (pg == NULL)
+	      goto error;
+	  in_ring = pg->exterior;
+	  if (in_ring == NULL)
+	      goto error;
+      }
+    if (perpendicular_offset != 0.0)
+      {
+	  geom2 = do_buffered_ring (handle, in_ring, perpendicular_offset);
+	  if (geom2 == NULL)
+	      goto error;
+	  pg = geom2->first_polygon;
+	  if (pg == NULL)
+	      goto error;
+	  in_ring = pg->exterior;
+	  if (in_ring == NULL)
+	      goto error;
+      }
+
+/* allocating the X and Y arrays */
+    if (in_ring->points < 2)
+	goto error;
+    xx = malloc (sizeof (double) * in_ring->points);
+    yy = malloc (sizeof (double) * in_ring->points);
+    if (xx == NULL || yy == NULL)
+      {
+	  if (xx != NULL)
+	      free (xx);
+	  if (yy != NULL)
+	      free (yy);
+	  goto error;
+      }
+    for (iv = 0; iv < in_ring->points; iv++)
+      {
+	  /* populating the X and Y arrays */
+	  rl2GetPoint (in_ring->coords, iv, &x, &y);
+	  *(xx + iv) = x;
+	  *(yy + iv) = y;
+      }
+    *points = in_ring->points;
+    *x_array = xx;
+    *y_array = yy;
+
+  error:
+    if (aux_ring)
+	rl2DestroyRing (aux_ring);
+    if (geom)
+	rl2_destroy_geometry (geom);
+    if (geom2)
+	rl2_destroy_geometry (geom2);
+}
+
+static void
+draw_labels (rl2GraphicsContextPtr ctx, sqlite3 * handle,
+	     const void *priv_data, rl2PrivTextSymbolizerPtr sym, int height,
+	     double minx, double miny, double maxx, double maxy, double x_res,
+	     double y_res, rl2GeometryPtr geom, rl2PrivVariantValuePtr value)
+{
+/* drawing TextLabels */
+    rl2GraphicsFontPtr font = NULL;
+    char *dummy = NULL;
+    const char *label = NULL;
+    int font_style;
+    int font_weight;
+    double opacity;
+    unsigned char norm_opacity;
+    rl2PointPtr point;
+    rl2LinestringPtr line;
+    rl2PolygonPtr polyg;
+    double rotation = 0.0;
+    double anchor_point_x = 0.0;
+    double anchor_point_y = 0.0;
+    double displacement_x = 0.0;
+    double displacement_y = 0.0;
+    double perpendicular_offset = 0.0;
+    int is_repeated = 0;
+    double initial_gap = 0.0;
+    double gap = 0.0;
+    int is_aligned = 0;
+    int generalize_line = 0;
+    int i;
+
+/* preparing the Text */
+    if (value->sqlite3_type == SQLITE_INTEGER)
+      {
+	  dummy = sqlite3_malloc (1024);
+#if defined(_WIN32) && !defined(__MINGW32__)
+	  sprintf (dummy, "%I64d", value->int_value);
+#else
+	  sprintf (dummy, "%lld", value->int_value);
+#endif
+	  label = dummy;
+      }
+    if (value->sqlite3_type == SQLITE_FLOAT)
+      {
+	  dummy = sqlite3_mprintf ("1.2f", value->dbl_value);
+	  label = dummy;
+      }
+    if (value->sqlite3_type == SQLITE_TEXT)
+	label = (const char *) (value->text_value);
+    if (label == NULL)
+	return;
+
+/* setting up the Font */
+    switch (sym->font_style)
+      {
+      case RL2_FONT_STYLE_ITALIC:
+	  font_style = RL2_FONTSTYLE_ITALIC;
+	  break;
+      case RL2_FONT_STYLE_OBLIQUE:
+	  font_style = RL2_FONTSTYLE_OBLIQUE;
+	  break;
+      case RL2_FONT_STYLE_NORMAL:
+      default:
+	  font_style = RL2_FONTSTYLE_NORMAL;
+	  break;
+      };
+    switch (sym->font_weight)
+      {
+      case RL2_FONT_WEIGHT_BOLD:
+	  font_weight = RL2_FONTWEIGHT_BOLD;
+	  break;
+      case RL2_FONT_WEIGHT_NORMAL:
+      default:
+	  font_weight = RL2_FONTWEIGHT_NORMAL;
+	  break;
+      };
+    for (i = 0; i < RL2_MAX_FONT_FAMILIES; i++)
+      {
+	  const char *facename = sym->font_families[i];
+	  if (facename != NULL)
+	      font =
+		  rl2_search_TrueType_font (handle, priv_data, facename,
+					    sym->font_size);
+	  if (font != NULL)
+	      break;
+      }
+    if (font == NULL)
+      {
+	  /* defaulting to a toy font */
+	  fprintf (stderr, "default toy font\n");
+	  font =
+	      rl2_graph_create_toy_font (NULL, sym->font_size, font_style,
+					 font_weight);
+      }
+    if (font == NULL)
+	goto stop;
+    if (sym->fill != NULL)
+      {
+	  if (sym->fill->opacity <= 0.0)
+	      norm_opacity = 0;
+	  else if (sym->fill->opacity >= 1.0)
+	      norm_opacity = 255;
+	  else
+	    {
+		opacity = 255.0 * sym->fill->opacity;
+		if (opacity <= 0.0)
+		    norm_opacity = 0;
+		else if (opacity >= 255.0)
+		    norm_opacity = 255;
+		else
+		    norm_opacity = opacity;
+	    }
+	  rl2_graph_font_set_color (font, sym->fill->red, sym->fill->green,
+				    sym->fill->blue, norm_opacity);
+      }
+    if (sym->halo != NULL)
+      {
+	  if (sym->halo->fill->opacity <= 0.0)
+	      norm_opacity = 0;
+	  else if (sym->halo->fill->opacity >= 1.0)
+	      norm_opacity = 255;
+	  else
+	    {
+		opacity = 255.0 * sym->halo->fill->opacity;
+		if (opacity <= 0.0)
+		    norm_opacity = 0;
+		else if (opacity >= 255.0)
+		    norm_opacity = 255;
+		else
+		    norm_opacity = opacity;
+	    }
+	  rl2_graph_font_set_halo (font, sym->halo->radius,
+				   sym->halo->fill->red,
+				   sym->halo->fill->green,
+				   sym->halo->fill->blue, norm_opacity);
+      }
+    rl2_graph_set_font (ctx, font);
+
+    if (sym->label_placement_type == RL2_LABEL_PLACEMENT_POINT)
+      {
+	  /* retrieving eventual Point Placement arguments */
+	  rl2PrivPointPlacementPtr ptpl =
+	      (rl2PrivPointPlacementPtr) (sym->label_placement);
+	  if (ptpl != NULL)
+	    {
+		anchor_point_x = ptpl->anchor_point_x;
+		anchor_point_y = ptpl->anchor_point_y;
+		displacement_x = ptpl->displacement_x;
+		displacement_y = ptpl->displacement_y;
+		rotation = ptpl->rotation;
+	    }
+      }
+    else if (sym->label_placement_type == RL2_LABEL_PLACEMENT_LINE)
+      {
+	  /* retrieving eventual Lineo Placement arguments */
+	  rl2PrivLinePlacementPtr lnpl =
+	      (rl2PrivLinePlacementPtr) (sym->label_placement);
+	  if (lnpl != NULL)
+	    {
+		perpendicular_offset = lnpl->perpendicular_offset;
+		is_repeated = lnpl->is_repeated;
+		initial_gap = lnpl->initial_gap;
+		gap = lnpl->gap;
+		is_aligned = lnpl->is_aligned;
+		generalize_line = lnpl->generalize_line;
+	    }
+      }
+
+    if (sym->label_placement_type == RL2_LABEL_PLACEMENT_POINT)
+      {
+	  /* POINT PLACEMENT */
+	  rl2Point pt;
+	  double cx;
+	  double cy;
+	  double x;
+	  double y;
+
+	  polyg = geom->first_polygon;
+	  while (polyg)
+	    {
+		/* drawing a POLYGON-based text label */
+		if (!label_get_centroid (handle, polyg, &cx, &cy))
+		  {
+		      polyg = polyg->next;
+		      continue;
+		  }
+		pt.x = cx;
+		pt.y = cy;
+		if (point_bbox_matches (&pt, minx, miny, maxx, maxy))
+		  {
+		      x = (cx - minx) / x_res;
+		      y = (double) height - ((cy - miny) / y_res);
+		      rl2_graph_draw_text (ctx, label, x + displacement_x,
+					   y - displacement_y, rotation,
+					   anchor_point_x, anchor_point_y);
+		  }
+		polyg = polyg->next;
+	    }
+
+	  line = geom->first_linestring;
+	  while (line)
+	    {
+		/* drawing a LINESTRING-based text label */
+		label_get_midpoint (handle, line, &cx, &cy);
+		pt.x = cx;
+		pt.y = cy;
+		if (point_bbox_matches (&pt, minx, miny, maxx, maxy))
+		  {
+		      x = (cx - minx) / x_res;
+		      y = (double) height - ((cy - miny) / y_res);
+		      rl2_graph_draw_text (ctx, label, x + displacement_x,
+					   y - displacement_y, rotation,
+					   anchor_point_x, anchor_point_y);
+		  }
+		line = line->next;
+	    }
+
+	  point = geom->first_point;
+	  while (point)
+	    {
+		/* drawing a POINT-based text label */
+		if (point_bbox_matches (point, minx, miny, maxx, maxy))
+		  {
+		      double x = (point->x - minx) / x_res;
+		      double y = (double) height - ((point->y - miny) / y_res);
+		      rl2_graph_draw_text (ctx, label, x + displacement_x,
+					   y - displacement_y, rotation,
+					   anchor_point_x, anchor_point_y);
+		  }
+		point = point->next;
+	    }
+
+      }
+    else if (sym->label_placement_type == RL2_LABEL_PLACEMENT_LINE)
+      {
+	  /* LINE PLACEMENT */
+	  rl2Point pt;
+	  int ib;
+	  double cx;
+	  double cy;
+	  double x;
+	  double y;
+	  double generalize_factor = 8.0;
+
+	  line = geom->first_linestring;
+	  while (line)
+	    {
+		/* drawing a LINESTRING-based text label */
+		if (!is_aligned)
+		  {
+		      /* horizontal label aligned to center point */
+		      label_get_midpoint (handle, line, &cx, &cy);
+		      pt.x = cx;
+		      pt.y = cy;
+		      if (point_bbox_matches (&pt, minx, miny, maxx, maxy))
+			{
+			    x = (cx - minx) / x_res;
+			    y = (double) height - ((cy - miny) / y_res);
+			    rl2_graph_draw_text (ctx, label, x, y, 0.0, 0.5,
+						 0.5);
+			}
+		  }
+		else
+		  {
+		      /* label is warped along the line */
+		      double *x_array = NULL;
+		      double *y_array = NULL;
+		      int points;
+		      if (linestring_bbox_matches
+			  (line, minx, miny, maxx, maxy))
+			{
+			    create_line_array_from_linestring (handle, line,
+							       perpendicular_offset,
+							       &points,
+							       &x_array,
+							       &y_array,
+							       generalize_line,
+							       generalize_factor,
+							       height, minx,
+							       miny, x_res,
+							       y_res);
+			    if (x_array != NULL && y_array != NULL)
+				rl2_graph_draw_warped_text (handle, ctx, label,
+							    points, x_array,
+							    y_array,
+							    initial_gap, gap,
+							    is_repeated);
+			    if (x_array)
+				free (x_array);
+			    if (y_array)
+				free (y_array);
+			}
+		  }
+		line = line->next;
+	    }
+
+	  polyg = geom->first_polygon;
+	  while (polyg)
+	    {
+		/* drawing a POLYGON-based text label */
+		rl2RingPtr ring = polyg->exterior;
+		/* exterior border */
+		if (ring_bbox_matches (ring, minx, miny, maxx, maxy))
+		  {
+		      if (!is_aligned)
+			{
+			    /* horizontal label aligned to Ring's center point */
+			    label_get_ring_midpoint (handle, ring, &cx, &cy);
+			    pt.x = cx;
+			    pt.y = cy;
+			    if (point_bbox_matches
+				(&pt, minx, miny, maxx, maxy))
+			      {
+				  x = (cx - minx) / x_res;
+				  y = (double) height - ((cy - miny) / y_res);
+				  rl2_graph_draw_text (ctx, label, x, y, 0.0,
+						       0.5, 0.5);
+			      }
+			}
+		      else
+			{
+			    /* label is warped along the Ring */
+			    double *x_array = NULL;
+			    double *y_array = NULL;
+			    int points;
+			    if (ring_bbox_matches
+				(ring, minx, miny, maxx, maxy))
+			      {
+				  create_line_array_from_ring (handle, ring,
+							       perpendicular_offset,
+							       &points,
+							       &x_array,
+							       &y_array,
+							       generalize_line,
+							       generalize_factor,
+							       height, minx,
+							       miny, x_res,
+							       y_res);
+				  if (x_array != NULL && y_array != NULL)
+				    {
+					rl2_graph_draw_warped_text (handle, ctx,
+								    label,
+								    points,
+								    x_array,
+								    y_array,
+								    initial_gap,
+								    gap,
+								    is_repeated);
+				    }
+				  if (x_array)
+				      free (x_array);
+				  if (y_array)
+				      free (y_array);
+			      }
+			}
+		  }
+		else
+		  {
+		      /* if the exterior ring is invisible we'll ignore all internal rings */
+		      polyg = polyg->next;
+		      continue;
+		  }
+		for (ib = 0; ib < polyg->num_interiors; ib++)
+		  {
+		      /* interior borders */
+		      ring = polyg->interiors + ib;
+		      if (ring_bbox_matches (ring, minx, miny, maxx, maxy))
+			{
+			    if (!is_aligned)
+			      {
+				  /* horizontal label aligned to Ring's center point */
+				  label_get_ring_midpoint (handle, ring, &cx,
+							   &cy);
+				  pt.x = cx;
+				  pt.y = cy;
+				  if (point_bbox_matches
+				      (&pt, minx, miny, maxx, maxy))
+				    {
+					x = (cx - minx) / x_res;
+					y = (double) height -
+					    ((cy - miny) / y_res);
+					rl2_graph_draw_text (ctx, label, x, y,
+							     0.0, 0.5, 0.5);
+				    }
+			      }
+			    else
+			      {
+				  /* label is warped along the Ring */
+				  double *x_array = NULL;
+				  double *y_array = NULL;
+				  int points;
+				  if (ring_bbox_matches
+				      (ring, minx, miny, maxx, maxy))
+				    {
+					create_line_array_from_ring (handle,
+								     ring,
+								     perpendicular_offset,
+								     &points,
+								     &x_array,
+								     &y_array,
+								     generalize_line,
+								     generalize_factor,
+								     height,
+								     minx, miny,
+								     x_res,
+								     y_res);
+					if (x_array != NULL && y_array != NULL)
+					    rl2_graph_draw_warped_text (handle,
+									ctx,
+									label,
+									points,
+									x_array,
+									y_array,
+									initial_gap,
+									gap,
+									is_repeated);
+					if (x_array)
+					    free (x_array);
+					if (y_array)
+					    free (y_array);
+				    }
+			      }
+			}
+		  }
+		polyg = polyg->next;
+	    }
+      }
+
+/* final cleanup - relasing resources */
+  stop:
+    if (dummy != NULL)
+	sqlite3_free (dummy);
+    if (font != NULL)
+	rl2_graph_destroy_font (font);
+}
+
+RL2_PRIVATE void
+rl2_draw_vector_feature (void *p_ctx, sqlite3 * handle, const void *priv_data,
+			 rl2VectorSymbolizerPtr symbolizer, int height,
+			 double minx, double miny, double maxx, double maxy,
+			 double x_res, double y_res, rl2GeometryPtr geom,
+			 rl2VariantArrayPtr variant)
+{
+/* drawing a vector feature on the current canvass */
+    rl2PrivVectorSymbolizerItemPtr item;
+    rl2GraphicsContextPtr ctx = (rl2GraphicsContextPtr) p_ctx;
+    rl2PrivVectorSymbolizerPtr sym = (rl2PrivVectorSymbolizerPtr) symbolizer;
+    rl2PrivVectorSymbolizerPtr default_symbolizer = NULL;
+
+    if (ctx == NULL || geom == NULL)
+	return;
+
+    if (sym == NULL)
+      {
+	  /* creating a default general purpose Symbolizer */
+
+	  default_symbolizer = rl2_create_default_vector_symbolizer ();
+	  item = rl2_create_default_point_symbolizer ();
+	  if (item->symbolizer_type == RL2_POINT_SYMBOLIZER
+	      && item->symbolizer != NULL)
+	    {
+		rl2PrivPointSymbolizerPtr s =
+		    (rl2PrivPointSymbolizerPtr) (item->symbolizer);
+		s->graphic = rl2_create_default_graphic ();
+		if (s->graphic != NULL)
+		  {
+		      s->graphic->size = 16.0;
+		      s->graphic->first = rl2_create_default_mark ();
+		      if (s->graphic->first != NULL)
+			{
+			    s->graphic->last = s->graphic->first;
+			    if (s->graphic->first->type == RL2_MARK_GRAPHIC
+				&& s->graphic->first->item != NULL)
+			      {
+				  rl2PrivMarkPtr mark =
+				      (rl2PrivMarkPtr) (s->graphic->
+							first->item);
+				  mark->well_known_type =
+				      RL2_GRAPHIC_MARK_SQUARE;
+				  mark->fill = rl2_create_default_fill ();
+				  mark->stroke = rl2_create_default_stroke ();
+			      }
+			}
+		  }
+	    }
+	  if (default_symbolizer->first == NULL)
+	      default_symbolizer->first = item;
+	  if (default_symbolizer->last != NULL)
+	      default_symbolizer->last->next = item;
+	  default_symbolizer->last = item;
+	  item = rl2_create_default_line_symbolizer ();
+	  if (item->symbolizer_type == RL2_LINE_SYMBOLIZER
+	      && item->symbolizer != NULL)
+	    {
+		rl2PrivLineSymbolizerPtr s =
+		    (rl2PrivLineSymbolizerPtr) (item->symbolizer);
+		s->stroke = rl2_create_default_stroke ();
+	    }
+	  if (default_symbolizer->first == NULL)
+	      default_symbolizer->first = item;
+	  if (default_symbolizer->last != NULL)
+	      default_symbolizer->last->next = item;
+	  if (default_symbolizer->first == NULL)
+	      default_symbolizer->first = item;
+	  if (default_symbolizer->last != NULL)
+	      default_symbolizer->last->next = item;
+	  default_symbolizer->last = item;
+	  item = rl2_create_default_polygon_symbolizer ();
+	  if (item->symbolizer_type == RL2_POLYGON_SYMBOLIZER
+	      && item->symbolizer != NULL)
+	    {
+		rl2PrivPolygonSymbolizerPtr s =
+		    (rl2PrivPolygonSymbolizerPtr) (item->symbolizer);
+		s->fill = rl2_create_default_fill ();
+		s->stroke = rl2_create_default_stroke ();
+	    }
+	  if (default_symbolizer->first == NULL)
+	      default_symbolizer->first = item;
+	  if (default_symbolizer->last != NULL)
+	      default_symbolizer->last->next = item;
+	  default_symbolizer->last = item;
+	  item = rl2_create_default_text_symbolizer ();
+	  if (default_symbolizer->first == NULL)
+	      default_symbolizer->first = item;
+	  if (default_symbolizer->last != NULL)
+	      default_symbolizer->last->next = item;
+	  default_symbolizer->last = item;
+	  sym = default_symbolizer;
+      }
+
+/* we'll render all geometries first */
+    if (geom->first_polygon != NULL)
+	draw_polygons (ctx, handle, sym, height, minx, miny, maxx, maxy,
+		       x_res, y_res, geom);
+    if (geom->first_linestring != NULL)
+	draw_lines (ctx, handle, sym, height, minx, miny, maxx, maxy, x_res,
+		    y_res, geom);
+    if (geom->first_point != NULL)
+	draw_points (ctx, handle, sym, height, minx, miny, maxx, maxy, x_res,
+		     y_res, geom);
+
+    if (sym != NULL)
+      {
+	  /* then we'll render any eventual TextSymbolizer */
+	  item = sym->first;
+	  while (item != NULL)
+	    {
+		if (item->symbolizer_type == RL2_TEXT_SYMBOLIZER
+		    && item->symbolizer != NULL)
+		  {
+		      rl2PrivTextSymbolizerPtr text =
+			  (rl2PrivTextSymbolizerPtr) (item->symbolizer);
+		      if (text->label != NULL)
+			{
+			    int v;
+			    rl2PrivVariantArrayPtr var =
+				(rl2PrivVariantArrayPtr) variant;
+			    if (var != NULL)
+			      {
+				  for (v = 0; v < var->count; v++)
+				    {
+					rl2PrivVariantValuePtr val =
+					    *(var->array + v);
+					if (val == NULL)
+					    continue;
+					if (val->column_name == NULL)
+					    continue;
+					if (strcasecmp
+					    (text->label,
+					     val->column_name) != 0)
+					    continue;
+					draw_labels (ctx, handle, priv_data,
+						     text, height, minx, miny,
+						     maxx, maxy, x_res, y_res,
+						     geom, val);
+				    }
+			      }
+			}
+		  }
+		item = item->next;
+	    }
+      }
+
+    if (default_symbolizer != NULL)
+	rl2_destroy_vector_symbolizer (default_symbolizer);
+}
+
+RL2_PRIVATE int
+rl2_aux_default_image (unsigned int width, unsigned int height,
+		       unsigned char red, unsigned char green,
+		       unsigned char blue, int format, int transparent,
+		       int quality, unsigned char **ximage, int *ximage_sz)
+{
+/* creating a default image */
+    unsigned int x;
+    unsigned int y;
+    unsigned char *pixels = malloc (width * height * 3);
+    unsigned char *po = pixels;
+    unsigned char *mask = NULL;
+    unsigned char *pm;
+
+    *ximage = NULL;
+    *ximage_sz = 0;
+    if (pixels == NULL)
+	return 0;
+
+    mask = malloc (width * height);
+    if (mask == NULL)
+	goto error;
+    pm = mask;
+
+/* priming the image buffer to background color */
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		*po++ = red;
+		*po++ = green;
+		*po++ = blue;
+		if (mask != NULL)
+		    *pm++ = 0;
+	    }
+      }
+
+    if (format == RL2_OUTPUT_FORMAT_PNG)
+      {
+	  if (transparent)
+	    {
+		if (rl2_rgb_alpha_to_png
+		    (width, height, pixels, mask, ximage, ximage_sz,
+		     1.0) != RL2_OK)
+		    goto error;
+	    }
+	  else
+	    {
+		if (rl2_rgb_to_png (width, height, pixels, ximage, ximage_sz)
+		    != RL2_OK)
+		    goto error;
+	    }
+      }
+    else if (format == RL2_OUTPUT_FORMAT_JPEG)
+      {
+	  if (rl2_rgb_to_jpeg
+	      (width, height, pixels, quality, ximage, ximage_sz) != RL2_OK)
+	      goto error;
+      }
+    else if (format == RL2_OUTPUT_FORMAT_TIFF)
+      {
+	  if (rl2_rgb_to_tiff (width, height, pixels, ximage, ximage_sz) !=
+	      RL2_OK)
+	      goto error;
+      }
+    else
+	goto error;
+    free (pixels);
+    if (mask != NULL)
+	free (mask);
+    return 1;
+
+  error:
+    if (pixels != NULL)
+	free (pixels);
+    if (mask != NULL)
+	free (mask);
+    return 0;
+}
diff --git a/src/rl2charls.c b/src/rl2charls.c
new file mode 100644
index 0000000..ef553e3
--- /dev/null
+++ b/src/rl2charls.c
@@ -0,0 +1,472 @@
+/*
+
+ rl2charls -- CharLS related functions
+
+ version 0.1, 2014 September 7
+
+ Author: Sandro Furieri a.furieri at lqt.it
+
+ -----------------------------------------------------------------------------
+ 
+ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ 
+ The contents of this file are subject to the Mozilla Public License Version
+ 1.1 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+ 
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the
+License.
+
+The Original Code is the RasterLite2 library
+
+The Initial Developer of the Original Code is Alessandro Furieri
+ 
+Portions created by the Initial Developer are Copyright (C) 2008-2013
+the Initial Developer. All Rights Reserved.
+
+Alternatively, the contents of this file may be used under the terms of
+either the GNU General Public License Version 2 or later (the "GPL"), or
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+in which case the provisions of the GPL or the LGPL are applicable instead
+of those above. If you wish to allow use of your version of this file only
+under the terms of either the GPL or the LGPL, and not to allow others to
+use your version of this file under the terms of the MPL, indicate your
+decision by deleting the provisions above and replace them with the notice
+and other provisions required by the GPL or the LGPL. If you do not delete
+the provisions above, a recipient may use your version of this file under
+the terms of any one of the MPL, the GPL or the LGPL.
+ 
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "config.h"
+
+#ifdef LOADABLE_EXTENSION
+#include "rasterlite2/sqlite.h"
+#endif
+
+#include "rasterlite2/rasterlite2.h"
+#include "rasterlite2_private.h"
+
+#ifndef OMIT_CHARLS		/* only if CharLS is enabled */
+
+#ifdef __ANDROID__		/* Android specific */
+#include <interface.h>
+#else
+#include <CharLS/interface.h>
+#endif
+
+static int
+endianness ()
+{
+/* checking if target CPU is a little-endian one */
+    union cvt
+    {
+	unsigned char byte[4];
+	int int_value;
+    } convert;
+    convert.int_value = 1;
+    if (convert.byte[0] == 0)
+	return 0;
+    return 1;
+}
+
+static void
+export_u16 (unsigned char *p, unsigned short value)
+{
+/* stores a 16bit int into a BLOB respecting declared endianness */
+    int little_endian_arch = endianness ();
+    union cvt
+    {
+	unsigned char byte[2];
+	unsigned short int_value;
+    } convert;
+    convert.int_value = value;
+    if (little_endian_arch)
+      {
+	  /* Litte-Endian architecture [e.g. x86] */
+	  *(p + 0) = convert.byte[0];
+	  *(p + 1) = convert.byte[1];
+      }
+    else
+      {
+	  /* Big Endian architecture [e.g. PPC] */
+	  *(p + 1) = convert.byte[0];
+	  *(p + 0) = convert.byte[1];
+      }
+}
+
+static unsigned short
+import_u16 (const unsigned char *p)
+{
+/* fetches a 16bit uint from BLOB respecting declared endiannes */
+    int little_endian_arch = endianness ();
+    union cvt
+    {
+	unsigned char byte[2];
+	unsigned short int_value;
+    } convert;
+    if (little_endian_arch)
+      {
+	  /* Litte-Endian architecture [e.g. x86] */
+	  convert.byte[0] = *(p + 0);
+	  convert.byte[1] = *(p + 1);
+      }
+    else
+      {
+	  /* Big Endian architecture [e.g. PPC] */
+	  convert.byte[0] = *(p + 1);
+	  convert.byte[1] = *(p + 0);
+      }
+    return convert.int_value;
+}
+
+static void
+prepare_ilv_buffer_16 (unsigned short *out, unsigned short *in, int width,
+		       int height, int num_bands)
+{
+/* rearranging pixels by separate LINE components - UINT 16 */
+    int x;
+    int y;
+    int ib;
+    unsigned short *p_out = out;
+
+    for (y = 0; y < height; y++)
+      {
+	  for (ib = 0; ib < num_bands; ib++)
+	    {
+		unsigned short *p_in = in + ((y * width * num_bands) + ib);
+		for (x = 0; x < width; x++)
+		  {
+		      *p_out++ = *p_in;
+		      p_in += num_bands;
+		  }
+	    }
+      }
+}
+
+static void
+prepare_ilv_buffer_8 (unsigned char *out, unsigned char *in, int width,
+		      int height, int num_bands)
+{
+/* rearranging pixels by separate LINE components - UINT 8 */
+    int x;
+    int y;
+    int ib;
+    unsigned char *p_out = out;
+
+    for (y = 0; y < height; y++)
+      {
+	  for (ib = 0; ib < num_bands; ib++)
+	    {
+		unsigned char *p_in = in + ((y * width * num_bands) + ib);
+		for (x = 0; x < width; x++)
+		  {
+		      *p_out++ = *p_in;
+		      p_in += num_bands;
+		  }
+	    }
+      }
+}
+
+RL2_PRIVATE int
+rl2_data_to_charls (const unsigned char *pixels, unsigned int width,
+		    unsigned int height, unsigned char sample_type,
+		    unsigned char pixel_type, unsigned char num_bands,
+		    unsigned char **compr_data, int *compressed_size)
+{
+/* compressing a block of pixels as CharLS - strictly lossless */
+    size_t in_sz;
+    size_t out_sz;
+    size_t compr_sz;
+    void *in_buffer = NULL;
+    unsigned char *out_buffer = NULL;
+    int sample_sz = 1;
+    struct JlsParameters params;
+
+    if (sample_type == RL2_SAMPLE_UINT16)
+	sample_sz = 2;
+/* initializing CharLS params */
+    memset (&params, 0, sizeof (params));
+    params.width = width;
+    params.height = height;
+    if (sample_type == RL2_SAMPLE_UINT16)
+	params.bitspersample = 16;
+    else
+	params.bitspersample = 8;
+    params.bytesperline = width * num_bands * sample_sz;
+    params.components = num_bands;
+    params.allowedlossyerror = 0;
+    if (num_bands == 1)
+	params.ilv = ILV_NONE;
+    else
+	params.ilv = ILV_LINE;
+    params.colorTransform = 0;
+    params.outputBgr = 0;
+    params.custom.MAXVAL = 0;
+    params.custom.T1 = 0;
+    params.custom.T2 = 0;
+    params.custom.T3 = 0;
+    params.custom.RESET = 0;
+    params.jfif.Ver = 0;
+/* allocating and populating the uncompressed buffer */
+    in_sz = width * height * num_bands * sample_sz;
+    in_buffer = malloc (in_sz);
+    if (num_bands == 1)
+	memcpy (in_buffer, pixels, in_sz);
+    else
+      {
+	  if (sample_type == RL2_SAMPLE_UINT16)
+	      prepare_ilv_buffer_16 ((unsigned short *) in_buffer,
+				     (unsigned short *) pixels, width, height,
+				     num_bands);
+	  else
+	      prepare_ilv_buffer_8 ((unsigned char *) in_buffer,
+				    (unsigned char *) pixels, width, height,
+				    num_bands);
+      }
+/* pre-allocating the compressed buffer */
+    out_sz = width * height * num_bands * sample_sz;
+    out_buffer = malloc (out_sz + 9);
+
+    if (JpegLsEncode
+	(out_buffer + 9, out_sz, &compr_sz, in_buffer, in_sz, &params) != 0)
+	goto error;
+
+/* installing the CharLS micro-header */
+    *(out_buffer + 0) = RL2_CHARLS_START;
+    *(out_buffer + 1) = sample_type;
+    *(out_buffer + 2) = pixel_type;
+    *(out_buffer + 3) = num_bands;
+    export_u16 (out_buffer + 4, width);
+    export_u16 (out_buffer + 6, height);
+    *(out_buffer + 8) = RL2_CHARLS_END;
+
+    *compr_data = out_buffer;
+    *compressed_size = compr_sz + 9;
+    free (in_buffer);
+    return RL2_OK;
+
+  error:
+    if (in_buffer != NULL)
+	free (in_buffer);
+    if (out_buffer != NULL)
+	free (out_buffer);
+    return RL2_ERROR;
+}
+
+static void
+from_ilv_buffer_16 (unsigned short *out, unsigned short *in, int width,
+		    int height, int num_bands)
+{
+/* rearranging pixels from separate LINE components - UINT 16 */
+    int x;
+    int y;
+    int ib;
+    unsigned short *p_in = in;
+
+    for (y = 0; y < height; y++)
+      {
+	  for (ib = 0; ib < num_bands; ib++)
+	    {
+		unsigned short *p_out = out + ((y * width * num_bands) + ib);
+		for (x = 0; x < width; x++)
+		  {
+		      *p_out = *p_in++;
+		      p_out += num_bands;
+		  }
+	    }
+      }
+}
+
+static void
+from_ilv_buffer_8 (unsigned char *out, unsigned char *in, int width,
+		   int height, int num_bands)
+{
+/* rearranging pixels from separate LINE components - UINT 8 */
+    int x;
+    int y;
+    int ib;
+    unsigned char *p_in = in;
+
+    for (y = 0; y < height; y++)
+      {
+	  for (ib = 0; ib < num_bands; ib++)
+	    {
+		unsigned char *p_out = out + ((y * width * num_bands) + ib);
+		for (x = 0; x < width; x++)
+		  {
+		      *p_out = *p_in++;
+		      p_out += num_bands;
+		  }
+	    }
+      }
+}
+
+RL2_PRIVATE int
+rl2_decode_charls (const unsigned char *charls_buf, int charls_sz,
+		   unsigned int *width, unsigned int *height,
+		   unsigned char *sample_type, unsigned char *pixel_type,
+		   unsigned char *num_bands, unsigned char **pixels,
+		   int *pixels_sz)
+{
+/* decompressing a block of pixels from CharLS */
+    size_t out_sz;
+    void *out_buffer = NULL;
+    int sample_sz = 1;
+    struct JlsParameters params;
+
+/* checking the CharLS micro-header for validity */
+    if (charls_sz < 10)
+	return RL2_ERROR;
+    if (*(charls_buf + 0) == RL2_CHARLS_START
+	&& *(charls_buf + 8) == RL2_CHARLS_END)
+	;
+    else
+	return RL2_ERROR;
+
+/* retrieving SampleType, PixelType and NumBands */
+    *sample_type = RL2_SAMPLE_UNKNOWN;
+    *pixel_type = RL2_PIXEL_UNKNOWN;
+    *num_bands = 0;
+    *width = import_u16 (charls_buf + 4);
+    *height = import_u16 (charls_buf + 6);
+    if (*(charls_buf + 1) == RL2_SAMPLE_UINT8
+	&& *(charls_buf + 2) == RL2_PIXEL_GRAYSCALE && *(charls_buf + 3) == 1)
+      {
+	  /* GRAYSCALE 8 bits */
+	  *sample_type = RL2_SAMPLE_UINT8;
+	  *pixel_type = RL2_PIXEL_GRAYSCALE;
+	  *num_bands = 1;
+      }
+    if (*(charls_buf + 1) == RL2_SAMPLE_UINT8
+	&& *(charls_buf + 2) == RL2_PIXEL_DATAGRID && *(charls_buf + 3) == 1)
+      {
+	  /* DATAGRID 8 bits */
+	  *sample_type = RL2_SAMPLE_UINT8;
+	  *pixel_type = RL2_PIXEL_DATAGRID;
+	  *num_bands = 1;
+      }
+    if (*(charls_buf + 1) == RL2_SAMPLE_UINT16
+	&& *(charls_buf + 2) == RL2_PIXEL_DATAGRID && *(charls_buf + 3) == 1)
+      {
+	  /* GRAYSCALE 16 bits */
+	  *sample_type = RL2_SAMPLE_UINT16;
+	  *pixel_type = RL2_PIXEL_DATAGRID;
+	  *num_bands = 1;
+      }
+    if (*(charls_buf + 1) == RL2_SAMPLE_UINT8
+	&& *(charls_buf + 2) == RL2_PIXEL_RGB && *(charls_buf + 3) == 3)
+      {
+	  /* RGB 8 bits */
+	  *sample_type = RL2_SAMPLE_UINT8;
+	  *pixel_type = RL2_PIXEL_RGB;
+	  *num_bands = 3;
+      }
+    if (*(charls_buf + 1) == RL2_SAMPLE_UINT16
+	&& *(charls_buf + 2) == RL2_PIXEL_RGB && *(charls_buf + 3) == 3)
+      {
+	  /* RGB 16 bits */
+	  *sample_type = RL2_SAMPLE_UINT16;
+	  *pixel_type = RL2_PIXEL_RGB;
+	  *num_bands = 3;
+      }
+    if (*(charls_buf + 1) == RL2_SAMPLE_UINT8
+	&& *(charls_buf + 2) == RL2_PIXEL_MULTIBAND && *(charls_buf + 3) == 3)
+      {
+	  /* 3-bands 8 bits */
+	  *sample_type = RL2_SAMPLE_UINT8;
+	  *pixel_type = RL2_PIXEL_MULTIBAND;
+	  *num_bands = 3;
+      }
+    if (*(charls_buf + 1) == RL2_SAMPLE_UINT16
+	&& *(charls_buf + 2) == RL2_PIXEL_MULTIBAND && *(charls_buf + 3) == 3)
+      {
+	  /* 3-bands 16 bits */
+	  *sample_type = RL2_SAMPLE_UINT16;
+	  *pixel_type = RL2_PIXEL_MULTIBAND;
+	  *num_bands = 3;
+      }
+    if (*(charls_buf + 1) == RL2_SAMPLE_UINT8
+	&& *(charls_buf + 2) == RL2_PIXEL_MULTIBAND && *(charls_buf + 3) == 4)
+      {
+	  /* 4-bands 8 bits */
+	  *sample_type = RL2_SAMPLE_UINT8;
+	  *pixel_type = RL2_PIXEL_MULTIBAND;
+	  *num_bands = 4;
+      }
+    if (*(charls_buf + 1) == RL2_SAMPLE_UINT16
+	&& *(charls_buf + 2) == RL2_PIXEL_MULTIBAND && *(charls_buf + 3) == 4)
+      {
+	  /* 4-bands 16 bits */
+	  *sample_type = RL2_SAMPLE_UINT16;
+	  *pixel_type = RL2_PIXEL_MULTIBAND;
+	  *num_bands = 4;
+      }
+    if (*sample_type == RL2_SAMPLE_UNKNOWN || *pixel_type == RL2_PIXEL_UNKNOWN
+	|| *num_bands == 0)
+	goto error;
+
+    if (*sample_type == RL2_SAMPLE_UINT16)
+	sample_sz = 2;
+/* initializing CharLS params */
+    memset (&params, 0, sizeof (params));
+    params.width = *width;
+    params.height = *height;
+    if (*sample_type == RL2_SAMPLE_UINT16)
+	params.bitspersample = 16;
+    else
+	params.bitspersample = 8;
+    params.bytesperline = *width * *num_bands * sample_sz;
+    params.components = *num_bands;
+    params.allowedlossyerror = 0;
+    if (*num_bands == 1)
+	params.ilv = ILV_NONE;
+    else
+	params.ilv = ILV_LINE;
+    params.colorTransform = 0;
+    params.outputBgr = 0;
+    params.custom.MAXVAL = 0;
+    params.custom.T1 = 0;
+    params.custom.T2 = 0;
+    params.custom.T3 = 0;
+    params.custom.RESET = 0;
+/* pre-allocating the uncompressed buffer */
+    out_sz = *width * *height * *num_bands * sample_sz;
+    out_buffer = malloc (out_sz);
+
+    if (JpegLsDecode
+	(out_buffer, out_sz, charls_buf + 9, charls_sz - 9, &params) != 0)
+	goto error;
+
+    *pixels = malloc (out_sz);
+    *pixels_sz = out_sz;
+    if (*num_bands == 1)
+	memcpy (*pixels, out_buffer, out_sz);
+    else
+      {
+	  if (*sample_type == RL2_SAMPLE_UINT16)
+	      from_ilv_buffer_16 ((unsigned short *) (*pixels),
+				  (unsigned short *) out_buffer, *width,
+				  *height, *num_bands);
+	  else
+	      from_ilv_buffer_8 ((unsigned char *) (*pixels),
+				 (unsigned char *) out_buffer, *width,
+				 *height, *num_bands);
+      }
+    free (out_buffer);
+    return RL2_OK;
+
+  error:
+    if (out_buffer != NULL)
+	free (out_buffer);
+    return RL2_ERROR;
+}
+
+#endif /* end CharLS conditional */
diff --git a/src/rl2codec.c b/src/rl2codec.c
index a01f423..954ee21 100644
--- a/src/rl2codec.c
+++ b/src/rl2codec.c
@@ -20,7 +20,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -827,6 +827,10 @@ check_encode_self_consistency (unsigned char sample_type,
 	  switch (compression)
 	    {
 	    case RL2_COMPRESSION_NONE:
+	    case RL2_COMPRESSION_DEFLATE:
+	    case RL2_COMPRESSION_DEFLATE_NO:
+	    case RL2_COMPRESSION_LZMA:
+	    case RL2_COMPRESSION_LZMA_NO:
 	    case RL2_COMPRESSION_PNG:
 	    case RL2_COMPRESSION_CCITTFAX4:
 		break;
@@ -850,6 +854,10 @@ check_encode_self_consistency (unsigned char sample_type,
 	  switch (compression)
 	    {
 	    case RL2_COMPRESSION_NONE:
+	    case RL2_COMPRESSION_DEFLATE:
+	    case RL2_COMPRESSION_DEFLATE_NO:
+	    case RL2_COMPRESSION_LZMA:
+	    case RL2_COMPRESSION_LZMA_NO:
 	    case RL2_COMPRESSION_PNG:
 		break;
 	    default:
@@ -871,10 +879,17 @@ check_encode_self_consistency (unsigned char sample_type,
 	  switch (compression)
 	    {
 	    case RL2_COMPRESSION_NONE:
+	    case RL2_COMPRESSION_DEFLATE:
+	    case RL2_COMPRESSION_DEFLATE_NO:
+	    case RL2_COMPRESSION_LZMA:
+	    case RL2_COMPRESSION_LZMA_NO:
 	    case RL2_COMPRESSION_PNG:
 	    case RL2_COMPRESSION_JPEG:
 	    case RL2_COMPRESSION_LOSSY_WEBP:
 	    case RL2_COMPRESSION_LOSSLESS_WEBP:
+	    case RL2_COMPRESSION_CHARLS:
+	    case RL2_COMPRESSION_LOSSY_JP2:
+	    case RL2_COMPRESSION_LOSSLESS_JP2:
 		break;
 	    default:
 		return 0;
@@ -897,7 +912,13 @@ check_encode_self_consistency (unsigned char sample_type,
 		  {
 		  case RL2_COMPRESSION_NONE:
 		  case RL2_COMPRESSION_DEFLATE:
+		  case RL2_COMPRESSION_DEFLATE_NO:
 		  case RL2_COMPRESSION_LZMA:
+		  case RL2_COMPRESSION_LZMA_NO:
+		  case RL2_COMPRESSION_PNG:
+		  case RL2_COMPRESSION_CHARLS:
+		  case RL2_COMPRESSION_LOSSY_JP2:
+		  case RL2_COMPRESSION_LOSSLESS_JP2:
 		      break;
 		  default:
 		      return 0;
@@ -908,10 +929,17 @@ check_encode_self_consistency (unsigned char sample_type,
 		switch (compression)
 		  {
 		  case RL2_COMPRESSION_NONE:
+		  case RL2_COMPRESSION_DEFLATE:
+		  case RL2_COMPRESSION_DEFLATE_NO:
+		  case RL2_COMPRESSION_LZMA:
+		  case RL2_COMPRESSION_LZMA_NO:
 		  case RL2_COMPRESSION_PNG:
 		  case RL2_COMPRESSION_JPEG:
 		  case RL2_COMPRESSION_LOSSY_WEBP:
 		  case RL2_COMPRESSION_LOSSLESS_WEBP:
+		  case RL2_COMPRESSION_CHARLS:
+		  case RL2_COMPRESSION_LOSSY_JP2:
+		  case RL2_COMPRESSION_LOSSLESS_JP2:
 		      break;
 		  default:
 		      return 0;
@@ -929,15 +957,61 @@ check_encode_self_consistency (unsigned char sample_type,
 	    };
 	  if (num_samples < 2)
 	      return 0;
-	  switch (compression)
+	  if (num_samples == 3 || num_samples == 4)
 	    {
-	    case RL2_COMPRESSION_NONE:
-	    case RL2_COMPRESSION_DEFLATE:
-	    case RL2_COMPRESSION_LZMA:
-		break;
-	    default:
-		return 0;
-	    };
+		if (sample_type == RL2_SAMPLE_UINT16)
+		  {
+		      switch (compression)
+			{
+			case RL2_COMPRESSION_NONE:
+			case RL2_COMPRESSION_DEFLATE:
+			case RL2_COMPRESSION_DEFLATE_NO:
+			case RL2_COMPRESSION_LZMA:
+			case RL2_COMPRESSION_LZMA_NO:
+			case RL2_COMPRESSION_PNG:
+			case RL2_COMPRESSION_CHARLS:
+			case RL2_COMPRESSION_LOSSY_JP2:
+			case RL2_COMPRESSION_LOSSLESS_JP2:
+			    break;
+			default:
+			    return 0;
+			};
+		  }
+		else
+		  {
+		      switch (compression)
+			{
+			case RL2_COMPRESSION_NONE:
+			case RL2_COMPRESSION_DEFLATE:
+			case RL2_COMPRESSION_DEFLATE_NO:
+			case RL2_COMPRESSION_LZMA:
+			case RL2_COMPRESSION_LZMA_NO:
+			case RL2_COMPRESSION_PNG:
+			case RL2_COMPRESSION_LOSSY_WEBP:
+			case RL2_COMPRESSION_LOSSLESS_WEBP:
+			case RL2_COMPRESSION_CHARLS:
+			case RL2_COMPRESSION_LOSSY_JP2:
+			case RL2_COMPRESSION_LOSSLESS_JP2:
+			    break;
+			default:
+			    return 0;
+			};
+		  }
+	    }
+	  else
+	    {
+		switch (compression)
+		  {
+		  case RL2_COMPRESSION_NONE:
+		  case RL2_COMPRESSION_DEFLATE:
+		  case RL2_COMPRESSION_DEFLATE_NO:
+		  case RL2_COMPRESSION_LZMA:
+		  case RL2_COMPRESSION_LZMA_NO:
+		      break;
+		  default:
+		      return 0;
+		  };
+	    }
 	  break;
       case RL2_PIXEL_DATAGRID:
 	  switch (sample_type)
@@ -956,15 +1030,39 @@ check_encode_self_consistency (unsigned char sample_type,
 	    };
 	  if (num_samples != 1)
 	      return 0;
-	  switch (compression)
+	  if (sample_type == RL2_SAMPLE_UINT8
+	      || sample_type == RL2_SAMPLE_UINT16)
 	    {
-	    case RL2_COMPRESSION_NONE:
-	    case RL2_COMPRESSION_DEFLATE:
-	    case RL2_COMPRESSION_LZMA:
-		break;
-	    default:
-		return 0;
-	    };
+		switch (compression)
+		  {
+		  case RL2_COMPRESSION_NONE:
+		  case RL2_COMPRESSION_DEFLATE:
+		  case RL2_COMPRESSION_DEFLATE_NO:
+		  case RL2_COMPRESSION_LZMA:
+		  case RL2_COMPRESSION_LZMA_NO:
+		  case RL2_COMPRESSION_PNG:
+		  case RL2_COMPRESSION_CHARLS:
+		  case RL2_COMPRESSION_LOSSY_JP2:
+		  case RL2_COMPRESSION_LOSSLESS_JP2:
+		      break;
+		  default:
+		      return 0;
+		  };
+	    }
+	  else
+	    {
+		switch (compression)
+		  {
+		  case RL2_COMPRESSION_NONE:
+		  case RL2_COMPRESSION_DEFLATE:
+		  case RL2_COMPRESSION_DEFLATE_NO:
+		  case RL2_COMPRESSION_LZMA:
+		  case RL2_COMPRESSION_LZMA_NO:
+		      break;
+		  default:
+		      return 0;
+		  };
+	    }
 	  break;
       };
     return 1;
@@ -1819,7 +1917,7 @@ odd_even_rows (rl2PrivRasterPtr raster, int *odd_rows, int *row_stride_odd,
     int o_size;
     int e_size;
     unsigned int row;
-    int pix_size;
+    int pix_size = 1;
     int swap = 0;
     if (little_endian != endianArch ())
 	swap = 1;
@@ -1924,9 +2022,10 @@ odd_even_rows (rl2PrivRasterPtr raster, int *odd_rows, int *row_stride_odd,
 }
 
 RL2_DECLARE int
-rl2_raster_encode (rl2RasterPtr rst, int compression, unsigned char **blob_odd,
-		   int *blob_odd_sz, unsigned char **blob_even,
-		   int *blob_even_sz, int quality, int little_endian)
+rl2_raster_encode (rl2RasterPtr rst, int compression,
+		   unsigned char **blob_odd, int *blob_odd_sz,
+		   unsigned char **blob_even, int *blob_even_sz, int quality,
+		   int little_endian)
 {
 /* encoding a Raster into the internal RL2 binary format */
     rl2PrivRasterPtr raster = (rl2PrivRasterPtr) rst;
@@ -1945,7 +2044,7 @@ rl2_raster_encode (rl2RasterPtr rst, int compression, unsigned char **blob_odd,
     unsigned char *block_even = NULL;
     int block_even_size = 0;
     unsigned char *ptr;
-    int uncompressed;
+    int uncompressed = 0;
     int compressed;
     int uncompressed_mask = 0;
     int compressed_mask = 0;
@@ -1956,7 +2055,7 @@ rl2_raster_encode (rl2RasterPtr rst, int compression, unsigned char **blob_odd,
     unsigned char *save_mask = NULL;
     uLong crc;
     int endian_arch = endianArch ();
-
+    int delta_dist;
     *blob_odd = NULL;
     *blob_odd_sz = 0;
     *blob_even = NULL;
@@ -1968,17 +2067,68 @@ rl2_raster_encode (rl2RasterPtr rst, int compression, unsigned char **blob_odd,
 	(raster->sampleType, raster->pixelType, raster->nBands, compression))
 	return RL2_ERROR;
 
+    switch (raster->pixelType)
+      {
+      case RL2_PIXEL_RGB:
+	  switch (raster->sampleType)
+	    {
+	    case RL2_SAMPLE_UINT16:
+		delta_dist = 6;
+		break;
+	    default:
+		delta_dist = 3;
+		break;
+	    };
+	  break;
+      case RL2_PIXEL_MULTIBAND:
+	  switch (raster->sampleType)
+	    {
+	    case RL2_SAMPLE_UINT16:
+		delta_dist = raster->nBands * 2;
+		break;
+	    default:
+		delta_dist = raster->nBands;
+		break;
+	    };
+	  break;
+      case RL2_PIXEL_DATAGRID:
+	  switch (raster->sampleType)
+	    {
+	    case RL2_SAMPLE_INT16:
+	    case RL2_SAMPLE_UINT16:
+		delta_dist = 2;
+		break;
+	    case RL2_SAMPLE_INT32:
+	    case RL2_SAMPLE_UINT32:
+	    case RL2_SAMPLE_FLOAT:
+		delta_dist = 4;
+		break;
+	    case RL2_SAMPLE_DOUBLE:
+		delta_dist = 8;
+		break;
+	    default:
+		delta_dist = 1;
+		break;
+	    };
+	  break;
+      default:
+	  delta_dist = 1;
+	  break;
+      };
+
     if (compression == RL2_COMPRESSION_NONE
 	|| compression == RL2_COMPRESSION_DEFLATE
-	|| compression == RL2_COMPRESSION_LZMA)
+	|| compression == RL2_COMPRESSION_DEFLATE_NO
+	|| compression == RL2_COMPRESSION_LZMA
+	|| compression == RL2_COMPRESSION_LZMA_NO)
       {
 	  /* preparing the pixels buffers */
 	  if (raster->sampleType == RL2_SAMPLE_1_BIT)
 	    {
 		/* packing 1-BIT data */
 		if (!pack_1bit_rows
-		    (raster, raster->rasterBuffer, &row_stride_odd, &pixels_odd,
-		     &size_odd))
+		    (raster, raster->rasterBuffer, &row_stride_odd,
+		     &pixels_odd, &size_odd))
 		    return RL2_ERROR;
 		odd_rows = raster->height;
 	    }
@@ -2002,9 +2152,9 @@ rl2_raster_encode (rl2RasterPtr rst, int compression, unsigned char **blob_odd,
 	    {
 		/* Odd/Even raster */
 		if (!odd_even_rows
-		    (raster, &odd_rows, &row_stride_odd, &pixels_odd, &size_odd,
-		     &even_rows, &row_stride_even, &pixels_even, &size_even,
-		     little_endian))
+		    (raster, &odd_rows, &row_stride_odd, &pixels_odd,
+		     &size_odd, &even_rows, &row_stride_even, &pixels_even,
+		     &size_even, little_endian))
 		    return RL2_ERROR;
 	    }
       }
@@ -2020,16 +2170,27 @@ rl2_raster_encode (rl2RasterPtr rst, int compression, unsigned char **blob_odd,
 	    {
 		/* Odd/Even raster */
 		if (!odd_even_rows
-		    (raster, &odd_rows, &row_stride_odd, &pixels_odd, &size_odd,
-		     &even_rows, &row_stride_even, &pixels_even, &size_even,
-		     little_endian))
+		    (raster, &odd_rows, &row_stride_odd, &pixels_odd,
+		     &size_odd, &even_rows, &row_stride_even, &pixels_even,
+		     &size_even, little_endian))
 		    return RL2_ERROR;
 	    }
       }
+    else if (compression == RL2_COMPRESSION_CHARLS)
+      {
+	  /* Odd/Even raster */
+	  if (!odd_even_rows
+	      (raster, &odd_rows, &row_stride_odd, &pixels_odd, &size_odd,
+	       &even_rows, &row_stride_even, &pixels_even, &size_even,
+	       little_endian))
+	      return RL2_ERROR;
+      }
     else if (compression == RL2_COMPRESSION_JPEG
 	     || compression == RL2_COMPRESSION_LOSSY_WEBP
 	     || compression == RL2_COMPRESSION_LOSSLESS_WEBP
-	     || compression == RL2_COMPRESSION_CCITTFAX4)
+	     || compression == RL2_COMPRESSION_CCITTFAX4
+	     || compression == RL2_COMPRESSION_LOSSY_JP2
+	     || compression == RL2_COMPRESSION_LOSSLESS_JP2)
       {
 	  /* no special action is required */
       }
@@ -2059,7 +2220,53 @@ rl2_raster_encode (rl2RasterPtr rst, int compression, unsigned char **blob_odd,
       }
     else if (compression == RL2_COMPRESSION_DEFLATE)
       {
-	  /* compressing as ZIP [Deflate] */
+	  /* compressing as ZIP DeltaFilter [Deflate] */
+	  int ret;
+	  uLong zLen = size_odd - 1;
+	  unsigned char *zip_buf = malloc (zLen);
+	  if (zip_buf == NULL)
+	      goto error;
+	  if (rl2_delta_encode (pixels_odd, size_odd, delta_dist) != RL2_OK)
+	      goto error;
+	  ret =
+	      compress (zip_buf, &zLen, (const Bytef *) pixels_odd,
+			(uLong) size_odd);
+	  if (ret == Z_OK)
+	    {
+		/* ok, ZIP compression was successful */
+		uncompressed = size_odd;
+		compressed = (int) zLen;
+		compr_data = zip_buf;
+		to_clean1 = zip_buf;
+	    }
+	  else if (ret == Z_BUF_ERROR)
+	    {
+		/* ZIP compression actually causes inflation: saving uncompressed data */
+		if (rl2_delta_decode (pixels_odd, size_odd, delta_dist) !=
+		    RL2_OK)
+		    goto error;
+		uncompressed = size_odd;
+		compressed = size_odd;
+		compr_data = pixels_odd;
+		free (zip_buf);
+		zip_buf = NULL;
+	    }
+	  else
+	    {
+		/* compression error */
+		free (zip_buf);
+		goto error;
+	    }
+	  if (mask_pix == NULL)
+	      uncompressed_mask = 0;
+	  else
+	      uncompressed_mask = raster->width * raster->height;
+	  compressed_mask = mask_pix_size;
+	  compr_mask = mask_pix;
+      }
+    else if (compression == RL2_COMPRESSION_DEFLATE_NO)
+      {
+	  /* compressing as ZIP noDelta [Deflate] */
 	  int ret;
 	  uLong zLen = size_odd - 1;
 	  unsigned char *zip_buf = malloc (zLen);
@@ -2100,7 +2307,69 @@ rl2_raster_encode (rl2RasterPtr rst, int compression, unsigned char **blob_odd,
       }
     else if (compression == RL2_COMPRESSION_LZMA)
       {
-	  /* compressing as LZMA */
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
+	  /* compressing as LZMA DeltaFilter */
+	  lzma_options_lzma opt_lzma2;
+	  lzma_options_delta opt_delta;
+	  lzma_ret ret;
+	  lzma_filter filters[3];
+	  size_t out_pos = 0;
+	  size_t lzmaLen = size_odd - 1;
+	  unsigned char *lzma_buf = malloc (lzmaLen);
+	  if (lzma_buf == NULL)
+	      goto error;
+	  opt_delta.type = LZMA_DELTA_TYPE_BYTE;
+	  opt_delta.dist = delta_dist;
+	  lzma_lzma_preset (&opt_lzma2, LZMA_PRESET_DEFAULT);
+	  filters[0].id = LZMA_FILTER_DELTA;
+	  filters[0].options = &opt_delta;
+	  filters[1].id = LZMA_FILTER_LZMA2;
+	  filters[1].options = &opt_lzma2;
+	  filters[2].id = LZMA_VLI_UNKNOWN;
+	  filters[2].options = NULL;
+	  ret =
+	      lzma_raw_buffer_encode (filters, NULL,
+				      (const uint8_t *) pixels_odd, size_odd,
+				      lzma_buf, &out_pos, lzmaLen);
+	  if (ret == LZMA_OK)
+	    {
+		/* ok, LZMA compression was successful */
+		uncompressed = size_odd;
+		compressed = (int) out_pos;
+		compr_data = lzma_buf;
+		to_clean1 = lzma_buf;
+	    }
+	  else if (ret == LZMA_BUF_ERROR)
+	    {
+		/* LZMA compression actually causes inflation: saving uncompressed data */
+		uncompressed = size_odd;
+		compressed = size_odd;
+		compr_data = pixels_odd;
+		free (lzma_buf);
+		lzma_buf = NULL;
+	    }
+	  else
+	    {
+		/* compression error */
+		free (lzma_buf);
+		goto error;
+	    }
+	  if (mask_pix == NULL)
+	      uncompressed_mask = 0;
+	  else
+	      uncompressed_mask = raster->width * raster->height;
+	  compressed_mask = mask_pix_size;
+	  compr_mask = mask_pix;
+#else /* LZMA is disabled */
+	  fprintf (stderr,
+		   "librasterlite2 was built by disabling LZMA support\n");
+	  goto error;
+#endif /* end LZMA conditional */
+      }
+    else if (compression == RL2_COMPRESSION_LZMA_NO)
+      {
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
+	  /* compressing as LZMA noDelta */
 	  lzma_options_lzma opt_lzma2;
 	  lzma_ret ret;
 	  lzma_filter filters[2];
@@ -2147,6 +2416,11 @@ rl2_raster_encode (rl2RasterPtr rst, int compression, unsigned char **blob_odd,
 	      uncompressed_mask = raster->width * raster->height;
 	  compressed_mask = mask_pix_size;
 	  compr_mask = mask_pix;
+#else /* LZMA is disabled */
+	  fprintf (stderr,
+		   "librasterlite2 was built by disabling LZMA support\n");
+	  goto error;
+#endif /* end LZMA conditional */
       }
     else if (compression == RL2_COMPRESSION_JPEG)
       {
@@ -2170,6 +2444,7 @@ rl2_raster_encode (rl2RasterPtr rst, int compression, unsigned char **blob_odd,
       }
     else if (compression == RL2_COMPRESSION_LOSSLESS_WEBP)
       {
+#ifndef OMIT_WEBP		/* only if WebP is enabled */
 	  /* compressing as lossless WEBP */
 	  if (rl2_raster_to_lossless_webp (rst, &compr_data, &compressed) ==
 	      RL2_OK)
@@ -2187,12 +2462,18 @@ rl2_raster_encode (rl2RasterPtr rst, int compression, unsigned char **blob_odd,
 	      uncompressed_mask = raster->width * raster->height;
 	  compressed_mask = mask_pix_size;
 	  compr_mask = mask_pix;
+#else /* WebP is disabled */
+	  fprintf (stderr,
+		   "librasterlite2 was built by disabling WebP support\n");
+	  goto error;
+#endif /* end WebP conditional */
       }
     else if (compression == RL2_COMPRESSION_LOSSY_WEBP)
       {
+#ifndef OMIT_WEBP		/* only if WebP is enabled */
 	  /* compressing as lossy WEBP */
-	  if (rl2_raster_to_lossy_webp (rst, &compr_data, &compressed, quality)
-	      == RL2_OK)
+	  if (rl2_raster_to_lossy_webp
+	      (rst, &compr_data, &compressed, quality) == RL2_OK)
 	    {
 		/* ok, lossy WEBP compression was successful */
 		uncompressed = raster->width * raster->height * raster->nBands;
@@ -2207,6 +2488,11 @@ rl2_raster_encode (rl2RasterPtr rst, int compression, unsigned char **blob_odd,
 	      uncompressed_mask = raster->width * raster->height;
 	  compressed_mask = mask_pix_size;
 	  compr_mask = mask_pix;
+#else /* WebP is disabled */
+	  fprintf (stderr,
+		   "librasterlite2 was built by disabling WebP support\n");
+	  goto error;
+#endif /* end WebP conditional */
       }
     else if (compression == RL2_COMPRESSION_PNG)
       {
@@ -2239,7 +2525,7 @@ rl2_raster_encode (rl2RasterPtr rst, int compression, unsigned char **blob_odd,
 		if (rl2_data_to_png
 		    (pixels_odd, NULL, 1.0, plt, raster->width,
 		     odd_rows, raster->sampleType, raster->pixelType,
-		     &compr_data, &compressed) == RL2_OK)
+		     raster->nBands, &compr_data, &compressed) == RL2_OK)
 		  {
 		      /* ok, PNG compression was successful */
 		      uncompressed = size_odd;
@@ -2255,6 +2541,33 @@ rl2_raster_encode (rl2RasterPtr rst, int compression, unsigned char **blob_odd,
 		    goto error;
 	    }
       }
+    else if (compression == RL2_COMPRESSION_CHARLS)
+      {
+#ifndef OMIT_CHARLS		/* only if CharLS is enabled */
+	  /* compressing as CHARLS */
+	  if (rl2_data_to_charls
+	      (pixels_odd, raster->width,
+	       odd_rows, raster->sampleType, raster->pixelType,
+	       raster->nBands, &compr_data, &compressed) == RL2_OK)
+	    {
+		/* ok, CHARLS compression was successful */
+		uncompressed = size_odd;
+		to_clean1 = compr_data;
+		if (mask_pix == NULL)
+		    uncompressed_mask = 0;
+		else
+		    uncompressed_mask = raster->width * raster->height;
+		compressed_mask = mask_pix_size;
+		compr_mask = mask_pix;
+	    }
+	  else
+	      goto error;
+#else /* CharLS is disabled */
+	  fprintf (stderr,
+		   "librasterlite2 was built by disabling CharLS support\n");
+	  goto error;
+#endif /* end CharLS conditional */
+      }
     else if (compression == RL2_COMPRESSION_CCITTFAX4)
       {
 	  /* compressing as TIFF FAX4 */
@@ -2275,6 +2588,58 @@ rl2_raster_encode (rl2RasterPtr rst, int compression, unsigned char **blob_odd,
 	  else
 	      goto error;
       }
+    else if (compression == RL2_COMPRESSION_LOSSLESS_JP2)
+      {
+#ifndef OMIT_OPENJPEG		/* only if OpenJpeg is enabled */
+	  /* compressing as lossless Jpeg2000 */
+	  if (rl2_raster_to_lossless_jpeg2000 (rst, &compr_data, &compressed)
+	      == RL2_OK)
+	    {
+		/* ok, lossless Jpeg2000 compression was successful */
+		uncompressed = raster->width * raster->height * raster->nBands;
+		to_clean1 = compr_data;
+	    }
+	  else
+	      goto error;
+	  odd_rows = raster->height;
+	  if (mask_pix == NULL)
+	      uncompressed_mask = 0;
+	  else
+	      uncompressed_mask = raster->width * raster->height;
+	  compressed_mask = mask_pix_size;
+	  compr_mask = mask_pix;
+#else /* OpenJpeg is disabled */
+	  fprintf (stderr,
+		   "librasterlite2 was built by disabling OpenJpeg support\n");
+	  goto error;
+#endif /* end OpenJpeg conditional */
+      }
+    else if (compression == RL2_COMPRESSION_LOSSY_JP2)
+      {
+#ifndef OMIT_OPENJPEG		/* only if OpenJpeg is enabled */
+	  /* compressing as lossy Jpeg2000 */
+	  if (rl2_raster_to_lossy_jpeg2000
+	      (rst, &compr_data, &compressed, quality) == RL2_OK)
+	    {
+		/* ok, lossy Jpeg2000 compression was successful */
+		uncompressed = raster->width * raster->height * raster->nBands;
+		to_clean1 = compr_data;
+	    }
+	  else
+	      goto error;
+	  odd_rows = raster->height;
+	  if (mask_pix == NULL)
+	      uncompressed_mask = 0;
+	  else
+	      uncompressed_mask = raster->width * raster->height;
+	  compressed_mask = mask_pix_size;
+	  compr_mask = mask_pix;
+#else /* OpenJpeg is disabled */
+	  fprintf (stderr,
+		   "librasterlite2 was built by disabling OpenJpeg support\n");
+	  goto error;
+#endif /* end OpenJpeg conditional */
+      }
 
 /* preparing the OddBlock */
     block_odd_size = 40 + compressed + compressed_mask;
@@ -2336,7 +2701,48 @@ rl2_raster_encode (rl2RasterPtr rst, int compression, unsigned char **blob_odd,
 	    }
 	  else if (compression == RL2_COMPRESSION_DEFLATE)
 	    {
-		/* compressing as ZIP [Deflate] */
+		/* compressing as ZIP DeltaFilter [Deflate] */
+		int ret;
+		uLong zLen = compressBound (size_even);
+		unsigned char *zip_buf = malloc (zLen);
+		if (zip_buf == NULL)
+		    goto error;
+		if (rl2_delta_encode (pixels_even, size_even, delta_dist) !=
+		    RL2_OK)
+		    goto error;
+		ret =
+		    compress (zip_buf, &zLen, (const Bytef *) pixels_even,
+			      (uLong) size_even);
+		if (ret == Z_OK)
+		  {
+		      /* ok, ZIP compression was successful */
+		      uncompressed = size_even;
+		      compressed = (int) zLen;
+		      compr_data = zip_buf;
+		      to_clean2 = zip_buf;
+		  }
+		else if (ret == Z_BUF_ERROR)
+		  {
+		      /* ZIP compression actually causes inflation: saving uncompressed data */
+		      if (rl2_delta_decode
+			  (pixels_even, size_even, delta_dist) != RL2_OK)
+			  goto error;
+		      uncompressed = size_even;
+		      compressed = size_even;
+		      compr_data = pixels_even;
+		      free (zip_buf);
+		      zip_buf = NULL;
+		  }
+		else
+		  {
+		      /* compression error */
+		      free (zip_buf);
+		      goto error;
+		  }
+	    }
+	  else if (compression == RL2_COMPRESSION_DEFLATE_NO)
+	    {
+		/* compressing as ZIP noDelta [Deflate] */
 		int ret;
 		uLong zLen = compressBound (size_even);
 		unsigned char *zip_buf = malloc (zLen);
@@ -2371,7 +2777,65 @@ rl2_raster_encode (rl2RasterPtr rst, int compression, unsigned char **blob_odd,
 	    }
 	  else if (compression == RL2_COMPRESSION_LZMA)
 	    {
-		/* compressing as LZMA */
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
+		/* compressing as LZMA DeltaFilter */
+		lzma_options_lzma opt_lzma2;
+		lzma_options_delta opt_delta;
+		lzma_ret ret;
+		lzma_filter filters[3];
+		size_t out_pos = 0;
+		size_t lzmaLen = size_even - 1;
+		unsigned char *lzma_buf = malloc (lzmaLen);
+		if (lzma_buf == NULL)
+		    goto error;
+		lzma_lzma_preset (&opt_lzma2, LZMA_PRESET_DEFAULT);
+		opt_delta.type = LZMA_DELTA_TYPE_BYTE;
+		opt_delta.dist = delta_dist;
+		lzma_lzma_preset (&opt_lzma2, LZMA_PRESET_DEFAULT);
+		filters[0].id = LZMA_FILTER_DELTA;
+		filters[0].options = &opt_delta;
+		filters[1].id = LZMA_FILTER_LZMA2;
+		filters[1].options = &opt_lzma2;
+		filters[2].id = LZMA_VLI_UNKNOWN;
+		filters[2].options = NULL;
+		ret =
+		    lzma_raw_buffer_encode (filters, NULL,
+					    (const uint8_t *) pixels_even,
+					    size_even, lzma_buf, &out_pos,
+					    lzmaLen);
+		if (ret == LZMA_OK)
+		  {
+		      /* ok, LZMA compression was successful */
+		      uncompressed = size_even;
+		      compressed = (int) out_pos;
+		      compr_data = lzma_buf;
+		      to_clean2 = lzma_buf;
+		  }
+		else if (ret == LZMA_BUF_ERROR)
+		  {
+		      /* LZMA compression actually causes inflation: saving uncompressed data */
+		      uncompressed = size_even;
+		      compressed = size_even;
+		      compr_data = pixels_even;
+		      free (lzma_buf);
+		      lzma_buf = NULL;
+		  }
+		else
+		  {
+		      /* compression error */
+		      free (lzma_buf);
+		      goto error;
+		  }
+#else /* LZMA is disabled */
+		fprintf (stderr,
+			 "librasterlite2 was built by disabling LZMA support\n");
+		goto error;
+#endif /* end LZMA conditional */
+	    }
+	  else if (compression == RL2_COMPRESSION_LZMA_NO)
+	    {
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
+		/* compressing as LZMA noDelta */
 		lzma_options_lzma opt_lzma2;
 		lzma_ret ret;
 		lzma_filter filters[2];
@@ -2381,6 +2845,7 @@ rl2_raster_encode (rl2RasterPtr rst, int compression, unsigned char **blob_odd,
 		if (lzma_buf == NULL)
 		    goto error;
 		lzma_lzma_preset (&opt_lzma2, LZMA_PRESET_DEFAULT);
+		lzma_lzma_preset (&opt_lzma2, LZMA_PRESET_DEFAULT);
 		filters[0].id = LZMA_FILTER_LZMA2;
 		filters[0].options = &opt_lzma2;
 		filters[1].id = LZMA_VLI_UNKNOWN;
@@ -2413,6 +2878,11 @@ rl2_raster_encode (rl2RasterPtr rst, int compression, unsigned char **blob_odd,
 		      free (lzma_buf);
 		      goto error;
 		  }
+#else /* LZMA is disabled */
+		fprintf (stderr,
+			 "librasterlite2 was built by disabling LZMA support\n");
+		goto error;
+#endif /* end LZMA conditional */
 	    }
 	  else if (compression == RL2_COMPRESSION_PNG)
 	    {
@@ -2428,7 +2898,7 @@ rl2_raster_encode (rl2RasterPtr rst, int compression, unsigned char **blob_odd,
 		      if (rl2_data_to_png
 			  (pixels_even, NULL, 1.0, plt, raster->width,
 			   even_rows, raster->sampleType, raster->pixelType,
-			   &compr_data, &compressed) == RL2_OK)
+			   raster->nBands, &compr_data, &compressed) == RL2_OK)
 			{
 			    /* ok, PNG compression was successful */
 			    uncompressed = size_even;
@@ -2438,6 +2908,27 @@ rl2_raster_encode (rl2RasterPtr rst, int compression, unsigned char **blob_odd,
 			  goto error;
 		  }
 	    }
+	  else if (compression == RL2_COMPRESSION_CHARLS)
+	    {
+#ifndef OMIT_CHARLS		/* only if CharLS is enabled */
+		/* compressing as CHARLS */
+		if (rl2_data_to_charls
+		    (pixels_even, raster->width,
+		     even_rows, raster->sampleType, raster->pixelType,
+		     raster->nBands, &compr_data, &compressed) == RL2_OK)
+		  {
+		      /* ok, CHARLS compression was successful */
+		      uncompressed = size_even;
+		      to_clean2 = compr_data;
+		  }
+		else
+		    goto error;
+#else /* CharLS is disabled */
+		fprintf (stderr,
+			 "librasterlite2 was built by disabling CharLS support\n");
+		goto error;
+#endif /* end CharLS conditional */
+	    }
 	  block_even_size = 32 + compressed;
 	  block_even = malloc (block_even_size);
 	  if (block_even == NULL)
@@ -2551,12 +3042,17 @@ check_blob_odd (const unsigned char *blob, int blob_sz, unsigned int *xwidth,
       {
       case RL2_COMPRESSION_NONE:
       case RL2_COMPRESSION_DEFLATE:
+      case RL2_COMPRESSION_DEFLATE_NO:
       case RL2_COMPRESSION_LZMA:
+      case RL2_COMPRESSION_LZMA_NO:
       case RL2_COMPRESSION_PNG:
       case RL2_COMPRESSION_JPEG:
       case RL2_COMPRESSION_LOSSY_WEBP:
       case RL2_COMPRESSION_LOSSLESS_WEBP:
       case RL2_COMPRESSION_CCITTFAX4:
+      case RL2_COMPRESSION_CHARLS:
+      case RL2_COMPRESSION_LOSSY_JP2:
+      case RL2_COMPRESSION_LOSSLESS_JP2:
 	  break;
       default:
 	  return 0;
@@ -2575,6 +3071,8 @@ check_blob_odd (const unsigned char *blob, int blob_sz, unsigned int *xwidth,
       case RL2_SAMPLE_UINT32:
       case RL2_SAMPLE_FLOAT:
       case RL2_SAMPLE_DOUBLE:
+      case RL2_COMPRESSION_LOSSY_JP2:
+      case RL2_COMPRESSION_LOSSLESS_JP2:
 	  break;
       default:
 	  return 0;
@@ -2636,10 +3134,11 @@ check_blob_odd (const unsigned char *blob, int blob_sz, unsigned int *xwidth,
 }
 
 static int
-check_blob_even (const unsigned char *blob, int blob_sz, unsigned short xwidth,
-		 unsigned short xheight, unsigned char xsample_type,
-		 unsigned char xpixel_type, unsigned char xnum_bands,
-		 unsigned char xcompression, uLong xcrc)
+check_blob_even (const unsigned char *blob, int blob_sz,
+		 unsigned short xwidth, unsigned short xheight,
+		 unsigned char xsample_type, unsigned char xpixel_type,
+		 unsigned char xnum_bands, unsigned char xcompression,
+		 uLong xcrc)
 {
 /* checking the EvenBlock for validity */
     const unsigned char *ptr;
@@ -2721,13 +3220,16 @@ check_scale (int scale, unsigned char sample_type, unsigned char compression,
     switch (scale)
       {
       case RL2_SCALE_1:
-	  if (sample_type == RL2_SAMPLE_1_BIT || sample_type == RL2_SAMPLE_2_BIT
+	  if (sample_type == RL2_SAMPLE_1_BIT
+	      || sample_type == RL2_SAMPLE_2_BIT
 	      || sample_type == RL2_SAMPLE_4_BIT)
 	      ;
 	  else if (compression == RL2_COMPRESSION_JPEG
 		   || compression == RL2_COMPRESSION_LOSSY_WEBP
 		   || compression == RL2_COMPRESSION_LOSSLESS_WEBP
-		   || compression == RL2_COMPRESSION_CCITTFAX4)
+		   || compression == RL2_COMPRESSION_CCITTFAX4
+		   || compression == RL2_COMPRESSION_LOSSY_JP2
+		   || compression == RL2_COMPRESSION_LOSSLESS_JP2)
 	    {
 		if (blob_even != NULL)
 		    return 0;
@@ -3695,9 +4197,10 @@ do_copy_int32 (int swap, const int *p_odd, const int *p_even, int *buf,
 }
 
 static void
-do_copy_uint32 (int swap, const unsigned int *p_odd, const unsigned int *p_even,
-		unsigned int *buf, unsigned short width,
-		unsigned short odd_rows, unsigned short even_rows)
+do_copy_uint32 (int swap, const unsigned int *p_odd,
+		const unsigned int *p_even, unsigned int *buf,
+		unsigned short width, unsigned short odd_rows,
+		unsigned short even_rows)
 {
 /* reassembling an UINT32 raster - scale 1:1 */
     int row;
@@ -4383,8 +4886,8 @@ RL2_DECLARE int
 rl2_is_valid_dbms_raster_tile (unsigned short level, unsigned int tile_width,
 			       unsigned int tile_height,
 			       const unsigned char *blob_odd, int blob_odd_sz,
-			       const unsigned char *blob_even, int blob_even_sz,
-			       unsigned char sample_type,
+			       const unsigned char *blob_even,
+			       int blob_even_sz, unsigned char sample_type,
 			       unsigned char pixel_type,
 			       unsigned char num_bands,
 			       unsigned char compression)
@@ -4420,46 +4923,10 @@ rl2_is_valid_dbms_raster_tile (unsigned short level, unsigned int tile_width,
     else
       {
 	  /* Pyramid-level tile */
-	  if (sample_type == RL2_SAMPLE_UINT8 && pixel_type == RL2_PIXEL_RGB
-	      && num_bands == 3)
-	    {
-		/* expecting an RGB/JPEG Pyramid tile 8bit */
-		if (xsample_type == RL2_SAMPLE_UINT8
-		    && xpixel_type == RL2_PIXEL_RGB && xnum_bands == 3
-		    && xcompression == RL2_COMPRESSION_JPEG)
-		    return RL2_OK;
-	    }
-	  if (sample_type == RL2_SAMPLE_UINT8
-	      && pixel_type == RL2_PIXEL_GRAYSCALE && num_bands == 1)
-	    {
-		/* expecting a GRAYSCALE/JPEG Pyramid tile 8bit */
-		if (xsample_type == RL2_SAMPLE_UINT8
-		    && xpixel_type == RL2_PIXEL_GRAYSCALE && xnum_bands == 1
-		    && xcompression == RL2_COMPRESSION_JPEG)
-		    return RL2_OK;
-	    }
-	  if (sample_type == RL2_SAMPLE_UINT16 && pixel_type == RL2_PIXEL_RGB
-	      && num_bands == 3)
-	    {
-		/* expecting an RGB/JPEG Pyramid tile 16bit */
-		if (xsample_type == RL2_SAMPLE_UINT16
-		    && xpixel_type == RL2_PIXEL_RGB && xnum_bands == 3
-		    && xcompression == RL2_COMPRESSION_DEFLATE)
-		    return RL2_OK;
-	    }
-	  if (sample_type == RL2_SAMPLE_UINT16
-	      && pixel_type == RL2_PIXEL_GRAYSCALE && num_bands == 1)
-	    {
-		/* expecting a GRAYSCALE/JPEG Pyramid tile 16bit */
-		if (xsample_type == RL2_SAMPLE_UINT16
-		    && xpixel_type == RL2_PIXEL_GRAYSCALE && xnum_bands == 1
-		    && xcompression == RL2_COMPRESSION_DEFLATE)
-		    return RL2_OK;
-	    }
-	  if (sample_type == RL2_SAMPLE_1_BIT
-	      && pixel_type == RL2_PIXEL_MONOCHROME && num_bands == 1)
+	  if ((sample_type == RL2_SAMPLE_1_BIT
+	       && pixel_type == RL2_PIXEL_MONOCHROME && num_bands == 1))
 	    {
-		/* expecting a GRAYSCALE/PNG Pyramid tile */
+		/* MONOCHROME: expecting a GRAYSCALE/PNG Pyramid tile */
 		if (xsample_type == RL2_SAMPLE_UINT8
 		    && xpixel_type == RL2_PIXEL_GRAYSCALE && xnum_bands == 1
 		    && xcompression == RL2_COMPRESSION_PNG)
@@ -4472,28 +4939,25 @@ rl2_is_valid_dbms_raster_tile (unsigned short level, unsigned int tile_width,
 	      (sample_type == RL2_SAMPLE_4_BIT
 	       && pixel_type == RL2_PIXEL_PALETTE && num_bands == 1))
 	    {
-		/* expecting an RGB/PNG Pyramid tile */
+		/* small-PALETTE: expecting an RGB/PNG Pyramid tile */
 		if (xsample_type == RL2_SAMPLE_UINT8
 		    && xpixel_type == RL2_PIXEL_RGB && xnum_bands == 3
 		    && xcompression == RL2_COMPRESSION_PNG)
 		    return RL2_OK;
 	    }
-	  if (sample_type == RL2_SAMPLE_UINT8 && pixel_type == RL2_PIXEL_PALETTE
-	      && num_bands == 1)
+	  if (sample_type == RL2_SAMPLE_UINT8
+	      && pixel_type == RL2_PIXEL_PALETTE && num_bands == 1)
 	    {
-		/* expecting an RGB/JPEG Pyramid tile */
+		/* PALETTE 8bits: expecting an RGB/PNG Pyramid tile */
 		if (xsample_type == RL2_SAMPLE_UINT8
 		    && xpixel_type == RL2_PIXEL_RGB && xnum_bands == 3
-		    && xcompression == RL2_COMPRESSION_JPEG)
+		    && xcompression == RL2_COMPRESSION_PNG)
 		    return RL2_OK;
 	    }
-	  if (sample_type == xsample_type && pixel_type == RL2_PIXEL_DATAGRID
-	      && num_bands == xnum_bands
-	      && xcompression == RL2_COMPRESSION_DEFLATE)
-	      return RL2_OK;
-	  if (sample_type == xsample_type && pixel_type == RL2_PIXEL_MULTIBAND
-	      && num_bands == xnum_bands
-	      && xcompression == RL2_COMPRESSION_DEFLATE)
+	  /* any other: expecting unchanged params */
+	  if (xsample_type == sample_type
+	      && xpixel_type == pixel_type && xnum_bands == num_bands
+	      && xcompression == compression)
 	      return RL2_OK;
       }
     return RL2_ERROR;
@@ -4510,8 +4974,8 @@ rl2_raster_decode (int scale, const unsigned char *blob_odd,
     rl2PalettePtr palette2 = NULL;
     unsigned int width;
     unsigned int height;
-    unsigned short mask_width;
-    unsigned short mask_height;
+    unsigned short mask_width = 0;
+    unsigned short mask_height = 0;
     unsigned char sample_type;
     unsigned char pixel_type;
     unsigned char num_bands;
@@ -4543,6 +5007,8 @@ rl2_raster_decode (int scale, const unsigned char *blob_odd,
     int swap;
     int endian;
     int endian_arch = endianArch ();
+    int delta_dist;
+
     if (blob_odd == NULL)
 	return NULL;
     if (!check_blob_odd
@@ -4552,13 +5018,62 @@ rl2_raster_decode (int scale, const unsigned char *blob_odd,
     if (blob_even != NULL)
       {
 	  if (!check_blob_even
-	      (blob_even, blob_even_sz, width, height, sample_type, pixel_type,
-	       num_bands, compression, crc))
+	      (blob_even, blob_even_sz, width, height, sample_type,
+	       pixel_type, num_bands, compression, crc))
 	      return NULL;
       }
     if (!check_scale (scale, sample_type, compression, blob_even))
 	return NULL;
 
+    switch (pixel_type)
+      {
+      case RL2_PIXEL_RGB:
+	  switch (sample_type)
+	    {
+	    case RL2_SAMPLE_UINT16:
+		delta_dist = 6;
+		break;
+	    default:
+		delta_dist = 3;
+		break;
+	    };
+	  break;
+      case RL2_PIXEL_MULTIBAND:
+	  switch (sample_type)
+	    {
+	    case RL2_SAMPLE_UINT16:
+		delta_dist = num_bands * 2;
+		break;
+	    default:
+		delta_dist = num_bands;
+		break;
+	    };
+	  break;
+      case RL2_PIXEL_DATAGRID:
+	  switch (sample_type)
+	    {
+	    case RL2_SAMPLE_INT16:
+	    case RL2_SAMPLE_UINT16:
+		delta_dist = 2;
+		break;
+	    case RL2_SAMPLE_INT32:
+	    case RL2_SAMPLE_UINT32:
+	    case RL2_SAMPLE_FLOAT:
+		delta_dist = 4;
+		break;
+	    case RL2_SAMPLE_DOUBLE:
+		delta_dist = 8;
+		break;
+	    default:
+		delta_dist = 1;
+		break;
+	    };
+	  break;
+      default:
+	  delta_dist = 1;
+	  break;
+      };
+
     endian = *(blob_odd + 2);
     num_bands = *(blob_odd + 6);
     ptr = blob_odd + 11;
@@ -4616,7 +5131,39 @@ rl2_raster_decode (int scale, const unsigned char *blob_odd,
     if (compression == RL2_COMPRESSION_DEFLATE
 	&& uncompressed_odd != compressed_odd)
       {
-	  /* decompressing from ZIP [Deflate] - ODD Block */
+	  /* decompressing from ZIP DeltaFilter [Deflate] - ODD Block */
+	  uLong refLen = uncompressed_odd;
+	  const Bytef *in = pixels_odd;
+	  odd_data = malloc (uncompressed_odd);
+	  if (odd_data == NULL)
+	      goto error;
+	  if (uncompress (odd_data, &refLen, in, compressed_odd) != Z_OK)
+	      goto error;
+	  if (rl2_delta_decode (odd_data, uncompressed_odd, delta_dist) !=
+	      RL2_OK)
+	      goto error;
+	  pixels_odd = odd_data;
+	  if (pixels_even != NULL && uncompressed_even != compressed_even)
+	    {
+		/* decompressing from ZIP DeltaFilter [Deflate] - EVEN Block */
+		uLong refLen = uncompressed_even;
+		const Bytef *in = pixels_even;
+		even_data = malloc (uncompressed_even);
+		if (even_data == NULL)
+		    goto error;
+		if (uncompress (even_data, &refLen, in, compressed_even) !=
+		    Z_OK)
+		    goto error;
+		if (rl2_delta_decode
+		    (even_data, uncompressed_even, delta_dist) != RL2_OK)
+		    goto error;
+		pixels_even = even_data;
+	    }
+      }
+    if (compression == RL2_COMPRESSION_DEFLATE_NO
+	&& uncompressed_odd != compressed_odd)
+      {
+	  /* decompressing from ZIP noDelta [Deflate] - ODD Block */
 	  uLong refLen = uncompressed_odd;
 	  const Bytef *in = pixels_odd;
 	  odd_data = malloc (uncompressed_odd);
@@ -4627,7 +5174,7 @@ rl2_raster_decode (int scale, const unsigned char *blob_odd,
 	  pixels_odd = odd_data;
 	  if (pixels_even != NULL && uncompressed_even != compressed_even)
 	    {
-		/* decompressing from ZIP [Deflate] - EVEN Block */
+		/* decompressing from ZIP noDelta [Deflate] - EVEN Block */
 		uLong refLen = uncompressed_even;
 		const Bytef *in = pixels_even;
 		even_data = malloc (uncompressed_even);
@@ -4642,7 +5189,71 @@ rl2_raster_decode (int scale, const unsigned char *blob_odd,
     if (compression == RL2_COMPRESSION_LZMA
 	&& uncompressed_odd != compressed_odd)
       {
-	  /* decompressing from LZMA - ODD Block */
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
+	  /* decompressing from LZMA DeltaFilter - ODD Block */
+	  lzma_options_lzma opt_lzma2;
+	  lzma_options_delta opt_delta;
+	  lzma_filter filters[3];
+	  size_t in_pos = 0;
+	  size_t out_pos = 0;
+	  size_t refLen = compressed_odd;
+	  odd_data = malloc (uncompressed_odd);
+	  if (odd_data == NULL)
+	      goto error;
+	  lzma_lzma_preset (&opt_lzma2, LZMA_PRESET_DEFAULT);
+	  opt_delta.type = LZMA_DELTA_TYPE_BYTE;
+	  opt_delta.dist = delta_dist;
+	  lzma_lzma_preset (&opt_lzma2, LZMA_PRESET_DEFAULT);
+	  filters[0].id = LZMA_FILTER_DELTA;
+	  filters[0].options = &opt_delta;
+	  filters[1].id = LZMA_FILTER_LZMA2;
+	  filters[1].options = &opt_lzma2;
+	  filters[2].id = LZMA_VLI_UNKNOWN;
+	  filters[2].options = NULL;
+	  if (lzma_raw_buffer_decode
+	      (filters, NULL, pixels_odd, &in_pos, refLen, odd_data, &out_pos,
+	       uncompressed_odd) != LZMA_OK)
+	      goto error;
+	  pixels_odd = odd_data;
+	  if (pixels_even != NULL && uncompressed_even != compressed_even)
+	    {
+		/* decompressing from LZMA DeltaFilter - EVEN Block */
+		lzma_options_lzma opt_lzma2;
+		lzma_options_delta opt_delta;
+		lzma_filter filters[3];
+		size_t in_pos = 0;
+		size_t out_pos = 0;
+		size_t refLen = compressed_even;
+		even_data = malloc (uncompressed_even);
+		if (even_data == NULL)
+		    goto error;
+		lzma_lzma_preset (&opt_lzma2, LZMA_PRESET_DEFAULT);
+		opt_delta.type = LZMA_DELTA_TYPE_BYTE;
+		opt_delta.dist = delta_dist;
+		lzma_lzma_preset (&opt_lzma2, LZMA_PRESET_DEFAULT);
+		filters[0].id = LZMA_FILTER_DELTA;
+		filters[0].options = &opt_delta;
+		filters[1].id = LZMA_FILTER_LZMA2;
+		filters[1].options = &opt_lzma2;
+		filters[2].id = LZMA_VLI_UNKNOWN;
+		filters[2].options = NULL;
+		if (lzma_raw_buffer_decode
+		    (filters, NULL, pixels_even, &in_pos, refLen, even_data,
+		     &out_pos, uncompressed_even) != LZMA_OK)
+		    goto error;
+		pixels_even = even_data;
+	    }
+#else /* LZMA is disabled */
+	  fprintf (stderr,
+		   "librasterlite2 was built by disabling LZMA support\n");
+	  goto error;
+#endif /* end LZMA conditional */
+      }
+    if (compression == RL2_COMPRESSION_LZMA_NO
+	&& uncompressed_odd != compressed_odd)
+      {
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
+	  /* decompressing from LZMA noDelta - ODD Block */
 	  lzma_options_lzma opt_lzma2;
 	  lzma_filter filters[2];
 	  size_t in_pos = 0;
@@ -4652,6 +5263,7 @@ rl2_raster_decode (int scale, const unsigned char *blob_odd,
 	  if (odd_data == NULL)
 	      goto error;
 	  lzma_lzma_preset (&opt_lzma2, LZMA_PRESET_DEFAULT);
+	  lzma_lzma_preset (&opt_lzma2, LZMA_PRESET_DEFAULT);
 	  filters[0].id = LZMA_FILTER_LZMA2;
 	  filters[0].options = &opt_lzma2;
 	  filters[1].id = LZMA_VLI_UNKNOWN;
@@ -4663,9 +5275,9 @@ rl2_raster_decode (int scale, const unsigned char *blob_odd,
 	  pixels_odd = odd_data;
 	  if (pixels_even != NULL && uncompressed_even != compressed_even)
 	    {
-		/* decompressing from LZMA - EVEN Block */
+		/* decompressing from LZMA noDelta - EVEN Block */
 		lzma_options_lzma opt_lzma2;
-		lzma_filter filters[2];
+		lzma_filter filters[3];
 		size_t in_pos = 0;
 		size_t out_pos = 0;
 		size_t refLen = compressed_even;
@@ -4673,6 +5285,7 @@ rl2_raster_decode (int scale, const unsigned char *blob_odd,
 		if (even_data == NULL)
 		    goto error;
 		lzma_lzma_preset (&opt_lzma2, LZMA_PRESET_DEFAULT);
+		lzma_lzma_preset (&opt_lzma2, LZMA_PRESET_DEFAULT);
 		filters[0].id = LZMA_FILTER_LZMA2;
 		filters[0].options = &opt_lzma2;
 		filters[1].id = LZMA_VLI_UNKNOWN;
@@ -4683,6 +5296,11 @@ rl2_raster_decode (int scale, const unsigned char *blob_odd,
 		    goto error;
 		pixels_even = even_data;
 	    }
+#else /* LZMA is disabled */
+	  fprintf (stderr,
+		   "librasterlite2 was built by disabling LZMA support\n");
+	  goto error;
+#endif /* end LZMA conditional */
       }
     if (compression == RL2_COMPRESSION_JPEG)
       {
@@ -4694,26 +5312,26 @@ rl2_raster_decode (int scale, const unsigned char *blob_odd,
 	    case RL2_SCALE_1:
 		ret =
 		    rl2_decode_jpeg_scaled (1, pixels_odd, compressed_odd,
-					    &width, &height, &pix_typ, &pixels,
-					    &pixels_sz);
+					    &width, &height, &pix_typ,
+					    &pixels, &pixels_sz);
 		break;
 	    case RL2_SCALE_2:
 		ret =
 		    rl2_decode_jpeg_scaled (2, pixels_odd, compressed_odd,
-					    &width, &height, &pix_typ, &pixels,
-					    &pixels_sz);
+					    &width, &height, &pix_typ,
+					    &pixels, &pixels_sz);
 		break;
 	    case RL2_SCALE_4:
 		ret =
 		    rl2_decode_jpeg_scaled (4, pixels_odd, compressed_odd,
-					    &width, &height, &pix_typ, &pixels,
-					    &pixels_sz);
+					    &width, &height, &pix_typ,
+					    &pixels, &pixels_sz);
 		break;
 	    case RL2_SCALE_8:
 		ret =
 		    rl2_decode_jpeg_scaled (8, pixels_odd, compressed_odd,
-					    &width, &height, &pix_typ, &pixels,
-					    &pixels_sz);
+					    &width, &height, &pix_typ,
+					    &pixels, &pixels_sz);
 		break;
 	    };
 	  if (ret != RL2_OK)
@@ -4723,6 +5341,7 @@ rl2_raster_decode (int scale, const unsigned char *blob_odd,
     if (compression == RL2_COMPRESSION_LOSSY_WEBP
 	|| compression == RL2_COMPRESSION_LOSSLESS_WEBP)
       {
+#ifndef OMIT_WEBP		/* only if WebP is enabled */
 	  /* decompressing from WEBP - always on the ODD Block */
 	  int ret = RL2_ERROR;
 	  switch (scale)
@@ -4759,12 +5378,18 @@ rl2_raster_decode (int scale, const unsigned char *blob_odd,
 	  if (ret != RL2_OK)
 	      goto error;
 	  goto done;
+#else /* WebP is disabled */
+	  fprintf (stderr,
+		   "librasterlite2 was built by disabling WebP support\n");
+	  goto error;
+#endif /* end WebP conditional */
       }
     if (compression == RL2_COMPRESSION_PNG)
       {
 	  /* decompressing from PNG */
 	  int ret;
-	  if (sample_type == RL2_SAMPLE_1_BIT || sample_type == RL2_SAMPLE_2_BIT
+	  if (sample_type == RL2_SAMPLE_1_BIT
+	      || sample_type == RL2_SAMPLE_2_BIT
 	      || sample_type == RL2_SAMPLE_4_BIT)
 	    {
 		/* Palette or Grayscale - 1,2 or 4 bit isn't scalable */
@@ -4772,9 +5397,9 @@ rl2_raster_decode (int scale, const unsigned char *blob_odd,
 		    goto error;
 		ret =
 		    rl2_decode_png (pixels_odd, compressed_odd,
-				    &width, &height, &sample_type, &pixel_type,
-				    &num_bands, &pixels, &pixels_sz, &mask,
-				    &mask_sz, &palette);
+				    &width, &height, &sample_type,
+				    &pixel_type, &num_bands, &pixels,
+				    &pixels_sz, &mask, &mask_sz, &palette, 0);
 		if (ret != RL2_OK)
 		    goto error;
 		goto done;
@@ -4785,7 +5410,7 @@ rl2_raster_decode (int scale, const unsigned char *blob_odd,
 				      &width, &odd_rows, &sample_type,
 				      &pixel_type, &num_bands, &odd_data,
 				      &pixels_sz, &odd_mask, &odd_mask_sz,
-				      &palette);
+				      &palette, 0);
 		if (ret != RL2_OK)
 		    goto error;
 		pixels_odd = odd_data;
@@ -4793,9 +5418,10 @@ rl2_raster_decode (int scale, const unsigned char *blob_odd,
 		  {
 		      ret = rl2_decode_png (pixels_even, compressed_even,
 					    &width, &even_rows, &sample_type,
-					    &pixel_type, &num_bands, &even_data,
-					    &pixels_sz, &even_mask,
-					    &even_mask_sz, &palette2);
+					    &pixel_type, &num_bands,
+					    &even_data, &pixels_sz,
+					    &even_mask, &even_mask_sz,
+					    &palette2, 0);
 		      if (ret != RL2_OK)
 			  goto error;
 		      rl2_destroy_palette (palette2);
@@ -4808,6 +5434,34 @@ rl2_raster_decode (int scale, const unsigned char *blob_odd,
 		goto merge;
 	    }
       }
+    if (compression == RL2_COMPRESSION_CHARLS)
+      {
+#ifndef OMIT_CHARLS		/* only if CharLS is enabled */
+	  /* decompressing from CHARLS */
+	  int ret = rl2_decode_charls (pixels_odd, compressed_odd,
+				       &width, &odd_rows, &sample_type,
+				       &pixel_type, &num_bands, &odd_data,
+				       &pixels_sz);
+	  if (ret != RL2_OK)
+	      goto error;
+	  pixels_odd = odd_data;
+	  if (scale == RL2_SCALE_1)
+	    {
+		ret = rl2_decode_charls (pixels_even, compressed_even,
+					 &width, &even_rows, &sample_type,
+					 &pixel_type, &num_bands, &even_data,
+					 &pixels_sz);
+		if (ret != RL2_OK)
+		    goto error;
+	    }
+	  pixels_even = even_data;
+	  goto merge;
+#else /* CharLS is disabled */
+	  fprintf (stderr,
+		   "librasterlite2 was built by disabling CharLS support\n");
+	  goto error;
+#endif /* end CharLS conditional */
+      }
     if (compression == RL2_COMPRESSION_CCITTFAX4)
       {
 	  /* decompressing from TIFF FAX4 */
@@ -4826,6 +5480,52 @@ rl2_raster_decode (int scale, const unsigned char *blob_odd,
 	  num_bands = 1;
 	  goto done;
       }
+    if (compression == RL2_COMPRESSION_LOSSY_JP2
+	|| compression == RL2_COMPRESSION_LOSSLESS_JP2)
+      {
+#ifndef OMIT_OPENJPEG		/* only if OpenJpeg is enabled */
+	  /* decompressing from Jpeg2000 - always on the ODD Block */
+	  int ret = RL2_ERROR;
+	  switch (scale)
+	    {
+	    case RL2_SCALE_1:
+		ret =
+		    rl2_decode_jpeg2000_scaled (1, pixels_odd, compressed_odd,
+						&width, &height, sample_type,
+						pixel_type, num_bands,
+						&pixels, &pixels_sz);
+		break;
+	    case RL2_SCALE_2:
+		ret =
+		    rl2_decode_jpeg2000_scaled (2, pixels_odd, compressed_odd,
+						&width, &height, sample_type,
+						pixel_type, num_bands,
+						&pixels, &pixels_sz);
+		break;
+	    case RL2_SCALE_4:
+		ret =
+		    rl2_decode_jpeg2000_scaled (4, pixels_odd, compressed_odd,
+						&width, &height, sample_type,
+						pixel_type, num_bands,
+						&pixels, &pixels_sz);
+		break;
+	    case RL2_SCALE_8:
+		ret =
+		    rl2_decode_jpeg2000_scaled (8, pixels_odd, compressed_odd,
+						&width, &height, sample_type,
+						pixel_type, num_bands,
+						&pixels, &pixels_sz);
+		break;
+	    };
+	  if (ret != RL2_OK)
+	      goto error;
+	  goto done;
+#else /* OpenJpeg is disabled */
+	  fprintf (stderr,
+		   "librasterlite2 was built by disabling OpenJpeg support\n");
+	  goto error;
+#endif /* end OpenJpeg conditional */
+      }
 
     if (sample_type == RL2_SAMPLE_1_BIT)
       {
@@ -4868,8 +5568,8 @@ rl2_raster_decode (int scale, const unsigned char *blob_odd,
 	  if (uncompressed_mask != (mask_width * mask_height))
 	      goto error;
 	  if (!unpack_rle
-	      (mask_width, mask_height, pixels_mask, compressed_mask, &mask_pix,
-	       &mask_pix_sz))
+	      (mask_width, mask_height, pixels_mask, compressed_mask,
+	       &mask_pix, &mask_pix_sz))
 	      goto error;
 	  if (!rescale_mask
 	      (scale, &mask_width, &mask_height, mask_pix, &mask, &mask_sz))
@@ -5193,7 +5893,8 @@ update_uint8_stats (unsigned short width, unsigned short height,
 	      ignore_no_data = 1;
 	  if (nbands != num_bands)
 	      ignore_no_data = 1;
-	  if (sample_type == RL2_SAMPLE_1_BIT || sample_type == RL2_SAMPLE_2_BIT
+	  if (sample_type == RL2_SAMPLE_1_BIT
+	      || sample_type == RL2_SAMPLE_2_BIT
 	      || sample_type == RL2_SAMPLE_4_BIT
 	      || sample_type == RL2_SAMPLE_UINT8)
 	      ;
@@ -5803,7 +6504,8 @@ update_int32_stats (unsigned short width, unsigned short height,
 
 static void
 compute_uint32_histogram (unsigned short width, unsigned short height,
-			  const unsigned int *pixels, const unsigned char *mask,
+			  const unsigned int *pixels,
+			  const unsigned char *mask,
 			  rl2PrivRasterStatisticsPtr st, rl2PixelPtr no_data)
 {
 /* computing INT16 tile histogram */
@@ -7135,3 +7837,341 @@ rl2_deserialize_dbms_pixel (const unsigned char *blob, int blob_size)
 	rl2_destroy_pixel (pixel);
     return NULL;
 }
+
+static void
+delta_encode_1 (unsigned char *buffer, int size)
+{
+/* Delta encoding - distance 1 */
+    int i;
+    unsigned char *p = buffer;
+    unsigned char history = *p++;
+    for (i = 1; i < size; i++)
+      {
+	  /* computing Deltas */
+	  unsigned char tmp = *p - history;
+	  history = *p;
+	  *p++ = tmp;
+      }
+}
+
+static void
+delta_encode_2 (unsigned char *buffer, int size)
+{
+/* Delta encoding - distance 2 */
+    int i;
+    unsigned char *p = buffer;
+    unsigned char history[2];
+/* saving the first component */
+    memcpy (history, p, 2);
+    p += 2;
+    for (i = 2; i < size; i += 2)
+      {
+	  /* computing Deltas */
+	  unsigned char tmp[2];
+	  tmp[0] = *(p + 0) - history[0];
+	  tmp[1] = *(p + 1) - history[1];
+	  memcpy (history, p, 2);
+	  memcpy (p, tmp, 2);
+	  p += 2;
+      }
+}
+
+static void
+delta_encode_3 (unsigned char *buffer, int size)
+{
+/* Delta encoding - distance 3 */
+    int i;
+    unsigned char *p = buffer;
+    unsigned char history[3];
+/* saving the first component */
+    memcpy (history, p, 3);
+    p += 3;
+    for (i = 3; i < size; i += 3)
+      {
+	  /* computing Deltas */
+	  unsigned char tmp[3];
+	  tmp[0] = *(p + 0) - history[0];
+	  tmp[1] = *(p + 1) - history[1];
+	  tmp[2] = *(p + 2) - history[2];
+	  memcpy (history, p, 3);
+	  memcpy (p, tmp, 3);
+	  p += 3;
+      }
+}
+
+static void
+delta_encode_4 (unsigned char *buffer, int size)
+{
+/* Delta encoding - distance 4 */
+    int i;
+    unsigned char *p = buffer;
+    unsigned char history[4];
+/* saving the first component */
+    memcpy (history, p, 4);
+    p += 4;
+    for (i = 4; i < size; i += 4)
+      {
+	  /* computing Deltas */
+	  unsigned char tmp[4];
+	  tmp[0] = *(p + 0) - history[0];
+	  tmp[1] = *(p + 1) - history[1];
+	  tmp[2] = *(p + 2) - history[2];
+	  tmp[3] = *(p + 3) - history[3];
+	  memcpy (history, p, 4);
+	  memcpy (p, tmp, 4);
+	  p += 4;
+      }
+}
+
+static void
+delta_encode_6 (unsigned char *buffer, int size)
+{
+/* Delta encoding - distance 6 */
+    int i;
+    unsigned char *p = buffer;
+    unsigned char history[6];
+/* saving the first component */
+    memcpy (history, p, 6);
+    p += 6;
+    for (i = 6; i < size; i += 6)
+      {
+	  /* computing Deltas */
+	  unsigned char tmp[6];
+	  tmp[0] = *(p + 0) - history[0];
+	  tmp[1] = *(p + 1) - history[1];
+	  tmp[2] = *(p + 2) - history[2];
+	  tmp[3] = *(p + 3) - history[3];
+	  tmp[4] = *(p + 4) - history[4];
+	  tmp[5] = *(p + 5) - history[5];
+	  memcpy (history, p, 6);
+	  memcpy (p, tmp, 6);
+	  p += 6;
+      }
+}
+
+static void
+delta_encode_8 (unsigned char *buffer, int size)
+{
+/* Delta encoding - distance 8 */
+    int i;
+    unsigned char *p = buffer;
+    unsigned char history[8];
+/* saving the first component */
+    memcpy (history, p, 8);
+    p += 8;
+    for (i = 8; i < size; i += 8)
+      {
+	  /* computing Deltas */
+	  unsigned char tmp[8];
+	  tmp[0] = *(p + 0) - history[0];
+	  tmp[1] = *(p + 1) - history[1];
+	  tmp[2] = *(p + 2) - history[2];
+	  tmp[3] = *(p + 3) - history[3];
+	  tmp[4] = *(p + 4) - history[4];
+	  tmp[5] = *(p + 5) - history[5];
+	  tmp[6] = *(p + 6) - history[6];
+	  tmp[7] = *(p + 7) - history[7];
+	  memcpy (history, p, 8);
+	  memcpy (p, tmp, 8);
+	  p += 8;
+      }
+}
+
+RL2_PRIVATE int
+rl2_delta_encode (unsigned char *buffer, int size, int distance)
+{
+/* Delta encoding */
+    if ((size % distance) != 0)
+	return RL2_ERROR;
+    switch (distance)
+      {
+      case 1:
+	  delta_encode_1 (buffer, size);
+	  return RL2_OK;
+      case 2:
+	  delta_encode_2 (buffer, size);
+	  return RL2_OK;
+      case 3:
+	  delta_encode_3 (buffer, size);
+	  return RL2_OK;
+      case 4:
+	  delta_encode_4 (buffer, size);
+	  return RL2_OK;
+      case 6:
+	  delta_encode_6 (buffer, size);
+	  return RL2_OK;
+      case 8:
+	  delta_encode_8 (buffer, size);
+	  return RL2_OK;
+      };
+    return RL2_ERROR;
+}
+
+static void
+delta_decode_1 (unsigned char *buffer, int size)
+{
+/* Delta decoding - distance 1 */
+    int i;
+    unsigned char *p = buffer;
+    unsigned char history = *p++;
+    for (i = 1; i < size; i++)
+      {
+	  /* restoring Deltas */
+	  unsigned char tmp = history + *p;
+	  *p = tmp;
+	  history = *p++;
+      }
+}
+
+static void
+delta_decode_2 (unsigned char *buffer, int size)
+{
+/* Delta decoding - distance 2 */
+    int i;
+    unsigned char *p = buffer;
+    unsigned char history[2];
+/* saving the first component */
+    memcpy (history, p, 2);
+    p += 2;
+    for (i = 2; i < size; i += 2)
+      {
+	  /* restoring Deltas */
+	  unsigned char tmp[2];
+	  tmp[0] = history[0] + *(p + 0);
+	  tmp[1] = history[1] + *(p + 1);
+	  memcpy (p, tmp, 2);
+	  memcpy (history, p, 2);
+	  p += 2;
+      }
+}
+
+static void
+delta_decode_3 (unsigned char *buffer, int size)
+{
+/* Delta decoding - distance 3 */
+    int i;
+    unsigned char *p = buffer;
+    unsigned char history[3];
+/* saving the first component */
+    memcpy (history, p, 3);
+    p += 3;
+    for (i = 3; i < size; i += 3)
+      {
+	  /* restoring Deltas */
+	  unsigned char tmp[3];
+	  tmp[0] = history[0] + *(p + 0);
+	  tmp[1] = history[1] + *(p + 1);
+	  tmp[2] = history[2] + *(p + 2);
+	  memcpy (p, tmp, 3);
+	  memcpy (history, p, 3);
+	  p += 3;
+      }
+}
+
+static void
+delta_decode_4 (unsigned char *buffer, int size)
+{
+/* Delta decoding - distance 4 */
+    int i;
+    unsigned char *p = buffer;
+    unsigned char history[4];
+/* saving the first component */
+    memcpy (history, p, 4);
+    p += 4;
+    for (i = 4; i < size; i += 4)
+      {
+	  /* restoring Deltas */
+	  unsigned char tmp[4];
+	  tmp[0] = history[0] + *(p + 0);
+	  tmp[1] = history[1] + *(p + 1);
+	  tmp[2] = history[2] + *(p + 2);
+	  tmp[3] = history[3] + *(p + 3);
+	  memcpy (p, tmp, 4);
+	  memcpy (history, p, 4);
+	  p += 4;
+      }
+}
+
+static void
+delta_decode_6 (unsigned char *buffer, int size)
+{
+/* Delta decoding - distance 6 */
+    int i;
+    unsigned char *p = buffer;
+    unsigned char history[6];
+/* saving the first component */
+    memcpy (history, p, 6);
+    p += 6;
+    for (i = 6; i < size; i += 6)
+      {
+	  /* restoring Deltas */
+	  unsigned char tmp[6];
+	  tmp[0] = history[0] + *(p + 0);
+	  tmp[1] = history[1] + *(p + 1);
+	  tmp[2] = history[2] + *(p + 2);
+	  tmp[3] = history[3] + *(p + 3);
+	  tmp[4] = history[4] + *(p + 4);
+	  tmp[5] = history[5] + *(p + 5);
+	  memcpy (p, tmp, 6);
+	  memcpy (history, p, 6);
+	  p += 6;
+      }
+}
+
+static void
+delta_decode_8 (unsigned char *buffer, int size)
+{
+/* Delta decoding - distance 8 */
+    int i;
+    unsigned char *p = buffer;
+    unsigned char history[8];
+/* saving the first component */
+    memcpy (history, p, 8);
+    p += 8;
+    for (i = 8; i < size; i += 8)
+      {
+	  /* restoring Deltas */
+	  unsigned char tmp[8];
+	  tmp[0] = history[0] + *(p + 0);
+	  tmp[1] = history[1] + *(p + 1);
+	  tmp[2] = history[2] + *(p + 2);
+	  tmp[3] = history[3] + *(p + 3);
+	  tmp[4] = history[4] + *(p + 4);
+	  tmp[5] = history[5] + *(p + 5);
+	  tmp[6] = history[6] + *(p + 6);
+	  tmp[7] = history[7] + *(p + 7);
+	  memcpy (p, tmp, 8);
+	  memcpy (history, p, 8);
+	  p += 8;
+      }
+}
+
+RL2_PRIVATE int
+rl2_delta_decode (unsigned char *buffer, int size, int distance)
+{
+/* Delta decoding */
+    if ((size % distance) != 0)
+	return RL2_ERROR;
+    switch (distance)
+      {
+      case 1:
+	  delta_decode_1 (buffer, size);
+	  return RL2_OK;
+      case 2:
+	  delta_decode_2 (buffer, size);
+	  return RL2_OK;
+      case 3:
+	  delta_decode_3 (buffer, size);
+	  return RL2_OK;
+      case 4:
+	  delta_decode_4 (buffer, size);
+	  return RL2_OK;
+      case 6:
+	  delta_decode_6 (buffer, size);
+	  return RL2_OK;
+      case 8:
+	  delta_decode_8 (buffer, size);
+	  return RL2_OK;
+      };
+    return RL2_ERROR;
+}
diff --git a/src/rl2dbms.c b/src/rl2dbms.c
index ea7af99..d53d5c4 100644
--- a/src/rl2dbms.c
+++ b/src/rl2dbms.c
@@ -20,7 +20,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -46,6 +46,14 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include <string.h>
 #include <float.h>
 
+#ifdef _WIN32
+#include <windows.h>
+#include <process.h>
+#else
+#include <unistd.h>
+#include <pthread.h>
+#endif
+
 #include "config.h"
 
 #ifdef LOADABLE_EXTENSION
@@ -55,8 +63,6 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include "rasterlite2/rasterlite2.h"
 #include "rasterlite2_private.h"
 
-#include <spatialite/gaiaaux.h>
-
 /* 64 bit integer: portable format for printf() */
 #if defined(_WIN32) && !defined(__MINGW32__)
 #define ERR_FRMT64 "ERROR: unable to decode Tile ID=%I64d\n"
@@ -71,9 +77,12 @@ insert_into_raster_coverages (sqlite3 * handle, const char *coverage,
 			      unsigned char compression, int quality,
 			      unsigned int tile_width,
 			      unsigned int tile_height, int srid,
-			      double x_res, double y_res, unsigned char *blob,
-			      int blob_sz, unsigned char *blob_no_data,
-			      int blob_no_data_sz)
+			      double x_res, double y_res,
+			      unsigned char *blob, int blob_sz,
+			      unsigned char *blob_no_data,
+			      int blob_no_data_sz, int strict_resolution,
+			      int mixed_resolutions, int section_paths,
+			      int section_md5, int section_summary)
 {
 /* inserting into "raster_coverages" */
     int ret;
@@ -86,7 +95,9 @@ insert_into_raster_coverages (sqlite3 * handle, const char *coverage,
     sql = "INSERT INTO raster_coverages (coverage_name, sample_type, "
 	"pixel_type, num_bands, compression, quality, tile_width, "
 	"tile_height, horz_resolution, vert_resolution, srid, "
-	"nodata_pixel, palette) VALUES (Lower(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+	"nodata_pixel, palette, strict_resolution, mixed_resolutions, "
+	"section_paths, section_md5, section_summary) VALUES "
+	"(Lower(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
       {
@@ -158,9 +169,15 @@ insert_into_raster_coverages (sqlite3 * handle, const char *coverage,
       case RL2_COMPRESSION_DEFLATE:
 	  xcompression = "DEFLATE";
 	  break;
+      case RL2_COMPRESSION_DEFLATE_NO:
+	  xcompression = "DEFLATE_NO";
+	  break;
       case RL2_COMPRESSION_LZMA:
 	  xcompression = "LZMA";
 	  break;
+      case RL2_COMPRESSION_LZMA_NO:
+	  xcompression = "LZMA_NO";
+	  break;
       case RL2_COMPRESSION_PNG:
 	  xcompression = "PNG";
 	  break;
@@ -176,6 +193,15 @@ insert_into_raster_coverages (sqlite3 * handle, const char *coverage,
       case RL2_COMPRESSION_CCITTFAX4:
 	  xcompression = "CCITTFAX4";
 	  break;
+      case RL2_COMPRESSION_CHARLS:
+	  xcompression = "CHARLS";
+	  break;
+      case RL2_COMPRESSION_LOSSY_JP2:
+	  xcompression = "LOSSY_JP2";
+	  break;
+      case RL2_COMPRESSION_LOSSLESS_JP2:
+	  xcompression = "LOSSLESS_JP2";
+	  break;
       };
     sqlite3_reset (stmt);
     sqlite3_clear_bindings (stmt);
@@ -188,8 +214,18 @@ insert_into_raster_coverages (sqlite3 * handle, const char *coverage,
     sqlite3_bind_int (stmt, 6, quality);
     sqlite3_bind_int (stmt, 7, tile_width);
     sqlite3_bind_int (stmt, 8, tile_height);
-    sqlite3_bind_double (stmt, 9, x_res);
-    sqlite3_bind_double (stmt, 10, y_res);
+    if (mixed_resolutions)
+      {
+	  /* conventional setting for mixed resolutions Coverage */
+	  sqlite3_bind_double (stmt, 9, 999999.999999);
+	  sqlite3_bind_double (stmt, 10, 999999.999999);
+      }
+    else
+      {
+	  /* real resolution in any other case */
+	  sqlite3_bind_double (stmt, 9, x_res);
+	  sqlite3_bind_double (stmt, 10, y_res);
+      }
     sqlite3_bind_int (stmt, 11, srid);
     if (blob_no_data == NULL)
 	sqlite3_bind_null (stmt, 12);
@@ -199,6 +235,11 @@ insert_into_raster_coverages (sqlite3 * handle, const char *coverage,
 	sqlite3_bind_null (stmt, 13);
     else
 	sqlite3_bind_blob (stmt, 13, blob, blob_sz, free);
+    sqlite3_bind_int (stmt, 14, strict_resolution);
+    sqlite3_bind_int (stmt, 15, mixed_resolutions);
+    sqlite3_bind_int (stmt, 16, section_paths);
+    sqlite3_bind_int (stmt, 17, section_md5);
+    sqlite3_bind_int (stmt, 18, section_summary);
     ret = sqlite3_step (stmt);
     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
 	goto coverage_registered;
@@ -223,7 +264,7 @@ create_levels (sqlite3 * handle, const char *coverage)
     char *xxcoverage;
 
     xcoverage = sqlite3_mprintf ("%s_levels", coverage);
-    xxcoverage = gaiaDoubleQuotedSql (xcoverage);
+    xxcoverage = rl2_double_quoted_sql (xcoverage);
     sqlite3_free (xcoverage);
     sql = sqlite3_mprintf ("CREATE TABLE \"%s\" ("
 			   "\tpyramid_level INTEGER PRIMARY KEY AUTOINCREMENT,\n"
@@ -239,8 +280,68 @@ create_levels (sqlite3 * handle, const char *coverage)
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "CREATE TABLE \"%s_levels\" error: %s\n", xxcoverage,
-		   sql_err);
+	  fprintf (stderr, "CREATE TABLE \"%s_levels\" error: %s\n",
+		   xxcoverage, sql_err);
+	  sqlite3_free (sql_err);
+	  free (xxcoverage);
+	  return 0;
+      }
+    free (xxcoverage);
+    return 1;
+}
+
+static int
+create_section_levels (sqlite3 * handle, const char *coverage)
+{
+/* creating the SECTION_LEVELS table */
+    int ret;
+    char *sql;
+    char *sql_err = NULL;
+    char *xcoverage;
+    char *xxcoverage;
+    char *pk_name;
+    char *xpk_name;
+    char *fk_name;
+    char *xfk_name;
+    char *mother;
+    char *xmother;
+
+    xcoverage = sqlite3_mprintf ("%s_section_levels", coverage);
+    xxcoverage = rl2_double_quoted_sql (xcoverage);
+    sqlite3_free (xcoverage);
+    pk_name = sqlite3_mprintf ("pk_%s_sectlevela", coverage);
+    xpk_name = rl2_double_quoted_sql (pk_name);
+    sqlite3_free (pk_name);
+    fk_name = sqlite3_mprintf ("fk_%s_sectlevels", coverage);
+    xfk_name = rl2_double_quoted_sql (fk_name);
+    sqlite3_free (fk_name);
+    mother = sqlite3_mprintf ("%s_sections", coverage);
+    xmother = rl2_double_quoted_sql (mother);
+    sqlite3_free (mother);
+    sql = sqlite3_mprintf ("CREATE TABLE \"%s\" (\n"
+			   "\tsection_id INTEGER NOT NULL,\n"
+			   "\tpyramid_level INTEGER NOT NULL,\n"
+			   "\tx_resolution_1_1 DOUBLE NOT NULL,\n"
+			   "\ty_resolution_1_1 DOUBLE NOT NULL,\n"
+			   "\tx_resolution_1_2 DOUBLE,\n"
+			   "\ty_resolution_1_2 DOUBLE,\n"
+			   "\tx_resolution_1_4 DOUBLE,\n"
+			   "\ty_resolution_1_4 DOUBLE,\n"
+			   "\tx_resolution_1_8 DOUBLE,\n"
+			   "\ty_resolution_1_8 DOUBLE,\n"
+			   "\tCONSTRAINT \"%s\" PRIMARY KEY (section_id, pyramid_level)\n"
+			   "\tCONSTRAINT \"%s\" FOREIGN KEY (section_id) "
+			   "REFERENCES \"%s\" (section_id))\n", xxcoverage,
+			   xpk_name, xfk_name, xmother);
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
+    sqlite3_free (sql);
+    free (xpk_name);
+    free (xfk_name);
+    free (xmother);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "CREATE TABLE \"%s_levels\" error: %s\n",
+		   xxcoverage, sql_err);
 	  sqlite3_free (sql_err);
 	  free (xxcoverage);
 	  return 0;
@@ -265,7 +366,7 @@ create_sections (sqlite3 * handle, const char *coverage, int srid)
 
 /* creating the SECTIONS table */
     xcoverage = sqlite3_mprintf ("%s_sections", coverage);
-    xxcoverage = gaiaDoubleQuotedSql (xcoverage);
+    xxcoverage = rl2_double_quoted_sql (xcoverage);
     sqlite3_free (xcoverage);
     sql = sqlite3_mprintf ("CREATE TABLE \"%s\" ("
 			   "\tsection_id INTEGER PRIMARY KEY AUTOINCREMENT,\n"
@@ -273,6 +374,8 @@ create_sections (sqlite3 * handle, const char *coverage, int srid)
 			   "\twidth INTEGER NOT NULL,\n"
 			   "\theight INTEGER NOT NULL,\n"
 			   "\tfile_path TEXT,\n"
+			   "\tmd5_checksum TEXT,\n"
+			   "\tsummary TEXT,\n"
 			   "\tstatistics BLOB)", xxcoverage);
     ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
     sqlite3_free (sql);
@@ -288,7 +391,7 @@ create_sections (sqlite3 * handle, const char *coverage, int srid)
 
 /* adding the safeguard Triggers */
     xtrigger = sqlite3_mprintf ("%s_sections_statistics_insert", coverage);
-    xxtrigger = gaiaDoubleQuotedSql (xtrigger);
+    xxtrigger = rl2_double_quoted_sql (xtrigger);
     sqlite3_free (xtrigger);
     xcoverage = sqlite3_mprintf ("%s_sections", coverage);
     sql = sqlite3_mprintf ("CREATE TRIGGER \"%s\"\n"
@@ -310,7 +413,7 @@ create_sections (sqlite3 * handle, const char *coverage, int srid)
       }
     free (xxtrigger);
     xtrigger = sqlite3_mprintf ("%s_sections_statistics_update", coverage);
-    xxtrigger = gaiaDoubleQuotedSql (xtrigger);
+    xxtrigger = rl2_double_quoted_sql (xtrigger);
     sqlite3_free (xtrigger);
     xcoverage = sqlite3_mprintf ("%s_sections", coverage);
     sql = sqlite3_mprintf ("CREATE TRIGGER \"%s\"\n"
@@ -368,13 +471,35 @@ create_sections (sqlite3 * handle, const char *coverage, int srid)
 
 /* creating the SECTIONS index by name */
     xcoverage = sqlite3_mprintf ("%s_sections", coverage);
-    xxcoverage = gaiaDoubleQuotedSql (xcoverage);
+    xxcoverage = rl2_double_quoted_sql (xcoverage);
+    sqlite3_free (xcoverage);
+    xindex = sqlite3_mprintf ("idx_%s_sect_name", coverage);
+    xxindex = rl2_double_quoted_sql (xindex);
+    sqlite3_free (xindex);
+    sql =
+	sqlite3_mprintf ("CREATE INDEX \"%s\" ON \"%s\" (section_name)",
+			 xxindex, xxcoverage);
+    free (xxcoverage);
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "CREATE INDEX \"%s\" error: %s\n", xxindex, sql_err);
+	  sqlite3_free (sql_err);
+	  free (xxindex);
+	  return 0;
+      }
+    free (xxindex);
+
+/* creating the SECTIONS index by MD5 checksum */
+    xcoverage = sqlite3_mprintf ("%s_sections", coverage);
+    xxcoverage = rl2_double_quoted_sql (xcoverage);
     sqlite3_free (xcoverage);
-    xindex = sqlite3_mprintf ("idx_%s_sections", coverage);
-    xxindex = gaiaDoubleQuotedSql (xindex);
+    xindex = sqlite3_mprintf ("idx_%s_sect_md5", coverage);
+    xxindex = rl2_double_quoted_sql (xindex);
     sqlite3_free (xindex);
     sql =
-	sqlite3_mprintf ("CREATE UNIQUE INDEX \"%s\" ON \"%s\" (section_name)",
+	sqlite3_mprintf ("CREATE INDEX \"%s\" ON \"%s\" (md5_checksum)",
 			 xxindex, xxcoverage);
     free (xxcoverage);
     ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
@@ -391,7 +516,8 @@ create_sections (sqlite3 * handle, const char *coverage, int srid)
 }
 
 static int
-create_tiles (sqlite3 * handle, const char *coverage, int srid)
+create_tiles (sqlite3 * handle, const char *coverage, int srid,
+	      int mixed_resolutions)
 {
 /* creating the TILES table */
     int ret;
@@ -415,29 +541,47 @@ create_tiles (sqlite3 * handle, const char *coverage, int srid)
     char *xxtiles;
 
     xcoverage = sqlite3_mprintf ("%s_tiles", coverage);
-    xxcoverage = gaiaDoubleQuotedSql (xcoverage);
+    xxcoverage = rl2_double_quoted_sql (xcoverage);
     sqlite3_free (xcoverage);
     xmother = sqlite3_mprintf ("%s_sections", coverage);
-    xxmother = gaiaDoubleQuotedSql (xmother);
+    xxmother = rl2_double_quoted_sql (xmother);
     sqlite3_free (xmother);
     xfk = sqlite3_mprintf ("fk_%s_tiles_section", coverage);
-    xxfk = gaiaDoubleQuotedSql (xfk);
+    xxfk = rl2_double_quoted_sql (xfk);
     sqlite3_free (xfk);
-    xmother2 = sqlite3_mprintf ("%s_levels", coverage);
-    xxmother2 = gaiaDoubleQuotedSql (xmother2);
+    if (mixed_resolutions)
+	xmother2 = sqlite3_mprintf ("%s_section_levels", coverage);
+    else
+	xmother2 = sqlite3_mprintf ("%s_levels", coverage);
+    xxmother2 = rl2_double_quoted_sql (xmother2);
     sqlite3_free (xmother2);
     xfk2 = sqlite3_mprintf ("fk_%s_tiles_level", coverage);
-    xxfk2 = gaiaDoubleQuotedSql (xfk2);
+    xxfk2 = rl2_double_quoted_sql (xfk2);
     sqlite3_free (xfk2);
-    sql = sqlite3_mprintf ("CREATE TABLE \"%s\" ("
-			   "\ttile_id INTEGER PRIMARY KEY AUTOINCREMENT,\n"
-			   "\tpyramid_level INTEGER NOT NULL,\n"
-			   "\tsection_id INTEGER,\n"
-			   "\tCONSTRAINT \"%s\" FOREIGN KEY (section_id) "
-			   "REFERENCES \"%s\" (section_id) ON DELETE CASCADE,\n"
-			   "\tCONSTRAINT \"%s\" FOREIGN KEY (pyramid_level) "
-			   "REFERENCES \"%s\" (pyramid_level) ON DELETE CASCADE)",
-			   xxcoverage, xxfk, xxmother, xxfk2, xxmother2);
+    if (mixed_resolutions)
+      {
+	  sql = sqlite3_mprintf ("CREATE TABLE \"%s\" ("
+				 "\ttile_id INTEGER PRIMARY KEY AUTOINCREMENT,\n"
+				 "\tpyramid_level INTEGER NOT NULL,\n"
+				 "\tsection_id INTEGER,\n"
+				 "\tCONSTRAINT \"%s\" FOREIGN KEY (section_id) "
+				 "REFERENCES \"%s\" (section_id) ON DELETE CASCADE,\n"
+				 "\tCONSTRAINT \"%s\" FOREIGN KEY (section_id, pyramid_level) "
+				 "REFERENCES \"%s\" (section_id, pyramid_level) ON DELETE CASCADE)",
+				 xxcoverage, xxfk, xxmother, xxfk2, xxmother2);
+      }
+    else
+      {
+	  sql = sqlite3_mprintf ("CREATE TABLE \"%s\" ("
+				 "\ttile_id INTEGER PRIMARY KEY AUTOINCREMENT,\n"
+				 "\tpyramid_level INTEGER NOT NULL,\n"
+				 "\tsection_id INTEGER,\n"
+				 "\tCONSTRAINT \"%s\" FOREIGN KEY (section_id) "
+				 "REFERENCES \"%s\" (section_id) ON DELETE CASCADE,\n"
+				 "\tCONSTRAINT \"%s\" FOREIGN KEY (pyramid_level) "
+				 "REFERENCES \"%s\" (pyramid_level) ON DELETE CASCADE)",
+				 xxcoverage, xxfk, xxmother, xxfk2, xxmother2);
+      }
     free (xxfk);
     free (xxmother);
     free (xxfk2);
@@ -489,14 +633,38 @@ create_tiles (sqlite3 * handle, const char *coverage, int srid)
 
 /* creating the TILES index by section */
     xcoverage = sqlite3_mprintf ("%s_tiles", coverage);
-    xxcoverage = gaiaDoubleQuotedSql (xcoverage);
+    xxcoverage = rl2_double_quoted_sql (xcoverage);
+    sqlite3_free (xcoverage);
+    xindex = sqlite3_mprintf ("idx_%s_tiles_sect", coverage);
+    xxindex = rl2_double_quoted_sql (xindex);
+    sqlite3_free (xindex);
+    sql =
+	sqlite3_mprintf
+	("CREATE INDEX \"%s\" ON \"%s\" (section_id, pyramid_level)", xxindex,
+	 xxcoverage);
+    free (xxcoverage);
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "CREATE INDEX \"%s\" error: %s\n", xxindex, sql_err);
+	  sqlite3_free (sql_err);
+	  free (xxindex);
+	  return 0;
+      }
+    free (xxindex);
+
+/* creating the TILES index by level */
+    xcoverage = sqlite3_mprintf ("%s_tiles", coverage);
+    xxcoverage = rl2_double_quoted_sql (xcoverage);
     sqlite3_free (xcoverage);
-    xindex = sqlite3_mprintf ("idx_%s_tiles", coverage);
-    xxindex = gaiaDoubleQuotedSql (xindex);
+    xindex = sqlite3_mprintf ("idx_%s_tiles_lev", coverage);
+    xxindex = rl2_double_quoted_sql (xindex);
     sqlite3_free (xindex);
     sql =
-	sqlite3_mprintf ("CREATE INDEX \"%s\" ON \"%s\" (section_id)", xxindex,
-			 xxcoverage);
+	sqlite3_mprintf
+	("CREATE INDEX \"%s\" ON \"%s\" (pyramid_level, section_id)", xxindex,
+	 xxcoverage);
     free (xxcoverage);
     ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
     sqlite3_free (sql);
@@ -511,13 +679,13 @@ create_tiles (sqlite3 * handle, const char *coverage, int srid)
 
 /* creating the TILE_DATA table */
     xcoverage = sqlite3_mprintf ("%s_tile_data", coverage);
-    xxcoverage = gaiaDoubleQuotedSql (xcoverage);
+    xxcoverage = rl2_double_quoted_sql (xcoverage);
     sqlite3_free (xcoverage);
     xmother = sqlite3_mprintf ("%s_tiles", coverage);
-    xxmother = gaiaDoubleQuotedSql (xmother);
+    xxmother = rl2_double_quoted_sql (xmother);
     sqlite3_free (xmother);
     xfk = sqlite3_mprintf ("fk_%s_tile_data", coverage);
-    xxfk = gaiaDoubleQuotedSql (xfk);
+    xxfk = rl2_double_quoted_sql (xfk);
     sqlite3_free (xfk);
     sql = sqlite3_mprintf ("CREATE TABLE \"%s\" ("
 			   "\ttile_id INTEGER NOT NULL PRIMARY KEY,\n"
@@ -542,11 +710,11 @@ create_tiles (sqlite3 * handle, const char *coverage, int srid)
 
 /* adding the safeguard Triggers */
     xtrigger = sqlite3_mprintf ("%s_tile_data_insert", coverage);
-    xxtrigger = gaiaDoubleQuotedSql (xtrigger);
+    xxtrigger = rl2_double_quoted_sql (xtrigger);
     sqlite3_free (xtrigger);
     xcoverage = sqlite3_mprintf ("%s_tile_data", coverage);
     xtiles = sqlite3_mprintf ("%s_tiles", coverage);
-    xxtiles = gaiaDoubleQuotedSql (xtiles);
+    xxtiles = rl2_double_quoted_sql (xtiles);
     sqlite3_free (xtiles);
     sql = sqlite3_mprintf ("CREATE TRIGGER \"%s\"\n"
 			   "BEFORE INSERT ON %Q\nFOR EACH ROW BEGIN\n"
@@ -569,11 +737,11 @@ create_tiles (sqlite3 * handle, const char *coverage, int srid)
       }
     free (xxtrigger);
     xtrigger = sqlite3_mprintf ("%s_tile_data_update", coverage);
-    xxtrigger = gaiaDoubleQuotedSql (xtrigger);
+    xxtrigger = rl2_double_quoted_sql (xtrigger);
     sqlite3_free (xtrigger);
     xcoverage = sqlite3_mprintf ("%s_tile_data", coverage);
     xtiles = sqlite3_mprintf ("%s_tiles", coverage);
-    xxtiles = gaiaDoubleQuotedSql (xtiles);
+    xxtiles = rl2_double_quoted_sql (xtiles);
     sqlite3_free (xtiles);
     sql = sqlite3_mprintf ("CREATE TRIGGER \"%s\"\n"
 			   "BEFORE UPDATE ON %Q\nFOR EACH ROW BEGIN\n"
@@ -605,7 +773,9 @@ rl2_create_dbms_coverage (sqlite3 * handle, const char *coverage,
 			  int quality, unsigned int tile_width,
 			  unsigned int tile_height, int srid, double x_res,
 			  double y_res, rl2PixelPtr no_data,
-			  rl2PalettePtr palette)
+			  rl2PalettePtr palette, int strict_resolution,
+			  int mixed_resolutions, int section_paths,
+			  int section_md5, int section_summary)
 {
 /* creating a DBMS-based Coverage */
     unsigned char *blob = NULL;
@@ -626,14 +796,23 @@ rl2_create_dbms_coverage (sqlite3 * handle, const char *coverage,
       }
     if (!insert_into_raster_coverages
 	(handle, coverage, sample, pixel, num_bands, compression, quality,
-	 tile_width, tile_height, srid, x_res, y_res, blob, blob_size,
-	 blob_no_data, blob_no_data_sz))
-	goto error;
-    if (!create_levels (handle, coverage))
+	 tile_width, tile_height, srid, x_res, y_res, blob,
+	 blob_size, blob_no_data, blob_no_data_sz, strict_resolution,
+	 mixed_resolutions, section_paths, section_md5, section_summary))
 	goto error;
+    if (mixed_resolutions)
+      {
+	  if (!create_section_levels (handle, coverage))
+	      goto error;
+      }
+    else
+      {
+	  if (!create_levels (handle, coverage))
+	      goto error;
+      }
     if (!create_sections (handle, coverage, srid))
 	goto error;
-    if (!create_tiles (handle, coverage, srid))
+    if (!create_tiles (handle, coverage, srid, mixed_resolutions))
 	goto error;
     return RL2_OK;
   error:
@@ -641,37 +820,36 @@ rl2_create_dbms_coverage (sqlite3 * handle, const char *coverage,
 }
 
 RL2_DECLARE int
-rl2_get_dbms_section_id (sqlite3 * handle, const char *coverage,
-			 const char *section, sqlite3_int64 * section_id)
+rl2_set_dbms_coverage_default_bands (sqlite3 * handle, const char *coverage,
+				     unsigned char red_band,
+				     unsigned char green_band,
+				     unsigned char blue_band,
+				     unsigned char nir_band)
 {
-/* retrieving a Section ID by its name */
+/* 
+/  setting up the default Red, Green, Blue and NIR bands
+/  will work only for a MULTIBAND coverage 
+*/
     int ret;
-    char *sql;
-    char *table;
-    char *xtable;
-    int found = 0;
     sqlite3_stmt *stmt = NULL;
+    const char *sql;
+    int num_bands;
+    int count = 0;
 
-    table = sqlite3_mprintf ("%s_sections", coverage);
-    xtable = gaiaDoubleQuotedSql (table);
-    sqlite3_free (table);
-    sql =
-	sqlite3_mprintf ("SELECT section_id FROM \"%s\" WHERE section_name = ?",
-			 xtable);
-    free (xtable);
+    sql = "SELECT num_bands FROM raster_coverages "
+	"WHERE Lower(coverage_name) = Lower(?) AND pixel_type = 'MULTIBAND'";
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
-    sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  printf ("SELECT section_name SQL error: %s\n",
+	  printf ("SELECT MultiBand # Bands SQL error: %s\n",
 		  sqlite3_errmsg (handle));
 	  goto error;
       }
 
-/* querying the section */
+/* querying the covrage */
     sqlite3_reset (stmt);
     sqlite3_clear_bindings (stmt);
-    sqlite3_bind_text (stmt, 1, section, strlen (section), SQLITE_STATIC);
+    sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
     while (1)
       {
 	  ret = sqlite3_step (stmt);
@@ -679,21 +857,69 @@ rl2_get_dbms_section_id (sqlite3 * handle, const char *coverage,
 	      break;
 	  if (ret == SQLITE_ROW)
 	    {
-		*section_id = sqlite3_column_int64 (stmt, 0);
-		found++;
+		num_bands = sqlite3_column_int (stmt, 0);
+		count++;
 	    }
 	  else
 	    {
 		fprintf (stderr,
-			 "SELECT section_name; sqlite3_step() error: %s\n",
+			 "SELECT MultiBand # Bands; sqlite3_step() error: %s\n",
 			 sqlite3_errmsg (handle));
 		goto error;
 	    }
       }
     sqlite3_finalize (stmt);
     stmt = NULL;
-    if (found == 1)
-	return RL2_OK;
+
+/* validation checks */
+    if (count != 1)
+	goto error;
+    if (red_band >= num_bands)
+	goto error;
+    if (green_band >= num_bands)
+	goto error;
+    if (blue_band >= num_bands)
+	goto error;
+    if (nir_band >= num_bands)
+	goto error;
+    if (red_band == green_band || red_band == blue_band || red_band == nir_band)
+	goto error;
+    if (green_band == blue_band || green_band == nir_band)
+	goto error;
+    if (blue_band == nir_band)
+	goto error;
+
+/* updating the Coverage */
+    sql = "UPDATE raster_coverages SET red_band_index = ?, "
+	"green_band_index = ?, blue_band_index = ?, nir_band_index = ? "
+	"WHERE Lower(coverage_name) = Lower(?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("UPDATE MultiBand default Bands SQL error: %s\n",
+		  sqlite3_errmsg (handle));
+	  goto error;
+      }
+
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_int (stmt, 1, red_band);
+    sqlite3_bind_int (stmt, 2, green_band);
+    sqlite3_bind_int (stmt, 3, blue_band);
+    sqlite3_bind_int (stmt, 4, nir_band);
+    sqlite3_bind_text (stmt, 5, coverage, strlen (coverage), SQLITE_STATIC);
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+	;
+    else
+      {
+	  fprintf (stderr,
+		   "sqlite3_step() error: UPDATE MultiBand default Bands \"%s\"\n",
+		   sqlite3_errmsg (handle));
+	  goto error;
+      }
+    sqlite3_finalize (stmt);
+    return RL2_OK;
 
   error:
     if (stmt != NULL)
@@ -702,436 +928,819 @@ rl2_get_dbms_section_id (sqlite3 * handle, const char *coverage,
 }
 
 RL2_DECLARE int
-rl2_delete_dbms_section (sqlite3 * handle, const char *coverage,
-			 sqlite3_int64 section_id)
+rl2_get_dbms_coverage_default_bands (sqlite3 * handle, const char *coverage,
+				     unsigned char *red_band,
+				     unsigned char *green_band,
+				     unsigned char *blue_band,
+				     unsigned char *nir_band)
 {
-/* deleting a Raster Section */
+/* 
+/  attempring to retrieve the default Red, Green, Blue and NIR bands
+/  will work only for a MULTIBAND coverage 
+*/
     int ret;
-    char *sql;
-    rl2CoveragePtr cvg = NULL;
-    char *table;
-    char *xtable;
     sqlite3_stmt *stmt = NULL;
-
-    table = sqlite3_mprintf ("%s_sections", coverage);
-    xtable = gaiaDoubleQuotedSql (table);
-    sqlite3_free (table);
-    sql = sqlite3_mprintf ("DELETE FROM \"%s\" WHERE section_id = ?", xtable);
-    free (xtable);
+    const char *sql;
+    int num_bands;
+    int red = -1;
+    int green = -1;
+    int blue = -1;
+    int nir = -1;
+    int count = 0;
+
+    sql = "SELECT num_bands, red_band_index, green_band_index, "
+	"blue_band_index, nir_band_index FROM raster_coverages "
+	"WHERE Lower(coverage_name) = Lower(?) AND pixel_type = 'MULTIBAND'";
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
-    sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  printf ("DELETE sections SQL error: %s\n", sqlite3_errmsg (handle));
+	  printf ("SELECT MultiBand default Bands SQL error: %s\n",
+		  sqlite3_errmsg (handle));
 	  goto error;
       }
 
-/* DELETing the section */
+/* querying the covrage */
     sqlite3_reset (stmt);
     sqlite3_clear_bindings (stmt);
-    sqlite3_bind_int64 (stmt, 1, section_id);
-    ret = sqlite3_step (stmt);
-    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
-	;
-    else
+    sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
+    while (1)
       {
-	  fprintf (stderr,
-		   "DELETE sections; sqlite3_step() error: %s\n",
-		   sqlite3_errmsg (handle));
-	  goto error;
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	    {
+		num_bands = sqlite3_column_int (stmt, 0);
+		if (sqlite3_column_type (stmt, 1) == SQLITE_INTEGER)
+		    red = sqlite3_column_int (stmt, 1);
+		if (sqlite3_column_type (stmt, 2) == SQLITE_INTEGER)
+		    green = sqlite3_column_int (stmt, 2);
+		if (sqlite3_column_type (stmt, 3) == SQLITE_INTEGER)
+		    blue = sqlite3_column_int (stmt, 3);
+		if (sqlite3_column_type (stmt, 4) == SQLITE_INTEGER)
+		    nir = sqlite3_column_int (stmt, 4);
+		count++;
+	    }
+	  else
+	    {
+		fprintf (stderr,
+			 "SELECT MultiBand default Bands; sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (handle));
+		goto error;
+	    }
       }
     sqlite3_finalize (stmt);
+    stmt = NULL;
 
-    rl2_destroy_coverage (cvg);
+/* validation checks */
+    if (count != 1)
+	goto error;
+    if (red < 0 || red >= num_bands)
+	goto error;
+    if (green < 0 || green >= num_bands)
+	goto error;
+    if (blue < 0 || blue >= num_bands)
+	goto error;
+    if (nir < 0 || nir >= num_bands)
+	goto error;
+    if (red == green || red == blue || red == nir)
+	goto error;
+    if (green == blue || green == nir)
+	goto error;
+    if (blue == nir)
+	goto error;
+
+    *red_band = red;
+    *green_band = green;
+    *blue_band = blue;
+    *nir_band = nir;
     return RL2_OK;
 
   error:
     if (stmt != NULL)
 	sqlite3_finalize (stmt);
-    if (cvg != NULL)
-	rl2_destroy_coverage (cvg);
     return RL2_ERROR;
 }
 
 RL2_DECLARE int
-rl2_drop_dbms_coverage (sqlite3 * handle, const char *coverage)
+rl2_enable_dbms_coverage_auto_ndvi (sqlite3 * handle, const char *coverage,
+				    int on_off)
 {
-/* dropping a Raster Coverage */
+/* 
+/  enabling / disabling the Auto NDVI capability
+/  will work only for a MULTIBAND coverage explicitly declaring
+/  default Red, Green, Blue and NIR bands
+*/
     int ret;
-    char *sql;
-    char *sql_err = NULL;
-    char *table;
-    char *xtable;
+    sqlite3_stmt *stmt = NULL;
+    const char *sql;
+    unsigned char red_band;
+    unsigned char green_band;
+    unsigned char blue_band;
+    unsigned char nir_band;
+
+    if (rl2_get_dbms_coverage_default_bands
+	(handle, coverage, &red_band, &green_band, &blue_band,
+	 &nir_band) != RL2_OK)
+	goto error;
 
-/* disabling the SECTIONS spatial index */
-    xtable = sqlite3_mprintf ("%s_sections", coverage);
-    sql = sqlite3_mprintf ("SELECT DisableSpatialIndex("
-			   "%Q, 'geometry')", xtable);
-    ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
-    sqlite3_free (sql);
+/* updating the Coverage */
+    sql = "UPDATE raster_coverages SET enable_auto_ndvi = ? "
+	"WHERE Lower(coverage_name) = Lower(?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "DisableSpatialIndex \"%s\" error: %s\n", xtable,
-		   sql_err);
-	  sqlite3_free (sql_err);
-	  sqlite3_free (xtable);
+	  printf ("UPDATE Enable Auto NDVI SQL error: %s\n",
+		  sqlite3_errmsg (handle));
 	  goto error;
       }
-    sqlite3_free (xtable);
 
-/* dropping the SECTIONS spatial index */
-    table = sqlite3_mprintf ("idx_%s_sections_geometry", coverage);
-    xtable = gaiaDoubleQuotedSql (table);
-    sql = sqlite3_mprintf ("DROP TABLE \"%s\"", xtable);
-    free (xtable);
-    ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
-    sqlite3_free (sql);
-    if (ret != SQLITE_OK)
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    if (on_off)
+	sqlite3_bind_int (stmt, 1, 1);
+    else
+	sqlite3_bind_int (stmt, 1, 0);
+    sqlite3_bind_text (stmt, 2, coverage, strlen (coverage), SQLITE_STATIC);
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+	;
+    else
       {
-	  fprintf (stderr, "DROP TABLE \"%s\" error: %s\n", table, sql_err);
-	  sqlite3_free (sql_err);
-	  sqlite3_free (table);
+	  fprintf (stderr,
+		   "sqlite3_step() error: UPDATE Enable Auto NDVI \"%s\"\n",
+		   sqlite3_errmsg (handle));
 	  goto error;
       }
-    sqlite3_free (table);
+    sqlite3_finalize (stmt);
+    return RL2_OK;
 
-/* disabling the TILES spatial index */
-    xtable = sqlite3_mprintf ("%s_tiles", coverage);
-    sql = sqlite3_mprintf ("SELECT DisableSpatialIndex("
-			   "%Q, 'geometry')", xtable);
-    ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
-    sqlite3_free (sql);
-    if (ret != SQLITE_OK)
-      {
-	  fprintf (stderr, "DisableSpatialIndex \"%s\" error: %s\n", xtable,
-		   sql_err);
-	  sqlite3_free (sql_err);
-	  sqlite3_free (xtable);
-	  goto error;
-      }
-    sqlite3_free (xtable);
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    return RL2_ERROR;
+}
 
-/* dropping the TILES spatial index */
-    table = sqlite3_mprintf ("idx_%s_tiles_geometry", coverage);
-    xtable = gaiaDoubleQuotedSql (table);
-    sql = sqlite3_mprintf ("DROP TABLE \"%s\"", xtable);
-    free (xtable);
-    ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
-    sqlite3_free (sql);
+RL2_DECLARE int
+rl2_is_dbms_coverage_auto_ndvi_enabled (sqlite3 * handle, const char *coverage)
+{
+/* 
+/  attempring to retrieve if the Auto NDVI feature is enabled
+/  will work only for a MULTIBAND coverage 
+*/
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+    const char *sql;
+    int num_bands;
+    int red = -1;
+    int green = -1;
+    int blue = -1;
+    int nir = -1;
+    int enabled = -1;
+    int count = 0;
+
+    sql = "SELECT num_bands, red_band_index, green_band_index, "
+	"blue_band_index, nir_band_index, enable_auto_ndvi FROM raster_coverages "
+	"WHERE Lower(coverage_name) = Lower(?) AND pixel_type = 'MULTIBAND'";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "DROP TABLE \"%s\" error: %s\n", table, sql_err);
-	  sqlite3_free (sql_err);
-	  sqlite3_free (table);
+	  printf ("SELECT IsEnabled Auto NDVI SQL error: %s\n",
+		  sqlite3_errmsg (handle));
 	  goto error;
       }
-    sqlite3_free (table);
 
-/* dropping the TILE_DATA table */
-    table = sqlite3_mprintf ("%s_tile_data", coverage);
-    xtable = gaiaDoubleQuotedSql (table);
-    sql = sqlite3_mprintf ("DROP TABLE \"%s\"", xtable);
-    free (xtable);
-    ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
-    sqlite3_free (sql);
-    if (ret != SQLITE_OK)
+/* querying the covrage */
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
+    while (1)
       {
-	  fprintf (stderr, "DROP TABLE \"%s\" error: %s\n", table, sql_err);
-	  sqlite3_free (sql_err);
-	  sqlite3_free (table);
-	  goto error;
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	    {
+		num_bands = sqlite3_column_int (stmt, 0);
+		if (sqlite3_column_type (stmt, 1) == SQLITE_INTEGER)
+		    red = sqlite3_column_int (stmt, 1);
+		if (sqlite3_column_type (stmt, 2) == SQLITE_INTEGER)
+		    green = sqlite3_column_int (stmt, 2);
+		if (sqlite3_column_type (stmt, 3) == SQLITE_INTEGER)
+		    blue = sqlite3_column_int (stmt, 3);
+		if (sqlite3_column_type (stmt, 4) == SQLITE_INTEGER)
+		    nir = sqlite3_column_int (stmt, 4);
+		if (sqlite3_column_type (stmt, 5) == SQLITE_INTEGER)
+		    enabled = sqlite3_column_int (stmt, 5);
+		count++;
+	    }
+	  else
+	    {
+		fprintf (stderr,
+			 "SELECT IsEnabled Auto NDVI; sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (handle));
+		goto error;
+	    }
       }
-    sqlite3_free (table);
+    sqlite3_finalize (stmt);
+    stmt = NULL;
 
-/* deleting the TILES Geometry definition */
-    table = sqlite3_mprintf ("%s_tiles", coverage);
-    xtable = gaiaDoubleQuotedSql (table);
+/* validation checks */
+    if (count != 1)
+	goto error;
+    if (red < 0 || red >= num_bands)
+	goto error;
+    if (green < 0 || green >= num_bands)
+	goto error;
+    if (blue < 0 || blue >= num_bands)
+	goto error;
+    if (nir < 0 || nir >= num_bands)
+	goto error;
+    if (red == green || red == blue || red == nir)
+	goto error;
+    if (green == blue || green == nir)
+	goto error;
+    if (blue == nir)
+	goto error;
+    if (enabled < 0)
+	goto error;
+
+    if (enabled)
+	return RL2_TRUE;
+    else
+	return RL2_FALSE;
+
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    return RL2_ERROR;
+}
+
+static int
+resolve_base_resolution_section (sqlite3 * handle, const char *coverage,
+				 sqlite3_int64 section_id, double *x_res,
+				 double *y_res)
+{
+/* resolving the Base Resolution - Mixed Resolutions */
+    int ret;
+    char *sql;
+    char *table;
+    char *xtable;
+    double xres;
+    double yres;
+    int count = 0;
+    sqlite3_stmt *stmt = NULL;
+
+    table = sqlite3_mprintf ("%s_section_levels", coverage);
+    xtable = rl2_double_quoted_sql (table);
     sqlite3_free (table);
-    sql = sqlite3_mprintf ("DELETE FROM geometry_columns "
-			   "WHERE Lower(f_table_name) = Lower(%Q)", xtable);
+    sql =
+	sqlite3_mprintf ("SELECT x_resolution_1_1, y_resolution_1_1 "
+			 "FROM \"%s\" WHERE pyramid_level = 0 AND section_id = ?",
+			 xtable);
     free (xtable);
-    ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "DELETE TilesGeometry \"%s\" error: %s\n",
-		   coverage, sql_err);
-	  sqlite3_free (sql_err);
+	  printf ("SELECT base_resolution SQL error: %s\n",
+		  sqlite3_errmsg (handle));
 	  goto error;
       }
 
-/* deleting the SECTIONS Geometry definition */
-    table = sqlite3_mprintf ("%s_sections", coverage);
-    xtable = gaiaDoubleQuotedSql (table);
-    sql = sqlite3_mprintf ("DELETE FROM geometry_columns "
-			   "WHERE Lower(f_table_name) = Lower(%Q)", xtable);
-    free (xtable);
-    sqlite3_free (table);
-    ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
-    sqlite3_free (sql);
-    if (ret != SQLITE_OK)
+/* querying the section */
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_int64 (stmt, 1, section_id);
+    while (1)
       {
-	  fprintf (stderr, "DELETE SectionsGeometry \"%s\" error: %s\n",
-		   coverage, sql_err);
-	  sqlite3_free (sql_err);
-	  goto error;
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	    {
+		xres = sqlite3_column_double (stmt, 0);
+		yres = sqlite3_column_double (stmt, 1);
+		count++;
+	    }
+	  else
+	    {
+		fprintf (stderr,
+			 "SELECT base_resolution; sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (handle));
+		goto error;
+	    }
       }
-
-/* dropping the TILES table */
-    table = sqlite3_mprintf ("%s_tiles", coverage);
-    xtable = gaiaDoubleQuotedSql (table);
-    sql = sqlite3_mprintf ("DROP TABLE \"%s\"", xtable);
-    free (xtable);
-    ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
-    sqlite3_free (sql);
-    if (ret != SQLITE_OK)
+    sqlite3_finalize (stmt);
+    stmt = NULL;
+    if (count == 1)
       {
-	  fprintf (stderr, "DROP TABLE \"%s\" error: %s\n", table, sql_err);
-	  sqlite3_free (sql_err);
-	  sqlite3_free (table);
-	  goto error;
+	  *x_res = xres;
+	  *y_res = yres;
+	  return RL2_OK;
       }
-    sqlite3_free (table);
 
-/* dropping the SECTIONS table */
-    table = sqlite3_mprintf ("%s_sections", coverage);
-    xtable = gaiaDoubleQuotedSql (table);
-    sql = sqlite3_mprintf ("DROP TABLE \"%s\"", xtable);
-    free (xtable);
-    ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_resolve_base_resolution_from_dbms (sqlite3 * handle, const char *coverage,
+				       int by_section,
+				       sqlite3_int64 section_id,
+				       double *x_res, double *y_res)
+{
+/* resolving the Base Resolution */
+    int ret;
+    char *sql;
+    double xres;
+    double yres;
+    int count = 0;
+    sqlite3_stmt *stmt = NULL;
+
+    if (rl2_is_mixed_resolutions_coverage (handle, coverage) > 0 && by_section)
+	return resolve_base_resolution_section (handle, coverage, section_id,
+						x_res, y_res);
+
+    sql =
+	sqlite3_mprintf ("SELECT horz_resolution, vert_resolution "
+			 "FROM raster_coverages WHERE coverage_name = Lower(%Q)",
+			 coverage);
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "DROP TABLE \"%s\" error: %s\n", table, sql_err);
-	  sqlite3_free (sql_err);
-	  sqlite3_free (table);
+	  printf ("SELECT base_resolution SQL error: %s\n",
+		  sqlite3_errmsg (handle));
 	  goto error;
       }
-    sqlite3_free (table);
 
-/* dropping the LEVELS table */
-    table = sqlite3_mprintf ("%s_levels", coverage);
-    xtable = gaiaDoubleQuotedSql (table);
-    sql = sqlite3_mprintf ("DROP TABLE \"%s\"", xtable);
-    free (xtable);
-    ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
-    sqlite3_free (sql);
-    if (ret != SQLITE_OK)
+    while (1)
       {
-	  fprintf (stderr, "DROP TABLE \"%s\" error: %s\n", table, sql_err);
-	  sqlite3_free (sql_err);
-	  sqlite3_free (table);
-	  goto error;
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	    {
+		xres = sqlite3_column_double (stmt, 0);
+		yres = sqlite3_column_double (stmt, 1);
+		count++;
+	    }
+	  else
+	    {
+		fprintf (stderr,
+			 "SELECT base_resolution; sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (handle));
+		goto error;
+	    }
       }
-    sqlite3_free (table);
-
-/* deleting the Raster Coverage definition */
-    sql = sqlite3_mprintf ("DELETE FROM raster_coverages "
-			   "WHERE Lower(coverage_name) = Lower(%Q)", coverage);
-    ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
-    sqlite3_free (sql);
-    if (ret != SQLITE_OK)
+    sqlite3_finalize (stmt);
+    stmt = NULL;
+    if (count == 1)
       {
-	  fprintf (stderr, "DELETE raster_coverage \"%s\" error: %s\n",
-		   coverage, sql_err);
-	  sqlite3_free (sql_err);
-	  goto error;
+	  *x_res = xres;
+	  *y_res = yres;
+	  return RL2_OK;
       }
-    return RL2_OK;
 
   error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
     return RL2_ERROR;
 }
 
-static void
-prime_void_tile_int8 (void *pixels, unsigned int width, unsigned int height,
-		      rl2PixelPtr no_data)
+RL2_DECLARE int
+rl2_resolve_full_section_from_dbms (sqlite3 * handle, const char *coverage,
+				    sqlite3_int64 section_id, double x_res,
+				    double y_res, double *minX, double *minY,
+				    double *maxX, double *maxY,
+				    unsigned int *Width, unsigned int *Height)
 {
-/* priming a void tile buffer - INT8 */
-    unsigned int row;
-    unsigned int col;
-    char *p = pixels;
-    char val = 0;
-
-    if (no_data != NULL)
+/* resolving a Full Section Extent and related Width and Height */
+    rl2CoveragePtr cvg;
+    double xx_res = x_res;
+    double yy_res = y_res;
+    unsigned char level;
+    unsigned char scale;
+    int ret;
+    char *sql;
+    char *table;
+    char *xtable;
+    int count = 0;
+    sqlite3_stmt *stmt = NULL;
+    double minx = 0.0;
+    double miny = 0.0;
+    double maxx = 0.0;
+    double maxy = 0.0;
+    int width = 0;
+    int height = 0;
+
+    cvg = rl2_create_coverage_from_dbms (handle, coverage);
+    if (cvg == NULL)
+	return RL2_ERROR;
+    if (rl2_find_matching_resolution
+	(handle, cvg, 1, section_id, &xx_res, &yy_res, &level,
+	 &scale) != RL2_OK)
       {
-	  /* retrieving the NO-DATA value */
-	  unsigned char sample_type;
-	  unsigned char pixel_type;
-	  unsigned char num_bands;
-	  if (rl2_get_pixel_type
-	      (no_data, &sample_type, &pixel_type, &num_bands) != RL2_OK)
-	      goto done;
-	  if (sample_type != RL2_SAMPLE_INT8 || num_bands != 1)
-	      goto done;
-	  rl2_get_pixel_sample_int8 (no_data, &val);
-      }
-
-  done:
-    for (row = 0; row < height; row++)
-      {
-	  for (col = 0; col < width; col++)
-	      *p++ = val;
+	  rl2_destroy_coverage (cvg);
+	  return RL2_ERROR;
       }
-}
-
-static void
-prime_void_tile_uint8 (void *pixels, unsigned int width,
-		       unsigned int height, unsigned char num_bands,
-		       rl2PixelPtr no_data)
-{
-/* priming a void tile buffer - UINT8 */
-    unsigned int row;
-    unsigned int col;
-    int band;
-    unsigned char *p = pixels;
-    unsigned char val = 0;
-    int ok_no_data = 0;
+    rl2_destroy_coverage (cvg);
 
-    if (no_data != NULL)
+    table = sqlite3_mprintf ("%s_sections", coverage);
+    xtable = rl2_double_quoted_sql (table);
+    sqlite3_free (table);
+    sql =
+	sqlite3_mprintf ("SELECT MbrMinX(geometry), MbrMinY(geometry), "
+			 "MbrMaxX(geometry), MbrMaxY(geometry), width, height "
+			 "FROM \"%s\" WHERE section_id = ?", xtable);
+    free (xtable);
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
       {
-	  /* retrieving the NO-DATA value */
-	  unsigned char sample_type;
-	  unsigned char pixel_type;
-	  unsigned char num_bands;
-	  if (rl2_get_pixel_type
-	      (no_data, &sample_type, &pixel_type, &num_bands) != RL2_OK)
-	      goto done;
-	  if (sample_type != RL2_SAMPLE_UINT8)
-	      goto done;
-	  ok_no_data = 1;
+	  printf ("SELECT section_full_extent SQL error: %s\n",
+		  sqlite3_errmsg (handle));
+	  goto error;
       }
 
-  done:
-    for (row = 0; row < height; row++)
+/* querying the section */
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_int64 (stmt, 1, section_id);
+    while (1)
       {
-	  for (col = 0; col < width; col++)
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
 	    {
-		for (band = 0; band < num_bands; band++)
-		  {
-		      if (ok_no_data)
-			  rl2_get_pixel_sample_uint8 (no_data, band, &val);
-		      *p++ = val;
-		  }
+		minx = sqlite3_column_double (stmt, 0);
+		miny = sqlite3_column_double (stmt, 1);
+		maxx = sqlite3_column_double (stmt, 2);
+		maxy = sqlite3_column_double (stmt, 3);
+		width = sqlite3_column_int (stmt, 4);
+		height = sqlite3_column_int (stmt, 5);
+		count++;
+	    }
+	  else
+	    {
+		fprintf (stderr,
+			 "SELECT section_full_extent; sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (handle));
+		goto error;
 	    }
       }
-}
-
-static void
-prime_void_tile_int16 (void *pixels, unsigned int width,
-		       unsigned int height, rl2PixelPtr no_data)
-{
-/* priming a void tile buffer - INT16 */
-    unsigned int row;
-    unsigned int col;
-    short *p = pixels;
-    short val = 0;
-
-    if (no_data != NULL)
+    sqlite3_finalize (stmt);
+    stmt = NULL;
+    if (level == 0 && scale == RL2_SCALE_1)
+	;
+    else
       {
-	  /* retrieving the NO-DATA value */
-	  unsigned char sample_type;
-	  unsigned char pixel_type;
-	  unsigned char num_bands;
-	  if (rl2_get_pixel_type
-	      (no_data, &sample_type, &pixel_type, &num_bands) != RL2_OK)
-	      goto done;
-	  if (sample_type != RL2_SAMPLE_INT16 || num_bands != 1)
-	      goto done;
-	  rl2_get_pixel_sample_int16 (no_data, &val);
+	  /* rescaling Width and Height */
+	  double ext_x = maxx - minx;
+	  double ext_y = maxy - miny;
+	  width = (unsigned int) (ext_x / xx_res);
+	  if (((double) width * xx_res) < ext_x)
+	      width++;
+	  height = (unsigned int) (ext_y / yy_res);
+	  if (((double) height * yy_res) < ext_y)
+	      height++;
+      }
+    if (count == 1)
+      {
+	  *minX = minx;
+	  *minY = miny;
+	  *maxX = maxx;
+	  *maxY = maxy;
+	  *Width = width;
+	  *Height = height;
+	  return RL2_OK;
       }
 
-  done:
-    for (row = 0; row < height; row++)
-      {
-	  for (col = 0; col < width; col++)
-	      *p++ = val;
-      }
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    return RL2_ERROR;
 }
 
-static void
-prime_void_tile_uint16 (void *pixels, unsigned int width,
-			unsigned int height, unsigned char num_bands,
-			rl2PixelPtr no_data)
+RL2_DECLARE int
+rl2_get_dbms_section_id (sqlite3 * handle, const char *coverage,
+			 const char *section, sqlite3_int64 * section_id,
+			 int *duplicate)
 {
-/* priming a void tile buffer - UINT16 */
-    unsigned int row;
-    unsigned int col;
-    int band;
-    unsigned short *p = pixels;
-    unsigned short val = 0;
-    int ok_no_data = 0;
+/* retrieving a Section ID by its name */
+    int ret;
+    char *sql;
+    char *table;
+    char *xtable;
+    int count = 0;
+    sqlite3_stmt *stmt = NULL;
 
-    if (no_data != NULL)
+    *duplicate = 0;
+    table = sqlite3_mprintf ("%s_sections", coverage);
+    xtable = rl2_double_quoted_sql (table);
+    sqlite3_free (table);
+    sql =
+	sqlite3_mprintf
+	("SELECT section_id FROM \"%s\" WHERE section_name = ?", xtable);
+    free (xtable);
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
       {
-	  /* retrieving the NO-DATA value */
-	  unsigned char sample_type;
-	  unsigned char pixel_type;
-	  unsigned char num_bands;
-	  if (rl2_get_pixel_type
-	      (no_data, &sample_type, &pixel_type, &num_bands) != RL2_OK)
-	      goto done;
-	  if (sample_type != RL2_SAMPLE_UINT16)
-	      goto done;
-	  ok_no_data = 1;
+	  printf ("SELECT section_id SQL error: %s\n", sqlite3_errmsg (handle));
+	  goto error;
       }
 
-  done:
-    for (row = 0; row < height; row++)
+/* querying the section */
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, section, strlen (section), SQLITE_STATIC);
+    while (1)
       {
-	  for (col = 0; col < width; col++)
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
 	    {
-		for (band = 0; band < num_bands; band++)
-		  {
-		      if (ok_no_data)
-			  rl2_get_pixel_sample_uint16 (no_data, band, &val);
-		      *p++ = val;
-		  }
+		*section_id = sqlite3_column_int64 (stmt, 0);
+		count++;
+	    }
+	  else
+	    {
+		fprintf (stderr,
+			 "SELECT section_id; sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (handle));
+		goto error;
 	    }
       }
+    sqlite3_finalize (stmt);
+    stmt = NULL;
+    if (count == 1)
+	return RL2_OK;
+    if (count > 1)
+	*duplicate = 1;
+
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    return RL2_ERROR;
 }
 
-static void
-prime_void_tile_int32 (void *pixels, unsigned int width,
-		       unsigned int height, rl2PixelPtr no_data)
+RL2_DECLARE int
+rl2_delete_dbms_section (sqlite3 * handle, const char *coverage,
+			 sqlite3_int64 section_id)
 {
-/* priming a void tile buffer - INT32 */
-    unsigned int row;
-    unsigned int col;
-    int *p = pixels;
-    int val = 0;
+/* deleting a Raster Section */
+    int ret;
+    char *sql;
+    rl2CoveragePtr cvg = NULL;
+    char *table;
+    char *xtable;
+    sqlite3_stmt *stmt = NULL;
 
-    if (no_data != NULL)
+    table = sqlite3_mprintf ("%s_sections", coverage);
+    xtable = rl2_double_quoted_sql (table);
+    sqlite3_free (table);
+    sql = sqlite3_mprintf ("DELETE FROM \"%s\" WHERE section_id = ?", xtable);
+    free (xtable);
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
       {
-	  /* retrieving the NO-DATA value */
-	  unsigned char sample_type;
-	  unsigned char pixel_type;
-	  unsigned char num_bands;
-	  if (rl2_get_pixel_type
-	      (no_data, &sample_type, &pixel_type, &num_bands) != RL2_OK)
-	      goto done;
-	  if (sample_type != RL2_SAMPLE_INT32 || num_bands != 1)
-	      goto done;
-	  rl2_get_pixel_sample_int32 (no_data, &val);
+	  printf ("DELETE sections SQL error: %s\n", sqlite3_errmsg (handle));
+	  goto error;
       }
 
-  done:
-    for (row = 0; row < height; row++)
+/* DELETing the section */
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_int64 (stmt, 1, section_id);
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+	;
+    else
       {
-	  for (col = 0; col < width; col++)
-	      *p++ = val;
+	  fprintf (stderr,
+		   "DELETE sections; sqlite3_step() error: %s\n",
+		   sqlite3_errmsg (handle));
+	  goto error;
       }
+    sqlite3_finalize (stmt);
+
+    rl2_destroy_coverage (cvg);
+    return RL2_OK;
+
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    if (cvg != NULL)
+	rl2_destroy_coverage (cvg);
+    return RL2_ERROR;
 }
 
-static void
-prime_void_tile_uint32 (void *pixels, unsigned int width,
-			unsigned int height, rl2PixelPtr no_data)
+RL2_DECLARE int
+rl2_drop_dbms_coverage (sqlite3 * handle, const char *coverage)
 {
-/* priming a void tile buffer - UINT32 */
-    unsigned int row;
-    unsigned int col;
-    unsigned int *p = pixels;
-    unsigned int val = 0;
+/* dropping a Raster Coverage */
+    int ret;
+    char *sql;
+    char *sql_err = NULL;
+    char *table;
+    char *xtable;
+
+/* disabling the SECTIONS spatial index */
+    xtable = sqlite3_mprintf ("%s_sections", coverage);
+    sql = sqlite3_mprintf ("SELECT DisableSpatialIndex("
+			   "%Q, 'geometry')", xtable);
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "DisableSpatialIndex \"%s\" error: %s\n", xtable,
+		   sql_err);
+	  sqlite3_free (sql_err);
+	  sqlite3_free (xtable);
+	  goto error;
+      }
+    sqlite3_free (xtable);
+
+/* dropping the SECTIONS spatial index */
+    table = sqlite3_mprintf ("idx_%s_sections_geometry", coverage);
+    xtable = rl2_double_quoted_sql (table);
+    sql = sqlite3_mprintf ("DROP TABLE \"%s\"", xtable);
+    free (xtable);
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "DROP TABLE \"%s\" error: %s\n", table, sql_err);
+	  sqlite3_free (sql_err);
+	  sqlite3_free (table);
+	  goto error;
+      }
+    sqlite3_free (table);
+
+/* disabling the TILES spatial index */
+    xtable = sqlite3_mprintf ("%s_tiles", coverage);
+    sql = sqlite3_mprintf ("SELECT DisableSpatialIndex("
+			   "%Q, 'geometry')", xtable);
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "DisableSpatialIndex \"%s\" error: %s\n", xtable,
+		   sql_err);
+	  sqlite3_free (sql_err);
+	  sqlite3_free (xtable);
+	  goto error;
+      }
+    sqlite3_free (xtable);
+
+/* dropping the TILES spatial index */
+    table = sqlite3_mprintf ("idx_%s_tiles_geometry", coverage);
+    xtable = rl2_double_quoted_sql (table);
+    sql = sqlite3_mprintf ("DROP TABLE \"%s\"", xtable);
+    free (xtable);
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "DROP TABLE \"%s\" error: %s\n", table, sql_err);
+	  sqlite3_free (sql_err);
+	  sqlite3_free (table);
+	  goto error;
+      }
+    sqlite3_free (table);
+
+/* dropping the TILE_DATA table */
+    table = sqlite3_mprintf ("%s_tile_data", coverage);
+    xtable = rl2_double_quoted_sql (table);
+    sql = sqlite3_mprintf ("DROP TABLE \"%s\"", xtable);
+    free (xtable);
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "DROP TABLE \"%s\" error: %s\n", table, sql_err);
+	  sqlite3_free (sql_err);
+	  sqlite3_free (table);
+	  goto error;
+      }
+    sqlite3_free (table);
+
+/* deleting the TILES Geometry definition */
+    table = sqlite3_mprintf ("%s_tiles", coverage);
+    xtable = rl2_double_quoted_sql (table);
+    sqlite3_free (table);
+    sql = sqlite3_mprintf ("DELETE FROM geometry_columns "
+			   "WHERE Lower(f_table_name) = Lower(%Q)", xtable);
+    free (xtable);
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "DELETE TilesGeometry \"%s\" error: %s\n",
+		   coverage, sql_err);
+	  sqlite3_free (sql_err);
+	  goto error;
+      }
+
+/* deleting the SECTIONS Geometry definition */
+    table = sqlite3_mprintf ("%s_sections", coverage);
+    xtable = rl2_double_quoted_sql (table);
+    sql = sqlite3_mprintf ("DELETE FROM geometry_columns "
+			   "WHERE Lower(f_table_name) = Lower(%Q)", xtable);
+    free (xtable);
+    sqlite3_free (table);
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "DELETE SectionsGeometry \"%s\" error: %s\n",
+		   coverage, sql_err);
+	  sqlite3_free (sql_err);
+	  goto error;
+      }
+
+/* dropping the TILES table */
+    table = sqlite3_mprintf ("%s_tiles", coverage);
+    xtable = rl2_double_quoted_sql (table);
+    sql = sqlite3_mprintf ("DROP TABLE \"%s\"", xtable);
+    free (xtable);
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "DROP TABLE \"%s\" error: %s\n", table, sql_err);
+	  sqlite3_free (sql_err);
+	  sqlite3_free (table);
+	  goto error;
+      }
+    sqlite3_free (table);
+
+/* dropping the SECTIONS table */
+    table = sqlite3_mprintf ("%s_sections", coverage);
+    xtable = rl2_double_quoted_sql (table);
+    sql = sqlite3_mprintf ("DROP TABLE \"%s\"", xtable);
+    free (xtable);
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "DROP TABLE \"%s\" error: %s\n", table, sql_err);
+	  sqlite3_free (sql_err);
+	  sqlite3_free (table);
+	  goto error;
+      }
+    sqlite3_free (table);
+
+/* dropping the LEVELS table */
+    table = sqlite3_mprintf ("%s_levels", coverage);
+    xtable = rl2_double_quoted_sql (table);
+    sql = sqlite3_mprintf ("DROP TABLE \"%s\"", xtable);
+    free (xtable);
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "DROP TABLE \"%s\" error: %s\n", table, sql_err);
+	  sqlite3_free (sql_err);
+	  sqlite3_free (table);
+	  goto error;
+      }
+    sqlite3_free (table);
+
+/* deleting the Raster Coverage definition */
+    sql = sqlite3_mprintf ("DELETE FROM raster_coverages "
+			   "WHERE Lower(coverage_name) = Lower(%Q)", coverage);
+    ret = sqlite3_exec (handle, sql, NULL, NULL, &sql_err);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "DELETE raster_coverage \"%s\" error: %s\n",
+		   coverage, sql_err);
+	  sqlite3_free (sql_err);
+	  goto error;
+      }
+    return RL2_OK;
+
+  error:
+    return RL2_ERROR;
+}
+
+static void
+prime_void_tile_int8 (void *pixels, unsigned int width, unsigned int height,
+		      rl2PixelPtr no_data)
+{
+/* priming a void tile buffer - INT8 */
+    unsigned int row;
+    unsigned int col;
+    char *p = pixels;
+    char val = 0;
 
     if (no_data != NULL)
       {
@@ -1142,9 +1751,9 @@ prime_void_tile_uint32 (void *pixels, unsigned int width,
 	  if (rl2_get_pixel_type
 	      (no_data, &sample_type, &pixel_type, &num_bands) != RL2_OK)
 	      goto done;
-	  if (sample_type != RL2_SAMPLE_UINT32 || num_bands != 1)
+	  if (sample_type != RL2_SAMPLE_INT8 || num_bands != 1)
 	      goto done;
-	  rl2_get_pixel_sample_uint32 (no_data, &val);
+	  rl2_get_pixel_sample_int8 (no_data, &val);
       }
 
   done:
@@ -1156,14 +1765,17 @@ prime_void_tile_uint32 (void *pixels, unsigned int width,
 }
 
 static void
-prime_void_tile_float (void *pixels, unsigned int width,
-		       unsigned int height, rl2PixelPtr no_data)
+prime_void_tile_uint8 (void *pixels, unsigned int width,
+		       unsigned int height, unsigned char num_bands,
+		       rl2PixelPtr no_data)
 {
-/* priming a void tile buffer - Float */
+/* priming a void tile buffer - UINT8 */
     unsigned int row;
     unsigned int col;
-    float *p = pixels;
-    float val = 0.0;
+    int band;
+    unsigned char *p = pixels;
+    unsigned char val = 0;
+    int ok_no_data = 0;
 
     if (no_data != NULL)
       {
@@ -1174,28 +1786,35 @@ prime_void_tile_float (void *pixels, unsigned int width,
 	  if (rl2_get_pixel_type
 	      (no_data, &sample_type, &pixel_type, &num_bands) != RL2_OK)
 	      goto done;
-	  if (sample_type != RL2_SAMPLE_FLOAT || num_bands != 1)
+	  if (sample_type != RL2_SAMPLE_UINT8)
 	      goto done;
-	  rl2_get_pixel_sample_float (no_data, &val);
+	  ok_no_data = 1;
       }
 
   done:
     for (row = 0; row < height; row++)
       {
 	  for (col = 0; col < width; col++)
-	      *p++ = val;
+	    {
+		for (band = 0; band < num_bands; band++)
+		  {
+		      if (ok_no_data)
+			  rl2_get_pixel_sample_uint8 (no_data, band, &val);
+		      *p++ = val;
+		  }
+	    }
       }
 }
 
 static void
-prime_void_tile_double (void *pixels, unsigned int width,
-			unsigned int height, rl2PixelPtr no_data)
+prime_void_tile_int16 (void *pixels, unsigned int width,
+		       unsigned int height, rl2PixelPtr no_data)
 {
-/* priming a void tile buffer - Double */
+/* priming a void tile buffer - INT16 */
     unsigned int row;
     unsigned int col;
-    double *p = pixels;
-    double val = 0.0;
+    short *p = pixels;
+    short val = 0;
 
     if (no_data != NULL)
       {
@@ -1206,9 +1825,9 @@ prime_void_tile_double (void *pixels, unsigned int width,
 	  if (rl2_get_pixel_type
 	      (no_data, &sample_type, &pixel_type, &num_bands) != RL2_OK)
 	      goto done;
-	  if (sample_type != RL2_SAMPLE_DOUBLE || num_bands != 1)
+	  if (sample_type != RL2_SAMPLE_INT16 || num_bands != 1)
 	      goto done;
-	  rl2_get_pixel_sample_double (no_data, &val);
+	  rl2_get_pixel_sample_int16 (no_data, &val);
       }
 
   done:
@@ -1219,19 +1838,189 @@ prime_void_tile_double (void *pixels, unsigned int width,
       }
 }
 
-RL2_DECLARE void
-rl2_prime_void_tile (void *pixels, unsigned int width, unsigned int height,
-		     unsigned char sample_type, unsigned char num_bands,
-		     rl2PixelPtr no_data)
+static void
+prime_void_tile_uint16 (void *pixels, unsigned int width,
+			unsigned int height, unsigned char num_bands,
+			rl2PixelPtr no_data)
 {
-/* priming a void tile buffer */
-    switch (sample_type)
+/* priming a void tile buffer - UINT16 */
+    unsigned int row;
+    unsigned int col;
+    int band;
+    unsigned short *p = pixels;
+    unsigned short val = 0;
+    int ok_no_data = 0;
+
+    if (no_data != NULL)
       {
-      case RL2_SAMPLE_INT8:
-	  prime_void_tile_int8 (pixels, width, height, no_data);
-	  break;
-      case RL2_SAMPLE_1_BIT:
-      case RL2_SAMPLE_2_BIT:
+	  /* retrieving the NO-DATA value */
+	  unsigned char sample_type;
+	  unsigned char pixel_type;
+	  unsigned char num_bands;
+	  if (rl2_get_pixel_type
+	      (no_data, &sample_type, &pixel_type, &num_bands) != RL2_OK)
+	      goto done;
+	  if (sample_type != RL2_SAMPLE_UINT16)
+	      goto done;
+	  ok_no_data = 1;
+      }
+
+  done:
+    for (row = 0; row < height; row++)
+      {
+	  for (col = 0; col < width; col++)
+	    {
+		for (band = 0; band < num_bands; band++)
+		  {
+		      if (ok_no_data)
+			  rl2_get_pixel_sample_uint16 (no_data, band, &val);
+		      *p++ = val;
+		  }
+	    }
+      }
+}
+
+static void
+prime_void_tile_int32 (void *pixels, unsigned int width,
+		       unsigned int height, rl2PixelPtr no_data)
+{
+/* priming a void tile buffer - INT32 */
+    unsigned int row;
+    unsigned int col;
+    int *p = pixels;
+    int val = 0;
+
+    if (no_data != NULL)
+      {
+	  /* retrieving the NO-DATA value */
+	  unsigned char sample_type;
+	  unsigned char pixel_type;
+	  unsigned char num_bands;
+	  if (rl2_get_pixel_type
+	      (no_data, &sample_type, &pixel_type, &num_bands) != RL2_OK)
+	      goto done;
+	  if (sample_type != RL2_SAMPLE_INT32 || num_bands != 1)
+	      goto done;
+	  rl2_get_pixel_sample_int32 (no_data, &val);
+      }
+
+  done:
+    for (row = 0; row < height; row++)
+      {
+	  for (col = 0; col < width; col++)
+	      *p++ = val;
+      }
+}
+
+static void
+prime_void_tile_uint32 (void *pixels, unsigned int width,
+			unsigned int height, rl2PixelPtr no_data)
+{
+/* priming a void tile buffer - UINT32 */
+    unsigned int row;
+    unsigned int col;
+    unsigned int *p = pixels;
+    unsigned int val = 0;
+
+    if (no_data != NULL)
+      {
+	  /* retrieving the NO-DATA value */
+	  unsigned char sample_type;
+	  unsigned char pixel_type;
+	  unsigned char num_bands;
+	  if (rl2_get_pixel_type
+	      (no_data, &sample_type, &pixel_type, &num_bands) != RL2_OK)
+	      goto done;
+	  if (sample_type != RL2_SAMPLE_UINT32 || num_bands != 1)
+	      goto done;
+	  rl2_get_pixel_sample_uint32 (no_data, &val);
+      }
+
+  done:
+    for (row = 0; row < height; row++)
+      {
+	  for (col = 0; col < width; col++)
+	      *p++ = val;
+      }
+}
+
+static void
+prime_void_tile_float (void *pixels, unsigned int width,
+		       unsigned int height, rl2PixelPtr no_data)
+{
+/* priming a void tile buffer - Float */
+    unsigned int row;
+    unsigned int col;
+    float *p = pixels;
+    float val = 0.0;
+
+    if (no_data != NULL)
+      {
+	  /* retrieving the NO-DATA value */
+	  unsigned char sample_type;
+	  unsigned char pixel_type;
+	  unsigned char num_bands;
+	  if (rl2_get_pixel_type
+	      (no_data, &sample_type, &pixel_type, &num_bands) != RL2_OK)
+	      goto done;
+	  if (sample_type != RL2_SAMPLE_FLOAT || num_bands != 1)
+	      goto done;
+	  rl2_get_pixel_sample_float (no_data, &val);
+      }
+
+  done:
+    for (row = 0; row < height; row++)
+      {
+	  for (col = 0; col < width; col++)
+	      *p++ = val;
+      }
+}
+
+static void
+prime_void_tile_double (void *pixels, unsigned int width,
+			unsigned int height, rl2PixelPtr no_data)
+{
+/* priming a void tile buffer - Double */
+    unsigned int row;
+    unsigned int col;
+    double *p = pixels;
+    double val = 0.0;
+
+    if (no_data != NULL)
+      {
+	  /* retrieving the NO-DATA value */
+	  unsigned char sample_type;
+	  unsigned char pixel_type;
+	  unsigned char num_bands;
+	  if (rl2_get_pixel_type
+	      (no_data, &sample_type, &pixel_type, &num_bands) != RL2_OK)
+	      goto done;
+	  if (sample_type != RL2_SAMPLE_DOUBLE || num_bands != 1)
+	      goto done;
+	  rl2_get_pixel_sample_double (no_data, &val);
+      }
+
+  done:
+    for (row = 0; row < height; row++)
+      {
+	  for (col = 0; col < width; col++)
+	      *p++ = val;
+      }
+}
+
+RL2_DECLARE void
+rl2_prime_void_tile (void *pixels, unsigned int width, unsigned int height,
+		     unsigned char sample_type, unsigned char num_bands,
+		     rl2PixelPtr no_data)
+{
+/* priming a void tile buffer */
+    switch (sample_type)
+      {
+      case RL2_SAMPLE_INT8:
+	  prime_void_tile_int8 (pixels, width, height, no_data);
+	  break;
+      case RL2_SAMPLE_1_BIT:
+      case RL2_SAMPLE_2_BIT:
       case RL2_SAMPLE_4_BIT:
       case RL2_SAMPLE_UINT8:
 	  prime_void_tile_uint8 (pixels, width, height, num_bands, no_data);
@@ -1320,6 +2109,11 @@ rl2_create_coverage_from_dbms (sqlite3 * handle, const char *coverage)
     double x_res;
     double y_res;
     int srid;
+    int strict_resolution = 0;
+    int mixed_resolutions = 0;
+    int section_paths = 0;
+    int section_md5 = 0;
+    int section_summary = 0;
     int ok = 0;
     const char *value;
     rl2PixelPtr no_data = NULL;
@@ -1328,7 +2122,9 @@ rl2_create_coverage_from_dbms (sqlite3 * handle, const char *coverage)
 /* querying the Coverage metadata defs */
     sql =
 	"SELECT sample_type, pixel_type, num_bands, compression, quality, tile_width, "
-	"tile_height, horz_resolution, vert_resolution, srid, nodata_pixel "
+	"tile_height, horz_resolution, vert_resolution, srid, nodata_pixel, "
+	"strict_resolution, mixed_resolutions, section_paths, "
+	"section_md5, section_summary "
 	"FROM raster_coverages WHERE Lower(coverage_name) = Lower(?)";
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
@@ -1358,6 +2154,11 @@ rl2_create_coverage_from_dbms (sqlite3 * handle, const char *coverage)
 		int ok_y_res = 0;
 		int ok_srid = 0;
 		int ok_nodata = 1;
+		int ok_strict = 0;
+		int ok_mixed = 0;
+		int ok_paths = 0;
+		int ok_md5 = 0;
+		int ok_summary = 0;
 		if (sqlite3_column_type (stmt, 0) == SQLITE_TEXT)
 		  {
 		      value = (const char *) sqlite3_column_text (stmt, 0);
@@ -1469,11 +2270,21 @@ rl2_create_coverage_from_dbms (sqlite3 * handle, const char *coverage)
 			    ok_compression = 1;
 			    compression = RL2_COMPRESSION_DEFLATE;
 			}
+		      if (strcasecmp (value, "DEFLATE_NO") == 0)
+			{
+			    ok_compression = 1;
+			    compression = RL2_COMPRESSION_DEFLATE_NO;
+			}
 		      if (strcasecmp (value, "LZMA") == 0)
 			{
 			    ok_compression = 1;
 			    compression = RL2_COMPRESSION_LZMA;
 			}
+		      if (strcasecmp (value, "LZMA_NO") == 0)
+			{
+			    ok_compression = 1;
+			    compression = RL2_COMPRESSION_LZMA_NO;
+			}
 		      if (strcasecmp (value, "PNG") == 0)
 			{
 			    ok_compression = 1;
@@ -1499,6 +2310,21 @@ rl2_create_coverage_from_dbms (sqlite3 * handle, const char *coverage)
 			    ok_compression = 1;
 			    compression = RL2_COMPRESSION_CCITTFAX4;
 			}
+		      if (strcasecmp (value, "CHARLS") == 0)
+			{
+			    ok_compression = 1;
+			    compression = RL2_COMPRESSION_CHARLS;
+			}
+		      if (strcasecmp (value, "LOSSY_JP2") == 0)
+			{
+			    ok_compression = 1;
+			    compression = RL2_COMPRESSION_LOSSY_JP2;
+			}
+		      if (strcasecmp (value, "LOSSLESS_JP2") == 0)
+			{
+			    ok_compression = 1;
+			    compression = RL2_COMPRESSION_LOSSLESS_JP2;
+			}
 		  }
 		if (sqlite3_column_type (stmt, 4) == SQLITE_INTEGER)
 		  {
@@ -1539,9 +2365,36 @@ rl2_create_coverage_from_dbms (sqlite3 * handle, const char *coverage)
 		      if (no_data == NULL)
 			  ok_nodata = 0;
 		  }
+		if (sqlite3_column_type (stmt, 11) == SQLITE_INTEGER)
+		  {
+		      strict_resolution = sqlite3_column_int (stmt, 11);
+		      ok_strict = 1;
+		  }
+		if (sqlite3_column_type (stmt, 12) == SQLITE_INTEGER)
+		  {
+		      mixed_resolutions = sqlite3_column_int (stmt, 12);
+		      ok_mixed = 1;
+		  }
+		if (sqlite3_column_type (stmt, 13) == SQLITE_INTEGER)
+		  {
+		      section_paths = sqlite3_column_int (stmt, 13);
+		      ok_paths = 1;
+		  }
+		if (sqlite3_column_type (stmt, 14) == SQLITE_INTEGER)
+		  {
+		      section_md5 = sqlite3_column_int (stmt, 14);
+		      ok_md5 = 1;
+		  }
+		if (sqlite3_column_type (stmt, 15) == SQLITE_INTEGER)
+		  {
+		      section_summary = sqlite3_column_int (stmt, 15);
+		      ok_summary = 1;
+		  }
 		if (ok_sample && ok_pixel && ok_num_bands && ok_compression
-		    && ok_quality && ok_tile_width && ok_tile_height && ok_x_res
-		    && ok_y_res && ok_srid && ok_nodata)
+		    && ok_quality && ok_tile_width && ok_tile_height
+		    && ok_x_res && ok_y_res && ok_srid && ok_nodata
+		    && ok_strict && ok_mixed && ok_paths && ok_md5
+		    && ok_summary)
 		    ok = 1;
 	    }
       }
@@ -1572,57 +2425,182 @@ rl2_create_coverage_from_dbms (sqlite3 * handle, const char *coverage)
 	  rl2_destroy_coverage (cvg);
 	  return NULL;
       }
-    return cvg;
-}
-
-static void
-void_int8_raw_buffer (char *buffer, unsigned int width, unsigned int height,
-		      rl2PixelPtr no_data)
-{
-/* preparing an empty/void INT8 raw buffer */
-    rl2PrivPixelPtr pxl = NULL;
-    unsigned int x;
-    unsigned int y;
-    char *p = buffer;
-    char nd_value = 0;
-    if (no_data != NULL)
-      {
-	  pxl = (rl2PrivPixelPtr) no_data;
-	  if (pxl->sampleType == RL2_SAMPLE_INT8 && pxl->nBands == 1)
-	    {
-
-		rl2PrivSamplePtr sample = pxl->Samples + 0;
-		nd_value = sample->int8;
-	    }
-      }
-    for (y = 0; y < height; y++)
+    if (rl2_set_coverage_policies
+	(cvg, strict_resolution, mixed_resolutions, section_paths,
+	 section_md5, section_summary) != RL2_OK)
       {
-	  for (x = 0; x < width; x++)
-	      *p++ = nd_value;
+	  fprintf (stderr,
+		   "ERROR: unable to set the Policies on the Coverage Object supporting \"%s\"\n",
+		   coverage);
+	  rl2_destroy_coverage (cvg);
+	  return NULL;
       }
+    return cvg;
 }
 
-static void
-void_uint8_raw_buffer (unsigned char *buffer, unsigned int width,
-		       unsigned int height, unsigned char num_bands,
-		       rl2PixelPtr no_data)
+RL2_DECLARE rl2VectorLayerPtr
+rl2_create_vector_layer_from_dbms (sqlite3 * handle, const char *coverage)
 {
-/* preparing an empty/void UINT8 raw buffer */
-    rl2PrivPixelPtr pxl = NULL;
-    unsigned int x;
-    unsigned int y;
-    unsigned char b;
-    unsigned char *p = buffer;
-    int has_nodata = 0;
-    if (no_data != NULL)
+/* attempting to create a Vector Layer Object from the DBMS definition */
+    char *sql;
+    int ret;
+    sqlite3_stmt *stmt;
+    char *f_table_name = NULL;
+    char *f_geometry_column = NULL;
+    int geometry_type;
+    int srid;
+    int spatial_index;
+    int ok = 0;
+    rl2VectorLayerPtr vector;
+
+/* querying the Vector Layer metadata defs */
+    sql =
+	"SELECT c.f_table_name, c.f_geometry_column, g.srid, g.geometry_type, "
+	"g.spatial_index_enabled FROM vector_coverages AS c "
+	"JOIN geometry_columns AS g ON (c.f_table_name = g.f_table_name "
+	"AND c.f_geometry_column = g.f_geometry_column) "
+	"WHERE Lower(c.coverage_name) = Lower(?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
       {
-	  pxl = (rl2PrivPixelPtr) no_data;
-	  if (pxl->sampleType == RL2_SAMPLE_UINT8 && pxl->nBands == num_bands)
-	      has_nodata = 1;
+	  fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
+	  return NULL;
       }
-    if (!has_nodata)
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
+    while (1)
       {
-	  for (y = 0; y < height; y++)
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		int len;
+		const char *name;
+		int ok_table_name = 0;
+		int ok_geometry_column = 0;
+		int ok_type = 0;
+		int ok_srid = 0;
+		int ok_index = 0;
+		if (sqlite3_column_type (stmt, 0) == SQLITE_TEXT)
+		  {
+		      name = (const char *) sqlite3_column_text (stmt, 0);
+		      len = strlen (name);
+		      if (f_table_name != NULL)
+			  free (f_table_name);
+		      f_table_name = malloc (len + 1);
+		      strcpy (f_table_name, name);
+		      ok_table_name = 1;
+		  }
+		if (sqlite3_column_type (stmt, 1) == SQLITE_TEXT)
+		  {
+		      name = (const char *) sqlite3_column_text (stmt, 1);
+		      len = strlen (name);
+		      if (f_geometry_column != NULL)
+			  free (f_geometry_column);
+		      f_geometry_column = malloc (len + 1);
+		      strcpy (f_geometry_column, name);
+		      ok_geometry_column = 1;
+		  }
+		if (sqlite3_column_type (stmt, 2) == SQLITE_INTEGER)
+		  {
+		      srid = sqlite3_column_int (stmt, 2);
+		      ok_srid = 1;
+		  }
+		if (sqlite3_column_type (stmt, 3) == SQLITE_INTEGER)
+		  {
+		      geometry_type = sqlite3_column_int (stmt, 3);
+		      ok_type = 1;
+		  }
+		if (sqlite3_column_type (stmt, 4) == SQLITE_INTEGER)
+		  {
+		      spatial_index = sqlite3_column_int (stmt, 4);
+		      ok_index = 1;
+		  }
+		if (ok_table_name && ok_geometry_column && ok_type && ok_srid
+		    && ok_index)
+		    ok = 1;
+	    }
+      }
+    sqlite3_finalize (stmt);
+
+    if (!ok)
+      {
+	  fprintf (stderr,
+		   "ERROR: unable to find a Vector Layer named \"%s\"\n",
+		   coverage);
+	  if (f_table_name != NULL)
+	      free (f_table_name);
+	  if (f_geometry_column != NULL)
+	      free (f_geometry_column);
+	  return NULL;
+      }
+
+    vector =
+	rl2_create_vector_layer (f_table_name, f_geometry_column,
+				 geometry_type, srid, spatial_index);
+    free (f_table_name);
+    free (f_geometry_column);
+    if (vector == NULL)
+      {
+	  fprintf (stderr,
+		   "ERROR: unable to create a Vector Layer Object supporting \"%s\"\n",
+		   coverage);
+	  return NULL;
+      }
+    return vector;
+}
+
+static void
+void_int8_raw_buffer (char *buffer, unsigned int width, unsigned int height,
+		      rl2PixelPtr no_data)
+{
+/* preparing an empty/void INT8 raw buffer */
+    rl2PrivPixelPtr pxl = NULL;
+    unsigned int x;
+    unsigned int y;
+    char *p = buffer;
+    char nd_value = 0;
+    if (no_data != NULL)
+      {
+	  pxl = (rl2PrivPixelPtr) no_data;
+	  if (pxl->sampleType == RL2_SAMPLE_INT8 && pxl->nBands == 1)
+	    {
+
+		rl2PrivSamplePtr sample = pxl->Samples + 0;
+		nd_value = sample->int8;
+	    }
+      }
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	      *p++ = nd_value;
+      }
+}
+
+static void
+void_uint8_raw_buffer (unsigned char *buffer, unsigned int width,
+		       unsigned int height, unsigned char num_bands,
+		       rl2PixelPtr no_data)
+{
+/* preparing an empty/void UINT8 raw buffer */
+    rl2PrivPixelPtr pxl = NULL;
+    unsigned int x;
+    unsigned int y;
+    unsigned char b;
+    unsigned char *p = buffer;
+    int has_nodata = 0;
+    if (no_data != NULL)
+      {
+	  pxl = (rl2PrivPixelPtr) no_data;
+	  if (pxl->sampleType == RL2_SAMPLE_UINT8 && pxl->nBands == num_bands)
+	      has_nodata = 1;
+      }
+    if (!has_nodata)
+      {
+	  for (y = 0; y < height; y++)
 	    {
 		for (x = 0; x < width; x++)
 		  {
@@ -1911,20 +2889,261 @@ void_raw_buffer_palette (unsigned char *buffer, unsigned int width,
       }
 }
 
+static void
+do_decode_tile (rl2AuxDecoderPtr decoder)
+{
+/* servicing an AuxDecoder Tile request */
+    decoder->raster =
+	(rl2PrivRasterPtr) rl2_raster_decode (decoder->scale,
+					      decoder->blob_odd,
+					      decoder->blob_odd_sz,
+					      decoder->blob_even,
+					      decoder->blob_even_sz,
+					      (rl2PalettePtr)
+					      (decoder->palette));
+    if (decoder->blob_odd != NULL)
+	free (decoder->blob_odd);
+    if (decoder->blob_even != NULL)
+	free (decoder->blob_even);
+    decoder->blob_odd = NULL;
+    decoder->blob_even = NULL;
+    decoder->palette = NULL;
+    if (decoder->raster == NULL)
+      {
+	  decoder->retcode = RL2_ERROR;
+	  return;
+      }
+    if (!rl2_copy_raw_pixels
+	((rl2RasterPtr) (decoder->raster), decoder->outbuf, decoder->width,
+	 decoder->height, decoder->sample_type, decoder->num_bands,
+	 decoder->auto_ndvi, decoder->red_band_index, decoder->nir_band_index,
+	 decoder->x_res, decoder->y_res, decoder->minx, decoder->maxy,
+	 decoder->tile_minx, decoder->tile_maxy,
+	 (rl2PixelPtr) (decoder->no_data),
+	 (rl2RasterSymbolizerPtr) (decoder->style),
+	 (rl2RasterStatisticsPtr) (decoder->stats)))
+      {
+	  decoder->retcode = RL2_ERROR;
+	  return;
+      }
+    rl2_destroy_raster ((rl2RasterPtr) (decoder->raster));
+    decoder->raster = NULL;
+    decoder->retcode = RL2_OK;
+}
+
+#ifdef _WIN32
+DWORD WINAPI
+doRunDecoderThread (void *arg)
+#else
+void *
+doRunDecoderThread (void *arg)
+#endif
+{
+/* threaded function: decoding a Tile */
+    rl2AuxDecoderPtr decoder = (rl2AuxDecoderPtr) arg;
+    do_decode_tile (decoder);
+#ifdef _WIN32
+    return 0;
+#else
+    pthread_exit (NULL);
+#endif
+}
+
+static void
+start_decoder_thread (rl2AuxDecoderPtr decoder)
+{
+/* starting a concurrent thread */
+#ifdef _WIN32
+    HANDLE thread_handle;
+    HANDLE *p_thread;
+    DWORD dwThreadId;
+    thread_handle =
+	CreateThread (NULL, 0, doRunDecoderThread, decoder, 0, &dwThreadId);
+    SetThreadPriority (thread_handle, THREAD_PRIORITY_IDLE);
+    p_thread = malloc (sizeof (HANDLE));
+    *p_thread = thread_handle;
+    decoder->opaque_thread_id = p_thread;
+#else
+    pthread_t thread_id;
+    pthread_t *p_thread;
+    int ok_prior = 0;
+    int policy;
+    int min_prio;
+    pthread_attr_t attr;
+    struct sched_param sp;
+    pthread_attr_init (&attr);
+    if (pthread_attr_setschedpolicy (&attr, SCHED_RR) == 0)
+      {
+	  /* attempting to set the lowest priority */
+	  if (pthread_attr_getschedpolicy (&attr, &policy) == 0)
+	    {
+		min_prio = sched_get_priority_min (policy);
+		sp.sched_priority = min_prio;
+		if (pthread_attr_setschedparam (&attr, &sp) == 0)
+		  {
+		      /* ok, setting the lowest priority */
+		      ok_prior = 1;
+		      pthread_create (&thread_id, &attr, doRunDecoderThread,
+				      decoder);
+		  }
+	    }
+      }
+    if (!ok_prior)
+      {
+	  /* failure: using standard priority */
+	  pthread_create (&thread_id, NULL, doRunDecoderThread, decoder);
+      }
+    p_thread = malloc (sizeof (pthread_t));
+    *p_thread = thread_id;
+    decoder->opaque_thread_id = p_thread;
+#endif
+}
+
+static int
+do_run_decoder_children (rl2AuxDecoderPtr * thread_slots, int thread_count)
+{
+/* concurrent execution of all decoder children threads */
+    rl2AuxDecoderPtr decoder;
+    int i;
+#ifdef _WIN32
+    HANDLE *handles;
+#endif
+
+    for (i = 0; i < thread_count; i++)
+      {
+	  /* starting all children threads */
+	  decoder = *(thread_slots + i);
+	  start_decoder_thread (decoder);
+      }
+
+/* waiting until all child threads exit */
+#ifdef _WIN32
+    handles = malloc (sizeof (HANDLE) * thread_count);
+    for (i = 0; i < thread_count; i++)
+      {
+	  /* initializing the HANDLEs array */
+	  HANDLE *pOpaque;
+	  decoder = *(thread_slots + i);
+	  pOpaque = (HANDLE *) (decoder->opaque_thread_id);
+	  *(handles + i) = *pOpaque;
+      }
+    WaitForMultipleObjects (thread_count, handles, TRUE, INFINITE);
+    free (handles);
+#else
+    for (i = 0; i < thread_count; i++)
+      {
+	  pthread_t *pOpaque;
+	  decoder = *(thread_slots + i);
+	  pOpaque = (pthread_t *) (decoder->opaque_thread_id);
+	  pthread_join (*pOpaque, NULL);
+      }
+#endif
+
+/* all children threads have now finished: resuming the main thread */
+    for (i = 0; i < thread_count; i++)
+      {
+	  /* cleaning up a request slot */
+	  decoder = *(thread_slots + i);
+	  if (decoder->blob_odd != NULL)
+	      free (decoder->blob_odd);
+	  if (decoder->blob_even != NULL)
+	      free (decoder->blob_even);
+	  if (decoder->raster != NULL)
+	      rl2_destroy_raster ((rl2RasterPtr) (decoder->raster));
+	  if (decoder->palette != NULL)
+	      rl2_destroy_palette ((rl2PalettePtr) (decoder->palette));
+	  if (decoder->opaque_thread_id != NULL)
+	      free (decoder->opaque_thread_id);
+	  decoder->blob_odd = NULL;
+	  decoder->blob_even = NULL;
+	  decoder->blob_odd_sz = 0;
+	  decoder->blob_even_sz = 0;
+	  decoder->raster = NULL;
+	  decoder->palette = NULL;
+	  decoder->opaque_thread_id = NULL;
+      }
+    for (i = 0; i < thread_count; i++)
+      {
+	  /* checking for eventual errors */
+	  decoder = *(thread_slots + i);
+	  if (decoder->retcode != RL2_OK)
+	    {
+		fprintf (stderr, ERR_FRMT64, decoder->tile_id);
+		goto error;
+	    }
+      }
+    return 1;
+
+  error:
+    return 0;
+}
+
 static int
-load_dbms_tiles_common (sqlite3 * handle, sqlite3_stmt * stmt_tiles,
-			sqlite3_stmt * stmt_data, unsigned char *outbuf,
-			unsigned int width,
-			unsigned int height, unsigned char sample_type,
-			unsigned char num_bands, double x_res, double y_res,
-			double minx, double maxy,
-			int scale, rl2PalettePtr palette, rl2PixelPtr no_data,
-			rl2RasterStylePtr style, rl2RasterStatisticsPtr stats)
+rl2_load_dbms_tiles_common (sqlite3 * handle, int max_threads,
+			    sqlite3_stmt * stmt_tiles,
+			    sqlite3_stmt * stmt_data, unsigned char *outbuf,
+			    unsigned int width, unsigned int height,
+			    unsigned char sample_type,
+			    unsigned char num_bands, unsigned char auto_ndvi,
+			    unsigned char red_band_index,
+			    unsigned char nir_band_index, double x_res,
+			    double y_res, double minx, double maxy, int scale,
+			    rl2PalettePtr palette, rl2PixelPtr no_data,
+			    rl2RasterSymbolizerPtr style,
+			    rl2RasterStatisticsPtr stats)
 {
 /* retrieving a full image from DBMS tiles */
     rl2RasterPtr raster = NULL;
     rl2PalettePtr plt = NULL;
     int ret;
+    rl2AuxDecoderPtr aux = NULL;
+    rl2AuxDecoderPtr decoder;
+    rl2AuxDecoderPtr *thread_slots = NULL;
+    int thread_count;
+    int iaux;
+
+    if (max_threads < 1)
+	max_threads = 1;
+    if (max_threads > 64)
+	max_threads = 64;
+/* allocating the AuxDecoder array */
+    aux = malloc (sizeof (rl2AuxDecoder) * max_threads);
+    if (aux == NULL)
+	return 0;
+    for (iaux = 0; iaux < max_threads; iaux++)
+      {
+	  /* initializing an empty AuxDecoder */
+	  decoder = aux + iaux;
+	  decoder->opaque_thread_id = NULL;
+	  decoder->blob_odd = NULL;
+	  decoder->blob_even = NULL;
+	  decoder->blob_odd_sz = 0;
+	  decoder->blob_even_sz = 0;
+	  decoder->outbuf = outbuf;
+	  decoder->width = width;
+	  decoder->height = height;
+	  decoder->sample_type = sample_type;
+	  decoder->num_bands = num_bands;
+	  decoder->auto_ndvi = auto_ndvi;
+	  decoder->red_band_index = red_band_index;
+	  decoder->nir_band_index = nir_band_index;
+	  decoder->x_res = x_res;
+	  decoder->y_res = y_res;
+	  decoder->scale = scale;
+	  decoder->minx = minx;
+	  decoder->maxy = maxy;
+	  decoder->no_data = (rl2PrivPixelPtr) no_data;
+	  decoder->style = (rl2PrivRasterSymbolizerPtr) style;
+	  decoder->stats = (rl2PrivRasterStatisticsPtr) stats;
+	  decoder->raster = NULL;
+	  decoder->palette = NULL;
+      }
+
+/* preparing the thread_slots stuct */
+    thread_slots = malloc (sizeof (rl2AuxDecoderPtr) * max_threads);
+    for (thread_count = 0; thread_count < max_threads; thread_count++)
+	*(thread_slots + thread_count) = NULL;
+    thread_count = 0;
 
 /* querying the tiles */
     while (1)
@@ -1934,6 +3153,7 @@ load_dbms_tiles_common (sqlite3 * handle, sqlite3_stmt * stmt_tiles,
 	      break;
 	  if (ret == SQLITE_ROW)
 	    {
+		int ok = 0;
 		const unsigned char *blob_odd = NULL;
 		int blob_odd_sz = 0;
 		const unsigned char *blob_even = NULL;
@@ -1941,6 +3161,10 @@ load_dbms_tiles_common (sqlite3 * handle, sqlite3_stmt * stmt_tiles,
 		sqlite3_int64 tile_id = sqlite3_column_int64 (stmt_tiles, 0);
 		double tile_minx = sqlite3_column_double (stmt_tiles, 1);
 		double tile_maxy = sqlite3_column_double (stmt_tiles, 2);
+		decoder = aux + thread_count;
+		decoder->tile_id = tile_id;
+		decoder->tile_minx = tile_minx;
+		decoder->tile_maxy = tile_maxy;
 
 		/* retrieving tile raw data from BLOBs */
 		sqlite3_reset (stmt_data);
@@ -1951,10 +3175,17 @@ load_dbms_tiles_common (sqlite3 * handle, sqlite3_stmt * stmt_tiles,
 		    break;
 		if (ret == SQLITE_ROW)
 		  {
+		      /* decoding a Tile - may be by using concurrent multithreading */
 		      if (sqlite3_column_type (stmt_data, 0) == SQLITE_BLOB)
 			{
 			    blob_odd = sqlite3_column_blob (stmt_data, 0);
 			    blob_odd_sz = sqlite3_column_bytes (stmt_data, 0);
+			    decoder->blob_odd = malloc (blob_odd_sz);
+			    if (decoder->blob_odd == NULL)
+				goto error;
+			    memcpy (decoder->blob_odd, blob_odd, blob_odd_sz);
+			    decoder->blob_odd_sz = blob_odd_sz;
+			    ok = 1;
 			}
 		      if (scale == RL2_SCALE_1)
 			{
@@ -1965,6 +3196,12 @@ load_dbms_tiles_common (sqlite3 * handle, sqlite3_stmt * stmt_tiles,
 				      sqlite3_column_blob (stmt_data, 1);
 				  blob_even_sz =
 				      sqlite3_column_bytes (stmt_data, 1);
+				  decoder->blob_even = malloc (blob_even_sz);
+				  if (decoder->blob_even == NULL)
+				      goto error;
+				  memcpy (decoder->blob_even, blob_even,
+					  blob_even_sz);
+				  decoder->blob_even_sz = blob_even_sz;
 			      }
 			}
 		  }
@@ -1975,23 +3212,46 @@ load_dbms_tiles_common (sqlite3 * handle, sqlite3_stmt * stmt_tiles,
 			       sqlite3_errmsg (handle));
 		      goto error;
 		  }
-		plt = rl2_clone_palette (palette);
-		raster =
-		    rl2_raster_decode (scale, blob_odd, blob_odd_sz, blob_even,
-				       blob_even_sz, plt);
-		plt = NULL;
-		if (raster == NULL)
+		if (!ok)
 		  {
-		      fprintf (stderr, ERR_FRMT64, tile_id);
-		      goto error;
+		      if (decoder->blob_odd != NULL)
+			  free (decoder->blob_odd);
+		      if (decoder->blob_even != NULL)
+			  free (decoder->blob_even);
+		      decoder->blob_odd = NULL;
+		      decoder->blob_even = NULL;
+		      decoder->blob_odd_sz = 0;
+		      decoder->blob_even_sz = 0;
+		  }
+		else
+		  {
+		      /* processing a Tile request (may be under parallel execution) */
+		      decoder->palette =
+			  (rl2PrivPalettePtr) rl2_clone_palette (palette);
+		      if (max_threads > 1)
+			{
+			    /* adopting a multithreaded strategy */
+			    *(thread_slots + thread_count) = decoder;
+			    thread_count++;
+			    if (thread_count == max_threads)
+			      {
+				  if (!do_run_decoder_children
+				      (thread_slots, thread_count))
+				      goto error;
+				  thread_count = 0;
+			      }
+			}
+		      else
+			{
+			    /* single thread execution */
+			    do_decode_tile (decoder);
+			    if (decoder->retcode != RL2_OK)
+			      {
+				  fprintf (stderr, ERR_FRMT64, tile_id);
+				  goto error;
+			      }
+			}
 		  }
-		if (!copy_raw_pixels
-		    (raster, outbuf, width, height, sample_type,
-		     num_bands, x_res, y_res, minx, maxy, tile_minx, tile_maxy,
-		     no_data, style, stats))
-		    goto error;
-		rl2_destroy_raster (raster);
-		raster = NULL;
 	    }
 	  else
 	    {
@@ -2001,10 +3261,39 @@ load_dbms_tiles_common (sqlite3 * handle, sqlite3_stmt * stmt_tiles,
 		goto error;
 	    }
       }
+    if (max_threads > 1 && thread_count > 0)
+      {
+	  /* launching the last multithreaded burst */
+	  if (!do_run_decoder_children (thread_slots, thread_count))
+	      goto error;
+      }
 
+    free (aux);
+    free (thread_slots);
     return 1;
 
   error:
+    if (aux != NULL)
+      {
+	  /* AuxDecoder cleanup */
+	  for (iaux = 0; iaux < max_threads; iaux++)
+	    {
+		decoder = aux + iaux;
+		if (decoder->blob_odd != NULL)
+		    free (decoder->blob_odd);
+		if (decoder->blob_even != NULL)
+		    free (decoder->blob_even);
+		if (decoder->raster != NULL)
+		    rl2_destroy_raster ((rl2RasterPtr) (decoder->raster));
+		if (decoder->palette != NULL)
+		    rl2_destroy_palette ((rl2PalettePtr) (decoder->palette));
+		if (decoder->opaque_thread_id != NULL)
+		    free (decoder->opaque_thread_id);
+	    }
+	  free (aux);
+      }
+    if (thread_slots != NULL)
+	free (thread_slots);
     if (raster != NULL)
 	rl2_destroy_raster (raster);
     if (plt != NULL)
@@ -2423,8 +3712,8 @@ load_triple_band_dbms_tiles (sqlite3 * handle, sqlite3_stmt * stmt_tiles,
 		      goto error;
 		  }
 		raster =
-		    rl2_raster_decode (scale, blob_odd, blob_odd_sz, blob_even,
-				       blob_even_sz, NULL);
+		    rl2_raster_decode (scale, blob_odd, blob_odd_sz,
+				       blob_even, blob_even_sz, NULL);
 		if (raster == NULL)
 		  {
 		      fprintf (stderr, ERR_FRMT64, tile_id);
@@ -2432,8 +3721,8 @@ load_triple_band_dbms_tiles (sqlite3 * handle, sqlite3_stmt * stmt_tiles,
 		  }
 		if (!copy_triple_band_raw_pixels
 		    (raster, outbuf, width, height, red_band, green_band,
-		     blue_band, x_res, y_res, minx, maxy, tile_minx, tile_maxy,
-		     no_data))
+		     blue_band, x_res, y_res, minx, maxy, tile_minx,
+		     tile_maxy, no_data))
 		    goto error;
 		rl2_destroy_raster (raster);
 		raster = NULL;
@@ -2585,9 +3874,10 @@ copy_mono_band_raw_pixels_u16 (rl2RasterPtr raster, unsigned char *outbuf,
 static int
 copy_mono_band_raw_pixels (rl2RasterPtr raster, unsigned char *outbuf,
 			   unsigned int width, unsigned int height,
-			   unsigned char mono_band, double x_res, double y_res,
-			   double minx, double maxy, double tile_minx,
-			   double tile_maxy, rl2PixelPtr no_data)
+			   unsigned char mono_band, double x_res,
+			   double y_res, double minx, double maxy,
+			   double tile_minx, double tile_maxy,
+			   rl2PixelPtr no_data)
 {
 /* copying raw pixels into the output buffer */
     unsigned int tile_width;
@@ -2718,9 +4008,10 @@ static int
 load_mono_band_dbms_tiles (sqlite3 * handle, sqlite3_stmt * stmt_tiles,
 			   sqlite3_stmt * stmt_data, unsigned char *outbuf,
 			   unsigned int width, unsigned int height,
-			   unsigned char mono_band, double x_res, double y_res,
-			   double minx, double miny, double maxx, double maxy,
-			   int level, int scale, rl2PixelPtr no_data)
+			   unsigned char mono_band, double x_res,
+			   double y_res, double minx, double miny,
+			   double maxx, double maxy, int level, int scale,
+			   rl2PixelPtr no_data)
 {
 /* retrieving a full image from DBMS tiles */
     rl2RasterPtr raster = NULL;
@@ -2779,8 +4070,8 @@ load_mono_band_dbms_tiles (sqlite3 * handle, sqlite3_stmt * stmt_tiles,
 		      goto error;
 		  }
 		raster =
-		    rl2_raster_decode (scale, blob_odd, blob_odd_sz, blob_even,
-				       blob_even_sz, NULL);
+		    rl2_raster_decode (scale, blob_odd, blob_odd_sz,
+				       blob_even, blob_even_sz, NULL);
 		if (raster == NULL)
 		  {
 		      fprintf (stderr, ERR_FRMT64, tile_id);
@@ -2811,14 +4102,17 @@ load_mono_band_dbms_tiles (sqlite3 * handle, sqlite3_stmt * stmt_tiles,
 }
 
 RL2_PRIVATE int
-load_dbms_tiles (sqlite3 * handle, sqlite3_stmt * stmt_tiles,
-		 sqlite3_stmt * stmt_data, unsigned char *outbuf,
-		 unsigned int width,
-		 unsigned int height, unsigned char sample_type,
-		 unsigned char num_bands, double x_res, double y_res,
-		 double minx, double miny, double maxx, double maxy, int level,
-		 int scale, rl2PalettePtr palette, rl2PixelPtr no_data,
-		 rl2RasterStylePtr style, rl2RasterStatisticsPtr stats)
+rl2_load_dbms_tiles (sqlite3 * handle, int max_threads,
+		     sqlite3_stmt * stmt_tiles, sqlite3_stmt * stmt_data,
+		     unsigned char *outbuf, unsigned int width,
+		     unsigned int height, unsigned char sample_type,
+		     unsigned char num_bands, unsigned char auto_ndvi,
+		     unsigned char red_band_index,
+		     unsigned char nir_band_index, double x_res, double y_res,
+		     double minx, double miny, double maxx, double maxy,
+		     int level, int scale, rl2PalettePtr palette,
+		     rl2PixelPtr no_data, rl2RasterSymbolizerPtr style,
+		     rl2RasterStatisticsPtr stats)
 {
 /* binding the query args */
     sqlite3_reset (stmt_tiles);
@@ -2829,38 +4123,44 @@ load_dbms_tiles (sqlite3 * handle, sqlite3_stmt * stmt_tiles,
     sqlite3_bind_double (stmt_tiles, 4, maxx);
     sqlite3_bind_double (stmt_tiles, 5, maxy);
 
-    if (!load_dbms_tiles_common
-	(handle, stmt_tiles, stmt_data, outbuf, width, height,
-	 sample_type, num_bands, x_res, y_res, minx, maxy, scale,
-	 palette, no_data, style, stats))
+    if (!rl2_load_dbms_tiles_common
+	(handle, max_threads, stmt_tiles, stmt_data, outbuf, width, height,
+	 sample_type, num_bands, auto_ndvi, red_band_index, nir_band_index,
+	 x_res, y_res, minx, maxy, scale, palette, no_data, style, stats))
 	return 0;
     return 1;
 }
 
 RL2_PRIVATE int
-load_dbms_tiles_section (sqlite3 * handle, sqlite3_int64 section_id,
-			 sqlite3_stmt * stmt_tiles, sqlite3_stmt * stmt_data,
-			 unsigned char *outbuf,
-			 unsigned int width, unsigned int height,
-			 unsigned char sample_type, unsigned char num_bands,
-			 double x_res, double y_res, double minx, double maxy,
-			 int scale, rl2PalettePtr palette, rl2PixelPtr no_data)
+rl2_load_dbms_tiles_section (sqlite3 * handle, int max_threads,
+			     sqlite3_int64 section_id,
+			     sqlite3_stmt * stmt_tiles,
+			     sqlite3_stmt * stmt_data, unsigned char *outbuf,
+			     unsigned int width, unsigned int height,
+			     unsigned char sample_type,
+			     unsigned char num_bands, unsigned char auto_ndvi,
+			     unsigned char red_band_index,
+			     unsigned char nir_band_index, double x_res,
+			     double y_res, double minx, double maxy,
+			     int scale, rl2PalettePtr palette,
+			     rl2PixelPtr no_data)
 {
 /* binding the query args */
     sqlite3_reset (stmt_tiles);
     sqlite3_clear_bindings (stmt_tiles);
     sqlite3_bind_int (stmt_tiles, 1, section_id);
 
-    if (!load_dbms_tiles_common
-	(handle, stmt_tiles, stmt_data, outbuf, width, height,
-	 sample_type, num_bands, x_res, y_res, minx, maxy, scale,
-	 palette, no_data, NULL, NULL))
+    if (!rl2_load_dbms_tiles_common
+	(handle, max_threads, stmt_tiles, stmt_data, outbuf, width, height,
+	 sample_type, num_bands, auto_ndvi, red_band_index, nir_band_index,
+	 x_res, y_res, minx, maxy, scale, palette, no_data, NULL, NULL))
 	return 0;
     return 1;
 }
 
 RL2_DECLARE int
 rl2_find_matching_resolution (sqlite3 * handle, rl2CoveragePtr cvg,
+			      int by_section, sqlite3_int64 section_id,
 			      double *x_res, double *y_res,
 			      unsigned char *level, unsigned char *scale)
 {
@@ -2876,20 +4176,53 @@ rl2_find_matching_resolution (sqlite3 * handle, rl2CoveragePtr cvg,
     char *xxcoverage;
     char *sql;
     sqlite3_stmt *stmt = NULL;
+    int mixed_resolutions = 0;
 
     if (coverage == NULL)
 	return RL2_ERROR;
     if (coverage->coverageName == NULL)
 	return RL2_ERROR;
 
-    xcoverage = sqlite3_mprintf ("%s_levels", coverage->coverageName);
-    xxcoverage = gaiaDoubleQuotedSql (xcoverage);
-    sqlite3_free (xcoverage);
-    sql =
-	sqlite3_mprintf
-	("SELECT pyramid_level, x_resolution_1_1, y_resolution_1_1, "
-	 "x_resolution_1_2, y_resolution_1_2, x_resolution_1_4, y_resolution_1_4, "
-	 "x_resolution_1_8, y_resolution_1_8 FROM \"%s\"", xxcoverage);
+    if (rl2_is_mixed_resolutions_coverage (handle, coverage->coverageName) > 0)
+	mixed_resolutions = 1;
+    if (!by_section && mixed_resolutions)
+      {
+	  /* undeclared Section on Mixed Resolution Coverage */
+	  return RL2_ERROR;
+      }
+
+    if (mixed_resolutions)
+      {
+	  /* Mixed Resolutions */
+	  char sctn[1024];
+#if defined(_WIN32) && !defined(__MINGW32__)
+	  sprintf (sctn, "%I64d", section_id);
+#else
+	  sprintf (sctn, "%lld", section_id);
+#endif
+	  xcoverage =
+	      sqlite3_mprintf ("%s_section_levels", coverage->coverageName);
+	  xxcoverage = rl2_double_quoted_sql (xcoverage);
+	  sqlite3_free (xcoverage);
+	  sql =
+	      sqlite3_mprintf
+	      ("SELECT pyramid_level, x_resolution_1_1, y_resolution_1_1, "
+	       "x_resolution_1_2, y_resolution_1_2, x_resolution_1_4, y_resolution_1_4, "
+	       "x_resolution_1_8, y_resolution_1_8 FROM \"%s\""
+	       "WHERE section_id = %s", xxcoverage, sctn);
+      }
+    else
+      {
+	  /* unique Resolution */
+	  xcoverage = sqlite3_mprintf ("%s_levels", coverage->coverageName);
+	  xxcoverage = rl2_double_quoted_sql (xcoverage);
+	  sqlite3_free (xcoverage);
+	  sql =
+	      sqlite3_mprintf
+	      ("SELECT pyramid_level, x_resolution_1_1, y_resolution_1_1, "
+	       "x_resolution_1_2, y_resolution_1_2, x_resolution_1_4, y_resolution_1_4, "
+	       "x_resolution_1_8, y_resolution_1_8 FROM \"%s\"", xxcoverage);
+      }
     free (xxcoverage);
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
@@ -3029,12 +4362,12 @@ rl2_find_matching_resolution (sqlite3 * handle, rl2CoveragePtr cvg,
     return RL2_ERROR;
 }
 
-static int
-has_styled_rgb_colors (rl2RasterStylePtr style)
+RL2_PRIVATE int
+rl2_has_styled_rgb_colors (rl2RasterSymbolizerPtr style)
 {
 /* testing for a RasterSymbolizer requiring RGB colors */
     rl2PrivColorMapPointPtr color;
-    rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
+    rl2PrivRasterSymbolizerPtr stl = (rl2PrivRasterSymbolizerPtr) style;
     if (stl == NULL)
 	return 0;
     if (stl->shadedRelief && stl->brightnessOnly)
@@ -3111,15 +4444,17 @@ rl2_get_shaded_relief_scale_factor (sqlite3 * handle, const char *coverage)
     return scale_factor;
 }
 
-static int
-get_raw_raster_data_common (sqlite3 * handle, rl2CoveragePtr cvg,
-			    unsigned int width, unsigned int height,
-			    double minx, double miny, double maxx, double maxy,
-			    double x_res, double y_res, unsigned char **buffer,
-			    int *buf_size, rl2PalettePtr * palette,
-			    unsigned char out_pixel, rl2PixelPtr bgcolor,
-			    rl2RasterStylePtr style,
-			    rl2RasterStatisticsPtr stats)
+RL2_PRIVATE int
+rl2_get_raw_raster_data_common (sqlite3 * handle, int max_threads,
+				rl2CoveragePtr cvg, int by_section,
+				sqlite3_int64 section_id, unsigned int width,
+				unsigned int height, double minx, double miny,
+				double maxx, double maxy, double x_res,
+				double y_res, unsigned char **buffer,
+				int *buf_size, rl2PalettePtr * palette,
+				unsigned char out_pixel, rl2PixelPtr bgcolor,
+				rl2RasterSymbolizerPtr style,
+				rl2RasterStatisticsPtr stats)
 {
 /* attempting to return a buffer containing raw pixels from the DBMS Coverage */
     rl2PalettePtr plt = NULL;
@@ -3150,6 +4485,11 @@ get_raw_raster_data_common (sqlite3 * handle, rl2CoveragePtr cvg,
     double relief_factor;
     float *shaded_relief = NULL;
     int shaded_relief_sz;
+    unsigned char red_band = 0;
+    unsigned char green_band = 0;
+    unsigned char blue_band = 0;
+    unsigned char nir_band = 0;
+    unsigned char auto_ndvi = 0;
 
     if (cvg == NULL || handle == NULL)
 	goto error;
@@ -3157,11 +4497,23 @@ get_raw_raster_data_common (sqlite3 * handle, rl2CoveragePtr cvg,
     if (coverage == NULL)
 	goto error;
     if (rl2_find_matching_resolution
-	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
+	(handle, cvg, by_section, section_id, &xx_res, &yy_res, &level,
+	 &scale) != RL2_OK)
 	goto error;
     if (rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands) !=
 	RL2_OK)
 	goto error;
+
+    if (rl2_get_dbms_coverage_default_bands
+	(handle, coverage, &red_band, &green_band, &blue_band,
+	 &nir_band) == RL2_OK)
+      {
+	  /* testing for Auto NDVI */
+	  if (rl2_is_dbms_coverage_auto_ndvi_enabled (handle, coverage) ==
+	      RL2_TRUE)
+	      auto_ndvi = 1;
+      }
+
     cvg_pixel_type = pixel_type;
 
     if (pixel_type == RL2_PIXEL_MONOCHROME && out_pixel == RL2_PIXEL_GRAYSCALE)
@@ -3243,10 +4595,10 @@ get_raw_raster_data_common (sqlite3 * handle, rl2CoveragePtr cvg,
 			    /* default: white */
 			    rl2_set_pixel_sample_uint8 (no_data, RL2_RED_BAND,
 							255);
-			    rl2_set_pixel_sample_uint8 (no_data, RL2_GREEN_BAND,
-							255);
-			    rl2_set_pixel_sample_uint8 (no_data, RL2_BLUE_BAND,
-							255);
+			    rl2_set_pixel_sample_uint8 (no_data,
+							RL2_GREEN_BAND, 255);
+			    rl2_set_pixel_sample_uint8 (no_data,
+							RL2_BLUE_BAND, 255);
 			}
 		  }
 	    }
@@ -3303,7 +4655,7 @@ get_raw_raster_data_common (sqlite3 * handle, rl2CoveragePtr cvg,
     if (out_pixel == RL2_PIXEL_GRAYSCALE
 	&& cvg_pixel_type == RL2_PIXEL_DATAGRID)
       {
-	  if (has_styled_rgb_colors (style))
+	  if (rl2_has_styled_rgb_colors (style))
 	    {
 		/* RGB RasterSymbolizer: promoting to RGB */
 		out_pixel = RL2_PIXEL_RGB;
@@ -3325,24 +4677,24 @@ get_raw_raster_data_common (sqlite3 * handle, rl2CoveragePtr cvg,
     if (style != NULL)
       {
 	  /* testing for Shaded Relief */
-	  if (rl2_has_raster_style_shaded_relief (style, &has_shaded_relief) !=
-	      RL2_OK)
+	  if (rl2_has_raster_symbolizer_shaded_relief
+	      (style, &has_shaded_relief) != RL2_OK)
 	      goto error;
 	  if (has_shaded_relief)
 	    {
 		/* preparing a Shaded Relief mask */
 		double scale_factor =
 		    rl2_get_shaded_relief_scale_factor (handle, coverage);
-		if (rl2_get_raster_style_shaded_relief
+		if (rl2_get_raster_symbolizer_shaded_relief
 		    (style, &brightness_only, &relief_factor) != RL2_OK)
 		    goto error;
 		if (rl2_build_shaded_relief_mask
-		    (handle, cvg, relief_factor, scale_factor, width, height,
-		     minx, miny, maxx, maxy, x_res, y_res, &shaded_relief,
-		     &shaded_relief_sz) != RL2_OK)
+		    (handle, max_threads, cvg, relief_factor, scale_factor,
+		     width, height, minx, miny, maxx, maxy, x_res, y_res,
+		     &shaded_relief, &shaded_relief_sz) != RL2_OK)
 		    goto error;
 
-		if (brightness_only || !has_styled_rgb_colors (style))
+		if (brightness_only || !rl2_has_styled_rgb_colors (style))
 		  {
 		      /* returning a Grayscale ShadedRelief (BrightnessOnly) */
 		      unsigned int row;
@@ -3379,14 +4731,35 @@ get_raw_raster_data_common (sqlite3 * handle, rl2CoveragePtr cvg,
 
 /* preparing the "tiles" SQL query */
     xtiles = sqlite3_mprintf ("%s_tiles", coverage);
-    xxtiles = gaiaDoubleQuotedSql (xtiles);
-    sql =
-	sqlite3_mprintf ("SELECT tile_id, MbrMinX(geometry), MbrMaxY(geometry) "
-			 "FROM \"%s\" "
-			 "WHERE pyramid_level = ? AND ROWID IN ( "
-			 "SELECT ROWID FROM SpatialIndex WHERE f_table_name = %Q "
-			 "AND search_frame = BuildMBR(?, ?, ?, ?))", xxtiles,
-			 xtiles);
+    xxtiles = rl2_double_quoted_sql (xtiles);
+    if (by_section)
+      {
+	  /* only from a single Section */
+	  char sctn[1024];
+#if defined(_WIN32) && !defined(__MINGW32__)
+	  sprintf (sctn, "%I64d", section_id);
+#else
+	  sprintf (sctn, "%lld", section_id);
+#endif
+	  sql =
+	      sqlite3_mprintf
+	      ("SELECT tile_id, MbrMinX(geometry), MbrMaxY(geometry) "
+	       "FROM \"%s\" "
+	       "WHERE section_id = %s AND pyramid_level = ? AND ROWID IN ( "
+	       "SELECT ROWID FROM SpatialIndex WHERE f_table_name = %Q "
+	       "AND search_frame = BuildMBR(?, ?, ?, ?))", xxtiles, sctn,
+	       xtiles);
+      }
+    else
+      {
+	  /* whole Coverage */
+	  sql =
+	      sqlite3_mprintf
+	      ("SELECT tile_id, MbrMinX(geometry), MbrMaxY(geometry) "
+	       "FROM \"%s\" " "WHERE pyramid_level = ? AND ROWID IN ( "
+	       "SELECT ROWID FROM SpatialIndex WHERE f_table_name = %Q "
+	       "AND search_frame = BuildMBR(?, ?, ?, ?))", xxtiles, xtiles);
+      }
     sqlite3_free (xtiles);
     free (xxtiles);
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_tiles, NULL);
@@ -3401,7 +4774,7 @@ get_raw_raster_data_common (sqlite3 * handle, rl2CoveragePtr cvg,
       {
 	  /* preparing the data SQL query - both ODD and EVEN */
 	  xdata = sqlite3_mprintf ("%s_tile_data", coverage);
-	  xxdata = gaiaDoubleQuotedSql (xdata);
+	  xxdata = rl2_double_quoted_sql (xdata);
 	  sqlite3_free (xdata);
 	  sql = sqlite3_mprintf ("SELECT tile_data_odd, tile_data_even "
 				 "FROM \"%s\" WHERE tile_id = ?", xxdata);
@@ -3420,7 +4793,7 @@ get_raw_raster_data_common (sqlite3 * handle, rl2CoveragePtr cvg,
       {
 	  /* preparing the data SQL query - only ODD */
 	  xdata = sqlite3_mprintf ("%s_tile_data", coverage);
-	  xxdata = gaiaDoubleQuotedSql (xdata);
+	  xxdata = rl2_double_quoted_sql (xdata);
 	  sqlite3_free (xdata);
 	  sql = sqlite3_mprintf ("SELECT tile_data_odd "
 				 "FROM \"%s\" WHERE tile_id = ?", xxdata);
@@ -3448,10 +4821,11 @@ get_raw_raster_data_common (sqlite3 * handle, rl2CoveragePtr cvg,
 	      void_raw_buffer (bufpix, width, height, sample_type, num_bands,
 			       no_data);
       }
-    if (!load_dbms_tiles
-	(handle, stmt_tiles, stmt_data, bufpix, width, height, sample_type,
-	 num_bands, xx_res, yy_res, minx, miny, maxx, maxy, level, scale, plt,
-	 no_data, style, stats))
+    if (!rl2_load_dbms_tiles
+	(handle, max_threads, stmt_tiles, stmt_data, bufpix, width, height,
+	 sample_type, num_bands, auto_ndvi, red_band, nir_band, xx_res,
+	 yy_res, minx, miny, maxx, maxy, level, scale, plt, no_data, style,
+	 stats))
 	goto error;
     if (kill_no_data != NULL)
 	rl2_destroy_pixel (kill_no_data);
@@ -3489,6 +4863,7 @@ get_raw_raster_data_common (sqlite3 * handle, rl2CoveragePtr cvg,
 	*palette = plt;
     if (shaded_relief != NULL)
 	free (shaded_relief);
+
     return RL2_OK;
 
   error:
@@ -3506,31 +4881,52 @@ get_raw_raster_data_common (sqlite3 * handle, rl2CoveragePtr cvg,
 }
 
 RL2_DECLARE int
-rl2_get_raw_raster_data (sqlite3 * handle, rl2CoveragePtr cvg,
-			 unsigned int width, unsigned int height,
-			 double minx, double miny, double maxx, double maxy,
-			 double x_res, double y_res, unsigned char **buffer,
-			 int *buf_size, rl2PalettePtr * palette,
-			 unsigned char out_pixel)
+rl2_get_raw_raster_data (sqlite3 * handle, int max_threads,
+			 rl2CoveragePtr cvg, unsigned int width,
+			 unsigned int height, double minx, double miny,
+			 double maxx, double maxy, double x_res, double y_res,
+			 unsigned char **buffer, int *buf_size,
+			 rl2PalettePtr * palette, unsigned char out_pixel)
 {
 /* attempting to return a buffer containing raw pixels from the DBMS Coverage */
-    return get_raw_raster_data_common (handle, cvg, width, height, minx, miny,
-				       maxx, maxy, x_res, y_res, buffer,
-				       buf_size, palette, out_pixel, NULL,
-				       NULL, NULL);
+    return rl2_get_raw_raster_data_common (handle, max_threads, cvg, 0, 0,
+					   width, height, minx, miny, maxx,
+					   maxy, x_res, y_res, buffer,
+					   buf_size, palette, out_pixel, NULL,
+					   NULL, NULL);
 }
 
 RL2_DECLARE int
-rl2_get_triple_band_raw_raster_data (sqlite3 * handle, rl2CoveragePtr cvg,
-				     unsigned int width,
-				     unsigned int height, double minx,
-				     double miny, double maxx, double maxy,
-				     double x_res, double y_res,
-				     unsigned char red_band,
-				     unsigned char green_band,
-				     unsigned char blue_band,
-				     unsigned char **buffer, int *buf_size,
-				     rl2PixelPtr bgcolor)
+rl2_get_section_raw_raster_data (sqlite3 * handle, int max_threads,
+				 rl2CoveragePtr cvg, sqlite3_int64 section_id,
+				 unsigned int width, unsigned int height,
+				 double minx, double miny, double maxx,
+				 double maxy, double x_res, double y_res,
+				 unsigned char **buffer, int *buf_size,
+				 rl2PalettePtr * palette,
+				 unsigned char out_pixel)
+{
+/* attempting to return a buffer containing raw pixels from the DBMS Coverage/Section */
+    return rl2_get_raw_raster_data_common (handle, max_threads, cvg, 1,
+					   section_id, width, height, minx,
+					   miny, maxx, maxy, x_res, y_res,
+					   buffer, buf_size, palette,
+					   out_pixel, NULL, NULL, NULL);
+}
+
+static int
+get_triple_band_raw_raster_data_common (int by_section, sqlite3 * handle,
+					rl2CoveragePtr cvg,
+					sqlite3_int64 section_id,
+					unsigned int width,
+					unsigned int height, double minx,
+					double miny, double maxx, double maxy,
+					double x_res, double y_res,
+					unsigned char red_band,
+					unsigned char green_band,
+					unsigned char blue_band,
+					unsigned char **buffer, int *buf_size,
+					rl2PixelPtr bgcolor)
 {
 /* attempting to return a buffer containing raw pixels from the DBMS Coverage */
     rl2PixelPtr no_data = NULL;
@@ -3559,7 +4955,8 @@ rl2_get_triple_band_raw_raster_data (sqlite3 * handle, rl2CoveragePtr cvg,
     if (coverage == NULL)
 	goto error;
     if (rl2_find_matching_resolution
-	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
+	(handle, cvg, by_section, section_id, &xx_res, &yy_res, &level,
+	 &scale) != RL2_OK)
 	goto error;
     if (rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands) !=
 	RL2_OK)
@@ -3596,14 +4993,35 @@ rl2_get_triple_band_raw_raster_data (sqlite3 * handle, rl2CoveragePtr cvg,
 
 /* preparing the "tiles" SQL query */
     xtiles = sqlite3_mprintf ("%s_tiles", coverage);
-    xxtiles = gaiaDoubleQuotedSql (xtiles);
-    sql =
-	sqlite3_mprintf ("SELECT tile_id, MbrMinX(geometry), MbrMaxY(geometry) "
-			 "FROM \"%s\" "
-			 "WHERE pyramid_level = ? AND ROWID IN ( "
-			 "SELECT ROWID FROM SpatialIndex WHERE f_table_name = %Q "
-			 "AND search_frame = BuildMBR(?, ?, ?, ?))", xxtiles,
-			 xtiles);
+    xxtiles = rl2_double_quoted_sql (xtiles);
+    if (by_section)
+      {
+	  /* only from a single Section */
+	  char sctn[1024];
+#if defined(_WIN32) && !defined(__MINGW32__)
+	  sprintf (sctn, "%I64d", section_id);
+#else
+	  sprintf (sctn, "%lld", section_id);
+#endif
+	  sql =
+	      sqlite3_mprintf
+	      ("SELECT tile_id, MbrMinX(geometry), MbrMaxY(geometry) "
+	       "FROM \"%s\" "
+	       "WHERE section_id = %s AND pyramid_level = ? AND ROWID IN ( "
+	       "SELECT ROWID FROM SpatialIndex WHERE f_table_name = %Q "
+	       "AND search_frame = BuildMBR(?, ?, ?, ?))", xxtiles, sctn,
+	       xtiles);
+      }
+    else
+      {
+	  /* whole Coverage */
+	  sql =
+	      sqlite3_mprintf
+	      ("SELECT tile_id, MbrMinX(geometry), MbrMaxY(geometry) "
+	       "FROM \"%s\" " "WHERE pyramid_level = ? AND ROWID IN ( "
+	       "SELECT ROWID FROM SpatialIndex WHERE f_table_name = %Q "
+	       "AND search_frame = BuildMBR(?, ?, ?, ?))", xxtiles, xtiles);
+      }
     sqlite3_free (xtiles);
     free (xxtiles);
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_tiles, NULL);
@@ -3616,7 +5034,7 @@ rl2_get_triple_band_raw_raster_data (sqlite3 * handle, rl2CoveragePtr cvg,
 
     /* preparing the data SQL query - both ODD and EVEN */
     xdata = sqlite3_mprintf ("%s_tile_data", coverage);
-    xxdata = gaiaDoubleQuotedSql (xdata);
+    xxdata = rl2_double_quoted_sql (xdata);
     sqlite3_free (xdata);
     sql = sqlite3_mprintf ("SELECT tile_data_odd, tile_data_even "
 			   "FROM \"%s\" WHERE tile_id = ?", xxdata);
@@ -3653,15 +5071,61 @@ rl2_get_triple_band_raw_raster_data (sqlite3 * handle, rl2CoveragePtr cvg,
     return RL2_ERROR;
 }
 
-static int
-get_mono_band_raw_raster_data_common (sqlite3 * handle, rl2CoveragePtr cvg,
-				      unsigned int width,
-				      unsigned int height, double minx,
-				      double miny, double maxx, double maxy,
-				      double x_res, double y_res,
-				      unsigned char **buffer, int *buf_size,
-				      unsigned char mono_band,
-				      rl2PixelPtr bgcolor)
+RL2_DECLARE int
+rl2_get_triple_band_raw_raster_data (sqlite3 * handle, rl2CoveragePtr cvg,
+				     unsigned int width,
+				     unsigned int height, double minx,
+				     double miny, double maxx, double maxy,
+				     double x_res, double y_res,
+				     unsigned char red_band,
+				     unsigned char green_band,
+				     unsigned char blue_band,
+				     unsigned char **buffer, int *buf_size,
+				     rl2PixelPtr bgcolor)
+{
+/* attempting to return a buffer containing raw pixels from the DBMS Coverage */
+    return get_triple_band_raw_raster_data_common (0, handle, cvg, 0, width,
+						   height, minx, miny, maxx,
+						   maxy, x_res, y_res,
+						   red_band, green_band,
+						   blue_band, buffer,
+						   buf_size, bgcolor);
+}
+
+RL2_DECLARE int
+rl2_get_section_triple_band_raw_raster_data (sqlite3 * handle,
+					     rl2CoveragePtr cvg,
+					     sqlite3_int64 section_id,
+					     unsigned int width,
+					     unsigned int height, double minx,
+					     double miny, double maxx,
+					     double maxy, double x_res,
+					     double y_res,
+					     unsigned char red_band,
+					     unsigned char green_band,
+					     unsigned char blue_band,
+					     unsigned char **buffer,
+					     int *buf_size, rl2PixelPtr bgcolor)
+{
+/* attempting to return a buffer containing raw pixels - Section */
+    return get_triple_band_raw_raster_data_common (1, handle, cvg, section_id,
+						   width, height, minx, miny,
+						   maxx, maxy, x_res, y_res,
+						   red_band, green_band,
+						   blue_band, buffer,
+						   buf_size, bgcolor);
+}
+
+static int
+get_mono_band_raw_raster_data_common (int by_section, sqlite3 * handle,
+				      rl2CoveragePtr cvg,
+				      sqlite3_int64 section_id,
+				      unsigned int width, unsigned int height,
+				      double minx, double miny, double maxx,
+				      double maxy, double x_res, double y_res,
+				      unsigned char **buffer, int *buf_size,
+				      unsigned char mono_band,
+				      rl2PixelPtr bgcolor)
 {
 /* attempting to return a buffer containing raw pixels from the DBMS Coverage */
     rl2PixelPtr no_data = NULL;
@@ -3690,7 +5154,8 @@ get_mono_band_raw_raster_data_common (sqlite3 * handle, rl2CoveragePtr cvg,
     if (coverage == NULL)
 	goto error;
     if (rl2_find_matching_resolution
-	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
+	(handle, cvg, by_section, section_id, &xx_res, &yy_res, &level,
+	 &scale) != RL2_OK)
 	goto error;
     if (rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands) !=
 	RL2_OK)
@@ -3723,14 +5188,36 @@ get_mono_band_raw_raster_data_common (sqlite3 * handle, rl2CoveragePtr cvg,
 
 /* preparing the "tiles" SQL query */
     xtiles = sqlite3_mprintf ("%s_tiles", coverage);
-    xxtiles = gaiaDoubleQuotedSql (xtiles);
-    sql =
-	sqlite3_mprintf ("SELECT tile_id, MbrMinX(geometry), MbrMaxY(geometry) "
-			 "FROM \"%s\" "
-			 "WHERE pyramid_level = ? AND ROWID IN ( "
-			 "SELECT ROWID FROM SpatialIndex WHERE f_table_name = %Q "
-			 "AND search_frame = BuildMBR(?, ?, ?, ?))", xxtiles,
-			 xtiles);
+    xxtiles = rl2_double_quoted_sql (xtiles);
+
+    if (by_section)
+      {
+	  /* single Section */
+	  char sctn[1024];
+#if defined(_WIN32) && !defined(__MINGW32__)
+	  sprintf (sctn, "%I64d", section_id);
+#else
+	  sprintf (sctn, "%lld", section_id);
+#endif
+	  sql =
+	      sqlite3_mprintf
+	      ("SELECT tile_id, MbrMinX(geometry), MbrMaxY(geometry) "
+	       "FROM \"%s\" "
+	       "WHERE section_id = %s AND pyramid_level = ? AND ROWID IN ( "
+	       "SELECT ROWID FROM SpatialIndex WHERE f_table_name = %Q "
+	       "AND search_frame = BuildMBR(?, ?, ?, ?))", xxtiles, sctn,
+	       xtiles);
+      }
+    else
+      {
+	  /* whole Coverage */
+	  sql =
+	      sqlite3_mprintf
+	      ("SELECT tile_id, MbrMinX(geometry), MbrMaxY(geometry) "
+	       "FROM \"%s\" " "WHERE pyramid_level = ? AND ROWID IN ( "
+	       "SELECT ROWID FROM SpatialIndex WHERE f_table_name = %Q "
+	       "AND search_frame = BuildMBR(?, ?, ?, ?))", xxtiles, xtiles);
+      }
     sqlite3_free (xtiles);
     free (xxtiles);
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_tiles, NULL);
@@ -3743,7 +5230,7 @@ get_mono_band_raw_raster_data_common (sqlite3 * handle, rl2CoveragePtr cvg,
 
     /* preparing the data SQL query - both ODD and EVEN */
     xdata = sqlite3_mprintf ("%s_tile_data", coverage);
-    xxdata = gaiaDoubleQuotedSql (xdata);
+    xxdata = rl2_double_quoted_sql (xdata);
     sqlite3_free (xdata);
     sql = sqlite3_mprintf ("SELECT tile_data_odd, tile_data_even "
 			   "FROM \"%s\" WHERE tile_id = ?", xxdata);
@@ -3790,22 +5277,45 @@ rl2_get_mono_band_raw_raster_data (sqlite3 * handle, rl2CoveragePtr cvg,
 				   rl2PixelPtr no_data)
 {
 /* attempting to return a buffer containing raw pixels from the DBMS Coverage */
-    return get_mono_band_raw_raster_data_common (handle, cvg, width, height,
-						 minx, miny, maxx, maxy,
-						 x_res, y_res, buffer,
+    return get_mono_band_raw_raster_data_common (0, handle, cvg, 0, width,
+						 height, minx, miny, maxx,
+						 maxy, x_res, y_res, buffer,
 						 buf_size, mono_band, no_data);
 }
 
 RL2_DECLARE int
-rl2_get_raw_raster_data_bgcolor (sqlite3 * handle, rl2CoveragePtr cvg,
-				 unsigned int width, unsigned int height,
-				 double minx, double miny, double maxx,
-				 double maxy, double x_res, double y_res,
+rl2_get_section_mono_band_raw_raster_data (sqlite3 * handle,
+					   rl2CoveragePtr cvg,
+					   sqlite3_int64 section_id,
+					   unsigned int width,
+					   unsigned int height, double minx,
+					   double miny, double maxx,
+					   double maxy, double x_res,
+					   double y_res,
+					   unsigned char mono_band,
+					   unsigned char **buffer,
+					   int *buf_size, rl2PixelPtr no_data)
+{
+/* attempting to return a buffer containing raw pixels from the DBMS Coverage */
+    return get_mono_band_raw_raster_data_common (1, handle, cvg, section_id,
+						 width, height, minx, miny,
+						 maxx, maxy, x_res, y_res,
+						 buffer, buf_size, mono_band,
+						 no_data);
+}
+
+RL2_DECLARE int
+rl2_get_raw_raster_data_bgcolor (sqlite3 * handle, int max_threads,
+				 rl2CoveragePtr cvg, unsigned int width,
+				 unsigned int height, double minx,
+				 double miny, double maxx, double maxy,
+				 double x_res, double y_res,
 				 unsigned char **buffer, int *buf_size,
 				 rl2PalettePtr * palette,
-				 unsigned char *out_pixel, unsigned char bg_red,
-				 unsigned char bg_green, unsigned char bg_blue,
-				 rl2RasterStylePtr style,
+				 unsigned char *out_pixel,
+				 unsigned char bg_red, unsigned char bg_green,
+				 unsigned char bg_blue,
+				 rl2RasterSymbolizerPtr style,
 				 rl2RasterStatisticsPtr stats)
 {
 /* attempting to return a buffer containing raw pixels from the DBMS Coverage + bgcolor */
@@ -3815,7 +5325,7 @@ rl2_get_raw_raster_data_bgcolor (sqlite3 * handle, rl2CoveragePtr cvg,
     unsigned char sample_type;
     unsigned char pixel_type;
     unsigned char num_bands;
-    rl2RasterStylePtr xstyle = style;
+    rl2RasterSymbolizerPtr xstyle = style;
 
     if (cvg == NULL || handle == NULL)
 	return RL2_ERROR;
@@ -3878,6 +5388,7 @@ rl2_get_raw_raster_data_bgcolor (sqlite3 * handle, rl2CoveragePtr cvg,
 		      free (red);
 		      free (green);
 		      free (blue);
+		      rl2_destroy_palette (palette);
 		  }
 	    }
 	  if (index < 0)
@@ -3887,29 +5398,29 @@ rl2_get_raw_raster_data_bgcolor (sqlite3 * handle, rl2CoveragePtr cvg,
 		  {
 		  case RL2_SAMPLE_1_BIT:
 		      no_data =
-			  rl2_create_pixel (RL2_SAMPLE_1_BIT, RL2_PIXEL_PALETTE,
-					    1);
+			  rl2_create_pixel (RL2_SAMPLE_1_BIT,
+					    RL2_PIXEL_PALETTE, 1);
 		      rl2_set_pixel_sample_1bit (no_data,
 						 (unsigned char) index);
 		      break;
 		  case RL2_SAMPLE_2_BIT:
 		      no_data =
-			  rl2_create_pixel (RL2_SAMPLE_2_BIT, RL2_PIXEL_PALETTE,
-					    1);
+			  rl2_create_pixel (RL2_SAMPLE_2_BIT,
+					    RL2_PIXEL_PALETTE, 1);
 		      rl2_set_pixel_sample_2bit (no_data,
 						 (unsigned char) index);
 		      break;
 		  case RL2_SAMPLE_4_BIT:
 		      no_data =
-			  rl2_create_pixel (RL2_SAMPLE_4_BIT, RL2_PIXEL_PALETTE,
-					    1);
+			  rl2_create_pixel (RL2_SAMPLE_4_BIT,
+					    RL2_PIXEL_PALETTE, 1);
 		      rl2_set_pixel_sample_4bit (no_data,
 						 (unsigned char) index);
 		      break;
 		  case RL2_SAMPLE_UINT8:
 		      no_data =
-			  rl2_create_pixel (RL2_SAMPLE_UINT8, RL2_PIXEL_PALETTE,
-					    1);
+			  rl2_create_pixel (RL2_SAMPLE_UINT8,
+					    RL2_PIXEL_PALETTE, 1);
 		      rl2_set_pixel_sample_uint8 (no_data, RL2_PALETTE_BAND,
 						  (unsigned char) index);
 		      break;
@@ -4010,7 +5521,7 @@ rl2_get_raw_raster_data_bgcolor (sqlite3 * handle, rl2CoveragePtr cvg,
 	  unsigned char pixel = *out_pixel;
 	  if (pixel == RL2_PIXEL_GRAYSCALE && pixel_type == RL2_PIXEL_DATAGRID)
 	    {
-		if (has_styled_rgb_colors (style))
+		if (rl2_has_styled_rgb_colors (style))
 		  {
 		      /* RGB RasterSymbolizer: promoting to RGB */
 		      pixel = RL2_PIXEL_RGB;
@@ -4036,15 +5547,15 @@ rl2_get_raw_raster_data_bgcolor (sqlite3 * handle, rl2CoveragePtr cvg,
     if (pixel_type == RL2_PIXEL_MONOCHROME)
 	xstyle = NULL;
     ret =
-	get_raw_raster_data_common (handle, cvg, width, height, minx, miny,
-				    maxx, maxy, x_res, y_res, buffer, buf_size,
-				    palette, *out_pixel, no_data, xstyle,
-				    stats);
+	rl2_get_raw_raster_data_common (handle, max_threads, cvg, 0, 0, width,
+					height, minx, miny, maxx, maxy, x_res,
+					y_res, buffer, buf_size, palette,
+					*out_pixel, no_data, xstyle, stats);
     if (no_data != NULL)
 	rl2_destroy_pixel (no_data);
     if (*out_pixel == RL2_PIXEL_GRAYSCALE && pixel_type == RL2_PIXEL_DATAGRID)
       {
-	  if (has_styled_rgb_colors (style))
+	  if (rl2_has_styled_rgb_colors (style))
 	    {
 		/* RGB RasterSymbolizer: promoting to RGB */
 		*out_pixel = RL2_PIXEL_RGB;
@@ -4052,13 +5563,14 @@ rl2_get_raw_raster_data_bgcolor (sqlite3 * handle, rl2CoveragePtr cvg,
       }
     if (pixel_type == RL2_PIXEL_MONOCHROME)
       {
-	  unsigned char red;
-	  unsigned char green;
-	  unsigned char blue;
+	  unsigned char red = 0;
+	  unsigned char green = 0;
+	  unsigned char blue = 0;
 	  int ok = 0;
 	  if (style != NULL)
 	    {
-		rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
+		rl2PrivRasterSymbolizerPtr stl =
+		    (rl2PrivRasterSymbolizerPtr) style;
 		if (stl->categorize != NULL)
 		  {
 		      rl2PrivColorMapPointPtr color = stl->categorize->first;
@@ -4209,8 +5721,9 @@ rl2_update_dbms_palette (sqlite3 * handle, const char *coverage,
 	return RL2_ERROR;
 
     sql =
-	sqlite3_mprintf ("SELECT sample_type, pixel_type FROM raster_coverages "
-			 "WHERE Lower(coverage_name) = Lower(%Q)", coverage);
+	sqlite3_mprintf
+	("SELECT sample_type, pixel_type FROM raster_coverages "
+	 "WHERE Lower(coverage_name) = Lower(%Q)", coverage);
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -4459,7 +5972,7 @@ rl2_update_dbms_coverage (sqlite3 * handle, const char *coverage)
 
 /* Extent query stmt */
     xtable = sqlite3_mprintf ("%s_sections", coverage);
-    xxtable = gaiaDoubleQuotedSql (xtable);
+    xxtable = rl2_double_quoted_sql (xtable);
     sqlite3_free (xtable);
     sql =
 	sqlite3_mprintf
@@ -4535,7 +6048,7 @@ rl2_update_dbms_coverage (sqlite3 * handle, const char *coverage)
 
 /* Raster Statistics query stmt */
     xtable = sqlite3_mprintf ("%s_sections", coverage);
-    xxtable = gaiaDoubleQuotedSql (xtable);
+    xxtable = rl2_double_quoted_sql (xtable);
     sqlite3_free (xtable);
     sql = sqlite3_mprintf ("SELECT statistics FROM \"%s\"", xxtable);
     free (xxtable);
@@ -4646,23 +6159,24 @@ rl2_update_dbms_coverage (sqlite3 * handle, const char *coverage)
     return RL2_ERROR;
 }
 
-RL2_DECLARE rl2RasterStylePtr
-rl2_create_raster_style_from_dbms (sqlite3 * handle, const char *coverage,
-				   const char *style)
+RL2_DECLARE rl2CoverageStylePtr
+rl2_create_coverage_style_from_dbms (sqlite3 * handle, const char *coverage,
+				     const char *style)
 {
-/* attempting to load and parse a RasterSymbolizer style */
+/* attempting to load and parse a Coverage Style */
     const char *sql;
     int ret;
     sqlite3_stmt *stmt = NULL;
-    rl2RasterStylePtr stl = NULL;
+    rl2CoverageStylePtr stl = NULL;
     char *name = NULL;
-    char *title = NULL;
-    char *abstract = NULL;
     unsigned char *xml = NULL;
+    int done = 0;
 
-    sql = "SELECT style_name, XB_GetTitle(style), XB_GetAbstract(style), "
-	"XB_GetDocument(style) FROM SE_raster_styled_layers "
-	"WHERE Lower(coverage_name) = Lower(?) AND Lower(style_name) = Lower(?)";
+    sql = "SELECT s.style_name, XB_GetDocument(s.style) "
+	"FROM SE_raster_styled_layers AS r "
+	"JOIN SE_raster_styles AS s ON (r.style_id = s.style_id) "
+	"WHERE Lower(r.coverage_name) = Lower(?) AND "
+	"Lower(s.style_name) = Lower(?)";
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
       {
@@ -4684,33 +6198,115 @@ rl2_create_raster_style_from_dbms (sqlite3 * handle, const char *coverage,
 		int len;
 		const char *str;
 		const unsigned char *ustr;
-		if (sqlite3_column_type (stmt, 0) == SQLITE_TEXT)
-		  {
-		      str = (const char *) sqlite3_column_text (stmt, 0);
-		      len = strlen (str);
-		      name = malloc (len + 1);
-		      strcpy (name, str);
-		  }
-		if (sqlite3_column_type (stmt, 1) == SQLITE_TEXT)
-		  {
-		      str = (const char *) sqlite3_column_text (stmt, 1);
-		      len = strlen (str);
-		      title = malloc (len + 1);
-		      strcpy (title, str);
-		  }
-		if (sqlite3_column_type (stmt, 2) == SQLITE_TEXT)
+		if (!done)
 		  {
-		      str = (const char *) sqlite3_column_text (stmt, 2);
-		      len = strlen (str);
-		      abstract = malloc (len + 1);
-		      strcpy (abstract, str);
+		      /* reteiving just the first reference in case of duplicates */
+		      done = 1;
+		      if (sqlite3_column_type (stmt, 0) == SQLITE_TEXT)
+			{
+			    str = (const char *) sqlite3_column_text (stmt, 0);
+			    len = strlen (str);
+			    name = malloc (len + 1);
+			    strcpy (name, str);
+			}
+		      if (sqlite3_column_type (stmt, 1) == SQLITE_TEXT)
+			{
+			    ustr = sqlite3_column_text (stmt, 1);
+			    len = strlen ((const char *) ustr);
+			    xml = malloc (len + 1);
+			    strcpy ((char *) xml, (const char *) ustr);
+			}
 		  }
-		if (sqlite3_column_type (stmt, 3) == SQLITE_TEXT)
+	    }
+	  else
+	    {
+		fprintf (stderr, "SQL error: %s\n%s\n", sql,
+			 sqlite3_errmsg (handle));
+		goto error;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    stmt = NULL;
+
+    if (name == NULL || xml == NULL)
+      {
+	  if (name != NULL)
+	      free (name);
+	  if (xml != NULL)
+	      free (xml);
+	  goto error;
+      }
+    stl = coverage_style_from_xml (name, xml);
+    if (stl == NULL)
+	goto error;
+    return stl;
+
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    if (stl != NULL)
+	rl2_destroy_coverage_style (stl);
+    return NULL;
+}
+
+RL2_DECLARE rl2FeatureTypeStylePtr
+rl2_create_feature_type_style_from_dbms (sqlite3 * handle,
+					 const char *coverage,
+					 const char *style)
+{
+/* attempting to load and parse a Feature Type Style */
+    const char *sql;
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+    rl2FeatureTypeStylePtr stl = NULL;
+    char *name = NULL;
+    unsigned char *xml = NULL;
+    int done = 0;
+
+    sql = "SELECT s.style_name, XB_GetDocument(s.style) "
+	"FROM SE_vector_styled_layers AS v "
+	"JOIN SE_vector_styles AS s ON (v.style_id = s.style_id) "
+	"WHERE Lower(v.coverage_name) = Lower(?) "
+	"AND Lower(s.style_name) = Lower(?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
+	  goto error;
+      }
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
+    sqlite3_bind_text (stmt, 2, style, strlen (style), SQLITE_STATIC);
+    while (1)
+      {
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		int len;
+		const char *str;
+		const unsigned char *ustr;
+		if (!done)
 		  {
-		      ustr = sqlite3_column_text (stmt, 3);
-		      len = strlen ((const char *) ustr);
-		      xml = malloc (len + 1);
-		      strcpy ((char *) xml, (const char *) ustr);
+		      /* reteiving just the first reference in case of duplicates */
+		      done = 1;
+		      if (sqlite3_column_type (stmt, 0) == SQLITE_TEXT)
+			{
+			    str = (const char *) sqlite3_column_text (stmt, 0);
+			    len = strlen (str);
+			    name = malloc (len + 1);
+			    strcpy (name, str);
+			}
+		      if (sqlite3_column_type (stmt, 1) == SQLITE_TEXT)
+			{
+			    ustr = sqlite3_column_text (stmt, 1);
+			    len = strlen ((const char *) ustr);
+			    xml = malloc (len + 1);
+			    strcpy ((char *) xml, (const char *) ustr);
+			}
 		  }
 	    }
 	  else
@@ -4727,15 +6323,11 @@ rl2_create_raster_style_from_dbms (sqlite3 * handle, const char *coverage,
       {
 	  if (name != NULL)
 	      free (name);
-	  if (title != NULL)
-	      free (title);
-	  if (abstract != NULL)
-	      free (abstract);
 	  if (xml != NULL)
 	      free (xml);
 	  goto error;
       }
-    stl = raster_style_from_sld_se_xml (name, title, abstract, xml);
+    stl = feature_type_style_from_xml (name, xml);
     if (stl == NULL)
 	goto error;
     return stl;
@@ -4744,7 +6336,7 @@ rl2_create_raster_style_from_dbms (sqlite3 * handle, const char *coverage,
     if (stmt != NULL)
 	sqlite3_finalize (stmt);
     if (stl != NULL)
-	rl2_destroy_raster_style (stl);
+	rl2_destroy_feature_type_style (stl);
     return NULL;
 }
 
@@ -4775,10 +6367,11 @@ test_named_layer (sqlite3 * handle, const char *groupName,
 
     ok = 0;
 /* testing if the Raster Coverage belong to the Layer Group */
-    sql = sqlite3_mprintf ("SELECT coverage_name FROM SE_styled_group_refs "
-			   "WHERE Lower(group_name) = Lower(%Q) AND "
-			   "Lower(coverage_name) = Lower(%Q)", groupName,
-			   namedLayer);
+    sql =
+	sqlite3_mprintf
+	("SELECT raster_coverage_name FROM SE_styled_group_refs "
+	 "WHERE Lower(group_name) = Lower(%Q) AND "
+	 "Lower(raster_coverage_name) = Lower(%Q)", groupName, namedLayer);
     ret = sqlite3_get_table (handle, sql, &results, &rows, &columns, NULL);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -4802,10 +6395,12 @@ test_named_style (sqlite3 * handle, const char *namedLayer,
     int ok = 0;
 /* testing if the Layer Style exists */
     char *sql =
-	sqlite3_mprintf ("SELECT style_name FROM SE_raster_styled_layers "
-			 "WHERE Lower(coverage_name) = Lower(%Q) AND "
-			 "Lower(style_name) = Lower(%Q)", namedLayer,
-			 namedStyle);
+	sqlite3_mprintf
+	("SELECT style_name FROM SE_raster_styled_layers AS r "
+	 "JOIN SE_raster_styles AS s ON (r.style_id = s.style_id) "
+	 "WHERE Lower(r.coverage_name) = Lower(%Q) AND "
+	 "Lower(s.style_name) = Lower(%Q)", namedLayer,
+	 namedStyle);
     ret = sqlite3_get_table (handle, sql, &results, &rows, &columns, NULL);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -4826,15 +6421,15 @@ rl2_create_group_style_from_dbms (sqlite3 * handle, const char *group,
     sqlite3_stmt *stmt = NULL;
     rl2GroupStylePtr stl = NULL;
     char *name = NULL;
-    char *title = NULL;
-    char *abstract = NULL;
     unsigned char *xml = NULL;
     rl2PrivGroupStylePtr grp_stl;
     rl2PrivChildStylePtr child;
+    int done = 0;
 
-    sql = "SELECT style_name, XB_GetTitle(style), XB_GetAbstract(style), "
-	"XB_GetDocument(style) FROM SE_group_styles "
-	"WHERE Lower(group_name) = Lower(?) AND Lower(style_name) = Lower(?)";
+    sql = "SELECT s.style_name, XB_GetDocument(s.style) "
+	"FROM SE_styled_group_styles AS g "
+	"JOIN SE_group_styles AS s ON (g.style_id = s.style_id) "
+	"WHERE Lower(g.group_name) = Lower(?) AND Lower(s.style_name) = Lower(?)";
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
       {
@@ -4856,33 +6451,24 @@ rl2_create_group_style_from_dbms (sqlite3 * handle, const char *group,
 		int len;
 		const char *str;
 		const unsigned char *ustr;
-		if (sqlite3_column_type (stmt, 0) == SQLITE_TEXT)
-		  {
-		      str = (const char *) sqlite3_column_text (stmt, 0);
-		      len = strlen (str);
-		      name = malloc (len + 1);
-		      strcpy (name, str);
-		  }
-		if (sqlite3_column_type (stmt, 1) == SQLITE_TEXT)
-		  {
-		      str = (const char *) sqlite3_column_text (stmt, 1);
-		      len = strlen (str);
-		      title = malloc (len + 1);
-		      strcpy (title, str);
-		  }
-		if (sqlite3_column_type (stmt, 2) == SQLITE_TEXT)
+		if (!done)
 		  {
-		      str = (const char *) sqlite3_column_text (stmt, 2);
-		      len = strlen (str);
-		      abstract = malloc (len + 1);
-		      strcpy (abstract, str);
-		  }
-		if (sqlite3_column_type (stmt, 3) == SQLITE_TEXT)
-		  {
-		      ustr = sqlite3_column_text (stmt, 3);
-		      len = strlen ((const char *) ustr);
-		      xml = malloc (len + 1);
-		      strcpy ((char *) xml, (const char *) ustr);
+		      /* retrieving just the first reference in case of duplicates */
+		      done = 1;
+		      if (sqlite3_column_type (stmt, 0) == SQLITE_TEXT)
+			{
+			    str = (const char *) sqlite3_column_text (stmt, 0);
+			    len = strlen (str);
+			    name = malloc (len + 1);
+			    strcpy (name, str);
+			}
+		      if (sqlite3_column_type (stmt, 1) == SQLITE_TEXT)
+			{
+			    ustr = sqlite3_column_text (stmt, 1);
+			    len = strlen ((const char *) ustr);
+			    xml = malloc (len + 1);
+			    strcpy ((char *) xml, (const char *) ustr);
+			}
 		  }
 	    }
 	  else
@@ -4899,17 +6485,13 @@ rl2_create_group_style_from_dbms (sqlite3 * handle, const char *group,
       {
 	  if (name != NULL)
 	      free (name);
-	  if (title != NULL)
-	      free (title);
-	  if (abstract != NULL)
-	      free (abstract);
 	  if (xml != NULL)
 	      free (xml);
 	  goto error;
       }
 
 /* final validation */
-    stl = group_style_from_sld_xml (name, title, abstract, xml);
+    stl = group_style_from_sld_xml (name, xml);
     if (stl == NULL)
 	goto error;
     grp_stl = (rl2PrivGroupStylePtr) stl;
@@ -5008,3 +6590,1128 @@ rl2_create_raster_statistics_from_dbms (sqlite3 * handle, const char *coverage)
 	sqlite3_finalize (stmt);
     return NULL;
 }
+
+
+RL2_DECLARE int
+rl2_check_raster_coverage_destination (sqlite3 * sqlite,
+				       const char *coverage_name)
+{
+/* checking if a Raster Coverage does not exist on Main */
+    int ret;
+    char *xcoverage;
+    sqlite3_stmt *stmt = NULL;
+    const char *sql;
+    int count = 0;
+
+    sql = "SELECT count(*) FROM main.raster_coverages "
+	"WHERE Lower(coverage_name) = Lower(?)";
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("SELECT check Raster Coverage destination SQL error: %s\n",
+		  sqlite3_errmsg (sqlite));
+	  goto error;
+      }
+
+/* querying the raster_covrages meta-table */
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
+		       SQLITE_STATIC);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	      count = sqlite3_column_int (stmt, 0);
+	  else
+	    {
+		fprintf (stderr,
+			 "SELECT check Raster Coverage destination sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (sqlite));
+		goto error;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    stmt = NULL;
+    if (count != 0)
+	return RL2_ERROR;
+
+/* checking for the coverage-LEVELS table */
+    xcoverage = sqlite3_mprintf ("%s_levels", coverage_name);
+    sql = "SELECT count(*) FROM main.sqlite_master "
+	"WHERE Lower(tbl_name) = Lower(?)";
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("SELECT check Raster Coverage destination SQL error: %s\n",
+		  sqlite3_errmsg (sqlite));
+	  goto error;
+      }
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, xcoverage, strlen (xcoverage), sqlite3_free);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	      count = sqlite3_column_int (stmt, 0);
+	  else
+	    {
+		fprintf (stderr,
+			 "SELECT check Raster Coverage destination sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (sqlite));
+		goto error;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    stmt = NULL;
+    if (count != 0)
+	return RL2_ERROR;
+
+/* checking for the coverage-SECTIONS table */
+    xcoverage = sqlite3_mprintf ("%s_sections", coverage_name);
+    sql = "SELECT count(*) FROM main.sqlite_master "
+	"WHERE Lower(tbl_name) = Lower(?)";
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("SELECT check Raster Coverage destination SQL error: %s\n",
+		  sqlite3_errmsg (sqlite));
+	  goto error;
+      }
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, xcoverage, strlen (xcoverage), sqlite3_free);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	      count = sqlite3_column_int (stmt, 0);
+	  else
+	    {
+		fprintf (stderr,
+			 "SELECT check Raster Coverage destination sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (sqlite));
+		goto error;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    stmt = NULL;
+    if (count != 0)
+	return RL2_ERROR;
+
+/* checking for the coverage-TILE_DATA table */
+    xcoverage = sqlite3_mprintf ("%s_tile_data", coverage_name);
+    sql = "SELECT count(*) FROM main.sqlite_master "
+	"WHERE Lower(tbl_name) = Lower(?)";
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("SELECT check Raster Coverage destination SQL error: %s\n",
+		  sqlite3_errmsg (sqlite));
+	  goto error;
+      }
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, xcoverage, strlen (xcoverage), sqlite3_free);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	      count = sqlite3_column_int (stmt, 0);
+	  else
+	    {
+		fprintf (stderr,
+			 "SELECT check Raster Coverage destination sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (sqlite));
+		goto error;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    stmt = NULL;
+    if (count != 0)
+	return RL2_ERROR;
+
+/* checking for the coverage-TILES table */
+    xcoverage = sqlite3_mprintf ("%s_tiles", coverage_name);
+    sql = "SELECT count(*) FROM main.sqlite_master "
+	"WHERE Lower(tbl_name) = Lower(?)";
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("SELECT check Raster Coverage destination SQL error: %s\n",
+		  sqlite3_errmsg (sqlite));
+	  goto error;
+      }
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, xcoverage, strlen (xcoverage), sqlite3_free);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	      count = sqlite3_column_int (stmt, 0);
+	  else
+	    {
+		fprintf (stderr,
+			 "SELECT check Raster Coverage destination sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (sqlite));
+		goto error;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    stmt = NULL;
+    if (count != 0)
+	return RL2_ERROR;
+
+    return RL2_OK;
+
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_check_raster_coverage_origin (sqlite3 * sqlite,
+				  const char *db_prefix,
+				  const char *coverage_name)
+{
+/* checking if a Raster Coverage does really exist on some attached DB */
+    int ret;
+    char *xcoverage;
+    char *xdb = NULL;
+    sqlite3_stmt *stmt = NULL;
+    char *sql;
+    int count = 0;
+
+    xdb = rl2_double_quoted_sql (db_prefix);
+    sql = sqlite3_mprintf ("SELECT count(*) FROM \"%s\".raster_coverages "
+			   "WHERE Lower(coverage_name) = Lower(?)", xdb);
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("SELECT check Raster Coverage origin SQL error: %s\n",
+		  sqlite3_errmsg (sqlite));
+	  goto error;
+      }
+
+/* querying the raster_covrages meta-table */
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
+		       SQLITE_STATIC);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	      count = sqlite3_column_int (stmt, 0);
+	  else
+	    {
+		fprintf (stderr,
+			 "SELECT check Raster Coverage origin sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (sqlite));
+		goto error;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    stmt = NULL;
+    if (count != 1)
+	goto error;
+
+/* checking for the coverage-LEVELS table */
+    xcoverage = sqlite3_mprintf ("%s_levels", coverage_name);
+    sql = sqlite3_mprintf ("SELECT count(*) FROM \"%s\".sqlite_master "
+			   "WHERE Lower(tbl_name) = Lower(?) AND type = 'table'",
+			   xdb);
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("SELECT check Raster Coverage origin SQL error: %s\n",
+		  sqlite3_errmsg (sqlite));
+	  goto error;
+      }
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, xcoverage, strlen (xcoverage), sqlite3_free);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	      count = sqlite3_column_int (stmt, 0);
+	  else
+	    {
+		fprintf (stderr,
+			 "SELECT check Raster Coverage origin sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (sqlite));
+		goto error;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    stmt = NULL;
+    if (count != 1)
+	goto error;
+
+/* checking for the coverage-SECTIONS table */
+    xcoverage = sqlite3_mprintf ("%s_sections", coverage_name);
+    sql = sqlite3_mprintf ("SELECT count(*) FROM \"%s\".sqlite_master "
+			   "WHERE Lower(tbl_name) = Lower(?) AND type = 'table'",
+			   xdb);
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("SELECT check Raster Coverage origin SQL error: %s\n",
+		  sqlite3_errmsg (sqlite));
+	  goto error;
+      }
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, xcoverage, strlen (xcoverage), sqlite3_free);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	      count = sqlite3_column_int (stmt, 0);
+	  else
+	    {
+		fprintf (stderr,
+			 "SELECT check Raster Coverage origin sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (sqlite));
+		goto error;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    stmt = NULL;
+    if (count != 1)
+	goto error;
+
+/* checking for the coverage-TILE_DATA table */
+    xcoverage = sqlite3_mprintf ("%s_tile_data", coverage_name);
+    sql = sqlite3_mprintf ("SELECT count(*) FROM \"%s\".sqlite_master "
+			   "WHERE Lower(tbl_name) = Lower(?) AND type = 'table'",
+			   xdb);
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("SELECT check Raster Coverage origin SQL error: %s\n",
+		  sqlite3_errmsg (sqlite));
+	  goto error;
+      }
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, xcoverage, strlen (xcoverage), sqlite3_free);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	      count = sqlite3_column_int (stmt, 0);
+	  else
+	    {
+		fprintf (stderr,
+			 "SELECT check Raster Coverage origin sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (sqlite));
+		goto error;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    stmt = NULL;
+    if (count != 1)
+	goto error;
+
+/* checking for the coverage-TILES table */
+    xcoverage = sqlite3_mprintf ("%s_tiles", coverage_name);
+    sql = sqlite3_mprintf ("SELECT count(*) FROM \"%s\".sqlite_master "
+			   "WHERE Lower(tbl_name) = Lower(?) AND type = 'table'",
+			   xdb);
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("SELECT check Raster Coverage origin SQL error: %s\n",
+		  sqlite3_errmsg (sqlite));
+	  goto error;
+      }
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, xcoverage, strlen (xcoverage), sqlite3_free);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	      count = sqlite3_column_int (stmt, 0);
+	  else
+	    {
+		fprintf (stderr,
+			 "SELECT check Raster Coverage origin sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (sqlite));
+		goto error;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    stmt = NULL;
+    if (count != 1)
+	goto error;
+
+    free (xdb);
+    return RL2_OK;
+
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    if (xdb != NULL)
+	free (xdb);
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_copy_raster_coverage (sqlite3 * sqlite, const char *db_prefix,
+			  const char *coverage_name)
+{
+/* copying a Raster Coverages from an attached DB into Main */
+    int ret;
+    char *sql;
+    sqlite3_stmt *stmt = NULL;
+    char *xdb = NULL;
+    char *xcoverage;
+    char *xxcoverage;
+    const char *sample_type;
+    const char *pixel_type;
+    int num_bands;
+    const char *compression;
+    int quality;
+    int tile_width;
+    int tile_height;
+    int srid;
+    double horz_res;
+    double vert_res;
+    unsigned char sample;
+    unsigned char pixel;
+    unsigned char compr;
+    int strict_resolution = 0;
+    int mixed_resolutions = 0;
+    int section_paths = 0;
+    int section_md5 = 0;
+    int section_summary = 0;
+    rl2PixelPtr no_data = NULL;
+    rl2PalettePtr palette = NULL;
+    char *title = NULL;
+    char *abstract = NULL;
+    unsigned char *statistics = NULL;
+    int statistics_sz;
+    int ok_geo = 0;
+    int ok_bbox = 0;
+    double geo_minx;
+    double geo_miny;
+    double geo_maxx;
+    double geo_maxy;
+    double ext_minx;
+    double ext_miny;
+    double ext_maxx;
+    double ext_maxy;
+    int ok_is_queryable = 0;
+    int ok_red_band_index = 0;
+    int ok_green_band_index = 0;
+    int ok_blue_band_index = 0;
+    int ok_nir_band_index = 0;
+    int ok_enable_auto_ndvi = 0;
+    int is_queryable;
+    int red_band_index;
+    int green_band_index;
+    int blue_band_index;
+    int nir_band_index;
+    int enable_auto_ndvi;
+    int ok = 0;
+
+    xdb = rl2_double_quoted_sql (db_prefix);
+
+/* querying the ording Coverage defs */
+    sql =
+	sqlite3_mprintf
+	("SELECT sample_type, pixel_type, num_bands, compression, quality, tile_width, "
+	 "tile_height, horz_resolution, vert_resolution, srid, nodata_pixel, "
+	 "strict_resolution, mixed_resolutions, section_paths, section_md5, "
+	 "section_summary, title, abstract, statistics, geo_minx, geo_miny, "
+	 "geo_maxx, geo_maxy, extent_minx, extent_miny, extent_maxx, extent_maxy, "
+	 "is_queryable, red_band_index, green_band_index, blue_band_index, "
+	 "nir_band_index, enable_auto_ndvi, palette "
+	 "FROM \"%s\".raster_coverages WHERE Lower(coverage_name) = Lower(?)",
+	 xdb);
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (sqlite));
+	  goto error;
+      }
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, coverage_name, strlen (coverage_name),
+		       SQLITE_STATIC);
+    while (1)
+      {
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		int ok_sample = 0;
+		int ok_pixel = 0;
+		int ok_num_bands = 0;
+		int ok_compression = 0;
+		int ok_quality = 0;
+		int ok_tile_width = 0;
+		int ok_tile_height = 0;
+		int ok_x_res = 0;
+		int ok_y_res = 0;
+		int ok_srid = 0;
+		int ok_nodata = 1;
+		int ok_strict = 0;
+		int ok_mixed = 0;
+		int ok_paths = 0;
+		int ok_md5 = 0;
+		int ok_summary = 0;
+		const char *value;
+		int len;
+		if (sqlite3_column_type (stmt, 0) == SQLITE_TEXT)
+		  {
+		      value = (const char *) sqlite3_column_text (stmt, 0);
+		      if (strcasecmp (value, "1-BIT") == 0)
+			{
+			    ok_sample = 1;
+			    sample_type = value;
+			}
+		      if (strcasecmp (value, "2-BIT") == 0)
+			{
+			    ok_sample = 1;
+			    sample_type = value;
+			}
+		      if (strcasecmp (value, "4-BIT") == 0)
+			{
+			    ok_sample = 1;
+			    sample_type = value;
+			}
+		      if (strcasecmp (value, "INT8") == 0)
+			{
+			    ok_sample = 1;
+			    sample_type = value;
+			}
+		      if (strcasecmp (value, "UINT8") == 0)
+			{
+			    ok_sample = 1;
+			    sample_type = value;
+			}
+		      if (strcasecmp (value, "INT16") == 0)
+			{
+			    ok_sample = 1;
+			    sample_type = value;
+			}
+		      if (strcasecmp (value, "UINT16") == 0)
+			{
+			    ok_sample = 1;
+			    sample_type = value;
+			}
+		      if (strcasecmp (value, "INT32") == 0)
+			{
+			    ok_sample = 1;
+			    sample_type = value;
+			}
+		      if (strcasecmp (value, "UINT32") == 0)
+			{
+			    ok_sample = 1;
+			    sample_type = value;
+			}
+		      if (strcasecmp (value, "FLOAT") == 0)
+			{
+			    ok_sample = 1;
+			    sample_type = value;
+			}
+		      if (strcasecmp (value, "DOUBLE") == 0)
+			{
+			    ok_sample = 1;
+			    sample_type = value;
+			}
+		      sample = RL2_SAMPLE_UNKNOWN;
+		      if (ok_sample)
+			{
+			    if (strcasecmp (sample_type, "1-BIT") == 0)
+				sample = RL2_SAMPLE_1_BIT;
+			    if (strcasecmp (sample_type, "2-BIT") == 0)
+				sample = RL2_SAMPLE_2_BIT;
+			    if (strcasecmp (sample_type, "4-BIT") == 0)
+				sample = RL2_SAMPLE_4_BIT;
+			    if (strcasecmp (sample_type, "INT8") == 0)
+				sample = RL2_SAMPLE_INT8;
+			    if (strcasecmp (sample_type, "UINT8") == 0)
+				sample = RL2_SAMPLE_UINT8;
+			    if (strcasecmp (sample_type, "INT16") == 0)
+				sample = RL2_SAMPLE_INT16;
+			    if (strcasecmp (sample_type, "UINT16") == 0)
+				sample = RL2_SAMPLE_UINT16;
+			    if (strcasecmp (sample_type, "INT32") == 0)
+				sample = RL2_SAMPLE_INT32;
+			    if (strcasecmp (sample_type, "UINT32") == 0)
+				sample = RL2_SAMPLE_UINT32;
+			    if (strcasecmp (sample_type, "FLOAT") == 0)
+				sample = RL2_SAMPLE_FLOAT;
+			    if (strcasecmp (sample_type, "DOUBLE") == 0)
+				sample = RL2_SAMPLE_DOUBLE;
+			}
+		  }
+		if (sqlite3_column_type (stmt, 1) == SQLITE_TEXT)
+		  {
+		      value = (const char *) sqlite3_column_text (stmt, 1);
+		      if (strcasecmp (value, "MONOCHROME") == 0)
+			{
+			    ok_pixel = 1;
+			    pixel_type = value;
+			}
+		      if (strcasecmp (value, "PALETTE") == 0)
+			{
+			    ok_pixel = 1;
+			    pixel_type = value;
+			}
+		      if (strcasecmp (value, "GRAYSCALE") == 0)
+			{
+			    ok_pixel = 1;
+			    pixel_type = value;
+			}
+		      if (strcasecmp (value, "RGB") == 0)
+			{
+			    ok_pixel = 1;
+			    pixel_type = value;
+			}
+		      if (strcasecmp (value, "MULTIBAND") == 0)
+			{
+			    ok_pixel = 1;
+			    pixel_type = value;
+			}
+		      if (strcasecmp (value, "DATAGRID") == 0)
+			{
+			    ok_pixel = 1;
+			    pixel_type = value;
+			}
+		      pixel = RL2_PIXEL_UNKNOWN;
+		      if (ok_pixel)
+			{
+			    if (strcasecmp (pixel_type, "MONOCHROME") == 0)
+				pixel = RL2_PIXEL_MONOCHROME;
+			    if (strcasecmp (pixel_type, "GRAYSCALE") == 0)
+				pixel = RL2_PIXEL_GRAYSCALE;
+			    if (strcasecmp (pixel_type, "PALETTE") == 0)
+				pixel = RL2_PIXEL_PALETTE;
+			    if (strcasecmp (pixel_type, "RGB") == 0)
+				pixel = RL2_PIXEL_RGB;
+			    if (strcasecmp (pixel_type, "DATAGRID") == 0)
+				pixel = RL2_PIXEL_DATAGRID;
+			    if (strcasecmp (pixel_type, "MULTIBAND") == 0)
+				pixel = RL2_PIXEL_MULTIBAND;
+			}
+		  }
+		if (sqlite3_column_type (stmt, 2) == SQLITE_INTEGER)
+		  {
+		      num_bands = sqlite3_column_int (stmt, 2);
+		      ok_num_bands = 1;
+		  }
+		if (sqlite3_column_type (stmt, 3) == SQLITE_TEXT)
+		  {
+		      value = (const char *) sqlite3_column_text (stmt, 3);
+		      if (strcasecmp (value, "NONE") == 0)
+			{
+			    ok_compression = 1;
+			    compression = value;
+			}
+		      if (strcasecmp (value, "DEFLATE") == 0)
+			{
+			    ok_compression = 1;
+			    compression = value;
+			}
+		      if (strcasecmp (value, "DEFLATE_NO") == 0)
+			{
+			    ok_compression = 1;
+			    compression = value;
+			}
+		      if (strcasecmp (value, "LZMA") == 0)
+			{
+			    ok_compression = 1;
+			    compression = value;
+			}
+		      if (strcasecmp (value, "LZMA_NO") == 0)
+			{
+			    ok_compression = 1;
+			    compression = value;
+			}
+		      if (strcasecmp (value, "PNG") == 0)
+			{
+			    ok_compression = 1;
+			    compression = value;
+			}
+		      if (strcasecmp (value, "JPEG") == 0)
+			{
+			    ok_compression = 1;
+			    compression = value;
+			}
+		      if (strcasecmp (value, "LOSSY_WEBP") == 0)
+			{
+			    ok_compression = 1;
+			    compression = value;
+			}
+		      if (strcasecmp (value, "LOSSLESS_WEBP") == 0)
+			{
+			    ok_compression = 1;
+			    compression = value;
+			}
+		      if (strcasecmp (value, "CCITTFAX4") == 0)
+			{
+			    ok_compression = 1;
+			    compression = value;
+			}
+		      if (strcasecmp (value, "CHARLS") == 0)
+			{
+			    ok_compression = 1;
+			    compression = value;
+			}
+		      if (strcasecmp (value, "LOSSY_JP2") == 0)
+			{
+			    ok_compression = 1;
+			    compression = value;
+			}
+		      if (strcasecmp (value, "LOSSLESS_JP2") == 0)
+			{
+			    ok_compression = 1;
+			    compression = value;
+			}
+		      compr = RL2_COMPRESSION_UNKNOWN;
+		      if (ok_compression)
+			{
+			    if (strcasecmp (compression, "NONE") == 0)
+				compr = RL2_COMPRESSION_NONE;
+			    if (strcasecmp (compression, "DEFLATE") == 0)
+				compr = RL2_COMPRESSION_DEFLATE;
+			    if (strcasecmp (compression, "DEFLATE_NO") == 0)
+				compr = RL2_COMPRESSION_DEFLATE_NO;
+			    if (strcasecmp (compression, "LZMA") == 0)
+				compr = RL2_COMPRESSION_LZMA;
+			    if (strcasecmp (compression, "LZMA_NO") == 0)
+				compr = RL2_COMPRESSION_LZMA_NO;
+			    if (strcasecmp (compression, "PNG") == 0)
+				compr = RL2_COMPRESSION_PNG;
+			    if (strcasecmp (compression, "GIF") == 0)
+				compr = RL2_COMPRESSION_GIF;
+			    if (strcasecmp (compression, "JPEG") == 0)
+				compr = RL2_COMPRESSION_JPEG;
+			    if (strcasecmp (compression, "WEBP") == 0)
+				compr = RL2_COMPRESSION_LOSSY_WEBP;
+			    if (strcasecmp (compression, "LL_WEBP") == 0)
+				compr = RL2_COMPRESSION_LOSSLESS_WEBP;
+			    if (strcasecmp (compression, "FAX4") == 0)
+				compr = RL2_COMPRESSION_CCITTFAX4;
+			    if (strcasecmp (compression, "CHARLS") == 0)
+				compr = RL2_COMPRESSION_CHARLS;
+			    if (strcasecmp (compression, "JP2") == 0)
+				compr = RL2_COMPRESSION_LOSSY_JP2;
+			    if (strcasecmp (compression, "LL_JP2") == 0)
+				compr = RL2_COMPRESSION_LOSSLESS_JP2;
+			}
+		  }
+		if (sqlite3_column_type (stmt, 4) == SQLITE_INTEGER)
+		  {
+		      quality = sqlite3_column_int (stmt, 4);
+		      ok_quality = 1;
+		  }
+		if (sqlite3_column_type (stmt, 5) == SQLITE_INTEGER)
+		  {
+		      tile_width = sqlite3_column_int (stmt, 5);
+		      ok_tile_width = 1;
+		  }
+		if (sqlite3_column_type (stmt, 6) == SQLITE_INTEGER)
+		  {
+		      tile_height = sqlite3_column_int (stmt, 6);
+		      ok_tile_height = 1;
+		  }
+		if (sqlite3_column_type (stmt, 7) == SQLITE_FLOAT)
+		  {
+		      horz_res = sqlite3_column_double (stmt, 7);
+		      ok_x_res = 1;
+		  }
+		if (sqlite3_column_type (stmt, 8) == SQLITE_FLOAT)
+		  {
+		      vert_res = sqlite3_column_double (stmt, 8);
+		      ok_y_res = 1;
+		  }
+		if (sqlite3_column_type (stmt, 9) == SQLITE_INTEGER)
+		  {
+		      srid = sqlite3_column_int (stmt, 9);
+		      ok_srid = 1;
+		  }
+		if (sqlite3_column_type (stmt, 10) == SQLITE_BLOB)
+		  {
+		      const unsigned char *blob =
+			  sqlite3_column_blob (stmt, 10);
+		      int blob_sz = sqlite3_column_bytes (stmt, 10);
+		      no_data = rl2_deserialize_dbms_pixel (blob, blob_sz);
+		      if (no_data == NULL)
+			  ok_nodata = 0;
+		  }
+		if (sqlite3_column_type (stmt, 11) == SQLITE_INTEGER)
+		  {
+		      strict_resolution = sqlite3_column_int (stmt, 11);
+		      ok_strict = 1;
+		  }
+		if (sqlite3_column_type (stmt, 12) == SQLITE_INTEGER)
+		  {
+		      mixed_resolutions = sqlite3_column_int (stmt, 12);
+		      ok_mixed = 1;
+		  }
+		if (sqlite3_column_type (stmt, 13) == SQLITE_INTEGER)
+		  {
+		      section_paths = sqlite3_column_int (stmt, 13);
+		      ok_paths = 1;
+		  }
+		if (sqlite3_column_type (stmt, 14) == SQLITE_INTEGER)
+		  {
+		      section_md5 = sqlite3_column_int (stmt, 14);
+		      ok_md5 = 1;
+		  }
+		if (sqlite3_column_type (stmt, 15) == SQLITE_INTEGER)
+		  {
+		      section_summary = sqlite3_column_int (stmt, 15);
+		      ok_summary = 1;
+		  }
+		if (sqlite3_column_type (stmt, 16) == SQLITE_TEXT)
+		  {
+		      value = (const char *) sqlite3_column_text (stmt, 16);
+		      len = strlen (value);
+		      title = malloc (len + 1);
+		      strcpy (title, value);
+		  }
+		if (sqlite3_column_type (stmt, 17) == SQLITE_TEXT)
+		  {
+		      value = (const char *) sqlite3_column_text (stmt, 17);
+		      len = strlen (value);
+		      abstract = malloc (len + 1);
+		      strcpy (abstract, value);
+		  }
+		if (sqlite3_column_type (stmt, 18) == SQLITE_BLOB)
+		  {
+		      statistics_sz = sqlite3_column_bytes (stmt, 18);
+		      statistics = malloc (statistics_sz);
+		      memcpy (statistics,
+			      (const unsigned char *)
+			      sqlite3_column_blob (stmt, 18), statistics_sz);
+		  }
+		if (sqlite3_column_type (stmt, 19) == SQLITE_FLOAT)
+		  {
+		      geo_minx = sqlite3_column_double (stmt, 19);
+		      ok_geo++;
+		  }
+		if (sqlite3_column_type (stmt, 20) == SQLITE_FLOAT)
+		  {
+		      geo_miny = sqlite3_column_double (stmt, 20);
+		      ok_geo++;
+		  }
+		if (sqlite3_column_type (stmt, 21) == SQLITE_FLOAT)
+		  {
+		      geo_maxx = sqlite3_column_double (stmt, 21);
+		      ok_geo++;
+		  }
+		if (sqlite3_column_type (stmt, 22) == SQLITE_FLOAT)
+		  {
+		      geo_maxy = sqlite3_column_double (stmt, 22);
+		      ok_geo++;
+		  }
+		if (sqlite3_column_type (stmt, 23) == SQLITE_FLOAT)
+		  {
+		      ext_minx = sqlite3_column_double (stmt, 23);
+		      ok_bbox++;
+		  }
+		if (sqlite3_column_type (stmt, 24) == SQLITE_FLOAT)
+		  {
+		      ext_miny = sqlite3_column_double (stmt, 24);
+		      ok_bbox++;
+		  }
+		if (sqlite3_column_type (stmt, 25) == SQLITE_FLOAT)
+		  {
+		      ext_maxx = sqlite3_column_double (stmt, 25);
+		      ok_bbox++;
+		  }
+		if (sqlite3_column_type (stmt, 26) == SQLITE_FLOAT)
+		  {
+		      ext_maxy = sqlite3_column_double (stmt, 26);
+		      ok_bbox++;
+		  }
+		if (sqlite3_column_type (stmt, 27) == SQLITE_INTEGER)
+		  {
+		      is_queryable = sqlite3_column_int (stmt, 27);
+		      ok_is_queryable = 1;
+		  }
+		if (sqlite3_column_type (stmt, 28) == SQLITE_INTEGER)
+		  {
+		      red_band_index = sqlite3_column_int (stmt, 28);
+		      ok_red_band_index = 1;
+		  }
+		if (sqlite3_column_type (stmt, 29) == SQLITE_INTEGER)
+		  {
+		      green_band_index = sqlite3_column_int (stmt, 29);
+		      ok_red_band_index = 1;
+		  }
+		if (sqlite3_column_type (stmt, 30) == SQLITE_INTEGER)
+		  {
+		      blue_band_index = sqlite3_column_int (stmt, 30);
+		      ok_red_band_index = 1;
+		  }
+		if (sqlite3_column_type (stmt, 31) == SQLITE_INTEGER)
+		  {
+		      nir_band_index = sqlite3_column_int (stmt, 31);
+		      ok_red_band_index = 1;
+		  }
+		if (sqlite3_column_type (stmt, 32) == SQLITE_INTEGER)
+		  {
+		      enable_auto_ndvi = sqlite3_column_int (stmt, 32);
+		      ok_enable_auto_ndvi = 1;
+		  }
+		if (sqlite3_column_type (stmt, 33) == SQLITE_BLOB)
+		  {
+		      const unsigned char *blob =
+			  sqlite3_column_blob (stmt, 33);
+		      int blob_sz = sqlite3_column_bytes (stmt, 33);
+		      palette = rl2_deserialize_dbms_palette (blob, blob_sz);
+		  }
+		if (ok_sample && ok_pixel && ok_num_bands && ok_compression
+		    && ok_quality && ok_tile_width && ok_tile_height
+		    && ok_x_res && ok_y_res && ok_srid && ok_nodata
+		    && ok_strict && ok_mixed && ok_paths && ok_md5
+		    && ok_summary)
+		    ok = 1;
+		if (ok_geo != 4)
+		    ok_geo = 0;
+		if (ok_bbox != 4)
+		    ok_bbox = 0;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    stmt = NULL;
+    if (!ok)
+	goto error;
+
+/* creating the destination Coverage */
+    ret = rl2_create_dbms_coverage (sqlite, coverage_name, sample, pixel,
+				    (unsigned char) num_bands,
+				    compr, quality,
+				    (unsigned short) tile_width,
+				    (unsigned short) tile_height, srid,
+				    horz_res, vert_res, no_data, palette,
+				    strict_resolution, mixed_resolutions,
+				    section_paths, section_md5,
+				    section_summary);
+    if (no_data != NULL)
+	rl2_destroy_pixel (no_data);
+    if (palette != NULL)
+	rl2_destroy_palette (palette);
+    if (ret != RL2_OK)
+	goto error;
+
+/* completing the destination coverage */
+    sql = "UPDATE main.raster_coverages SET title = ?, "
+	"abstract = ?, statistics = ?, geo_minx = ?, geo_miny = ?, geo_maxx = ?, "
+	"geo_maxy = ?, extent_minx = ?, extent_miny = ?, extent_maxx = ?, "
+	"extent_maxy = ?, is_queryable = ?, red_band_index = ?, green_band_index = ?, "
+	"blue_band_index = ?, nir_band_index = ?, enable_auto_ndvi = ? "
+	"WHERE Lower(coverage_name) = Lower(?)";
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (sqlite));
+	  goto error;
+      }
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    if (title == NULL)
+	sqlite3_bind_null (stmt, 1);
+    else
+	sqlite3_bind_text (stmt, 1, title, strlen (title), free);
+    if (abstract == NULL)
+	sqlite3_bind_null (stmt, 2);
+    else
+	sqlite3_bind_text (stmt, 2, abstract, strlen (abstract), free);
+    if (statistics == NULL)
+	sqlite3_bind_null (stmt, 3);
+    else
+	sqlite3_bind_blob (stmt, 3, statistics, statistics_sz, free);
+    if (ok_geo)
+      {
+	  sqlite3_bind_double (stmt, 4, geo_minx);
+	  sqlite3_bind_double (stmt, 5, geo_miny);
+	  sqlite3_bind_double (stmt, 6, geo_maxx);
+	  sqlite3_bind_double (stmt, 7, geo_maxy);
+      }
+    else
+      {
+	  sqlite3_bind_null (stmt, 4);
+	  sqlite3_bind_null (stmt, 5);
+	  sqlite3_bind_null (stmt, 6);
+	  sqlite3_bind_null (stmt, 7);
+      }
+    if (ok_bbox)
+      {
+	  sqlite3_bind_double (stmt, 8, ext_minx);
+	  sqlite3_bind_double (stmt, 9, ext_miny);
+	  sqlite3_bind_double (stmt, 10, ext_maxx);
+	  sqlite3_bind_double (stmt, 11, ext_maxy);
+      }
+    else
+      {
+	  sqlite3_bind_null (stmt, 8);
+	  sqlite3_bind_null (stmt, 9);
+	  sqlite3_bind_null (stmt, 10);
+	  sqlite3_bind_null (stmt, 11);
+      }
+    if (!ok_is_queryable)
+	sqlite3_bind_null (stmt, 12);
+    else
+	sqlite3_bind_int (stmt, 12, is_queryable);
+    if (!ok_red_band_index)
+	sqlite3_bind_null (stmt, 13);
+    else
+	sqlite3_bind_int (stmt, 13, red_band_index);
+    if (!ok_green_band_index)
+	sqlite3_bind_null (stmt, 14);
+    else
+	sqlite3_bind_int (stmt, 14, green_band_index);
+    if (!ok_blue_band_index)
+	sqlite3_bind_null (stmt, 15);
+    else
+	sqlite3_bind_int (stmt, 15, blue_band_index);
+    if (!ok_nir_band_index)
+	sqlite3_bind_null (stmt, 16);
+    else
+	sqlite3_bind_int (stmt, 16, nir_band_index);
+    if (!ok_enable_auto_ndvi)
+	sqlite3_bind_null (stmt, 17);
+    else
+	sqlite3_bind_int (stmt, 17, enable_auto_ndvi);
+    sqlite3_bind_text (stmt, 18, coverage_name, strlen (coverage_name),
+		       SQLITE_STATIC);
+    ret = sqlite3_step (stmt);
+    sqlite3_finalize (stmt);
+    stmt = NULL;
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+	goto ok_continue;
+    fprintf (stderr,
+	     "sqlite3_step() error: UPDATE raster_coverages \"%s\"\n",
+	     sqlite3_errmsg (sqlite));
+    goto error;
+
+  ok_continue:
+/* copying coverage-LEVELS */
+    xcoverage = sqlite3_mprintf ("%s_levels", coverage_name);
+    xxcoverage = rl2_double_quoted_sql (xcoverage);
+    sqlite3_free (xcoverage);
+    sql = sqlite3_mprintf ("INSERT INTO main.\"%s\" (pyramid_level, "
+			   "x_resolution_1_1, y_resolution_1_1, x_resolution_1_2, y_resolution_1_2, "
+			   "x_resolution_1_4, y_resolution_1_4, x_resolution_1_8, y_resolution_1_8) "
+			   "SELECT pyramid_level, x_resolution_1_1, y_resolution_1_1, x_resolution_1_2, "
+			   "y_resolution_1_2, x_resolution_1_4, y_resolution_1_4, x_resolution_1_8, "
+			   "y_resolution_1_8 FROM \"%s\".\"%s\"", xxcoverage,
+			   xdb, xxcoverage);
+    free (xxcoverage);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+	goto error;
+
+/* copying  coverage-SECTIONS */
+    xcoverage = sqlite3_mprintf ("%s_sections", coverage_name);
+    xxcoverage = rl2_double_quoted_sql (xcoverage);
+    sqlite3_free (xcoverage);
+    sql =
+	sqlite3_mprintf ("INSERT INTO main.\"%s\" (section_id, section_name, "
+			 "width, height, file_path, md5_checksum, summary, statistics, geometry) "
+			 "SELECT section_id, section_name, width, height, file_path, md5_checksum, "
+			 "summary, statistics, geometry FROM \"%s\".\"%s\"",
+			 xxcoverage, xdb, xxcoverage);
+    free (xxcoverage);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+	goto error;
+
+/* copying  coverage-TILES */
+    xcoverage = sqlite3_mprintf ("%s_tiles", coverage_name);
+    xxcoverage = rl2_double_quoted_sql (xcoverage);
+    sqlite3_free (xcoverage);
+    sql = sqlite3_mprintf ("INSERT INTO main.\"%s\" (tile_id, pyramid_level, "
+			   "section_id, geometry) SELECT tile_id, pyramid_level, section_id, geometry "
+			   "FROM \"%s\".\"%s\"", xxcoverage, xdb, xxcoverage);
+    free (xxcoverage);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+	goto error;
+
+/* copying  coverage-TILE_DATA */
+    xcoverage = sqlite3_mprintf ("%s_tile_data", coverage_name);
+    xxcoverage = rl2_double_quoted_sql (xcoverage);
+    sqlite3_free (xcoverage);
+    sql = sqlite3_mprintf ("INSERT INTO main.\"%s\" (tile_id, tile_data_odd, "
+			   "tile_data_even) SELECT tile_id, tile_data_odd, tile_data_even "
+			   "FROM \"%s\".\"%s\"", xxcoverage, xdb, xxcoverage);
+    free (xxcoverage);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+	goto error;
+
+/* copying KEYWORDS */
+    sql = sqlite3_mprintf ("INSERT INTO main.raster_coverages_keyword "
+			   "(coverage_name, keyword) SELECT coverage_name, keyword "
+			   "FROM \"%s\".raster_coverages_keyword", xdb);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+	goto error;
+
+/* copying SRID */
+    sql = sqlite3_mprintf ("INSERT INTO main.raster_coverages_srid "
+			   "(coverage_name, srid, extent_minx, extent_miny, extent_maxx, extent_maxx) "
+			   "SELECT coverage_name, srid, extent_minx, extent_miny, extent_maxx, extent_maxx "
+			   "FROM \"%s\".raster_coverages_srid", xdb);
+    ret = sqlite3_exec (sqlite, sql, NULL, NULL, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+	goto error;
+
+    free (xdb);
+    return RL2_OK;
+
+  error:
+    if (xdb != NULL)
+	free (xdb);
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    return RL2_ERROR;
+}
diff --git a/src/rl2gif.c b/src/rl2gif.c
index e6b4727..5846400 100644
--- a/src/rl2gif.c
+++ b/src/rl2gif.c
@@ -20,7 +20,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -606,8 +606,8 @@ rl2_raster_from_gif (const unsigned char *gif, int gif_size)
 RL2_PRIVATE int
 rl2_decode_gif (const unsigned char *gif, int gif_size, unsigned int *xwidth,
 		unsigned int *xheight, unsigned char *xsample_type,
-		unsigned char *xpixel_type, unsigned char **blob, int *blob_sz,
-		rl2PalettePtr * palette)
+		unsigned char *xpixel_type, unsigned char **blob,
+		int *blob_sz, rl2PalettePtr * palette)
 {
 /* attempting to create a raster from a GIF image - raw block */
     struct gif_memory_buffer membuf;
diff --git a/src/rl2import.c b/src/rl2import.c
index ebf4021..7694e7b 100644
--- a/src/rl2import.c
+++ b/src/rl2import.c
@@ -20,7 +20,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -41,10 +41,12 @@ the terms of any one of the MPL, the GPL or the LGPL.
  
 */
 
+#include <unistd.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <float.h>
+#include <time.h>
 
 #include <sys/types.h>
 #if defined(_WIN32) && !defined(__MINGW32__)
@@ -60,12 +62,129 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include "rasterlite2/sqlite.h"
 #endif
 
+#ifdef _WIN32
+#include <windows.h>
+#include <process.h>
+#else
+#include <pthread.h>
+#endif
+
 #include "rasterlite2/rasterlite2.h"
 #include "rasterlite2/rl2tiff.h"
 #include "rasterlite2/rl2graphics.h"
 #include "rasterlite2_private.h"
 
-#include <spatialite/gaiaaux.h>
+static void
+destroyAuxImporterTile (rl2AuxImporterTilePtr tile)
+{
+/* destroying an AuxImporter Tile */
+    if (tile == NULL)
+	return;
+    if (tile->opaque_thread_id != NULL)
+	free (tile->opaque_thread_id);
+    if (tile->raster != NULL)
+	rl2_destroy_raster (tile->raster);
+    if (tile->blob_odd != NULL)
+	free (tile->blob_odd);
+    if (tile->blob_even != NULL)
+	free (tile->blob_even);
+    free (tile);
+}
+
+static void
+doAuxImporterTileCleanup (rl2AuxImporterTilePtr tile)
+{
+/* AuxTile cleanup */
+    if (tile == NULL)
+	return;
+    tile->blob_odd = NULL;
+    tile->blob_even = NULL;
+    rl2_destroy_raster (tile->raster);
+    tile->raster = NULL;
+}
+
+static void
+addTile2AuxImporter (rl2AuxImporterPtr aux, unsigned int row,
+		     unsigned int col, double minx, double maxy)
+{
+/* adding a Tile to some AuxImporter container */
+    rl2AuxImporterTilePtr tile;
+    if (aux == NULL)
+	return;
+
+    tile = malloc (sizeof (rl2AuxImporterTile));
+    tile->opaque_thread_id = NULL;
+    tile->mother = aux;
+    tile->raster = NULL;
+    tile->row = row;
+    tile->col = col;
+    tile->minx = minx;
+    tile->maxx = minx + ((double) (aux->tile_w) * aux->res_x);
+    if (tile->maxx > aux->maxx)
+	tile->maxx = aux->maxx;
+    tile->maxy = maxy;
+    tile->miny = tile->maxy - ((double) (aux->tile_h) * aux->res_y);
+    if (tile->miny < aux->miny)
+	tile->miny = aux->miny;
+    tile->retcode = RL2_ERROR;
+    tile->blob_odd = NULL;
+    tile->blob_even = NULL;
+    tile->blob_odd_sz = 0;
+    tile->blob_even_sz = 0;
+    tile->next = NULL;
+/* appending to the double linked list */
+    if (aux->first == NULL)
+	aux->first = tile;
+    if (aux->last != NULL)
+	aux->last->next = tile;
+    aux->last = tile;
+}
+
+static rl2AuxImporterPtr
+createAuxImporter (rl2PrivCoveragePtr coverage, int srid, double maxx,
+		   double miny, unsigned int tile_w, unsigned int tile_h,
+		   double res_x, double res_y, unsigned char origin_type,
+		   const void *origin, unsigned char forced_conversion,
+		   int verbose, unsigned char compression, int quality)
+{
+/* creating an AuxImporter container */
+    rl2AuxImporterPtr aux = malloc (sizeof (rl2AuxImporter));
+    aux->coverage = coverage;
+    aux->srid = srid;
+    aux->maxx = maxx;
+    aux->miny = miny;
+    aux->tile_w = tile_w;
+    aux->tile_h = tile_h;
+    aux->res_x = res_x;
+    aux->res_y = res_y;
+    aux->origin_type = origin_type;
+    aux->origin = origin;
+    aux->forced_conversion = forced_conversion;
+    aux->verbose = verbose;
+    aux->compression = compression;
+    aux->quality = quality;
+    aux->first = NULL;
+    aux->last = NULL;
+    return aux;
+}
+
+static void
+destroyAuxImporter (rl2AuxImporterPtr aux)
+{
+/* destroying an AuxImporter container */
+    rl2AuxImporterTilePtr tile;
+    rl2AuxImporterTilePtr tile_n;
+    if (aux == NULL)
+	return;
+    tile = aux->first;
+    while (tile != NULL)
+      {
+	  tile_n = tile->next;
+	  destroyAuxImporterTile (tile);
+	  tile = tile_n;
+      }
+    free (aux);
+}
 
 static char *
 formatFloat (double value)
@@ -125,19 +244,15 @@ formatLat (double value)
 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)
+		sqlite3_int64 section_id, int srid, 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)
 {
 /* INSERTing the tile */
     int ret;
     sqlite3_int64 tile_id;
-    unsigned char *blob;
-    int blob_size;
-    gaiaGeomCollPtr geom;
     rl2RasterStatisticsPtr stats = NULL;
 
     stats = rl2_get_raster_statistics
@@ -148,16 +263,11 @@ do_insert_tile (sqlite3 * handle, unsigned char *blob_odd, int blob_odd_sz,
     sqlite3_reset (stmt_tils);
     sqlite3_clear_bindings (stmt_tils);
     sqlite3_bind_int64 (stmt_tils, 1, section_id);
-    *tile_maxx = *tile_minx + ((double) tile_w * res_x);
-    if (*tile_maxx > maxx)
-	*tile_maxx = maxx;
-    *tile_miny = *tile_maxy - ((double) tile_h * res_y);
-    if (*tile_miny < miny)
-	*tile_miny = miny;
-    geom = build_extent (srid, *tile_minx, *tile_miny, *tile_maxx, *tile_maxy);
-    gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
-    gaiaFreeGeomColl (geom);
-    sqlite3_bind_blob (stmt_tils, 2, blob, blob_size, free);
+    sqlite3_bind_double (stmt_tils, 2, tile_minx);
+    sqlite3_bind_double (stmt_tils, 3, tile_miny);
+    sqlite3_bind_double (stmt_tils, 4, tile_maxx);
+    sqlite3_bind_double (stmt_tils, 5, tile_maxy);
+    sqlite3_bind_int (stmt_tils, 6, srid);
     ret = sqlite3_step (stmt_tils);
     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
 	;
@@ -221,17 +331,181 @@ compute_aggregate_sq_diff (rl2RasterStatisticsPtr section_stats)
       }
 }
 
+static void
+do_get_tile (rl2AuxImporterTilePtr tile)
+{
+/* loading data required by an AuxImporter Tile */
+    rl2AsciiGridOriginPtr ascii_grid_origin = NULL;
+    rl2TiffOriginPtr tiff_origin;
+    rl2RasterPtr raster_origin;
+    rl2AuxImporterPtr aux;
+    if (tile == NULL)
+	return;
+
+    aux = tile->mother;
+    switch (aux->origin_type)
+      {
+      case RL2_ORIGIN_ASCII_GRID:
+	  ascii_grid_origin = (rl2AsciiGridOriginPtr) (aux->origin);
+	  tile->raster =
+	      rl2_get_tile_from_ascii_grid_origin ((rl2CoveragePtr)
+						   (aux->coverage),
+						   ascii_grid_origin,
+						   tile->row, tile->col,
+						   aux->verbose);
+	  break;
+      case RL2_ORIGIN_JPEG:
+	  raster_origin = (rl2RasterPtr) (aux->origin);
+	  tile->raster =
+	      rl2_get_tile_from_jpeg_origin ((rl2CoveragePtr) (aux->coverage),
+					     raster_origin, tile->row,
+					     tile->col,
+					     aux->forced_conversion,
+					     aux->verbose);
+	  break;
+      case RL2_ORIGIN_JPEG2000:
+	  raster_origin = (rl2RasterPtr) (aux->origin);
+	  tile->raster =
+	      rl2_get_tile_from_jpeg2000_origin ((rl2CoveragePtr)
+						 (aux->coverage),
+						 raster_origin, tile->row,
+						 tile->col,
+						 aux->forced_conversion,
+						 aux->verbose);
+	  break;
+      case RL2_ORIGIN_TIFF:
+	  tiff_origin = (rl2TiffOriginPtr) (aux->origin);
+	  tile->raster =
+	      rl2_get_tile_from_tiff_origin ((rl2CoveragePtr) (aux->coverage),
+					     tiff_origin, tile->row,
+					     tile->col, aux->srid,
+					     aux->verbose);
+	  break;
+      case RL2_ORIGIN_RAW:
+	  raster_origin = (rl2RasterPtr) (aux->origin);
+	  tile->raster =
+	      rl2_get_tile_from_raw_pixels ((rl2CoveragePtr) (aux->coverage),
+					    raster_origin, tile->row,
+					    tile->col);
+	  break;
+      };
+}
+
+static void
+do_encode_tile (rl2AuxImporterTilePtr tile)
+{
+/* servicising an AuxImporter Tile request */
+    rl2AuxImporterPtr aux;
+    if (tile == NULL)
+	goto error;
+
+    aux = tile->mother;
+    if (tile->raster == NULL)
+      {
+	  fprintf (stderr,
+		   "ERROR: unable to get a tile [Row=%d Col=%d]\n",
+		   tile->row, tile->col);
+	  goto error;
+      }
+    if (rl2_raster_encode
+	(tile->raster, aux->compression, &(tile->blob_odd),
+	 &(tile->blob_odd_sz), &(tile->blob_even), &(tile->blob_even_sz),
+	 aux->quality, 1) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "ERROR: unable to encode a tile [Row=%d Col=%d]\n",
+		   tile->row, tile->col);
+	  goto error;
+      }
+    tile->retcode = RL2_OK;
+    return;
+
+  error:
+    doAuxImporterTileCleanup (tile);
+    tile->retcode = RL2_ERROR;
+}
+
+#ifdef _WIN32
+DWORD WINAPI
+doRunImportThread (void *arg)
+#else
+void *
+doRunImportThread (void *arg)
+#endif
+{
+/* threaded function: preparing a compressed Tile to be imported */
+    rl2AuxImporterTilePtr aux_tile = (rl2AuxImporterTilePtr) arg;
+    do_encode_tile (aux_tile);
+#ifdef _WIN32
+    return 0;
+#else
+    pthread_exit (NULL);
+#endif
+}
+
+static void
+start_tile_thread (rl2AuxImporterTilePtr aux_tile)
+{
+/* starting a concurrent thread */
+#ifdef _WIN32
+    HANDLE thread_handle;
+    HANDLE *p_thread;
+    DWORD dwThreadId;
+    thread_handle =
+	CreateThread (NULL, 0, doRunImportThread, aux_tile, 0, &dwThreadId);
+    SetThreadPriority (thread_handle, THREAD_PRIORITY_IDLE);
+    p_thread = malloc (sizeof (HANDLE));
+    *p_thread = thread_handle;
+    aux_tile->opaque_thread_id = p_thread;
+#else
+    pthread_t thread_id;
+    pthread_t *p_thread;
+    int ok_prior = 0;
+    int policy;
+    int min_prio;
+    pthread_attr_t attr;
+    struct sched_param sp;
+    pthread_attr_init (&attr);
+    if (pthread_attr_setschedpolicy (&attr, SCHED_RR) == 0)
+      {
+	  /* attempting to set the lowest priority */
+	  if (pthread_attr_getschedpolicy (&attr, &policy) == 0)
+	    {
+		min_prio = sched_get_priority_min (policy);
+		sp.sched_priority = min_prio;
+		if (pthread_attr_setschedparam (&attr, &sp) == 0)
+		  {
+		      /* ok, setting the lowest priority */
+		      ok_prior = 1;
+		      pthread_create (&thread_id, &attr, doRunImportThread,
+				      aux_tile);
+		  }
+	    }
+      }
+    if (!ok_prior)
+      {
+	  /* failure: using standard priority */
+	  pthread_create (&thread_id, NULL, doRunImportThread, aux_tile);
+      }
+    p_thread = malloc (sizeof (pthread_t));
+    *p_thread = thread_id;
+    aux_tile->opaque_thread_id = p_thread;
+#endif
+}
+
 static int
-do_import_ascii_grid (sqlite3 * handle, const char *src_path,
+do_import_ascii_grid (sqlite3 * handle, int max_threads, 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)
+		      sqlite3_stmt * stmt_levl, sqlite3_stmt * stmt_upd_sect,
+		      int verbose, int current, int total)
 {
 /* importing an ASCII Data Grid file */
     int ret;
+    rl2PrivCoveragePtr coverage = (rl2PrivCoveragePtr) cvg;
     rl2AsciiGridOriginPtr origin = NULL;
     rl2RasterPtr raster = NULL;
     rl2RasterStatisticsPtr section_stats = NULL;
@@ -240,13 +514,7 @@ do_import_ascii_grid (sqlite3 * handle, const char *src_path,
     unsigned int col;
     unsigned int width;
     unsigned int height;
-    unsigned char *blob_odd = NULL;
-    unsigned char *blob_even = NULL;
-    int blob_odd_sz;
-    int blob_even_sz;
     double tile_minx;
-    double tile_miny;
-    double tile_maxx;
     double tile_maxy;
     double minx;
     double miny;
@@ -256,18 +524,43 @@ do_import_ascii_grid (sqlite3 * handle, const char *src_path,
     double res_y;
     double base_res_x;
     double base_res_y;
+    double confidence;
     char *dumb1;
     char *dumb2;
     sqlite3_int64 section_id;
-
+    time_t start;
+    time_t now;
+    time_t diff;
+    int mins;
+    int secs;
+    char *xml_summary = NULL;
+    rl2AuxImporterPtr aux = NULL;
+    rl2AuxImporterTilePtr aux_tile;
+    rl2AuxImporterTilePtr *thread_slots = NULL;
+    int thread_count;
+
+    time (&start);
     if (rl2_get_coverage_resolution (cvg, &base_res_x, &base_res_y) != RL2_OK)
-	goto error;
+      {
+	  if (verbose)
+	      fprintf (stderr, "Unknown Coverage Resolution\n");
+	  goto error;
+      }
     origin = rl2_create_ascii_grid_origin (src_path, srid, sample_type);
     if (origin == NULL)
-	goto error;
+      {
+	  if (verbose)
+	      fprintf (stderr, "Invalid ASCII Grid Origin: %s\n", src_path);
+	  goto error;
+      }
+    xml_summary = rl2_build_ascii_xml_summary (origin);
 
-    printf ("Importing: %s\n", rl2_get_ascii_grid_origin_path (origin));
     printf ("------------------\n");
+    if (total > 1)
+	printf ("%d/%d) Importing: %s\n", current, total,
+		rl2_get_ascii_grid_origin_path (origin));
+    else
+	printf ("Importing: %s\n", rl2_get_ascii_grid_origin_path (origin));
     ret = rl2_get_ascii_grid_origin_size (origin, &width, &height);
     if (ret == RL2_OK)
 	printf ("    Image Size (pixels): %d x %d\n", width, height);
@@ -297,8 +590,53 @@ do_import_ascii_grid (sqlite3 * handle, const char *src_path,
 	  sqlite3_free (dumb1);
 	  sqlite3_free (dumb2);
       }
+    if (coverage->mixedResolutions)
+      {
+	  /* accepting any resolution */
+      }
+    else if (coverage->strictResolution)
+      {
+	  /* enforcing Strict Resolution check */
+	  if (res_x != coverage->hResolution)
+	    {
+		if (verbose)
+		    fprintf (stderr,
+			     "Mismatching Horizontal Resolution (Strict) !!!\n");
+		goto error;
+	    }
+	  if (res_y != coverage->vResolution)
+	    {
+		if (verbose)
+		    fprintf (stderr,
+			     "Mismatching Vertical Resolution (Strict) !!!\n");
+		goto error;
+	    }
+      }
+    else
+      {
+	  /* permissive Resolution check */
+	  confidence = coverage->hResolution / 100.0;
+	  if (res_x < (coverage->hResolution - confidence)
+	      || res_x > (coverage->hResolution + confidence))
+	    {
+		if (verbose)
+		    fprintf (stderr,
+			     "Mismatching Horizontal Resolution (Permissive) !!!\n");
+		goto error;
+	    }
+	  confidence = coverage->vResolution / 100.0;
+	  if (res_y < (coverage->vResolution - confidence)
+	      || res_y > (coverage->vResolution + confidence))
+	    {
+		if (verbose)
+		    fprintf (stderr,
+			     "Mismatching Vertical Resolution (Permissive) !!!\n");
+		goto error;
+	    }
+      }
 
-    if (rl2_eval_ascii_grid_origin_compatibility (cvg, origin) != RL2_TRUE)
+    if (rl2_eval_ascii_grid_origin_compatibility (cvg, origin, verbose) !=
+	RL2_TRUE)
       {
 	  fprintf (stderr, "Coverage/ASCII mismatch\n");
 	  goto error;
@@ -306,103 +644,211 @@ do_import_ascii_grid (sqlite3 * handle, const char *src_path,
     no_data = rl2_get_coverage_no_data (cvg);
 
 /* INSERTing the section */
-    if (!do_insert_section
-	(handle, src_path, section, srid, width, height, minx, miny, maxx, maxy,
-	 stmt_sect, &section_id))
+    if (!rl2_do_insert_section
+	(handle, src_path, section, srid, width, height, minx, miny, maxx,
+	 maxy, xml_summary, coverage->sectionPaths, coverage->sectionMD5,
+	 coverage->sectionSummary, stmt_sect, &section_id))
 	goto error;
     section_stats = rl2_create_raster_statistics (sample_type, 1);
     if (section_stats == NULL)
 	goto error;
 /* INSERTing the base-levels */
-    if (!do_insert_levels
-	(handle, base_res_x, base_res_y, 1.0, sample_type, stmt_levl))
-	goto error;
+    if (coverage->mixedResolutions)
+      {
+	  /* multiple resolutions Coverage */
+	  if (!rl2_do_insert_section_levels
+	      (handle, section_id, res_x, res_y, 1.0, sample_type, stmt_levl))
+	      goto error;
+      }
+    else
+      {
+	  /* single resolution Coverage */
+	  if (!rl2_do_insert_levels
+	      (handle, base_res_x, base_res_y, 1.0, sample_type, stmt_levl))
+	      goto error;
+      }
 
+/* preparing all Tile Requests */
+    aux =
+	createAuxImporter (coverage, srid, maxx, miny, tile_w, tile_h, res_x,
+			   res_y, RL2_ORIGIN_ASCII_GRID, origin,
+			   RL2_CONVERT_NO, verbose, compression, 100);
     tile_maxy = maxy;
     for (row = 0; row < height; row += tile_h)
       {
 	  tile_minx = minx;
 	  for (col = 0; col < width; col += tile_w)
 	    {
-		raster =
-		    rl2_get_tile_from_ascii_grid_origin (cvg, origin, row, col);
-		if (raster == NULL)
+		/* adding a Tile request */
+		addTile2AuxImporter (aux, row, col, tile_minx, tile_maxy);
+		tile_minx += (double) tile_w *res_x;
+	    }
+	  tile_maxy -= (double) tile_h *res_y;
+      }
+
+    if (max_threads < 1)
+	max_threads = 1;
+    if (max_threads > 64)
+	max_threads = 64;
+/* prepating the thread_slots stuct */
+    thread_slots = malloc (sizeof (rl2AuxImporterTilePtr) * max_threads);
+    for (thread_count = 0; thread_count < max_threads; thread_count++)
+	*(thread_slots + thread_count) = NULL;
+    thread_count = 0;
+    aux_tile = aux->first;
+    while (aux_tile != NULL)
+      {
+	  /* processing a Tile request (may be under parallel execution) */
+	  if (max_threads > 1)
+	    {
+		/* adopting a multithreaded strategy */
+		do_get_tile (aux_tile);
+		*(thread_slots + thread_count) = aux_tile;
+		thread_count++;
+		start_tile_thread (aux_tile);
+		if (thread_count == max_threads || aux_tile->next == NULL)
 		  {
-		      fprintf (stderr,
-			       "ERROR: unable to get a tile [Row=%d Col=%d]\n",
-			       row, col);
-		      goto error;
+		      /* waiting until all child threads exit */
+#ifdef _WIN32
+		      HANDLE *handles;
+		      int z;
+		      int cnt = 0;
+		      for (z = 0; z < max_threads; z++)
+			{
+			    /* counting how many active threads we currently have */
+			    rl2AuxImporterTilePtr pTile = *(thread_slots + z);
+			    if (pTile == NULL)
+				continue;
+			    cnt++;
+			}
+		      handles = malloc (sizeof (HANDLE) * cnt);
+		      cnt = 0;
+		      for (z = 0; z < max_threads; z++)
+			{
+			    /* initializing the HANDLEs array */
+			    HANDLE *pOpaque;
+			    rl2AuxImporterTilePtr pTile = *(thread_slots + z);
+			    if (pTile == NULL)
+				continue;
+			    pOpaque = (HANDLE *) (pTile->opaque_thread_id);
+			    *(handles + cnt) = *pOpaque;
+			    cnt++;
+			}
+		      WaitForMultipleObjects (cnt, handles, TRUE, INFINITE);
+#else
+		      for (thread_count = 0; thread_count < max_threads;
+			   thread_count++)
+			{
+			    pthread_t *pOpaque;
+			    rl2AuxImporterTilePtr pTile =
+				*(thread_slots + thread_count);
+			    if (pTile == NULL)
+				continue;
+			    pOpaque = (pthread_t *) (pTile->opaque_thread_id);
+			    pthread_join (*pOpaque, NULL);
+			}
+#endif
+
+		      /* all children threads have now finished: resuming the main thread */
+		      for (thread_count = 0; thread_count < max_threads;
+			   thread_count++)
+			{
+			    /* checking for eventual errors */
+			    rl2AuxImporterTilePtr pTile =
+				*(thread_slots + thread_count);
+			    if (pTile == NULL)
+				continue;
+			    if (pTile->retcode != RL2_OK)
+				goto error;
+			}
+#ifdef _WIN32
+		      free (handles);
+#endif
+		      thread_count = 0;
+		      /* we can now continue by inserting all tiles into the DBMS */
 		  }
-		if (rl2_raster_encode
-		    (raster, compression, &blob_odd, &blob_odd_sz, &blob_even,
-		     &blob_even_sz, 100, 1) != RL2_OK)
+		else
 		  {
-		      fprintf (stderr,
-			       "ERROR: unable to encode a tile [Row=%d Col=%d]\n",
-			       row, col);
-		      goto error;
+		      aux_tile = aux_tile->next;
+		      continue;
 		  }
+	    }
+	  else
+	    {
+		/* single thread execution */
+		do_get_tile (aux_tile);
+		*(thread_slots + 0) = aux_tile;
+		do_encode_tile (aux_tile);
+		if (aux_tile->retcode != RL2_OK)
+		    goto error;
+	    }
 
-		/* INSERTing the tile */
+	  for (thread_count = 0; thread_count < max_threads; thread_count++)
+	    {
+		/* INSERTing the tile(s) */
+		rl2AuxImporterTilePtr pTile = *(thread_slots + thread_count);
+		if (pTile == NULL)
+		    continue;
 		if (!do_insert_tile
-		    (handle, blob_odd, blob_odd_sz, blob_even, blob_even_sz,
-		     section_id, srid, res_x, res_y, tile_w, tile_h, miny,
-		     maxx, &tile_minx, &tile_miny, &tile_maxx, &tile_maxy,
+		    (handle, pTile->blob_odd, pTile->blob_odd_sz,
+		     pTile->blob_even, pTile->blob_even_sz, section_id, srid,
+		     pTile->minx, pTile->miny, pTile->maxx, pTile->maxy,
 		     NULL, no_data, stmt_tils, stmt_data, section_stats))
-		    goto error;
-		blob_odd = NULL;
-		blob_even = NULL;
-		rl2_destroy_raster (raster);
-		raster = NULL;
-		tile_minx += (double) tile_w *res_x;
+		  {
+		      pTile->blob_odd = NULL;
+		      pTile->blob_even = NULL;
+		      goto error;
+		  }
+		doAuxImporterTileCleanup (pTile);
 	    }
-	  tile_maxy -= (double) tile_h *res_y;
+	  for (thread_count = 0; thread_count < max_threads; thread_count++)
+	      *(thread_slots + thread_count) = NULL;
+	  thread_count = 0;
+	  aux_tile = aux_tile->next;
       }
+    destroyAuxImporter (aux);
+    aux = NULL;
+    free (thread_slots);
+    thread_slots = NULL;
 
 /* updating the Section's Statistics */
     compute_aggregate_sq_diff (section_stats);
-    if (!do_insert_stats (handle, section_stats, section_id, stmt_upd_sect))
+    if (!rl2_do_insert_stats (handle, section_stats, section_id, stmt_upd_sect))
 	goto error;
 
     rl2_destroy_ascii_grid_origin (origin);
     rl2_destroy_raster_statistics (section_stats);
     origin = NULL;
     section_stats = NULL;
+    time (&now);
+    diff = now - start;
+    mins = diff / 60;
+    secs = diff - (mins * 60);
+    printf (">> Grid successfully imported in: %d mins %02d secs\n", mins,
+	    secs);
 
     if (pyramidize)
       {
 	  /* immediately building the Section's Pyramid */
 	  const char *coverage_name = rl2_get_coverage_name (cvg);
-	  const char *section_name = section;
-	  char *sect_name = NULL;
 	  if (coverage_name == NULL)
 	      goto error;
-	  if (section_name == NULL)
+	  if (rl2_build_section_pyramid
+	      (handle, max_threads, coverage_name, section_id, 1,
+	       verbose) != RL2_OK)
 	    {
-		sect_name = get_section_name (src_path);
-		section_name = sect_name;
-	    }
-	  if (section_name == NULL)
-	      goto error;
-	  if (rl2_build_section_pyramid (handle, coverage_name, section_name, 1)
-	      != RL2_OK)
-	    {
-		if (sect_name != NULL)
-		    free (sect_name);
 		fprintf (stderr, "unable to build the Section's Pyramid\n");
 		goto error;
 	    }
-	  if (sect_name != NULL)
-	      free (sect_name);
       }
 
     return 1;
 
   error:
-    if (blob_odd != NULL)
-	free (blob_odd);
-    if (blob_even != NULL)
-	free (blob_even);
+    if (aux != NULL)
+	destroyAuxImporter (aux);
+    if (thread_slots != NULL)
+	free (thread_slots);
     if (origin != NULL)
 	rl2_destroy_ascii_grid_origin (origin);
     if (raster != NULL)
@@ -465,10 +911,133 @@ check_jpeg_origin_compatibility (rl2RasterPtr raster, rl2CoveragePtr coverage,
     return 0;
 }
 
-static char *
-build_worldfile_path (const char *path, const char *suffix)
+#ifndef OMIT_OPENJPEG		/* only if OpenJpeg is enabled */
+
+static int
+check_jpeg2000_origin_compatibility (rl2RasterPtr raster,
+				     rl2CoveragePtr coverage,
+				     unsigned int *width,
+				     unsigned int *height,
+				     unsigned char *forced_conversion)
+{
+/* checking if the Jpeg2000 and the Coverage are mutually compatible */
+    rl2PrivRasterPtr rst = (rl2PrivRasterPtr) raster;
+    rl2PrivCoveragePtr cvg = (rl2PrivCoveragePtr) coverage;
+    if (rst == NULL || cvg == NULL)
+	return 0;
+    if (rst->sampleType == RL2_SAMPLE_UINT8
+	&& rst->pixelType == RL2_PIXEL_GRAYSCALE && rst->nBands == 1)
+      {
+	  if (cvg->sampleType == RL2_SAMPLE_UINT8
+	      && cvg->pixelType == RL2_PIXEL_GRAYSCALE && cvg->nBands == 1)
+	    {
+		*width = rst->width;
+		*height = rst->height;
+		*forced_conversion = RL2_CONVERT_NO;
+		return 1;
+	    }
+	  if (cvg->sampleType == RL2_SAMPLE_UINT8
+	      && cvg->pixelType == RL2_PIXEL_RGB && cvg->nBands == 3)
+	    {
+		*width = rst->width;
+		*height = rst->height;
+		*forced_conversion = RL2_CONVERT_GRAYSCALE_TO_RGB;
+		return 1;
+	    }
+      }
+    if (rst->sampleType == RL2_SAMPLE_UINT8 && rst->pixelType == RL2_PIXEL_RGB
+	&& rst->nBands == 3)
+      {
+	  if (cvg->sampleType == RL2_SAMPLE_UINT8
+	      && cvg->pixelType == RL2_PIXEL_RGB && cvg->nBands == 3)
+	    {
+		*width = rst->width;
+		*height = rst->height;
+		*forced_conversion = RL2_CONVERT_NO;
+		return 1;
+	    }
+	  if (cvg->sampleType == RL2_SAMPLE_UINT8
+	      && cvg->pixelType == RL2_PIXEL_GRAYSCALE && cvg->nBands == 1)
+	    {
+		*width = rst->width;
+		*height = rst->height;
+		*forced_conversion = RL2_CONVERT_RGB_TO_GRAYSCALE;
+		return 1;
+	    }
+      }
+    if (rst->sampleType == RL2_SAMPLE_UINT8
+	&& rst->pixelType == RL2_PIXEL_MULTIBAND && (rst->nBands == 3
+						     || rst->nBands == 4))
+      {
+	  if (cvg->sampleType == RL2_SAMPLE_UINT8
+	      && cvg->pixelType == RL2_PIXEL_MULTIBAND
+	      && cvg->nBands == rst->nBands)
+	    {
+		*width = rst->width;
+		*height = rst->height;
+		*forced_conversion = RL2_CONVERT_NO;
+		return 1;
+	    }
+      }
+    if (rst->sampleType == RL2_SAMPLE_UINT8
+	&& rst->pixelType == RL2_PIXEL_DATAGRID && rst->nBands == 1)
+      {
+	  if (cvg->sampleType == RL2_SAMPLE_UINT8
+	      && cvg->pixelType == RL2_PIXEL_DATAGRID && cvg->nBands == 1)
+	    {
+		*width = rst->width;
+		*height = rst->height;
+		*forced_conversion = RL2_CONVERT_NO;
+		return 1;
+	    }
+      }
+    if (rst->sampleType == RL2_SAMPLE_UINT16
+	&& rst->pixelType == RL2_PIXEL_DATAGRID && rst->nBands == 1)
+      {
+	  if (cvg->sampleType == RL2_SAMPLE_UINT16
+	      && cvg->pixelType == RL2_PIXEL_DATAGRID && cvg->nBands == 1)
+	    {
+		*width = rst->width;
+		*height = rst->height;
+		*forced_conversion = RL2_CONVERT_NO;
+		return 1;
+	    }
+      }
+    if (rst->sampleType == RL2_SAMPLE_UINT16
+	&& rst->pixelType == RL2_PIXEL_RGB && rst->nBands == 3)
+      {
+	  if (cvg->sampleType == RL2_SAMPLE_UINT16
+	      && cvg->pixelType == RL2_PIXEL_RGB && cvg->nBands == 3)
+	    {
+		*width = rst->width;
+		*height = rst->height;
+		*forced_conversion = RL2_CONVERT_NO;
+		return 1;
+	    }
+      }
+    if (rst->sampleType == RL2_SAMPLE_UINT16
+	&& rst->pixelType == RL2_PIXEL_MULTIBAND && (rst->nBands == 3
+						     || rst->nBands == 4))
+      {
+	  if (cvg->sampleType == RL2_SAMPLE_UINT16
+	      && cvg->pixelType == RL2_PIXEL_MULTIBAND
+	      && cvg->nBands == rst->nBands)
+	    {
+		*width = rst->width;
+		*height = rst->height;
+		*forced_conversion = RL2_CONVERT_NO;
+		return 1;
+	    }
+      }
+    return 0;
+}
+
+#endif /* end OpenJpeg conditional */
+
+RL2_DECLARE char *
+rl2_build_worldfile_path (const char *path, const char *suffix)
 {
-/* building the JGW path (WorldFile) */
+/* building a WorldFile path */
     char *wf_path;
     const char *x = NULL;
     const char *p = path;
@@ -504,17 +1073,35 @@ read_jgw_worldfile (const char *src_path, double *minx, double *maxy,
     double y;
     char *jgw_path = NULL;
 
-    jgw_path = build_worldfile_path (src_path, ".jgw");
+    jgw_path = rl2_build_worldfile_path (src_path, ".jgw");
     if (jgw_path == NULL)
 	goto error;
     jgw = fopen (jgw_path, "r");
     free (jgw_path);
     jgw_path = NULL;
     if (jgw == NULL)
-	goto error;
-    if (!parse_worldfile (jgw, &x, &y, &res_x, &res_y))
-	goto error;
-    fclose (jgw);
+      {
+	  /* trying the ".jpgw" suffix */
+	  jgw_path = rl2_build_worldfile_path (src_path, ".jpgw");
+	  if (jgw_path == NULL)
+	      goto error;
+	  jgw = fopen (jgw_path, "r");
+	  free (jgw_path);
+      }
+    if (jgw == NULL)
+      {
+	  /* trying the ".wld" suffix */
+	  jgw_path = rl2_build_worldfile_path (src_path, ".wld");
+	  if (jgw_path == NULL)
+	      goto error;
+	  jgw = fopen (jgw_path, "r");
+	  free (jgw_path);
+      }
+    if (jgw == NULL)
+	goto error;
+    if (!parse_worldfile (jgw, &x, &y, &res_x, &res_y))
+	goto error;
+    fclose (jgw);
     *pres_x = res_x;
     *pres_y = res_y;
     *minx = x;
@@ -537,7 +1124,7 @@ write_jgw_worldfile (const char *path, double minx, double maxy, double x_res,
     FILE *jgw = NULL;
     char *jgw_path = NULL;
 
-    jgw_path = build_worldfile_path (path, ".jgw");
+    jgw_path = rl2_build_worldfile_path (path, ".jgw");
     if (jgw_path == NULL)
 	goto error;
     jgw = fopen (jgw_path, "w");
@@ -562,18 +1149,20 @@ write_jgw_worldfile (const char *path, double minx, double maxy, double x_res,
 }
 
 static int
-do_import_jpeg_image (sqlite3 * handle, const char *src_path,
+do_import_jpeg_image (sqlite3 * handle, int max_threads, 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)
+		      int quality, sqlite3_stmt * stmt_data,
+		      sqlite3_stmt * stmt_tils, sqlite3_stmt * stmt_sect,
+		      sqlite3_stmt * stmt_levl, sqlite3_stmt * stmt_upd_sect,
+		      int verbose, int current, int total)
 {
 /* importing a JPEG image file [with optional WorldFile */
-    rl2SectionPtr origin;
+    rl2SectionPtr origin = NULL;
     rl2RasterPtr rst_in;
+    rl2PrivRasterPtr raster_in;
     rl2RasterPtr raster = NULL;
     rl2RasterStatisticsPtr section_stats = NULL;
     rl2PixelPtr no_data = NULL;
@@ -581,13 +1170,7 @@ do_import_jpeg_image (sqlite3 * handle, const char *src_path,
     unsigned int col;
     unsigned int width;
     unsigned int height;
-    unsigned char *blob_odd = NULL;
-    unsigned char *blob_even = NULL;
-    int blob_odd_sz;
-    int blob_even_sz;
     double tile_minx;
-    double tile_miny;
-    double tile_maxx;
     double tile_maxy;
     double minx;
     double miny;
@@ -595,18 +1178,40 @@ do_import_jpeg_image (sqlite3 * handle, const char *src_path,
     double maxy;
     double res_x;
     double res_y;
+    int is_georeferenced = 0;
     char *dumb1;
     char *dumb2;
     sqlite3_int64 section_id;
     unsigned char forced_conversion = RL2_CONVERT_NO;
     double base_res_x;
     double base_res_y;
+    rl2PrivCoveragePtr coverage = (rl2PrivCoveragePtr) cvg;
+    double confidence;
+    time_t start;
+    time_t now;
+    time_t diff;
+    int mins;
+    int secs;
+    char *xml_summary = NULL;
+    rl2AuxImporterPtr aux = NULL;
+    rl2AuxImporterTilePtr aux_tile;
+    rl2AuxImporterTilePtr *thread_slots = NULL;
+    int thread_count;
 
     if (rl2_get_coverage_resolution (cvg, &base_res_x, &base_res_y) != RL2_OK)
-	goto error;
+      {
+	  if (verbose)
+	      fprintf (stderr, "Unknown Coverage Resolution\n");
+	  goto error;
+      }
     origin = rl2_section_from_jpeg (src_path);
     if (origin == NULL)
-	goto error;
+      {
+	  if (verbose)
+	      fprintf (stderr, "Invalid JPEG Origin: %s\n", src_path);
+	  goto error;
+      }
+    time (&start);
     rst_in = rl2_get_section_raster (origin);
     if (!check_jpeg_origin_compatibility
 	(rst_in, cvg, &width, &height, &forced_conversion))
@@ -616,6 +1221,7 @@ do_import_jpeg_image (sqlite3 * handle, const char *src_path,
 	  /* georeferenced JPEG */
 	  maxx = minx + ((double) width * res_x);
 	  miny = maxy - ((double) height * res_y);
+	  is_georeferenced = 1;
       }
     else
       {
@@ -629,9 +1235,17 @@ do_import_jpeg_image (sqlite3 * handle, const char *src_path,
 	  res_x = 1.0;
 	  res_y = 1.0;
       }
+    raster_in = (rl2PrivRasterPtr) rst_in;
+    xml_summary =
+	rl2_build_jpeg_xml_summary (width, height, raster_in->pixelType,
+				    is_georeferenced, res_x, res_y, minx,
+				    miny, maxx, maxy);
 
-    printf ("Importing: %s\n", src_path);
     printf ("------------------\n");
+    if (total > 1)
+	printf ("%d/%d) Importing: %s\n", current, total, src_path);
+    else
+	printf ("Importing: %s\n", src_path);
     printf ("    Image Size (pixels): %d x %d\n", width, height);
     printf ("                   SRID: %d\n", srid);
     dumb1 = formatLong (minx);
@@ -649,108 +1263,264 @@ do_import_jpeg_image (sqlite3 * handle, const char *src_path,
     printf ("       Pixel resolution: X=%s Y=%s\n", dumb1, dumb2);
     sqlite3_free (dumb1);
     sqlite3_free (dumb2);
+    if (coverage->Srid != srid)
+      {
+	  if (verbose)
+	      fprintf (stderr, "Mismatching SRID !!!\n");
+	  goto error;
+      }
+    if (coverage->mixedResolutions)
+      {
+	  /* accepting any resolution */
+      }
+    else if (coverage->strictResolution)
+      {
+	  /* enforcing Strict Resolution check */
+	  if (res_x != coverage->hResolution)
+	    {
+		if (verbose)
+		    fprintf (stderr,
+			     "Mismatching Horizontal Resolution (Strict) !!!\n");
+		goto error;
+	    }
+	  if (res_y != coverage->vResolution)
+	    {
+		if (verbose)
+		    fprintf (stderr,
+			     "Mismatching Vertical Resolution (Strict) !!!\n");
+		goto error;
+	    }
+      }
+    else
+      {
+	  /* permissive Resolution check */
+	  confidence = coverage->hResolution / 100.0;
+	  if (res_x < (coverage->hResolution - confidence)
+	      || res_x > (coverage->hResolution + confidence))
+	    {
+		if (verbose)
+		    fprintf (stderr,
+			     "Mismatching Horizontal Resolution (Permissive) !!!\n");
+		goto error;
+	    }
+	  confidence = coverage->vResolution / 100.0;
+	  if (res_y < (coverage->vResolution - confidence)
+	      || res_y > (coverage->vResolution + confidence))
+	    {
+		if (verbose)
+		    fprintf (stderr,
+			     "Mismatching Vertical Resolution !(Permissive) !!\n");
+		goto error;
+	    }
+      }
 
     no_data = rl2_get_coverage_no_data (cvg);
 
 /* INSERTing the section */
-    if (!do_insert_section
-	(handle, src_path, section, srid, width, height, minx, miny, maxx, maxy,
-	 stmt_sect, &section_id))
+    if (!rl2_do_insert_section
+	(handle, src_path, section, srid, width, height, minx, miny, maxx,
+	 maxy, xml_summary, coverage->sectionPaths, coverage->sectionMD5,
+	 coverage->sectionSummary, stmt_sect, &section_id))
 	goto error;
     section_stats = rl2_create_raster_statistics (sample_type, num_bands);
     if (section_stats == NULL)
 	goto error;
 /* INSERTing the base-levels */
-    if (!do_insert_levels
-	(handle, base_res_x, base_res_y, 1.0, sample_type, stmt_levl))
-	goto error;
+    if (coverage->mixedResolutions)
+      {
+	  /* multiple resolutions Coverage */
+	  if (!rl2_do_insert_section_levels
+	      (handle, section_id, res_x, res_y, 1.0, sample_type, stmt_levl))
+	      goto error;
+      }
+    else
+      {
+	  /* single resolution Coverage */
+	  if (!rl2_do_insert_levels
+	      (handle, base_res_x, base_res_y, 1.0, sample_type, stmt_levl))
+	      goto error;
+      }
 
+/* preparing all Tile Requests */
+    aux =
+	createAuxImporter (coverage, srid, maxx, miny, tile_w, tile_h, res_x,
+			   res_y, RL2_ORIGIN_JPEG, rst_in, forced_conversion,
+			   verbose, compression, quality);
     tile_maxy = maxy;
     for (row = 0; row < height; row += tile_h)
       {
 	  tile_minx = minx;
 	  for (col = 0; col < width; col += tile_w)
 	    {
-		raster =
-		    rl2_get_tile_from_jpeg_origin (cvg, rst_in, row, col,
-						   forced_conversion);
-		if (raster == NULL)
+		/* adding a Tile request */
+		addTile2AuxImporter (aux, row, col, tile_minx, tile_maxy);
+		tile_minx += (double) tile_w *res_x;
+	    }
+	  tile_maxy -= (double) tile_h *res_y;
+      }
+
+    if (max_threads < 1)
+	max_threads = 1;
+    if (max_threads > 64)
+	max_threads = 64;
+/* prepating the thread_slots stuct */
+    thread_slots = malloc (sizeof (rl2AuxImporterTilePtr) * max_threads);
+    for (thread_count = 0; thread_count < max_threads; thread_count++)
+	*(thread_slots + thread_count) = NULL;
+    thread_count = 0;
+    aux_tile = aux->first;
+    while (aux_tile != NULL)
+      {
+	  /* processing a Tile request (may be under parallel execution) */
+	  if (max_threads > 1)
+	    {
+		/* adopting a multithreaded strategy */
+		do_get_tile (aux_tile);
+		*(thread_slots + thread_count) = aux_tile;
+		thread_count++;
+		start_tile_thread (aux_tile);
+		if (thread_count == max_threads || aux_tile->next == NULL)
 		  {
-		      fprintf (stderr,
-			       "ERROR: unable to get a tile [Row=%d Col=%d]\n",
-			       row, col);
-		      goto error;
+		      /* waiting until all child threads exit */
+#ifdef _WIN32
+		      HANDLE *handles;
+		      int z;
+		      int cnt = 0;
+		      for (z = 0; z < max_threads; z++)
+			{
+			    /* counting how many active threads we currently have */
+			    rl2AuxImporterTilePtr pTile = *(thread_slots + z);
+			    if (pTile == NULL)
+				continue;
+			    cnt++;
+			}
+		      handles = malloc (sizeof (HANDLE) * cnt);
+		      cnt = 0;
+		      for (z = 0; z < max_threads; z++)
+			{
+			    /* initializing the HANDLEs array */
+			    HANDLE *pOpaque;
+			    rl2AuxImporterTilePtr pTile = *(thread_slots + z);
+			    if (pTile == NULL)
+				continue;
+			    pOpaque = (HANDLE *) (pTile->opaque_thread_id);
+			    *(handles + cnt) = *pOpaque;
+			    cnt++;
+			}
+		      WaitForMultipleObjects (cnt, handles, TRUE, INFINITE);
+#else
+		      for (thread_count = 0; thread_count < max_threads;
+			   thread_count++)
+			{
+			    pthread_t *pOpaque;
+			    rl2AuxImporterTilePtr pTile =
+				*(thread_slots + thread_count);
+			    if (pTile == NULL)
+				continue;
+			    pOpaque = (pthread_t *) (pTile->opaque_thread_id);
+			    pthread_join (*pOpaque, NULL);
+			}
+#endif
+
+		      /* all children threads have now finished: resuming the main thread */
+		      for (thread_count = 0; thread_count < max_threads;
+			   thread_count++)
+			{
+			    rl2AuxImporterTilePtr pTile =
+				*(thread_slots + thread_count);
+			    if (pTile == NULL)
+				continue;
+			    if (pTile->retcode != RL2_OK)
+				goto error;
+			}
+#ifdef _WIN32
+		      free (handles);
+#endif
+		      thread_count = 0;
+		      /* we can now continue by inserting all tiles into the DBMS */
 		  }
-		if (rl2_raster_encode
-		    (raster, compression, &blob_odd, &blob_odd_sz, &blob_even,
-		     &blob_even_sz, 100, 1) != RL2_OK)
+		else
 		  {
-		      fprintf (stderr,
-			       "ERROR: unable to encode a tile [Row=%d Col=%d]\n",
-			       row, col);
-		      goto error;
+		      aux_tile = aux_tile->next;
+		      continue;
 		  }
+	    }
+	  else
+	    {
+		/* single thread execution */
+		do_get_tile (aux_tile);
+		*(thread_slots + 0) = aux_tile;
+		do_encode_tile (aux_tile);
+		if (aux_tile->retcode != RL2_OK)
+		    goto error;
+	    }
 
-		/* INSERTing the tile */
+	  for (thread_count = 0; thread_count < max_threads; thread_count++)
+	    {
+		/* INSERTing the tile(s) */
+		rl2AuxImporterTilePtr pTile = *(thread_slots + thread_count);
+		if (pTile == NULL)
+		    continue;
 		if (!do_insert_tile
-		    (handle, blob_odd, blob_odd_sz, blob_even, blob_even_sz,
-		     section_id, srid, res_x, res_y, tile_w, tile_h, miny,
-		     maxx, &tile_minx, &tile_miny, &tile_maxx, &tile_maxy,
+		    (handle, pTile->blob_odd, pTile->blob_odd_sz,
+		     pTile->blob_even, pTile->blob_even_sz, section_id, srid,
+		     pTile->minx, pTile->miny, pTile->maxx, pTile->maxy,
 		     NULL, no_data, stmt_tils, stmt_data, section_stats))
-		    goto error;
-		blob_odd = NULL;
-		blob_even = NULL;
-		rl2_destroy_raster (raster);
-		raster = NULL;
-		tile_minx += (double) tile_w *res_x;
+		  {
+		      pTile->blob_odd = NULL;
+		      pTile->blob_even = NULL;
+		      goto error;
+		  }
+		doAuxImporterTileCleanup (pTile);
 	    }
-	  tile_maxy -= (double) tile_h *res_y;
+	  for (thread_count = 0; thread_count < max_threads; thread_count++)
+	      *(thread_slots + thread_count) = NULL;
+	  thread_count = 0;
+	  aux_tile = aux_tile->next;
       }
+    destroyAuxImporter (aux);
+    aux = NULL;
+    free (thread_slots);
+    thread_slots = NULL;
 
 /* updating the Section's Statistics */
     compute_aggregate_sq_diff (section_stats);
-    if (!do_insert_stats (handle, section_stats, section_id, stmt_upd_sect))
+    if (!rl2_do_insert_stats (handle, section_stats, section_id, stmt_upd_sect))
 	goto error;
 
     rl2_destroy_section (origin);
     rl2_destroy_raster_statistics (section_stats);
     origin = NULL;
     section_stats = NULL;
+    time (&now);
+    diff = now - start;
+    mins = diff / 60;
+    secs = diff - (mins * 60);
+    printf (">> Image successfully imported in: %d mins %02d secs\n", mins,
+	    secs);
 
     if (pyramidize)
       {
 	  /* immediately building the Section's Pyramid */
 	  const char *coverage_name = rl2_get_coverage_name (cvg);
-	  const char *section_name = section;
-	  char *sect_name = NULL;
 	  if (coverage_name == NULL)
 	      goto error;
-	  if (section_name == NULL)
-	    {
-		sect_name = get_section_name (src_path);
-		section_name = sect_name;
-	    }
-	  if (section_name == NULL)
-	      goto error;
-	  if (rl2_build_section_pyramid (handle, coverage_name, section_name, 1)
-	      != RL2_OK)
+	  if (rl2_build_section_pyramid
+	      (handle, max_threads, coverage_name, section_id, 1,
+	       verbose) != RL2_OK)
 	    {
-		if (sect_name != NULL)
-		    free (sect_name);
 		fprintf (stderr, "unable to build the Section's Pyramid\n");
 		goto error;
 	    }
-	  if (sect_name != NULL)
-	      free (sect_name);
       }
 
     return 1;
 
   error:
-    if (blob_odd != NULL)
-	free (blob_odd);
-    if (blob_even != NULL)
-	free (blob_even);
+    if (aux != NULL)
+	destroyAuxImporter (aux);
+    if (thread_slots != NULL)
+	free (thread_slots);
     if (origin != NULL)
 	rl2_destroy_section (origin);
     if (raster != NULL)
@@ -760,63 +1530,79 @@ do_import_jpeg_image (sqlite3 * handle, const char *src_path,
     return 0;
 }
 
-static int
-is_ascii_grid (const char *path)
-{
-/* testing for an ASCII Grid */
-    int len = strlen (path);
-    if (len > 4)
-      {
-	  if (strcasecmp (path + len - 4, ".asc") == 0)
-	      return 1;
-      }
-    return 0;
-}
+#ifndef OMIT_OPENJPEG		/* only if OpenJpeg is enabled */
 
 static int
-is_jpeg_image (const char *path)
+read_j2w_worldfile (const char *src_path, double *minx, double *maxy,
+		    double *pres_x, double *pres_y)
 {
-/* testing for a JPEG image */
-    int len = strlen (path);
-    if (len > 4)
+/* attempting to retrieve georeferencing from a Jpeg2000+J2W origin */
+    FILE *j2w = NULL;
+    double res_x;
+    double res_y;
+    double x;
+    double y;
+    char *j2w_path = NULL;
+
+    j2w_path = rl2_build_worldfile_path (src_path, ".j2w");
+    if (j2w_path == NULL)
+	goto error;
+    j2w = fopen (j2w_path, "r");
+    free (j2w_path);
+    j2w_path = NULL;
+    if (j2w == NULL)
       {
-	  if (strcasecmp (path + len - 4, ".jpg") == 0)
-	      return 1;
+	  /* trying the ".wld" suffix */
+	  j2w_path = rl2_build_worldfile_path (src_path, ".wld");
+	  if (j2w_path == NULL)
+	      goto error;
+	  j2w = fopen (j2w_path, "r");
+	  free (j2w_path);
       }
+    if (j2w == NULL)
+	goto error;
+    if (!parse_worldfile (j2w, &x, &y, &res_x, &res_y))
+	goto error;
+    fclose (j2w);
+    *pres_x = res_x;
+    *pres_y = res_y;
+    *minx = x;
+    *maxy = y;
+    return 1;
+
+  error:
+    if (j2w_path != NULL)
+	free (j2w_path);
+    if (j2w != NULL)
+	fclose (j2w);
     return 0;
 }
 
 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)
+do_import_jpeg2000_image (sqlite3 * handle, int max_threads,
+			  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, int quality,
+			  sqlite3_stmt * stmt_data, sqlite3_stmt * stmt_tils,
+			  sqlite3_stmt * stmt_sect, sqlite3_stmt * stmt_levl,
+			  sqlite3_stmt * stmt_upd_sect, int verbose,
+			  int current, int total)
 {
-/* importing a single Source file */
-    int ret;
-    rl2TiffOriginPtr origin = NULL;
+/* importing a Jpeg2000 image file [with optional WorldFile */
+    rl2PrivCoveragePtr p_coverage = (rl2PrivCoveragePtr) cvg;
+    rl2SectionPtr origin = NULL;
+    rl2RasterPtr rst_in;
+    rl2PrivRasterPtr raster_in;
     rl2RasterPtr raster = NULL;
-    rl2PalettePtr aux_palette = NULL;
     rl2RasterStatisticsPtr section_stats = NULL;
     rl2PixelPtr no_data = NULL;
     unsigned int row;
     unsigned int col;
     unsigned int width;
     unsigned int height;
-    unsigned char *blob_odd = NULL;
-    unsigned char *blob_even = NULL;
-    int blob_odd_sz;
-    int blob_even_sz;
-    int srid;
-    int xsrid;
     double tile_minx;
-    double tile_miny;
-    double tile_maxx;
     double tile_maxy;
     double minx;
     double miny;
@@ -824,204 +1610,369 @@ do_import_file (sqlite3 * handle, const char *src_path,
     double maxy;
     double res_x;
     double res_y;
+    int is_georeferenced = 0;
     char *dumb1;
     char *dumb2;
     sqlite3_int64 section_id;
+    unsigned char forced_conversion = RL2_CONVERT_NO;
     double base_res_x;
     double base_res_y;
-
-    if (is_ascii_grid (src_path))
-	return do_import_ascii_grid (handle, src_path, cvg, section, force_srid,
-				     tile_w, tile_h, pyramidize, sample_type,
-				     compression, stmt_data, stmt_tils,
-				     stmt_sect, stmt_levl, stmt_upd_sect);
-
-    if (is_jpeg_image (src_path))
-	return do_import_jpeg_image (handle, src_path, cvg, section, force_srid,
-				     tile_w, tile_h, pyramidize, sample_type,
-				     num_bands, compression, stmt_data,
-				     stmt_tils, stmt_sect, stmt_levl,
-				     stmt_upd_sect);
+    rl2PrivCoveragePtr coverage = (rl2PrivCoveragePtr) cvg;
+    double confidence;
+    time_t start;
+    time_t now;
+    time_t diff;
+    int mins;
+    int secs;
+    unsigned char xsample_type;
+    unsigned char pixel_type;
+    unsigned char xnum_bands;
+    unsigned int tile_width;
+    unsigned int tile_height;
+    unsigned char num_levels;
+    char *xml_summary = NULL;
+    rl2AuxImporterPtr aux = NULL;
+    rl2AuxImporterTilePtr aux_tile;
+    rl2AuxImporterTilePtr *thread_slots = NULL;
+    int thread_count;
 
     if (rl2_get_coverage_resolution (cvg, &base_res_x, &base_res_y) != RL2_OK)
-	goto error;
-    if (worldfile)
-	origin =
-	    rl2_create_tiff_origin (src_path, RL2_TIFF_WORLDFILE, force_srid,
-				    sample_type, pixel_type, num_bands);
-    else
-	origin =
-	    rl2_create_tiff_origin (src_path, RL2_TIFF_GEOTIFF, force_srid,
-				    sample_type, pixel_type, num_bands);
+      {
+	  if (verbose)
+	      fprintf (stderr, "Unknown Coverage Resolution\n");
+	  goto error;
+      }
+    origin =
+	rl2_section_from_jpeg2000 (src_path, p_coverage->sampleType,
+				   p_coverage->pixelType, p_coverage->nBands);
     if (origin == NULL)
+      {
+	  if (verbose)
+	      fprintf (stderr, "Invalid Jpeg2000 Origin: %s\n", src_path);
+	  goto error;
+      }
+    if (rl2_get_jpeg2000_infos
+	(src_path, &width, &height, &xsample_type, &pixel_type, &xnum_bands,
+	 &tile_width, &tile_height, &num_levels) != RL2_OK)
+      {
+	  if (verbose)
+	      fprintf (stderr, "Invalid Jpeg2000 Origin: %s\n", src_path);
+	  goto error;
+      }
+    time (&start);
+    rst_in = rl2_get_section_raster (origin);
+    if (!check_jpeg2000_origin_compatibility
+	(rst_in, cvg, &width, &height, &forced_conversion))
 	goto error;
-    if (rl2_get_coverage_srid (cvg, &xsrid) == RL2_OK)
+    if (read_j2w_worldfile (src_path, &minx, &maxy, &res_x, &res_y))
       {
-	  if (xsrid == RL2_GEOREFERENCING_NONE)
-	      rl2_set_tiff_origin_not_referenced (origin);
+	  /* georeferenced Jpeg2000 */
+	  maxx = minx + ((double) width * res_x);
+	  miny = maxy - ((double) height * res_y);
+	  is_georeferenced = 1;
+      }
+    else
+      {
+	  /* not georeferenced Jpeg2000 */
+	  if (srid != -1)
+	      goto error;
+	  minx = 0.0;
+	  miny = 0.0;
+	  maxx = width - 1.0;
+	  maxy = height - 1.0;
+	  res_x = 1.0;
+	  res_y = 1.0;
       }
+    raster_in = (rl2PrivRasterPtr) rst_in;
+    xml_summary =
+	rl2_build_jpeg2000_xml_summary (width, height, raster_in->sampleType,
+					raster_in->pixelType,
+					raster_in->nBands, is_georeferenced,
+					res_x, res_y, minx, miny, maxx, maxy,
+					tile_width, tile_height);
 
-    printf ("Importing: %s\n", rl2_get_tiff_origin_path (origin));
     printf ("------------------\n");
-    ret = rl2_get_tiff_origin_size (origin, &width, &height);
-    if (ret == RL2_OK)
-	printf ("    Image Size (pixels): %d x %d\n", width, height);
-    ret = rl2_get_tiff_origin_srid (origin, &srid);
-    if (ret == RL2_OK)
+    if (total > 1)
+	printf ("%d/%d) Importing: %s\n", current, total, src_path);
+    else
+	printf ("Importing: %s\n", src_path);
+    printf ("    Image Size (pixels): %d x %d\n", width, height);
+    printf ("                   SRID: %d\n", srid);
+    dumb1 = formatLong (minx);
+    dumb2 = formatLat (miny);
+    printf ("       LowerLeft Corner: X=%s Y=%s\n", dumb1, dumb2);
+    sqlite3_free (dumb1);
+    sqlite3_free (dumb2);
+    dumb1 = formatLong (maxx);
+    dumb2 = formatLat (maxy);
+    printf ("      UpperRight Corner: X=%s Y=%s\n", dumb1, dumb2);
+    sqlite3_free (dumb1);
+    sqlite3_free (dumb2);
+    dumb1 = formatFloat (res_x);
+    dumb2 = formatFloat (res_y);
+    printf ("       Pixel resolution: X=%s Y=%s\n", dumb1, dumb2);
+    sqlite3_free (dumb1);
+    sqlite3_free (dumb2);
+    if (coverage->Srid != srid)
       {
-	  if (force_srid > 0 && force_srid != srid)
-	    {
-		printf ("                   SRID: %d (forced to %d)\n", srid,
-			force_srid);
-		srid = force_srid;
-	    }
-	  else
-	      printf ("                   SRID: %d\n", srid);
+	  if (verbose)
+	      fprintf (stderr, "Mismatching SRID !!!\n");
+	  goto error;
       }
-    ret = rl2_get_tiff_origin_extent (origin, &minx, &miny, &maxx, &maxy);
-    if (ret == RL2_OK)
+    if (coverage->mixedResolutions)
       {
-	  dumb1 = formatLong (minx);
-	  dumb2 = formatLat (miny);
-	  printf ("       LowerLeft Corner: X=%s Y=%s\n", dumb1, dumb2);
-	  sqlite3_free (dumb1);
-	  sqlite3_free (dumb2);
-	  dumb1 = formatLong (maxx);
-	  dumb2 = formatLat (maxy);
-	  printf ("      UpperRight Corner: X=%s Y=%s\n", dumb1, dumb2);
-	  sqlite3_free (dumb1);
-	  sqlite3_free (dumb2);
+	  /* accepting any resolution */
       }
-    ret = rl2_get_tiff_origin_resolution (origin, &res_x, &res_y);
-    if (ret == RL2_OK)
+    else if (coverage->strictResolution)
       {
-	  dumb1 = formatFloat (res_x);
-	  dumb2 = formatFloat (res_y);
-	  printf ("       Pixel resolution: X=%s Y=%s\n", dumb1, dumb2);
-	  sqlite3_free (dumb1);
-	  sqlite3_free (dumb2);
+	  /* enforcing Strict Resolution check */
+	  if (res_x != coverage->hResolution)
+	    {
+		if (verbose)
+		    fprintf (stderr,
+			     "Mismatching Horizontal Resolution (Strict) !!!\n");
+		goto error;
+	    }
+	  if (res_y != coverage->vResolution)
+	    {
+		if (verbose)
+		    fprintf (stderr,
+			     "Mismatching Vertical Resolution (Strict) !!!\n");
+		goto error;
+	    }
       }
-
-    if (pixel_type == RL2_PIXEL_PALETTE)
+    else
       {
-	  /* remapping the Palette */
-	  if (rl2_check_dbms_palette (handle, cvg, origin) != RL2_OK)
+	  /* permissive Resolution check */
+	  confidence = coverage->hResolution / 100.0;
+	  if (res_x < (coverage->hResolution - confidence)
+	      || res_x > (coverage->hResolution + confidence))
 	    {
-		fprintf (stderr, "Mismatching Palette !!!\n");
+		if (verbose)
+		    fprintf (stderr,
+			     "Mismatching Horizontal Resolution (Permissive) !!!\n");
+		goto error;
+	    }
+	  confidence = coverage->vResolution / 100.0;
+	  if (res_y < (coverage->vResolution - confidence)
+	      || res_y > (coverage->vResolution + confidence))
+	    {
+		if (verbose)
+		    fprintf (stderr,
+			     "Mismatching Vertical Resolution !(Permissive) !!\n");
 		goto error;
 	    }
       }
 
-    if (rl2_eval_tiff_origin_compatibility (cvg, origin, force_srid) !=
-	RL2_TRUE)
-      {
-	  fprintf (stderr, "Coverage/TIFF mismatch\n");
-	  goto error;
-      }
     no_data = rl2_get_coverage_no_data (cvg);
 
 /* INSERTing the section */
-    if (!do_insert_section
-	(handle, src_path, section, srid, width, height, minx, miny, maxx, maxy,
-	 stmt_sect, &section_id))
+    if (!rl2_do_insert_section
+	(handle, src_path, section, srid, width, height, minx, miny, maxx,
+	 maxy, xml_summary, coverage->sectionPaths, coverage->sectionMD5,
+	 coverage->sectionSummary, stmt_sect, &section_id))
 	goto error;
     section_stats = rl2_create_raster_statistics (sample_type, num_bands);
     if (section_stats == NULL)
 	goto error;
 /* INSERTing the base-levels */
-    if (!do_insert_levels
-	(handle, base_res_x, base_res_y, 1.0, sample_type, stmt_levl))
-	goto error;
-
+    if (coverage->mixedResolutions)
+      {
+	  /* multiple resolutions Coverage */
+	  if (!rl2_do_insert_section_levels
+	      (handle, section_id, res_x, res_y, 1.0, sample_type, stmt_levl))
+	      goto error;
+      }
+    else
+      {
+	  /* single resolution Coverage */
+	  if (!rl2_do_insert_levels
+	      (handle, base_res_x, base_res_y, 1.0, sample_type, stmt_levl))
+	      goto error;
+      }
+
+/* preparing all Tile Requests */
+    aux =
+	createAuxImporter (coverage, srid, maxx, miny, tile_w, tile_h, res_x,
+			   res_y, RL2_ORIGIN_JPEG2000, rst_in,
+			   forced_conversion, verbose, compression, quality);
     tile_maxy = maxy;
     for (row = 0; row < height; row += tile_h)
       {
 	  tile_minx = minx;
 	  for (col = 0; col < width; col += tile_w)
 	    {
-		raster =
-		    rl2_get_tile_from_tiff_origin (cvg, origin, row, col, srid);
-		if (raster == NULL)
+		/* adding a Tile request */
+		addTile2AuxImporter (aux, row, col, tile_minx, tile_maxy);
+		tile_minx += (double) tile_w *res_x;
+	    }
+	  tile_maxy -= (double) tile_h *res_y;
+      }
+
+    if (max_threads < 1)
+	max_threads = 1;
+    if (max_threads > 64)
+	max_threads = 64;
+/* prepating the thread_slots stuct */
+    thread_slots = malloc (sizeof (rl2AuxImporterTilePtr) * max_threads);
+    for (thread_count = 0; thread_count < max_threads; thread_count++)
+	*(thread_slots + thread_count) = NULL;
+    thread_count = 0;
+    aux_tile = aux->first;
+    while (aux_tile != NULL)
+      {
+	  /* processing a Tile request (may be under parallel execution) */
+	  if (max_threads > 1)
+	    {
+		/* adopting a multithreaded strategy */
+		do_get_tile (aux_tile);
+		*(thread_slots + thread_count) = aux_tile;
+		thread_count++;
+		start_tile_thread (aux_tile);
+		if (thread_count == max_threads || aux_tile->next == NULL)
 		  {
-		      fprintf (stderr,
-			       "ERROR: unable to get a tile [Row=%d Col=%d]\n",
-			       row, col);
-		      goto error;
+		      /* waiting until all child threads exit */
+#ifdef _WIN32
+		      HANDLE *handles;
+		      int z;
+		      int cnt = 0;
+		      for (z = 0; z < max_threads; z++)
+			{
+			    /* counting how many active threads we currently have */
+			    rl2AuxImporterTilePtr pTile = *(thread_slots + z);
+			    if (pTile == NULL)
+				continue;
+			    cnt++;
+			}
+		      handles = malloc (sizeof (HANDLE) * cnt);
+		      cnt = 0;
+		      for (z = 0; z < max_threads; z++)
+			{
+			    /* initializing the HANDLEs array */
+			    HANDLE *pOpaque;
+			    rl2AuxImporterTilePtr pTile = *(thread_slots + z);
+			    if (pTile == NULL)
+				continue;
+			    pOpaque = (HANDLE *) (pTile->opaque_thread_id);
+			    *(handles + cnt) = *pOpaque;
+			    cnt++;
+			}
+		      WaitForMultipleObjects (cnt, handles, TRUE, INFINITE);
+#else
+		      for (thread_count = 0; thread_count < max_threads;
+			   thread_count++)
+			{
+			    pthread_t *pOpaque;
+			    rl2AuxImporterTilePtr pTile =
+				*(thread_slots + thread_count);
+			    if (pTile == NULL)
+				continue;
+			    pOpaque = (pthread_t *) (pTile->opaque_thread_id);
+			    pthread_join (*pOpaque, NULL);
+			}
+#endif
+
+		      /* all children threads have now finished: resuming the main thread */
+		      for (thread_count = 0; thread_count < max_threads;
+			   thread_count++)
+			{
+			    rl2AuxImporterTilePtr pTile =
+				*(thread_slots + thread_count);
+			    if (pTile == NULL)
+				continue;
+			    if (pTile->retcode != RL2_OK)
+				goto error;
+			}
+#ifdef _WIN32
+		      free (handles);
+#endif
+		      thread_count = 0;
+		      /* we can now continue by inserting all tiles into the DBMS */
 		  }
-		if (rl2_raster_encode
-		    (raster, compression, &blob_odd, &blob_odd_sz, &blob_even,
-		     &blob_even_sz, quality, 1) != RL2_OK)
+		else
 		  {
-		      fprintf (stderr,
-			       "ERROR: unable to encode a tile [Row=%d Col=%d]\n",
-			       row, col);
-		      goto error;
+		      aux_tile = aux_tile->next;
+		      continue;
 		  }
-		/* INSERTing the tile */
-		aux_palette =
-		    rl2_clone_palette (rl2_get_raster_palette (raster));
+	    }
+	  else
+	    {
+		/* single thread execution */
+		do_get_tile (aux_tile);
+		*(thread_slots + 0) = aux_tile;
+		do_encode_tile (aux_tile);
+		if (aux_tile->retcode != RL2_OK)
+		    goto error;
+	    }
 
+	  for (thread_count = 0; thread_count < max_threads; thread_count++)
+	    {
+		/* INSERTing the tile(s) */
+		rl2AuxImporterTilePtr pTile = *(thread_slots + thread_count);
+		if (pTile == NULL)
+		    continue;
 		if (!do_insert_tile
-		    (handle, blob_odd, blob_odd_sz, blob_even, blob_even_sz,
-		     section_id, srid, res_x, res_y, tile_w, tile_h, miny,
-		     maxx, &tile_minx, &tile_miny, &tile_maxx, &tile_maxy,
-		     aux_palette, no_data, stmt_tils, stmt_data, section_stats))
-		    goto error;
-		blob_odd = NULL;
-		blob_even = NULL;
-		rl2_destroy_raster (raster);
-		raster = NULL;
-		tile_minx += (double) tile_w *res_x;
+		    (handle, pTile->blob_odd, pTile->blob_odd_sz,
+		     pTile->blob_even, pTile->blob_even_sz, section_id, srid,
+		     pTile->minx, pTile->miny, pTile->maxx, pTile->maxy,
+		     NULL, no_data, stmt_tils, stmt_data, section_stats))
+		  {
+		      pTile->blob_odd = NULL;
+		      pTile->blob_even = NULL;
+		      goto error;
+		  }
+		doAuxImporterTileCleanup (pTile);
 	    }
-	  tile_maxy -= (double) tile_h *res_y;
+	  for (thread_count = 0; thread_count < max_threads; thread_count++)
+	      *(thread_slots + thread_count) = NULL;
+	  thread_count = 0;
+	  aux_tile = aux_tile->next;
       }
+    destroyAuxImporter (aux);
+    aux = NULL;
+    free (thread_slots);
+    thread_slots = NULL;
 
 /* updating the Section's Statistics */
     compute_aggregate_sq_diff (section_stats);
-    if (!do_insert_stats (handle, section_stats, section_id, stmt_upd_sect))
+    if (!rl2_do_insert_stats (handle, section_stats, section_id, stmt_upd_sect))
 	goto error;
 
-    rl2_destroy_tiff_origin (origin);
+    rl2_destroy_section (origin);
     rl2_destroy_raster_statistics (section_stats);
     origin = NULL;
     section_stats = NULL;
+    time (&now);
+    diff = now - start;
+    mins = diff / 60;
+    secs = diff - (mins * 60);
+    printf (">> Image successfully imported in: %d mins %02d secs\n", mins,
+	    secs);
 
     if (pyramidize)
       {
 	  /* immediately building the Section's Pyramid */
 	  const char *coverage_name = rl2_get_coverage_name (cvg);
-	  const char *section_name = section;
-	  char *sect_name = NULL;
 	  if (coverage_name == NULL)
 	      goto error;
-	  if (section_name == NULL)
-	    {
-		sect_name = get_section_name (src_path);
-		section_name = sect_name;
-	    }
-	  if (section_name == NULL)
-	      goto error;
-	  if (rl2_build_section_pyramid (handle, coverage_name, section_name, 1)
-	      != RL2_OK)
+	  if (rl2_build_section_pyramid
+	      (handle, max_threads, coverage_name, section_id, 1,
+	       verbose) != RL2_OK)
 	    {
-		if (sect_name != NULL)
-		    free (sect_name);
 		fprintf (stderr, "unable to build the Section's Pyramid\n");
 		goto error;
 	    }
-	  if (sect_name != NULL)
-	      free (sect_name);
       }
 
     return 1;
 
   error:
-    if (blob_odd != NULL)
-	free (blob_odd);
-    if (blob_even != NULL)
-	free (blob_even);
+    if (aux != NULL)
+	destroyAuxImporter (aux);
+    if (thread_slots != NULL)
+	free (thread_slots);
     if (origin != NULL)
-	rl2_destroy_tiff_origin (origin);
+	rl2_destroy_section (origin);
     if (raster != NULL)
 	rl2_destroy_raster (raster);
     if (section_stats != NULL)
@@ -1029,358 +1980,896 @@ do_import_file (sqlite3 * handle, const char *src_path,
     return 0;
 }
 
+#endif /* end of OpenJpeg conditional */
+
 static int
-check_extension_match (const char *file_name, const char *file_ext)
+is_ascii_grid (const char *path)
 {
-/* checks the file extension */
-    const char *mark = NULL;
-    const char *p = file_name;
-    int len;
-    char *ext;
-    int match = 0;
-    if (file_ext == NULL)
-	return 0;
-
-    len = strlen (file_ext);
-    if (*file_ext == '.')
-      {
-	  /* file extension starts with dot */
-	  ext = malloc (len + 1);
-	  strcpy (ext, file_ext);
-      }
-    else
-      {
-	  /* file extension doesn't start with dot */
-	  ext = malloc (len + 2);
-	  *ext = '.';
-	  strcpy (ext + 1, file_ext);
-      }
-    while (*p != '\0')
-      {
-	  if (*p == '.')
-	      mark = p;
-	  p++;
-      }
-    if (mark == NULL)
+/* testing for an ASCII Grid */
+    int len = strlen (path);
+    if (len > 4)
       {
-	  free (ext);
-	  return 0;
+	  if (strcasecmp (path + len - 4, ".asc") == 0)
+	      return 1;
       }
-    match = strcasecmp (mark, ext);
-    free (ext);
-    if (match == 0)
-	return 1;
     return 0;
 }
 
 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)
+is_jpeg_image (const char *path)
 {
-/* importing a whole directory */
-#if defined(_WIN32) && !defined(__MINGW32__)
-/* Visual Studio .NET */
-    struct _finddata_t c_file;
-    intptr_t hFile;
-    int cnt = 0;
-    char *search;
-    char *path;
-    int ret;
-    if (_chdir (dir_path) < 0)
-	return 0;
-    search = sqlite3_mprintf ("*%s", file_ext);
-    if ((hFile = _findfirst (search, &c_file)) == -1L)
-	;
-    else
+/* testing for a JPEG image */
+    int len = strlen (path);
+    if (len > 4)
       {
-	  while (1)
-	    {
-		if ((c_file.attrib & _A_RDONLY) == _A_RDONLY
-		    || (c_file.attrib & _A_NORMAL) == _A_NORMAL)
-		  {
-		      path = sqlite3_mprintf ("%s/%s", dir_path, c_file.name);
-		      ret =
-			  do_import_file (handle, path, cvg, section, worldfile,
-					  force_srid, pyramidize, sample_type,
-					  pixel_type, num_bands, tile_w, tile_h,
-					  compression, quality, stmt_data,
-					  stmt_tils, stmt_sect, stmt_levl,
-					  stmt_upd_sect);
-		      sqlite3_free (path);
-		      if (!ret)
-			  goto error;
-		      cnt++;
-		  }
-		if (_findnext (hFile, &c_file) != 0)
-		    break;
-	    };
-	error:
-	  _findclose (hFile);
+	  if (strcasecmp (path + len - 4, ".jpg") == 0)
+	      return 1;
       }
-    sqlite3_free (search);
-    return cnt;
-#else
-/* not Visual Studio .NET */
-    int cnt = 0;
-    char *path;
-    struct dirent *entry;
-    int ret;
-    DIR *dir = opendir (dir_path);
-    if (!dir)
-	return 0;
-    while (1)
+    return 0;
+}
+
+#ifndef OMIT_OPENJPEG		/* only if OpenJpeg is enabled */
+
+static int
+is_jpeg2000_image (const char *path)
+{
+/* testing for a Jpeg2000 image */
+    int len = strlen (path);
+    if (len > 4)
       {
-	  /* scanning dir-entries */
-	  entry = readdir (dir);
-	  if (!entry)
-	      break;
-	  if (!check_extension_match (entry->d_name, file_ext))
-	      continue;
-	  path = sqlite3_mprintf ("%s/%s", dir_path, entry->d_name);
-	  ret =
-	      do_import_file (handle, path, cvg, section, worldfile, force_srid,
-			      pyramidize, sample_type, pixel_type, num_bands,
-			      tile_w, tile_h, compression, quality, stmt_data,
-			      stmt_tils, stmt_sect, stmt_levl, stmt_upd_sect);
-	  sqlite3_free (path);
-	  if (!ret)
-	      goto error;
-	  cnt++;
+	  if (strcasecmp (path + len - 4, ".jp2") == 0)
+	      return 1;
       }
-  error:
-    closedir (dir);
-    return cnt;
-#endif
+    return 0;
 }
 
+#endif /* end OpenJpeg conditional */
+
 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)
+do_import_file (sqlite3 * handle, int max_threads, 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, int verbose, int current,
+		int total)
 {
-/* main IMPORT Raster function */
+/* importing a single Source file */
+    rl2PrivCoveragePtr coverage = (rl2PrivCoveragePtr) cvg;
     int ret;
-    char *sql;
-    const char *coverage;
-    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;
-    char *table;
-    char *xtable;
-    unsigned int tileWidth;
-    unsigned int tileHeight;
-    sqlite3_stmt *stmt_data = NULL;
-    sqlite3_stmt *stmt_tils = NULL;
-    sqlite3_stmt *stmt_sect = NULL;
-    sqlite3_stmt *stmt_levl = NULL;
-    sqlite3_stmt *stmt_upd_sect = NULL;
-
-    if (cvg == NULL)
-	goto error;
-
-    if (rl2_get_coverage_tile_size (cvg, &tileWidth, &tileHeight) != RL2_OK)
-	goto error;
+    rl2TiffOriginPtr origin = NULL;
+    rl2PalettePtr aux_palette = NULL;
+    rl2RasterStatisticsPtr section_stats = NULL;
+    rl2PixelPtr no_data = NULL;
+    unsigned int row;
+    unsigned int col;
+    unsigned int width;
+    unsigned int height;
+    int srid;
+    int xsrid;
+    double tile_minx;
+    double tile_maxy;
+    double minx;
+    double miny;
+    double maxx;
+    double maxy;
+    double res_x;
+    double res_y;
+    char *dumb1;
+    char *dumb2;
+    sqlite3_int64 section_id;
+    double base_res_x;
+    double base_res_y;
+    double confidence;
+    time_t start;
+    time_t now;
+    time_t diff;
+    int mins;
+    int secs;
+    char *xml_summary = NULL;
+    rl2AuxImporterPtr aux = NULL;
+    rl2AuxImporterTilePtr aux_tile;
+    rl2AuxImporterTilePtr *thread_slots = NULL;
+    int thread_count;
 
-    tile_w = tileWidth;
-    tile_h = tileHeight;
-    rl2_get_coverage_compression (cvg, &compression, &quality);
-    rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands);
-    coverage = rl2_get_coverage_name (cvg);
+    if (is_ascii_grid (src_path))
+	return do_import_ascii_grid (handle, max_threads, src_path, cvg,
+				     section, force_srid, tile_w, tile_h,
+				     pyramidize, sample_type, compression,
+				     stmt_data, stmt_tils, stmt_sect,
+				     stmt_levl, stmt_upd_sect, verbose,
+				     current, total);
 
-    table = sqlite3_mprintf ("%s_sections", coverage);
-    xtable = gaiaDoubleQuotedSql (table);
-    sqlite3_free (table);
-    sql =
-	sqlite3_mprintf
-	("INSERT INTO \"%s\" (section_id, section_name, file_path, "
-	 "width, height, geometry) VALUES (NULL, ?, ?, ?, ?, ?)", xtable);
-    free (xtable);
-    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_sect, NULL);
-    sqlite3_free (sql);
-    if (ret != SQLITE_OK)
+    if (is_jpeg_image (src_path))
+	return do_import_jpeg_image (handle, max_threads, src_path, cvg,
+				     section, force_srid, tile_w, tile_h,
+				     pyramidize, sample_type, num_bands,
+				     compression, quality, stmt_data,
+				     stmt_tils, stmt_sect, stmt_levl,
+				     stmt_upd_sect, verbose, current, total);
+
+#ifndef OMIT_OPENJPEG		/* only if OpenJpeg is enabled */
+    if (is_jpeg2000_image (src_path))
+	return do_import_jpeg2000_image (handle, max_threads, src_path, cvg,
+					 section, force_srid, tile_w, tile_h,
+					 pyramidize, sample_type, num_bands,
+					 compression, quality, stmt_data,
+					 stmt_tils, stmt_sect, stmt_levl,
+					 stmt_upd_sect, verbose, current,
+					 total);
+#endif /* end OpenJpeg conditonal */
+
+    time (&start);
+    if (rl2_get_coverage_resolution (cvg, &base_res_x, &base_res_y) != RL2_OK)
       {
-	  printf ("INSERT INTO sections SQL error: %s\n",
-		  sqlite3_errmsg (handle));
+	  if (verbose)
+	      fprintf (stderr, "Unknown Coverage Resolution\n");
+	  goto error;
+      }
+    if (worldfile)
+	origin =
+	    rl2_create_tiff_origin (src_path, RL2_TIFF_WORLDFILE, force_srid,
+				    sample_type, pixel_type, num_bands);
+    else
+	origin =
+	    rl2_create_tiff_origin (src_path, RL2_TIFF_GEOTIFF, force_srid,
+				    sample_type, pixel_type, num_bands);
+    if (origin == NULL)
+      {
+	  if (verbose)
+	      fprintf (stderr, "Invalid TIFF Origin: %s\n", src_path);
 	  goto error;
       }
+    if (rl2_get_coverage_srid (cvg, &xsrid) == RL2_OK)
+      {
+	  if (xsrid == RL2_GEOREFERENCING_NONE)
+	      rl2_set_tiff_origin_not_referenced (origin);
+      }
+    xml_summary = rl2_build_tiff_xml_summary (origin);
 
-    table = sqlite3_mprintf ("%s_sections", coverage);
-    xtable = gaiaDoubleQuotedSql (table);
-    sqlite3_free (table);
-    sql =
-	sqlite3_mprintf
-	("UPDATE \"%s\" SET statistics = ? WHERE section_id = ?", xtable);
-    free (xtable);
-    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_upd_sect, NULL);
-    sqlite3_free (sql);
-    if (ret != SQLITE_OK)
+    printf ("------------------\n");
+    if (total > 1)
+	printf ("%d/%d) Importing: %s\n", current, total,
+		rl2_get_tiff_origin_path (origin));
+    else
+	printf ("Importing: %s\n", rl2_get_tiff_origin_path (origin));
+    ret = rl2_get_tiff_origin_size (origin, &width, &height);
+    if (ret == RL2_OK)
+	printf ("    Image Size (pixels): %d x %d\n", width, height);
+    ret = rl2_get_tiff_origin_srid (origin, &srid);
+    if (ret == RL2_OK)
       {
-	  printf ("UPDATE sections SQL error: %s\n", sqlite3_errmsg (handle));
-	  goto error;
+	  if (force_srid > 0 && force_srid != srid)
+	    {
+		printf ("                   SRID: %d (forced to %d)\n", srid,
+			force_srid);
+		srid = force_srid;
+	    }
+	  else
+	      printf ("                   SRID: %d\n", srid);
       }
-
-    table = sqlite3_mprintf ("%s_levels", coverage);
-    xtable = gaiaDoubleQuotedSql (table);
-    sqlite3_free (table);
-    sql =
-	sqlite3_mprintf
-	("INSERT OR IGNORE INTO \"%s\" (pyramid_level, "
-	 "x_resolution_1_1, y_resolution_1_1, "
-	 "x_resolution_1_2, y_resolution_1_2, x_resolution_1_4, "
-	 "y_resolution_1_4, x_resolution_1_8, y_resolution_1_8) "
-	 "VALUES (0, ?, ?, ?, ?, ?, ?, ?, ?)", xtable);
-    free (xtable);
-    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_levl, NULL);
-    sqlite3_free (sql);
-    if (ret != SQLITE_OK)
+    ret = rl2_get_tiff_origin_extent (origin, &minx, &miny, &maxx, &maxy);
+    if (ret == RL2_OK)
       {
-	  printf ("INSERT INTO levels SQL error: %s\n",
-		  sqlite3_errmsg (handle));
-	  goto error;
+	  dumb1 = formatLong (minx);
+	  dumb2 = formatLat (miny);
+	  printf ("       LowerLeft Corner: X=%s Y=%s\n", dumb1, dumb2);
+	  sqlite3_free (dumb1);
+	  sqlite3_free (dumb2);
+	  dumb1 = formatLong (maxx);
+	  dumb2 = formatLat (maxy);
+	  printf ("      UpperRight Corner: X=%s Y=%s\n", dumb1, dumb2);
+	  sqlite3_free (dumb1);
+	  sqlite3_free (dumb2);
+      }
+    ret = rl2_get_tiff_origin_resolution (origin, &res_x, &res_y);
+    if (ret == RL2_OK)
+      {
+	  dumb1 = formatFloat (res_x);
+	  dumb2 = formatFloat (res_y);
+	  printf ("       Pixel resolution: X=%s Y=%s\n", dumb1, dumb2);
+	  sqlite3_free (dumb1);
+	  sqlite3_free (dumb2);
+      }
+    if (coverage->mixedResolutions)
+      {
+	  /* accepting any resolution */
+      }
+    else if (coverage->strictResolution)
+      {
+	  /* enforcing Strict Resolution check */
+	  if (res_x != coverage->hResolution)
+	    {
+		if (verbose)
+		    fprintf (stderr,
+			     "Mismatching Horizontal Resolution (Strict) !!!\n");
+		goto error;
+	    }
+	  if (res_y != coverage->vResolution)
+	    {
+		if (verbose)
+		    fprintf (stderr,
+			     "Mismatching Vertical Resolution (Strict) !!!\n");
+		goto error;
+	    }
+      }
+    else
+      {
+	  /* permissive Resolution check */
+	  confidence = coverage->hResolution / 100.0;
+	  if (res_x < (coverage->hResolution - confidence)
+	      || res_x > (coverage->hResolution + confidence))
+	    {
+		if (verbose)
+		    fprintf (stderr,
+			     "Mismatching Horizontal Resolution (Permissive) !!!\n");
+		goto error;
+	    }
+	  confidence = coverage->vResolution / 100.0;
+	  if (res_y < (coverage->vResolution - confidence)
+	      || res_y > (coverage->vResolution + confidence))
+	    {
+		if (verbose)
+		    fprintf (stderr,
+			     "Mismatching Vertical Resolution !(Permissive) !!\n");
+		goto error;
+	    }
       }
 
-    table = sqlite3_mprintf ("%s_tiles", coverage);
-    xtable = gaiaDoubleQuotedSql (table);
-    sqlite3_free (table);
-    sql =
-	sqlite3_mprintf
-	("INSERT INTO \"%s\" (tile_id, pyramid_level, section_id, geometry) "
-	 "VALUES (NULL, 0, ?, ?)", xtable);
-    free (xtable);
-    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_tils, NULL);
-    sqlite3_free (sql);
-    if (ret != SQLITE_OK)
+    if (pixel_type == RL2_PIXEL_PALETTE)
       {
-	  printf ("INSERT INTO tiles SQL error: %s\n", sqlite3_errmsg (handle));
-	  goto error;
+	  /* remapping the Palette */
+	  if (rl2_check_dbms_palette (handle, cvg, origin) != RL2_OK)
+	    {
+		fprintf (stderr, "Mismatching Palette !!!\n");
+		goto error;
+	    }
       }
 
-    table = sqlite3_mprintf ("%s_tile_data", coverage);
-    xtable = gaiaDoubleQuotedSql (table);
-    sqlite3_free (table);
-    sql =
-	sqlite3_mprintf
-	("INSERT INTO \"%s\" (tile_id, tile_data_odd, tile_data_even) "
-	 "VALUES (?, ?, ?)", xtable);
-    free (xtable);
-    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_data, NULL);
-    sqlite3_free (sql);
-    if (ret != SQLITE_OK)
+    if (rl2_eval_tiff_origin_compatibility (cvg, origin, force_srid, verbose)
+	!= RL2_TRUE)
       {
-	  printf ("INSERT INTO tile_data SQL error: %s\n",
-		  sqlite3_errmsg (handle));
+	  fprintf (stderr, "Coverage/TIFF mismatch\n");
 	  goto error;
       }
+    no_data = rl2_get_coverage_no_data (cvg);
 
-    if (dir_path == NULL)
+/* INSERTing the section */
+    if (!rl2_do_insert_section
+	(handle, src_path, section, srid, width, height, minx, miny, maxx,
+	 maxy, xml_summary, coverage->sectionPaths, coverage->sectionMD5,
+	 coverage->sectionSummary, stmt_sect, &section_id))
+	goto error;
+    section_stats = rl2_create_raster_statistics (sample_type, num_bands);
+    if (section_stats == NULL)
+	goto error;
+/* INSERTing the base-levels */
+    if (coverage->mixedResolutions)
       {
-	  /* importing a single Image file */
-	  if (!do_import_file
-	      (handle, src_path, cvg, section, worldfile, force_srid,
-	       pyramidize, sample_type, pixel_type, num_bands, tile_w, tile_h,
-	       compression, quality, stmt_data, stmt_tils, stmt_sect,
-	       stmt_levl, stmt_upd_sect))
+	  /* multiple resolutions Coverage */
+	  if (!rl2_do_insert_section_levels
+	      (handle, section_id, res_x, res_y, 1.0, sample_type, stmt_levl))
 	      goto error;
       }
     else
       {
-	  /* importing all Image files from a whole directory */
-	  if (!do_import_dir
-	      (handle, dir_path, file_ext, cvg, section, worldfile, force_srid,
-	       pyramidize, sample_type, pixel_type, num_bands, tile_w, tile_h,
-	       compression, quality, stmt_data, stmt_tils, stmt_sect,
-	       stmt_levl, stmt_upd_sect))
+	  /* single resolution Coverage */
+	  if (!rl2_do_insert_levels
+	      (handle, base_res_x, base_res_y, 1.0, sample_type, stmt_levl))
 	      goto error;
       }
 
-    sqlite3_finalize (stmt_upd_sect);
-    sqlite3_finalize (stmt_sect);
-    sqlite3_finalize (stmt_levl);
-    sqlite3_finalize (stmt_tils);
-    sqlite3_finalize (stmt_data);
-    stmt_upd_sect = NULL;
-    stmt_sect = NULL;
-    stmt_levl = NULL;
-    stmt_tils = NULL;
-    stmt_data = NULL;
+/* preparing all Tile Requests */
+    aux =
+	createAuxImporter (coverage, srid, maxx, miny, tile_w, tile_h, res_x,
+			   res_y, RL2_ORIGIN_TIFF, origin, RL2_CONVERT_NO,
+			   verbose, compression, quality);
+    tile_maxy = maxy;
+    for (row = 0; row < height; row += tile_h)
+      {
+	  tile_minx = minx;
+	  for (col = 0; col < width; col += tile_w)
+	    {
+		/* adding a Tile request */
+		addTile2AuxImporter (aux, row, col, tile_minx, tile_maxy);
+		tile_minx += (double) tile_w *res_x;
+	    }
+	  tile_maxy -= (double) tile_h *res_y;
+      }
 
-    if (rl2_update_dbms_coverage (handle, coverage) != RL2_OK)
+    if (max_threads < 1)
+	max_threads = 1;
+    if (max_threads > 64)
+	max_threads = 64;
+/* prepating the thread_slots stuct */
+    thread_slots = malloc (sizeof (rl2AuxImporterTilePtr) * max_threads);
+    for (thread_count = 0; thread_count < max_threads; thread_count++)
+	*(thread_slots + thread_count) = NULL;
+    thread_count = 0;
+    aux_tile = aux->first;
+    while (aux_tile != NULL)
       {
-	  fprintf (stderr, "unable to update the Coverage\n");
-	  goto error;
+	  /* processing a Tile request (may be under parallel execution) */
+	  if (max_threads > 1)
+	    {
+		/* adopting a multithreaded strategy */
+		do_get_tile (aux_tile);
+		*(thread_slots + thread_count) = aux_tile;
+		thread_count++;
+		start_tile_thread (aux_tile);
+		if (thread_count == max_threads || aux_tile->next == NULL)
+		  {
+		      /* waiting until all child threads exit */
+#ifdef _WIN32
+		      HANDLE *handles;
+		      int z;
+		      int cnt = 0;
+		      for (z = 0; z < max_threads; z++)
+			{
+			    /* counting how many active threads we currently have */
+			    rl2AuxImporterTilePtr pTile = *(thread_slots + z);
+			    if (pTile == NULL)
+				continue;
+			    cnt++;
+			}
+		      handles = malloc (sizeof (HANDLE) * cnt);
+		      cnt = 0;
+		      for (z = 0; z < max_threads; z++)
+			{
+			    /* initializing the HANDLEs array */
+			    HANDLE *pOpaque;
+			    rl2AuxImporterTilePtr pTile = *(thread_slots + z);
+			    if (pTile == NULL)
+				continue;
+			    pOpaque = (HANDLE *) (pTile->opaque_thread_id);
+			    *(handles + cnt) = *pOpaque;
+			    cnt++;
+			}
+		      WaitForMultipleObjects (cnt, handles, TRUE, INFINITE);
+#else
+		      for (thread_count = 0; thread_count < max_threads;
+			   thread_count++)
+			{
+			    pthread_t *pOpaque;
+			    rl2AuxImporterTilePtr pTile =
+				*(thread_slots + thread_count);
+			    if (pTile == NULL)
+				continue;
+			    pOpaque = (pthread_t *) (pTile->opaque_thread_id);
+			    pthread_join (*pOpaque, NULL);
+			}
+#endif
+
+		      /* all children threads have now finished: resuming the main thread */
+		      for (thread_count = 0; thread_count < max_threads;
+			   thread_count++)
+			{
+			    rl2AuxImporterTilePtr pTile =
+				*(thread_slots + thread_count);
+			    if (pTile == NULL)
+				continue;
+			    if (pTile->retcode != RL2_OK)
+				goto error;
+			}
+#ifdef _WIN32
+		      free (handles);
+#endif
+		      thread_count = 0;
+		      /* we can now continue by inserting all tiles into the DBMS */
+		  }
+		else
+		  {
+		      aux_tile = aux_tile->next;
+		      continue;
+		  }
+	    }
+	  else
+	    {
+		/* single thread execution */
+		do_get_tile (aux_tile);
+		*(thread_slots + 0) = aux_tile;
+		do_encode_tile (aux_tile);
+		if (aux_tile->retcode != RL2_OK)
+		    goto error;
+	    }
+
+	  for (thread_count = 0; thread_count < max_threads; thread_count++)
+	    {
+		/* INSERTing the tile(s) */
+		rl2AuxImporterTilePtr pTile = *(thread_slots + thread_count);
+		if (pTile == NULL)
+		    continue;
+		aux_palette =
+		    rl2_clone_palette (rl2_get_raster_palette
+				       (aux_tile->raster));
+		if (!do_insert_tile
+		    (handle, pTile->blob_odd, pTile->blob_odd_sz,
+		     pTile->blob_even, pTile->blob_even_sz, section_id, srid,
+		     pTile->minx, pTile->miny, pTile->maxx, pTile->maxy,
+		     aux_palette, no_data, stmt_tils, stmt_data, section_stats))
+		  {
+		      pTile->blob_odd = NULL;
+		      pTile->blob_even = NULL;
+		      goto error;
+		  }
+		doAuxImporterTileCleanup (pTile);
+	    }
+	  for (thread_count = 0; thread_count < max_threads; thread_count++)
+	      *(thread_slots + thread_count) = NULL;
+	  thread_count = 0;
+	  aux_tile = aux_tile->next;
+      }
+    destroyAuxImporter (aux);
+    aux = NULL;
+    free (thread_slots);
+    thread_slots = NULL;
+
+/* updating the Section's Statistics */
+    compute_aggregate_sq_diff (section_stats);
+    if (!rl2_do_insert_stats (handle, section_stats, section_id, stmt_upd_sect))
+	goto error;
+
+    rl2_destroy_tiff_origin (origin);
+    rl2_destroy_raster_statistics (section_stats);
+    origin = NULL;
+    section_stats = NULL;
+    time (&now);
+    diff = now - start;
+    mins = diff / 60;
+    secs = diff - (mins * 60);
+    printf (">> Image successfully imported in: %d mins %02d secs\n", mins,
+	    secs);
+
+    if (pyramidize)
+      {
+	  /* immediately building the Section's Pyramid */
+	  const char *coverage_name = rl2_get_coverage_name (cvg);
+	  if (coverage_name == NULL)
+	      goto error;
+	  if (rl2_build_section_pyramid
+	      (handle, max_threads, coverage_name, section_id, 1,
+	       verbose) != RL2_OK)
+	    {
+		fprintf (stderr, "unable to build the Section's Pyramid\n");
+		goto error;
+	    }
       }
 
     return 1;
 
   error:
-    if (stmt_upd_sect != NULL)
-	sqlite3_finalize (stmt_upd_sect);
-    if (stmt_sect != NULL)
-	sqlite3_finalize (stmt_sect);
-    if (stmt_levl != NULL)
-	sqlite3_finalize (stmt_levl);
-    if (stmt_tils != NULL)
-	sqlite3_finalize (stmt_tils);
-    if (stmt_data != NULL)
-	sqlite3_finalize (stmt_data);
+    if (aux != NULL)
+	destroyAuxImporter (aux);
+    if (thread_slots != NULL)
+	free (thread_slots);
+    if (section_stats != NULL)
+	rl2_destroy_raster_statistics (section_stats);
     return 0;
 }
 
-RL2_DECLARE int
-rl2_load_raster_into_dbms (sqlite3 * handle, const char *src_path,
-			   rl2CoveragePtr coverage, int worldfile,
-			   int force_srid, int pyramidize)
+static int
+check_extension_match (const char *file_name, const char *file_ext)
 {
-/* importing a single Raster file */
-    if (!do_import_common
-	(handle, src_path, NULL, NULL, coverage, NULL, worldfile, force_srid,
-	 pyramidize))
-	return RL2_ERROR;
-    return RL2_OK;
-}
+/* checks the file extension */
+    const char *mark = NULL;
+    const char *p = file_name;
+    int len;
+    char *ext;
+    int match = 0;
+    if (file_ext == NULL)
+	return 0;
 
-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)
-{
-/* importing multiple Raster files from dir */
-    if (!do_import_common
-	(handle, NULL, dir_path, file_ext, coverage, NULL, worldfile,
-	 force_srid, pyramidize))
-	return RL2_ERROR;
-    return RL2_OK;
+    len = strlen (file_ext);
+    if (*file_ext == '.')
+      {
+	  /* file extension starts with dot */
+	  ext = malloc (len + 1);
+	  strcpy (ext, file_ext);
+      }
+    else
+      {
+	  /* file extension doesn't start with dot */
+	  ext = malloc (len + 2);
+	  *ext = '.';
+	  strcpy (ext + 1, file_ext);
+      }
+    while (*p != '\0')
+      {
+	  if (*p == '.')
+	      mark = p;
+	  p++;
+      }
+    if (mark == NULL)
+      {
+	  free (ext);
+	  return 0;
+      }
+    match = strcasecmp (mark, ext);
+    free (ext);
+    if (match == 0)
+	return 1;
+    return 0;
 }
 
 static int
-mismatching_size (unsigned int width, unsigned int height, double x_res,
-		  double y_res, double minx, double miny, double maxx,
-		  double maxy)
+do_import_dir (sqlite3 * handle, int max_threads, 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, int verbose)
 {
-/* checking if the image size and the map extent do match */
+/* importing a whole directory */
+#if defined(_WIN32) && !defined(__MINGW32__)
+/* Visual Studio .NET */
+    struct _finddata_t c_file;
+    intptr_t hFile;
+    int cnt = 0;
+    int total = 0;
+    char *search;
+    char *path;
+    int ret;
+    if (_chdir (dir_path) < 0)
+	return 0;
+    search = sqlite3_mprintf ("*%s", file_ext);
+    if ((hFile = _findfirst (search, &c_file)) == -1L)
+	;
+    else
+      {
+	  while (1)
+	    {
+		if ((c_file.attrib & _A_RDONLY) == _A_RDONLY
+		    || (c_file.attrib & _A_NORMAL) == _A_NORMAL)
+		    total++;
+		if (_findnext (hFile, &c_file) != 0)
+		    break;
+	    }
+	  _findclose (hFile);
+	  if ((hFile = _findfirst (search, &c_file)) == -1L)
+	      ;
+	  else
+	    {
+		while (1)
+		  {
+		      if ((c_file.attrib & _A_RDONLY) == _A_RDONLY
+			  || (c_file.attrib & _A_NORMAL) == _A_NORMAL)
+			{
+			    path =
+				sqlite3_mprintf ("%s/%s", dir_path,
+						 c_file.name);
+			    ret =
+				do_import_file (handle, max_threads, path,
+						cvg, section, worldfile,
+						force_srid, pyramidize,
+						sample_type, pixel_type,
+						num_bands, tile_w, tile_h,
+						compression, quality,
+						stmt_data, stmt_tils,
+						stmt_sect, stmt_levl,
+						stmt_upd_sect, verbose,
+						cnt + 1, total);
+			    sqlite3_free (path);
+			    if (!ret)
+				goto error;
+			    cnt++;
+			}
+		      if (_findnext (hFile, &c_file) != 0)
+			  break;
+		  }
+	      error:
+		_findclose (hFile);
+	    }
+	  sqlite3_free (search);
+	  return cnt;
+#else
+/* not Visual Studio .NET */
+    int cnt = 0;
+    int total = 0;
+    char *path;
+    struct dirent *entry;
+    int ret;
+    DIR *dir = opendir (dir_path);
+    if (!dir)
+	return 0;
+    while (1)
+      {
+	  /* counting how many valid entries */
+	  entry = readdir (dir);
+	  if (!entry)
+	      break;
+	  if (!check_extension_match (entry->d_name, file_ext))
+	      continue;
+	  total++;
+      }
+    rewinddir (dir);
+    while (1)
+      {
+	  /* scanning dir-entries */
+	  entry = readdir (dir);
+	  if (!entry)
+	      break;
+	  if (!check_extension_match (entry->d_name, file_ext))
+	      continue;
+	  path = sqlite3_mprintf ("%s/%s", dir_path, entry->d_name);
+	  ret =
+	      do_import_file (handle, max_threads, path, cvg, section,
+			      worldfile, force_srid, pyramidize, sample_type,
+			      pixel_type, num_bands, tile_w, tile_h,
+			      compression, quality, stmt_data, stmt_tils,
+			      stmt_sect, stmt_levl, stmt_upd_sect, verbose,
+			      cnt + 1, total);
+	  sqlite3_free (path);
+	  if (!ret)
+	      goto error;
+	  cnt++;
+      }
+  error:
+    closedir (dir);
+    return cnt;
+#endif
+}
+
+static int
+do_import_common (sqlite3 * handle, int max_threads, const char *src_path,
+		  const char *dir_path, const char *file_ext,
+		  rl2CoveragePtr cvg, const char *section, int worldfile,
+		  int force_srid, int pyramidize, int verbose)
+{
+/* main IMPORT Raster function */
+    rl2PrivCoveragePtr privcvg = (rl2PrivCoveragePtr) cvg;
+    int ret;
+    char *sql;
+    const char *coverage;
+    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;
+    char *table;
+    char *xtable;
+    unsigned int tileWidth;
+    unsigned int tileHeight;
+    sqlite3_stmt *stmt_data = NULL;
+    sqlite3_stmt *stmt_tils = NULL;
+    sqlite3_stmt *stmt_sect = NULL;
+    sqlite3_stmt *stmt_levl = NULL;
+    sqlite3_stmt *stmt_upd_sect = NULL;
+
+    if (cvg == NULL)
+	goto error;
+
+    if (rl2_get_coverage_tile_size (cvg, &tileWidth, &tileHeight) != RL2_OK)
+	goto error;
+
+    tile_w = tileWidth;
+    tile_h = tileHeight;
+    rl2_get_coverage_compression (cvg, &compression, &quality);
+    rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands);
+    coverage = rl2_get_coverage_name (cvg);
+
+    table = sqlite3_mprintf ("%s_sections", coverage);
+    xtable = rl2_double_quoted_sql (table);
+    sqlite3_free (table);
+    sql =
+	sqlite3_mprintf
+	("INSERT INTO \"%s\" (section_id, section_name, file_path, "
+	 "md5_checksum, summary, width, height, geometry) "
+	 "VALUES (NULL, ?, ?, ?, XB_Create(?), ?, ?, ?)", xtable);
+    free (xtable);
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_sect, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("INSERT INTO sections SQL error: %s\n",
+		  sqlite3_errmsg (handle));
+	  goto error;
+      }
+
+    table = sqlite3_mprintf ("%s_sections", coverage);
+    xtable = rl2_double_quoted_sql (table);
+    sqlite3_free (table);
+    sql =
+	sqlite3_mprintf
+	("UPDATE \"%s\" SET statistics = ? WHERE section_id = ?", xtable);
+    free (xtable);
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_upd_sect, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("UPDATE sections SQL error: %s\n", sqlite3_errmsg (handle));
+	  goto error;
+      }
+
+    if (privcvg->mixedResolutions)
+      {
+	  /* mixed resolutions Coverage */
+	  table = sqlite3_mprintf ("%s_section_levels", coverage);
+	  xtable = rl2_double_quoted_sql (table);
+	  sqlite3_free (table);
+	  sql =
+	      sqlite3_mprintf
+	      ("INSERT OR IGNORE INTO \"%s\" (section_id, pyramid_level, "
+	       "x_resolution_1_1, y_resolution_1_1, "
+	       "x_resolution_1_2, y_resolution_1_2, x_resolution_1_4, "
+	       "y_resolution_1_4, x_resolution_1_8, y_resolution_1_8) "
+	       "VALUES (?, 0, ?, ?, ?, ?, ?, ?, ?, ?)", xtable);
+	  free (xtable);
+	  ret =
+	      sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_levl, NULL);
+	  sqlite3_free (sql);
+	  if (ret != SQLITE_OK)
+	    {
+		printf ("INSERT INTO section_levels SQL error: %s\n",
+			sqlite3_errmsg (handle));
+		goto error;
+	    }
+      }
+    else
+      {
+	  /* single resolution Coverage */
+	  table = sqlite3_mprintf ("%s_levels", coverage);
+	  xtable = rl2_double_quoted_sql (table);
+	  sqlite3_free (table);
+	  sql =
+	      sqlite3_mprintf
+	      ("INSERT OR IGNORE INTO \"%s\" (pyramid_level, "
+	       "x_resolution_1_1, y_resolution_1_1, "
+	       "x_resolution_1_2, y_resolution_1_2, x_resolution_1_4, "
+	       "y_resolution_1_4, x_resolution_1_8, y_resolution_1_8) "
+	       "VALUES (0, ?, ?, ?, ?, ?, ?, ?, ?)", xtable);
+	  free (xtable);
+	  ret =
+	      sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_levl, NULL);
+	  sqlite3_free (sql);
+	  if (ret != SQLITE_OK)
+	    {
+		printf ("INSERT INTO levels SQL error: %s\n",
+			sqlite3_errmsg (handle));
+		goto error;
+	    }
+      }
+
+    table = sqlite3_mprintf ("%s_tiles", coverage);
+    xtable = rl2_double_quoted_sql (table);
+    sqlite3_free (table);
+    sql =
+	sqlite3_mprintf
+	("INSERT INTO \"%s\" (tile_id, pyramid_level, section_id, geometry) "
+	 "VALUES (NULL, 0, ?, BuildMBR(?, ?, ?, ?, ?))", xtable);
+    free (xtable);
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_tils, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("INSERT INTO tiles SQL error: %s\n", sqlite3_errmsg (handle));
+	  goto error;
+      }
+
+    table = sqlite3_mprintf ("%s_tile_data", coverage);
+    xtable = rl2_double_quoted_sql (table);
+    sqlite3_free (table);
+    sql =
+	sqlite3_mprintf
+	("INSERT INTO \"%s\" (tile_id, tile_data_odd, tile_data_even) "
+	 "VALUES (?, ?, ?)", xtable);
+    free (xtable);
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_data, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("INSERT INTO tile_data SQL error: %s\n",
+		  sqlite3_errmsg (handle));
+	  goto error;
+      }
+
+    if (dir_path == NULL)
+      {
+	  /* importing a single Image file */
+	  if (!do_import_file
+	      (handle, max_threads, src_path, cvg, section, worldfile,
+	       force_srid, pyramidize, sample_type, pixel_type, num_bands,
+	       tile_w, tile_h, compression, quality, stmt_data, stmt_tils,
+	       stmt_sect, stmt_levl, stmt_upd_sect, verbose, -1, -1))
+	      goto error;
+      }
+    else
+      {
+	  /* importing all Image files from a whole directory */
+	  if (!do_import_dir
+	      (handle, max_threads, dir_path, file_ext, cvg, section,
+	       worldfile, force_srid, pyramidize, sample_type, pixel_type,
+	       num_bands, tile_w, tile_h, compression, quality, stmt_data,
+	       stmt_tils, stmt_sect, stmt_levl, stmt_upd_sect, verbose))
+	      goto error;
+      }
+
+    sqlite3_finalize (stmt_upd_sect);
+    sqlite3_finalize (stmt_sect);
+    sqlite3_finalize (stmt_levl);
+    sqlite3_finalize (stmt_tils);
+    sqlite3_finalize (stmt_data);
+    stmt_upd_sect = NULL;
+    stmt_sect = NULL;
+    stmt_levl = NULL;
+    stmt_tils = NULL;
+    stmt_data = NULL;
+
+    if (rl2_update_dbms_coverage (handle, coverage) != RL2_OK)
+      {
+	  fprintf (stderr, "unable to update the Coverage\n");
+	  goto error;
+      }
+
+    return 1;
+
+  error:
+    if (stmt_upd_sect != NULL)
+	sqlite3_finalize (stmt_upd_sect);
+    if (stmt_sect != NULL)
+	sqlite3_finalize (stmt_sect);
+    if (stmt_levl != NULL)
+	sqlite3_finalize (stmt_levl);
+    if (stmt_tils != NULL)
+	sqlite3_finalize (stmt_tils);
+    if (stmt_data != NULL)
+	sqlite3_finalize (stmt_data);
+    return 0;
+}
+
+RL2_DECLARE int
+rl2_load_raster_into_dbms (sqlite3 * handle, int max_threads,
+			   const char *src_path, rl2CoveragePtr coverage,
+			   int worldfile, int force_srid, int pyramidize,
+			   int verbose)
+{
+/* importing a single Raster file */
+    if (!do_import_common
+	(handle, max_threads, src_path, NULL, NULL, coverage, NULL, worldfile,
+	 force_srid, pyramidize, verbose))
+	return RL2_ERROR;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_load_mrasters_into_dbms (sqlite3 * handle, int max_threads,
+			     const char *dir_path, const char *file_ext,
+			     rl2CoveragePtr coverage, int worldfile,
+			     int force_srid, int pyramidize, int verbose)
+{
+/* importing multiple Raster files from dir */
+    if (!do_import_common
+	(handle, max_threads, NULL, dir_path, file_ext, coverage, NULL,
+	 worldfile, force_srid, pyramidize, verbose))
+	return RL2_ERROR;
+    return RL2_OK;
+}
+
+static int
+mismatching_size (unsigned int width, unsigned int height, double x_res,
+		  double y_res, double minx, double miny, double maxx,
+		  double maxy)
+{
+/* checking if the image size and the map extent do match */
     double ext_x = (double) width * x_res;
     double ext_y = (double) height * y_res;
     double img_x = maxx - minx;
-    double img_y = maxy = miny;
+    double img_y = maxy - miny;
     double confidence;
     confidence = ext_x / 100.0;
     if (img_x < (ext_x - confidence) || img_x > (ext_x + confidence))
-	return 0;
+	return 1;
     confidence = ext_y / 100.0;
     if (img_y < (ext_y - confidence) || img_y > (ext_y + confidence))
-	return 0;
-    return 1;
+	return 1;
+    return 0;
 }
 
 static void
@@ -1484,12 +2973,11 @@ copy_int16_outbuf_to_tile (const short *outbuf, short *tile,
 }
 
 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)
+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)
 {
 /* copying UINT16 pixels from the output buffer into the tile */
     unsigned int x;
@@ -1663,8 +3151,8 @@ copy_from_outbuf_to_tile (const unsigned char *outbuf, unsigned char *tile,
 	  break;
       case RL2_SAMPLE_INT16:
 	  copy_int16_outbuf_to_tile ((short *) outbuf,
-				     (short *) tile, width, height, tile_width,
-				     tile_height, base_y, base_x);
+				     (short *) tile, width, height,
+				     tile_width, tile_height, base_y, base_x);
 	  break;
       case RL2_SAMPLE_UINT16:
 	  copy_uint16_outbuf_to_tile ((unsigned short *) outbuf,
@@ -1684,8 +3172,8 @@ copy_from_outbuf_to_tile (const unsigned char *outbuf, unsigned char *tile,
 	  break;
       case RL2_SAMPLE_FLOAT:
 	  copy_float_outbuf_to_tile ((float *) outbuf,
-				     (float *) tile, width, height, tile_width,
-				     tile_height, base_y, base_x);
+				     (float *) tile, width, height,
+				     tile_width, tile_height, base_y, base_x);
 	  break;
       case RL2_SAMPLE_DOUBLE:
 	  copy_double_outbuf_to_tile ((double *) outbuf,
@@ -1701,15 +3189,16 @@ copy_from_outbuf_to_tile (const unsigned char *outbuf, unsigned char *tile,
       };
 }
 
-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)
+static int
+export_geotiff_common (sqlite3 * handle, int max_threads,
+		       const char *dst_path, rl2CoveragePtr cvg,
+		       int by_section, sqlite3_int64 section_id, 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)
 {
-/* exporting a GeoTIFF from the DBMS into the file-system */
+/* exporting a GeoTIFF common implementation */
     rl2RasterPtr raster = NULL;
     rl2PalettePtr palette = NULL;
     rl2PalettePtr plt2 = NULL;
@@ -1732,7 +3221,8 @@ rl2_export_geotiff_from_dbms (sqlite3 * handle, const char *dst_path,
     unsigned int base_y;
 
     if (rl2_find_matching_resolution
-	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
+	(handle, cvg, by_section, section_id, &xx_res, &yy_res, &level,
+	 &scale) != RL2_OK)
 	return RL2_ERROR;
 
     if (mismatching_size
@@ -1771,10 +3261,24 @@ rl2_export_geotiff_from_dbms (sqlite3 * handle, const char *dst_path,
 	    }
       }
 
-    if (rl2_get_raw_raster_data
-	(handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
-	 yy_res, &outbuf, &outbuf_size, &palette, pixel_type) != RL2_OK)
-	goto error;
+    if (by_section)
+      {
+	  /* just a single Section */
+	  if (rl2_get_section_raw_raster_data
+	      (handle, max_threads, cvg, section_id, width, height, minx,
+	       miny, maxx, maxy, xx_res, yy_res, &outbuf, &outbuf_size,
+	       &palette, pixel_type) != RL2_OK)
+	      goto error;
+      }
+    else
+      {
+	  /* whole Coverage */
+	  if (rl2_get_raw_raster_data
+	      (handle, max_threads, cvg, width, height, minx, miny, maxx,
+	       maxy, xx_res, yy_res, &outbuf, &outbuf_size, &palette,
+	       pixel_type) != RL2_OK)
+	      goto error;
+      }
 
 /* computing the sample size */
     switch (sample_type)
@@ -1818,8 +3322,8 @@ rl2_export_geotiff_from_dbms (sqlite3 * handle, const char *dst_path,
 		    rl2_prime_void_tile_palette (bufpix, tile_sz, tile_sz,
 						 no_data);
 		else
-		    rl2_prime_void_tile (bufpix, tile_sz, tile_sz, sample_type,
-					 num_bands, no_data);
+		    rl2_prime_void_tile (bufpix, tile_sz, tile_sz,
+					 sample_type, num_bands, no_data);
 		copy_from_outbuf_to_tile (outbuf, bufpix, sample_type,
 					  num_bands, width, height, tile_sz,
 					  tile_sz, base_y, base_x);
@@ -1867,16 +3371,48 @@ rl2_export_geotiff_from_dbms (sqlite3 * handle, const char *dst_path,
 }
 
 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)
+rl2_export_geotiff_from_dbms (sqlite3 * handle, int max_threads,
+			      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)
 {
-/* exporting a TIFF+TFW from the DBMS into the file-system */
+/* exporting a GeoTIFF from the DBMS into the file-system */
+    return export_geotiff_common (handle, max_threads, dst_path, cvg, 0, 0,
+				  x_res, y_res, minx, miny, maxx, maxy, width,
+				  height, compression, tile_sz, with_worldfile);
+}
+
+RL2_DECLARE int
+rl2_export_section_geotiff_from_dbms (sqlite3 * handle, int max_threads,
+				      const char *dst_path,
+				      rl2CoveragePtr cvg,
+				      sqlite3_int64 section_id, 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)
+{
+/* exporting a GeoTIFF - Section*/
+    return export_geotiff_common (handle, max_threads, dst_path, cvg, 1,
+				  section_id, x_res, y_res, minx, miny, maxx,
+				  maxy, width, height, compression, tile_sz,
+				  with_worldfile);
+}
+
+static int
+export_tiff_worlfile_common (sqlite3 * handle, int max_threads,
+			     const char *dst_path, rl2CoveragePtr cvg,
+			     int by_section, sqlite3_int64 section_id,
+			     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)
+{
+/* exporting a TIFF+TFW common implementation */
     rl2RasterPtr raster = NULL;
     rl2PalettePtr palette = NULL;
     rl2PalettePtr plt2 = NULL;
@@ -1899,7 +3435,8 @@ rl2_export_tiff_worldfile_from_dbms (sqlite3 * handle, const char *dst_path,
     unsigned int base_y;
 
     if (rl2_find_matching_resolution
-	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
+	(handle, cvg, by_section, section_id, &xx_res, &yy_res, &level,
+	 &scale) != RL2_OK)
 	return RL2_ERROR;
 
     if (mismatching_size
@@ -1938,10 +3475,24 @@ rl2_export_tiff_worldfile_from_dbms (sqlite3 * handle, const char *dst_path,
 	    }
       }
 
-    if (rl2_get_raw_raster_data
-	(handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
-	 yy_res, &outbuf, &outbuf_size, &palette, pixel_type) != RL2_OK)
-	goto error;
+    if (by_section)
+      {
+	  /* just a single select Section */
+	  if (rl2_get_section_raw_raster_data
+	      (handle, max_threads, cvg, section_id, width, height, minx,
+	       miny, maxx, maxy, xx_res, yy_res, &outbuf, &outbuf_size,
+	       &palette, pixel_type) != RL2_OK)
+	      goto error;
+      }
+    else
+      {
+	  /* whole Coverage */
+	  if (rl2_get_raw_raster_data
+	      (handle, max_threads, cvg, width, height, minx, miny, maxx,
+	       maxy, xx_res, yy_res, &outbuf, &outbuf_size, &palette,
+	       pixel_type) != RL2_OK)
+	      goto error;
+      }
 
 /* computing the sample size */
     switch (sample_type)
@@ -1963,9 +3514,10 @@ rl2_export_tiff_worldfile_from_dbms (sqlite3 * handle, const char *dst_path,
     tiff =
 	rl2_create_tiff_worldfile_destination (dst_path, width, height,
 					       sample_type, pixel_type,
-					       num_bands, palette, compression,
-					       1, tile_sz, srid, minx, miny,
-					       maxx, maxy, xx_res, yy_res);
+					       num_bands, palette,
+					       compression, 1, tile_sz, srid,
+					       minx, miny, maxx, maxy, xx_res,
+					       yy_res);
     if (tiff == NULL)
 	goto error;
     for (base_y = 0; base_y < height; base_y += tile_sz)
@@ -1985,8 +3537,8 @@ rl2_export_tiff_worldfile_from_dbms (sqlite3 * handle, const char *dst_path,
 		    rl2_prime_void_tile_palette (bufpix, tile_sz, tile_sz,
 						 no_data);
 		else
-		    rl2_prime_void_tile (bufpix, tile_sz, tile_sz, sample_type,
-					 num_bands, no_data);
+		    rl2_prime_void_tile (bufpix, tile_sz, tile_sz,
+					 sample_type, num_bands, no_data);
 		copy_from_outbuf_to_tile (outbuf, bufpix, sample_type,
 					  num_bands, width, height, tile_sz,
 					  tile_sz, base_y, base_x);
@@ -2031,14 +3583,51 @@ rl2_export_tiff_worldfile_from_dbms (sqlite3 * handle, const char *dst_path,
 }
 
 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)
+rl2_export_tiff_worldfile_from_dbms (sqlite3 * handle, int max_threads,
+				     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)
 {
-/* exporting a plain TIFF from the DBMS into the file-system */
+/* exporting a TIFF+TFW from the DBMS into the file-system */
+    return export_tiff_worlfile_common (handle, max_threads, dst_path, cvg, 0,
+					0, x_res, y_res, minx, miny, maxx,
+					maxy, width, height, compression,
+					tile_sz);
+}
+
+RL2_DECLARE int
+rl2_export_section_tiff_worldfile_from_dbms (sqlite3 * handle,
+					     int max_threads,
+					     const char *dst_path,
+					     rl2CoveragePtr cvg,
+					     sqlite3_int64 section_id,
+					     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)
+{
+/* exporting a TIFF+TFW - single Section */
+    return export_tiff_worlfile_common (handle, max_threads, dst_path, cvg, 1,
+					section_id, x_res, y_res, minx, miny,
+					maxx, maxy, width, height,
+					compression, tile_sz);
+}
+
+static int
+export_tiff_common (sqlite3 * handle, int max_threads, const char *dst_path,
+		    rl2CoveragePtr cvg, int by_section,
+		    sqlite3_int64 section_id, 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)
+{
+/* exporting a plain TIFF common implementation */
     rl2RasterPtr raster = NULL;
     rl2PalettePtr palette = NULL;
     rl2PalettePtr plt2 = NULL;
@@ -2061,7 +3650,8 @@ rl2_export_tiff_from_dbms (sqlite3 * handle, const char *dst_path,
     unsigned int base_y;
 
     if (rl2_find_matching_resolution
-	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
+	(handle, cvg, by_section, section_id, &xx_res, &yy_res, &level,
+	 &scale) != RL2_OK)
 	return RL2_ERROR;
 
     if (mismatching_size
@@ -2102,10 +3692,24 @@ rl2_export_tiff_from_dbms (sqlite3 * handle, const char *dst_path,
 	    }
       }
 
-    if (rl2_get_raw_raster_data
-	(handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
-	 yy_res, &outbuf, &outbuf_size, &palette, pixel_type) != RL2_OK)
-	goto error;
+    if (by_section)
+      {
+	  /* just a single Section */
+	  if (rl2_get_section_raw_raster_data
+	      (handle, max_threads, cvg, section_id, width, height, minx,
+	       miny, maxx, maxy, xx_res, yy_res, &outbuf, &outbuf_size,
+	       &palette, pixel_type) != RL2_OK)
+	      goto error;
+      }
+    else
+      {
+	  /* whole Coverage */
+	  if (rl2_get_raw_raster_data
+	      (handle, max_threads, cvg, width, height, minx, miny, maxx,
+	       maxy, xx_res, yy_res, &outbuf, &outbuf_size, &palette,
+	       pixel_type) != RL2_OK)
+	      goto error;
+      }
 
 /* computing the sample size */
     switch (sample_type)
@@ -2147,8 +3751,8 @@ rl2_export_tiff_from_dbms (sqlite3 * handle, const char *dst_path,
 		    rl2_prime_void_tile_palette (bufpix, tile_sz, tile_sz,
 						 no_data);
 		else
-		    rl2_prime_void_tile (bufpix, tile_sz, tile_sz, sample_type,
-					 num_bands, no_data);
+		    rl2_prime_void_tile (bufpix, tile_sz, tile_sz,
+					 sample_type, num_bands, no_data);
 		copy_from_outbuf_to_tile (outbuf, bufpix, sample_type,
 					  num_bands, width, height, tile_sz,
 					  tile_sz, base_y, base_x);
@@ -2189,21 +3793,50 @@ rl2_export_tiff_from_dbms (sqlite3 * handle, const char *dst_path,
 }
 
 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)
+rl2_export_tiff_from_dbms (sqlite3 * handle, int max_threads,
+			   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)
 {
-/* exporting a Band-Composed GeoTIFF from the DBMS into the file-system */
+/* exporting a plain TIFF from the DBMS into the file-system */
+    return export_tiff_common (handle, max_threads, dst_path, cvg, 0, 0,
+			       x_res, y_res, minx, miny, maxx, maxy, width,
+			       height, compression, tile_sz);
+}
+
+RL2_DECLARE int
+rl2_export_section_tiff_from_dbms (sqlite3 * handle, int max_threads,
+				   const char *dst_path, rl2CoveragePtr cvg,
+				   sqlite3_int64 section_id, 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)
+{
+/* exporting a plain TIFF - single Section*/
+    return export_tiff_common (handle, max_threads, dst_path, cvg, 1,
+			       section_id, x_res, y_res, minx, miny, maxx,
+			       maxy, width, height, compression, tile_sz);
+}
+
+static int
+export_triple_band_geotiff_common (int by_section, sqlite3 * handle,
+				   const char *dst_path,
+				   rl2CoveragePtr cvg,
+				   sqlite3_int64 section_id, 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)
+{
+/* exporting a Band-Composed GeoTIFF - common implementation */
     rl2RasterPtr raster = NULL;
     rl2TiffDestinationPtr tiff = NULL;
     rl2PixelPtr no_data_multi = NULL;
@@ -2224,7 +3857,8 @@ rl2_export_triple_band_geotiff_from_dbms (sqlite3 * handle,
     unsigned int base_y;
 
     if (rl2_find_matching_resolution
-	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
+	(handle, cvg, by_section, section_id, &xx_res, &yy_res, &level,
+	 &scale) != RL2_OK)
 	return RL2_ERROR;
 
     if (mismatching_size
@@ -2251,18 +3885,31 @@ rl2_export_triple_band_geotiff_from_dbms (sqlite3 * handle,
 	rl2_create_triple_band_pixel (no_data_multi, red_band, green_band,
 				      blue_band);
 
-    if (rl2_get_triple_band_raw_raster_data
-	(handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
-	 yy_res, red_band, green_band, blue_band, &outbuf, &outbuf_size,
-	 no_data) != RL2_OK)
-	goto error;
+    if (by_section)
+      {
+	  /* single Section */
+	  if (rl2_get_section_triple_band_raw_raster_data
+	      (handle, cvg, section_id, width, height, minx, miny, maxx, maxy,
+	       xx_res, yy_res, red_band, green_band, blue_band, &outbuf,
+	       &outbuf_size, no_data) != RL2_OK)
+	      goto error;
+      }
+    else
+      {
+	  /* whole Coverage */
+	  if (rl2_get_triple_band_raw_raster_data
+	      (handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
+	       yy_res, red_band, green_band, blue_band, &outbuf, &outbuf_size,
+	       no_data) != RL2_OK)
+	      goto error;
+      }
 
     tiff =
 	rl2_create_geotiff_destination (dst_path, handle, width, height,
 					sample_type, RL2_PIXEL_RGB, 3,
 					NULL, compression, 1, tile_sz, srid,
-					minx, miny, maxx, maxy, xx_res, yy_res,
-					with_worldfile);
+					minx, miny, maxx, maxy, xx_res,
+					yy_res, with_worldfile);
     if (tiff == NULL)
 	goto error;
     for (base_y = 0; base_y < height; base_y += tile_sz)
@@ -2328,19 +3975,67 @@ rl2_export_triple_band_geotiff_from_dbms (sqlite3 * handle,
 }
 
 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)
+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)
 {
-/* exporting a Mono-Band GeoTIFF from the DBMS into the file-system */
+/* exporting a Band-Composed GeoTIFF from the DBMS into the file-system */
+    return export_triple_band_geotiff_common (0, handle, dst_path, cvg, 0,
+					      x_res, y_res, minx, miny, maxx,
+					      maxy, width, height, red_band,
+					      green_band, blue_band,
+					      compression, tile_sz,
+					      with_worldfile);
+}
+
+RL2_DECLARE int
+rl2_export_section_triple_band_geotiff_from_dbms (sqlite3 * handle,
+						  const char *dst_path,
+						  rl2CoveragePtr cvg,
+						  sqlite3_int64 section_id,
+						  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)
+{
+/* exporting a Band-Composed GeoTIFF - Section */
+    return export_triple_band_geotiff_common (1, handle, dst_path, cvg,
+					      section_id, x_res, y_res, minx,
+					      miny, maxx, maxy, width, height,
+					      red_band, green_band, blue_band,
+					      compression, tile_sz,
+					      with_worldfile);
+}
+
+static int
+export_mono_band_geotiff_common (int by_section, sqlite3 * handle,
+				 const char *dst_path,
+				 rl2CoveragePtr cvg, sqlite3_int64 section_id,
+				 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)
+{
+/* exporting a Mono-Band GeoTIFF common implementation */
     rl2RasterPtr raster = NULL;
     rl2TiffDestinationPtr tiff = NULL;
     rl2PixelPtr no_data_mono = NULL;
@@ -2362,7 +4057,8 @@ rl2_export_mono_band_geotiff_from_dbms (sqlite3 * handle,
     unsigned char out_pixel;
 
     if (rl2_find_matching_resolution
-	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
+	(handle, cvg, by_section, section_id, &xx_res, &yy_res, &level,
+	 &scale) != RL2_OK)
 	return RL2_ERROR;
 
     if (mismatching_size
@@ -2383,10 +4079,23 @@ rl2_export_mono_band_geotiff_from_dbms (sqlite3 * handle,
     no_data_mono = rl2_get_coverage_no_data (cvg);
     no_data = rl2_create_mono_band_pixel (no_data_mono, mono_band);
 
-    if (rl2_get_mono_band_raw_raster_data
-	(handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
-	 yy_res, mono_band, &outbuf, &outbuf_size, no_data) != RL2_OK)
-	goto error;
+    if (by_section)
+      {
+	  /* single Section */
+	  if (rl2_get_section_mono_band_raw_raster_data
+	      (handle, cvg, section_id, width, height, minx, miny, maxx, maxy,
+	       xx_res, yy_res, mono_band, &outbuf, &outbuf_size,
+	       no_data) != RL2_OK)
+	      goto error;
+      }
+    else
+      {
+	  /* whole Coverage */
+	  if (rl2_get_mono_band_raw_raster_data
+	      (handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
+	       yy_res, mono_band, &outbuf, &outbuf_size, no_data) != RL2_OK)
+	      goto error;
+      }
 
     if (sample_type == RL2_SAMPLE_UINT16)
 	out_pixel = RL2_PIXEL_DATAGRID;
@@ -2397,8 +4106,8 @@ rl2_export_mono_band_geotiff_from_dbms (sqlite3 * handle,
 	rl2_create_geotiff_destination (dst_path, handle, width, height,
 					sample_type, out_pixel, 1,
 					NULL, compression, 1, tile_sz, srid,
-					minx, miny, maxx, maxy, xx_res, yy_res,
-					with_worldfile);
+					minx, miny, maxx, maxy, xx_res,
+					yy_res, with_worldfile);
     if (tiff == NULL)
 	goto error;
     for (base_y = 0; base_y < height; base_y += tile_sz)
@@ -2464,21 +4173,66 @@ rl2_export_mono_band_geotiff_from_dbms (sqlite3 * handle,
 }
 
 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)
+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)
 {
-/* exporting a Band-Composed TIFF+TFW from the DBMS into the file-system */
+/* exporting a Mono-Band GeoTIFF from the DBMS into the file-system */
+    return export_mono_band_geotiff_common (0, handle, dst_path, cvg, 0,
+					    x_res, y_res, minx, miny, maxx,
+					    maxy, width, height, mono_band,
+					    compression, tile_sz,
+					    with_worldfile);
+}
+
+RL2_DECLARE int
+rl2_export_section_mono_band_geotiff_from_dbms (sqlite3 * handle,
+						const char *dst_path,
+						rl2CoveragePtr cvg,
+						sqlite3_int64 section_id,
+						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)
+{
+/* exporting a Mono-Band GeoTIFF - Section */
+    return export_mono_band_geotiff_common (1, handle, dst_path, cvg,
+					    section_id, x_res, y_res, minx,
+					    miny, maxx, maxy, width, height,
+					    mono_band, compression, tile_sz,
+					    with_worldfile);
+}
+
+static int
+export_triple_band_tiff_worldfile_common (int by_section, sqlite3 * handle,
+					  const char *dst_path,
+					  rl2CoveragePtr cvg,
+					  sqlite3_int64 section_id,
+					  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)
+{
+/* exporting a Band-Composed TIFF+TFW common implementation */
     rl2RasterPtr raster = NULL;
     rl2PixelPtr no_data_multi = NULL;
     rl2PixelPtr no_data = NULL;
@@ -2499,7 +4253,8 @@ rl2_export_triple_band_tiff_worldfile_from_dbms (sqlite3 * handle,
     unsigned int base_y;
 
     if (rl2_find_matching_resolution
-	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
+	(handle, cvg, by_section, section_id, &xx_res, &yy_res, &level,
+	 &scale) != RL2_OK)
 	return RL2_ERROR;
 
     if (mismatching_size
@@ -2526,18 +4281,31 @@ rl2_export_triple_band_tiff_worldfile_from_dbms (sqlite3 * handle,
 	rl2_create_triple_band_pixel (no_data_multi, red_band, green_band,
 				      blue_band);
 
-    if (rl2_get_triple_band_raw_raster_data
-	(handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
-	 yy_res, red_band, green_band, blue_band, &outbuf, &outbuf_size,
-	 no_data) != RL2_OK)
-	goto error;
+    if (by_section)
+      {
+	  /* single Section */
+	  if (rl2_get_section_triple_band_raw_raster_data
+	      (handle, cvg, section_id, width, height, minx, miny, maxx, maxy,
+	       xx_res, yy_res, red_band, green_band, blue_band, &outbuf,
+	       &outbuf_size, no_data) != RL2_OK)
+	      goto error;
+      }
+    else
+      {
+	  /* whole Coverage */
+	  if (rl2_get_triple_band_raw_raster_data
+	      (handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
+	       yy_res, red_band, green_band, blue_band, &outbuf, &outbuf_size,
+	       no_data) != RL2_OK)
+	      goto error;
+      }
 
     tiff =
 	rl2_create_tiff_worldfile_destination (dst_path, width, height,
 					       sample_type, RL2_PIXEL_RGB,
-					       3, NULL, compression, 1, tile_sz,
-					       srid, minx, miny, maxx, maxy,
-					       xx_res, yy_res);
+					       3, NULL, compression, 1,
+					       tile_sz, srid, minx, miny,
+					       maxx, maxy, xx_res, yy_res);
     if (tiff == NULL)
 	goto error;
     for (base_y = 0; base_y < height; base_y += tile_sz)
@@ -2600,19 +4368,76 @@ rl2_export_triple_band_tiff_worldfile_from_dbms (sqlite3 * handle,
 }
 
 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)
+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)
 {
-/* exporting a Mono-Band TIFF+TFW from the DBMS into the file-system */
+/* exporting a Band-Composed TIFF+TFW from the DBMS into the file-system */
+    return export_triple_band_tiff_worldfile_common (0, handle, dst_path, cvg,
+						     0, x_res, y_res, minx,
+						     miny, maxx, maxy, width,
+						     height, red_band,
+						     green_band, blue_band,
+						     compression, tile_sz);
+}
+
+RL2_DECLARE int
+rl2_export_section_triple_band_tiff_worldfile_from_dbms (sqlite3 * handle,
+							 const char *dst_path,
+							 rl2CoveragePtr cvg,
+							 sqlite3_int64
+							 section_id,
+							 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)
+{
+/* exporting a Band-Composed TIFF+TFW - Sction */
+    return export_triple_band_tiff_worldfile_common (1, handle, dst_path, cvg,
+						     section_id, x_res, y_res,
+						     minx, miny, maxx, maxy,
+						     width, height, red_band,
+						     green_band, blue_band,
+						     compression, tile_sz);
+}
+
+static int
+export_mono_band_tiff_worldfile_common (int by_section, sqlite3 * handle,
+					const char *dst_path,
+					rl2CoveragePtr cvg,
+					sqlite3_int64 section_id,
+					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)
+{
+/* exporting a Mono-Band TIFF+TFW - common implementation */
     rl2RasterPtr raster = NULL;
     rl2PixelPtr no_data_multi = NULL;
     rl2PixelPtr no_data = NULL;
@@ -2634,7 +4459,8 @@ rl2_export_mono_band_tiff_worldfile_from_dbms (sqlite3 * handle,
     unsigned char out_pixel;
 
     if (rl2_find_matching_resolution
-	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
+	(handle, cvg, by_section, section_id, &xx_res, &yy_res, &level,
+	 &scale) != RL2_OK)
 	return RL2_ERROR;
 
     if (mismatching_size
@@ -2655,10 +4481,23 @@ rl2_export_mono_band_tiff_worldfile_from_dbms (sqlite3 * handle,
     no_data_multi = rl2_get_coverage_no_data (cvg);
     no_data = rl2_create_mono_band_pixel (no_data_multi, mono_band);
 
-    if (rl2_get_mono_band_raw_raster_data
-	(handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
-	 yy_res, mono_band, &outbuf, &outbuf_size, no_data) != RL2_OK)
-	goto error;
+    if (by_section)
+      {
+	  /* single Section */
+	  if (rl2_get_section_mono_band_raw_raster_data
+	      (handle, cvg, section_id, width, height, minx, miny, maxx, maxy,
+	       xx_res, yy_res, mono_band, &outbuf, &outbuf_size,
+	       no_data) != RL2_OK)
+	      goto error;
+      }
+    else
+      {
+	  /* whole Coverage */
+	  if (rl2_get_mono_band_raw_raster_data
+	      (handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
+	       yy_res, mono_band, &outbuf, &outbuf_size, no_data) != RL2_OK)
+	      goto error;
+      }
 
     if (sample_type == RL2_SAMPLE_UINT16)
 	out_pixel = RL2_PIXEL_DATAGRID;
@@ -2668,9 +4507,9 @@ rl2_export_mono_band_tiff_worldfile_from_dbms (sqlite3 * handle,
     tiff =
 	rl2_create_tiff_worldfile_destination (dst_path, width, height,
 					       sample_type, out_pixel,
-					       1, NULL, compression, 1, tile_sz,
-					       srid, minx, miny, maxx, maxy,
-					       xx_res, yy_res);
+					       1, NULL, compression, 1,
+					       tile_sz, srid, minx, miny,
+					       maxx, maxy, xx_res, yy_res);
     if (tiff == NULL)
 	goto error;
     for (base_y = 0; base_y < height; base_y += tile_sz)
@@ -2733,25 +4572,72 @@ rl2_export_mono_band_tiff_worldfile_from_dbms (sqlite3 * handle,
 }
 
 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)
+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)
 {
-/* exporting a plain Band-Composed TIFF from the DBMS into the file-system */
-    rl2RasterPtr raster = NULL;
-    rl2PixelPtr no_data_multi = NULL;
-    rl2PixelPtr no_data = NULL;
-    rl2TiffDestinationPtr tiff = NULL;
-    unsigned char level;
-    unsigned char scale;
+/* exporting a Mono-Band TIFF+TFW from the DBMS into the file-system */
+    return export_mono_band_tiff_worldfile_common (0, handle, dst_path, cvg,
+						   0, x_res, y_res, minx,
+						   miny, maxx, maxy, width,
+						   height, mono_band,
+						   compression, tile_sz);
+}
+
+RL2_DECLARE int
+rl2_export_section_mono_band_tiff_worldfile_from_dbms (sqlite3 * handle,
+						       const char *dst_path,
+						       rl2CoveragePtr cvg,
+						       sqlite3_int64
+						       section_id,
+						       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)
+{
+/* exporting a Mono-Band TIFF+TFW - Section */
+    return export_mono_band_tiff_worldfile_common (1, handle, dst_path, cvg,
+						   section_id, x_res, y_res,
+						   minx, miny, maxx, maxy,
+						   width, height, mono_band,
+						   compression, tile_sz);
+}
+
+static int
+export_triple_band_tiff_common (int by_section, sqlite3 * handle,
+				const char *dst_path, rl2CoveragePtr cvg,
+				sqlite3_int64 section_id, 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)
+{
+/* exporting a plain Band-Composed TIFF common implementation */
+    rl2RasterPtr raster = NULL;
+    rl2PixelPtr no_data_multi = NULL;
+    rl2PixelPtr no_data = NULL;
+    rl2TiffDestinationPtr tiff = NULL;
+    unsigned char level;
+    unsigned char scale;
     double xx_res = x_res;
     double yy_res = y_res;
     unsigned char sample_type;
@@ -2766,7 +4652,8 @@ rl2_export_triple_band_tiff_from_dbms (sqlite3 * handle, const char *dst_path,
     unsigned int base_y;
 
     if (rl2_find_matching_resolution
-	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
+	(handle, cvg, by_section, section_id, &xx_res, &yy_res, &level,
+	 &scale) != RL2_OK)
 	return RL2_ERROR;
 
     if (mismatching_size
@@ -2793,11 +4680,24 @@ rl2_export_triple_band_tiff_from_dbms (sqlite3 * handle, const char *dst_path,
 	rl2_create_triple_band_pixel (no_data_multi, red_band, green_band,
 				      blue_band);
 
-    if (rl2_get_triple_band_raw_raster_data
-	(handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
-	 yy_res, red_band, green_band, blue_band, &outbuf, &outbuf_size,
-	 no_data) != RL2_OK)
-	goto error;
+    if (by_section)
+      {
+	  /* single Section */
+	  if (rl2_get_section_triple_band_raw_raster_data
+	      (handle, cvg, section_id, width, height, minx, miny, maxx, maxy,
+	       xx_res, yy_res, red_band, green_band, blue_band, &outbuf,
+	       &outbuf_size, no_data) != RL2_OK)
+	      goto error;
+      }
+    else
+      {
+	  /* whole Coverage */
+	  if (rl2_get_triple_band_raw_raster_data
+	      (handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
+	       yy_res, red_band, green_band, blue_band, &outbuf, &outbuf_size,
+	       no_data) != RL2_OK)
+	      goto error;
+      }
 
     tiff =
 	rl2_create_tiff_destination (dst_path, width, height, sample_type,
@@ -2861,17 +4761,60 @@ rl2_export_triple_band_tiff_from_dbms (sqlite3 * handle, const char *dst_path,
 }
 
 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)
+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)
 {
-/* exporting a plain Mono-Band TIFF from the DBMS into the file-system */
+/* exporting a plain Band-Composed TIFF from the DBMS into the file-system */
+    return export_triple_band_tiff_common (0, handle, dst_path, cvg, 0, x_res,
+					   y_res, minx, miny, maxx, maxy,
+					   width, height, red_band,
+					   green_band, blue_band, compression,
+					   tile_sz);
+}
+
+RL2_DECLARE int
+rl2_export_section_triple_band_tiff_from_dbms (sqlite3 * handle,
+					       const char *dst_path,
+					       rl2CoveragePtr cvg,
+					       sqlite3_int64 section_id,
+					       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)
+{
+/* exporting a plain Band-Composed TIFF - Section */
+    return export_triple_band_tiff_common (1, handle, dst_path, cvg,
+					   section_id, x_res, y_res, minx,
+					   miny, maxx, maxy, width, height,
+					   red_band, green_band, blue_band,
+					   compression, tile_sz);
+}
+
+static int
+export_mono_band_tiff_common (int by_section, sqlite3 * handle,
+			      const char *dst_path, rl2CoveragePtr cvg,
+			      sqlite3_int64 section_id, 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)
+{
+/* exporting a plain Mono-Band TIFF - common implementation */
     rl2RasterPtr raster = NULL;
     rl2PixelPtr no_data_multi = NULL;
     rl2PixelPtr no_data = NULL;
@@ -2893,7 +4836,8 @@ rl2_export_mono_band_tiff_from_dbms (sqlite3 * handle, const char *dst_path,
     unsigned char out_pixel;
 
     if (rl2_find_matching_resolution
-	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
+	(handle, cvg, by_section, section_id, &xx_res, &yy_res, &level,
+	 &scale) != RL2_OK)
 	return RL2_ERROR;
 
     if (mismatching_size
@@ -2914,10 +4858,23 @@ rl2_export_mono_band_tiff_from_dbms (sqlite3 * handle, const char *dst_path,
     no_data_multi = rl2_get_coverage_no_data (cvg);
     no_data = rl2_create_mono_band_pixel (no_data_multi, mono_band);
 
-    if (rl2_get_mono_band_raw_raster_data
-	(handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
-	 yy_res, mono_band, &outbuf, &outbuf_size, no_data) != RL2_OK)
-	goto error;
+    if (by_section)
+      {
+	  /* single Section */
+	  if (rl2_get_section_mono_band_raw_raster_data
+	      (handle, cvg, section_id, width, height, minx, miny, maxx, maxy,
+	       xx_res, yy_res, mono_band, &outbuf, &outbuf_size,
+	       no_data) != RL2_OK)
+	      goto error;
+      }
+    else
+      {
+	  /* whole Coverage */
+	  if (rl2_get_mono_band_raw_raster_data
+	      (handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
+	       yy_res, mono_band, &outbuf, &outbuf_size, no_data) != RL2_OK)
+	      goto error;
+      }
 
     if (sample_type == RL2_SAMPLE_UINT16)
 	out_pixel = RL2_PIXEL_DATAGRID;
@@ -2986,14 +4943,53 @@ rl2_export_mono_band_tiff_from_dbms (sqlite3 * handle, const char *dst_path,
 }
 
 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)
+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)
 {
-/* exporting an ASCII Grid from the DBMS into the file-system */
+/* exporting a plain Mono-Band TIFF from the DBMS into the file-system */
+    return export_mono_band_tiff_common (0, handle, dst_path, cvg, 0, x_res,
+					 y_res, minx, miny, maxx, maxy, width,
+					 height, mono_band, compression,
+					 tile_sz);
+}
+
+RL2_DECLARE int
+rl2_export_section_mono_band_tiff_from_dbms (sqlite3 * handle,
+					     const char *dst_path,
+					     rl2CoveragePtr cvg,
+					     sqlite3_int64 section_id,
+					     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)
+{
+/* exporting a plain Mono-Band TIFF from the DBMS - Section */
+    return export_mono_band_tiff_common (1, handle, dst_path, cvg, section_id,
+					 x_res, y_res, minx, miny, maxx, maxy,
+					 width, height, mono_band,
+					 compression, tile_sz);
+}
+
+static int
+export_ascii_grid_common (int by_section, sqlite3 * handle, int max_threads,
+			  const char *dst_path, rl2CoveragePtr cvg,
+			  sqlite3_int64 section_id, double res, double minx,
+			  double miny, double maxx, double maxy,
+			  unsigned int width, unsigned int height,
+			  int is_centered, int decimal_digits)
+{
+/* exporting an ASCII Grid common implementation */
     rl2PalettePtr palette = NULL;
     rl2AsciiGridDestinationPtr ascii = NULL;
     rl2PixelPtr pixel;
@@ -3010,7 +5006,8 @@ rl2_export_ascii_grid_from_dbms (sqlite3 * handle, const char *dst_path,
     int pixels_size;
 
     if (rl2_find_matching_resolution
-	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
+	(handle, cvg, by_section, section_id, &xx_res, &yy_res, &level,
+	 &scale) != RL2_OK)
 	return RL2_ERROR;
 
     if (mismatching_size
@@ -3085,10 +5082,24 @@ rl2_export_ascii_grid_from_dbms (sqlite3 * handle, const char *dst_path,
 	    }
       }
 
-    if (rl2_get_raw_raster_data
-	(handle, cvg, width, height, minx, miny, maxx, maxy, res, res, &pixels,
-	 &pixels_size, &palette, RL2_PIXEL_DATAGRID) != RL2_OK)
-	goto error;
+    if (by_section)
+      {
+	  /* single Section */
+	  if (rl2_get_section_raw_raster_data
+	      (handle, max_threads, cvg, section_id, width, height, minx,
+	       miny, maxx, maxy, res, res, &pixels, &pixels_size, &palette,
+	       RL2_PIXEL_DATAGRID) != RL2_OK)
+	      goto error;
+      }
+    else
+      {
+	  /* whole Coverage */
+	  if (rl2_get_raw_raster_data
+	      (handle, max_threads, cvg, width, height, minx, miny, maxx,
+	       maxy, res, res, &pixels, &pixels_size, &palette,
+	       RL2_PIXEL_DATAGRID) != RL2_OK)
+	      goto error;
+      }
 
     ascii =
 	rl2_create_ascii_grid_destination (dst_path, width, height,
@@ -3125,14 +5136,291 @@ rl2_export_ascii_grid_from_dbms (sqlite3 * handle, const char *dst_path,
 }
 
 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)
+rl2_export_ascii_grid_from_dbms (sqlite3 * handle, int max_threads,
+				 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)
 {
-/* exporting a JPEG (with possible JGW) from the DBMS into the file-system */
+/* exporting an ASCII Grid from the DBMS into the file-system */
+    return export_ascii_grid_common (0, handle, max_threads, dst_path, cvg, 0,
+				     res, minx, miny, maxx, maxy, width,
+				     height, is_centered, decimal_digits);
+}
+
+RL2_DECLARE int
+rl2_export_section_ascii_grid_from_dbms (sqlite3 * handle, int max_threads,
+					 const char *dst_path,
+					 rl2CoveragePtr cvg,
+					 sqlite3_int64 section_id, double res,
+					 double minx, double miny,
+					 double maxx, double maxy,
+					 unsigned int width,
+					 unsigned int height, int is_centered,
+					 int decimal_digits)
+{
+/* exporting an ASCII Grid - Section */
+    return export_ascii_grid_common (1, handle, max_threads, dst_path, cvg,
+				     section_id, res, minx, miny, maxx, maxy,
+				     width, height, is_centered,
+				     decimal_digits);
+}
+
+static int
+is_ndvi_nodata_u8 (rl2PrivPixelPtr no_data, const unsigned char *p_in)
+{
+/* testing for NO-DATA */
+    if (no_data != NULL)
+      {
+	  unsigned char band;
+	  int match = 0;
+	  rl2PrivSamplePtr sample;
+	  for (band = 0; band < no_data->nBands; band++)
+	    {
+		sample = no_data->Samples + band;
+		if (*(p_in + band) == sample->uint8)
+		    match++;
+	    }
+	  if (match == no_data->nBands)
+	      return 1;
+      }
+    return 0;
+}
+
+static int
+is_ndvi_nodata_u16 (rl2PrivPixelPtr no_data, const unsigned short *p_in)
+{
+/* testing for NO-DATA */
+    if (no_data != NULL)
+      {
+	  unsigned char band;
+	  int match = 0;
+	  rl2PrivSamplePtr sample;
+	  for (band = 0; band < no_data->nBands; band++)
+	    {
+		sample = no_data->Samples + band;
+		if (*(p_in + band) == sample->uint16)
+		    match++;
+	    }
+	  if (match == no_data->nBands)
+	      return 1;
+      }
+    return 0;
+}
+
+static float
+compute_ndvi (void *pixels, unsigned char sample_type,
+	      unsigned char num_bands, unsigned short width,
+	      unsigned char red_band, unsigned char nir_band,
+	      unsigned short row, unsigned short col,
+	      rl2PrivPixelPtr in_no_data, float out_no_data)
+{
+/* computing a Normalized Difference Vegetaion Index -NDVI */
+    float red;
+    float nir;
+    unsigned char *p8;
+    unsigned short *p16;
+    if (sample_type == RL2_SAMPLE_UINT16)
+      {
+	  /* UINT16 samples */
+	  p16 = (unsigned short *) pixels;
+	  p16 += (row * width * num_bands) + (col * num_bands);
+	  if (is_ndvi_nodata_u16 (in_no_data, p16))
+	      return out_no_data;
+	  red = *(p16 + red_band);
+	  nir = *(p16 + nir_band);
+      }
+    else
+      {
+	  /* assuming UINT8 samples */
+	  p8 = (unsigned char *) pixels;
+	  p8 += (row * width * num_bands) + (col * num_bands);
+	  if (is_ndvi_nodata_u8 (in_no_data, p8))
+	      return out_no_data;
+	  red = *(p8 + red_band);
+	  nir = *(p8 + nir_band);
+      }
+    return (nir - red) / (nir + red);
+}
+
+static int
+export_ndvi_ascii_grid_common (int by_section, sqlite3 * handle,
+			       int max_threads, const char *dst_path,
+			       rl2CoveragePtr cvg, sqlite3_int64 section_id,
+			       double res, double minx, double miny,
+			       double maxx, double maxy, unsigned int width,
+			       unsigned int height, int red_band,
+			       int nir_band, int is_centered,
+			       int decimal_digits)
+{
+/* exporting an NDVI ASCII Grid common implementation */
+    rl2PalettePtr palette = NULL;
+    rl2PixelPtr in_no_data;
+    rl2AsciiGridDestinationPtr ascii = NULL;
+    unsigned char level;
+    unsigned char scale;
+    double xx_res = res;
+    double yy_res = res;
+    unsigned char sample_type;
+    unsigned char pixel_type;
+    unsigned char num_bands;
+    float out_no_data = -2.0;
+    unsigned short row;
+    unsigned short col;
+    unsigned int base_y;
+    unsigned char *pixels = NULL;
+    int pixels_size;
+    unsigned char *out_pixels = NULL;
+    int out_pixels_size;
+    float *po;
+
+    if (rl2_find_matching_resolution
+	(handle, cvg, by_section, section_id, &xx_res, &yy_res, &level,
+	 &scale) != RL2_OK)
+	return RL2_ERROR;
+
+    if (mismatching_size
+	(width, height, xx_res, yy_res, minx, miny, maxx, maxy))
+	goto error;
+
+    if (rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands) !=
+	RL2_OK)
+	goto error;
+    in_no_data = rl2_get_coverage_no_data (cvg);
+
+    if (pixel_type != RL2_PIXEL_MULTIBAND)
+	goto error;
+
+    if (red_band < 0 || red_band >= num_bands)
+	goto error;
+
+    if (nir_band < 0 || nir_band >= num_bands)
+	goto error;
+
+    if (red_band == nir_band)
+	goto error;
+
+    if (by_section)
+      {
+	  /* single Section */
+	  if (rl2_get_section_raw_raster_data
+	      (handle, max_threads, cvg, section_id, width, height, minx,
+	       miny, maxx, maxy, res, res, &pixels, &pixels_size, &palette,
+	       RL2_PIXEL_MULTIBAND) != RL2_OK)
+	      goto error;
+      }
+    else
+      {
+	  /* whole Coverage */
+	  if (rl2_get_raw_raster_data
+	      (handle, max_threads, cvg, width, height, minx, miny, maxx,
+	       maxy, res, res, &pixels, &pixels_size, &palette,
+	       RL2_PIXEL_MULTIBAND) != RL2_OK)
+	      goto error;
+      }
+
+/* creating the output NDVI raster */
+    out_pixels_size = width * height * sizeof (float);
+    out_pixels = malloc (out_pixels_size);
+    if (out_pixels == NULL)
+	goto error;
+    po = (float *) out_pixels;
+    for (row = 0; row < height; row++)
+      {
+	  /* computing NDVI */
+	  for (col = 0; col < width; col++)
+	      *po++ =
+		  compute_ndvi (pixels, sample_type, num_bands, width,
+				red_band, nir_band, row, col,
+				(rl2PrivPixelPtr) in_no_data, out_no_data);
+      }
+    free (pixels);
+    pixels = NULL;
+
+    ascii =
+	rl2_create_ascii_grid_destination (dst_path, width, height,
+					   xx_res, minx, miny, is_centered,
+					   out_no_data, decimal_digits,
+					   out_pixels, out_pixels_size,
+					   RL2_SAMPLE_FLOAT);
+    if (ascii == NULL)
+	goto error;
+    out_pixels = NULL;		/* pix-buffer ownership now belongs to the ASCII object */
+/* writing the ASCII Grid header */
+    if (rl2_write_ascii_grid_header (ascii) != RL2_OK)
+	goto error;
+    for (base_y = 0; base_y < height; base_y++)
+      {
+	  /* exporting all scanlines from the output buffer */
+	  unsigned int line_no;
+	  if (rl2_write_ascii_grid_scanline (ascii, &line_no) != RL2_OK)
+	      goto error;
+      }
+
+    rl2_destroy_ascii_grid_destination (ascii);
+    if (palette != NULL)
+	rl2_destroy_palette (palette);
+    return RL2_OK;
+
+  error:
+    if (ascii != NULL)
+	rl2_destroy_ascii_grid_destination (ascii);
+    if (pixels != NULL)
+	free (pixels);
+    if (palette != NULL)
+	rl2_destroy_palette (palette);
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_export_ndvi_ascii_grid_from_dbms (sqlite3 * handle, int max_threads,
+				      const char *dst_path,
+				      rl2CoveragePtr cvg, double res,
+				      double minx, double miny, double maxx,
+				      double maxy, unsigned int width,
+				      unsigned int height, int red_band,
+				      int nir_band, int is_centered,
+				      int decimal_digits)
+{
+/* exporting an ASCII Grid from the DBMS into the file-system */
+    return export_ndvi_ascii_grid_common (0, handle, max_threads, dst_path,
+					  cvg, 0, res, minx, miny, maxx, maxy,
+					  width, height, red_band, nir_band,
+					  is_centered, decimal_digits);
+}
+
+RL2_DECLARE int
+rl2_export_section_ndvi_ascii_grid_from_dbms (sqlite3 * handle,
+					      int max_threads,
+					      const char *dst_path,
+					      rl2CoveragePtr cvg,
+					      sqlite3_int64 section_id,
+					      double res, double minx,
+					      double miny, double maxx,
+					      double maxy, unsigned int width,
+					      unsigned int height,
+					      int red_band, int nir_band,
+					      int is_centered,
+					      int decimal_digits)
+{
+/* exporting an ASCII Grid - Section */
+    return export_ndvi_ascii_grid_common (1, handle, max_threads, dst_path,
+					  cvg, section_id, res, minx, miny,
+					  maxx, maxy, width, height, red_band,
+					  nir_band, is_centered,
+					  decimal_digits);
+}
+
+static int
+export_jpeg_common (int by_section, sqlite3 * handle, int max_threads,
+		    const char *dst_path, rl2CoveragePtr cvg,
+		    sqlite3_int64 section_id, 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)
+{
+/* common implementation for Write JPEG */
     rl2SectionPtr section = NULL;
     rl2RasterPtr raster = NULL;
     unsigned char level;
@@ -3146,7 +5434,8 @@ rl2_export_jpeg_from_dbms (sqlite3 * handle, const char *dst_path,
     int outbuf_size;
 
     if (rl2_find_matching_resolution
-	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
+	(handle, cvg, by_section, section_id, &xx_res, &yy_res, &level,
+	 &scale) != RL2_OK)
 	return RL2_ERROR;
 
     if (mismatching_size
@@ -3165,10 +5454,24 @@ rl2_export_jpeg_from_dbms (sqlite3 * handle, const char *dst_path,
     else
 	goto error;
 
-    if (rl2_get_raw_raster_data
-	(handle, cvg, width, height, minx, miny, maxx, maxy, xx_res,
-	 yy_res, &outbuf, &outbuf_size, NULL, pixel_type) != RL2_OK)
-	goto error;
+    if (by_section)
+      {
+	  /* single Section */
+	  if (rl2_get_section_raw_raster_data
+	      (handle, max_threads, cvg, section_id, width, height, minx,
+	       miny, maxx, maxy, xx_res, yy_res, &outbuf, &outbuf_size, NULL,
+	       pixel_type) != RL2_OK)
+	      goto error;
+      }
+    else
+      {
+	  /* whole Coverage */
+	  if (rl2_get_raw_raster_data
+	      (handle, max_threads, cvg, width, height, minx, miny, maxx,
+	       maxy, xx_res, yy_res, &outbuf, &outbuf_size, NULL,
+	       pixel_type) != RL2_OK)
+	      goto error;
+      }
 
     raster =
 	rl2_create_raster (width, height, sample_type, pixel_type, num_bands,
@@ -3202,3 +5505,548 @@ rl2_export_jpeg_from_dbms (sqlite3 * handle, const char *dst_path,
 	free (outbuf);
     return RL2_ERROR;
 }
+
+RL2_DECLARE int
+rl2_export_jpeg_from_dbms (sqlite3 * handle, int max_threads,
+			   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)
+{
+/* exporting a JPEG (with possible JGW) from the DBMS into the file-system */
+    return export_jpeg_common (0, handle, max_threads, dst_path, cvg, 0,
+			       x_res, y_res, minx, miny, maxx, maxy, width,
+			       height, quality, with_worldfile);
+}
+
+RL2_DECLARE int
+rl2_export_section_jpeg_from_dbms (sqlite3 * handle, int max_threads,
+				   const char *dst_path, rl2CoveragePtr cvg,
+				   sqlite3_int64 section_id, 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)
+{
+/* exporting a JPEG (with possible JGW) - Section */
+    return export_jpeg_common (1, handle, max_threads, dst_path, cvg,
+			       section_id, x_res, y_res, minx, miny, maxx,
+			       maxy, width, height, quality, with_worldfile);
+}
+
+static int
+export_raw_pixels_common (int by_section, sqlite3 * handle, int max_threads,
+			  rl2CoveragePtr cvg, sqlite3_int64 section_id,
+			  double x_res, double y_res, double minx,
+			  double miny, double maxx, double maxy,
+			  unsigned int width, unsigned int height,
+			  int big_endian, unsigned char **blob, int *blob_size)
+{
+/* common implementation for Export RAW pixels */
+    unsigned char level;
+    unsigned char scale;
+    double xx_res = x_res;
+    double yy_res = y_res;
+    unsigned char sample_type;
+    unsigned char pixel_type;
+    unsigned char num_bands;
+    unsigned char *bufpix;
+    unsigned char *outbuf = NULL;
+    int outbuf_size;
+
+    if (rl2_find_matching_resolution
+	(handle, cvg, by_section, section_id, &xx_res, &yy_res, &level,
+	 &scale) != RL2_OK)
+	return RL2_ERROR;
+
+    if (mismatching_size
+	(width, height, xx_res, yy_res, minx, miny, maxx, maxy))
+	goto error;
+
+    if (rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands) !=
+	RL2_OK)
+	goto error;
+
+    if (by_section)
+      {
+	  /* single Section */
+	  if (rl2_get_section_raw_raster_data
+	      (handle, max_threads, cvg, section_id, width, height, minx,
+	       miny, maxx, maxy, xx_res, yy_res, &outbuf, &outbuf_size, NULL,
+	       pixel_type) != RL2_OK)
+	      goto error;
+      }
+    else
+      {
+	  /* whole Coverage */
+	  if (rl2_get_raw_raster_data
+	      (handle, max_threads, cvg, width, height, minx, miny, maxx,
+	       maxy, xx_res, yy_res, &outbuf, &outbuf_size, NULL,
+	       pixel_type) != RL2_OK)
+	      goto error;
+      }
+    bufpix =
+	rl2_copy_endian_raw_pixels (outbuf, outbuf_size, width, height,
+				    sample_type, num_bands, big_endian);
+    if (bufpix == NULL)
+	goto error;
+    *blob = bufpix;
+    *blob_size = outbuf_size;
+    free (outbuf);
+    return RL2_OK;
+
+  error:
+    if (outbuf != NULL)
+	free (outbuf);
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_export_raw_pixels_from_dbms (sqlite3 * handle, int max_threads,
+				 rl2CoveragePtr coverage, double x_res,
+				 double y_res, double minx, double miny,
+				 double maxx, double maxy,
+				 unsigned int width,
+				 unsigned int height, int big_endian,
+				 unsigned char **blob, int *blob_size)
+{
+/* exporting RAW pixel buffer and Transparency Mask from the DBMS */
+    return export_raw_pixels_common (0, handle, max_threads, coverage, 0,
+				     x_res, y_res, minx, miny, maxx, maxy,
+				     width, height, big_endian, blob,
+				     blob_size);
+}
+
+RL2_DECLARE int
+rl2_export_section_raw_pixels_from_dbms (sqlite3 * handle, int max_threads,
+					 rl2CoveragePtr coverage,
+					 sqlite3_int64 section_id,
+					 double x_res, double y_res,
+					 double minx, double miny,
+					 double maxx, double maxy,
+					 unsigned int width,
+					 unsigned int height,
+					 int big_endian,
+					 unsigned char **blob, int *blob_size)
+{
+/* exporting RAW pixel buffer and Transparency Mask - Section */
+    return export_raw_pixels_common (1, handle, max_threads, coverage,
+				     section_id, x_res, y_res, minx, miny,
+				     maxx, maxy, width, height, big_endian,
+				     blob, blob_size);
+}
+
+RL2_DECLARE int
+rl2_load_raw_raster_into_dbms (sqlite3 * handle, int max_threads,
+			       rl2CoveragePtr cvg, const char *section,
+			       rl2RasterPtr rst, int pyramidize)
+{
+/* main IMPORT Raster function */
+    rl2PrivCoveragePtr privcvg = (rl2PrivCoveragePtr) cvg;
+    rl2PrivRasterPtr privrst = (rl2PrivRasterPtr) rst;
+    int ret;
+    char *sql;
+    const char *coverage;
+    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;
+    char *table;
+    char *xtable;
+    unsigned int tileWidth;
+    unsigned int tileHeight;
+    unsigned int width;
+    unsigned int height;
+    int srid;
+    double minx;
+    double miny;
+    double maxx;
+    double maxy;
+    double tile_minx;
+    double tile_maxy;
+    rl2RasterStatisticsPtr section_stats = NULL;
+    rl2PixelPtr no_data = NULL;
+    rl2PalettePtr aux_palette = NULL;
+    unsigned int row;
+    unsigned int col;
+    double res_x;
+    double res_y;
+    double base_res_x;
+    double base_res_y;
+    char *xml_summary = NULL;
+    sqlite3_stmt *stmt_data = NULL;
+    sqlite3_stmt *stmt_tils = NULL;
+    sqlite3_stmt *stmt_sect = NULL;
+    sqlite3_stmt *stmt_levl = NULL;
+    sqlite3_stmt *stmt_upd_sect = NULL;
+    sqlite3_int64 section_id;
+    rl2AuxImporterPtr aux = NULL;
+    rl2AuxImporterTilePtr aux_tile;
+    rl2AuxImporterTilePtr *thread_slots = NULL;
+    int thread_count;
+
+    if (cvg == NULL)
+	goto error;
+    if (section == NULL)
+	goto error;
+    if (rst == NULL)
+	goto error;
+
+    if (rl2_get_coverage_tile_size (cvg, &tileWidth, &tileHeight) != RL2_OK)
+	goto error;
+    if (rl2_get_raster_size (rst, &width, &height) != RL2_OK)
+	goto error;
+    if (rl2_get_raster_srid (rst, &srid) != RL2_OK)
+	goto error;
+    if (rl2_get_raster_extent (rst, &minx, &miny, &maxx, &maxy) != RL2_OK)
+	goto error;
+
+    tile_w = tileWidth;
+    tile_h = tileHeight;
+    rl2_get_coverage_compression (cvg, &compression, &quality);
+    rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands);
+    coverage = rl2_get_coverage_name (cvg);
+
+    table = sqlite3_mprintf ("%s_sections", coverage);
+    xtable = rl2_double_quoted_sql (table);
+    sqlite3_free (table);
+    sql =
+	sqlite3_mprintf
+	("INSERT INTO \"%s\" (section_id, section_name, file_path, "
+	 "md5_checksum, summary, width, height, geometry) "
+	 "VALUES (NULL, ?, ?, ?, XB_Create(?), ?, ?, ?)", xtable);
+    free (xtable);
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_sect, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("INSERT INTO sections SQL error: %s\n",
+		  sqlite3_errmsg (handle));
+	  goto error;
+      }
+
+    table = sqlite3_mprintf ("%s_sections", coverage);
+    xtable = rl2_double_quoted_sql (table);
+    sqlite3_free (table);
+    sql =
+	sqlite3_mprintf
+	("UPDATE \"%s\" SET statistics = ? WHERE section_id = ?", xtable);
+    free (xtable);
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_upd_sect, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("UPDATE sections SQL error: %s\n", sqlite3_errmsg (handle));
+	  goto error;
+      }
+
+    if (privcvg->mixedResolutions)
+      {
+	  /* mixed resolutions Coverage */
+	  table = sqlite3_mprintf ("%s_section_levels", coverage);
+	  xtable = rl2_double_quoted_sql (table);
+	  sqlite3_free (table);
+	  sql =
+	      sqlite3_mprintf
+	      ("INSERT OR IGNORE INTO \"%s\" (section_id, pyramid_level, "
+	       "x_resolution_1_1, y_resolution_1_1, "
+	       "x_resolution_1_2, y_resolution_1_2, x_resolution_1_4, "
+	       "y_resolution_1_4, x_resolution_1_8, y_resolution_1_8) "
+	       "VALUES (?, 0, ?, ?, ?, ?, ?, ?, ?, ?)", xtable);
+	  free (xtable);
+	  ret =
+	      sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_levl, NULL);
+	  sqlite3_free (sql);
+	  if (ret != SQLITE_OK)
+	    {
+		printf ("INSERT INTO section_levels SQL error: %s\n",
+			sqlite3_errmsg (handle));
+		goto error;
+	    }
+      }
+    else
+      {
+	  /* single resolution Coverage */
+	  table = sqlite3_mprintf ("%s_levels", coverage);
+	  xtable = rl2_double_quoted_sql (table);
+	  sqlite3_free (table);
+	  sql =
+	      sqlite3_mprintf
+	      ("INSERT OR IGNORE INTO \"%s\" (pyramid_level, "
+	       "x_resolution_1_1, y_resolution_1_1, "
+	       "x_resolution_1_2, y_resolution_1_2, x_resolution_1_4, "
+	       "y_resolution_1_4, x_resolution_1_8, y_resolution_1_8) "
+	       "VALUES (0, ?, ?, ?, ?, ?, ?, ?, ?)", xtable);
+	  free (xtable);
+	  ret =
+	      sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_levl, NULL);
+	  sqlite3_free (sql);
+	  if (ret != SQLITE_OK)
+	    {
+		printf ("INSERT INTO levels SQL error: %s\n",
+			sqlite3_errmsg (handle));
+		goto error;
+	    }
+      }
+
+    table = sqlite3_mprintf ("%s_tiles", coverage);
+    xtable = rl2_double_quoted_sql (table);
+    sqlite3_free (table);
+    sql =
+	sqlite3_mprintf
+	("INSERT INTO \"%s\" (tile_id, pyramid_level, section_id, geometry) "
+	 "VALUES (NULL, 0, ?, BuildMBR(?, ?, ?, ?, ?))", xtable);
+    free (xtable);
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_tils, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("INSERT INTO tiles SQL error: %s\n", sqlite3_errmsg (handle));
+	  goto error;
+      }
+
+    table = sqlite3_mprintf ("%s_tile_data", coverage);
+    xtable = rl2_double_quoted_sql (table);
+    sqlite3_free (table);
+    sql =
+	sqlite3_mprintf
+	("INSERT INTO \"%s\" (tile_id, tile_data_odd, tile_data_even) "
+	 "VALUES (?, ?, ?)", xtable);
+    free (xtable);
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_data, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("INSERT INTO tile_data SQL error: %s\n",
+		  sqlite3_errmsg (handle));
+	  goto error;
+      }
+    res_x = privrst->hResolution;
+    res_y = privrst->vResolution;
+    base_res_x = privcvg->hResolution;
+    base_res_y = privcvg->vResolution;
+    xml_summary = rl2_build_raw_pixels_xml_summary (rst);
+
+/* INSERTing the section */
+    if (!rl2_do_insert_section
+	(handle, "loaded from RAW pixels", section, srid, width, height, minx,
+	 miny, maxx, maxy, xml_summary, privcvg->sectionPaths,
+	 privcvg->sectionMD5, privcvg->sectionSummary, stmt_sect, &section_id))
+	goto error;
+    section_stats = rl2_create_raster_statistics (sample_type, num_bands);
+    if (section_stats == NULL)
+	goto error;
+/* INSERTing the base-levels */
+    if (privcvg->mixedResolutions)
+      {
+	  /* multiple resolutions Coverage */
+	  if (!rl2_do_insert_section_levels
+	      (handle, section_id, res_x, res_y, 1.0, sample_type, stmt_levl))
+	      goto error;
+      }
+    else
+      {
+	  /* single resolution Coverage */
+	  if (!rl2_do_insert_levels
+	      (handle, base_res_x, base_res_y, 1.0, sample_type, stmt_levl))
+	      goto error;
+      }
+
+/* preparing all Tile Requests */
+    aux =
+	createAuxImporter (privcvg, srid, maxx, miny, tile_w, tile_h, res_x,
+			   res_y, RL2_ORIGIN_RAW, rst, RL2_CONVERT_NO, 1,
+			   compression, quality);
+    tile_maxy = maxy;
+    for (row = 0; row < height; row += tile_h)
+      {
+	  tile_minx = minx;
+	  for (col = 0; col < width; col += tile_w)
+	    {
+		/* adding a Tile request */
+		addTile2AuxImporter (aux, row, col, tile_minx, tile_maxy);
+		tile_minx += (double) tile_w *res_x;
+	    }
+	  tile_maxy -= (double) tile_h *res_y;
+      }
+
+    if (max_threads < 1)
+	max_threads = 1;
+    if (max_threads > 64)
+	max_threads = 64;
+/* prepating the thread_slots stuct */
+    thread_slots = malloc (sizeof (rl2AuxImporterTilePtr) * max_threads);
+    for (thread_count = 0; thread_count < max_threads; thread_count++)
+	*(thread_slots + thread_count) = NULL;
+    thread_count = 0;
+    aux_tile = aux->first;
+    while (aux_tile != NULL)
+      {
+	  /* processing a Tile request (may be under parallel execution) */
+	  if (max_threads > 1)
+	    {
+		/* adopting a multithreaded strategy */
+		do_get_tile (aux_tile);
+		*(thread_slots + thread_count) = aux_tile;
+		thread_count++;
+		start_tile_thread (aux_tile);
+		if (thread_count == max_threads || aux_tile->next == NULL)
+		  {
+		      /* waiting until all child threads exit */
+#ifdef _WIN32
+		      HANDLE *handles;
+		      int z;
+		      int cnt = 0;
+		      for (z = 0; z < max_threads; z++)
+			{
+			    /* counting how many active threads we currently have */
+			    rl2AuxImporterTilePtr pTile = *(thread_slots + z);
+			    if (pTile == NULL)
+				continue;
+			    cnt++;
+			}
+		      handles = malloc (sizeof (HANDLE) * cnt);
+		      cnt = 0;
+		      for (z = 0; z < max_threads; z++)
+			{
+			    /* initializing the HANDLEs array */
+			    HANDLE *pOpaque;
+			    rl2AuxImporterTilePtr pTile = *(thread_slots + z);
+			    if (pTile == NULL)
+				continue;
+			    pOpaque = (HANDLE *) (pTile->opaque_thread_id);
+			    *(handles + cnt) = *pOpaque;
+			    cnt++;
+			}
+		      WaitForMultipleObjects (cnt, handles, TRUE, INFINITE);
+#else
+		      for (thread_count = 0; thread_count < max_threads;
+			   thread_count++)
+			{
+			    pthread_t *pOpaque;
+			    rl2AuxImporterTilePtr pTile =
+				*(thread_slots + thread_count);
+			    if (pTile == NULL)
+				continue;
+			    pOpaque = (pthread_t *) (pTile->opaque_thread_id);
+			    pthread_join (*pOpaque, NULL);
+			}
+#endif
+
+		      /* all children threads have now finished: resuming the main thread */
+		      for (thread_count = 0; thread_count < max_threads;
+			   thread_count++)
+			{
+			    /* checking for eventual errors */
+			    rl2AuxImporterTilePtr pTile =
+				*(thread_slots + thread_count);
+			    if (pTile == NULL)
+				continue;
+			    if (pTile->retcode != RL2_OK)
+				goto error;
+			}
+#ifdef _WIN32
+		      free (handles);
+#endif
+		      thread_count = 0;
+		      /* we can now continue by inserting all tiles into the DBMS */
+		  }
+		else
+		  {
+		      aux_tile = aux_tile->next;
+		      continue;
+		  }
+	    }
+	  else
+	    {
+		/* single thread execution */
+		do_get_tile (aux_tile);
+		*(thread_slots + 0) = aux_tile;
+		do_encode_tile (aux_tile);
+		if (aux_tile->retcode != RL2_OK)
+		    goto error;
+	    }
+
+	  /* INSERTing the tile */
+	  aux_palette =
+	      rl2_clone_palette (rl2_get_raster_palette (aux_tile->raster));
+	  if (!do_insert_tile
+	      (handle, aux_tile->blob_odd, aux_tile->blob_odd_sz,
+	       aux_tile->blob_even, aux_tile->blob_even_sz, section_id, srid,
+	       aux_tile->minx, aux_tile->miny, aux_tile->maxx, aux_tile->maxy,
+	       aux_palette, no_data, stmt_tils, stmt_data, section_stats))
+	    {
+		aux_tile->blob_odd = NULL;
+		aux_tile->blob_even = NULL;
+		goto error;
+	    }
+	  doAuxImporterTileCleanup (aux_tile);
+	  aux_tile = aux_tile->next;
+      }
+    destroyAuxImporter (aux);
+    aux = NULL;
+    free (thread_slots);
+    thread_slots = NULL;
+
+/* updating the Section's Statistics */
+    compute_aggregate_sq_diff (section_stats);
+    if (!rl2_do_insert_stats (handle, section_stats, section_id, stmt_upd_sect))
+	goto error;
+
+    rl2_destroy_raster_statistics (section_stats);
+    section_stats = NULL;
+
+    if (pyramidize)
+      {
+	  /* immediately building the Section's Pyramid */
+	  const char *coverage_name = rl2_get_coverage_name (cvg);
+	  if (coverage_name == NULL)
+	      goto error;
+	  if (rl2_build_section_pyramid
+	      (handle, max_threads, coverage_name, section_id, 1, 0) != RL2_OK)
+	    {
+		fprintf (stderr, "unable to build the Section's Pyramid\n");
+		goto error;
+	    }
+      }
+
+    sqlite3_finalize (stmt_upd_sect);
+    sqlite3_finalize (stmt_sect);
+    sqlite3_finalize (stmt_levl);
+    sqlite3_finalize (stmt_tils);
+    sqlite3_finalize (stmt_data);
+    stmt_upd_sect = NULL;
+    stmt_sect = NULL;
+    stmt_levl = NULL;
+    stmt_tils = NULL;
+    stmt_data = NULL;
+
+    if (rl2_update_dbms_coverage (handle, coverage) != RL2_OK)
+      {
+	  fprintf (stderr, "unable to update the Coverage\n");
+	  goto error;
+      }
+
+    return RL2_OK;
+
+  error:
+    if (aux != NULL)
+	destroyAuxImporter (aux);
+    if (thread_slots != NULL)
+	free (thread_slots);
+    if (stmt_upd_sect != NULL)
+	sqlite3_finalize (stmt_upd_sect);
+    if (stmt_sect != NULL)
+	sqlite3_finalize (stmt_sect);
+    if (stmt_levl != NULL)
+	sqlite3_finalize (stmt_levl);
+    if (stmt_tils != NULL)
+	sqlite3_finalize (stmt_tils);
+    if (stmt_data != NULL)
+	sqlite3_finalize (stmt_data);
+    return RL2_ERROR;
+}
diff --git a/src/rl2jpeg.c b/src/rl2jpeg.c
index af97ad9..b6bde4b 100644
--- a/src/rl2jpeg.c
+++ b/src/rl2jpeg.c
@@ -20,7 +20,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -230,7 +230,8 @@ rl2_jpeg_src (j_decompress_ptr cinfo,
     if (cinfo->src == NULL)
       {				/* first time for this JPEG object? */
 	  cinfo->src = (struct jpeg_source_mgr *)
-	      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+	      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo,
+					  JPOOL_PERMANENT,
 					  sizeof (struct jpeg_source_mgr));
       }
 
@@ -265,7 +266,8 @@ rl2_jpeg_dest (j_compress_ptr cinfo,
     if (cinfo->dest == NULL)
       {				/* first time for this JPEG object? */
 	  cinfo->dest = (struct jpeg_destination_mgr *)
-	      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+	      (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo,
+					  JPOOL_PERMANENT,
 					  sizeof (jpeg_mem_destination_mgr));
 	  dest = (jpeg_mem_dest_ptr) cinfo->dest;
 	  dest->newbuffer = NULL;
@@ -757,8 +759,8 @@ rl2_raster_to_jpeg (rl2RasterPtr raster, unsigned char **jpeg, int *jpeg_size,
 
     if (rst == NULL)
 	return RL2_ERROR;
-    if (check_jpeg_compatibility (rst->sampleType, rst->pixelType, rst->nBands)
-	!= RL2_OK)
+    if (check_jpeg_compatibility
+	(rst->sampleType, rst->pixelType, rst->nBands) != RL2_OK)
 	return RL2_ERROR;
     if (rl2_data_to_jpeg
 	(rst->rasterBuffer, rst->maskBuffer, (rl2PalettePtr) (rst->Palette),
@@ -782,8 +784,8 @@ rl2_rgb_to_jpeg (unsigned int width, unsigned int height,
 	return RL2_ERROR;
 
     if (rl2_data_to_jpeg
-	(rgb, NULL, NULL, width, height, RL2_SAMPLE_UINT8, RL2_PIXEL_RGB, &blob,
-	 &blob_size, quality) != RL2_OK)
+	(rgb, NULL, NULL, width, height, RL2_SAMPLE_UINT8, RL2_PIXEL_RGB,
+	 &blob, &blob_size, quality) != RL2_OK)
 	return RL2_ERROR;
     *jpeg = blob;
     *jpeg_size = blob_size;
@@ -792,8 +794,8 @@ rl2_rgb_to_jpeg (unsigned int width, unsigned int height,
 
 RL2_DECLARE int
 rl2_gray_to_jpeg (unsigned int width, unsigned int height,
-		  const unsigned char *gray, int quality, unsigned char **jpeg,
-		  int *jpeg_size)
+		  const unsigned char *gray, int quality,
+		  unsigned char **jpeg, int *jpeg_size)
 {
 /* creating a PNG image from a Grayscale buffer */
     unsigned char *blob;
@@ -802,8 +804,8 @@ rl2_gray_to_jpeg (unsigned int width, unsigned int height,
 	return RL2_ERROR;
 
     if (rl2_data_to_jpeg
-	(gray, NULL, NULL, width, height, RL2_SAMPLE_UINT8, RL2_PIXEL_GRAYSCALE,
-	 &blob, &blob_size, quality) != RL2_OK)
+	(gray, NULL, NULL, width, height, RL2_SAMPLE_UINT8,
+	 RL2_PIXEL_GRAYSCALE, &blob, &blob_size, quality) != RL2_OK)
 	return RL2_ERROR;
     *jpeg = blob;
     *jpeg_size = blob_size;
@@ -851,8 +853,9 @@ rl2_section_from_jpeg (const char *path)
 
 /* creating the raster section */
     scn =
-	rl2_create_section (path, RL2_COMPRESSION_JPEG, RL2_TILESIZE_UNDEFINED,
-			    RL2_TILESIZE_UNDEFINED, rst);
+	rl2_create_section (path, RL2_COMPRESSION_JPEG,
+			    RL2_TILESIZE_UNDEFINED, RL2_TILESIZE_UNDEFINED,
+			    rst);
     return scn;
 }
 
@@ -878,8 +881,8 @@ rl2_raster_from_jpeg (const unsigned char *jpeg, int jpeg_size)
 
 /* creating the raster */
     rst =
-	rl2_create_raster (width, height, RL2_SAMPLE_UINT8, pixel_type, nBands,
-			   data, data_size, NULL, NULL, 0, NULL);
+	rl2_create_raster (width, height, RL2_SAMPLE_UINT8, pixel_type,
+			   nBands, data, data_size, NULL, NULL, 0, NULL);
     if (rst == NULL)
 	goto error;
     return rst;
@@ -892,6 +895,69 @@ rl2_raster_from_jpeg (const unsigned char *jpeg, int jpeg_size)
     return NULL;
 }
 
+RL2_DECLARE int
+rl2_get_jpeg_infos (const char *path, unsigned int *width,
+		    unsigned int *height, unsigned char *pixel_type)
+{
+/* attempting to retrieve basic infos from a JPEG image */
+    int jpeg_size;
+    unsigned char *jpeg = NULL;
+    struct jpeg_decompress_struct cinfo;
+    struct jpeg_error_mgr jerr;
+    int row_stride;
+    JSAMPARRAY buffer;
+
+/* attempting to create a raster */
+    if (rl2_blob_from_file (path, &jpeg, &jpeg_size) != RL2_OK)
+	return RL2_ERROR;
+
+    cinfo.err = jpeg_std_error (&jerr);
+    jpeg_create_decompress (&cinfo);
+    rl2_jpeg_src (&cinfo, (unsigned char *) jpeg, jpeg_size);
+    jpeg_read_header (&cinfo, TRUE);
+    cinfo.scale_num = 8;
+    cinfo.scale_denom = 8;
+    if ((cinfo.jpeg_color_space == JCS_CMYK)
+	|| (cinfo.jpeg_color_space == JCS_YCCK))
+	cinfo.out_color_space = JCS_CMYK;
+    if (!jpeg_start_decompress (&cinfo))
+	goto error;
+
+    if (cinfo.out_color_space == JCS_RGB && cinfo.output_components == 3)
+	*pixel_type = RL2_PIXEL_RGB;
+    else if (cinfo.out_color_space == JCS_GRAYSCALE
+	     && cinfo.output_components == 1)
+	*pixel_type = RL2_PIXEL_GRAYSCALE;
+    else if (cinfo.out_color_space == JCS_CMYK && cinfo.output_components == 4)
+	*pixel_type = RL2_PIXEL_RGB;
+    else
+	goto error;
+    *width = cinfo.output_width;
+    *height = cinfo.output_height;
+/* creating the scanline buffer */
+    row_stride = cinfo.output_width * cinfo.output_components;
+    buffer =
+	(*cinfo.mem->alloc_sarray) ((j_common_ptr) & cinfo, JPOOL_IMAGE,
+				    row_stride, 1);
+    if (buffer == NULL)
+	goto error;
+    while (cinfo.output_scanline < cinfo.output_height)
+      {
+	  /* reading all decompressed scanlines */
+	  jpeg_read_scanlines (&cinfo, buffer, 1);
+      }
+
+/* memory cleanup */
+    jpeg_finish_decompress (&cinfo);
+    jpeg_destroy_decompress (&cinfo);
+    free (jpeg);
+    return RL2_OK;
+
+  error:
+    free (jpeg);
+    jpeg_destroy_decompress (&cinfo);
+    return RL2_ERROR;
+}
 
 RL2_PRIVATE int
 rl2_decode_jpeg_scaled (int scale, const unsigned char *jpeg, int jpeg_size,
@@ -1001,8 +1067,8 @@ rl2_decode_jpeg_scaled (int scale, const unsigned char *jpeg, int jpeg_size,
 		JSAMPROW row = buffer[0];
 		for (i = 0; i < (int) (cinfo.output_width); i++)
 		  {
-		      CMYK2RGB (*(row + 0), *(row + 1), *(row + 2), *(row + 3),
-				inverted, p_data);
+		      CMYK2RGB (*(row + 0), *(row + 1), *(row + 2),
+				*(row + 3), inverted, p_data);
 		      row += 4;
 		      p_data += 3;
 		  }
@@ -1228,15 +1294,15 @@ read_from_jpeg (rl2PrivRasterPtr origin, unsigned short width,
 static int
 eval_jpeg_origin_compatibility (rl2PrivCoveragePtr coverage,
 				rl2PrivRasterPtr raster,
-				unsigned char forced_conversion)
+				unsigned char forced_conversion, int verbose)
 {
 /* checking for strict compatibility */
     if (coverage->sampleType == RL2_SAMPLE_UINT8
 	&& coverage->pixelType == RL2_PIXEL_GRAYSCALE && coverage->nBands == 1)
       {
 	  if (raster->sampleType == RL2_SAMPLE_UINT8
-	      && raster->pixelType == RL2_PIXEL_GRAYSCALE && raster->nBands == 1
-	      && forced_conversion == RL2_CONVERT_NO)
+	      && raster->pixelType == RL2_PIXEL_GRAYSCALE
+	      && raster->nBands == 1 && forced_conversion == RL2_CONVERT_NO)
 	      return 1;
 	  if (raster->sampleType == RL2_SAMPLE_UINT8
 	      && raster->pixelType == RL2_PIXEL_RGB && raster->nBands == 3
@@ -1251,17 +1317,20 @@ eval_jpeg_origin_compatibility (rl2PrivCoveragePtr coverage,
 	      && forced_conversion == RL2_CONVERT_NO)
 	      return 1;
 	  if (raster->sampleType == RL2_SAMPLE_UINT8
-	      && raster->pixelType == RL2_PIXEL_GRAYSCALE && raster->nBands == 1
+	      && raster->pixelType == RL2_PIXEL_GRAYSCALE
+	      && raster->nBands == 1
 	      && forced_conversion == RL2_CONVERT_GRAYSCALE_TO_RGB)
 	      return 1;
       }
+    if (verbose)
+	fprintf (stderr, "Mismatching JPEG colorspace !!!\n");
     return 0;
 }
 
 RL2_DECLARE rl2RasterPtr
 rl2_get_tile_from_jpeg_origin (rl2CoveragePtr cvg, rl2RasterPtr jpeg,
 			       unsigned int startRow, unsigned int startCol,
-			       unsigned char forced_conversion)
+			       unsigned char forced_conversion, int verbose)
 {
 /* attempting to create a Coverage-tile from a JPEG origin */
     unsigned int x;
@@ -1277,7 +1346,8 @@ rl2_get_tile_from_jpeg_origin (rl2CoveragePtr cvg, rl2RasterPtr jpeg,
 
     if (coverage == NULL || origin == NULL)
 	return NULL;
-    if (!eval_jpeg_origin_compatibility (coverage, origin, forced_conversion))
+    if (!eval_jpeg_origin_compatibility
+	(coverage, origin, forced_conversion, verbose))
 	return NULL;
 
 /* testing for tile's boundary validity */
@@ -1342,3 +1412,153 @@ rl2_get_tile_from_jpeg_origin (rl2CoveragePtr cvg, rl2RasterPtr jpeg,
 	free (mask);
     return NULL;
 }
+
+RL2_DECLARE char *
+rl2_build_jpeg_xml_summary (unsigned int width, unsigned int height,
+			    unsigned char pixel_type, int is_georeferenced,
+			    double res_x, double res_y, double minx,
+			    double miny, double maxx, double maxy)
+{
+/* attempting to build an XML Summary from a JPEG */
+    char *xml;
+    char *prev;
+    int len;
+
+    xml = sqlite3_mprintf ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<ImportedRaster>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<RasterFormat>JPEG</RasterFormat>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<RasterWidth>%u</RasterWidth>", prev, width);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<RasterHeight>%u</RasterHeight>", prev, height);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<RowsPerStrip>1</RowsPerStrip>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<BitsPerSample>8</BitsPerSample>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    if (pixel_type == RL2_PIXEL_GRAYSCALE)
+	xml = sqlite3_mprintf ("%s<SamplesPerPixel>1</SamplesPerPixel>", prev);
+    else
+	xml = sqlite3_mprintf ("%s<SamplesPerPixel>3</SamplesPerPixel>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    if (pixel_type == RL2_PIXEL_GRAYSCALE)
+	xml =
+	    sqlite3_mprintf
+	    ("%s<PhotometricInterpretation>min-is-black</PhotometricInterpretation>",
+	     prev);
+    else
+	xml =
+	    sqlite3_mprintf
+	    ("%s<PhotometricInterpretation>RGB</PhotometricInterpretation>",
+	     prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<Compression>JPEG</Compression>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml =
+	sqlite3_mprintf ("%s<SampleFormat>unsigned integer</SampleFormat>",
+			 prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml =
+	sqlite3_mprintf
+	("%s<PlanarConfiguration>single Raster plane</PlanarConfiguration>",
+	 prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<NoDataPixel>unknown</NoDataPixel>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    if (is_georeferenced)
+      {
+	  xml = sqlite3_mprintf ("%s<GeoReferencing>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<SpatialReferenceSystem>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<SRID>unspecified</SRID>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<RefSysName>undeclared</RefSysName>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s</SpatialReferenceSystem>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<SpatialResolution>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml =
+	      sqlite3_mprintf
+	      ("%s<HorizontalResolution>%1.10f</HorizontalResolution>", prev,
+	       res_x);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml =
+	      sqlite3_mprintf
+	      ("%s<VerticalResolution>%1.10f</VerticalResolution>", prev,
+	       res_y);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s</SpatialResolution>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<BoundingBox>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<MinX>%1.10f</MinX>", prev, minx);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<MinY>%1.10f</MinY>", prev, miny);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<MaxX>%1.10f</MaxX>", prev, maxx);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<MaxY>%1.10f</MaxY>", prev, maxy);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s</BoundingBox>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<Extent>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml =
+	      sqlite3_mprintf
+	      ("%s<HorizontalExtent>%1.10f</HorizontalExtent>", prev,
+	       maxx - minx);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml =
+	      sqlite3_mprintf ("%s<VerticalExtent>%1.10f</VerticalExtent>",
+			       prev, maxy - miny);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s</Extent>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s</GeoReferencing>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+      }
+    xml = sqlite3_mprintf ("%s</ImportedRaster>", prev);
+    sqlite3_free (prev);
+    len = strlen (xml);
+    prev = xml;
+    xml = malloc (len + 1);
+    strcpy (xml, prev);
+    sqlite3_free (prev);
+    return xml;
+}
diff --git a/src/rl2md5.c b/src/rl2md5.c
new file mode 100644
index 0000000..52665d9
--- /dev/null
+++ b/src/rl2md5.c
@@ -0,0 +1,116 @@
+/*
+
+ rl2md5.c --   a thin wrapper built around the original MD5
+               implementation from Alexander Peslyak 
+               (released on the Public Domain)
+
+ version 0.1, 2014 August 5
+
+ Author: Sandro Furieri a.furieri at lqt.it
+
+ -----------------------------------------------------------------------------
+ 
+ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ 
+ The contents of this file are subject to the Mozilla Public License Version
+ 1.1 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+ 
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the
+License.
+
+The Original Code is the RasterLite2 library
+
+The Initial Developer of the Original Code is Alessandro Furieri
+ 
+Portions created by the Initial Developer are Copyright (C) 2008-2013
+the Initial Developer. All Rights Reserved.
+
+Contributor(s): 
+
+Alternatively, the contents of this file may be used under the terms of
+either the GNU General Public License Version 2 or later (the "GPL"), or
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+in which case the provisions of the GPL or the LGPL are applicable instead
+of those above. If you wish to allow use of your version of this file only
+under the terms of either the GPL or the LGPL, and not to allow others to
+use your version of this file under the terms of the MPL, indicate your
+decision by deleting the provisions above and replace them with the notice
+and other provisions required by the GPL or the LGPL. If you do not delete
+the provisions above, a recipient may use your version of this file under
+the terms of any one of the MPL, the GPL or the LGPL.
+ 
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "config.h"
+
+#ifdef LOADABLE_EXTENSION
+#include "rasterlite2/sqlite.h"
+#endif
+
+#include "rasterlite2/rasterlite2.h"
+#include "rasterlite2_private.h"
+
+#include "md5.h"
+
+RL2_PRIVATE void *
+rl2_CreateMD5Checksum (void)
+{
+/* Creates and initializes an MD5 checksum object */
+    MD5_CTX *md5 = malloc (sizeof (MD5_CTX));
+    rl2_MD5_Init (md5);
+    return md5;
+}
+
+RL2_PRIVATE void
+rl2_FreeMD5Checksum (void *p_md5)
+{
+/* memory cleanup - destroying an MD5 checksum object */
+    unsigned char result[32];
+    MD5_CTX *md5 = (MD5_CTX *) p_md5;
+    if (md5 == NULL)
+	return;
+    rl2_MD5_Final (result, md5);
+    free (md5);
+}
+
+RL2_PRIVATE void
+rl2_UpdateMD5Checksum (void *p_md5, const unsigned char *blob, int blob_len)
+{
+/* progressively updating the MD5 checksum */
+    MD5_CTX *md5 = (MD5_CTX *) p_md5;
+    if (md5 == NULL || blob == NULL)
+	return;
+    rl2_MD5_Update (md5, (void *) blob, blob_len);
+}
+
+RL2_PRIVATE char *
+rl2_FinalizeMD5Checksum (void *p_md5)
+{
+/* return the current MD5 checksum and resets the MD5 object */
+    int i;
+    char *hex;
+    char hex_byte[8];
+    unsigned char result[32];
+    MD5_CTX *md5 = (MD5_CTX *) p_md5;
+    if (md5 == NULL)
+	return NULL;
+    rl2_MD5_Final (result, md5);
+    rl2_MD5_Init (md5);
+/* formatting the MD5 checksum as hex-text */
+    hex = malloc (33);
+    *hex = '\0';
+    for (i = 0; i < 16; i++)
+      {
+	  sprintf (hex_byte, "%02x", result[i]);
+	  strcat (hex, hex_byte);
+      }
+    return hex;
+}
diff --git a/src/rl2openjpeg.c b/src/rl2openjpeg.c
new file mode 100644
index 0000000..7fc6d6e
--- /dev/null
+++ b/src/rl2openjpeg.c
@@ -0,0 +1,1642 @@
+/*
+
+ rl2openjpeg -- OpenJPEG (JPEG2000) related functions
+
+ version 0.1, 2014 September 11
+
+ Author: Sandro Furieri a.furieri at lqt.it
+
+ -----------------------------------------------------------------------------
+ 
+ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ 
+ The contents of this file are subject to the Mozilla Public License Version
+ 1.1 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+ 
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the
+License.
+
+The Original Code is the RasterLite2 library
+
+The Initial Developer of the Original Code is Alessandro Furieri
+ 
+Portions created by the Initial Developer are Copyright (C) 2008-2013
+the Initial Developer. All Rights Reserved.
+
+Alternatively, the contents of this file may be used under the terms of
+either the GNU General Public License Version 2 or later (the "GPL"), or
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+in which case the provisions of the GPL or the LGPL are applicable instead
+of those above. If you wish to allow use of your version of this file only
+under the terms of either the GPL or the LGPL, and not to allow others to
+use your version of this file under the terms of the MPL, indicate your
+decision by deleting the provisions above and replace them with the notice
+and other provisions required by the GPL or the LGPL. If you do not delete
+the provisions above, a recipient may use your version of this file under
+the terms of any one of the MPL, the GPL or the LGPL.
+ 
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "config.h"
+
+#ifdef LOADABLE_EXTENSION
+#include "rasterlite2/sqlite.h"
+#endif
+
+#include "rasterlite2/rasterlite2.h"
+#include "rasterlite2/rl2tiff.h"
+#include "rasterlite2_private.h"
+
+#ifndef OMIT_OPENJPEG		/* only if OpenJpeg is enabled */
+
+#ifdef HAVE_OPENJPEG_2_1_OPENJPEG_H
+#include <openjpeg-2.1/openjpeg.h>
+#else
+#ifdef __ANDROID__		/* Android specific */
+#include <openjpeg.h>
+#else
+#include <openjpeg-2.0/openjpeg.h>
+#endif
+#endif
+
+struct jp2_memfile
+{
+/* a struct emulating a file [memory mapped] */
+    unsigned char *buffer;
+    int malloc_block;
+    tsize_t size;
+    tsize_t eof;
+    toff_t current;
+};
+
+static void
+info_callback (const char *msg, void *unused)
+{
+    if (unused != NULL || msg == NULL)
+	unused = NULL;		/* suppressing stupid compiler warnings */
+    /* fprintf (stderr, "OpenJpeg Info: %s\n", msg); */
+}
+
+static void
+warning_callback (const char *msg, void *unused)
+{
+    if (unused != NULL)
+	unused = NULL;		/* suppressing stupid compiler warnings */
+    fprintf (stderr, "OpenJpeg Warning: %s\n", msg);
+}
+
+static void
+error_callback (const char *msg, void *unused)
+{
+    if (unused != NULL)
+	unused = NULL;		/* suppressing stupid compiler warnings */
+    fprintf (stderr, "OpenJpeg Error: %s\n", msg);
+}
+
+static void
+memory_realloc (struct jp2_memfile *mem, tsize_t req_size)
+{
+/* expanding the allocated memory */
+    unsigned char *new_buffer;
+    tsize_t new_size = mem->size;
+    while (new_size <= req_size)
+	new_size += mem->malloc_block;
+    new_buffer = realloc (mem->buffer, new_size);
+    if (!new_buffer)
+	return;
+    mem->buffer = new_buffer;
+    memset (mem->buffer + mem->size, '\0', new_size - mem->size);
+    mem->size = new_size;
+}
+
+static OPJ_SIZE_T
+write_callback (void *buffer, OPJ_SIZE_T size, void *data)
+{
+/* emulating the write()  function */
+    struct jp2_memfile *mem = data;
+    if ((mem->current + size) >= (toff_t) mem->size)
+	memory_realloc (mem, mem->current + size);
+    if ((mem->current + size) >= (toff_t) mem->size)
+	return 0;
+    memcpy (mem->buffer + mem->current, (unsigned char *) buffer, size);
+    mem->current += size;
+    if (mem->current > (toff_t) mem->eof)
+	mem->eof = (tsize_t) (mem->current);
+    return size;
+}
+
+static OPJ_SIZE_T
+read_callback (void *buffer, OPJ_SIZE_T size, void *data)
+{
+/* emulating the read()  function */
+    struct jp2_memfile *mem = data;
+    tsize_t len;
+    if (mem->current >= (toff_t) mem->eof)
+	return 0;
+    len = size;
+    if ((mem->current + size) >= (toff_t) mem->eof)
+	len = (tsize_t) (mem->eof - mem->current);
+    memcpy (buffer, mem->buffer + mem->current, len);
+    mem->current += len;
+    return len;
+}
+
+static OPJ_BOOL
+seek_callback (OPJ_OFF_T offset, void *data)
+{
+/* emulating the lseek()  function */
+    struct jp2_memfile *mem = data;
+    mem->current = offset;
+    if ((toff_t) mem->eof < mem->current)
+	mem->eof = (tsize_t) (mem->current);
+    return 1;
+}
+
+static OPJ_OFF_T
+skip_callback (OPJ_OFF_T size, void *data)
+{
+/* skip  function */
+    struct jp2_memfile *mem = data;
+    mem->current += size;
+    if ((toff_t) mem->eof < mem->current)
+	mem->eof = (tsize_t) (mem->current);
+    return size;
+}
+
+static int
+check_jpeg2000_compatibility (unsigned char sample_type,
+			      unsigned char pixel_type,
+			      unsigned char num_samples)
+{
+/* checks for Jpeg2000 compatibility */
+    switch (sample_type)
+      {
+      case RL2_SAMPLE_UINT8:
+      case RL2_SAMPLE_UINT16:
+	  break;
+      default:
+	  return RL2_ERROR;
+      };
+    switch (pixel_type)
+      {
+      case RL2_PIXEL_GRAYSCALE:
+      case RL2_PIXEL_RGB:
+      case RL2_PIXEL_MULTIBAND:
+      case RL2_PIXEL_DATAGRID:
+	  break;
+      default:
+	  return RL2_ERROR;
+      };
+    if (pixel_type == RL2_PIXEL_GRAYSCALE)
+      {
+	  if (num_samples != 1)
+	      return RL2_ERROR;
+      }
+    if (pixel_type == RL2_PIXEL_DATAGRID)
+      {
+	  if (num_samples != 1)
+	      return RL2_ERROR;
+      }
+    if (pixel_type == RL2_PIXEL_RGB)
+      {
+	  if (num_samples != 3)
+	      return RL2_ERROR;
+      }
+    if (pixel_type == RL2_PIXEL_MULTIBAND)
+      {
+	  if (num_samples != 3 && num_samples != 4)
+	      return RL2_ERROR;
+      }
+    return RL2_OK;
+}
+
+static void
+copy_tile_u16 (unsigned short *tile_buf, rl2PrivRasterPtr rst, int start_x,
+	       int start_y, int tile_w, int tile_h)
+{
+/* preparing an UINT16 Jpeg2000 tile */
+    int x;
+    int y;
+    int ib;
+    unsigned short *p_in;
+    unsigned short *p_out;
+
+    p_out = tile_buf;
+    for (ib = 0; ib < rst->nBands; ib++)
+      {
+	  p_out = tile_buf + (ib * tile_w * tile_h);
+	  for (y = 0; y < tile_h; y++)
+	    {
+		int base_y = start_y + y;
+		if (base_y >= (int) (rst->height))
+		    break;
+		for (x = 0; x < tile_w; x++)
+		  {
+		      int base_x = start_x + x;
+		      if (base_x >= (int) (rst->width))
+			{
+			    p_out++;
+			    continue;
+			}
+		      p_in = (unsigned short *) (rst->rasterBuffer);
+		      p_in +=
+			  (base_y * rst->width * rst->nBands) +
+			  (base_x * rst->nBands) + ib;
+		      *p_out++ = *p_in;
+		  }
+	    }
+      }
+}
+
+static void
+copy_tile_u8 (unsigned char *tile_buf, rl2PrivRasterPtr rst, int start_x,
+	      int start_y, int tile_w, int tile_h)
+{
+/* preparing an UINT8 Jpeg2000 tile */
+    int x;
+    int y;
+    int ib;
+    unsigned char *p_in;
+    unsigned char *p_out;
+
+    p_out = tile_buf;
+    for (ib = 0; ib < rst->nBands; ib++)
+      {
+	  p_out = tile_buf + (ib * tile_w * tile_h);
+	  for (y = 0; y < tile_h; y++)
+	    {
+		int base_y = start_y + y;
+		if (base_y >= (int) (rst->height))
+		    break;
+		for (x = 0; x < tile_w; x++)
+		  {
+		      int base_x = start_x + x;
+		      if (base_x >= (int) (rst->width))
+			{
+			    p_out++;
+			    continue;
+			}
+		      p_in = (unsigned char *) (rst->rasterBuffer);
+		      p_in +=
+			  (base_y * rst->width * rst->nBands) +
+			  (base_x * rst->nBands) + ib;
+		      *p_out++ = *p_in;
+		  }
+	    }
+      }
+}
+
+static int
+compress_jpeg2000 (rl2RasterPtr ptr, unsigned char **jpeg2000,
+		   int *jpeg2000_size, int quality, int lossy)
+{
+/* compressing a Jpeg2000 image */
+    opj_codec_t *codec = NULL;
+    opj_image_t *image = NULL;
+    opj_image_cmptparm_t *band_params = NULL;
+    opj_stream_t *stream = NULL;
+    opj_cparameters_t parameters;
+    OPJ_COLOR_SPACE color_space;
+    int ib;
+    int jp2_tile_x = 1024;
+    int jp2_tile_y = 1024;
+    int x;
+    int y;
+    int tile_no = 0;
+    double rate = 100.0 / (double) quality;
+    void *tile_buf = NULL;
+    int tile_sz;
+    struct jp2_memfile clientdata;
+    rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
+
+    if ((int) (rst->width) < jp2_tile_x)
+	jp2_tile_x = (int) (rst->width);
+    if ((int) (rst->height) < jp2_tile_y)
+	jp2_tile_y = (int) (rst->height);
+/* initializing the memory Write struct */
+    clientdata.buffer = NULL;
+    clientdata.malloc_block = 1024;
+    clientdata.size = 0;
+    clientdata.eof = 0;
+    clientdata.current = 0;
+
+/* creating and initializing the Jpeg2000 codec */
+    codec = opj_create_compress (OPJ_CODEC_JP2);
+    if (codec == NULL)
+	return RL2_ERROR;
+    opj_set_info_handler (codec, info_callback, NULL);
+    opj_set_warning_handler (codec, warning_callback, NULL);
+    opj_set_error_handler (codec, error_callback, NULL);
+
+    band_params = malloc (rst->nBands * sizeof (opj_image_cmptparm_t));
+    for (ib = 0; ib < rst->nBands; ib++)
+      {
+	  band_params[ib].x0 = 0;
+	  band_params[ib].y0 = 0;
+	  band_params[ib].dx = 1;
+	  band_params[ib].dy = 1;
+	  band_params[ib].w = rst->width;
+	  band_params[ib].h = rst->height;
+	  band_params[ib].sgnd = 0;
+	  if (rst->sampleType == RL2_SAMPLE_UINT16)
+	      band_params[ib].prec = 16;
+	  else
+	      band_params[ib].prec = 8;
+      }
+    if (rst->nBands == 1)
+	color_space = OPJ_CLRSPC_GRAY;
+    else
+	color_space = OPJ_CLRSPC_SRGB;
+    image = opj_image_tile_create (rst->nBands, band_params, color_space);
+    free (band_params);
+    band_params = NULL;
+    if (image == NULL)
+      {
+	  fprintf (stderr, "OpenJpeg Error: opj_image_tile_create() failed\n");
+	  opj_destroy_codec (codec);
+	  return RL2_ERROR;
+      }
+    image->x0 = 0;
+    image->y0 = 0;
+    image->x1 = rst->width;
+    image->y1 = rst->height;
+    image->color_space = color_space;
+    image->numcomps = rst->nBands;
+
+    opj_set_default_encoder_parameters (&parameters);
+    parameters.cp_disto_alloc = 1;
+    parameters.tcp_numlayers = 1;
+    parameters.tcp_rates[0] = rate;
+    parameters.cp_tx0 = 0;
+    parameters.cp_ty0 = 0;
+    parameters.tile_size_on = 1;
+    parameters.cp_tdx = jp2_tile_x;
+    parameters.cp_tdy = jp2_tile_y;
+    if (!lossy)
+	parameters.irreversible = 0;
+    else
+	parameters.irreversible = 1;
+    parameters.numresolution = 4;
+    parameters.prog_order = OPJ_LRCP;
+
+    if (!opj_setup_encoder (codec, &parameters, image))
+      {
+	  fprintf (stderr, "OpenJpeg Error: opj_setup_encoder() failed\n");
+	  opj_image_destroy (image);
+	  opj_destroy_codec (codec);
+	  return RL2_ERROR;
+      }
+
+/* preparing the output stream */
+    stream = opj_stream_create (1024 * 1024, 0);
+    opj_stream_set_write_function (stream, write_callback);
+    opj_stream_set_seek_function (stream, seek_callback);
+    opj_stream_set_skip_function (stream, skip_callback);
+#ifdef OPENJPEG_2_1
+    opj_stream_set_user_data (stream, &clientdata, NULL);
+#else
+    opj_stream_set_user_data (stream, &clientdata);
+#endif
+
+    if (!opj_start_compress (codec, image, stream))
+      {
+	  fprintf (stderr, "OpenJpeg Error: opj_start_compress() failed\n");
+	  goto error;
+      }
+
+/* compressing by tiles */
+    if (rst->sampleType == RL2_SAMPLE_UINT16)
+	tile_sz = jp2_tile_x * jp2_tile_y * rst->nBands * 2;
+    else
+	tile_sz = jp2_tile_x * jp2_tile_y * rst->nBands;
+    tile_buf = malloc (tile_sz);
+    memset (tile_buf, 0, tile_sz);
+    for (y = 0; y < (int) (rst->height); y += jp2_tile_y)
+      {
+	  for (x = 0; x < (int) (rst->width); x += jp2_tile_x)
+	    {
+		if (rst->sampleType == RL2_SAMPLE_UINT16)
+		    copy_tile_u16 (tile_buf, rst, x, y, jp2_tile_x, jp2_tile_y);
+		else
+		    copy_tile_u8 (tile_buf, rst, x, y, jp2_tile_x, jp2_tile_y);
+		if (!opj_write_tile
+		    (codec, tile_no++, tile_buf, tile_sz, stream))
+		  {
+		      fprintf (stderr,
+			       "OpenJpeg Error: opj_write_tile() failed\n");
+		      goto error;
+		  }
+	    }
+      }
+    free (tile_buf);
+
+    if (!opj_end_compress (codec, stream))
+      {
+	  fprintf (stderr, "OpenJpeg Error: opj_end_compress() failed\n");
+	  goto error;
+      }
+    opj_stream_destroy (stream);
+    opj_image_destroy (image);
+    opj_destroy_codec (codec);
+
+    *jpeg2000 = clientdata.buffer;
+    *jpeg2000_size = clientdata.eof;
+
+    return RL2_OK;
+
+  error:
+    opj_stream_destroy (stream);
+    opj_image_destroy (image);
+    opj_destroy_codec (codec);
+    if (clientdata.buffer != NULL)
+	free (clientdata.buffer);
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_section_to_lossy_jpeg2000 (rl2SectionPtr scn, const char *path, int quality)
+{
+/* attempting to save a raster section into a Jpeg2000 (lossy) file */
+    int blob_size;
+    unsigned char *blob;
+    rl2RasterPtr rst;
+    int ret;
+
+    if (scn == NULL)
+	return RL2_ERROR;
+    rst = rl2_get_section_raster (scn);
+    if (rst == NULL)
+	return RL2_ERROR;
+/* attempting to export as a Jpeg2000 image */
+    if (rl2_raster_to_lossy_jpeg2000 (rst, &blob, &blob_size, quality) !=
+	RL2_OK)
+	return RL2_ERROR;
+    ret = rl2_blob_to_file (path, blob, blob_size);
+    free (blob);
+    if (ret != RL2_OK)
+	return RL2_ERROR;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_raster_to_lossy_jpeg2000 (rl2RasterPtr rst, unsigned char **jpeg2000,
+			      int *jpeg2000_size, int quality)
+{
+/* creating a Jpeg2000 image (lossy) from a raster */
+    unsigned char sample_type;
+    unsigned char pixel_type;
+    unsigned char num_samples;
+    unsigned char *blob;
+    int blob_size;
+
+    if (rst == NULL)
+	return RL2_ERROR;
+    if (rl2_get_raster_type (rst, &sample_type, &pixel_type, &num_samples) !=
+	RL2_OK)
+	return RL2_ERROR;
+    if (check_jpeg2000_compatibility (sample_type, pixel_type, num_samples) !=
+	RL2_OK)
+	return RL2_ERROR;
+    if (compress_jpeg2000 (rst, &blob, &blob_size, quality, 1) != RL2_OK)
+	return RL2_ERROR;
+    *jpeg2000 = blob;
+    *jpeg2000_size = blob_size;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_section_to_lossless_jpeg2000 (rl2SectionPtr scn, const char *path)
+{
+/* attempting to save a raster section into a Jpeg2000 (lossless) file */
+    int blob_size;
+    unsigned char *blob;
+    rl2RasterPtr rst;
+    int ret;
+
+    if (scn == NULL)
+	return RL2_ERROR;
+    rst = rl2_get_section_raster (scn);
+    if (rst == NULL)
+	return RL2_ERROR;
+/* attempting to export as a Jpeg2000 image */
+    if (rl2_raster_to_lossless_jpeg2000 (rst, &blob, &blob_size) != RL2_OK)
+	return RL2_ERROR;
+    ret = rl2_blob_to_file (path, blob, blob_size);
+    free (blob);
+    if (ret != RL2_OK)
+	return RL2_ERROR;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_raster_to_lossless_jpeg2000 (rl2RasterPtr rst, unsigned char **jpeg2000,
+				 int *jpeg2000_size)
+{
+/* creating a Jpeg2000 image (lossless) from a raster */
+    unsigned char sample_type;
+    unsigned char pixel_type;
+    unsigned char num_samples;
+    unsigned char *blob;
+    int blob_size;
+
+    if (rst == NULL)
+	return RL2_ERROR;
+    if (rl2_get_raster_type (rst, &sample_type, &pixel_type, &num_samples) !=
+	RL2_OK)
+	return RL2_ERROR;
+    if (check_jpeg2000_compatibility (sample_type, pixel_type, num_samples) !=
+	RL2_OK)
+	return RL2_ERROR;
+    if (compress_jpeg2000 (rst, &blob, &blob_size, 100, 0) != RL2_OK)
+	return RL2_ERROR;
+    *jpeg2000 = blob;
+    *jpeg2000_size = blob_size;
+    return RL2_OK;
+}
+
+RL2_DECLARE rl2SectionPtr
+rl2_section_from_jpeg2000 (const char *path, unsigned char sample_type,
+			   unsigned char pixel_type, unsigned char num_bands)
+{
+/* attempting to create a raster section from a Jpeg2000 file */
+    int blob_size;
+    unsigned char *blob;
+    rl2SectionPtr scn;
+    rl2RasterPtr rst;
+
+/* attempting to create a raster */
+    if (rl2_blob_from_file (path, &blob, &blob_size) != RL2_OK)
+	return NULL;
+    rst =
+	rl2_raster_from_jpeg2000 (blob, blob_size, sample_type, pixel_type,
+				  num_bands);
+    free (blob);
+    if (rst == NULL)
+	return NULL;
+
+/* creating the raster section */
+    scn =
+	rl2_create_section (path, RL2_COMPRESSION_LOSSY_JP2,
+			    RL2_TILESIZE_UNDEFINED, RL2_TILESIZE_UNDEFINED,
+			    rst);
+    return scn;
+}
+
+RL2_DECLARE rl2RasterPtr
+rl2_raster_from_jpeg2000 (const unsigned char *jpeg2000, int jpeg2000_size,
+			  unsigned char sample_type, unsigned char pixel_type,
+			  unsigned char num_bands)
+{
+/* attempting to create a raster from a Jpeg2000 image */
+    rl2RasterPtr rst = NULL;
+    unsigned char *buf;
+    int buf_size;
+    unsigned int width;
+    unsigned int height;
+
+    if (rl2_decode_jpeg2000_scaled
+	(1, jpeg2000, jpeg2000_size, &width, &height, sample_type, pixel_type,
+	 num_bands, &buf, &buf_size) != RL2_OK)
+	return NULL;
+
+/* creating the raster */
+    rst =
+	rl2_create_raster (width, height, sample_type, pixel_type, num_bands,
+			   buf, buf_size, NULL, NULL, 0, NULL);
+    if (rst == NULL)
+      {
+	  free (buf);
+      }
+    return rst;
+}
+
+static void
+save_tile_u16 (unsigned short *buf, unsigned short *jp2_data, int start_x,
+	       int start_y, int end_x, int end_y, int num_bands, int width,
+	       int height)
+{
+/* copying pixels from a Jpeg2000 tile into the output raster - UINT16 */
+    int x;
+    int y;
+    int ib;
+    unsigned short *p_in = jp2_data;
+    unsigned short *p_out;
+
+    for (ib = 0; ib < num_bands; ib++)
+      {
+	  for (y = start_y; y < end_y; y++)
+	    {
+		if (y >= height)
+		  {
+		      for (x = start_x; x < end_x; x++)
+			  p_in++;
+		      continue;
+		  }
+		for (x = start_x; x < end_x; x++)
+		  {
+		      if (x >= width)
+			{
+			    p_in++;
+			    continue;
+			}
+		      p_out =
+			  buf + (y * width * num_bands) + (x * num_bands) + ib;
+		      *p_out = *p_in++;
+		  }
+	    }
+      }
+}
+
+static void
+save_tile_u8 (unsigned char *buf, unsigned char *jp2_data, int start_x,
+	      int start_y, int end_x, int end_y, int num_bands, int width,
+	      int height)
+{
+/* copying pixels from a Jpeg2000 tile into the output raster - UINT8 */
+    int x;
+    int y;
+    int ib;
+    unsigned char *p_in = jp2_data;
+    unsigned char *p_out;
+
+    for (ib = 0; ib < num_bands; ib++)
+      {
+	  for (y = start_y; y < end_y; y++)
+	    {
+		if (y >= height)
+		  {
+		      for (x = start_x; x < end_x; x++)
+			  p_in++;
+		      continue;
+		  }
+		for (x = start_x; x < end_x; x++)
+		  {
+		      if (x >= width)
+			{
+			    p_in++;
+			    continue;
+			}
+		      p_out =
+			  buf + (y * width * num_bands) + (x * num_bands) + ib;
+		      *p_out = *p_in++;
+		  }
+	    }
+      }
+}
+
+RL2_PRIVATE int
+rl2_decode_jpeg2000_scaled (int scale, const unsigned char *jpeg2000,
+			    int jpeg2000_sz, unsigned int *xwidth,
+			    unsigned int *xheight, unsigned char xsample_type,
+			    unsigned char xpixel_type,
+			    unsigned char xnum_bands, unsigned char **pixels,
+			    int *pixels_size)
+{
+/* attempting to create a raster from a Jpeg2000 image - supporting rescaled size */
+    unsigned char *buf = NULL;
+    int buf_size = 0;
+    unsigned int width;
+    unsigned int height;
+    unsigned char sample_type = RL2_SAMPLE_UNKNOWN;
+    unsigned char pixel_type = RL2_PIXEL_UNKNOWN;
+    unsigned char num_bands;
+    unsigned char sample_sz = 1;
+    struct jp2_memfile clientdata;
+    opj_codec_t *codec;
+    opj_dparameters_t parameters;
+    opj_stream_t *stream;
+    opj_image_t *image = NULL;
+    opj_codestream_info_v2_t *code_stream_info;
+    OPJ_UINT32 nComponents;
+    OPJ_UINT32 tile_index;
+    OPJ_UINT32 data_size;
+    OPJ_INT32 tile_x0;
+    OPJ_INT32 tile_y0;
+    OPJ_INT32 tile_x1;
+    OPJ_INT32 tile_y1;
+    OPJ_UINT32 nb_comps;
+    OPJ_BOOL should_go_on;
+    OPJ_BYTE *jp2_data = NULL;
+    int nResolutions;
+    int level;
+
+    if (scale == 1)
+	level = 0;
+    else if (scale == 2)
+	level = 1;
+    else if (scale == 4)
+	level = 2;
+    else if (scale == 8)
+	level = 3;
+    else
+	return RL2_ERROR;
+
+/* creating and initializing the Jpeg2000 decoder */
+    codec = opj_create_decompress (OPJ_CODEC_JP2);
+    opj_set_info_handler (codec, info_callback, NULL);
+    opj_set_warning_handler (codec, warning_callback, NULL);
+    opj_set_error_handler (codec, error_callback, NULL);
+    opj_set_default_decoder_parameters (&parameters);
+    if (!opj_setup_decoder (codec, &parameters))
+	return RL2_ERROR;
+
+/* preparing the input stream */
+    stream = opj_stream_create (1024, 1);
+    opj_stream_set_user_data_length (stream, jpeg2000_sz);
+    opj_stream_set_read_function (stream, read_callback);
+    opj_stream_set_seek_function (stream, seek_callback);
+    opj_stream_set_skip_function (stream, skip_callback);
+/* initializing the memory Read struct */
+    clientdata.buffer = (unsigned char *) jpeg2000;
+    clientdata.malloc_block = 1024;
+    clientdata.size = jpeg2000_sz;
+    clientdata.eof = jpeg2000_sz;
+    clientdata.current = 0;
+#ifdef OPENJPEG_2_1
+    opj_stream_set_user_data (stream, &clientdata, NULL);
+#else
+    opj_stream_set_user_data (stream, &clientdata);
+#endif
+    if (!opj_read_header (stream, codec, &image))
+      {
+	  fprintf (stderr, "OpenJpeg Error: opj_read_header() failed\n");
+	  goto error;
+      }
+    code_stream_info = opj_get_cstr_info (codec);
+    nComponents = code_stream_info->nbcomps;
+    nResolutions =
+	code_stream_info->m_default_tile_info.tccp_info[0].numresolutions;
+    opj_destroy_cstr_info (&code_stream_info);
+    if (image == NULL)
+	goto error;
+    if (nResolutions < 4)
+	goto error;
+    if (image->comps[0].prec == 16 && image->comps[0].sgnd == 0)
+	sample_type = RL2_SAMPLE_UINT16;
+    if (image->comps[0].prec == 8 && image->comps[0].sgnd == 0)
+	sample_type = RL2_SAMPLE_UINT8;
+    if (nComponents == 1)
+      {
+	  if (sample_type == RL2_SAMPLE_UINT16)
+	      pixel_type = RL2_PIXEL_DATAGRID;
+	  if (sample_type == RL2_SAMPLE_UINT8)
+	    {
+		pixel_type = RL2_PIXEL_GRAYSCALE;
+		if (xpixel_type == RL2_PIXEL_DATAGRID)
+		    pixel_type = RL2_PIXEL_DATAGRID;
+	    }
+	  num_bands = 1;
+      }
+    if (nComponents == 3)
+      {
+	  pixel_type = RL2_PIXEL_RGB;
+	  if (xpixel_type == RL2_PIXEL_MULTIBAND)
+	      pixel_type = RL2_PIXEL_MULTIBAND;
+	  num_bands = 3;
+      }
+    if (nComponents == 4)
+      {
+	  pixel_type = RL2_PIXEL_MULTIBAND;
+	  num_bands = 4;
+      }
+    if (sample_type != xsample_type || pixel_type != xpixel_type
+	|| num_bands != xnum_bands)
+	goto error;
+
+/* validating the Sample and Pixel types */
+    if (sample_type == RL2_SAMPLE_UNKNOWN || pixel_type != xpixel_type)
+      {
+	  fprintf (stderr,
+		   "OpenJpeg Error: invalid Sample/Pixel/Bands layout\n");
+	  goto error;
+      }
+    width = image->comps[0].w;
+    height = image->comps[0].h;
+    if (!opj_set_decoded_resolution_factor (codec, level))
+      {
+	  fprintf (stderr,
+		   "OpenJpeg Error: opj_set_decoded_resolution_factor() failed");
+	  goto error;
+      }
+
+/* allocating the raster buffer */
+    if (sample_type == RL2_SAMPLE_UINT16)
+	sample_sz = 2;
+    buf_size = (width / scale) * (height / scale) * num_bands * sample_sz;
+    buf = malloc (buf_size);
+    memset (buf, 0, buf_size);
+
+    while (1)
+      {
+	  /* decoding one JP2 tile at each time */
+	  if (!opj_read_tile_header
+	      (codec, stream, &tile_index, &data_size, &tile_x0, &tile_y0,
+	       &tile_x1, &tile_y1, &nb_comps, &should_go_on))
+	    {
+		fprintf (stderr,
+			 "OpenJpeg Error: opj_read_tile_header() failed\n");
+		goto error;
+	    }
+	  if (!should_go_on)
+	      break;
+	  if (nb_comps != num_bands)
+	    {
+		fprintf (stderr, "OpenJpeg Error: unexpected nb_comps !!!\n");
+		goto error;
+	    }
+	  jp2_data = malloc (data_size);
+	  if (!opj_decode_tile_data
+	      (codec, tile_index, jp2_data, data_size, stream))
+	    {
+		fprintf (stderr,
+			 "OpenJpeg Error: opj_decode_tile_data() failed\n");
+		goto error;
+	    }
+	  if (sample_type == RL2_SAMPLE_UINT16)
+	      save_tile_u16 ((unsigned short *) buf,
+			     (unsigned short *) jp2_data, tile_x0 / scale,
+			     tile_y0 / scale, tile_x1 / scale,
+			     tile_y1 / scale, num_bands, width / scale,
+			     height / scale);
+	  else
+	      save_tile_u8 ((unsigned char *) buf, (unsigned char *) jp2_data,
+			    tile_x0 / scale, tile_y0 / scale, tile_x1 / scale,
+			    tile_y1 / scale, num_bands, width / scale,
+			    height / scale);
+	  free (jp2_data);
+	  jp2_data = NULL;
+      }
+
+    opj_destroy_codec (codec);
+    opj_stream_destroy (stream);
+    opj_image_destroy (image);
+
+    *xwidth = width / scale;
+    *xheight = height / scale;
+    *pixels = buf;
+    *pixels_size = buf_size;
+    return RL2_OK;
+
+  error:
+    if (buf != NULL)
+	free (buf);
+    if (jp2_data != NULL)
+	free (jp2_data);
+    opj_destroy_codec (codec);
+    opj_stream_destroy (stream);
+    opj_image_destroy (image);
+    return RL2_ERROR;
+}
+
+static int
+eval_jpeg2000_origin_compatibility (rl2PrivCoveragePtr coverage,
+				    rl2PrivRasterPtr raster,
+				    unsigned char forced_conversion,
+				    int verbose)
+{
+/* checking for strict compatibility */
+    if (coverage->sampleType == RL2_SAMPLE_UINT8
+	&& coverage->pixelType == RL2_PIXEL_GRAYSCALE && coverage->nBands == 1)
+      {
+	  if (raster->sampleType == RL2_SAMPLE_UINT8
+	      && raster->pixelType == RL2_PIXEL_GRAYSCALE
+	      && raster->nBands == 1 && forced_conversion == RL2_CONVERT_NO)
+	      return 1;
+	  if (raster->sampleType == RL2_SAMPLE_UINT8
+	      && raster->pixelType == RL2_PIXEL_RGB && raster->nBands == 3
+	      && forced_conversion == RL2_CONVERT_RGB_TO_GRAYSCALE)
+	      return 1;
+      }
+    if (coverage->sampleType == RL2_SAMPLE_UINT8
+	&& coverage->pixelType == RL2_PIXEL_RGB && coverage->nBands == 3)
+      {
+	  if (raster->sampleType == RL2_SAMPLE_UINT8
+	      && raster->pixelType == RL2_PIXEL_RGB && raster->nBands == 3
+	      && forced_conversion == RL2_CONVERT_NO)
+	      return 1;
+	  if (raster->sampleType == RL2_SAMPLE_UINT8
+	      && raster->pixelType == RL2_PIXEL_GRAYSCALE
+	      && raster->nBands == 1
+	      && forced_conversion == RL2_CONVERT_GRAYSCALE_TO_RGB)
+	      return 1;
+      }
+    if (coverage->sampleType == RL2_SAMPLE_UINT8
+	&& coverage->pixelType == RL2_PIXEL_DATAGRID && coverage->nBands == 1)
+      {
+	  if (raster->sampleType == RL2_SAMPLE_UINT8
+	      && raster->pixelType == RL2_PIXEL_DATAGRID
+	      && raster->nBands == 1 && forced_conversion == RL2_CONVERT_NO)
+	      return 1;
+      }
+    if (coverage->sampleType == RL2_SAMPLE_UINT8
+	&& coverage->pixelType == RL2_PIXEL_MULTIBAND
+	&& (coverage->nBands == 3 || coverage->nBands == 4))
+      {
+	  if (raster->sampleType == RL2_SAMPLE_UINT8
+	      && raster->pixelType == RL2_PIXEL_MULTIBAND
+	      && raster->nBands == coverage->nBands
+	      && forced_conversion == RL2_CONVERT_NO)
+	      return 1;
+      }
+    if (coverage->sampleType == RL2_SAMPLE_UINT16
+	&& coverage->pixelType == RL2_PIXEL_DATAGRID && coverage->nBands == 1)
+      {
+	  if (raster->sampleType == RL2_SAMPLE_UINT16
+	      && raster->pixelType == RL2_PIXEL_DATAGRID
+	      && raster->nBands == 1 && forced_conversion == RL2_CONVERT_NO)
+	      return 1;
+      }
+    if (coverage->sampleType == RL2_SAMPLE_UINT16
+	&& coverage->pixelType == RL2_PIXEL_RGB && coverage->nBands == 3)
+      {
+	  if (raster->sampleType == RL2_SAMPLE_UINT16
+	      && raster->pixelType == RL2_PIXEL_RGB && raster->nBands == 3
+	      && forced_conversion == RL2_CONVERT_NO)
+	      return 1;
+      }
+    if (coverage->sampleType == RL2_SAMPLE_UINT16
+	&& coverage->pixelType == RL2_PIXEL_MULTIBAND
+	&& (coverage->nBands == 3 || coverage->nBands == 4))
+      {
+	  if (raster->sampleType == RL2_SAMPLE_UINT16
+	      && raster->pixelType == RL2_PIXEL_MULTIBAND
+	      && raster->nBands == coverage->nBands
+	      && forced_conversion == RL2_CONVERT_NO)
+	      return 1;
+      }
+    if (verbose)
+	fprintf (stderr, "Mismatching Jpeg2000 colorspace !!!\n");
+    return 0;
+}
+
+static int
+read_jpeg2000_pixels_gray_to_rgb (rl2PrivRasterPtr origin,
+				  unsigned short width, unsigned short height,
+				  unsigned int startRow,
+				  unsigned int startCol, unsigned char *pixels)
+{
+/* Grayscale -> RGB */
+    unsigned short x;
+    unsigned short y;
+    unsigned short row;
+    unsigned short col;
+    for (y = 0, row = startRow; y < height && row < origin->height; y++, row++)
+      {
+	  /* looping on rows */
+	  unsigned char *p_out = pixels + (y * width * 3);
+	  unsigned char *p_in_base =
+	      origin->rasterBuffer + (row * origin->width);
+	  for (x = 0, col = startCol; x < width && col < origin->width;
+	       x++, col++)
+	    {
+		unsigned char *p_in = p_in_base + col;
+		unsigned char value = *p_in;
+		*p_out++ = value;	/* red */
+		*p_out++ = value;	/* green */
+		*p_out++ = value;	/* blue */
+	    }
+      }
+    return 1;
+}
+
+static int
+read_jpeg2000_pixels_rgb_to_gray (rl2PrivRasterPtr origin,
+				  unsigned short width, unsigned short height,
+				  unsigned int startRow,
+				  unsigned int startCol, unsigned char *pixels)
+{
+/* RGB -> Grayscale */
+    unsigned short x;
+    unsigned short y;
+    unsigned short row;
+    unsigned short col;
+    for (y = 0, row = startRow; y < height && row < origin->height; y++, row++)
+      {
+	  /* looping on rows */
+	  unsigned char *p_out = pixels + (y * width);
+	  unsigned char *p_in_base =
+	      origin->rasterBuffer + (row * origin->width * 3);
+	  for (x = 0, col = startCol; x < width && col < origin->width;
+	       x++, col++)
+	    {
+		unsigned char *p_in = p_in_base + (col * 3);
+		unsigned char r = *p_in++;
+		unsigned char g = *p_in++;
+		unsigned char b = *p_in++;
+		double gray =
+		    ((double) r * 0.2126) + ((double) g * 0.7152) +
+		    ((double) b * 0.0722);
+		*p_out++ = (unsigned char) gray;
+	    }
+      }
+    return 1;
+}
+
+static int
+read_jpeg2000_pixels_u8 (rl2PrivRasterPtr origin, unsigned short width,
+			 unsigned short height, unsigned int startRow,
+			 unsigned int startCol, unsigned char *pixels,
+			 int num_bands)
+{
+/* no coversion - UINT8 */
+    unsigned short x;
+    unsigned short y;
+    int ib;
+    unsigned short row;
+    unsigned short col;
+    for (y = 0, row = startRow; y < height && row < origin->height; y++, row++)
+      {
+	  /* looping on rows */
+	  unsigned char *p_out = pixels + (y * width * num_bands);
+	  unsigned char *p_in_base =
+	      origin->rasterBuffer + (row * origin->width * num_bands);
+	  for (x = 0, col = startCol; x < width && col < origin->width;
+	       x++, col++)
+	    {
+		unsigned char *p_in = p_in_base + (col * num_bands);
+		for (ib = 0; ib < num_bands; ib++)
+		    *p_out++ = *p_in++;
+	    }
+      }
+    return 1;
+}
+
+static int
+read_jpeg2000_pixels_u16 (rl2PrivRasterPtr origin, unsigned short width,
+			  unsigned short height, unsigned int startRow,
+			  unsigned int startCol, unsigned short *pixels,
+			  int num_bands)
+{
+/* no coversion - UINT16 */
+    unsigned short x;
+    unsigned short y;
+    int ib;
+    unsigned short row;
+    unsigned short col;
+    for (y = 0, row = startRow; y < height && row < origin->height; y++, row++)
+      {
+	  /* looping on rows */
+	  unsigned short *p_out = pixels + (y * width * num_bands);
+	  unsigned short *p_in_base =
+	      (unsigned short *) (origin->rasterBuffer) +
+	      (row * origin->width * num_bands);
+	  for (x = 0, col = startCol; x < width && col < origin->width;
+	       x++, col++)
+	    {
+		unsigned short *p_in = p_in_base + (col * num_bands);
+		for (ib = 0; ib < num_bands; ib++)
+		    *p_out++ = *p_in++;
+	    }
+      }
+    return 1;
+}
+
+static int
+read_from_jpeg2000 (rl2PrivRasterPtr origin, unsigned short width,
+		    unsigned short height, unsigned char sample_type,
+		    unsigned char pixel_type, unsigned char num_bands,
+		    unsigned char forced_conversion, unsigned int startRow,
+		    unsigned int startCol, unsigned char **pixels,
+		    int *pixels_sz)
+{
+/* creating a tile from the Jpeg2000 origin */
+    int nb;
+    unsigned char *bufPixels = NULL;
+    int bufPixelsSz = 0;
+    rl2PixelPtr no_data = NULL;
+
+    no_data = rl2_create_pixel (sample_type, pixel_type, num_bands);
+    if (sample_type == RL2_SAMPLE_UINT8
+	&& (pixel_type == RL2_PIXEL_RGB || pixel_type == RL2_PIXEL_GRAYSCALE))
+      {
+	  for (nb = 0; nb < num_bands; nb++)
+	      rl2_set_pixel_sample_uint8 (no_data, nb, 255);
+      }
+    else
+      {
+	  if (sample_type == RL2_SAMPLE_UINT8)
+	    {
+		for (nb = 0; nb < num_bands; nb++)
+		    rl2_set_pixel_sample_uint8 (no_data, nb, 0);
+	    }
+	  if (sample_type == RL2_SAMPLE_UINT16)
+	    {
+		for (nb = 0; nb < num_bands; nb++)
+		    rl2_set_pixel_sample_uint16 (no_data, nb, 0);
+	    }
+      }
+
+/* allocating the pixels buffer */
+    bufPixelsSz = width * height * num_bands;
+    bufPixels = malloc (bufPixelsSz);
+    if (bufPixels == NULL)
+	goto error;
+    if ((startRow + height) > origin->height
+	|| (startCol + width) > origin->width)
+	rl2_prime_void_tile (bufPixels, width, height, sample_type, num_bands,
+			     no_data);
+
+
+    if (pixel_type == RL2_PIXEL_GRAYSCALE && sample_type == RL2_SAMPLE_UINT8
+	&& num_bands == 1 && forced_conversion == RL2_CONVERT_RGB_TO_GRAYSCALE)
+      {
+	  if (!read_jpeg2000_pixels_rgb_to_gray
+	      (origin, width, height, startRow, startCol, bufPixels))
+	      goto error;
+      }
+    else if (pixel_type == RL2_PIXEL_RGB && sample_type == RL2_SAMPLE_UINT8
+	     && num_bands == 3
+	     && forced_conversion == RL2_CONVERT_GRAYSCALE_TO_RGB)
+      {
+	  if (!read_jpeg2000_pixels_gray_to_rgb
+	      (origin, width, height, startRow, startCol, bufPixels))
+	      goto error;
+      }
+    else if (forced_conversion == RL2_CONVERT_NO)
+      {
+	  if (sample_type == RL2_SAMPLE_UINT8)
+	    {
+		if (!read_jpeg2000_pixels_u8
+		    (origin, width, height, startRow, startCol, bufPixels,
+		     num_bands))
+		    goto error;
+	    }
+	  else if (sample_type == RL2_SAMPLE_UINT16)
+	    {
+		if (!read_jpeg2000_pixels_u16
+		    (origin, width, height, startRow, startCol,
+		     (unsigned short *) bufPixels, num_bands))
+		    goto error;
+	    }
+	  else
+	      goto error;
+      }
+    else
+	goto error;
+    if (no_data != NULL)
+	rl2_destroy_pixel (no_data);
+
+    *pixels = bufPixels;
+    *pixels_sz = bufPixelsSz;
+    return RL2_OK;
+  error:
+    if (bufPixels != NULL)
+	free (bufPixels);
+    if (no_data != NULL)
+	rl2_destroy_pixel (no_data);
+    return RL2_ERROR;
+}
+
+RL2_DECLARE rl2RasterPtr
+rl2_get_tile_from_jpeg2000_origin (rl2CoveragePtr cvg, rl2RasterPtr jpeg2000,
+				   unsigned int startRow,
+				   unsigned int startCol,
+				   unsigned char forced_conversion, int verbose)
+{
+/* attempting to create a Coverage-tile from a Jpeg2000 origin */
+    unsigned int x;
+    rl2PrivCoveragePtr coverage = (rl2PrivCoveragePtr) cvg;
+    rl2PrivRasterPtr origin = (rl2PrivRasterPtr) jpeg2000;
+    rl2RasterPtr raster = NULL;
+    unsigned char *pixels = NULL;
+    int pixels_sz = 0;
+    unsigned char *mask = NULL;
+    int mask_size = 0;
+    unsigned int unused_width = 0;
+    unsigned int unused_height = 0;
+
+    if (coverage == NULL || origin == NULL)
+	return NULL;
+    if (!eval_jpeg2000_origin_compatibility
+	(coverage, origin, forced_conversion, verbose))
+	return NULL;
+
+/* testing for tile's boundary validity */
+    if (startCol > origin->width)
+	return NULL;
+    if (startRow > origin->height)
+	return NULL;
+    x = startCol / coverage->tileWidth;
+    if ((x * coverage->tileWidth) != startCol)
+	return NULL;
+    x = startRow / coverage->tileHeight;
+    if ((x * coverage->tileHeight) != startRow)
+	return NULL;
+
+/* attempting to create the tile */
+    if (read_from_jpeg2000
+	(origin, coverage->tileWidth, coverage->tileHeight,
+	 coverage->sampleType, coverage->pixelType, coverage->nBands,
+	 forced_conversion, startRow, startCol, &pixels, &pixels_sz) != RL2_OK)
+	goto error;
+    if (startCol + coverage->tileWidth > origin->width)
+	unused_width = (startCol + coverage->tileWidth) - origin->width;
+    if (startRow + coverage->tileHeight > origin->height)
+	unused_height = (startRow + coverage->tileHeight) - origin->height;
+    if (unused_width || unused_height)
+      {
+	  /* 
+	   * creating a Transparency Mask so to shadow any 
+	   * unused portion of the current tile 
+	   */
+	  unsigned int shadow_x = coverage->tileWidth - unused_width;
+	  unsigned int shadow_y = coverage->tileHeight - unused_height;
+	  unsigned int row;
+	  mask_size = coverage->tileWidth * coverage->tileHeight;
+	  mask = malloc (mask_size);
+	  if (mask == NULL)
+	      goto error;
+	  /* full Transparent mask */
+	  memset (mask, 0, coverage->tileWidth * coverage->tileHeight);
+	  for (row = 0; row < coverage->tileHeight; row++)
+	    {
+		unsigned char *p = mask + (row * coverage->tileWidth);
+		if (row < shadow_y)
+		  {
+		      /* setting opaque pixels */
+		      memset (p, 1, shadow_x);
+		  }
+	    }
+      }
+    raster =
+	rl2_create_raster (coverage->tileWidth, coverage->tileHeight,
+			   coverage->sampleType, coverage->pixelType,
+			   coverage->nBands, pixels, pixels_sz, NULL, mask,
+			   mask_size, NULL);
+    if (raster == NULL)
+	goto error;
+    return raster;
+  error:
+    if (pixels != NULL)
+	free (pixels);
+    if (mask != NULL)
+	free (mask);
+    return NULL;
+}
+
+RL2_DECLARE int
+rl2_get_jpeg2000_infos (const char *path, unsigned int *xwidth,
+			unsigned int *xheight, unsigned char *xsample_type,
+			unsigned char *xpixel_type, unsigned char *xnum_bands,
+			unsigned int *xtile_width, unsigned int *xtile_height,
+			unsigned char *num_levels)
+{
+/* attempting to retrieve the basic infos about some Jpeg2000 */
+    unsigned char *jpeg2000 = NULL;
+    int jpeg2000_sz;
+    unsigned int width;
+    unsigned int height;
+    unsigned char sample_type = RL2_SAMPLE_UNKNOWN;
+    unsigned char pixel_type = RL2_PIXEL_UNKNOWN;
+    struct jp2_memfile clientdata;
+    opj_codec_t *codec;
+    opj_dparameters_t parameters;
+    opj_stream_t *stream;
+    opj_image_t *image = NULL;
+    opj_codestream_info_v2_t *code_stream_info;
+    OPJ_UINT32 nComponents;
+    OPJ_INT32 tile_width;
+    OPJ_INT32 tile_height;
+    int nResolutions;
+
+/* loading in memory the Jpeg2000 raster */
+    if (rl2_blob_from_file (path, &jpeg2000, &jpeg2000_sz) != RL2_OK)
+	return RL2_ERROR;
+
+/* creating and initializing the Jpeg2000 decoder */
+    codec = opj_create_decompress (OPJ_CODEC_JP2);
+    opj_set_info_handler (codec, info_callback, NULL);
+    opj_set_warning_handler (codec, warning_callback, NULL);
+    opj_set_error_handler (codec, error_callback, NULL);
+    opj_set_default_decoder_parameters (&parameters);
+    if (!opj_setup_decoder (codec, &parameters))
+	return RL2_ERROR;
+
+/* preparing the input stream */
+    stream = opj_stream_create (1024, 1);
+    opj_stream_set_user_data_length (stream, jpeg2000_sz);
+    opj_stream_set_read_function (stream, read_callback);
+    opj_stream_set_seek_function (stream, seek_callback);
+    opj_stream_set_skip_function (stream, skip_callback);
+/* initializing the memory Read struct */
+    clientdata.buffer = (unsigned char *) jpeg2000;
+    clientdata.malloc_block = 1024;
+    clientdata.size = jpeg2000_sz;
+    clientdata.eof = jpeg2000_sz;
+    clientdata.current = 0;
+#ifdef OPENJPEG_2_1
+    opj_stream_set_user_data (stream, &clientdata, NULL);
+#else
+    opj_stream_set_user_data (stream, &clientdata);
+#endif
+    if (!opj_read_header (stream, codec, &image))
+      {
+	  fprintf (stderr, "OpenJpeg Error: opj_read_header() failed\n");
+	  goto error;
+      }
+    code_stream_info = opj_get_cstr_info (codec);
+    tile_width = code_stream_info->tdx;
+    tile_height = code_stream_info->tdy;
+    nComponents = code_stream_info->nbcomps;
+    nResolutions =
+	code_stream_info->m_default_tile_info.tccp_info[0].numresolutions;
+    opj_destroy_cstr_info (&code_stream_info);
+    if (image == NULL)
+	goto error;
+    if (nResolutions < 4)
+	goto error;
+    if (image->comps[0].prec == 16 && image->comps[0].sgnd == 0)
+	sample_type = RL2_SAMPLE_UINT16;
+    if (image->comps[0].prec == 8 && image->comps[0].sgnd == 0)
+	sample_type = RL2_SAMPLE_UINT8;
+    if (nComponents == 1)
+      {
+	  if (sample_type == RL2_SAMPLE_UINT16)
+	      pixel_type = RL2_PIXEL_DATAGRID;
+	  if (sample_type == RL2_SAMPLE_UINT8)
+	      pixel_type = RL2_PIXEL_GRAYSCALE;
+      }
+    if (nComponents == 3)
+	pixel_type = RL2_PIXEL_RGB;
+    if (nComponents == 4)
+	pixel_type = RL2_PIXEL_MULTIBAND;
+    width = image->comps[0].w;
+    height = image->comps[0].h;
+
+    opj_destroy_codec (codec);
+    opj_stream_destroy (stream);
+    opj_image_destroy (image);
+    free (jpeg2000);
+
+    *xwidth = width;
+    *xheight = height;
+    *xsample_type = sample_type;
+    *xpixel_type = pixel_type;
+    *xnum_bands = nComponents;
+    *xtile_width = tile_width;
+    *xtile_height = tile_height;
+    *num_levels = nResolutions;
+    return RL2_OK;
+
+  error:
+    opj_destroy_codec (codec);
+    opj_stream_destroy (stream);
+    opj_image_destroy (image);
+    if (jpeg2000 != NULL)
+	free (jpeg2000);
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_get_jpeg2000_blob_type (const unsigned char *jpeg2000, int jpeg2000_sz,
+			    unsigned char *xsample_type,
+			    unsigned char *xpixel_type,
+			    unsigned char *xnum_bands)
+{
+/* attempting to retrieve the basic infos about some Jpeg2000 - BLOB version */
+    unsigned char sample_type = RL2_SAMPLE_UNKNOWN;
+    unsigned char pixel_type = RL2_PIXEL_UNKNOWN;
+    struct jp2_memfile clientdata;
+    opj_codec_t *codec;
+    opj_dparameters_t parameters;
+    opj_stream_t *stream;
+    opj_image_t *image = NULL;
+    opj_codestream_info_v2_t *code_stream_info;
+    OPJ_UINT32 nComponents;
+
+/* creating and initializing the Jpeg2000 decoder */
+    codec = opj_create_decompress (OPJ_CODEC_JP2);
+    opj_set_info_handler (codec, info_callback, NULL);
+    opj_set_warning_handler (codec, warning_callback, NULL);
+    opj_set_error_handler (codec, error_callback, NULL);
+    opj_set_default_decoder_parameters (&parameters);
+    if (!opj_setup_decoder (codec, &parameters))
+	return RL2_ERROR;
+
+/* preparing the input stream */
+    stream = opj_stream_create (1024, 1);
+    opj_stream_set_user_data_length (stream, jpeg2000_sz);
+    opj_stream_set_read_function (stream, read_callback);
+    opj_stream_set_seek_function (stream, seek_callback);
+    opj_stream_set_skip_function (stream, skip_callback);
+/* initializing the memory Read struct */
+    clientdata.buffer = (unsigned char *) jpeg2000;
+    clientdata.malloc_block = 1024;
+    clientdata.size = jpeg2000_sz;
+    clientdata.eof = jpeg2000_sz;
+    clientdata.current = 0;
+#ifdef OPENJPEG_2_1
+    opj_stream_set_user_data (stream, &clientdata, NULL);
+#else
+    opj_stream_set_user_data (stream, &clientdata);
+#endif
+    if (!opj_read_header (stream, codec, &image))
+      {
+	  fprintf (stderr, "OpenJpeg Error: opj_read_header() failed\n");
+	  goto error;
+      }
+    code_stream_info = opj_get_cstr_info (codec);
+    nComponents = code_stream_info->nbcomps;
+    opj_destroy_cstr_info (&code_stream_info);
+    if (image == NULL)
+	goto error;
+    if (image->comps[0].prec == 16 && image->comps[0].sgnd == 0)
+	sample_type = RL2_SAMPLE_UINT16;
+    if (image->comps[0].prec == 8 && image->comps[0].sgnd == 0)
+	sample_type = RL2_SAMPLE_UINT8;
+    if (nComponents == 1)
+      {
+	  if (sample_type == RL2_SAMPLE_UINT16)
+	      pixel_type = RL2_PIXEL_DATAGRID;
+	  if (sample_type == RL2_SAMPLE_UINT8)
+	      pixel_type = RL2_PIXEL_GRAYSCALE;
+      }
+    if (nComponents == 3)
+	pixel_type = RL2_PIXEL_RGB;
+    if (nComponents == 4)
+	pixel_type = RL2_PIXEL_MULTIBAND;
+
+    opj_destroy_codec (codec);
+    opj_stream_destroy (stream);
+    opj_image_destroy (image);
+
+    *xsample_type = sample_type;
+    *xpixel_type = pixel_type;
+    *xnum_bands = nComponents;
+    return RL2_OK;
+
+  error:
+    opj_destroy_codec (codec);
+    opj_stream_destroy (stream);
+    opj_image_destroy (image);
+    return RL2_ERROR;
+}
+
+RL2_DECLARE char *
+rl2_build_jpeg2000_xml_summary (unsigned int width, unsigned int height,
+				unsigned char sample_type,
+				unsigned char pixel_type,
+				unsigned char num_bands, int is_georeferenced,
+				double res_x, double res_y, double minx,
+				double miny, double maxx, double maxy,
+				unsigned int tile_width,
+				unsigned int tile_height)
+{
+/* attempting to build an XML Summary from a Jpeg2000 */
+    char *xml;
+    char *prev;
+    int len;
+    int bps = 8;
+
+    xml = sqlite3_mprintf ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<ImportedRaster>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<RasterFormat>Jpeg2000</RasterFormat>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<RasterWidth>%u</RasterWidth>", prev, width);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<RasterHeight>%u</RasterHeight>", prev, height);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<TileWidth>%u</TileWidth>", prev, tile_width);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<TileHeight>%u</TileHeight>", prev, tile_height);
+    sqlite3_free (prev);
+    prev = xml;
+    if (sample_type == RL2_SAMPLE_UINT16)
+	bps = 16;
+    xml = sqlite3_mprintf ("%s<BitsPerSample>%d</BitsPerSample>", prev, bps);
+    sqlite3_free (prev);
+    prev = xml;
+    xml =
+	sqlite3_mprintf ("%s<SamplesPerPixel>%d</SamplesPerPixel>", prev,
+			 num_bands);
+    sqlite3_free (prev);
+    prev = xml;
+    if (pixel_type == RL2_PIXEL_RGB)
+	xml =
+	    sqlite3_mprintf
+	    ("%s<PhotometricInterpretation>RGB</PhotometricInterpretation>",
+	     prev);
+    else
+	xml =
+	    sqlite3_mprintf
+	    ("%s<PhotometricInterpretation>min-is-black</PhotometricInterpretation>",
+	     prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<Compression>Jpeg2000</Compression>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml =
+	sqlite3_mprintf ("%s<SampleFormat>unsigned integer</SampleFormat>",
+			 prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml =
+	sqlite3_mprintf
+	("%s<PlanarConfiguration>single Raster plane</PlanarConfiguration>",
+	 prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<NoDataPixel>unknown</NoDataPixel>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    if (is_georeferenced)
+      {
+	  xml = sqlite3_mprintf ("%s<GeoReferencing>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<SpatialReferenceSystem>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<SRID>unspecified</SRID>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<RefSysName>undeclared</RefSysName>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s</SpatialReferenceSystem>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<SpatialResolution>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml =
+	      sqlite3_mprintf
+	      ("%s<HorizontalResolution>%1.10f</HorizontalResolution>", prev,
+	       res_x);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml =
+	      sqlite3_mprintf
+	      ("%s<VerticalResolution>%1.10f</VerticalResolution>", prev,
+	       res_y);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s</SpatialResolution>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<BoundingBox>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<MinX>%1.10f</MinX>", prev, minx);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<MinY>%1.10f</MinY>", prev, miny);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<MaxX>%1.10f</MaxX>", prev, maxx);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<MaxY>%1.10f</MaxY>", prev, maxy);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s</BoundingBox>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<Extent>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml =
+	      sqlite3_mprintf
+	      ("%s<HorizontalExtent>%1.10f</HorizontalExtent>", prev,
+	       maxx - minx);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml =
+	      sqlite3_mprintf ("%s<VerticalExtent>%1.10f</VerticalExtent>",
+			       prev, maxy - miny);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s</Extent>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s</GeoReferencing>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+      }
+    xml = sqlite3_mprintf ("%s</ImportedRaster>", prev);
+    sqlite3_free (prev);
+    len = strlen (xml);
+    prev = xml;
+    xml = malloc (len + 1);
+    strcpy (xml, prev);
+    sqlite3_free (prev);
+    return xml;
+}
+
+#endif /* end OpenJpeg conditional */
diff --git a/src/rl2paint.c b/src/rl2paint.c
index 05ab535..e032d99 100644
--- a/src/rl2paint.c
+++ b/src/rl2paint.c
@@ -51,16 +51,19 @@ the terms of any one of the MPL, the GPL or the LGPL.
 
 #include "rasterlite2/rasterlite2.h"
 #include "rasterlite2/rl2graphics.h"
+#include "rasterlite2/rl2svg.h"
 #include "rasterlite2_private.h"
 
 #ifdef __ANDROID__		/* Android specific */
 #include <cairo.h>
 #include <cairo-svg.h>
 #include <cairo-pdf.h>
+#include <cairo-ft.h>
 #else /* any other standard platform (Win, Linux, Mac) */
 #include <cairo/cairo.h>
 #include <cairo/cairo-svg.h>
 #include <cairo/cairo-pdf.h>
+#include <cairo/cairo-ft.h>
 #endif /* end Android conditionals */
 
 #define RL2_SURFACE_IMG 2671
@@ -70,13 +73,28 @@ the terms of any one of the MPL, the GPL or the LGPL.
 struct rl2_graphics_pen
 {
 /* a struct wrapping a Cairo Pen */
+    int is_solid_color;
+    int is_linear_gradient;
+    int is_pattern;
     double red;
     double green;
     double blue;
     double alpha;
+    double x0;
+    double y0;
+    double x1;
+    double y1;
+    double red2;
+    double green2;
+    double blue2;
+    double alpha2;
+    cairo_pattern_t *pattern;
     double width;
-    double lengths[4];
-    int lengths_count;
+    double *dash_array;
+    int dash_count;
+    double dash_offset;
+    int line_cap;
+    int line_join;
 };
 
 struct rl2_graphics_brush
@@ -114,34 +132,47 @@ typedef struct rl2_graphics_context
     double font_green;
     double font_blue;
     double font_alpha;
-    int is_font_outlined;
-    double font_outline_width;
+    int with_font_halo;
+    double halo_radius;
+    double halo_red;
+    double halo_green;
+    double halo_blue;
+    double halo_alpha;
 } RL2GraphContext;
 typedef RL2GraphContext *RL2GraphContextPtr;
 
-typedef struct rl2_graphics_pattern_brush
+typedef struct rl2_priv_graphics_pattern
 {
-/* a Cairo based pattern brush */
+/* a Cairo based pattern */
     int width;
     int height;
     unsigned char *rgba;
     cairo_surface_t *bitmap;
     cairo_pattern_t *pattern;
-} RL2GraphPatternBrush;
-typedef RL2GraphPatternBrush *RL2GraphPatternBrushPtr;
+} RL2PrivGraphPattern;
+typedef RL2PrivGraphPattern *RL2PrivGraphPatternPtr;
 
 typedef struct rl2_graphics_font
 {
-/* a struct wrapping a Cairo Font */
+/* a struct wrapping a Cairo/FreeType Font */
+    int toy_font;
+    char *facename;
+    cairo_font_face_t *cairo_font;
+    cairo_scaled_font_t *cairo_scaled_font;
+    struct rl2_private_tt_font *tt_font;
     double size;
-    int is_outlined;
-    double outline_width;
+    double font_red;
+    double font_green;
+    double font_blue;
+    double font_alpha;
+    int with_halo;
+    double halo_radius;
+    double halo_red;
+    double halo_green;
+    double halo_blue;
+    double halo_alpha;
     int style;
     int weight;
-    double red;
-    double green;
-    double blue;
-    double alpha;
 } RL2GraphFont;
 typedef RL2GraphFont *RL2GraphFontPtr;
 
@@ -180,13 +211,20 @@ rl2_graph_create_context (int width, int height)
 	goto error2;
 
 /* setting up a default Black Pen */
+    ctx->current_pen.is_solid_color = 1;
+    ctx->current_pen.is_linear_gradient = 0;
+    ctx->current_pen.is_pattern = 0;
     ctx->current_pen.red = 0.0;
     ctx->current_pen.green = 0.0;
     ctx->current_pen.blue = 0.0;
     ctx->current_pen.alpha = 1.0;
     ctx->current_pen.width = 1.0;
-    ctx->current_pen.lengths[0] = 1.0;
-    ctx->current_pen.lengths_count = 1;
+    ctx->current_pen.line_cap = RL2_PEN_CAP_BUTT;
+    ctx->current_pen.line_join = RL2_PEN_JOIN_MITER;
+    ctx->current_pen.dash_array = NULL;
+    ctx->current_pen.dash_count = 0;
+    ctx->current_pen.dash_offset = 0.0;
+    ctx->current_pen.pattern = NULL;
 
 /* setting up a default Black Brush */
     ctx->current_brush.is_solid_color = 1;
@@ -208,8 +246,12 @@ rl2_graph_create_context (int width, int height)
     ctx->font_green = 0.0;
     ctx->font_blue = 0.0;
     ctx->font_alpha = 1.0;
-    ctx->is_font_outlined = 0;
-    ctx->font_outline_width = 0.0;
+    ctx->with_font_halo = 0;
+    ctx->halo_radius = 0.0;
+    ctx->halo_red = 1.0;
+    ctx->halo_green = 1.0;
+    ctx->halo_blue = 1.0;
+    ctx->halo_alpha = 1.0;
     return (rl2GraphicsContextPtr) ctx;
   error2:
     cairo_destroy (ctx->cairo);
@@ -226,7 +268,10 @@ destroy_context (RL2GraphContextPtr ctx)
 /* memory cleanup - destroying a Graphics Context */
     if (ctx == NULL)
 	return;
+    if (ctx->current_pen.dash_array != NULL)
+	free (ctx->current_pen.dash_array);
     cairo_destroy (ctx->cairo);
+    cairo_surface_finish (ctx->surface);
     cairo_surface_destroy (ctx->surface);
     free (ctx);
 }
@@ -300,13 +345,20 @@ rl2_graph_create_svg_context (const char *path, int width, int height)
 	goto error2;
 
 /* setting up a default Black Pen */
+    ctx->current_pen.is_solid_color = 1;
+    ctx->current_pen.is_linear_gradient = 0;
+    ctx->current_pen.is_pattern = 0;
     ctx->current_pen.red = 0.0;
     ctx->current_pen.green = 0.0;
     ctx->current_pen.blue = 0.0;
     ctx->current_pen.alpha = 1.0;
     ctx->current_pen.width = 1.0;
-    ctx->current_pen.lengths[0] = 1.0;
-    ctx->current_pen.lengths_count = 1;
+    ctx->current_pen.line_cap = RL2_PEN_CAP_BUTT;
+    ctx->current_pen.line_join = RL2_PEN_JOIN_MITER;
+    ctx->current_pen.dash_array = NULL;
+    ctx->current_pen.dash_count = 0;
+    ctx->current_pen.dash_offset = 0.0;
+    ctx->current_pen.pattern = NULL;
 
 /* setting up a default Black Brush */
     ctx->current_brush.is_solid_color = 1;
@@ -328,8 +380,12 @@ rl2_graph_create_svg_context (const char *path, int width, int height)
     ctx->font_green = 0.0;
     ctx->font_blue = 0.0;
     ctx->font_alpha = 1.0;
-    ctx->is_font_outlined = 0;
-    ctx->font_outline_width = 0.0;
+    ctx->with_font_halo = 0;
+    ctx->halo_radius = 0.0;
+    ctx->halo_red = 1.0;
+    ctx->halo_green = 1.0;
+    ctx->halo_blue = 1.0;
+    ctx->halo_alpha = 1.0;
     return (rl2GraphicsContextPtr) ctx;
   error2:
     cairo_destroy (ctx->cairo);
@@ -390,13 +446,20 @@ rl2_graph_create_pdf_context (const char *path, int dpi, double page_width,
 	goto error4;
 
 /* setting up a default Black Pen */
+    ctx->current_pen.is_solid_color = 1;
+    ctx->current_pen.is_linear_gradient = 0;
+    ctx->current_pen.is_pattern = 0;
     ctx->current_pen.red = 0.0;
     ctx->current_pen.green = 0.0;
     ctx->current_pen.blue = 0.0;
     ctx->current_pen.alpha = 1.0;
     ctx->current_pen.width = 1.0;
-    ctx->current_pen.lengths[0] = 1.0;
-    ctx->current_pen.lengths_count = 1;
+    ctx->current_pen.line_cap = RL2_PEN_CAP_BUTT;
+    ctx->current_pen.line_join = RL2_PEN_JOIN_MITER;
+    ctx->current_pen.dash_array = NULL;
+    ctx->current_pen.dash_count = 0;
+    ctx->current_pen.dash_offset = 0.0;
+    ctx->current_pen.pattern = NULL;
 
 /* setting up a default Black Brush */
     ctx->current_brush.is_solid_color = 1;
@@ -416,8 +479,12 @@ rl2_graph_create_pdf_context (const char *path, int dpi, double page_width,
     ctx->font_green = 0.0;
     ctx->font_blue = 0.0;
     ctx->font_alpha = 1.0;
-    ctx->is_font_outlined = 0;
-    ctx->font_outline_width = 0.0;
+    ctx->with_font_halo = 0;
+    ctx->halo_radius = 0.0;
+    ctx->halo_red = 1.0;
+    ctx->halo_green = 1.0;
+    ctx->halo_blue = 1.0;
+    ctx->halo_alpha = 1.0;
     return (rl2GraphicsContextPtr) ctx;
   error4:
     cairo_destroy (ctx->clip_cairo);
@@ -523,13 +590,20 @@ rl2_graph_create_mem_pdf_context (rl2MemPdfPtr mem_pdf, int dpi,
 	goto error4;
 
 /* setting up a default Black Pen */
+    ctx->current_pen.is_solid_color = 1;
+    ctx->current_pen.is_linear_gradient = 0;
+    ctx->current_pen.is_pattern = 0;
     ctx->current_pen.red = 0.0;
     ctx->current_pen.green = 0.0;
     ctx->current_pen.blue = 0.0;
     ctx->current_pen.alpha = 1.0;
     ctx->current_pen.width = 1.0;
-    ctx->current_pen.lengths[0] = 1.0;
-    ctx->current_pen.lengths_count = 1;
+    ctx->current_pen.line_cap = RL2_PEN_CAP_BUTT;
+    ctx->current_pen.line_join = RL2_PEN_JOIN_MITER;
+    ctx->current_pen.dash_array = NULL;
+    ctx->current_pen.dash_count = 0;
+    ctx->current_pen.dash_offset = 0.0;
+    ctx->current_pen.pattern = NULL;
 
 /* setting up a default Black Brush */
     ctx->current_brush.is_solid_color = 1;
@@ -549,8 +623,12 @@ rl2_graph_create_mem_pdf_context (rl2MemPdfPtr mem_pdf, int dpi,
     ctx->font_green = 0.0;
     ctx->font_blue = 0.0;
     ctx->font_alpha = 1.0;
-    ctx->is_font_outlined = 0;
-    ctx->font_outline_width = 0.0;
+    ctx->with_font_halo = 0;
+    ctx->halo_radius = 0.0;
+    ctx->halo_red = 1.0;
+    ctx->halo_green = 1.0;
+    ctx->halo_blue = 1.0;
+    ctx->halo_alpha = 1.0;
     return (rl2GraphicsContextPtr) ctx;
   error4:
     cairo_destroy (ctx->clip_cairo);
@@ -573,11 +651,67 @@ rl2_graph_create_mem_pdf_context (rl2MemPdfPtr mem_pdf, int dpi,
 }
 
 RL2_DECLARE int
-rl2_graph_set_pen (rl2GraphicsContextPtr context, unsigned char red,
-		   unsigned char green, unsigned char blue, unsigned char alpha,
-		   double width, int style)
+rl2_graph_set_solid_pen (rl2GraphicsContextPtr context, unsigned char red,
+			 unsigned char green, unsigned char blue,
+			 unsigned char alpha, double width, int line_cap,
+			 int line_join)
+{
+/* creating a Color Pen - solid style */
+    double d_red = (double) red / 255.0;
+    double d_green = (double) green / 255.0;
+    double d_blue = (double) blue / 255.0;
+    double d_alpha = (double) alpha / 255.0;
+    RL2GraphContextPtr ctx = (RL2GraphContextPtr) context;
+    if (ctx == NULL)
+	return 0;
+
+    ctx->current_pen.width = width;
+    ctx->current_pen.is_solid_color = 1;
+    ctx->current_pen.is_linear_gradient = 0;
+    ctx->current_pen.is_pattern = 0;
+    ctx->current_pen.red = d_red;
+    ctx->current_pen.green = d_green;
+    ctx->current_pen.blue = d_blue;
+    ctx->current_pen.alpha = d_alpha;
+    switch (line_cap)
+      {
+      case RL2_PEN_CAP_ROUND:
+      case RL2_PEN_CAP_SQUARE:
+	  ctx->current_pen.line_cap = line_cap;
+	  break;
+      default:
+	  ctx->current_pen.line_cap = RL2_PEN_CAP_BUTT;
+	  break;
+
+      };
+    switch (line_join)
+      {
+      case RL2_PEN_JOIN_ROUND:
+      case RL2_PEN_JOIN_BEVEL:
+	  ctx->current_pen.line_join = line_join;
+	  break;
+      default:
+	  ctx->current_pen.line_join = RL2_PEN_JOIN_MITER;
+	  break;
+
+      };
+    ctx->current_pen.dash_count = 0;
+    if (ctx->current_pen.dash_array != NULL)
+	free (ctx->current_pen.dash_array);
+    ctx->current_pen.dash_array = NULL;
+    ctx->current_pen.dash_offset = 0.0;
+    return 1;
+}
+
+RL2_DECLARE int
+rl2_graph_set_dashed_pen (rl2GraphicsContextPtr context, unsigned char red,
+			  unsigned char green, unsigned char blue,
+			  unsigned char alpha, double width, int line_cap,
+			  int line_join, int dash_count, double dash_list[],
+			  double dash_offset)
 {
-/* creating a Color Pen */
+/* creating a Color Pen - dashed style */
+    int d;
     double d_red = (double) red / 255.0;
     double d_green = (double) green / 255.0;
     double d_blue = (double) blue / 255.0;
@@ -585,41 +719,304 @@ rl2_graph_set_pen (rl2GraphicsContextPtr context, unsigned char red,
     RL2GraphContextPtr ctx = (RL2GraphContextPtr) context;
     if (ctx == NULL)
 	return 0;
+    if (dash_count <= 0 || dash_list == NULL)
+	return 0;
 
     ctx->current_pen.width = width;
+    ctx->current_pen.is_solid_color = 1;
+    ctx->current_pen.is_linear_gradient = 0;
+    ctx->current_pen.is_pattern = 0;
+    ctx->current_pen.red = d_red;
+    ctx->current_pen.green = d_green;
+    ctx->current_pen.blue = d_blue;
+    ctx->current_pen.alpha = d_alpha;
+    switch (line_cap)
+      {
+      case RL2_PEN_CAP_ROUND:
+      case RL2_PEN_CAP_SQUARE:
+	  ctx->current_pen.line_cap = line_cap;
+	  break;
+      default:
+	  ctx->current_pen.line_cap = RL2_PEN_CAP_BUTT;
+	  break;
+
+      };
+    switch (line_join)
+      {
+      case RL2_PEN_JOIN_ROUND:
+      case RL2_PEN_JOIN_BEVEL:
+	  ctx->current_pen.line_join = line_join;
+	  break;
+      default:
+	  ctx->current_pen.line_join = RL2_PEN_JOIN_MITER;
+	  break;
+
+      };
+    ctx->current_pen.dash_count = dash_count;
+    if (ctx->current_pen.dash_array != NULL)
+	free (ctx->current_pen.dash_array);
+    ctx->current_pen.dash_array = malloc (sizeof (double) * dash_count);
+    for (d = 0; d < dash_count; d++)
+	*(ctx->current_pen.dash_array + d) = *(dash_list + d);
+    ctx->current_pen.dash_offset = dash_offset;
+    return 1;
+}
+
+RL2_DECLARE int
+rl2_graph_set_linear_gradient_solid_pen (rl2GraphicsContextPtr context,
+					 double x, double y, double width,
+					 double height, unsigned char red1,
+					 unsigned char green1,
+					 unsigned char blue1,
+					 unsigned char alpha1,
+					 unsigned char red2,
+					 unsigned char green2,
+					 unsigned char blue2,
+					 unsigned char alpha2,
+					 double pen_width, int line_cap,
+					 int line_join)
+{
+/* setting up a Linear Gradient Pen - solid style */
+    double d_red = (double) red1 / 255.0;
+    double d_green = (double) green1 / 255.0;
+    double d_blue = (double) blue1 / 255.0;
+    double d_alpha = (double) alpha1 / 255.0;
+    RL2GraphContextPtr ctx = (RL2GraphContextPtr) context;
+    if (ctx == NULL)
+	return 0;
+
+    ctx->current_pen.width = pen_width;
+    switch (line_cap)
+      {
+      case RL2_PEN_CAP_ROUND:
+      case RL2_PEN_CAP_SQUARE:
+	  ctx->current_pen.line_cap = line_cap;
+	  break;
+      default:
+	  ctx->current_pen.line_cap = RL2_PEN_CAP_BUTT;
+	  break;
+
+      };
+    switch (line_join)
+      {
+      case RL2_PEN_JOIN_ROUND:
+      case RL2_PEN_JOIN_BEVEL:
+	  ctx->current_pen.line_join = line_join;
+	  break;
+      default:
+	  ctx->current_pen.line_join = RL2_PEN_JOIN_MITER;
+	  break;
+
+      };
+    ctx->current_pen.is_solid_color = 0;
+    ctx->current_pen.is_linear_gradient = 1;
+    ctx->current_pen.is_pattern = 0;
+    ctx->current_pen.red = d_red;
+    ctx->current_pen.green = d_green;
+    ctx->current_pen.blue = d_blue;
+    ctx->current_pen.alpha = d_alpha;
+    ctx->current_pen.x0 = x;
+    ctx->current_pen.y0 = y;
+    ctx->current_pen.x1 = x + width;
+    ctx->current_pen.y1 = y + height;
+    d_red = (double) red2 / 255.0;
+    d_green = (double) green2 / 255.0;
+    d_blue = (double) blue2 / 255.0;
+    d_alpha = (double) alpha2 / 255.0;
+    ctx->current_pen.red2 = d_red;
+    ctx->current_pen.green2 = d_green;
+    ctx->current_pen.blue2 = d_blue;
+    ctx->current_pen.alpha2 = d_alpha;
+    ctx->current_pen.dash_count = 0;
+    if (ctx->current_pen.dash_array != NULL)
+	free (ctx->current_pen.dash_array);
+    ctx->current_pen.dash_array = NULL;
+    ctx->current_pen.dash_offset = 0.0;
+    return 1;
+}
+
+RL2_DECLARE int
+rl2_graph_set_linear_gradient_dashed_pen (rl2GraphicsContextPtr context,
+					  double x, double y, double width,
+					  double height, unsigned char red1,
+					  unsigned char green1,
+					  unsigned char blue1,
+					  unsigned char alpha1,
+					  unsigned char red2,
+					  unsigned char green2,
+					  unsigned char blue2,
+					  unsigned char alpha2,
+					  double pen_width, int line_cap,
+					  int line_join, int dash_count,
+					  double dash_list[],
+					  double dash_offset)
+{
+/* setting up a Linear Gradient Pen - dashed style */
+    int d;
+    double d_red = (double) red1 / 255.0;
+    double d_green = (double) green1 / 255.0;
+    double d_blue = (double) blue1 / 255.0;
+    double d_alpha = (double) alpha1 / 255.0;
+    RL2GraphContextPtr ctx = (RL2GraphContextPtr) context;
+    if (ctx == NULL)
+	return 0;
+    if (dash_count <= 0 || dash_list == NULL)
+	return 0;
+
+    ctx->current_pen.width = pen_width;
+    switch (line_cap)
+      {
+      case RL2_PEN_CAP_ROUND:
+      case RL2_PEN_CAP_SQUARE:
+	  ctx->current_pen.line_cap = line_cap;
+	  break;
+      default:
+	  ctx->current_pen.line_cap = RL2_PEN_CAP_BUTT;
+	  break;
+
+      };
+    switch (line_join)
+      {
+      case RL2_PEN_JOIN_ROUND:
+      case RL2_PEN_JOIN_BEVEL:
+	  ctx->current_pen.line_join = line_join;
+	  break;
+      default:
+	  ctx->current_pen.line_join = RL2_PEN_JOIN_MITER;
+	  break;
+
+      };
+    ctx->current_pen.is_solid_color = 0;
+    ctx->current_pen.is_linear_gradient = 1;
+    ctx->current_pen.is_pattern = 0;
     ctx->current_pen.red = d_red;
     ctx->current_pen.green = d_green;
     ctx->current_pen.blue = d_blue;
     ctx->current_pen.alpha = d_alpha;
-    switch (style)
+    ctx->current_pen.x0 = x;
+    ctx->current_pen.y0 = y;
+    ctx->current_pen.x1 = x + width;
+    ctx->current_pen.y1 = y + height;
+    d_red = (double) red2 / 255.0;
+    d_green = (double) green2 / 255.0;
+    d_blue = (double) blue2 / 255.0;
+    d_alpha = (double) alpha2 / 255.0;
+    ctx->current_pen.red2 = d_red;
+    ctx->current_pen.green2 = d_green;
+    ctx->current_pen.blue2 = d_blue;
+    ctx->current_pen.alpha2 = d_alpha;
+    ctx->current_pen.dash_count = dash_count;
+    if (ctx->current_pen.dash_array != NULL)
+	free (ctx->current_pen.dash_array);
+    ctx->current_pen.dash_array = malloc (sizeof (double) * dash_count);
+    for (d = 0; d < dash_count; d++)
+	*(ctx->current_pen.dash_array + d) = *(dash_list + d);
+    ctx->current_pen.dash_offset = dash_offset;
+    return 1;
+}
+
+RL2_DECLARE int
+rl2_graph_set_pattern_solid_pen (rl2GraphicsContextPtr context,
+				 rl2GraphicsPatternPtr brush,
+				 double width, int line_cap, int line_join)
+{
+/* setting up a Pattern Pen - solid style */
+    RL2PrivGraphPatternPtr pattern = (RL2PrivGraphPatternPtr) brush;
+    RL2GraphContextPtr ctx = (RL2GraphContextPtr) context;
+
+    if (ctx == NULL)
+	return 0;
+    if (pattern == NULL)
+	return 0;
+
+    ctx->current_pen.width = width;
+    switch (line_cap)
+      {
+      case RL2_PEN_CAP_ROUND:
+      case RL2_PEN_CAP_SQUARE:
+	  ctx->current_pen.line_cap = line_cap;
+	  break;
+      default:
+	  ctx->current_pen.line_cap = RL2_PEN_CAP_BUTT;
+	  break;
+
+      };
+    switch (line_join)
       {
-      case RL2_PENSTYLE_DOT:
-	  ctx->current_pen.lengths[0] = 2;
-	  ctx->current_pen.lengths[1] = 2;
-	  ctx->current_pen.lengths_count = 2;
+      case RL2_PEN_JOIN_ROUND:
+      case RL2_PEN_JOIN_BEVEL:
+	  ctx->current_pen.line_join = line_join;
+	  break;
+      default:
+	  ctx->current_pen.line_join = RL2_PEN_JOIN_MITER;
 	  break;
-      case RL2_PENSTYLE_LONG_DASH:
-	  ctx->current_pen.lengths[0] = 16;
-	  ctx->current_pen.lengths[1] = 8;
-	  ctx->current_pen.lengths_count = 2;
+
+      };
+    ctx->current_pen.is_solid_color = 0;
+    ctx->current_pen.is_linear_gradient = 0;
+    ctx->current_pen.is_pattern = 1;
+    ctx->current_pen.pattern = pattern->pattern;
+    ctx->current_pen.dash_count = 0;
+    if (ctx->current_pen.dash_array != NULL)
+	free (ctx->current_pen.dash_array);
+    ctx->current_pen.dash_array = NULL;
+    ctx->current_pen.dash_offset = 0.0;
+    return 1;
+}
+
+RL2_DECLARE int
+rl2_graph_set_pattern_dashed_pen (rl2GraphicsContextPtr context,
+				  rl2GraphicsPatternPtr brush,
+				  double width, int line_cap, int line_join,
+				  int dash_count, double dash_list[],
+				  double dash_offset)
+{
+/* setting up a Pattern Pen - dashed style */
+    int d;
+    RL2PrivGraphPatternPtr pattern = (RL2PrivGraphPatternPtr) brush;
+    RL2GraphContextPtr ctx = (RL2GraphContextPtr) context;
+
+    if (ctx == NULL)
+	return 0;
+    if (pattern == NULL)
+	return 0;
+    if (dash_count <= 0 || dash_list == NULL)
+	return 0;
+
+    ctx->current_pen.width = width;
+    switch (line_cap)
+      {
+      case RL2_PEN_CAP_ROUND:
+      case RL2_PEN_CAP_SQUARE:
+	  ctx->current_pen.line_cap = line_cap;
 	  break;
-      case RL2_PENSTYLE_SHORT_DASH:
-	  ctx->current_pen.lengths[0] = 8;
-	  ctx->current_pen.lengths[1] = 4;
-	  ctx->current_pen.lengths_count = 2;
+      default:
+	  ctx->current_pen.line_cap = RL2_PEN_CAP_BUTT;
 	  break;
-      case RL2_PENSTYLE_DOT_DASH:
-	  ctx->current_pen.lengths[0] = 8;
-	  ctx->current_pen.lengths[1] = 4;
-	  ctx->current_pen.lengths[2] = 2;
-	  ctx->current_pen.lengths[3] = 4;
-	  ctx->current_pen.lengths_count = 4;
+
+      };
+    switch (line_join)
+      {
+      case RL2_PEN_JOIN_ROUND:
+      case RL2_PEN_JOIN_BEVEL:
+	  ctx->current_pen.line_join = line_join;
 	  break;
       default:
-	  ctx->current_pen.lengths[0] = 1;
-	  ctx->current_pen.lengths[1] = 0;
-	  ctx->current_pen.lengths_count = 2;
+	  ctx->current_pen.line_join = RL2_PEN_JOIN_MITER;
+	  break;
+
       };
+    ctx->current_pen.is_solid_color = 0;
+    ctx->current_pen.is_linear_gradient = 0;
+    ctx->current_pen.is_pattern = 1;
+    ctx->current_pen.pattern = pattern->pattern;
+    ctx->current_pen.dash_count = dash_count;
+    if (ctx->current_pen.dash_array != NULL)
+	free (ctx->current_pen.dash_array);
+    ctx->current_pen.dash_array = malloc (sizeof (double) * dash_count);
+    for (d = 0; d < dash_count; d++)
+	*(ctx->current_pen.dash_array + d) = *(dash_list + d);
+    ctx->current_pen.dash_offset = dash_offset;
     return 1;
 }
 
@@ -651,8 +1048,9 @@ RL2_DECLARE int
 rl2_graph_set_linear_gradient_brush (rl2GraphicsContextPtr context, double x,
 				     double y, double width, double height,
 				     unsigned char red1, unsigned char green1,
-				     unsigned char blue1, unsigned char alpha1,
-				     unsigned char red2, unsigned char green2,
+				     unsigned char blue1,
+				     unsigned char alpha1, unsigned char red2,
+				     unsigned char green2,
 				     unsigned char blue2, unsigned char alpha2)
 {
 /* setting up a Linear Gradient Brush */
@@ -691,7 +1089,7 @@ rl2_graph_set_pattern_brush (rl2GraphicsContextPtr context,
 			     rl2GraphicsPatternPtr brush)
 {
 /* setting up a Pattern Brush */
-    RL2GraphPatternBrushPtr pattern = (RL2GraphPatternBrushPtr) brush;
+    RL2PrivGraphPatternPtr pattern = (RL2PrivGraphPatternPtr) brush;
     RL2GraphContextPtr ctx = (RL2GraphContextPtr) context;
 
     if (ctx == NULL)
@@ -707,6 +1105,25 @@ rl2_graph_set_pattern_brush (rl2GraphicsContextPtr context,
     return 1;
 }
 
+static void
+rl2_priv_graph_destroy_font (RL2GraphFontPtr fnt)
+{
+/* destroying a font (not yet cached) */
+    if (fnt == NULL)
+	return;
+
+    if (fnt->tt_font != NULL)
+      {
+	  if (fnt->tt_font->facename != NULL)
+	      free (fnt->tt_font->facename);
+	  if (fnt->tt_font->FTface != NULL)
+	      FT_Done_Face ((FT_Face) (fnt->tt_font->FTface));
+	  if (fnt->tt_font->ttf_data != NULL)
+	      free (fnt->tt_font->ttf_data);
+      }
+    free (fnt);
+}
+
 RL2_DECLARE int
 rl2_graph_set_font (rl2GraphicsContextPtr context, rl2GraphicsFontPtr font)
 {
@@ -727,21 +1144,47 @@ rl2_graph_set_font (rl2GraphicsContextPtr context, rl2GraphicsFontPtr font)
     else
 	cairo = ctx->cairo;
 
-    if (fnt->style == RL2_FONTSTYLE_ITALIC)
-	style = CAIRO_FONT_SLANT_ITALIC;
-    if (fnt->weight == RL2_FONTWEIGHT_BOLD)
-	weight = CAIRO_FONT_WEIGHT_BOLD;
-    cairo_select_font_face (cairo, "monospace", style, weight);
     size = fnt->size;
-    if (fnt->is_outlined)
-	size += fnt->outline_width;
-    cairo_set_font_size (cairo, size);
-    ctx->font_red = fnt->red;
-    ctx->font_green = fnt->green;
-    ctx->font_blue = fnt->blue;
-    ctx->font_alpha = fnt->alpha;
-    ctx->is_font_outlined = fnt->is_outlined;
-    ctx->font_outline_width = fnt->outline_width;
+    ctx->font_red = fnt->font_red;
+    ctx->font_green = fnt->font_green;
+    ctx->font_blue = fnt->font_blue;
+    ctx->font_alpha = fnt->font_alpha;
+    ctx->with_font_halo = fnt->with_halo;
+    if (fnt->with_halo)
+      {
+	  ctx->halo_radius = fnt->halo_radius;
+	  ctx->halo_red = fnt->halo_red;
+	  ctx->halo_green = fnt->halo_green;
+	  ctx->halo_blue = fnt->halo_blue;
+	  ctx->halo_alpha = fnt->halo_alpha;
+	  size += fnt->halo_radius;
+      }
+    if (fnt->toy_font)
+      {
+	  /* using a CAIRO built-in "toy" font */
+	  if (fnt->style == RL2_FONTSTYLE_ITALIC)
+	      style = CAIRO_FONT_SLANT_ITALIC;
+	  if (fnt->style == RL2_FONTSTYLE_OBLIQUE)
+	      style = CAIRO_FONT_SLANT_OBLIQUE;
+	  if (fnt->weight == RL2_FONTWEIGHT_BOLD)
+	      weight = CAIRO_FONT_WEIGHT_BOLD;
+	  cairo_select_font_face (cairo, fnt->facename, style, weight);
+	  cairo_set_font_size (cairo, size);
+      }
+    else
+      {
+	  /* using a TrueType font */
+	  cairo_font_options_t *font_options = cairo_font_options_create ();
+	  cairo_matrix_t ctm;
+	  cairo_matrix_t font_matrix;
+	  cairo_get_matrix (cairo, &ctm);
+	  cairo_matrix_init (&font_matrix, size, 0.0, 0.0, size, 0.0, 0.0);
+	  fnt->cairo_scaled_font =
+	      cairo_scaled_font_create (fnt->cairo_font, &font_matrix, &ctm,
+					font_options);
+	  cairo_font_options_destroy (font_options);
+	  cairo_set_scaled_font (cairo, fnt->cairo_scaled_font);
+      }
 
     return 1;
 }
@@ -802,16 +1245,17 @@ adjust_for_endianness (unsigned char *rgbaArray, int width, int height)
 }
 
 RL2_DECLARE rl2GraphicsPatternPtr
-rl2_graph_create_pattern (unsigned char *rgbaArray, int width, int height)
+rl2_graph_create_pattern (unsigned char *rgbaArray, int width, int height,
+			  int extend)
 {
 /* creating a pattern brush */
-    RL2GraphPatternBrushPtr pattern;
+    RL2PrivGraphPatternPtr pattern;
 
     if (rgbaArray == NULL)
 	return NULL;
 
     adjust_for_endianness (rgbaArray, width, height);
-    pattern = malloc (sizeof (RL2GraphPatternBrush));
+    pattern = malloc (sizeof (RL2PrivGraphPattern));
     if (pattern == NULL)
 	return NULL;
     pattern->width = width;
@@ -821,15 +1265,212 @@ rl2_graph_create_pattern (unsigned char *rgbaArray, int width, int height)
 	cairo_image_surface_create_for_data (rgbaArray, CAIRO_FORMAT_ARGB32,
 					     width, height, width * 4);
     pattern->pattern = cairo_pattern_create_for_surface (pattern->bitmap);
-    cairo_pattern_set_extend (pattern->pattern, CAIRO_EXTEND_REPEAT);
+    if (extend)
+	cairo_pattern_set_extend (pattern->pattern, CAIRO_EXTEND_REPEAT);
+    else
+	cairo_pattern_set_extend (pattern->pattern, CAIRO_EXTEND_NONE);
     return (rl2GraphicsPatternPtr) pattern;
 }
 
+RL2_DECLARE rl2GraphicsPatternPtr
+rl2_create_pattern_from_external_graphic (sqlite3 * handle,
+					  const char *xlink_href, int extend)
+{
+/* creating a pattern brush from an External Graphic resource */
+    const char *sql;
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+    rl2RasterPtr raster = NULL;
+    unsigned char *rgbaArray = NULL;
+    int rgbaSize;
+    unsigned int width;
+    unsigned int height;
+    if (xlink_href == NULL)
+	return NULL;
+
+/* preparing the SQL query statement */
+    sql =
+	"SELECT resource, GetMimeType(resource) FROM SE_external_graphics "
+	"WHERE Lower(xlink_href) = Lower(?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	goto error;
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, xlink_href, strlen (xlink_href), SQLITE_STATIC);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	    {
+		if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
+		  {
+		      const unsigned char *blob = sqlite3_column_blob (stmt, 0);
+		      int blob_sz = sqlite3_column_bytes (stmt, 0);
+		      const char *mime =
+			  (const char *) sqlite3_column_text (stmt, 1);
+		      if (strcmp (mime, "image/jpeg") == 0)
+			{
+			    if (raster != NULL)
+				rl2_destroy_raster (raster);
+			    raster = rl2_raster_from_jpeg (blob, blob_sz);
+			}
+		      if (strcmp (mime, "image/png") == 0)
+			{
+			    if (raster != NULL)
+				rl2_destroy_raster (raster);
+			    raster = rl2_raster_from_png (blob, blob_sz, 1);
+			}
+		      if (strcmp (mime, "image/gif") == 0)
+			{
+			    if (raster != NULL)
+				rl2_destroy_raster (raster);
+			    raster = rl2_raster_from_gif (blob, blob_sz);
+			}
+		  }
+	    }
+	  else
+	      goto error;
+      }
+    sqlite3_finalize (stmt);
+    stmt = NULL;
+    if (raster == NULL)
+	goto error;
+
+/* retieving the raster RGBA map */
+    if (rl2_get_raster_size (raster, &width, &height) == RL2_OK)
+      {
+	  if (rl2_raster_data_to_RGBA (raster, &rgbaArray, &rgbaSize) != RL2_OK)
+	      rgbaArray = NULL;
+      }
+    rl2_destroy_raster (raster);
+    raster = NULL;
+    if (rgbaArray == NULL)
+	goto error;
+    return rl2_graph_create_pattern (rgbaArray, width, height, extend);
+
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    if (raster != NULL)
+	rl2_destroy_raster (raster);
+    return NULL;
+}
+
+RL2_DECLARE rl2GraphicsPatternPtr
+rl2_create_pattern_from_external_svg (sqlite3 * handle,
+				      const char *xlink_href, double size)
+{
+/* creating a pattern brush from an External SVG resource */
+    const char *sql;
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+    rl2RasterPtr raster = NULL;
+    unsigned char *rgbaArray = NULL;
+    int rgbaSize;
+    unsigned int width;
+    unsigned int height;
+    if (xlink_href == NULL)
+	return NULL;
+    if (size <= 0.0)
+	return NULL;
+
+/* preparing the SQL query statement */
+    sql =
+	"SELECT XB_GetPayload(resource) FROM SE_external_graphics "
+	"WHERE Lower(xlink_href) = Lower(?) AND "
+	"GetMimeType(resource) = 'image/svg+xml'";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	goto error;
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, xlink_href, strlen (xlink_href), SQLITE_STATIC);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	    {
+		if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
+		  {
+		      const unsigned char *blob = sqlite3_column_blob (stmt, 0);
+		      int blob_sz = sqlite3_column_bytes (stmt, 0);
+		      rl2SvgPtr svg_handle = rl2_create_svg (blob, blob_sz);
+		      if (svg_handle != NULL)
+			{
+			    double svgWidth;
+			    double svgHeight;
+			    if (rl2_get_svg_size
+				(svg_handle, &svgWidth, &svgHeight) == RL2_OK)
+			      {
+				  double sz;
+				  double w = svgWidth;
+				  double h = svgHeight;
+				  if (w < size && h < size)
+				    {
+					while (w < size && h < size)
+					  {
+					      /* rescaling */
+					      w *= 1.0001;
+					      h *= 1.0001;
+					  }
+				    }
+				  else
+				    {
+					while (w > size || h > size)
+					  {
+					      /* rescaling */
+					      w *= 0.9;
+					      h *= 0.9;
+					  }
+				    }
+				  sz = w;
+				  if (h > sz)
+				      sz = h;
+				  if (raster != NULL)
+				      rl2_destroy_raster (raster);
+				  raster =
+				      rl2_raster_from_svg (svg_handle, size);
+			      }
+			    rl2_destroy_svg (svg_handle);
+			}
+		  }
+	    }
+      }
+    sqlite3_finalize (stmt);
+    stmt = NULL;
+    if (raster == NULL)
+	goto error;
+
+/* retieving the raster RGBA map */
+    if (rl2_get_raster_size (raster, &width, &height) == RL2_OK)
+      {
+	  if (rl2_raster_data_to_RGBA (raster, &rgbaArray, &rgbaSize) != RL2_OK)
+	      rgbaArray = NULL;
+      }
+    rl2_destroy_raster (raster);
+    raster = NULL;
+    if (rgbaArray == NULL)
+	goto error;
+    return rl2_graph_create_pattern (rgbaArray, width, height, 0);
+
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    if (raster != NULL)
+	rl2_destroy_raster (raster);
+    return NULL;
+}
+
 RL2_DECLARE void
 rl2_graph_destroy_pattern (rl2GraphicsPatternPtr brush)
 {
 /* destroying a pattern brush */
-    RL2GraphPatternBrushPtr pattern = (RL2GraphPatternBrushPtr) brush;
+    RL2PrivGraphPatternPtr pattern = (RL2PrivGraphPatternPtr) brush;
 
     if (pattern == NULL)
 	return;
@@ -841,38 +1482,460 @@ rl2_graph_destroy_pattern (rl2GraphicsPatternPtr brush)
     free (pattern);
 }
 
-RL2_DECLARE rl2GraphicsFontPtr
-rl2_graph_create_font (double size, int style, int weight)
+RL2_DECLARE int
+rl2_graph_get_pattern_size (rl2GraphicsPatternPtr ptr,
+			    unsigned int *width, unsigned int *height)
 {
-/* creating a font */
-    RL2GraphFontPtr fnt;
+/* will return the Pattern dimensions */
+    RL2PrivGraphPatternPtr pattern = (RL2PrivGraphPatternPtr) ptr;
 
-    fnt = malloc (sizeof (RL2GraphFont));
-    if (fnt == NULL)
-	return NULL;
-    if (size < 1.0)
-	fnt->size = 1.0;
-    else if (size > 32.0)
-	fnt->size = 32.0;
-    else
-	fnt->size = size;
-    if (style == RL2_FONTSTYLE_ITALIC)
-	fnt->style = RL2_FONTSTYLE_ITALIC;
-    else
-	fnt->style = RL2_FONTSTYLE_NORMAL;
-    if (weight == RL2_FONTWEIGHT_BOLD)
-	fnt->weight = RL2_FONTWEIGHT_BOLD;
-    else
+    if (pattern == NULL)
+	return RL2_ERROR;
+    *width = pattern->width;
+    *height = pattern->height;
+    return RL2_OK;
+}
+
+static void
+aux_pattern_get_pixel (int x, int y, int width, unsigned char *bitmap,
+		       unsigned char *red, unsigned char *green,
+		       unsigned char *blue, unsigned char *alpha)
+{
+/* get pixel */
+    unsigned char *p_in = bitmap + (y * width * 4) + (x * 4);
+    int little_endian = rl2cr_endian_arch ();
+    if (little_endian)
+      {
+	  *blue = *p_in++;
+	  *green = *p_in++;
+	  *red = *p_in++;
+	  *alpha = *p_in++;
+      }
+    else
+      {
+	  *alpha = *p_in++;
+	  *red = *p_in++;
+	  *green = *p_in++;
+	  *blue = *p_in++;
+      }
+}
+
+static void
+aux_pattern_set_pixel (int x, int y, int width, unsigned char *bitmap,
+		       unsigned char red, unsigned char green,
+		       unsigned char blue, unsigned char alpha)
+{
+/* set pixel */
+    unsigned char *p_out = bitmap + (y * width * 4) + (x * 4);
+    int little_endian = rl2cr_endian_arch ();
+    if (little_endian)
+      {
+	  *p_out++ = blue;
+	  *p_out++ = green;
+	  *p_out++ = red;
+	  *p_out++ = alpha;
+      }
+    else
+      {
+	  *p_out++ = alpha;
+	  *p_out++ = red;
+	  *p_out++ = green;
+	  *p_out++ = blue;
+      }
+}
+
+RL2_DECLARE int
+rl2_graph_pattern_recolor (rl2GraphicsPatternPtr ptrn, unsigned char r,
+			   unsigned char g, unsigned char b)
+{
+/* recoloring a Monochrome Pattern */
+    int x;
+    int y;
+    int width;
+    int height;
+    unsigned char red;
+    unsigned char green;
+    unsigned char blue;
+    unsigned char alpha;
+    unsigned char xred;
+    unsigned char xgreen;
+    unsigned char xblue;
+    unsigned char xalpha;
+    int valid = 0;
+    int has_black = 0;
+    unsigned char *bitmap;
+    RL2PrivGraphPatternPtr pattern = (RL2PrivGraphPatternPtr) ptrn;
+    if (pattern == NULL)
+	return RL2_ERROR;
+
+    width = pattern->width;
+    height = pattern->height;
+    cairo_surface_flush (pattern->bitmap);
+    bitmap = cairo_image_surface_get_data (pattern->bitmap);
+    if (bitmap == NULL)
+	return RL2_ERROR;
+/* checking for a Monochrome Pattern */
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		aux_pattern_get_pixel (x, y, width, bitmap, &red, &green,
+				       &blue, &alpha);
+		if (alpha != 0)
+		  {
+		      if (red < 64 && green < 64 && blue < 64)
+			  has_black++;
+		      if (valid)
+			{
+			    if (xred == red && xgreen == green
+				&& xblue == blue && alpha == xalpha)
+				;
+			    else
+				goto not_mono;
+			}
+		      else
+			{
+			    xred = red;
+			    xgreen = green;
+			    xblue = blue;
+			    xalpha = alpha;
+			    valid = 1;
+			}
+		  }
+	    }
+      }
+/* all right, applying the new color */
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		aux_pattern_get_pixel (x, y, width, bitmap, &red, &green,
+				       &blue, &alpha);
+		if (alpha != 0)
+		    aux_pattern_set_pixel (x, y, width, bitmap, r, g, b, alpha);
+	    }
+      }
+    cairo_surface_mark_dirty (pattern->bitmap);
+    return RL2_OK;
+
+  not_mono:
+    if (has_black)
+      {
+	  /* recoloring only the black pixels */
+	  for (y = 0; y < height; y++)
+	    {
+		for (x = 0; x < width; x++)
+		  {
+		      aux_pattern_get_pixel (x, y, width, bitmap, &red,
+					     &green, &blue, &alpha);
+		      if (red < 64 && green < 64 && blue < 64)
+			  aux_pattern_set_pixel (x, y, width, bitmap, r, g, b,
+						 alpha);
+		  }
+	    }
+	  cairo_surface_mark_dirty (pattern->bitmap);
+	  return RL2_OK;
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_graph_pattern_transparency (rl2GraphicsPatternPtr ptrn, unsigned char aleph)
+{
+/* changing the Pattern's transparency */
+    int x;
+    int y;
+    int width;
+    int height;
+    unsigned char red;
+    unsigned char green;
+    unsigned char blue;
+    unsigned char alpha;
+    unsigned char *bitmap;
+    RL2PrivGraphPatternPtr pattern = (RL2PrivGraphPatternPtr) ptrn;
+    if (pattern == NULL)
+	return RL2_ERROR;
+
+    width = pattern->width;
+    height = pattern->height;
+    cairo_surface_flush (pattern->bitmap);
+    bitmap = cairo_image_surface_get_data (pattern->bitmap);
+    if (bitmap == NULL)
+	return RL2_ERROR;
+/* applying the new transparency */
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		aux_pattern_get_pixel (x, y, width, bitmap, &red, &green,
+				       &blue, &alpha);
+		if (alpha != 0)
+		    aux_pattern_set_pixel (x, y, width, bitmap, red, green,
+					   blue, aleph);
+	    }
+      }
+    cairo_surface_mark_dirty (pattern->bitmap);
+    return RL2_OK;
+}
+
+RL2_DECLARE rl2GraphicsFontPtr
+rl2_graph_create_toy_font (const char *facename, double size, int style,
+			   int weight)
+{
+/* creating a font based on CAIRO internal "toy" fonts */
+    RL2GraphFontPtr fnt;
+    int len;
+
+    fnt = malloc (sizeof (RL2GraphFont));
+    if (fnt == NULL)
+	return NULL;
+    fnt->toy_font = 1;
+    fnt->tt_font = NULL;
+    if (facename == NULL)
+	facename = "monospace";
+    if (strcasecmp (facename, "serif") == 0)
+      {
+	  len = strlen ("serif");
+	  fnt->facename = malloc (len + 1);
+	  strcpy (fnt->facename, "serif");
+      }
+    else if (strcasecmp (facename, "sans-serif") == 0)
+      {
+	  len = strlen ("sans-serif");
+	  fnt->facename = malloc (len + 1);
+	  strcpy (fnt->facename, "sans-serif");
+      }
+    else
+      {
+	  /* defaulting to "monospace" */
+	  len = strlen ("monospace");
+	  fnt->facename = malloc (len + 1);
+	  strcpy (fnt->facename, "monospace");
+      }
+    if (size < 1.0)
+	fnt->size = 1.0;
+    else if (size > 72.0)
+	fnt->size = 72.0;
+    else
+	fnt->size = size;
+    if (style == RL2_FONTSTYLE_ITALIC)
+	fnt->style = RL2_FONTSTYLE_ITALIC;
+    else if (style == RL2_FONTSTYLE_OBLIQUE)
+	fnt->style = RL2_FONTSTYLE_OBLIQUE;
+    else
+	fnt->style = RL2_FONTSTYLE_NORMAL;
+    if (weight == RL2_FONTWEIGHT_BOLD)
+	fnt->weight = RL2_FONTWEIGHT_BOLD;
+    else
+	fnt->weight = RL2_FONTWEIGHT_NORMAL;
+    fnt->font_red = 0.0;
+    fnt->font_green = 0.0;
+    fnt->font_blue = 0.0;
+    fnt->font_alpha = 1.0;
+    fnt->with_halo = 0;
+    fnt->halo_radius = 0.0;
+    fnt->halo_red = 0.0;
+    fnt->halo_green = 0.0;
+    fnt->halo_blue = 0.0;
+    fnt->halo_alpha = 1.0;
+    return (rl2GraphicsFontPtr) fnt;
+}
+
+static void
+rl2_destroy_private_tt_font (struct rl2_private_tt_font *font)
+{
+/* destroying a private font */
+    if (font == NULL)
+	return;
+
+    if (font->facename != NULL)
+	free (font->facename);
+    if (font->FTface != NULL)
+	FT_Done_Face ((FT_Face) (font->FTface));
+    if (font->ttf_data != NULL)
+	free (font->ttf_data);
+    free (font);
+}
+
+static void
+rl2_font_destructor_callback (void *data)
+{
+/* font destructor callback */
+    struct rl2_private_tt_font *font = (struct rl2_private_tt_font *) data;
+    if (font == NULL)
+	return;
+
+/* adjusting the double-linked list */
+    if (font == font->container->first_font
+	&& font == font->container->last_font)
+      {
+	  /* going to remove the unique item from the list */
+	  font->container->first_font = NULL;
+	  font->container->last_font = NULL;
+      }
+    else if (font == font->container->first_font)
+      {
+	  /* going to remove the first item from the list */
+	  font->next->prev = NULL;
+	  font->container->first_font = font->next;
+      }
+    else if (font == font->container->last_font)
+      {
+	  /* going to remove the last item from the list */
+	  font->prev->next = NULL;
+	  font->container->last_font = font->prev;
+      }
+    else
+      {
+	  /* normal case */
+	  font->prev->next = font->next;
+	  font->next->prev = font->prev;
+      }
+
+/* destroying the cached font */
+    rl2_destroy_private_tt_font (font);
+}
+
+RL2_DECLARE rl2GraphicsFontPtr
+rl2_graph_create_TrueType_font (const void *priv_data,
+				const unsigned char *ttf, int ttf_bytes,
+				double size)
+{
+/* creating a TrueType font */
+    RL2GraphFontPtr fnt;
+    char *facename;
+    int is_bold;
+    int is_italic;
+    unsigned char *font = NULL;
+    int font_sz;
+    FT_Error error;
+    FT_Library library;
+    FT_Face face;
+    static const cairo_user_data_key_t key;
+    struct rl2_private_data *cache = (struct rl2_private_data *) priv_data;
+    struct rl2_private_tt_font *tt_font;
+    if (cache == NULL)
+	return NULL;
+    if (cache->FTlibrary == NULL)
+	return NULL;
+    library = (FT_Library) (cache->FTlibrary);
+
+/* testing the BLOB-encoded TTF object for validity */
+    if (ttf == NULL || ttf_bytes <= 0)
+	return NULL;
+    if (rl2_is_valid_encoded_font (ttf, ttf_bytes) != RL2_OK)
+	return NULL;
+    facename = rl2_get_encoded_font_facename (ttf, ttf_bytes);
+    if (facename == NULL)
+	return NULL;
+    is_bold = rl2_is_encoded_font_bold (ttf, ttf_bytes);
+    is_italic = rl2_is_encoded_font_italic (ttf, ttf_bytes);
+
+/* decoding the TTF BLOB */
+    if (rl2_font_decode (ttf, ttf_bytes, &font, &font_sz) != RL2_OK)
+	return NULL;
+/* creating a FreeType font object */
+    error = FT_New_Memory_Face (library, font, font_sz, 0, &face);
+    if (error)
+      {
+	  free (facename);
+	  return NULL;
+      }
+
+    fnt = malloc (sizeof (RL2GraphFont));
+    if (fnt == NULL)
+      {
+	  free (facename);
+	  FT_Done_Face (face);
+	  return NULL;
+      }
+    tt_font = malloc (sizeof (struct rl2_private_tt_font));
+    if (tt_font == NULL)
+      {
+	  free (facename);
+	  FT_Done_Face (face);
+	  free (fnt);
+	  return NULL;
+      }
+    fnt->toy_font = 0;
+    fnt->tt_font = tt_font;
+    fnt->tt_font->facename = facename;
+    fnt->tt_font->is_bold = is_bold;
+    fnt->tt_font->is_italic = is_italic;
+    fnt->tt_font->container = cache;
+    fnt->tt_font->FTface = face;
+    fnt->tt_font->ttf_data = font;
+    fnt->cairo_font = cairo_ft_font_face_create_for_ft_face (face, 0);
+    if (fnt->cairo_font == NULL)
+      {
+	  rl2_priv_graph_destroy_font (fnt);
+	  return NULL;
+      }
+    fnt->cairo_scaled_font = NULL;
+/* inserting into the cache */
+    tt_font->prev = cache->last_font;
+    tt_font->next = NULL;
+    if (cache->first_font == NULL)
+	cache->first_font = tt_font;
+    if (cache->last_font != NULL)
+	cache->last_font->next = tt_font;
+    cache->last_font = tt_font;
+/* registering the destructor callback */
+    if (cairo_font_face_set_user_data
+	(fnt->cairo_font, &key, tt_font,
+	 rl2_font_destructor_callback) != CAIRO_STATUS_SUCCESS)
+      {
+	  rl2_priv_graph_destroy_font (fnt);
+	  return NULL;
+      }
+    if (size < 1.0)
+	fnt->size = 1.0;
+    else if (size > 72.0)
+	fnt->size = 72.0;
+    else
+	fnt->size = size;
+    if (is_italic)
+	fnt->style = RL2_FONTSTYLE_ITALIC;
+    else
+	fnt->style = RL2_FONTSTYLE_NORMAL;
+    if (is_bold)
+	fnt->weight = RL2_FONTWEIGHT_BOLD;
+    else
 	fnt->weight = RL2_FONTWEIGHT_NORMAL;
-    fnt->is_outlined = 0;
-    fnt->outline_width = 0.0;
-    fnt->red = 0.0;
-    fnt->green = 0.0;
-    fnt->blue = 0.0;
-    fnt->alpha = 1.0;
+    fnt->font_red = 0.0;
+    fnt->font_green = 0.0;
+    fnt->font_blue = 0.0;
+    fnt->font_alpha = 1.0;
+    fnt->with_halo = 0;
+    fnt->halo_radius = 0.0;
+    fnt->halo_red = 0.0;
+    fnt->halo_green = 0.0;
+    fnt->halo_blue = 0.0;
+    fnt->halo_alpha = 1.0;
     return (rl2GraphicsFontPtr) fnt;
 }
 
+RL2_DECLARE int
+rl2_graph_release_font (rl2GraphicsContextPtr context)
+{
+/* selecting a default font so to releasee the currently set Font */
+    cairo_t *cairo;
+    RL2GraphContextPtr ctx = (RL2GraphContextPtr) context;
+    if (ctx == NULL)
+	return 0;
+
+    if (ctx == NULL)
+	return 0;
+    if (ctx->type == RL2_SURFACE_PDF)
+	cairo = ctx->clip_cairo;
+    else
+	cairo = ctx->cairo;
+    cairo_select_font_face (cairo, "monospace", CAIRO_FONT_SLANT_NORMAL,
+			    CAIRO_FONT_WEIGHT_NORMAL);
+    cairo_set_font_size (cairo, 10.0);
+    return 1;
+}
+
 RL2_DECLARE void
 rl2_graph_destroy_font (rl2GraphicsFontPtr font)
 {
@@ -881,8 +1944,19 @@ rl2_graph_destroy_font (rl2GraphicsFontPtr font)
 
     if (fnt == NULL)
 	return;
-
-    free (fnt);
+    if (fnt->toy_font == 0)
+      {
+	  if (fnt->cairo_scaled_font != NULL)
+	      cairo_scaled_font_destroy (fnt->cairo_scaled_font);
+	  if (fnt->cairo_font != NULL)
+	      cairo_font_face_destroy (fnt->cairo_font);
+      }
+    else
+      {
+	  if (fnt->facename != NULL)
+	      free (fnt->facename);
+	  free (fnt);
+      }
 }
 
 RL2_DECLARE int
@@ -896,31 +1970,37 @@ rl2_graph_font_set_color (rl2GraphicsFontPtr font, unsigned char red,
     if (fnt == NULL)
 	return 0;
 
-    fnt->red = (double) red / 255.0;
-    fnt->green = (double) green / 255.0;
-    fnt->blue = (double) blue / 255.0;
-    fnt->alpha = (double) alpha / 255.0;
+    fnt->font_red = (double) red / 255.0;
+    fnt->font_green = (double) green / 255.0;
+    fnt->font_blue = (double) blue / 255.0;
+    fnt->font_alpha = (double) alpha / 255.0;
     return 1;
 }
 
 RL2_DECLARE int
-rl2_graph_font_set_outline (rl2GraphicsFontPtr font, double width)
+rl2_graph_font_set_halo (rl2GraphicsFontPtr font, double radius,
+			 unsigned char red, unsigned char green,
+			 unsigned char blue, unsigned char alpha)
 {
-/* setting up the font outline */
+/* setting up the font Halo */
     RL2GraphFontPtr fnt = (RL2GraphFontPtr) font;
 
     if (fnt == NULL)
 	return 0;
 
-    if (width <= 0.0)
+    if (radius <= 0.0)
       {
-	  fnt->is_outlined = 0;
-	  fnt->outline_width = 0.0;
+	  fnt->with_halo = 0;
+	  fnt->halo_radius = 0.0;
       }
     else
       {
-	  fnt->is_outlined = 1;
-	  fnt->outline_width = width;
+	  fnt->with_halo = 1;
+	  fnt->halo_radius = radius;
+	  fnt->halo_red = (double) red / 255.0;
+	  fnt->halo_green = (double) green / 255.0;
+	  fnt->halo_blue = (double) blue / 255.0;
+	  fnt->halo_alpha = (double) alpha / 255.0;
       }
     return 1;
 }
@@ -1009,6 +2089,30 @@ set_current_brush (RL2GraphContextPtr ctx)
       }
 }
 
+RL2_DECLARE int
+rl2_graph_release_pattern_brush (rl2GraphicsContextPtr context)
+{
+/* releasing the current Pattern Brush */
+    RL2GraphContextPtr ctx = (RL2GraphContextPtr) context;
+    cairo_t *cairo;
+    if (ctx == NULL)
+	return 0;
+    if (ctx->type == RL2_SURFACE_PDF)
+	cairo = ctx->clip_cairo;
+    else
+	cairo = ctx->cairo;
+    if (ctx->current_brush.is_pattern)
+      {
+	  ctx->current_brush.is_solid_color = 1;
+	  ctx->current_brush.is_pattern = 0;
+	  cairo_set_source_rgba (cairo, 0.0, 0.0, 0.0, 1.0);
+	  ctx->current_brush.pattern = NULL;
+	  return 1;
+      }
+    else
+	return 0;
+}
+
 static void
 set_current_pen (RL2GraphContextPtr ctx)
 {
@@ -1019,13 +2123,93 @@ set_current_pen (RL2GraphContextPtr ctx)
     else
 	cairo = ctx->cairo;
     cairo_set_line_width (cairo, ctx->current_pen.width);
-    cairo_set_source_rgba (cairo, ctx->current_pen.red,
-			   ctx->current_pen.green, ctx->current_pen.blue,
-			   ctx->current_pen.alpha);
-    cairo_set_line_cap (cairo, CAIRO_LINE_CAP_BUTT);
-    cairo_set_line_join (cairo, CAIRO_LINE_JOIN_MITER);
-    cairo_set_dash (cairo, ctx->current_pen.lengths,
-		    ctx->current_pen.lengths_count, 0.0);
+    if (ctx->current_pen.is_solid_color)
+      {
+	  /* using a Solid Color Pen */
+	  cairo_set_source_rgba (cairo, ctx->current_pen.red,
+				 ctx->current_pen.green,
+				 ctx->current_pen.blue, ctx->current_pen.alpha);
+      }
+    else if (ctx->current_pen.is_linear_gradient)
+      {
+	  /* using a Linear Gradient Pen */
+	  cairo_pattern_t *pattern =
+	      cairo_pattern_create_linear (ctx->current_pen.x0,
+					   ctx->current_pen.y0,
+					   ctx->current_pen.x1,
+					   ctx->current_pen.y1);
+	  cairo_pattern_add_color_stop_rgba (pattern, 0.0,
+					     ctx->current_pen.red,
+					     ctx->current_pen.green,
+					     ctx->current_pen.blue,
+					     ctx->current_pen.alpha);
+	  cairo_pattern_add_color_stop_rgba (pattern, 1.0,
+					     ctx->current_pen.red2,
+					     ctx->current_pen.green2,
+					     ctx->current_pen.blue2,
+					     ctx->current_pen.alpha2);
+	  cairo_set_source (cairo, pattern);
+	  cairo_pattern_destroy (pattern);
+      }
+    else if (ctx->current_pen.is_pattern)
+      {
+	  /* using a Pattern Pen */
+	  cairo_set_source (cairo, ctx->current_pen.pattern);
+      }
+    switch (ctx->current_pen.line_cap)
+      {
+      case RL2_PEN_CAP_ROUND:
+	  cairo_set_line_cap (cairo, CAIRO_LINE_CAP_ROUND);
+	  break;
+      case RL2_PEN_CAP_SQUARE:
+	  cairo_set_line_cap (cairo, CAIRO_LINE_CAP_SQUARE);
+	  break;
+      default:
+	  cairo_set_line_cap (cairo, CAIRO_LINE_CAP_BUTT);
+	  break;
+      };
+    switch (ctx->current_pen.line_join)
+      {
+      case RL2_PEN_JOIN_ROUND:
+	  cairo_set_line_join (cairo, CAIRO_LINE_JOIN_ROUND);
+	  break;
+      case RL2_PEN_JOIN_BEVEL:
+	  cairo_set_line_join (cairo, CAIRO_LINE_JOIN_BEVEL);
+	  break;
+      default:
+	  cairo_set_line_join (cairo, CAIRO_LINE_JOIN_MITER);
+	  break;
+      };
+    if (ctx->current_pen.dash_count == 0 || ctx->current_pen.dash_array == NULL)
+	cairo_set_dash (cairo, NULL, 0, 0.0);
+    else
+	cairo_set_dash (cairo, ctx->current_pen.dash_array,
+			ctx->current_pen.dash_count,
+			ctx->current_pen.dash_offset);
+}
+
+RL2_DECLARE int
+rl2_graph_release_pattern_pen (rl2GraphicsContextPtr context)
+{
+/* releasing the current Pattern Pen */
+    RL2GraphContextPtr ctx = (RL2GraphContextPtr) context;
+    cairo_t *cairo;
+    if (ctx == NULL)
+	return 0;
+    if (ctx->type == RL2_SURFACE_PDF)
+	cairo = ctx->clip_cairo;
+    else
+	cairo = ctx->cairo;
+    if (ctx->current_pen.is_pattern)
+      {
+	  ctx->current_pen.is_solid_color = 1;
+	  ctx->current_pen.is_pattern = 0;
+	  cairo_set_source_rgba (cairo, 0.0, 0.0, 0.0, 1.0);
+	  ctx->current_pen.pattern = NULL;
+	  return 1;
+      }
+    else
+	return 0;
 }
 
 RL2_DECLARE int
@@ -1111,8 +2295,8 @@ rl2_graph_draw_ellipse (rl2GraphicsContextPtr context, double x, double y,
 
 RL2_DECLARE int
 rl2_graph_draw_circle_sector (rl2GraphicsContextPtr context, double center_x,
-			      double center_y, double radius, double from_angle,
-			      double to_angle)
+			      double center_y, double radius,
+			      double from_angle, double to_angle)
 {
 /* drawing a filled circular sector */
     cairo_t *cairo;
@@ -1238,6 +2422,7 @@ rl2_graph_fill_path (rl2GraphicsContextPtr context, int preserve)
 	cairo = ctx->cairo;
 
     set_current_brush (ctx);
+    cairo_set_fill_rule (cairo, CAIRO_FILL_RULE_EVEN_ODD);
     if (preserve == RL2_PRESERVE_PATH)
 	cairo_fill_preserve (cairo);
     else
@@ -1257,6 +2442,8 @@ rl2_graph_get_text_extent (rl2GraphicsContextPtr context, const char *text,
 
     if (ctx == NULL)
 	return 0;
+    if (text == NULL)
+	return 0;
     if (ctx->type == RL2_SURFACE_PDF)
 	cairo = ctx->clip_cairo;
     else
@@ -1273,50 +2460,466 @@ rl2_graph_get_text_extent (rl2GraphicsContextPtr context, const char *text,
 }
 
 RL2_DECLARE int
-rl2_graph_draw_text (rl2GraphicsContextPtr context, const char *text, double x,
-		     double y, double angle)
+rl2_graph_draw_text (rl2GraphicsContextPtr context, const char *text,
+		     double x, double y, double angle, double anchor_point_x,
+		     double anchor_point_y)
 {
 /* drawing a text string (using the current font) */
+    double rads;
+    double pre_x;
+    double pre_y;
+    double width;
+    double height;
+    double post_x;
+    double post_y;
+    double center_x;
+    double center_y;
+    double cx;
+    double cy;
     cairo_t *cairo;
     RL2GraphContextPtr ctx = (RL2GraphContextPtr) context;
 
     if (ctx == NULL)
 	return 0;
+    if (text == NULL)
+	return 0;
     if (ctx->type == RL2_SURFACE_PDF)
 	cairo = ctx->clip_cairo;
     else
 	cairo = ctx->cairo;
 
+/* setting the Anchor Point */
+    rl2_graph_get_text_extent (ctx, text, &pre_x, &pre_y, &width, &height,
+			       &post_x, &post_y);
+    if (anchor_point_x < 0.0 || anchor_point_x > 1.0 || anchor_point_x == 0.5)
+	center_x = width / 2.0;
+    else
+	center_x = width * anchor_point_x;
+    if (anchor_point_y < 0.0 || anchor_point_y > 1.0 || anchor_point_y == 0.5)
+	center_y = height / 2.0;
+    else
+	center_y = height * anchor_point_y;
+    cx = 0.0 - center_x;
+    cy = 0.0 + center_y;
+
     cairo_save (cairo);
     cairo_translate (cairo, x, y);
-    cairo_rotate (cairo, angle);
-    if (ctx->is_font_outlined)
+    rads = angle * .0174532925199432958;
+    cairo_rotate (cairo, rads);
+    if (ctx->with_font_halo)
       {
-	  /* outlined font */
-	  cairo_move_to (cairo, 0.0, 0.0);
+	  /* font with Halo */
+	  cairo_move_to (cairo, cx, cy);
 	  cairo_text_path (cairo, text);
 	  cairo_set_source_rgba (cairo, ctx->font_red, ctx->font_green,
 				 ctx->font_blue, ctx->font_alpha);
 	  cairo_fill_preserve (cairo);
-	  cairo_set_source_rgba (cairo, 1.0, 1.0, 1.0, ctx->font_alpha);
-	  cairo_set_line_width (cairo, ctx->font_outline_width);
+	  cairo_set_source_rgba (cairo, ctx->halo_red, ctx->halo_green,
+				 ctx->halo_blue, ctx->halo_alpha);
+	  cairo_set_line_width (cairo, ctx->halo_radius);
 	  cairo_stroke (cairo);
       }
     else
       {
-	  /* no outline */
+	  /* no Halo */
 	  cairo_set_source_rgba (cairo, ctx->font_red, ctx->font_green,
 				 ctx->font_blue, ctx->font_alpha);
-	  cairo_move_to (cairo, 0.0, 0.0);
+	  cairo_move_to (cairo, cx, cy);
 	  cairo_show_text (cairo, text);
       }
     cairo_restore (cairo);
     return 1;
 }
 
+static void
+do_estimate_text_length (cairo_t * cairo, const char *text, double *length,
+			 double *extra)
+{
+/* estimating the text length */
+    const char *p = text;
+    int count = 0;
+    double radius = 0.0;
+    cairo_font_extents_t extents;
+
+    while (*p++ != '\0')
+	count++;
+    cairo_font_extents (cairo, &extents);
+    radius =
+	sqrt ((extents.max_x_advance * extents.max_x_advance) +
+	      (extents.height * extents.height)) / 2.0;
+    *length = radius * count;
+    *extra = radius;
+}
+
+static void
+get_aux_start_point (rl2GeometryPtr geom, double *x, double *y)
+{
+/* extracting the first point from a Curve */
+    double x0;
+    double y0;
+    rl2LinestringPtr ln = geom->first_linestring;
+    rl2GetPoint (ln->coords, 0, &x0, &y0);
+    *x = x0;
+    *y = y0;
+}
+
+static int
+get_aux_interception_point (sqlite3 * handle, rl2GeometryPtr geom,
+			    rl2GeometryPtr circle, double *x, double *y)
+{
+/* computing and interception point */
+    sqlite3_stmt *stmt = NULL;
+    const char *sql;
+    int ret;
+    unsigned char *blob1;
+    int size1;
+    unsigned char *blob2;
+    int size2;
+    int ok = 0;
+
+    rl2_serialize_linestring (geom->first_linestring, &blob1, &size1);
+    rl2_serialize_linestring (circle->first_linestring, &blob2, &size2);
+
+/* preparing the SQL query statement */
+    sql = "SELECT ST_Intersection(?, ?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	goto error;
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_blob (stmt, 1, blob1, size1, free);
+    sqlite3_bind_blob (stmt, 2, blob2, size2, free);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	    {
+		if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
+		  {
+		      const unsigned char *blob3 =
+			  sqlite3_column_blob (stmt, 0);
+		      int size3 = sqlite3_column_bytes (stmt, 0);
+		      rl2GeometryPtr result =
+			  rl2_geometry_from_blob (blob3, size3);
+		      if (result == NULL)
+			  break;
+		      if (result->first_point == NULL)
+			  break;
+		      *x = result->first_point->x;
+		      *y = result->first_point->y;
+		      ok = 1;
+		  }
+	    }
+	  else
+	      goto error;
+      }
+    if (ok == 0)
+	goto error;
+    sqlite3_finalize (stmt);
+    return 1;
+
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    return 0;
+}
+
+static int
+aux_is_discarded_portion (rl2LinestringPtr ln, double x, double y)
+{
+/* attempting to identify the already processed portion */
+    double xx;
+    double yy;
+    rl2GetPoint (ln->coords, 0, &xx, &yy);
+    if (xx == x && yy == y)
+	return 1;
+    rl2GetPoint (ln->coords, ln->points - 1, &xx, &yy);
+    if (xx == x && yy == y)
+	return 1;
+    return 0;
+}
+
+static rl2GeometryPtr
+aux_reduce_curve (sqlite3 * handle, rl2GeometryPtr geom,
+		  rl2GeometryPtr circle, double x, double y)
+{
+/* reducing a Curve by discarding the alreasdy processed portion */
+    sqlite3_stmt *stmt = NULL;
+    const char *sql;
+    int ret;
+    unsigned char *blob1;
+    int size1;
+    unsigned char *blob2;
+    int size2;
+    rl2GeometryPtr out = NULL;
+    rl2LinestringPtr ln;
+    rl2LinestringPtr save_ln = NULL;
+    int count = 0;
+
+    rl2_serialize_linestring (geom->first_linestring, &blob1, &size1);
+    rl2_serialize_linestring (circle->first_linestring, &blob2, &size2);
+
+/* preparing the SQL query statement */
+    sql = "SELECT ST_Split(?, ?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	goto error;
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_blob (stmt, 1, blob1, size1, free);
+    sqlite3_bind_blob (stmt, 2, blob2, size2, free);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	    {
+		if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
+		  {
+		      const unsigned char *blob3 =
+			  sqlite3_column_blob (stmt, 0);
+		      int size3 = sqlite3_column_bytes (stmt, 0);
+		      rl2GeometryPtr result =
+			  rl2_geometry_from_blob (blob3, size3);
+		      if (result == NULL)
+			  break;
+		      ln = result->first_linestring;
+		      while (ln != NULL)
+			{
+			    if (aux_is_discarded_portion (ln, x, y))
+				;
+			    else
+			      {
+				  save_ln = ln;
+				  count++;
+			      }
+			    ln = ln->next;
+			}
+		  }
+	    }
+	  else
+	      goto error;
+      }
+    if (save_ln == NULL || count != 1)
+	goto error;
+    out = rl2_clone_linestring (save_ln);
+    sqlite3_finalize (stmt);
+    return out;
+
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    return NULL;
+}
+
+static int
+check_reverse (rl2GeometryPtr geom)
+{
+/* testing for an inverse label */
+    rl2LinestringPtr ln;
+    double x0;
+    double y0;
+    double x1;
+    double y1;
+    double width;
+    double height;
+    int last;
+
+    if (geom == NULL)
+	return 0;
+    ln = geom->first_linestring;
+    if (ln == NULL)
+	return 0;
+    if (ln->points < 2)
+	return 0;
+    last = ln->points - 1;
+
+    rl2GetPoint (ln->coords, 0, &x0, &y0);
+    rl2GetPoint (ln->coords, last, &x1, &y1);
+    width = fabs (x0 - x1);
+    height = fabs (y0 - y1);
+    if (width > 3.0)
+      {
+	  if (x0 > x1)
+	      return 1;
+      }
+    else
+      {
+	  if (y0 > y1)
+	      return 1;
+      }
+    return 0;
+}
+
+static void
+reverse_text (const char *in, char *dest, int len)
+{
+/* reversing a text string */
+    char *out;
+    int n = 1;
+    while (*in != '\0')
+      {
+	  out = dest + len - n;
+	  *out = *in++;
+	  n++;
+      }
+    *(dest + len) = '\0';
+}
+
+static rl2GeometryPtr
+rl2_draw_wrapped_label (sqlite3 * handle, rl2GraphicsContextPtr context,
+			cairo_t * cairo, const char *text, rl2GeometryPtr geom)
+{
+/* placing each character along the modelling line */
+    double x0;
+    double y0;
+    double x1;
+    double y1;
+    double radius;
+    double m;
+    double rads;
+    double angle;
+    char buf[2];
+    rl2GeometryPtr g2;
+    rl2GeometryPtr g = rl2_clone_curve (geom);
+    rl2GeometryPtr circle;
+    char *rev_text = NULL;
+    const char *c = text;
+    cairo_font_extents_t extents;
+
+    cairo_font_extents (cairo, &extents);
+    radius =
+	sqrt ((extents.max_x_advance * extents.max_x_advance) +
+	      (extents.height * extents.height)) / 2.0;
+    if (check_reverse (g))
+      {
+	  /* reverse text */
+	  int len = strlen (text);
+	  rev_text = malloc (len + 1);
+	  reverse_text (text, rev_text, len);
+	  c = rev_text;
+      }
+    while (*c != '\0' && g != NULL)
+      {
+	  buf[0] = *c;
+	  buf[1] = '\0';
+	  get_aux_start_point (g, &x0, &y0);
+	  circle = rl2_build_circle (x0, y0, radius);
+	  if (!get_aux_interception_point (handle, g, circle, &x1, &y1))
+	    {
+		rl2_destroy_geometry (circle);
+		rl2_destroy_geometry (g);
+		g = NULL;
+		break;
+	    }
+	  m = (y1 - y0) / (x1 - x0);
+	  rads = atan (m);
+	  angle = rads / .0174532925199432958;
+	  if (x1 < x0 && rev_text == NULL)
+	      angle += 180.0;
+	  rl2_graph_draw_text (context, buf, x0, y0, angle, 0.5, 0.5);
+	  c++;
+	  g2 = aux_reduce_curve (handle, g, circle, x0, y0);
+	  rl2_destroy_geometry (circle);
+	  rl2_destroy_geometry (g);
+	  g = g2;
+      }
+    if (rev_text)
+	free (rev_text);
+    return g;
+}
+
+RL2_DECLARE int
+rl2_graph_draw_warped_text (sqlite3 * handle, rl2GraphicsContextPtr context,
+			    const char *text, int points, double *x,
+			    double *y, double initial_gap, double gap,
+			    int repeated)
+{
+/* drawing a text string warped along a modelling curve (using the current font) */
+    double curve_len;
+    double text_len;
+    double extra_len;
+    double start;
+    double from;
+    rl2GeometryPtr geom = NULL;
+    rl2GeometryPtr geom2 = NULL;
+    cairo_t *cairo;
+    RL2GraphContextPtr ctx = (RL2GraphContextPtr) context;
+
+    if (ctx == NULL)
+	return 0;
+    if (text == NULL)
+	return 0;
+    if (ctx->type == RL2_SURFACE_PDF)
+	cairo = ctx->clip_cairo;
+    else
+	cairo = ctx->cairo;
+
+    geom = rl2_curve_from_XY (points, x, y);
+    if (geom == NULL)
+	return 0;
+
+    curve_len = rl2_compute_curve_length (geom);
+    do_estimate_text_length (cairo, text, &text_len, &extra_len);
+    if ((initial_gap + text_len + (2.0 * extra_len)) > curve_len)
+	return 0;		/* not enough room to place the label */
+
+    if (repeated)
+      {
+	  /* repeated labels */
+	  int first = 1;
+	  rl2GeometryPtr geom3 = rl2_clone_linestring (geom->first_linestring);
+	  while (geom3 != NULL)
+	    {
+		if (first)
+		  {
+		      start = initial_gap + extra_len;
+		      first = 0;
+		  }
+		else
+		    start = gap + extra_len;
+		curve_len = rl2_compute_curve_length (geom3);
+		if ((start + text_len + extra_len) > curve_len)
+		    break;	/* not enough room to place the label */
+		from = start / curve_len;
+		/* extracting the sub-path modelling the label */
+		geom2 = rl2_curve_substring (handle, geom3, from, 1.0);
+		rl2_destroy_geometry (geom3);
+		if (geom2 == NULL)
+		    goto error;
+		geom3 =
+		    rl2_draw_wrapped_label (handle, context, cairo, text,
+					    geom2);
+		rl2_destroy_geometry (geom2);
+	    }
+      }
+    else
+      {
+	  /* single label */
+	  start = (curve_len - text_len) / 2.0;
+	  from = start / curve_len;
+	  /* extracting the sub-path modelling the label */
+	  geom2 = rl2_curve_substring (handle, geom, from, 1.0);
+	  if (geom2 == NULL)
+	      goto error;
+	  rl2_draw_wrapped_label (handle, context, cairo, text, geom2);
+	  rl2_destroy_geometry (geom2);
+      }
+
+    rl2_destroy_geometry (geom);
+    return 1;
+
+  error:
+    rl2_destroy_geometry (geom);
+    return 0;
+}
+
 RL2_DECLARE int
 rl2_graph_draw_bitmap (rl2GraphicsContextPtr context,
-		       rl2GraphicsBitmapPtr bitmap, int x, int y)
+		       rl2GraphicsBitmapPtr bitmap, double x, double y)
 {
 /* drawing a symbol bitmap */
     cairo_t *cairo;
@@ -1353,7 +2956,7 @@ rl2_graph_draw_bitmap (rl2GraphicsContextPtr context,
 RL2_DECLARE int
 rl2_graph_draw_rescaled_bitmap (rl2GraphicsContextPtr context,
 				rl2GraphicsBitmapPtr bitmap, double scale_x,
-				double scale_y, int x, int y)
+				double scale_y, double x, double y)
 {
 /* drawing a rescaled bitmap */
     cairo_t *cairo;
@@ -1386,6 +2989,247 @@ rl2_graph_draw_rescaled_bitmap (rl2GraphicsContextPtr context,
     return 1;
 }
 
+RL2_DECLARE int
+rl2_graph_draw_graphic_symbol (rl2GraphicsContextPtr context,
+			       rl2GraphicsPatternPtr symbol, double width,
+			       double height, double x,
+			       double y, double angle,
+			       double anchor_point_x, double anchor_point_y)
+{
+/* drawing a Graphic Symbol */
+    double rads;
+    double scale_x;
+    double scale_y;
+    double center_x;
+    double center_y;
+    cairo_t *cairo;
+    cairo_surface_t *surface;
+    RL2GraphContextPtr ctx = (RL2GraphContextPtr) context;
+    RL2PrivGraphPatternPtr pattern = (RL2PrivGraphPatternPtr) symbol;
+
+    if (ctx == NULL)
+	return 0;
+    if (pattern == NULL)
+	return 0;
+    if (ctx->type == RL2_SURFACE_PDF)
+      {
+	  surface = ctx->clip_surface;
+	  cairo = ctx->clip_cairo;
+      }
+    else
+      {
+	  surface = ctx->surface;
+	  cairo = ctx->cairo;
+      }
+
+/* setting the Anchor Point */
+    scale_x = width / (double) (pattern->width);
+    scale_y = height / (double) (pattern->height);
+    if (anchor_point_x < 0.0 || anchor_point_x > 1.0 || anchor_point_x == 0.5)
+	center_x = (double) (pattern->width) / 2.0;
+    else
+	center_x = (double) (pattern->width) * anchor_point_x;
+    if (anchor_point_y < 0.0 || anchor_point_y > 1.0 || anchor_point_y == 0.5)
+	center_y = (double) (pattern->height) / 2.0;
+    else
+	center_y = (double) (pattern->height) * anchor_point_y;
+
+    cairo_save (cairo);
+    cairo_translate (cairo, x, y);
+    cairo_scale (cairo, scale_x, scale_y);
+    rads = angle * .0174532925199432958;
+    cairo_rotate (cairo, rads);
+    cairo_translate (cairo, 0.0 - center_x, 0.0 - center_y);
+    cairo_set_source (cairo, pattern->pattern);
+    cairo_paint (cairo);
+    cairo_restore (cairo);
+    cairo_surface_flush (surface);
+
+    return 1;
+}
+
+RL2_DECLARE int
+rl2_graph_draw_mark_symbol (rl2GraphicsContextPtr context, int mark_type,
+			    double size,
+			    double x, double y,
+			    double angle,
+			    double anchor_point_x,
+			    double anchor_point_y, int fill, int stroke)
+{
+/* drawing a Mark Symbol */
+    double xsize;
+    double size2 = size / 2.0;
+    double size4 = size / 4.0;
+    double size6 = size / 6.0;
+    double size8 = size / 8.0;
+    double size13 = size / 3.0;
+    double size23 = (size / 3.0) * 2.0;
+    int i;
+    double rads;
+    double center_x;
+    double center_y;
+    cairo_t *cairo;
+    cairo_surface_t *surface;
+    RL2GraphContextPtr ctx = (RL2GraphContextPtr) context;
+
+    if (ctx == NULL)
+	return 0;
+    if (ctx->type == RL2_SURFACE_PDF)
+      {
+	  surface = ctx->clip_surface;
+	  cairo = ctx->clip_cairo;
+      }
+    else
+      {
+	  surface = ctx->surface;
+	  cairo = ctx->cairo;
+      }
+    cairo_save (cairo);
+    cairo_translate (cairo, x, y);
+    rads = angle * .0174532925199432958;
+    cairo_rotate (cairo, rads);
+
+/* setting the Anchor Point */
+    xsize = size;
+    if (mark_type == RL2_GRAPHIC_MARK_CIRCLE
+	|| mark_type == RL2_GRAPHIC_MARK_TRIANGLE
+	|| mark_type == RL2_GRAPHIC_MARK_STAR)
+	xsize = size23 * 2.0;
+    if (anchor_point_x < 0.0 || anchor_point_x > 1.0 || anchor_point_x == 0.5)
+	center_x = 0.0;
+    else
+	center_x = 0.0 + (xsize / 2.0) - (xsize * anchor_point_x);
+    if (anchor_point_y < 0.0 || anchor_point_y > 1.0 || anchor_point_y == 0.5)
+	center_y = 0.0;
+    else
+	center_y = 0.0 - (xsize / 2.0) + (xsize * anchor_point_y);
+    x = center_x;
+    y = center_y;
+    if (size2 <= 0.0)
+	size2 = 1.0;
+    if (size4 <= 0.0)
+	size4 = 1.0;
+    if (size6 <= 0.0)
+	size6 = 1.0;
+    if (size13 <= 0.0)
+	size13 = 1.0;
+    if (size23 <= 0.0)
+	size23 = 1.0;
+
+/* preparing the Mark Symbol path */
+    switch (mark_type)
+      {
+      case RL2_GRAPHIC_MARK_CIRCLE:
+	  rads = 0.0;
+	  for (i = 0; i < 32; i++)
+	    {
+		double tic = 6.28318530718 / 32.0;
+		double cx = x + (size23 * sin (rads));
+		double cy = y + (size23 * cos (rads));
+		if (i == 0)
+		    rl2_graph_move_to_point (ctx, cx, cy);
+		else
+		    rl2_graph_add_line_to_path (ctx, cx, cy);
+		rads += tic;
+	    }
+	  rl2_graph_close_subpath (ctx);
+	  break;
+      case RL2_GRAPHIC_MARK_TRIANGLE:
+	  rads = 0.0;
+	  for (i = 0; i < 3; i++)
+	    {
+		double tic = 6.28318530718 / 3.0;
+		double cx = x + (size23 * sin (rads));
+		double cy = y + (size23 * cos (rads));
+		if (i == 0)
+		    rl2_graph_move_to_point (ctx, cx, cy);
+		else
+		    rl2_graph_add_line_to_path (ctx, cx, cy);
+		rads += tic;
+	    }
+	  rl2_graph_close_subpath (ctx);
+	  break;
+      case RL2_GRAPHIC_MARK_STAR:
+	  rads = 3.14159265359;
+	  for (i = 0; i < 10; i++)
+	    {
+		double tic = (i % 2) ? size4 : size23;
+		double cx = x + (tic * sin (rads));
+		double cy = y + (tic * cos (rads));
+		if (i == 0)
+		    rl2_graph_move_to_point (ctx, cx, cy);
+		else
+		    rl2_graph_add_line_to_path (ctx, cx, cy);
+		rads += 0.628318530718;
+	    }
+	  rl2_graph_close_subpath (ctx);
+	  break;
+      case RL2_GRAPHIC_MARK_CROSS:
+	  rl2_graph_move_to_point (ctx, x - size8, y - size2);
+	  rl2_graph_add_line_to_path (ctx, x + size8, y - size2);
+	  rl2_graph_add_line_to_path (ctx, x + size8, y - size8);
+	  rl2_graph_add_line_to_path (ctx, x + size2, y - size8);
+	  rl2_graph_add_line_to_path (ctx, x + size2, y + size8);
+	  rl2_graph_add_line_to_path (ctx, x + size8, y + size8);
+	  rl2_graph_add_line_to_path (ctx, x + size8, y + size2);
+	  rl2_graph_add_line_to_path (ctx, x - size8, y + size2);
+	  rl2_graph_add_line_to_path (ctx, x - size8, y + size8);
+	  rl2_graph_add_line_to_path (ctx, x - size2, y + size8);
+	  rl2_graph_add_line_to_path (ctx, x - size2, y - size8);
+	  rl2_graph_add_line_to_path (ctx, x - size8, y - size8);
+	  rl2_graph_close_subpath (ctx);
+	  break;
+      case RL2_GRAPHIC_MARK_X:
+	  rl2_graph_move_to_point (ctx, x, y - size6);
+	  rl2_graph_add_line_to_path (ctx, x - size4, y - size2);
+	  rl2_graph_add_line_to_path (ctx, x - size2, y - size2);
+	  rl2_graph_add_line_to_path (ctx, x - size8, y);
+	  rl2_graph_add_line_to_path (ctx, x - size2, y + size2);
+	  rl2_graph_add_line_to_path (ctx, x - size4, y + size2);
+	  rl2_graph_add_line_to_path (ctx, x, y + size6);
+	  rl2_graph_add_line_to_path (ctx, x + size4, y + size2);
+	  rl2_graph_add_line_to_path (ctx, x + size2, y + size2);
+	  rl2_graph_add_line_to_path (ctx, x + size8, y);
+	  rl2_graph_add_line_to_path (ctx, x + size2, y - size2);
+	  rl2_graph_add_line_to_path (ctx, x + size4, y - size2);
+	  rl2_graph_close_subpath (ctx);
+	  break;
+      case RL2_GRAPHIC_MARK_SQUARE:
+      default:
+	  rl2_graph_move_to_point (ctx, x - size2, y - size2);
+	  rl2_graph_add_line_to_path (ctx, x - size2, y + size2);
+	  rl2_graph_add_line_to_path (ctx, x + size2, y + size2);
+	  rl2_graph_add_line_to_path (ctx, x + size2, y - size2);
+	  rl2_graph_close_subpath (ctx);
+	  break;
+      };
+
+/* fillingt and stroking the path */
+    if (fill && !stroke)
+	rl2_graph_fill_path (ctx, RL2_CLEAR_PATH);
+    else if (stroke && !fill)
+	rl2_graph_stroke_path (ctx, RL2_CLEAR_PATH);
+    else
+      {
+	  rl2_graph_fill_path (ctx, RL2_PRESERVE_PATH);
+	  rl2_graph_stroke_path (ctx, RL2_CLEAR_PATH);
+      }
+    cairo_restore (cairo);
+    cairo_surface_flush (surface);
+
+    return 1;
+}
+
+static unsigned char
+unpremultiply (unsigned char c, unsigned char a)
+{
+/* Cairo has premultiplied alphas */
+    double x = ((double) c * 255.0) / (double) a;
+    if (a == 0)
+	return 0;
+    return (unsigned char) x;
+}
+
 RL2_DECLARE unsigned char *
 rl2_graph_get_context_rgb_array (rl2GraphicsContextPtr context)
 {
@@ -1418,30 +3262,32 @@ rl2_graph_get_context_rgb_array (rl2GraphicsContextPtr context)
 		unsigned char r;
 		unsigned char g;
 		unsigned char b;
+		unsigned char a;
 		if (little_endian)
 		  {
 		      b = *p_in++;
 		      g = *p_in++;
 		      r = *p_in++;
-		      p_in++;	/* skipping Alpha */
+		      a = *p_in++;
 		  }
 		else
 		  {
-		      p_in++;	/* skipping Alpha */
+		      a = *p_in++;
 		      r = *p_in++;
 		      g = *p_in++;
 		      b = *p_in++;
 		  }
-		*p_out++ = r;
-		*p_out++ = g;
-		*p_out++ = b;
+		*p_out++ = unpremultiply (r, a);
+		*p_out++ = unpremultiply (g, a);
+		*p_out++ = unpremultiply (b, a);
 	    }
       }
     return rgb;
 }
 
 RL2_DECLARE unsigned char *
-rl2_graph_get_context_alpha_array (rl2GraphicsContextPtr context)
+rl2_graph_get_context_alpha_array (rl2GraphicsContextPtr context,
+				   int *half_transparent)
 {
 /* creating an Alpha buffer from the given Context */
     int width;
@@ -1451,8 +3297,10 @@ rl2_graph_get_context_alpha_array (rl2GraphicsContextPtr context)
     unsigned char *p_in;
     unsigned char *p_out;
     unsigned char *alpha;
+    int real_alpha = 0;
     int little_endian = rl2cr_endian_arch ();
     RL2GraphContextPtr ctx = (RL2GraphContextPtr) context;
+    *half_transparent = 0;
 
     if (ctx == NULL)
 	return NULL;
@@ -1472,15 +3320,21 @@ rl2_graph_get_context_alpha_array (rl2GraphicsContextPtr context)
 		if (little_endian)
 		  {
 		      p_in += 3;	/* skipping RGB */
+		      if (*p_in >= 1 && *p_in <= 254)
+			  real_alpha = 1;
 		      *p_out++ = *p_in++;
 		  }
 		else
 		  {
+		      if (*p_in >= 1 && *p_in <= 254)
+			  real_alpha = 1;
 		      *p_out++ = *p_in++;
 		      p_in += 3;	/* skipping RGB */
 		  }
 	    }
       }
+    if (real_alpha)
+	*half_transparent = 1;
     return alpha;
 }
 
@@ -1649,7 +3503,8 @@ rl2_gray_pdf (unsigned int width, unsigned int height, unsigned char **pdf,
 					  1.0, 1.0);
     if (ctx == NULL)
 	goto error;
-    rl2_graph_set_pen (ctx, 255, 0, 0, 255, 2.0, RL2_PENSTYLE_SOLID);
+    rl2_graph_set_solid_pen (ctx, 255, 0, 0, 255, 2.0, RL2_PEN_CAP_BUTT,
+			     RL2_PEN_JOIN_MITER);
     rl2_graph_set_brush (ctx, 128, 128, 128, 255);
     rl2_graph_draw_rounded_rectangle (ctx, 0, 0, width, height, width / 10.0);
 
@@ -1713,3 +3568,48 @@ rl2_get_mem_pdf_buffer (rl2MemPdfPtr target, unsigned char **buffer, int *size)
     *size = mem->write_offset;
     return RL2_OK;
 }
+
+RL2_DECLARE void *
+rl2_alloc_private (void)
+{
+/* allocating and initializing default private connection data */
+    FT_Error error;
+    FT_Library library;
+    struct rl2_private_data *priv_data =
+	malloc (sizeof (struct rl2_private_data));
+    if (priv_data == NULL)
+	return NULL;
+    priv_data->max_threads = 1;
+/* initializing FreeType */
+    error = FT_Init_FreeType (&library);
+    if (error)
+	priv_data->FTlibrary = NULL;
+    else
+	priv_data->FTlibrary = library;
+    priv_data->first_font = NULL;
+    priv_data->last_font = NULL;
+    return priv_data;
+}
+
+RL2_DECLARE void
+rl2_cleanup_private (const void *ptr)
+{
+/* destroying private connection data */
+    struct rl2_private_tt_font *pF;
+    struct rl2_private_tt_font *pFn;
+    struct rl2_private_data *priv_data = (struct rl2_private_data *) ptr;
+    if (priv_data == NULL)
+	return;
+
+/* cleaning the internal Font Cache */
+    pF = priv_data->first_font;
+    while (pF != NULL)
+      {
+	  pFn = pF->next;
+	  rl2_destroy_private_tt_font (pF);
+	  pF = pFn;
+      }
+    if (priv_data->FTlibrary != NULL)
+	FT_Done_FreeType ((FT_Library) (priv_data->FTlibrary));
+    free (priv_data);
+}
diff --git a/src/rl2png.c b/src/rl2png.c
index ea78674..9d0e508 100644
--- a/src/rl2png.c
+++ b/src/rl2png.c
@@ -20,7 +20,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -117,7 +117,7 @@ compress_palette_png (const unsigned char *pixels, unsigned int width,
 /* compressing a PNG image of the PALETTE type */
     png_structp png_ptr;
     png_infop info_ptr;
-    int bit_depth;
+    int bit_depth = 0;
     png_bytep *row_pointers = NULL;
     png_bytep p_out;
     unsigned int row;
@@ -228,13 +228,13 @@ compress_palette_png (const unsigned char *pixels, unsigned int width,
 }
 
 static int
-compress_grayscale_png (const unsigned char *pixels, const unsigned char *mask,
-			double opacity, unsigned int width,
-			unsigned int height, unsigned char sample_type,
-			unsigned char pixel_type, unsigned char **png,
-			int *png_size)
+compress_grayscale_png8 (const unsigned char *pixels,
+			 const unsigned char *mask, double opacity,
+			 unsigned int width, unsigned int height,
+			 unsigned char sample_type, unsigned char pixel_type,
+			 unsigned char **png, int *png_size)
 {
-/* compressing a PNG image of the GRAYSCALE type */
+/* compressing a PNG image of the GRAYSCALE type - 8 bits */
     png_structp png_ptr;
     png_infop info_ptr;
     int bit_depth;
@@ -361,11 +361,101 @@ compress_grayscale_png (const unsigned char *pixels, const unsigned char *mask,
 }
 
 static int
-compress_rgb_png (const unsigned char *pixels, const unsigned char *mask,
-		  double opacity, unsigned int width, unsigned int height,
-		  unsigned char **png, int *png_size)
+compress_grayscale_png16 (const unsigned char *pixels, unsigned int width,
+			  unsigned int height, unsigned char sample_type,
+			  unsigned char **png, int *png_size)
 {
-/* compressing a PNG image of the RGB type */
+/* compressing a PNG image of the GRAYSCALE type - 16 bits */
+    png_structp png_ptr;
+    png_infop info_ptr;
+    int bit_depth;
+    png_bytep *row_pointers = NULL;
+    png_bytep p_out;
+    unsigned int row;
+    unsigned int col;
+    const unsigned short *p_in;
+    int nBands;
+    int type;
+    struct png_memory_buffer membuf;
+    membuf.buffer = NULL;
+    membuf.size = 0;
+
+    png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+    if (!png_ptr)
+	return RL2_ERROR;
+    info_ptr = png_create_info_struct (png_ptr);
+    if (!info_ptr)
+      {
+	  png_destroy_write_struct (&png_ptr, NULL);
+	  return RL2_ERROR;
+      }
+    if (setjmp (png_jmpbuf (png_ptr)))
+      {
+	  goto error;
+      }
+
+    png_set_write_fn (png_ptr, &membuf, rl2_png_write_data, rl2_png_flush);
+    switch (sample_type)
+      {
+      case RL2_SAMPLE_UINT8:
+	  bit_depth = 8;
+	  break;
+      case RL2_SAMPLE_UINT16:
+	  bit_depth = 16;
+	  break;
+      };
+    type = PNG_COLOR_TYPE_GRAY;
+    nBands = 1;
+    png_set_IHDR (png_ptr, info_ptr, width, height, bit_depth,
+		  type, PNG_INTERLACE_NONE,
+		  PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+    png_write_info (png_ptr, info_ptr);
+    png_set_packing (png_ptr);
+    row_pointers = malloc (sizeof (png_bytep) * height);
+    if (row_pointers == NULL)
+	goto error;
+    for (row = 0; row < height; ++row)
+	row_pointers[row] = NULL;
+    p_in = (unsigned short *) pixels;
+    for (row = 0; row < height; row++)
+      {
+	  if ((row_pointers[row] = malloc (width * nBands * 2)) == NULL)
+	      goto error;
+	  p_out = row_pointers[row];
+	  for (col = 0; col < width; col++)
+	    {
+		unsigned int value = *p_in++;
+		png_save_uint_16 (p_out, value);
+		p_out += 2;
+	    }
+      }
+
+    png_write_image (png_ptr, row_pointers);
+    png_write_end (png_ptr, info_ptr);
+    for (row = 0; row < height; ++row)
+	free (row_pointers[row]);
+    free (row_pointers);
+    png_destroy_write_struct (&png_ptr, &info_ptr);
+    *png = membuf.buffer;
+    *png_size = membuf.size;
+    return RL2_OK;
+
+  error:
+    png_destroy_write_struct (&png_ptr, &info_ptr);
+    for (row = 0; row < height; ++row)
+	free (row_pointers[row]);
+    free (row_pointers);
+    if (membuf.buffer != NULL)
+	free (membuf.buffer);
+    return RL2_ERROR;
+}
+
+static int
+compress_rgb_png8 (const unsigned char *pixels, const unsigned char *mask,
+		   double opacity, unsigned int width, unsigned int height,
+		   unsigned char **png, int *png_size)
+{
+/* compressing a PNG image of the RGB type - 8 bits */
     png_structp png_ptr;
     png_infop info_ptr;
     png_bytep *row_pointers = NULL;
@@ -464,6 +554,330 @@ compress_rgb_png (const unsigned char *pixels, const unsigned char *mask,
 }
 
 static int
+compress_rgba_png8 (const unsigned char *pixels, const unsigned char *alpha,
+		    unsigned int width, unsigned int height,
+		    unsigned char **png, int *png_size)
+{
+/* compressing a PNG image of the RGBA type - 8 bits */
+    png_structp png_ptr;
+    png_infop info_ptr;
+    png_bytep *row_pointers = NULL;
+    png_bytep p_out;
+    unsigned int row;
+    unsigned int col;
+    const unsigned char *p_in;
+    const unsigned char *p_alpha;
+    int nBands;
+    int type;
+    struct png_memory_buffer membuf;
+    membuf.buffer = NULL;
+    membuf.size = 0;
+
+    png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+    if (!png_ptr)
+	return RL2_ERROR;
+    info_ptr = png_create_info_struct (png_ptr);
+    if (!info_ptr)
+      {
+	  png_destroy_write_struct (&png_ptr, NULL);
+	  return RL2_ERROR;
+      }
+    if (setjmp (png_jmpbuf (png_ptr)))
+      {
+	  goto error;
+      }
+
+    png_set_write_fn (png_ptr, &membuf, rl2_png_write_data, rl2_png_flush);
+    type = PNG_COLOR_TYPE_RGB_ALPHA;
+    nBands = 4;
+    png_set_IHDR (png_ptr, info_ptr, width, height, 8,
+		  type, PNG_INTERLACE_NONE,
+		  PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+    png_write_info (png_ptr, info_ptr);
+    row_pointers = malloc (sizeof (png_bytep) * height);
+    if (row_pointers == NULL)
+	goto error;
+    for (row = 0; row < height; ++row)
+	row_pointers[row] = NULL;
+    p_in = pixels;
+    p_alpha = alpha;
+    for (row = 0; row < height; row++)
+      {
+	  if ((row_pointers[row] = malloc (width * nBands)) == NULL)
+	      goto error;
+	  p_out = row_pointers[row];
+	  for (col = 0; col < width; col++)
+	    {
+		*p_out++ = *p_in++;
+		*p_out++ = *p_in++;
+		*p_out++ = *p_in++;
+		*p_out++ = *p_alpha++;
+	    }
+      }
+    png_write_image (png_ptr, row_pointers);
+    png_write_end (png_ptr, info_ptr);
+    for (row = 0; row < height; ++row)
+	free (row_pointers[row]);
+    free (row_pointers);
+    png_destroy_write_struct (&png_ptr, &info_ptr);
+    *png = membuf.buffer;
+    *png_size = membuf.size;
+    return RL2_OK;
+
+  error:
+    png_destroy_write_struct (&png_ptr, &info_ptr);
+    for (row = 0; row < height; ++row)
+	free (row_pointers[row]);
+    free (row_pointers);
+    if (membuf.buffer != NULL)
+	free (membuf.buffer);
+    return RL2_ERROR;
+}
+
+static int
+compress_rgb_png16 (const unsigned char *pixels, unsigned int width,
+		    unsigned int height, unsigned char **png, int *png_size)
+{
+/* compressing a PNG image of the RGB type - 16 bits */
+    png_structp png_ptr;
+    png_infop info_ptr;
+    png_bytep *row_pointers = NULL;
+    png_bytep p_out;
+    unsigned int row;
+    unsigned int col;
+    const unsigned short *p_in;
+    int nBands;
+    int type;
+    struct png_memory_buffer membuf;
+    membuf.buffer = NULL;
+    membuf.size = 0;
+
+    png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+    if (!png_ptr)
+	return RL2_ERROR;
+    info_ptr = png_create_info_struct (png_ptr);
+    if (!info_ptr)
+      {
+	  png_destroy_write_struct (&png_ptr, NULL);
+	  return RL2_ERROR;
+      }
+    if (setjmp (png_jmpbuf (png_ptr)))
+      {
+	  goto error;
+      }
+
+    png_set_write_fn (png_ptr, &membuf, rl2_png_write_data, rl2_png_flush);
+    type = PNG_COLOR_TYPE_RGB;
+    nBands = 3;
+    png_set_IHDR (png_ptr, info_ptr, width, height, 16,
+		  type, PNG_INTERLACE_NONE,
+		  PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+    png_write_info (png_ptr, info_ptr);
+    row_pointers = malloc (sizeof (png_bytep) * height);
+    if (row_pointers == NULL)
+	goto error;
+    for (row = 0; row < height; ++row)
+	row_pointers[row] = NULL;
+    p_in = (unsigned short *) pixels;
+    for (row = 0; row < height; row++)
+      {
+	  if ((row_pointers[row] = malloc (width * nBands * 2)) == NULL)
+	      goto error;
+	  p_out = row_pointers[row];
+	  for (col = 0; col < width; col++)
+	    {
+		unsigned int value = *p_in++;
+		png_save_uint_16 (p_out, value);
+		p_out += 2;
+		value = *p_in++;
+		png_save_uint_16 (p_out, value);
+		p_out += 2;
+		value = *p_in++;
+		png_save_uint_16 (p_out, value);
+		p_out += 2;
+	    }
+      }
+    png_write_image (png_ptr, row_pointers);
+    png_write_end (png_ptr, info_ptr);
+    for (row = 0; row < height; ++row)
+	free (row_pointers[row]);
+    free (row_pointers);
+    png_destroy_write_struct (&png_ptr, &info_ptr);
+    *png = membuf.buffer;
+    *png_size = membuf.size;
+    return RL2_OK;
+
+  error:
+    png_destroy_write_struct (&png_ptr, &info_ptr);
+    for (row = 0; row < height; ++row)
+	free (row_pointers[row]);
+    free (row_pointers);
+    if (membuf.buffer != NULL)
+	free (membuf.buffer);
+    return RL2_ERROR;
+}
+
+static int
+compress_4bands_png8 (const unsigned char *pixels, unsigned int width,
+		      unsigned int height, unsigned char **png, int *png_size)
+{
+/* compressing a PNG image of the 4-bands type - 8 bits */
+    png_structp png_ptr;
+    png_infop info_ptr;
+    png_bytep *row_pointers = NULL;
+    png_bytep p_out;
+    unsigned int row;
+    unsigned int col;
+    const unsigned char *p_in;
+    int type;
+    struct png_memory_buffer membuf;
+    membuf.buffer = NULL;
+    membuf.size = 0;
+
+    png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+    if (!png_ptr)
+	return RL2_ERROR;
+    info_ptr = png_create_info_struct (png_ptr);
+    if (!info_ptr)
+      {
+	  png_destroy_write_struct (&png_ptr, NULL);
+	  return RL2_ERROR;
+      }
+    if (setjmp (png_jmpbuf (png_ptr)))
+      {
+	  goto error;
+      }
+
+    png_set_write_fn (png_ptr, &membuf, rl2_png_write_data, rl2_png_flush);
+    type = PNG_COLOR_TYPE_RGB_ALPHA;
+    png_set_IHDR (png_ptr, info_ptr, width, height, 8,
+		  type, PNG_INTERLACE_NONE,
+		  PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+    png_write_info (png_ptr, info_ptr);
+    row_pointers = malloc (sizeof (png_bytep) * height);
+    if (row_pointers == NULL)
+	goto error;
+    for (row = 0; row < height; ++row)
+	row_pointers[row] = NULL;
+    p_in = pixels;
+    for (row = 0; row < height; row++)
+      {
+	  if ((row_pointers[row] = malloc (width * 4)) == NULL)
+	      goto error;
+	  p_out = row_pointers[row];
+	  for (col = 0; col < width; col++)
+	    {
+		*p_out++ = *p_in++;
+		*p_out++ = *p_in++;
+		*p_out++ = *p_in++;
+		*p_out++ = *p_in++;
+	    }
+      }
+    png_write_image (png_ptr, row_pointers);
+    png_write_end (png_ptr, info_ptr);
+    for (row = 0; row < height; ++row)
+	free (row_pointers[row]);
+    free (row_pointers);
+    png_destroy_write_struct (&png_ptr, &info_ptr);
+    *png = membuf.buffer;
+    *png_size = membuf.size;
+    return RL2_OK;
+
+  error:
+    png_destroy_write_struct (&png_ptr, &info_ptr);
+    for (row = 0; row < height; ++row)
+	free (row_pointers[row]);
+    free (row_pointers);
+    if (membuf.buffer != NULL)
+	free (membuf.buffer);
+    return RL2_ERROR;
+}
+
+static int
+compress_4bands_png16 (const unsigned char *pixels, unsigned int width,
+		       unsigned int height, unsigned char **png, int *png_size)
+{
+/* compressing a PNG image of the 4-bands type - 16 bits */
+    png_structp png_ptr;
+    png_infop info_ptr;
+    png_bytep *row_pointers = NULL;
+    png_bytep p_out;
+    unsigned int row;
+    unsigned int col;
+    const unsigned short *p_in;
+    int type;
+    struct png_memory_buffer membuf;
+    membuf.buffer = NULL;
+    membuf.size = 0;
+
+    png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+    if (!png_ptr)
+	return RL2_ERROR;
+    info_ptr = png_create_info_struct (png_ptr);
+    if (!info_ptr)
+      {
+	  png_destroy_write_struct (&png_ptr, NULL);
+	  return RL2_ERROR;
+      }
+    if (setjmp (png_jmpbuf (png_ptr)))
+      {
+	  goto error;
+      }
+
+    png_set_write_fn (png_ptr, &membuf, rl2_png_write_data, rl2_png_flush);
+    type = PNG_COLOR_TYPE_RGB_ALPHA;
+    png_set_IHDR (png_ptr, info_ptr, width, height, 16,
+		  type, PNG_INTERLACE_NONE,
+		  PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+    png_write_info (png_ptr, info_ptr);
+    row_pointers = malloc (sizeof (png_bytep) * height);
+    if (row_pointers == NULL)
+	goto error;
+    for (row = 0; row < height; ++row)
+	row_pointers[row] = NULL;
+    p_in = (unsigned short *) pixels;
+    for (row = 0; row < height; row++)
+      {
+	  if ((row_pointers[row] = malloc (width * 4 * 2)) == NULL)
+	      goto error;
+	  p_out = row_pointers[row];
+	  for (col = 0; col < width; col++)
+	    {
+		unsigned int value = *p_in++;
+		png_save_uint_16 (p_out, value);
+		p_out += 2;
+		value = *p_in++;
+		png_save_uint_16 (p_out, value);
+		p_out += 2;
+		value = *p_in++;
+		png_save_uint_16 (p_out, value);
+		p_out += 2;
+		value = *p_in++;
+		png_save_uint_16 (p_out, value);
+		p_out += 2;
+	    }
+      }
+    png_write_image (png_ptr, row_pointers);
+    png_write_end (png_ptr, info_ptr);
+    for (row = 0; row < height; ++row)
+	free (row_pointers[row]);
+    free (row_pointers);
+    png_destroy_write_struct (&png_ptr, &info_ptr);
+    *png = membuf.buffer;
+    *png_size = membuf.size;
+    return RL2_OK;
+
+  error:
+    png_destroy_write_struct (&png_ptr, &info_ptr);
+    for (row = 0; row < height; ++row)
+	free (row_pointers[row]);
+    free (row_pointers);
+    if (membuf.buffer != NULL)
+	free (membuf.buffer);
+    return RL2_ERROR;
+}
+
+static int
 check_png_compatibility (unsigned char sample_type, unsigned char pixel_type,
 			 unsigned char num_samples)
 {
@@ -474,6 +888,7 @@ check_png_compatibility (unsigned char sample_type, unsigned char pixel_type,
       case RL2_SAMPLE_2_BIT:
       case RL2_SAMPLE_4_BIT:
       case RL2_SAMPLE_UINT8:
+      case RL2_SAMPLE_UINT16:
 	  break;
       default:
 	  return RL2_ERROR;
@@ -484,6 +899,8 @@ check_png_compatibility (unsigned char sample_type, unsigned char pixel_type,
       case RL2_PIXEL_PALETTE:
       case RL2_PIXEL_GRAYSCALE:
       case RL2_PIXEL_RGB:
+      case RL2_PIXEL_MULTIBAND:
+      case RL2_PIXEL_DATAGRID:
 	  break;
       default:
 	  return RL2_ERROR;
@@ -534,6 +951,7 @@ check_png_compatibility (unsigned char sample_type, unsigned char pixel_type,
 	  switch (sample_type)
 	    {
 	    case RL2_SAMPLE_UINT8:
+	    case RL2_SAMPLE_UINT16:
 		break;
 	    default:
 		return RL2_ERROR;
@@ -541,6 +959,32 @@ check_png_compatibility (unsigned char sample_type, unsigned char pixel_type,
 	  if (num_samples != 3)
 	      return RL2_ERROR;
       }
+    if (pixel_type == RL2_PIXEL_MULTIBAND)
+      {
+	  switch (sample_type)
+	    {
+	    case RL2_SAMPLE_UINT8:
+	    case RL2_SAMPLE_UINT16:
+		break;
+	    default:
+		return RL2_ERROR;
+	    };
+	  if (num_samples == 3 || num_samples == 4)
+	      ;
+	  else
+	      return RL2_ERROR;
+      }
+    if (pixel_type == RL2_PIXEL_DATAGRID)
+      {
+	  switch (sample_type)
+	    {
+	    case RL2_SAMPLE_UINT8:
+	    case RL2_SAMPLE_UINT16:
+		break;
+	    default:
+		return RL2_ERROR;
+	    };
+      }
     return RL2_OK;
 }
 
@@ -591,7 +1035,8 @@ rl2_raster_to_png (rl2RasterPtr rst, unsigned char **png, int *png_size)
 
     if (rl2_data_to_png
 	(raster->rasterBuffer, raster->maskBuffer, 1.0, plt, raster->width,
-	 raster->height, sample_type, pixel_type, &blob, &blob_size) != RL2_OK)
+	 raster->height, sample_type, pixel_type, num_samples, &blob,
+	 &blob_size) != RL2_OK)
 	return RL2_ERROR;
     *png = blob;
     *png_size = blob_size;
@@ -610,7 +1055,7 @@ rl2_rgb_to_png (unsigned int width, unsigned int height,
 
     if (rl2_data_to_png
 	(rgb, NULL, 1.0, NULL, width, height, RL2_SAMPLE_UINT8, RL2_PIXEL_RGB,
-	 &blob, &blob_size) != RL2_OK)
+	 3, &blob, &blob_size) != RL2_OK)
 	return RL2_ERROR;
     *png = blob;
     *png_size = blob_size;
@@ -630,7 +1075,27 @@ rl2_rgb_alpha_to_png (unsigned int width, unsigned int height,
 
     if (rl2_data_to_png
 	(rgb, alpha, opacity, NULL, width, height, RL2_SAMPLE_UINT8,
-	 RL2_PIXEL_RGB, &blob, &blob_size) != RL2_OK)
+	 RL2_PIXEL_RGB, 3, &blob, &blob_size) != RL2_OK)
+	return RL2_ERROR;
+    *png = blob;
+    *png_size = blob_size;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_rgb_real_alpha_to_png (unsigned int width, unsigned int height,
+			   const unsigned char *rgb,
+			   const unsigned char *alpha, unsigned char **png,
+			   int *png_size)
+{
+/* creating a PNG image from two distinct RGB + Alpha buffer */
+    unsigned char *blob;
+    int blob_size;
+    if (rgb == NULL || alpha == NULL)
+	return RL2_ERROR;
+
+    if (compress_rgba_png8 (rgb, alpha, width, height,
+			    &blob, &blob_size) != RL2_OK)
 	return RL2_ERROR;
     *png = blob;
     *png_size = blob_size;
@@ -649,7 +1114,7 @@ rl2_gray_to_png (unsigned int width, unsigned int height,
 
     if (rl2_data_to_png
 	(gray, NULL, 1.0, NULL, width, height, RL2_SAMPLE_UINT8,
-	 RL2_PIXEL_GRAYSCALE, &blob, &blob_size) != RL2_OK)
+	 RL2_PIXEL_GRAYSCALE, 1, &blob, &blob_size) != RL2_OK)
 	return RL2_ERROR;
     *png = blob;
     *png_size = blob_size;
@@ -669,7 +1134,7 @@ rl2_gray_alpha_to_png (unsigned int width, unsigned int height,
 
     if (rl2_data_to_png
 	(gray, alpha, opacity, NULL, width, height, RL2_SAMPLE_UINT8,
-	 RL2_PIXEL_GRAYSCALE, &blob, &blob_size) != RL2_OK)
+	 RL2_PIXEL_GRAYSCALE, 1, &blob, &blob_size) != RL2_OK)
 	return RL2_ERROR;
     *png = blob;
     *png_size = blob_size;
@@ -680,10 +1145,11 @@ RL2_PRIVATE int
 rl2_data_to_png (const unsigned char *pixels, const unsigned char *mask,
 		 double opacity, rl2PalettePtr plt, unsigned int width,
 		 unsigned int height, unsigned char sample_type,
-		 unsigned char pixel_type, unsigned char **png, int *png_size)
+		 unsigned char pixel_type, unsigned char num_bands,
+		 unsigned char **png, int *png_size)
 {
 /* encoding a PNG image */
-    int ret;
+    int ret = RL2_ERROR;
     unsigned char *blob;
     int blob_size;
 
@@ -697,16 +1163,55 @@ rl2_data_to_png (const unsigned char *pixels, const unsigned char *mask,
 				    &blob, &blob_size);
 	  break;
       case RL2_PIXEL_MONOCHROME:
-      case RL2_PIXEL_GRAYSCALE:
 	  ret =
-	      compress_grayscale_png (pixels, mask, opacity, width, height,
-				      sample_type, pixel_type, &blob,
-				      &blob_size);
+	      compress_grayscale_png8 (pixels, mask, opacity, width, height,
+				       sample_type, pixel_type, &blob,
+				       &blob_size);
+	  break;
+      case RL2_PIXEL_GRAYSCALE:
+      case RL2_PIXEL_DATAGRID:
+	  if (sample_type == RL2_SAMPLE_UINT16)
+	      ret =
+		  compress_grayscale_png16 (pixels, width, height,
+					    sample_type, &blob, &blob_size);
+	  else
+	      ret =
+		  compress_grayscale_png8 (pixels, mask, opacity, width,
+					   height, sample_type, pixel_type,
+					   &blob, &blob_size);
 	  break;
       case RL2_PIXEL_RGB:
-	  ret =
-	      compress_rgb_png (pixels, mask, opacity, width, height, &blob,
-				&blob_size);
+	  if (sample_type == RL2_SAMPLE_UINT8)
+	      ret =
+		  compress_rgb_png8 (pixels, mask, opacity, width, height,
+				     &blob, &blob_size);
+	  else if (sample_type == RL2_SAMPLE_UINT16)
+	      ret =
+		  compress_rgb_png16 (pixels, width, height, &blob, &blob_size);
+	  break;
+      case RL2_PIXEL_MULTIBAND:
+	  if (sample_type == RL2_SAMPLE_UINT8)
+	    {
+		if (num_bands == 3)
+		    ret =
+			compress_rgb_png8 (pixels, mask, opacity, width,
+					   height, &blob, &blob_size);
+		else if (num_bands == 4)
+		    ret =
+			compress_4bands_png8 (pixels, width, height, &blob,
+					      &blob_size);
+	    }
+	  else if (sample_type == RL2_SAMPLE_UINT16)
+	    {
+		if (num_bands == 3)
+		    ret =
+			compress_rgb_png16 (pixels, width, height, &blob,
+					    &blob_size);
+		else
+		    ret =
+			compress_4bands_png16 (pixels, width, height, &blob,
+					       &blob_size);
+	    }
 	  break;
       };
     if (ret != RL2_OK)
@@ -728,7 +1233,7 @@ rl2_section_from_png (const char *path)
 /* attempting to create a raster */
     if (rl2_blob_from_file (path, &blob, &blob_size) != RL2_OK)
 	return NULL;
-    rst = rl2_raster_from_png (blob, blob_size);
+    rst = rl2_raster_from_png (blob, blob_size, 0);
     free (blob);
     if (rst == NULL)
 	return NULL;
@@ -741,14 +1246,14 @@ rl2_section_from_png (const char *path)
 }
 
 RL2_DECLARE rl2RasterPtr
-rl2_raster_from_png (const unsigned char *blob, int blob_size)
+rl2_raster_from_png (const unsigned char *blob, int blob_size, int alpha_mask)
 {
 /* attempting to create a raster from a PNG image */
     rl2RasterPtr rst = NULL;
     unsigned int width;
     unsigned int height;
     unsigned char sample_type;
-    unsigned char pixel_type;
+    unsigned char pixel_type = RL2_PIXEL_UNKNOWN;
     unsigned char nBands;
     unsigned char *data = NULL;
     int data_size;
@@ -758,11 +1263,17 @@ rl2_raster_from_png (const unsigned char *blob, int blob_size)
 
     if (rl2_decode_png
 	(blob, blob_size, &width, &height, &sample_type, &pixel_type, &nBands,
-	 &data, &data_size, &mask, &mask_sz, &palette) != RL2_OK)
+	 &data, &data_size, &mask, &mask_sz, &palette, alpha_mask) != RL2_OK)
 	goto error;
-    rst =
-	rl2_create_raster (width, height, sample_type, pixel_type, nBands, data,
-			   data_size, palette, mask, mask_sz, NULL);
+    if (alpha_mask)
+	rst =
+	    rl2_create_raster_alpha (width, height, sample_type, pixel_type,
+				     nBands, data, data_size, palette, mask,
+				     mask_sz, NULL);
+    else
+	rst =
+	    rl2_create_raster (width, height, sample_type, pixel_type, nBands,
+			       data, data_size, palette, mask, mask_sz, NULL);
     if (rst == NULL)
 	goto error;
     return rst;
@@ -783,7 +1294,7 @@ rl2_decode_png (const unsigned char *blob, int blob_size,
 		unsigned char *xsample_type, unsigned char *xpixel_type,
 		unsigned char *num_bands, unsigned char **pixels,
 		int *pixels_sz, unsigned char **xmask, int *xmask_sz,
-		rl2PalettePtr * xpalette)
+		rl2PalettePtr * xpalette, int alpha_mask)
 {
 /* attempting to decode a PNG image - raw block */
     png_uint_32 width;
@@ -797,7 +1308,7 @@ rl2_decode_png (const unsigned char *blob, int blob_size,
     struct png_memory_buffer membuf;
     unsigned char sample_type = RL2_SAMPLE_UNKNOWN;
     unsigned char pixel_type = RL2_PIXEL_UNKNOWN;
-    int nBands;
+    int nBands = 1;
     int i;
     png_colorp palette;
     int red[256];
@@ -820,6 +1331,7 @@ rl2_decode_png (const unsigned char *blob, int blob_size,
     int nTransp;
     png_color_16p transpValues;
     int has_alpha = 0;
+    int sampleSz = 1;
 
     if (blob == NULL || blob_size == 0)
 	return RL2_ERROR;
@@ -858,6 +1370,10 @@ rl2_decode_png (const unsigned char *blob, int blob_size,
       case 8:
 	  sample_type = RL2_SAMPLE_UINT8;
 	  break;
+      case 16:
+	  sample_type = RL2_SAMPLE_UINT16;
+	  sampleSz = 2;
+	  break;
       };
     if (bit_depth < 8)
 	png_set_packing (png_ptr);
@@ -888,10 +1404,21 @@ rl2_decode_png (const unsigned char *blob, int blob_size,
 	  nBands = 3;
 	  break;
       };
+    if (*xpixel_type == RL2_PIXEL_MULTIBAND)
+      {
+	  pixel_type = RL2_PIXEL_MULTIBAND;
+	  if (color_type == PNG_COLOR_TYPE_RGB)
+	      nBands = 3;
+	  if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+	      nBands = 4;
+      }
+    if (*xpixel_type == RL2_PIXEL_DATAGRID)
+	pixel_type = RL2_PIXEL_DATAGRID;
     if (pixel_type == RL2_PIXEL_PALETTE)
       {
-	  if (png_get_tRNS (png_ptr, info_ptr, &transp, &nTransp, &transpValues)
-	      == PNG_INFO_tRNS)
+	  if (png_get_tRNS
+	      (png_ptr, info_ptr, &transp, &nTransp,
+	       &transpValues) == PNG_INFO_tRNS)
 	    {
 		/* a Transparency palette is defined */
 		int i;
@@ -901,20 +1428,25 @@ rl2_decode_png (const unsigned char *blob, int blob_size,
 	    }
       }
 /* creating the raster data */
-    data_size = width * height * nBands;
+    data_size = width * height * nBands * sampleSz;
     data = malloc (data_size);
     if (data == NULL)
 	goto error;
     p_data = data;
-    if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA
-	|| color_type == PNG_COLOR_TYPE_RGB_ALPHA || has_alpha)
+    if (pixel_type == RL2_PIXEL_MULTIBAND || pixel_type == RL2_PIXEL_DATAGRID)
+	;
+    else
       {
-	  /* creating a transparency mask */
-	  mask_sz = width * height;
-	  mask = malloc (mask_sz);
-	  if (mask == NULL)
-	      goto error;
-	  p_mask = mask;
+	  if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA
+	      || color_type == PNG_COLOR_TYPE_RGB_ALPHA || has_alpha)
+	    {
+		/* creating a transparency mask */
+		mask_sz = width * height;
+		mask = malloc (mask_sz);
+		if (mask == NULL)
+		    goto error;
+		p_mask = mask;
+	    }
       }
     png_read_update_info (png_ptr, info_ptr);
     rowbytes = png_get_rowbytes (png_ptr, info_ptr);
@@ -929,100 +1461,176 @@ rl2_decode_png (const unsigned char *blob, int blob_size,
     png_read_image (png_ptr, row_pointers);
     png_read_end (png_ptr, NULL);
     png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
-    switch (color_type)
+    if (bit_depth == 16)
       {
-      case PNG_COLOR_TYPE_RGB:
-	  for (row = 0; row < height; row++)
+	  unsigned short *p_out = (unsigned short *) p_data;
+	  switch (color_type)
 	    {
-		png_bytep p_in = row_pointers[row];
-		for (col = 0; col < width; col++)
+	    case PNG_COLOR_TYPE_GRAY:
+		for (row = 0; row < height; row++)
 		  {
-		      *p_data++ = *p_in++;
-		      *p_data++ = *p_in++;
-		      *p_data++ = *p_in++;
+		      png_bytep p_in = row_pointers[row];
+		      for (col = 0; col < width; col++)
+			{
+			    png_uint_16 value = png_get_uint_16 (p_in);
+			    p_in += 2;
+			    *p_out++ = value;
+			}
 		  }
-	    }
-	  break;
-      case PNG_COLOR_TYPE_RGB_ALPHA:
-	  for (row = 0; row < height; row++)
-	    {
-		png_bytep p_in = row_pointers[row];
-		for (col = 0; col < width; col++)
+		break;
+	    case PNG_COLOR_TYPE_RGB:
+		for (row = 0; row < height; row++)
 		  {
-		      *p_data++ = *p_in++;
-		      *p_data++ = *p_in++;
-		      *p_data++ = *p_in++;
-		      if (p_mask != NULL)
+		      png_bytep p_in = row_pointers[row];
+		      for (col = 0; col < width; col++)
 			{
-			    if (*p_in++ < 128)
-				*p_mask++ = 0;
-			    else
-				*p_mask++ = 1;
+			    png_uint_16 value = png_get_uint_16 (p_in);
+			    p_in += 2;
+			    *p_out++ = value;
+			    value = png_get_uint_16 (p_in);
+			    p_in += 2;
+			    *p_out++ = value;
+			    value = png_get_uint_16 (p_in);
+			    p_in += 2;
+			    *p_out++ = value;
 			}
-		      else
-			  p_in++;
 		  }
-	    }
-	  break;
-      case PNG_COLOR_TYPE_GRAY:
-	  for (row = 0; row < height; row++)
-	    {
-		png_bytep p_in = row_pointers[row];
-		for (col = 0; col < width; col++)
+		break;
+	    case PNG_COLOR_TYPE_RGB_ALPHA:
+		for (row = 0; row < height; row++)
 		  {
-		      unsigned char val = *p_in++;
-		      switch (sample_type)
+		      png_bytep p_in = row_pointers[row];
+		      for (col = 0; col < width; col++)
 			{
-			case RL2_SAMPLE_1_BIT:
-			case RL2_SAMPLE_2_BIT:
-			case RL2_SAMPLE_4_BIT:
-			case RL2_SAMPLE_UINT8:
-			    break;
-			default:
-			    val = 0;
-			};
-		      *p_data++ = val;
+			    png_uint_16 value = png_get_uint_16 (p_in);
+			    p_in += 2;
+			    *p_out++ = value;
+			    value = png_get_uint_16 (p_in);
+			    p_in += 2;
+			    *p_out++ = value;
+			    value = png_get_uint_16 (p_in);
+			    p_in += 2;
+			    *p_out++ = value;
+			    value = png_get_uint_16 (p_in);
+			    p_in += 2;
+			    *p_out++ = value;
+			}
 		  }
-	    }
-	  break;
-      case PNG_COLOR_TYPE_GRAY_ALPHA:
-	  for (row = 0; row < height; row++)
+		break;
+	    };
+      }
+    else
+      {
+	  switch (color_type)
 	    {
-		png_bytep p_in = row_pointers[row];
-		for (col = 0; col < width; col++)
+	    case PNG_COLOR_TYPE_RGB:
+		for (row = 0; row < height; row++)
+		  {
+		      png_bytep p_in = row_pointers[row];
+		      for (col = 0; col < width; col++)
+			{
+			    *p_data++ = *p_in++;
+			    *p_data++ = *p_in++;
+			    *p_data++ = *p_in++;
+			}
+		  }
+		break;
+	    case PNG_COLOR_TYPE_RGB_ALPHA:
+		for (row = 0; row < height; row++)
 		  {
-		      *p_data++ = *p_in++;
-		      if (p_mask != NULL)
+		      png_bytep p_in = row_pointers[row];
+		      for (col = 0; col < width; col++)
 			{
-			    if (*p_in++ < 128)
-				*p_mask++ = 0;
+			    *p_data++ = *p_in++;
+			    *p_data++ = *p_in++;
+			    *p_data++ = *p_in++;
+			    if (pixel_type == RL2_PIXEL_MULTIBAND)
+				*p_data++ = *p_in++;
 			    else
-				*p_mask++ = 1;
+			      {
+				  if (p_mask != NULL)
+				    {
+					if (alpha_mask)
+					    *p_mask++ = *p_in++;
+					else
+					  {
+					      if (*p_in++ < 128)
+						  *p_mask++ = 0;
+					      else
+						  *p_mask++ = 1;
+					  }
+				    }
+				  else
+				      p_in++;
+			      }
 			}
-		      else
-			  p_in++;
 		  }
-	    }
-	  break;
-      default:			/* palette */
-	  for (row = 0; row < height; row++)
-	    {
-		png_bytep p_in = row_pointers[row];
-		for (col = 0; col < width; col++)
+		break;
+	    case PNG_COLOR_TYPE_GRAY:
+		for (row = 0; row < height; row++)
+		  {
+		      png_bytep p_in = row_pointers[row];
+		      for (col = 0; col < width; col++)
+			{
+			    unsigned char val = *p_in++;
+			    switch (sample_type)
+			      {
+			      case RL2_SAMPLE_1_BIT:
+			      case RL2_SAMPLE_2_BIT:
+			      case RL2_SAMPLE_4_BIT:
+			      case RL2_SAMPLE_UINT8:
+				  break;
+			      default:
+				  val = 0;
+			      };
+			    *p_data++ = val;
+			}
+		  }
+		break;
+	    case PNG_COLOR_TYPE_GRAY_ALPHA:
+		for (row = 0; row < height; row++)
 		  {
-		      *p_data++ = *p_in;
-		      if (p_mask != NULL)
+		      png_bytep p_in = row_pointers[row];
+		      for (col = 0; col < width; col++)
 			{
-			    if (alpha[*p_in] < 128)
-				*p_mask++ = 0;
+			    *p_data++ = *p_in++;
+			    if (p_mask != NULL)
+			      {
+				  if (alpha_mask)
+				      *p_mask++ = *p_in++;
+				  else
+				    {
+					if (*p_in++ < 128)
+					    *p_mask++ = 0;
+					else
+					    *p_mask++ = 1;
+				    }
+			      }
 			    else
-				*p_mask++ = 1;
+				p_in++;
 			}
-		      p_in++;
 		  }
-	    }
-	  break;
-      };
+		break;
+	    default:		/* palette */
+		for (row = 0; row < height; row++)
+		  {
+		      png_bytep p_in = row_pointers[row];
+		      for (col = 0; col < width; col++)
+			{
+			    *p_data++ = *p_in;
+			    if (p_mask != NULL)
+			      {
+				  if (alpha[*p_in] < 128)
+				      *p_mask++ = 0;
+				  else
+				      *p_mask++ = 1;
+			      }
+			    p_in++;
+			}
+		  }
+		break;
+	    };
+      }
 
     free (image_data);
     free (row_pointers);
diff --git a/src/rl2pyramid.c b/src/rl2pyramid.c
index ca59e73..6bfc71f 100644
--- a/src/rl2pyramid.c
+++ b/src/rl2pyramid.c
@@ -20,7 +20,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -65,8 +65,6 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include "rasterlite2/rl2graphics.h"
 #include "rasterlite2_private.h"
 
-#include <spatialite/gaiaaux.h>
-
 /* 64 bit integer: portable format for printf() */
 #if defined(_WIN32) && !defined(__MINGW32__)
 #define ERR_FRMT64 "ERROR: unable to decode Tile ID=%I64d\n"
@@ -107,6 +105,40 @@ do_insert_pyramid_levels (sqlite3 * handle, int id_level, double res_x,
 }
 
 static int
+do_insert_pyramid_section_levels (sqlite3 * handle, sqlite3_int64 section_id,
+				  int id_level, double res_x, double res_y,
+				  sqlite3_stmt * stmt_levl)
+{
+/* INSERTing the Pyramid levels - mixed resolutions Coverage */
+    int ret;
+    sqlite3_reset (stmt_levl);
+    sqlite3_clear_bindings (stmt_levl);
+    sqlite3_bind_int64 (stmt_levl, 1, section_id);
+    sqlite3_bind_int (stmt_levl, 2, id_level);
+    sqlite3_bind_double (stmt_levl, 3, res_x);
+    sqlite3_bind_double (stmt_levl, 4, res_y);
+    sqlite3_bind_double (stmt_levl, 5, res_x * 2.0);
+    sqlite3_bind_double (stmt_levl, 6, res_y * 2.0);
+    sqlite3_bind_double (stmt_levl, 7, res_x * 4.0);
+    sqlite3_bind_double (stmt_levl, 8, res_y * 4.0);
+    sqlite3_bind_double (stmt_levl, 9, res_x * 8.0);
+    sqlite3_bind_double (stmt_levl, 10, res_y * 8.0);
+    ret = sqlite3_step (stmt_levl);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+	;
+    else
+      {
+	  fprintf (stderr,
+		   "INSERT INTO section_levels; sqlite3_step() error: %s\n",
+		   sqlite3_errmsg (handle));
+	  goto error;
+      }
+    return 1;
+  error:
+    return 0;
+}
+
+static int
 do_insert_pyramid_tile (sqlite3 * handle, unsigned char *blob_odd,
 			int blob_odd_sz, unsigned char *blob_even,
 			int blob_even_sz, int id_level,
@@ -117,9 +149,6 @@ do_insert_pyramid_tile (sqlite3 * handle, unsigned char *blob_odd,
 /* INSERTing a Pyramid tile */
     int ret;
     sqlite3_int64 tile_id;
-    unsigned char *blob;
-    int blob_size;
-    gaiaGeomCollPtr geom;
 
     sqlite3_reset (stmt_tils);
     sqlite3_clear_bindings (stmt_tils);
@@ -128,10 +157,11 @@ do_insert_pyramid_tile (sqlite3 * handle, unsigned char *blob_odd,
 	sqlite3_bind_null (stmt_tils, 2);
     else
 	sqlite3_bind_int64 (stmt_tils, 2, section_id);
-    geom = build_extent (srid, minx, miny, maxx, maxy);
-    gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
-    gaiaFreeGeomColl (geom);
-    sqlite3_bind_blob (stmt_tils, 3, blob, blob_size, free);
+    sqlite3_bind_double (stmt_tils, 3, minx);
+    sqlite3_bind_double (stmt_tils, 4, miny);
+    sqlite3_bind_double (stmt_tils, 5, maxx);
+    sqlite3_bind_double (stmt_tils, 6, maxy);
+    sqlite3_bind_int (stmt_tils, 7, srid);
     ret = sqlite3_step (stmt_tils);
     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
 	;
@@ -168,74 +198,17 @@ do_insert_pyramid_tile (sqlite3 * handle, unsigned char *blob_odd,
 }
 
 static int
-resolve_section_id (sqlite3 * handle, const char *coverage, const char *section,
-		    sqlite3_int64 * sect_id)
-{
-/* resolving the Section ID by name */
-    char *table;
-    char *xtable;
-    char *sql;
-    sqlite3_stmt *stmt = NULL;
-    int ret;
-    int ok = 0;
-
-/* Section infos */
-    table = sqlite3_mprintf ("%s_sections", coverage);
-    xtable = gaiaDoubleQuotedSql (table);
-    sqlite3_free (table);
-    sql = sqlite3_mprintf ("SELECT section_id "
-			   "FROM \"%s\" WHERE section_name = %Q", xtable,
-			   section);
-    free (xtable);
-    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
-    sqlite3_free (sql);
-    if (ret != SQLITE_OK)
-      {
-	  fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
-	  goto error;
-      }
-    while (1)
-      {
-	  ret = sqlite3_step (stmt);
-	  if (ret == SQLITE_DONE)
-	      break;
-	  if (ret == SQLITE_ROW)
-	    {
-		*sect_id = sqlite3_column_int64 (stmt, 0);
-		ok = 1;
-	    }
-	  else
-	    {
-		fprintf (stderr,
-			 "SELECT section_info; sqlite3_step() error: %s\n",
-			 sqlite3_errmsg (handle));
-		goto error;
-	    }
-      }
-    sqlite3_finalize (stmt);
-    return ok;
-
-  error:
-    if (stmt != NULL)
-	sqlite3_finalize (stmt);
-    return 0;
-}
-
-static int
 delete_section_pyramid (sqlite3 * handle, const char *coverage,
-			const char *section)
+			sqlite3_int64 section_id)
 {
 /* attempting to delete a section pyramid */
     char *sql;
     char *table;
     char *xtable;
-    sqlite3_int64 section_id;
     char sect_id[1024];
     int ret;
     char *err_msg = NULL;
 
-    if (!resolve_section_id (handle, coverage, section, &section_id))
-	return 0;
 #if defined(_WIN32) && !defined(__MINGW32__)
     sprintf (sect_id, "%I64d", section_id);
 #else
@@ -243,7 +216,7 @@ delete_section_pyramid (sqlite3 * handle, const char *coverage,
 #endif
 
     table = sqlite3_mprintf ("%s_tiles", coverage);
-    xtable = gaiaDoubleQuotedSql (table);
+    xtable = rl2_double_quoted_sql (table);
     sqlite3_free (table);
     sql =
 	sqlite3_mprintf
@@ -264,20 +237,17 @@ delete_section_pyramid (sqlite3 * handle, const char *coverage,
 
 static int
 check_section_pyramid (sqlite3 * handle, const char *coverage,
-		       const char *section)
+		       sqlite3_int64 section_id)
 {
 /* checking if a section's pyramid already exists */
     char *sql;
     char *table;
     char *xtable;
-    sqlite3_int64 section_id;
     char sect_id[1024];
     sqlite3_stmt *stmt = NULL;
     int ret;
     int count = 0;
 
-    if (!resolve_section_id (handle, coverage, section, &section_id))
-	return 1;
 #if defined(_WIN32) && !defined(__MINGW32__)
     sprintf (sect_id, "%I64d", section_id);
 #else
@@ -285,12 +255,12 @@ check_section_pyramid (sqlite3 * handle, const char *coverage,
 #endif
 
     table = sqlite3_mprintf ("%s_tiles", coverage);
-    xtable = gaiaDoubleQuotedSql (table);
+    xtable = rl2_double_quoted_sql (table);
     sqlite3_free (table);
     sql =
 	sqlite3_mprintf ("SELECT Count(*) FROM \"%s\" "
-			 "WHERE section_id = %s AND pyramid_level > 0", xtable,
-			 sect_id);
+			 "WHERE section_id = %s AND pyramid_level > 0",
+			 xtable, sect_id);
     free (xtable);
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     sqlite3_free (sql);
@@ -319,8 +289,8 @@ check_section_pyramid (sqlite3 * handle, const char *coverage,
 }
 
 static int
-get_section_infos (sqlite3 * handle, const char *coverage, const char *section,
-		   sqlite3_int64 * sect_id, unsigned int *sect_width,
+get_section_infos (sqlite3 * handle, const char *coverage,
+		   sqlite3_int64 section_id, unsigned int *sect_width,
 		   unsigned int *sect_height, double *minx, double *miny,
 		   double *maxx, double *maxy, rl2PalettePtr * palette,
 		   rl2PixelPtr * no_data)
@@ -335,13 +305,12 @@ get_section_infos (sqlite3 * handle, const char *coverage, const char *section,
 
 /* Section infos */
     table = sqlite3_mprintf ("%s_sections", coverage);
-    xtable = gaiaDoubleQuotedSql (table);
+    xtable = rl2_double_quoted_sql (table);
     sqlite3_free (table);
     sql =
-	sqlite3_mprintf ("SELECT section_id, width, height, MbrMinX(geometry), "
+	sqlite3_mprintf ("SELECT width, height, MbrMinX(geometry), "
 			 "MbrMinY(geometry), MbrMaxX(geometry), MbrMaxY(geometry) "
-			 "FROM \"%s\" WHERE section_name = %Q", xtable,
-			 section);
+			 "FROM \"%s\" WHERE section_id = ?", xtable);
     free (xtable);
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     sqlite3_free (sql);
@@ -350,6 +319,9 @@ get_section_infos (sqlite3 * handle, const char *coverage, const char *section,
 	  fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
 	  goto error;
       }
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_int64 (stmt, 1, section_id);
     while (1)
       {
 	  ret = sqlite3_step (stmt);
@@ -357,13 +329,12 @@ get_section_infos (sqlite3 * handle, const char *coverage, const char *section,
 	      break;
 	  if (ret == SQLITE_ROW)
 	    {
-		*sect_id = sqlite3_column_int64 (stmt, 0);
-		*sect_width = sqlite3_column_int (stmt, 1);
-		*sect_height = sqlite3_column_int (stmt, 2);
-		*minx = sqlite3_column_double (stmt, 3);
-		*miny = sqlite3_column_double (stmt, 4);
-		*maxx = sqlite3_column_double (stmt, 5);
-		*maxy = sqlite3_column_double (stmt, 6);
+		*sect_width = sqlite3_column_int (stmt, 0);
+		*sect_height = sqlite3_column_int (stmt, 1);
+		*minx = sqlite3_column_double (stmt, 2);
+		*miny = sqlite3_column_double (stmt, 3);
+		*maxx = sqlite3_column_double (stmt, 4);
+		*maxy = sqlite3_column_double (stmt, 5);
 		ok = 1;
 	    }
 	  else
@@ -375,12 +346,14 @@ get_section_infos (sqlite3 * handle, const char *coverage, const char *section,
 	    }
       }
     sqlite3_finalize (stmt);
+    stmt = NULL;
     if (!ok)
 	goto error;
 
 /* Coverage's palette and no-data */
-    sql = sqlite3_mprintf ("SELECT palette, nodata_pixel FROM raster_coverages "
-			   "WHERE Lower(coverage_name) = Lower(%Q)", coverage);
+    sql =
+	sqlite3_mprintf ("SELECT palette, nodata_pixel FROM raster_coverages "
+			 "WHERE Lower(coverage_name) = Lower(%Q)", coverage);
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -519,9 +492,9 @@ delete_sect_pyramid (SectionPyramidPtr pyr)
 }
 
 static int
-insert_tile_into_section_pyramid (SectionPyramidPtr pyr, sqlite3_int64 tile_id,
-				  double minx, double miny, double maxx,
-				  double maxy)
+insert_tile_into_section_pyramid (SectionPyramidPtr pyr,
+				  sqlite3_int64 tile_id, double minx,
+				  double miny, double maxx, double maxy)
 {
 /* inserting a base tile into the Pyramid level */
     SectionPyramidTileInPtr tile;
@@ -604,8 +577,8 @@ set_pyramid_tile_destination (SectionPyramidPtr pyr, double minx, double miny,
 		if (first)
 		  {
 		      out =
-			  add_pyramid_out_tile (pyr, row, col, minx, miny, maxx,
-						maxy);
+			  add_pyramid_out_tile (pyr, row, col, minx, miny,
+						maxx, maxy);
 		      first = 0;
 		  }
 		if (out != NULL)
@@ -795,8 +768,8 @@ rescale_grid_int8 (char *buf_out, unsigned int tileWidth,
 		if (xx >= tileWidth)
 		    break;
 		*p_out =
-		    rescale_pixel_int8 (buf_in, tileWidth, tileHeight, col * 8,
-					row * 8, nd);
+		    rescale_pixel_int8 (buf_in, tileWidth, tileHeight,
+					col * 8, row * 8, nd);
 	    }
       }
 }
@@ -875,8 +848,8 @@ rescale_grid_uint8 (unsigned char *buf_out, unsigned int tileWidth,
 		if (xx >= tileWidth)
 		    break;
 		*p_out =
-		    rescale_pixel_uint8 (buf_in, tileWidth, tileHeight, col * 8,
-					 row * 8, nd);
+		    rescale_pixel_uint8 (buf_in, tileWidth, tileHeight,
+					 col * 8, row * 8, nd);
 	    }
       }
 }
@@ -955,8 +928,8 @@ rescale_grid_int16 (short *buf_out, unsigned int tileWidth,
 		if (xx >= tileWidth)
 		    break;
 		*p_out =
-		    rescale_pixel_int16 (buf_in, tileWidth, tileHeight, col * 8,
-					 row * 8, nd);
+		    rescale_pixel_int16 (buf_in, tileWidth, tileHeight,
+					 col * 8, row * 8, nd);
 	    }
       }
 }
@@ -1115,8 +1088,8 @@ rescale_grid_int32 (int *buf_out, unsigned int tileWidth,
 		if (xx >= tileWidth)
 		    break;
 		*p_out =
-		    rescale_pixel_int32 (buf_in, tileWidth, tileHeight, col * 8,
-					 row * 8, nd);
+		    rescale_pixel_int32 (buf_in, tileWidth, tileHeight,
+					 col * 8, row * 8, nd);
 	    }
       }
 }
@@ -1275,8 +1248,8 @@ rescale_grid_float (float *buf_out, unsigned int tileWidth,
 		if (xx >= tileWidth)
 		    break;
 		*p_out =
-		    rescale_pixel_float (buf_in, tileWidth, tileHeight, col * 8,
-					 row * 8, nd);
+		    rescale_pixel_float (buf_in, tileWidth, tileHeight,
+					 col * 8, row * 8, nd);
 	    }
       }
 }
@@ -1376,9 +1349,9 @@ rescale_grid (void *buf_out, unsigned int tileWidth,
 			     no_data);
 	  break;
       case RL2_SAMPLE_UINT8:
-	  rescale_grid_uint8 ((unsigned char *) buf_out, tileWidth, tileHeight,
-			      (const unsigned char *) buf_in, x, y, tic_x,
-			      tic_y, no_data);
+	  rescale_grid_uint8 ((unsigned char *) buf_out, tileWidth,
+			      tileHeight, (const unsigned char *) buf_in, x,
+			      y, tic_x, tic_y, no_data);
 	  break;
       case RL2_SAMPLE_INT16:
 	  rescale_grid_int16 ((short *) buf_out, tileWidth, tileHeight,
@@ -1396,9 +1369,9 @@ rescale_grid (void *buf_out, unsigned int tileWidth,
 			      no_data);
 	  break;
       case RL2_SAMPLE_UINT32:
-	  rescale_grid_uint32 ((unsigned int *) buf_out, tileWidth, tileHeight,
-			       (const unsigned int *) buf_in, x, y, tic_x,
-			       tic_y, no_data);
+	  rescale_grid_uint32 ((unsigned int *) buf_out, tileWidth,
+			       tileHeight, (const unsigned int *) buf_in, x,
+			       y, tic_x, tic_y, no_data);
 	  break;
       case RL2_SAMPLE_FLOAT:
 	  rescale_grid_float ((float *) buf_out, tileWidth, tileHeight,
@@ -1445,6 +1418,7 @@ update_sect_pyramid_grid (sqlite3 * handle, sqlite3_stmt * stmt_rd,
     int pixel_sz = 1;
     int out_sz;
     int mask_sz = 0;
+    unsigned char compression;
 
     if (pyr == NULL)
 	goto error;
@@ -1452,6 +1426,7 @@ update_sect_pyramid_grid (sqlite3 * handle, sqlite3_stmt * stmt_rd,
     tic_y = tileHeight / pyr->scale;
     geo_x = (double) tic_x *pyr->res_x;
     geo_y = (double) tic_y *pyr->res_y;
+    compression = pyr->compression;
 
     switch (sample_type)
       {
@@ -1545,8 +1520,9 @@ update_sect_pyramid_grid (sqlite3 * handle, sqlite3_stmt * stmt_rd,
 		      pos_y -= geo_y;
 		  }
 		rst = (rl2PrivRasterPtr) raster_in;
-		rescale_grid (buf_out, tileWidth, tileHeight, rst->rasterBuffer,
-			      sample_type, x, y, tic_x, tic_y, no_data);
+		rescale_grid (buf_out, tileWidth, tileHeight,
+			      rst->rasterBuffer, sample_type, x, y, tic_x,
+			      tic_y, no_data);
 		rl2_destroy_raster (raster_in);
 		raster_in = NULL;
 		tile_in = tile_in->next;
@@ -1565,7 +1541,7 @@ update_sect_pyramid_grid (sqlite3 * handle, sqlite3_stmt * stmt_rd,
 		goto error;
 	    }
 	  if (rl2_raster_encode
-	      (raster_out, RL2_COMPRESSION_DEFLATE, &blob_odd, &blob_odd_sz,
+	      (raster_out, compression, &blob_odd, &blob_odd_sz,
 	       &blob_even, &blob_even_sz, 100, 1) != RL2_OK)
 	    {
 		fprintf (stderr, "ERROR: unable to encode a Pyramid tile\n");
@@ -1576,9 +1552,10 @@ update_sect_pyramid_grid (sqlite3 * handle, sqlite3_stmt * stmt_rd,
 
 	  /* INSERTing the tile */
 	  if (!do_insert_pyramid_tile
-	      (handle, blob_odd, blob_odd_sz, blob_even, blob_even_sz, id_level,
-	       pyr->section_id, pyr->srid, tile_out->minx, tile_out->miny,
-	       tile_out->maxx, tile_out->maxy, stmt_tils, stmt_data))
+	      (handle, blob_odd, blob_odd_sz, blob_even, blob_even_sz,
+	       id_level, pyr->section_id, pyr->srid, tile_out->minx,
+	       tile_out->miny, tile_out->maxx, tile_out->maxy, stmt_tils,
+	       stmt_data))
 	      goto error;
 
 	  tile_out = tile_out->next;
@@ -1600,8 +1577,8 @@ update_sect_pyramid_grid (sqlite3 * handle, sqlite3_stmt * stmt_rd,
 
 static double
 rescale_mb_pixel_uint8 (const unsigned char *buf_in, unsigned int tileWidth,
-			unsigned int tileHeight, unsigned int x, unsigned int y,
-			unsigned char nd, unsigned char nb,
+			unsigned int tileHeight, unsigned int x,
+			unsigned int y, unsigned char nd, unsigned char nb,
 			unsigned char num_bands)
 {
 /* rescaling a MultiBand pixel sample (8x8) - UINT8 */
@@ -1678,9 +1655,9 @@ rescale_multiband_uint8 (unsigned char *buf_out, unsigned int tileWidth,
 			      }
 			}
 		      *(p_out + nb) =
-			  rescale_mb_pixel_uint8 (buf_in, tileWidth, tileHeight,
-						  col * 8, row * 8, nd, nb,
-						  num_bands);
+			  rescale_mb_pixel_uint8 (buf_in, tileWidth,
+						  tileHeight, col * 8,
+						  row * 8, nd, nb, num_bands);
 		  }
 	    }
       }
@@ -1768,8 +1745,8 @@ rescale_multiband_uint16 (unsigned short *buf_out, unsigned int tileWidth,
 			}
 		      *(p_out + nb) =
 			  rescale_mb_pixel_uint16 (buf_in, tileWidth,
-						   tileHeight, col * 8, row * 8,
-						   nd, nb, num_bands);
+						   tileHeight, col * 8,
+						   row * 8, nd, nb, num_bands);
 		  }
 	    }
       }
@@ -1792,8 +1769,9 @@ rescale_multiband (void *buf_out, unsigned int tileWidth,
 	  break;
       case RL2_SAMPLE_UINT16:
 	  rescale_multiband_uint16 ((unsigned short *) buf_out, tileWidth,
-				    tileHeight, (const unsigned short *) buf_in,
-				    x, y, tic_x, tic_y, num_bands, no_data);
+				    tileHeight,
+				    (const unsigned short *) buf_in, x, y,
+				    tic_x, tic_y, num_bands, no_data);
 	  break;
       };
 }
@@ -1832,6 +1810,7 @@ update_sect_pyramid_multiband (sqlite3 * handle, sqlite3_stmt * stmt_rd,
     int pixel_sz = 1;
     int out_sz;
     int mask_sz = 0;
+    unsigned char compression;
 
     if (pyr == NULL)
 	goto error;
@@ -1839,6 +1818,7 @@ update_sect_pyramid_multiband (sqlite3 * handle, sqlite3_stmt * stmt_rd,
     tic_y = tileHeight / pyr->scale;
     geo_x = (double) tic_x *pyr->res_x;
     geo_y = (double) tic_y *pyr->res_y;
+    compression = pyr->compression;
 
     switch (sample_type)
       {
@@ -1924,8 +1904,8 @@ update_sect_pyramid_multiband (sqlite3 * handle, sqlite3_stmt * stmt_rd,
 		  }
 		rst = (rl2PrivRasterPtr) raster_in;
 		rescale_multiband (buf_out, tileWidth, tileHeight,
-				   rst->rasterBuffer, sample_type, num_bands, x,
-				   y, tic_x, tic_y, no_data);
+				   rst->rasterBuffer, sample_type, num_bands,
+				   x, y, tic_x, tic_y, no_data);
 		rl2_destroy_raster (raster_in);
 		raster_in = NULL;
 		tile_in = tile_in->next;
@@ -1944,7 +1924,7 @@ update_sect_pyramid_multiband (sqlite3 * handle, sqlite3_stmt * stmt_rd,
 		goto error;
 	    }
 	  if (rl2_raster_encode
-	      (raster_out, RL2_COMPRESSION_DEFLATE, &blob_odd, &blob_odd_sz,
+	      (raster_out, compression, &blob_odd, &blob_odd_sz,
 	       &blob_even, &blob_even_sz, 100, 1) != RL2_OK)
 	    {
 		fprintf (stderr, "ERROR: unable to encode a Pyramid tile\n");
@@ -1955,9 +1935,10 @@ update_sect_pyramid_multiband (sqlite3 * handle, sqlite3_stmt * stmt_rd,
 
 	  /* INSERTing the tile */
 	  if (!do_insert_pyramid_tile
-	      (handle, blob_odd, blob_odd_sz, blob_even, blob_even_sz, id_level,
-	       pyr->section_id, pyr->srid, tile_out->minx, tile_out->miny,
-	       tile_out->maxx, tile_out->maxy, stmt_tils, stmt_data))
+	      (handle, blob_odd, blob_odd_sz, blob_even, blob_even_sz,
+	       id_level, pyr->section_id, pyr->srid, tile_out->minx,
+	       tile_out->miny, tile_out->maxx, tile_out->maxy, stmt_tils,
+	       stmt_data))
 	      goto error;
 
 	  tile_out = tile_out->next;
@@ -2009,7 +1990,8 @@ update_sect_pyramid (sqlite3 * handle, sqlite3_stmt * stmt_rd,
     unsigned char *blob_even;
     int blob_even_sz;
     unsigned char *p;
-    unsigned char compression = RL2_COMPRESSION_NONE;
+    unsigned char compression;
+    int hald_transparent;
 
     if (pyr == NULL)
 	goto error;
@@ -2017,6 +1999,7 @@ update_sect_pyramid (sqlite3 * handle, sqlite3_stmt * stmt_rd,
     tic_y = tileHeight / pyr->scale;
     geo_x = (double) tic_x *pyr->res_x;
     geo_y = (double) tic_y *pyr->res_y;
+    compression = pyr->compression;
 
     tile_out = pyr->first_out;
     while (tile_out != NULL)
@@ -2072,7 +2055,7 @@ update_sect_pyramid (sqlite3 * handle, sqlite3_stmt * stmt_rd,
 	  rgb = rl2_graph_get_context_rgb_array (ctx);
 	  if (rgb == NULL)
 	      goto error;
-	  alpha = rl2_graph_get_context_alpha_array (ctx);
+	  alpha = rl2_graph_get_context_alpha_array (ctx, &hald_transparent);
 	  if (alpha == NULL)
 	      goto error;
 	  p = alpha;
@@ -2142,26 +2125,22 @@ update_sect_pyramid (sqlite3 * handle, sqlite3_stmt * stmt_rd,
 		      compression = RL2_COMPRESSION_PNG;
 		  }
 		else
-		  {
-		      nd = rl2_clone_pixel (no_data);
-		      compression = RL2_COMPRESSION_JPEG;
-		  }
+		    nd = rl2_clone_pixel (no_data);
 		raster =
-		    rl2_create_raster (tileWidth, tileHeight, RL2_SAMPLE_UINT8,
-				       RL2_PIXEL_GRAYSCALE, 1, gray,
-				       tileWidth * tileHeight, NULL, alpha,
-				       tileWidth * tileHeight, nd);
+		    rl2_create_raster (tileWidth, tileHeight,
+				       RL2_SAMPLE_UINT8, RL2_PIXEL_GRAYSCALE,
+				       1, gray, tileWidth * tileHeight, NULL,
+				       alpha, tileWidth * tileHeight, nd);
 	    }
 	  else if (pyr->pixel_type == RL2_PIXEL_RGB)
 	    {
 		/* RGB Pyramid */
 		nd = rl2_clone_pixel (no_data);
 		raster =
-		    rl2_create_raster (tileWidth, tileHeight, RL2_SAMPLE_UINT8,
-				       RL2_PIXEL_RGB, 3, rgb,
-				       tileWidth * tileHeight * 3, NULL, alpha,
-				       tileWidth * tileHeight, nd);
-		compression = RL2_COMPRESSION_JPEG;
+		    rl2_create_raster (tileWidth, tileHeight,
+				       RL2_SAMPLE_UINT8, RL2_PIXEL_RGB, 3,
+				       rgb, tileWidth * tileHeight * 3, NULL,
+				       alpha, tileWidth * tileHeight, nd);
 	    }
 	  if (raster == NULL)
 	    {
@@ -2182,9 +2161,10 @@ update_sect_pyramid (sqlite3 * handle, sqlite3_stmt * stmt_rd,
 
 	  /* INSERTing the tile */
 	  if (!do_insert_pyramid_tile
-	      (handle, blob_odd, blob_odd_sz, blob_even, blob_even_sz, id_level,
-	       pyr->section_id, pyr->srid, tile_out->minx, tile_out->miny,
-	       tile_out->maxx, tile_out->maxy, stmt_tils, stmt_data))
+	      (handle, blob_odd, blob_odd_sz, blob_even, blob_even_sz,
+	       id_level, pyr->section_id, pyr->srid, tile_out->minx,
+	       tile_out->miny, tile_out->maxx, tile_out->maxy, stmt_tils,
+	       stmt_data))
 	      goto error;
 
 	  tile_out = tile_out->next;
@@ -2227,6 +2207,7 @@ rescale_monolithic_rgba (int id_level,
     unsigned char *p_in;
     unsigned char *p_out;
     unsigned char *p_msk;
+    int half_transparent;
 
 /* creating a graphics context */
     ctx = rl2_graph_create_context (tileWidth, tileHeight);
@@ -2277,7 +2258,7 @@ rescale_monolithic_rgba (int id_level,
     rgb = rl2_graph_get_context_rgb_array (ctx);
     if (rgb == NULL)
 	goto error;
-    alpha = rl2_graph_get_context_alpha_array (ctx);
+    alpha = rl2_graph_get_context_alpha_array (ctx, &half_transparent);
     if (alpha == NULL)
 	goto error;
     rl2_graph_destroy_context (ctx);
@@ -2295,7 +2276,7 @@ rescale_monolithic_rgba (int id_level,
 			{
 			    /* skipping a transparent pixel */
 			    p_in += 3;
-			    p_out += 3;
+			    p_out++;
 			}
 		      else
 			{
@@ -2369,9 +2350,9 @@ rescale_monolithic_rgba (int id_level,
 #define floor2(exp) ((long) exp)
 
 static rl2RasterPtr
-create_124_rescaled_raster (const unsigned char *rgba, unsigned char pixel_type,
-			    unsigned int tileWidth, unsigned int tileHeight,
-			    int scale)
+create_124_rescaled_raster (const unsigned char *rgba,
+			    unsigned char pixel_type, unsigned int tileWidth,
+			    unsigned int tileHeight, int scale)
 {
 /* creating a rescaled raster (1,2 or 4 bit pyramids) 
 /
@@ -2558,8 +2539,9 @@ create_124_rescaled_raster (const unsigned char *rgba, unsigned char pixel_type,
       }
 
     raster =
-	rl2_create_raster (out_width, out_height, RL2_SAMPLE_UINT8, pixel_type,
-			   num_bands, rgb, rgb_sz, NULL, mask, mask_sz, NULL);
+	rl2_create_raster (out_width, out_height, RL2_SAMPLE_UINT8,
+			   pixel_type, num_bands, rgb, rgb_sz, NULL, mask,
+			   mask_sz, NULL);
     return raster;
 }
 
@@ -2769,8 +2751,8 @@ rescale_monolithic_124 (int id_level,
 		if (rgba == NULL)
 		    goto error;
 		base_tile =
-		    create_124_rescaled_raster (rgba, out_pixel_type, tileWidth,
-						tileHeight, factor);
+		    create_124_rescaled_raster (rgba, out_pixel_type,
+						tileWidth, tileHeight, factor);
 		free (rgba);
 		if (base_tile == NULL)
 		    goto error;
@@ -2828,10 +2810,10 @@ copy_multiband_rescaled (rl2RasterPtr raster_out, rl2RasterPtr raster_in,
     unsigned int y;
     int dx;
     int dy;
-    unsigned char *p_in_u8;
-    unsigned char *p_out_u8;
-    unsigned short *p_in_u16;
-    unsigned short *p_out_u16;
+    unsigned char *p_in_u8 = NULL;
+    unsigned char *p_out_u8 = NULL;
+    unsigned short *p_in_u16 = NULL;
+    unsigned short *p_out_u16 = NULL;
     unsigned char *p_msk_in;
     unsigned char *p_msk_out;
     int mismatch = 0;
@@ -3144,8 +3126,9 @@ rescale_multiband_u16 (unsigned int tileWidth, unsigned int tileHeight,
 }
 
 static void
-mb_prime_nodata_u8 (unsigned char *buf, unsigned int width, unsigned int height,
-		    unsigned char num_bands, rl2PixelPtr no_data)
+mb_prime_nodata_u8 (unsigned char *buf, unsigned int width,
+		    unsigned int height, unsigned char num_bands,
+		    rl2PixelPtr no_data)
 {
 /* priming a void buffer */
     rl2PrivPixelPtr nd = (rl2PrivPixelPtr) no_data;
@@ -3273,9 +3256,9 @@ create_rescaled_multiband_raster (unsigned int factor, unsigned int tileWidth,
 		  case RL2_SAMPLE_UINT16:
 		      rescale_multiband_u16 (tileWidth, tileHeight, num_bands,
 					     out_width, out_height, factor,
-					     (unsigned short *) buf_in, mask_in,
-					     (unsigned short *) buf, mask, x, y,
-					     ox, oy, no_data);
+					     (unsigned short *) buf_in,
+					     mask_in, (unsigned short *) buf,
+					     mask, x, y, ox, oy, no_data);
 		      break;
 		  };
 		ox++;
@@ -3301,22 +3284,22 @@ copy_datagrid_rescaled (rl2RasterPtr raster_out, rl2RasterPtr raster_in,
     unsigned int y;
     int dx;
     int dy;
-    char *p_in_8;
-    char *p_out_8;
-    unsigned char *p_in_u8;
-    unsigned char *p_out_u8;
-    short *p_in_16;
-    short *p_out_16;
-    unsigned short *p_in_u16;
-    unsigned short *p_out_u16;
-    int *p_in_32;
-    int *p_out_32;
-    unsigned int *p_in_u32;
-    unsigned int *p_out_u32;
-    float *p_in_flt;
-    float *p_out_flt;
-    double *p_in_dbl;
-    double *p_out_dbl;
+    char *p_in_8 = NULL;
+    char *p_out_8 = NULL;
+    unsigned char *p_in_u8 = NULL;
+    unsigned char *p_out_u8 = NULL;
+    short *p_in_16 = NULL;
+    short *p_out_16 = NULL;
+    unsigned short *p_in_u16 = NULL;
+    unsigned short *p_out_u16 = NULL;
+    int *p_in_32 = NULL;
+    int *p_out_32 = NULL;
+    unsigned int *p_in_u32 = NULL;
+    unsigned int *p_out_u32 = NULL;
+    float *p_in_flt = NULL;
+    float *p_out_flt = NULL;
+    double *p_in_dbl = NULL;
+    double *p_out_dbl = NULL;
     unsigned char *p_msk_in;
     unsigned char *p_msk_out;
     int mismatch = 0;
@@ -4065,16 +4048,16 @@ create_rescaled_datagrid_raster (unsigned int factor, unsigned int tileWidth,
 		      break;
 		  case RL2_SAMPLE_INT16:
 		      rescale_datagrid_16 (tileWidth, tileHeight, out_width,
-					   out_height, factor, (short *) buf_in,
-					   (short *) buf, mask, x, y, ox, oy,
-					   no_data_16);
+					   out_height, factor,
+					   (short *) buf_in, (short *) buf,
+					   mask, x, y, ox, oy, no_data_16);
 		      break;
 		  case RL2_SAMPLE_UINT16:
 		      rescale_datagrid_u16 (tileWidth, tileHeight, out_width,
 					    out_height, factor,
 					    (unsigned short *) buf_in,
-					    (unsigned short *) buf, mask, x, y,
-					    ox, oy, no_data_u16);
+					    (unsigned short *) buf, mask, x,
+					    y, ox, oy, no_data_u16);
 		      break;
 		  case RL2_SAMPLE_INT32:
 		      rescale_datagrid_32 (tileWidth, tileHeight, out_width,
@@ -4118,10 +4101,11 @@ static int
 rescale_monolithic_multiband (int id_level,
 			      unsigned int tileWidth, unsigned int tileHeight,
 			      unsigned char sample_type,
-			      unsigned char num_bands, int factor, double res_x,
-			      double res_y, double minx, double miny,
-			      double maxx, double maxy, unsigned char *buffer,
-			      int buf_size, unsigned char *mask, int *mask_size,
+			      unsigned char num_bands, int factor,
+			      double res_x, double res_y, double minx,
+			      double miny, double maxx, double maxy,
+			      unsigned char *buffer, int buf_size,
+			      unsigned char *mask, int *mask_size,
 			      rl2PixelPtr no_data, sqlite3_stmt * stmt_geo,
 			      sqlite3_stmt * stmt_data)
 {
@@ -4147,8 +4131,8 @@ rescale_monolithic_multiband (int id_level,
 	  for (x = 0; x < tileWidth; x++)
 	      *p_out++ = 0;
       }
-    rl2_prime_void_tile (buffer, tileWidth, tileHeight, sample_type, num_bands,
-			 no_data);
+    rl2_prime_void_tile (buffer, tileWidth, tileHeight, sample_type,
+			 num_bands, no_data);
 /* creating the output raster */
     raster =
 	rl2_create_raster (tileWidth, tileHeight, sample_type,
@@ -4358,6 +4342,7 @@ rescale_monolithic_datagrid (int id_level,
 
 static int
 prepare_section_pyramid_stmts (sqlite3 * handle, const char *coverage,
+			       int mixed_resolutions,
 			       sqlite3_stmt ** xstmt_rd,
 			       sqlite3_stmt ** xstmt_levl,
 			       sqlite3_stmt ** xstmt_tils,
@@ -4381,7 +4366,7 @@ prepare_section_pyramid_stmts (sqlite3 * handle, const char *coverage,
     *xstmt_data = NULL;
 
     table_tile_data = sqlite3_mprintf ("%s_tile_data", coverage);
-    xtable_tile_data = gaiaDoubleQuotedSql (table_tile_data);
+    xtable_tile_data = rl2_double_quoted_sql (table_tile_data);
     sqlite3_free (table_tile_data);
     sql = sqlite3_mprintf ("SELECT tile_data_odd, tile_data_even "
 			   "FROM \"%s\" WHERE tile_id = ?", xtable_tile_data);
@@ -4393,16 +4378,34 @@ prepare_section_pyramid_stmts (sqlite3 * handle, const char *coverage,
 	  fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
 	  goto error;
       }
-    table = sqlite3_mprintf ("%s_levels", coverage);
-    xtable = gaiaDoubleQuotedSql (table);
-    sqlite3_free (table);
-    sql =
-	sqlite3_mprintf
-	("INSERT OR IGNORE INTO \"%s\" (pyramid_level, "
-	 "x_resolution_1_1, y_resolution_1_1, "
-	 "x_resolution_1_2, y_resolution_1_2, x_resolution_1_4, "
-	 "y_resolution_1_4, x_resolution_1_8, y_resolution_1_8) "
-	 "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", xtable);
+    if (mixed_resolutions)
+      {
+	  /* mixed resolution Coverage */
+	  table = sqlite3_mprintf ("%s_section_levels", coverage);
+	  xtable = rl2_double_quoted_sql (table);
+	  sqlite3_free (table);
+	  sql =
+	      sqlite3_mprintf
+	      ("INSERT OR IGNORE INTO \"%s\" (section_id, pyramid_level, "
+	       "x_resolution_1_1, y_resolution_1_1, "
+	       "x_resolution_1_2, y_resolution_1_2, x_resolution_1_4, "
+	       "y_resolution_1_4, x_resolution_1_8, y_resolution_1_8) "
+	       "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", xtable);
+      }
+    else
+      {
+	  /* ordinary Coverage */
+	  table = sqlite3_mprintf ("%s_levels", coverage);
+	  xtable = rl2_double_quoted_sql (table);
+	  sqlite3_free (table);
+	  sql =
+	      sqlite3_mprintf
+	      ("INSERT OR IGNORE INTO \"%s\" (pyramid_level, "
+	       "x_resolution_1_1, y_resolution_1_1, "
+	       "x_resolution_1_2, y_resolution_1_2, x_resolution_1_4, "
+	       "y_resolution_1_4, x_resolution_1_8, y_resolution_1_8) "
+	       "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", xtable);
+      }
     free (xtable);
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_levl, NULL);
     sqlite3_free (sql);
@@ -4414,12 +4417,12 @@ prepare_section_pyramid_stmts (sqlite3 * handle, const char *coverage,
       }
 
     table = sqlite3_mprintf ("%s_tiles", coverage);
-    xtable = gaiaDoubleQuotedSql (table);
+    xtable = rl2_double_quoted_sql (table);
     sqlite3_free (table);
     sql =
 	sqlite3_mprintf
 	("INSERT INTO \"%s\" (tile_id, pyramid_level, section_id, geometry) "
-	 "VALUES (NULL, ?, ?, ?)", xtable);
+	 "VALUES (NULL, ?, ?, BuildMBR(?, ?, ?, ?, ?))", xtable);
     free (xtable);
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_tils, NULL);
     sqlite3_free (sql);
@@ -4430,7 +4433,7 @@ prepare_section_pyramid_stmts (sqlite3 * handle, const char *coverage,
       }
 
     table = sqlite3_mprintf ("%s_tile_data", coverage);
-    xtable = gaiaDoubleQuotedSql (table);
+    xtable = rl2_double_quoted_sql (table);
     sqlite3_free (table);
     sql =
 	sqlite3_mprintf
@@ -4466,10 +4469,11 @@ prepare_section_pyramid_stmts (sqlite3 * handle, const char *coverage,
 
 static int
 do_build_section_pyramid (sqlite3 * handle, const char *coverage,
-			  const char *section, unsigned char sample_type,
+			  sqlite3_int64 section_id, unsigned char sample_type,
 			  unsigned char pixel_type, unsigned char num_samples,
-			  unsigned char compression, int quality, int srid,
-			  unsigned int tileWidth, unsigned int tileHeight)
+			  unsigned char compression, int mixed_resolutions,
+			  int quality, int srid, unsigned int tileWidth,
+			  unsigned int tileHeight)
 {
 /* attempting to (re)build a section pyramid from scratch */
     char *table_levels;
@@ -4480,7 +4484,6 @@ do_build_section_pyramid (sqlite3 * handle, const char *coverage,
     int id_level = 0;
     double new_res_x;
     double new_res_y;
-    sqlite3_int64 sect_id;
     unsigned int sect_width;
     unsigned int sect_height;
     double minx;
@@ -4506,31 +4509,54 @@ do_build_section_pyramid (sqlite3 * handle, const char *coverage,
     rl2PixelPtr no_data = NULL;
 
     if (!get_section_infos
-	(handle, coverage, section, &sect_id, &sect_width, &sect_height, &minx,
+	(handle, coverage, section_id, &sect_width, &sect_height, &minx,
 	 &miny, &maxx, &maxy, &palette, &no_data))
 	goto error;
 
     if (!prepare_section_pyramid_stmts
-	(handle, coverage, &stmt_rd, &stmt_levl, &stmt_tils, &stmt_data))
+	(handle, coverage, mixed_resolutions, &stmt_rd, &stmt_levl,
+	 &stmt_tils, &stmt_data))
 	goto error;
 
     while (1)
       {
 	  /* looping on pyramid levels */
-	  table_levels = sqlite3_mprintf ("%s_levels", coverage);
-	  xtable_levels = gaiaDoubleQuotedSql (table_levels);
+	  if (mixed_resolutions)
+	      table_levels = sqlite3_mprintf ("%s_section_levels", coverage);
+	  else
+	      table_levels = sqlite3_mprintf ("%s_levels", coverage);
+	  xtable_levels = rl2_double_quoted_sql (table_levels);
 	  sqlite3_free (table_levels);
 	  table_tiles = sqlite3_mprintf ("%s_tiles", coverage);
-	  xtable_tiles = gaiaDoubleQuotedSql (table_tiles);
+	  xtable_tiles = rl2_double_quoted_sql (table_tiles);
 	  sqlite3_free (table_tiles);
-	  sql =
-	      sqlite3_mprintf ("SELECT l.x_resolution_1_1, l.y_resolution_1_1, "
-			       "t.tile_id, MbrMinX(t.geometry), MbrMinY(t.geometry), "
-			       "MbrMaxX(t.geometry), MbrMaxY(t.geometry) "
-			       "FROM \"%s\" AS l "
-			       "JOIN \"%s\" AS t ON (l.pyramid_level = t.pyramid_level) "
-			       "WHERE l.pyramid_level = %d AND t.section_id = %d",
-			       xtable_levels, xtable_tiles, id_level, sect_id);
+	  if (mixed_resolutions)
+	    {
+		/* mixed resolutions Coverage */
+		sql =
+		    sqlite3_mprintf
+		    ("SELECT l.x_resolution_1_1, l.y_resolution_1_1, "
+		     "t.tile_id, MbrMinX(t.geometry), MbrMinY(t.geometry), "
+		     "MbrMaxX(t.geometry), MbrMaxY(t.geometry) "
+		     "FROM \"%s\" AS l "
+		     "JOIN \"%s\" AS t ON (l.section_id = t.section_id "
+		     "AND l.pyramid_level = t.pyramid_level) "
+		     "WHERE l.pyramid_level = %d AND l.section_id = ?",
+		     xtable_levels, xtable_tiles, id_level);
+	    }
+	  else
+	    {
+		/* ordinary Coverage */
+		sql =
+		    sqlite3_mprintf
+		    ("SELECT l.x_resolution_1_1, l.y_resolution_1_1, "
+		     "t.tile_id, MbrMinX(t.geometry), MbrMinY(t.geometry), "
+		     "MbrMaxX(t.geometry), MbrMaxY(t.geometry) "
+		     "FROM \"%s\" AS l "
+		     "JOIN \"%s\" AS t ON (l.pyramid_level = t.pyramid_level) "
+		     "WHERE l.pyramid_level = %d AND t.section_id = ?",
+		     xtable_levels, xtable_tiles, id_level);
+	    }
 	  free (xtable_levels);
 	  free (xtable_tiles);
 	  ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
@@ -4541,6 +4567,9 @@ do_build_section_pyramid (sqlite3 * handle, const char *coverage,
 			 sqlite3_errmsg (handle));
 		goto error;
 	    }
+	  sqlite3_reset (stmt);
+	  sqlite3_clear_bindings (stmt);
+	  sqlite3_bind_int64 (stmt, 1, section_id);
 	  first = 1;
 	  while (1)
 	    {
@@ -4562,16 +4591,17 @@ do_build_section_pyramid (sqlite3 * handle, const char *coverage,
 		      if (first)
 			{
 			    pyr =
-				alloc_sect_pyramid (sect_id, sect_width,
+				alloc_sect_pyramid (section_id, sect_width,
 						    sect_height, sample_type,
 						    pixel_type, num_samples,
-						    compression, quality, srid,
-						    new_res_x, new_res_y,
+						    compression, quality,
+						    srid, new_res_x,
+						    new_res_y,
 						    (double) tileWidth *
 						    new_res_x,
 						    (double) tileHeight *
-						    new_res_y, minx, miny, maxx,
-						    maxy, scale);
+						    new_res_y, minx, miny,
+						    maxx, maxy, scale);
 			    first = 0;
 			    if (pyr == NULL)
 				goto error;
@@ -4612,9 +4642,19 @@ do_build_section_pyramid (sqlite3 * handle, const char *coverage,
 	  if (pyr->scaled_width <= tileWidth
 	      && pyr->scaled_height <= tileHeight)
 	      break;
-	  if (!do_insert_pyramid_levels
-	      (handle, id_level, pyr->res_x, pyr->res_y, stmt_levl))
-	      goto error;
+	  if (mixed_resolutions)
+	    {
+		if (!do_insert_pyramid_section_levels
+		    (handle, section_id, id_level, pyr->res_x, pyr->res_y,
+		     stmt_levl))
+		    goto error;
+	    }
+	  else
+	    {
+		if (!do_insert_pyramid_levels
+		    (handle, id_level, pyr->res_x, pyr->res_y, stmt_levl))
+		    goto error;
+	    }
 	  if (pixel_type == RL2_PIXEL_DATAGRID)
 	    {
 		/* DataGrid Pyramid */
@@ -4645,9 +4685,19 @@ do_build_section_pyramid (sqlite3 * handle, const char *coverage,
 
     if (pyr != NULL)
       {
-	  if (!do_insert_pyramid_levels
-	      (handle, id_level, pyr->res_x, pyr->res_y, stmt_levl))
-	      goto error;
+	  if (mixed_resolutions)
+	    {
+		if (!do_insert_pyramid_section_levels
+		    (handle, section_id, id_level, pyr->res_x, pyr->res_y,
+		     stmt_levl))
+		    goto error;
+	    }
+	  else
+	    {
+		if (!do_insert_pyramid_levels
+		    (handle, id_level, pyr->res_x, pyr->res_y, stmt_levl))
+		    goto error;
+	    }
 	  if (pixel_type == RL2_PIXEL_DATAGRID)
 	    {
 		/* DataGrid Pyramid */
@@ -4708,10 +4758,10 @@ get_coverage_extent (sqlite3 * handle, const char *coverage, double *minx,
     char *sql;
     int ret;
     sqlite3_stmt *stmt;
-    double extent_minx;
-    double extent_miny;
-    double extent_maxx;
-    double extent_maxy;
+    double extent_minx = 0.0;
+    double extent_miny = 0.0;
+    double extent_maxx = 0.0;
+    double extent_maxy = 0.0;
     int ok = 0;
 
 /* querying the Coverage metadata defs */
@@ -4789,7 +4839,7 @@ find_base_resolution (sqlite3 * handle, const char *coverage,
     sqlite3_stmt *stmt = NULL;
 
     xcoverage = sqlite3_mprintf ("%s_levels", coverage);
-    xxcoverage = gaiaDoubleQuotedSql (xcoverage);
+    xxcoverage = rl2_double_quoted_sql (xcoverage);
     sqlite3_free (xcoverage);
     sql =
 	sqlite3_mprintf ("SELECT x_resolution_1_1, y_resolution_1_1 "
@@ -4842,14 +4892,88 @@ find_base_resolution (sqlite3 * handle, const char *coverage,
 }
 
 static int
-get_section_raw_raster_data (sqlite3 * handle, const char *coverage,
-			     sqlite3_int64 sect_id, unsigned int width,
-			     unsigned int height, unsigned char sample_type,
-			     unsigned char pixel_type, unsigned char num_bands,
-			     double minx, double maxy,
-			     double x_res, double y_res, unsigned char **buffer,
-			     int *buf_size, rl2PalettePtr palette,
-			     rl2PixelPtr no_data)
+find_section_base_resolution (sqlite3 * handle, const char *coverage,
+			      sqlite3_int64 section_id, double *x_res,
+			      double *y_res)
+{
+/* attempting to identify the base resolution level */
+/*           mixed resolution Coverage              */
+    int ret;
+    int found = 0;
+    double xx_res;
+    double yy_res;
+    char *xcoverage;
+    char *xxcoverage;
+    char *sql;
+    sqlite3_stmt *stmt = NULL;
+
+    xcoverage = sqlite3_mprintf ("%s_section_levels", coverage);
+    xxcoverage = rl2_double_quoted_sql (xcoverage);
+    sqlite3_free (xcoverage);
+    sql =
+	sqlite3_mprintf ("SELECT x_resolution_1_1, y_resolution_1_1 "
+			 "FROM \"%s\" WHERE section_id = ? AND pyramid_level = 0",
+			 xxcoverage);
+    free (xxcoverage);
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
+	  goto error;
+      }
+    sqlite3_free (sql);
+
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_int64 (stmt, 1, section_id);
+    while (1)
+      {
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		if (sqlite3_column_type (stmt, 0) == SQLITE_FLOAT
+		    && sqlite3_column_type (stmt, 1) == SQLITE_FLOAT)
+		  {
+		      found = 1;
+		      xx_res = sqlite3_column_double (stmt, 0);
+		      yy_res = sqlite3_column_double (stmt, 1);
+		  }
+	    }
+	  else
+	    {
+		fprintf (stderr, "SQL error: %s\n%s\n", sql,
+			 sqlite3_errmsg (handle));
+		goto error;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    if (found)
+      {
+	  *x_res = xx_res;
+	  *y_res = yy_res;
+	  return 1;
+      }
+    return 0;
+
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    return 0;
+}
+
+static int
+get_section_raw_raster_data (sqlite3 * handle, int max_threads,
+			     const char *coverage, sqlite3_int64 sect_id,
+			     unsigned int width, unsigned int height,
+			     unsigned char sample_type,
+			     unsigned char pixel_type,
+			     unsigned char num_bands, double minx,
+			     double maxy, double x_res, double y_res,
+			     unsigned char **buffer, int *buf_size,
+			     rl2PalettePtr palette, rl2PixelPtr no_data)
 {
 /* attempting to return a buffer containing raw pixels from the whole DBMS Section */
     unsigned char *bufpix = NULL;
@@ -4889,11 +5013,11 @@ get_section_raw_raster_data (sqlite3 * handle, const char *coverage,
 
 /* preparing the "tiles" SQL query */
     xtiles = sqlite3_mprintf ("%s_tiles", coverage);
-    xxtiles = gaiaDoubleQuotedSql (xtiles);
+    xxtiles = rl2_double_quoted_sql (xtiles);
     sql =
-	sqlite3_mprintf ("SELECT tile_id, MbrMinX(geometry), MbrMaxY(geometry) "
-			 "FROM \"%s\" "
-			 "WHERE pyramid_level = 0 AND section_id = ?", xxtiles);
+	sqlite3_mprintf
+	("SELECT tile_id, MbrMinX(geometry), MbrMaxY(geometry) "
+	 "FROM \"%s\" " "WHERE pyramid_level = 0 AND section_id = ?", xxtiles);
     sqlite3_free (xtiles);
     free (xxtiles);
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_tiles, NULL);
@@ -4907,7 +5031,7 @@ get_section_raw_raster_data (sqlite3 * handle, const char *coverage,
 
 /* preparing the data SQL query - both ODD and EVEN */
     xdata = sqlite3_mprintf ("%s_tile_data", coverage);
-    xxdata = gaiaDoubleQuotedSql (xdata);
+    xxdata = rl2_double_quoted_sql (xdata);
     sqlite3_free (xdata);
     sql = sqlite3_mprintf ("SELECT tile_data_odd, tile_data_even "
 			   "FROM \"%s\" WHERE tile_id = ?", xxdata);
@@ -4927,10 +5051,10 @@ get_section_raw_raster_data (sqlite3 * handle, const char *coverage,
     else
 	void_raw_buffer (bufpix, width, height, sample_type, num_bands,
 			 no_data);
-    if (!load_dbms_tiles_section
-	(handle, sect_id, stmt_tiles, stmt_data, bufpix, width, height,
-	 sample_type, num_bands, x_res, y_res, minx, maxy, RL2_SCALE_1, palette,
-	 no_data))
+    if (!rl2_load_dbms_tiles_section
+	(handle, max_threads, sect_id, stmt_tiles, stmt_data, bufpix, width,
+	 height, sample_type, num_bands, 0, 0, 0, x_res, y_res, minx, maxy,
+	 RL2_SCALE_1, palette, no_data))
 	goto error;
     sqlite3_finalize (stmt_tiles);
     sqlite3_finalize (stmt_data);
@@ -4950,7 +5074,8 @@ get_section_raw_raster_data (sqlite3 * handle, const char *coverage,
 
 static void
 raster_tile_124_rescaled (unsigned char *outbuf,
-			  unsigned char pixel_type, const unsigned char *inbuf,
+			  unsigned char pixel_type,
+			  const unsigned char *inbuf,
 			  unsigned int section_width,
 			  unsigned int section_height, unsigned int out_width,
 			  unsigned int out_height, rl2PalettePtr palette)
@@ -5241,8 +5366,9 @@ copy_124_tile (unsigned char pixel_type, const unsigned char *outbuf,
 }
 
 static int
-do_build_124_bit_section_pyramid (sqlite3 * handle, const char *coverage,
-				  const char *section,
+do_build_124_bit_section_pyramid (sqlite3 * handle, int max_threads,
+				  const char *coverage, int mixed_resolutions,
+				  sqlite3_int64 section_id,
 				  unsigned char sample_type,
 				  unsigned char pixel_type,
 				  unsigned char num_samples, int srid,
@@ -5254,7 +5380,6 @@ do_build_124_bit_section_pyramid (sqlite3 * handle, const char *coverage,
 /* attempting to (re)build a 1,2,4-bit section pyramid from scratch */
     double base_res_x;
     double base_res_y;
-    sqlite3_int64 sect_id;
     unsigned int sect_width;
     unsigned int sect_height;
     int id_level = 0;
@@ -5294,20 +5419,31 @@ do_build_124_bit_section_pyramid (sqlite3 * handle, const char *coverage,
     unsigned char *p_out;
 
     if (!get_section_infos
-	(handle, coverage, section, &sect_id, &sect_width, &sect_height, &minx,
+	(handle, coverage, section_id, &sect_width, &sect_height, &minx,
 	 &miny, &maxx, &maxy, &palette, &no_data))
 	goto error;
 
-    if (!find_base_resolution (handle, coverage, &base_res_x, &base_res_y))
-	goto error;
+    if (mixed_resolutions)
+      {
+	  if (!find_section_base_resolution
+	      (handle, coverage, section_id, &base_res_x, &base_res_y))
+	      goto error;
+      }
+    else
+      {
+	  if (!find_base_resolution
+	      (handle, coverage, &base_res_x, &base_res_y))
+	      goto error;
+      }
     if (!get_section_raw_raster_data
-	(handle, coverage, sect_id, sect_width, sect_height, sample_type,
-	 pixel_type, num_samples, minx, maxy, base_res_x,
+	(handle, max_threads, coverage, section_id, sect_width, sect_height,
+	 sample_type, pixel_type, num_samples, minx, maxy, base_res_x,
 	 base_res_y, &inbuf, &inbuf_size, palette, no_data))
 	goto error;
 
     if (!prepare_section_pyramid_stmts
-	(handle, coverage, &stmt_rd, &stmt_levl, &stmt_tils, &stmt_data))
+	(handle, coverage, mixed_resolutions, &stmt_rd, &stmt_levl,
+	 &stmt_tils, &stmt_data))
 	goto error;
 
     id_level = 1;
@@ -5366,9 +5502,18 @@ do_build_124_bit_section_pyramid (sqlite3 * handle, const char *coverage,
 				    sect_width, sect_height, out_width,
 				    out_height, palette);
 
-	  if (!do_insert_pyramid_levels
-	      (handle, id_level, x_res, y_res, stmt_levl))
-	      goto error;
+	  if (mixed_resolutions)
+	    {
+		if (!do_insert_pyramid_section_levels
+		    (handle, section_id, id_level, x_res, y_res, stmt_levl))
+		    goto error;
+	    }
+	  else
+	    {
+		if (!do_insert_pyramid_levels
+		    (handle, id_level, x_res, y_res, stmt_levl))
+		    goto error;
+	    }
 
 	  for (row = 0; row < out_height; row += tileHeight)
 	    {
@@ -5400,12 +5545,14 @@ do_build_124_bit_section_pyramid (sqlite3 * handle, const char *coverage,
 				  /* converting the NO-DATA pixel */
 				  nd = rl2_create_pixel (RL2_SAMPLE_UINT8,
 							 RL2_PIXEL_RGB, 3);
-				  rl2_set_pixel_sample_uint8 (nd, RL2_RED_BAND,
+				  rl2_set_pixel_sample_uint8 (nd,
+							      RL2_RED_BAND,
 							      bgRed);
 				  rl2_set_pixel_sample_uint8 (nd,
 							      RL2_GREEN_BAND,
 							      bgGreen);
-				  rl2_set_pixel_sample_uint8 (nd, RL2_BLUE_BAND,
+				  rl2_set_pixel_sample_uint8 (nd,
+							      RL2_BLUE_BAND,
 							      bgBlue);
 			      }
 			}
@@ -5435,8 +5582,9 @@ do_build_124_bit_section_pyramid (sqlite3 * handle, const char *coverage,
 			    goto error;
 			}
 		      if (rl2_raster_encode
-			  (raster, RL2_COMPRESSION_PNG, &blob_odd, &blob_odd_sz,
-			   &blob_even, &blob_even_sz, 100, 1) != RL2_OK)
+			  (raster, RL2_COMPRESSION_PNG, &blob_odd,
+			   &blob_odd_sz, &blob_even, &blob_even_sz, 100,
+			   1) != RL2_OK)
 			{
 			    fprintf (stderr,
 				     "ERROR: unable to encode a Pyramid tile\n");
@@ -5446,7 +5594,7 @@ do_build_124_bit_section_pyramid (sqlite3 * handle, const char *coverage,
 		      /* INSERTing the tile */
 		      if (!do_insert_pyramid_tile
 			  (handle, blob_odd, blob_odd_sz, blob_even,
-			   blob_even_sz, id_level, sect_id, srid, t_minx,
+			   blob_even_sz, id_level, section_id, srid, t_minx,
 			   t_miny, t_maxx, t_maxy, stmt_tils, stmt_data))
 			  goto error;
 		      rl2_destroy_raster (raster);
@@ -5502,8 +5650,9 @@ do_build_124_bit_section_pyramid (sqlite3 * handle, const char *coverage,
 }
 
 static int
-do_build_palette_section_pyramid (sqlite3 * handle, const char *coverage,
-				  const char *section, int srid,
+do_build_palette_section_pyramid (sqlite3 * handle, int max_threads,
+				  const char *coverage, int mixed_resolutions,
+				  sqlite3_int64 section_id, int srid,
 				  unsigned int tileWidth,
 				  unsigned int tileHeight,
 				  unsigned char bgRed, unsigned char bgGreen,
@@ -5512,7 +5661,6 @@ do_build_palette_section_pyramid (sqlite3 * handle, const char *coverage,
 /* attempting to (re)build a Palette section pyramid from scratch */
     double base_res_x;
     double base_res_y;
-    sqlite3_int64 sect_id;
     unsigned int sect_width;
     unsigned int sect_height;
     int id_level = 0;
@@ -5552,22 +5700,33 @@ do_build_palette_section_pyramid (sqlite3 * handle, const char *coverage,
     unsigned char *p_out;
 
     if (!get_section_infos
-	(handle, coverage, section, &sect_id, &sect_width, &sect_height, &minx,
+	(handle, coverage, section_id, &sect_width, &sect_height, &minx,
 	 &miny, &maxx, &maxy, &palette, &no_data))
 	goto error;
     if (palette == NULL)
 	goto error;
 
-    if (!find_base_resolution (handle, coverage, &base_res_x, &base_res_y))
-	goto error;
+    if (mixed_resolutions)
+      {
+	  if (!find_section_base_resolution
+	      (handle, coverage, section_id, &base_res_x, &base_res_y))
+	      goto error;
+      }
+    else
+      {
+	  if (!find_base_resolution
+	      (handle, coverage, &base_res_x, &base_res_y))
+	      goto error;
+      }
     if (!get_section_raw_raster_data
-	(handle, coverage, sect_id, sect_width, sect_height, RL2_SAMPLE_UINT8,
-	 RL2_PIXEL_PALETTE, 1, minx, maxy, base_res_x,
+	(handle, max_threads, coverage, section_id, sect_width, sect_height,
+	 RL2_SAMPLE_UINT8, RL2_PIXEL_PALETTE, 1, minx, maxy, base_res_x,
 	 base_res_y, &inbuf, &inbuf_size, palette, no_data))
 	goto error;
 
     if (!prepare_section_pyramid_stmts
-	(handle, coverage, &stmt_rd, &stmt_levl, &stmt_tils, &stmt_data))
+	(handle, coverage, mixed_resolutions, &stmt_rd, &stmt_levl,
+	 &stmt_tils, &stmt_data))
 	goto error;
 
     id_level = 1;
@@ -5606,10 +5765,18 @@ do_build_palette_section_pyramid (sqlite3 * handle, const char *coverage,
 	  raster_tile_124_rescaled (outbuf, RL2_PIXEL_PALETTE, inbuf,
 				    sect_width, sect_height, out_width,
 				    out_height, palette);
-
-	  if (!do_insert_pyramid_levels
-	      (handle, id_level, x_res, y_res, stmt_levl))
-	      goto error;
+	  if (mixed_resolutions)
+	    {
+		if (!do_insert_pyramid_section_levels
+		    (handle, section_id, id_level, x_res, y_res, stmt_levl))
+		    goto error;
+	    }
+	  else
+	    {
+		if (!do_insert_pyramid_levels
+		    (handle, id_level, x_res, y_res, stmt_levl))
+		    goto error;
+	    }
 
 	  for (row = 0; row < out_height; row += tileHeight)
 	    {
@@ -5634,9 +5801,10 @@ do_build_palette_section_pyramid (sqlite3 * handle, const char *coverage,
 			}
 		      t_maxx = t_minx + (tileWidth * x_res);
 		      if (!copy_124_tile (out_pixel_type, outbuf, &tilebuf,
-					  &tilebuf_sz, &tilemask, &tilemask_sz,
-					  row, col, out_width, out_height,
-					  tileWidth, tileHeight, no_data))
+					  &tilebuf_sz, &tilemask,
+					  &tilemask_sz, row, col, out_width,
+					  out_height, tileWidth, tileHeight,
+					  no_data))
 			{
 			    fprintf (stderr,
 				     "ERROR: unable to extract a Pyramid Tile\n");
@@ -5657,7 +5825,7 @@ do_build_palette_section_pyramid (sqlite3 * handle, const char *coverage,
 			    goto error;
 			}
 		      if (rl2_raster_encode
-			  (raster, RL2_COMPRESSION_JPEG, &blob_odd,
+			  (raster, RL2_COMPRESSION_PNG, &blob_odd,
 			   &blob_odd_sz, &blob_even, &blob_even_sz, 100,
 			   1) != RL2_OK)
 			{
@@ -5669,7 +5837,7 @@ do_build_palette_section_pyramid (sqlite3 * handle, const char *coverage,
 		      /* INSERTing the tile */
 		      if (!do_insert_pyramid_tile
 			  (handle, blob_odd, blob_odd_sz, blob_even,
-			   blob_even_sz, id_level, sect_id, srid, t_minx,
+			   blob_even_sz, id_level, section_id, srid, t_minx,
 			   t_miny, t_maxx, t_maxy, stmt_tils, stmt_data))
 			  goto error;
 		      rl2_destroy_raster (raster);
@@ -5818,11 +5986,13 @@ get_background_color (sqlite3 * handle, rl2CoveragePtr coverage,
 }
 
 RL2_DECLARE int
-rl2_build_section_pyramid (sqlite3 * handle, const char *coverage,
-			   const char *section, int forced_rebuild)
+rl2_build_section_pyramid (sqlite3 * handle, int max_threads,
+			   const char *coverage, sqlite3_int64 section_id,
+			   int forced_rebuild, int verbose)
 {
 /* (re)building section-level pyramid for a single Section */
     rl2CoveragePtr cvg = NULL;
+    rl2PrivCoveragePtr ptrcvg;
     unsigned char sample_type;
     unsigned char pixel_type;
     unsigned char num_bands;
@@ -5849,11 +6019,12 @@ rl2_build_section_pyramid (sqlite3 * handle, const char *coverage,
 	goto error;
     if (rl2_get_coverage_srid (cvg, &srid) != RL2_OK)
 	goto error;
+    ptrcvg = (rl2PrivCoveragePtr) cvg;
 
     if (!forced_rebuild)
       {
 	  /* checking if the section pyramid already exists */
-	  build = check_section_pyramid (handle, coverage, section);
+	  build = check_section_pyramid (handle, coverage, section_id);
       }
     else
       {
@@ -5864,7 +6035,7 @@ rl2_build_section_pyramid (sqlite3 * handle, const char *coverage,
     if (build)
       {
 	  /* attempting to delete the section pyramid */
-	  if (!delete_section_pyramid (handle, coverage, section))
+	  if (!delete_section_pyramid (handle, coverage, section_id))
 	      goto error;
 	  /* attempting to (re)build the section pyramid */
 	  if ((sample_type == RL2_SAMPLE_1_BIT
@@ -5879,9 +6050,9 @@ rl2_build_section_pyramid (sqlite3 * handle, const char *coverage,
 		/* special case: 1,2,4 bit Pyramid */
 		get_background_color (handle, cvg, &bgRed, &bgGreen, &bgBlue);
 		if (!do_build_124_bit_section_pyramid
-		    (handle, coverage, section, sample_type, pixel_type,
-		     num_bands, srid, tileWidth, tileHeight, bgRed, bgGreen,
-		     bgBlue))
+		    (handle, max_threads, coverage, ptrcvg->mixedResolutions,
+		     section_id, sample_type, pixel_type, num_bands, srid,
+		     tileWidth, tileHeight, bgRed, bgGreen, bgBlue))
 		    goto error;
 	    }
 	  else if (sample_type == RL2_SAMPLE_UINT8
@@ -5890,21 +6061,33 @@ rl2_build_section_pyramid (sqlite3 * handle, const char *coverage,
 		/* special case: 8 bit Palette Pyramid */
 		get_background_color (handle, cvg, &bgRed, &bgGreen, &bgBlue);
 		if (!do_build_palette_section_pyramid
-		    (handle, coverage, section, srid, tileWidth, tileHeight,
-		     bgRed, bgGreen, bgBlue))
+		    (handle, max_threads, coverage, ptrcvg->mixedResolutions,
+		     section_id, srid, tileWidth, tileHeight, bgRed, bgGreen,
+		     bgBlue))
 		    goto error;
 	    }
 	  else
 	    {
 		/* ordinary RGB, Grayscale, MultiBand or DataGrid Pyramid */
 		if (!do_build_section_pyramid
-		    (handle, coverage, section, sample_type, pixel_type,
-		     num_bands, compression, quality, srid, tileWidth,
-		     tileHeight))
+		    (handle, coverage, section_id, sample_type, pixel_type,
+		     num_bands, compression, ptrcvg->mixedResolutions,
+		     quality, srid, tileWidth, tileHeight))
 		    goto error;
 	    }
-	  printf ("  ----------\n");
-	  printf ("    Pyramid levels successfully built for: %s\n", section);
+	  if (verbose)
+	    {
+		printf ("  ----------\n");
+#if defined(_WIN32) && !defined(__MINGW32__)
+		printf
+		    ("    Pyramid levels successfully built for Section %I64d\n",
+		     section_id);
+#else
+		printf
+		    ("    Pyramid levels successfully built for Section %lld\n",
+		     section_id);
+#endif
+	    }
       }
     rl2_destroy_coverage (cvg);
 
@@ -5917,41 +6100,48 @@ rl2_build_section_pyramid (sqlite3 * handle, const char *coverage,
 }
 
 RL2_DECLARE int
-rl2_build_all_section_pyramids (sqlite3 * handle, const char *coverage,
-				int forced_rebuild)
+rl2_build_all_section_pyramids (sqlite3 * handle, int max_threads,
+				const char *coverage, int forced_rebuild,
+				int verbose)
 {
 /* (re)building section-level pyramids for a whole Coverage */
     char *table;
     char *xtable;
     int ret;
-    int i;
-    char **results;
-    int rows;
-    int columns;
+    sqlite3_stmt *stmt;
     char *sql;
 
     table = sqlite3_mprintf ("%s_sections", coverage);
-    xtable = gaiaDoubleQuotedSql (table);
+    xtable = rl2_double_quoted_sql (table);
     sqlite3_free (table);
-    sql = sqlite3_mprintf ("SELECT section_name FROM \"%s\"", xtable);
+    sql = sqlite3_mprintf ("SELECT section_id FROM \"%s\"", xtable);
     free (xtable);
-    ret = sqlite3_get_table (handle, sql, &results, &rows, &columns, NULL);
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
 	goto error;
-    if (rows < 1)
-	;
-    else
+    while (1)
       {
-	  for (i = 1; i <= rows; i++)
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
 	    {
-		const char *section = results[(i * columns) + 0];
+		sqlite3_int64 section_id = sqlite3_column_int64 (stmt, 0);
 		if (rl2_build_section_pyramid
-		    (handle, coverage, section, forced_rebuild) != RL2_OK)
+		    (handle, max_threads, coverage, section_id,
+		     forced_rebuild, verbose) != RL2_OK)
 		    goto error;
 	    }
+	  else
+	    {
+		fprintf (stderr,
+			 "SELECT section_id; sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (handle));
+		goto error;
+	    }
       }
-    sqlite3_free_table (results);
+    sqlite3_finalize (stmt);
     return RL2_OK;
 
   error:
@@ -5979,7 +6169,7 @@ is_full_mask (const unsigned char *mask, int mask_size)
 
 RL2_DECLARE int
 rl2_build_monolithic_pyramid (sqlite3 * handle, const char *coverage,
-			      int virt_levels)
+			      int virt_levels, int verbose)
 {
 /* (re)building monolithic pyramid for a whole coverage */
     rl2CoveragePtr cvg = NULL;
@@ -6041,7 +6231,7 @@ rl2_build_monolithic_pyramid (sqlite3 * handle, const char *coverage,
 
 /* preparing the "tiles" SQL query */
     xtiles = sqlite3_mprintf ("%s_tiles", coverage);
-    xxtiles = gaiaDoubleQuotedSql (xtiles);
+    xxtiles = rl2_double_quoted_sql (xtiles);
     sql =
 	sqlite3_mprintf
 	("SELECT tile_id, MbrMinX(geometry), MbrMaxY(geometry) FROM \"%s\" "
@@ -6063,6 +6253,13 @@ rl2_build_monolithic_pyramid (sqlite3 * handle, const char *coverage,
     if (cvg == NULL)
 	goto error;
     cov = (rl2PrivCoveragePtr) cvg;
+    if (cov->mixedResolutions)
+      {
+	  fprintf (stderr,
+		   "MixedResolutions forbids a Monolithic Pyramid on \"%s\"\n",
+		   cov->coverageName);
+	  goto error;
+      }
 
     if (rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands) !=
 	RL2_OK)
@@ -6078,20 +6275,19 @@ rl2_build_monolithic_pyramid (sqlite3 * handle, const char *coverage,
     no_data = rl2_get_coverage_no_data (cvg);
     palette = rl2_get_dbms_palette (handle, coverage);
     if (!prepare_section_pyramid_stmts
-	(handle, coverage, &stmt_rd, &stmt_levl, &stmt_tils, &stmt_data))
+	(handle, coverage, 0, &stmt_rd, &stmt_levl, &stmt_tils, &stmt_data))
 	goto error;
 
     if (sample_type == RL2_SAMPLE_1_BIT
 	&& pixel_type == RL2_PIXEL_MONOCHROME && num_bands == 1)
       {
-	  /* monochrome: output colorspace is Grayscale */
+	  /* monochrome: output colorspace is Grayscale compression PNG */
 	  out_sample_type = RL2_SAMPLE_UINT8;
 	  out_pixel_type = RL2_PIXEL_GRAYSCALE;
 	  out_num_bands = 1;
 	  out_compression = RL2_COMPRESSION_PNG;
 	  out_quality = 100;
-	  factor = 2;
-	  resize_factor = 2;
+	  virt_levels = 1;
       }
     else if ((sample_type == RL2_SAMPLE_1_BIT
 	      && pixel_type == RL2_PIXEL_PALETTE && num_bands == 1)
@@ -6099,24 +6295,23 @@ rl2_build_monolithic_pyramid (sqlite3 * handle, const char *coverage,
 		 && pixel_type == RL2_PIXEL_PALETTE && num_bands == 1)
 	     || (sample_type == RL2_SAMPLE_4_BIT))
       {
-	  /* palette 1,2,4: output colorspace is RGB */
+	  /* palette 1,2,4: output colorspace is RGB compression PNG */
 	  out_sample_type = RL2_SAMPLE_UINT8;
 	  out_pixel_type = RL2_PIXEL_RGB;
 	  out_num_bands = 3;
 	  out_compression = RL2_COMPRESSION_PNG;
 	  out_quality = 100;
-	  factor = 2;
-	  resize_factor = 2;
+	  virt_levels = 1;
       }
-    else if (sample_type == RL2_SAMPLE_UINT8 && pixel_type == RL2_PIXEL_PALETTE
-	     && num_bands == 1)
+    else if (sample_type == RL2_SAMPLE_UINT8
+	     && pixel_type == RL2_PIXEL_PALETTE && num_bands == 1)
       {
-	  /* palette 8: RGB JPEG pyramid level */
+	  /* palette 8: output colorspace is RGB compression PNG */
 	  out_sample_type = RL2_SAMPLE_UINT8;
 	  out_pixel_type = RL2_PIXEL_RGB;
 	  out_num_bands = 3;
-	  out_compression = RL2_COMPRESSION_JPEG;
-	  out_quality = 80;
+	  out_compression = RL2_COMPRESSION_PNG;
+	  out_quality = 100;
       }
     else
       {
@@ -6124,37 +6319,28 @@ rl2_build_monolithic_pyramid (sqlite3 * handle, const char *coverage,
 	  out_sample_type = sample_type;
 	  out_pixel_type = pixel_type;
 	  out_num_bands = num_bands;
-	  if (sample_type == RL2_SAMPLE_UINT8
-	      && ((pixel_type == RL2_PIXEL_RGB && num_bands == 3)
-		  || (pixel_type == RL2_PIXEL_GRAYSCALE && num_bands == 1)))
-	    {
-		out_compression = RL2_COMPRESSION_JPEG;
-		out_quality = quality;
-	    }
-	  else
-	    {
-		out_compression = RL2_COMPRESSION_DEFLATE;
-		out_quality = 100;
-	    }
-	  /* setting the requested virt_levels */
-	  switch (virt_levels)
-	    {
-	    case 1:		/* separating each physical level */
-		resize_factor = 2;
-		break;
-	    case 2:		/* one physical + one virtual */
-		resize_factor = 4;
-		break;
-	    case 3:		/* one physical + two virtuals */
-		resize_factor = 8;
-		break;
-	    default:
-		resize_factor = 8;
-		break;
-	    };
-	  factor = resize_factor;
+	  out_compression = compression;
+	  out_quality = quality;
       }
 
+    /* setting the requested virt_levels */
+    switch (virt_levels)
+      {
+      case 1:			/* separating each physical level */
+	  resize_factor = 2;
+	  break;
+      case 2:			/* one physical + one virtual */
+	  resize_factor = 4;
+	  break;
+      case 3:			/* one physical + two virtuals */
+	  resize_factor = 8;
+	  break;
+      default:
+	  resize_factor = 8;
+	  break;
+      };
+    factor = resize_factor;
+
 /* computing output tile buffers */
     switch (out_sample_type)
       {
@@ -6222,10 +6408,12 @@ rl2_build_monolithic_pyramid (sqlite3 * handle, const char *coverage,
 		      buffer = malloc (buf_size);
 		      if (buffer == NULL)
 			  goto error;
+		      memset (buffer, 0, buf_size);
 		      mask_size = tileWidth * tileHeight;
 		      mask = malloc (mask_size);
 		      if (mask == NULL)
 			  goto error;
+		      memset (mask, 0, mask_size);
 		      end_x = tile_maxx;
 		      if (tile_maxx > maxx)
 			  end_x = maxx;
@@ -6237,18 +6425,19 @@ rl2_build_monolithic_pyramid (sqlite3 * handle, const char *coverage,
 			   && pixel_type == RL2_PIXEL_GRAYSCALE
 			   && num_bands == 1)
 			  || (sample_type == RL2_SAMPLE_UINT8
-			      && pixel_type == RL2_PIXEL_RGB && num_bands == 3)
+			      && pixel_type == RL2_PIXEL_RGB
+			      && num_bands == 3)
 			  || (sample_type == RL2_SAMPLE_UINT8
 			      && pixel_type == RL2_PIXEL_PALETTE
 			      && num_bands == 1))
 			{
 			    /* RGB, PALETTE or GRAYSCALE datasource (UINT8) */
 			    if (!rescale_monolithic_rgba
-				(id_level, tileWidth, tileHeight, resize_factor,
-				 res_x, res_y, tile_minx, tile_miny,
-				 tile_maxx, tile_maxy, buffer, buf_size, mask,
-				 &mask_size, palette, no_data, stmt_geo,
-				 stmt_rd))
+				(id_level, tileWidth, tileHeight,
+				 resize_factor, res_x, res_y, tile_minx,
+				 tile_miny, tile_maxx, tile_maxy, buffer,
+				 buf_size, mask, &mask_size, palette, no_data,
+				 stmt_geo, stmt_rd))
 				goto error;
 			    if (mask_size == 0)
 				mask = NULL;
@@ -6294,8 +6483,8 @@ rl2_build_monolithic_pyramid (sqlite3 * handle, const char *coverage,
 				(id_level, tileWidth, tileHeight, sample_type,
 				 resize_factor, res_x, res_y, tile_minx,
 				 tile_miny, tile_maxx, tile_maxy, buffer,
-				 buf_size, mask, &mask_size, no_data, stmt_geo,
-				 stmt_rd))
+				 buf_size, mask, &mask_size, no_data,
+				 stmt_geo, stmt_rd))
 				goto error;
 			    if (mask_size == 0)
 				mask = NULL;
@@ -6347,12 +6536,14 @@ rl2_build_monolithic_pyramid (sqlite3 * handle, const char *coverage,
 			      {
 				  nd = rl2_create_pixel (RL2_SAMPLE_UINT8,
 							 RL2_PIXEL_RGB, 3);
-				  rl2_set_pixel_sample_uint8 (nd, RL2_RED_BAND,
+				  rl2_set_pixel_sample_uint8 (nd,
+							      RL2_RED_BAND,
 							      255);
 				  rl2_set_pixel_sample_uint8 (nd,
 							      RL2_GREEN_BAND,
 							      255);
-				  rl2_set_pixel_sample_uint8 (nd, RL2_BLUE_BAND,
+				  rl2_set_pixel_sample_uint8 (nd,
+							      RL2_BLUE_BAND,
 							      255);
 			      }
 			}
@@ -6396,10 +6587,13 @@ rl2_build_monolithic_pyramid (sqlite3 * handle, const char *coverage,
 		  }
 		tile_maxy = tile_miny;
 		row++;
-		printf ("  ----------\n");
-		printf
-		    ("    %s: Monolithic Pyramid Level %d - Row %d of %d  successfully built\n",
-		     coverage, id_level + 1, row, tot_rows);
+		if (verbose)
+		  {
+		      printf ("  ----------\n");
+		      printf
+			  ("    %s: Monolithic Pyramid Level %d - Row %d of %d  successfully built\n",
+			   coverage, id_level + 1, row, tot_rows);
+		  }
 	    }
 	  if (stop)
 	      break;
@@ -6434,9 +6628,13 @@ rl2_build_monolithic_pyramid (sqlite3 * handle, const char *coverage,
     sqlite3_finalize (stmt_levl);
     sqlite3_finalize (stmt_tils);
     sqlite3_finalize (stmt_data);
-    printf ("  ----------\n");
-    printf ("    Monolithic Pyramid levels successfully built for: %s\n",
-	    coverage);
+    if (verbose)
+      {
+	  printf ("  ----------\n");
+	  printf
+	      ("    Monolithic Pyramid levels successfully built for: %s\n",
+	       coverage);
+      }
     free (buffer);
     free (mask);
     rl2_destroy_coverage (cvg);
@@ -6476,9 +6674,14 @@ rl2_delete_all_pyramids (sqlite3 * handle, const char *coverage)
     char *xtable;
     int ret;
     char *err_msg = NULL;
+    int mixed_resolutions =
+	rl2_is_mixed_resolutions_coverage (handle, coverage);
+
+    if (mixed_resolutions < 0)
+	return RL2_ERROR;
 
     table = sqlite3_mprintf ("%s_tiles", coverage);
-    xtable = gaiaDoubleQuotedSql (table);
+    xtable = rl2_double_quoted_sql (table);
     sqlite3_free (table);
     sql =
 	sqlite3_mprintf ("DELETE FROM \"%s\" WHERE pyramid_level > 0", xtable);
@@ -6493,30 +6696,56 @@ rl2_delete_all_pyramids (sqlite3 * handle, const char *coverage)
 	  return RL2_ERROR;
       }
 
-    table = sqlite3_mprintf ("%s_levels", coverage);
-    xtable = gaiaDoubleQuotedSql (table);
-    sqlite3_free (table);
-    sql =
-	sqlite3_mprintf ("DELETE FROM \"%s\" WHERE pyramid_level > 0", xtable);
-    free (xtable);
-    ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
-    sqlite3_free (sql);
-    if (ret != SQLITE_OK)
+    if (mixed_resolutions)
       {
-	  fprintf (stderr, "DELETE FROM \"%s_levels\" error: %s\n", coverage,
-		   err_msg);
-	  sqlite3_free (err_msg);
-	  return RL2_ERROR;
+	  /* Mixed Resolution Coverage */
+	  table = sqlite3_mprintf ("%s_section_levels", coverage);
+	  xtable = rl2_double_quoted_sql (table);
+	  sqlite3_free (table);
+	  sql =
+	      sqlite3_mprintf ("DELETE FROM \"%s\" WHERE pyramid_level > 0",
+			       xtable);
+	  free (xtable);
+	  ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+	  sqlite3_free (sql);
+	  if (ret != SQLITE_OK)
+	    {
+		fprintf (stderr,
+			 "DELETE FROM \"%s_section_levels\" error: %s\n",
+			 coverage, err_msg);
+		sqlite3_free (err_msg);
+		return RL2_ERROR;
+	    }
+      }
+    else
+      {
+	  /* ordinary Coverage */
+	  table = sqlite3_mprintf ("%s_levels", coverage);
+	  xtable = rl2_double_quoted_sql (table);
+	  sqlite3_free (table);
+	  sql =
+	      sqlite3_mprintf ("DELETE FROM \"%s\" WHERE pyramid_level > 0",
+			       xtable);
+	  free (xtable);
+	  ret = sqlite3_exec (handle, sql, NULL, NULL, &err_msg);
+	  sqlite3_free (sql);
+	  if (ret != SQLITE_OK)
+	    {
+		fprintf (stderr, "DELETE FROM \"%s_levels\" error: %s\n",
+			 coverage, err_msg);
+		sqlite3_free (err_msg);
+		return RL2_ERROR;
+	    }
       }
     return RL2_OK;
 }
 
 RL2_DECLARE int
 rl2_delete_section_pyramid (sqlite3 * handle, const char *coverage,
-			    const char *section)
+			    sqlite3_int64 section_id)
 {
 /* deleting section-level pyramid for a single Section */
-    if (!delete_section_pyramid (handle, coverage, section))
+    if (!delete_section_pyramid (handle, coverage, section_id))
 	return RL2_ERROR;
     return RL2_OK;
 }
diff --git a/src/rl2rastersym.c b/src/rl2rastersym.c
index 801ae03..5f115fa 100644
--- a/src/rl2rastersym.c
+++ b/src/rl2rastersym.c
@@ -20,7 +20,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -46,6 +46,14 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include <string.h>
 #include <float.h>
 
+#ifdef _WIN32
+#include <windows.h>
+#include <process.h>
+#else
+#include <unistd.h>
+#include <pthread.h>
+#endif
+
 #include "config.h"
 
 #ifdef LOADABLE_EXTENSION
@@ -55,8 +63,6 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include "rasterlite2/rasterlite2.h"
 #include "rasterlite2_private.h"
 
-#include <spatialite/gaiaaux.h>
-
 /* 64 bit integer: portable format for printf() */
 #if defined(_WIN32) && !defined(__MINGW32__)
 #define ERR_FRMT64 "ERROR: unable to decode Tile ID=%I64d\n"
@@ -234,6 +240,291 @@ apply_color_map (double mono, unsigned char *p_out,
 }
 
 static unsigned char *
+ndvi_uint8_pixel_handler (const unsigned char *p_in, unsigned char *p_out,
+			  unsigned char red_band, unsigned char nir_band,
+			  rl2BandHandlingPtr ndvi_handling)
+{
+/* styling an opaque NDVI pixel - UINT8 */
+    unsigned char red = *(p_in + red_band);
+    unsigned char nir = *(p_in + nir_band);
+    double ndvi = ((double) nir - (double) red) / ((double) nir + (double) red);
+/* applying the ColorMap */
+    return apply_color_map (ndvi, p_out, ndvi_handling);
+}
+
+static void
+copy_uint8_ndvi_pixels (const unsigned char *buffer,
+			const unsigned char *mask, unsigned char *outbuf,
+			unsigned short width, unsigned short height,
+			unsigned char out_num_bands,
+			unsigned char num_bands, double x_res, double y_res,
+			double minx, double maxy, double tile_minx,
+			double tile_maxy, unsigned short tile_width,
+			unsigned short tile_height, rl2PixelPtr no_data,
+			unsigned char red_band, unsigned char nir_band,
+			rl2BandHandlingPtr ndvi_handling)
+{
+/* copying UINT8 NDVI pixels from the DBMS tile into the output image */
+    int x;
+    int y;
+    int b;
+    int out_x;
+    int out_y;
+    double geo_x;
+    double geo_y;
+    const unsigned char *p_in = buffer;
+    const unsigned char *p_msk = mask;
+    unsigned char *p_out;
+    int ib;
+    int transparent;
+    unsigned char sample_type;
+    unsigned char pixel_type;
+    unsigned char nbands;
+    int ignore_no_data = 1;
+    double y_res2 = y_res / 2.0;
+    double x_res2 = x_res / 2.0;
+
+    if (no_data != NULL)
+      {
+	  ignore_no_data = 0;
+	  if (rl2_get_pixel_type (no_data, &sample_type, &pixel_type, &nbands)
+	      != RL2_OK)
+	      ignore_no_data = 1;
+	  if (nbands != num_bands)
+	      ignore_no_data = 1;
+	  if (sample_type == RL2_SAMPLE_UINT8)
+	      ;
+	  else
+	      ignore_no_data = 1;
+      }
+
+    geo_y = tile_maxy + y_res2;
+    for (y = 0; y < tile_height; y++)
+      {
+	  geo_y -= y_res;
+	  out_y = (maxy - geo_y) / y_res;
+	  if (out_y < 0 || out_y >= height)
+	    {
+		p_in += tile_width * num_bands;
+		if (p_msk != NULL)
+		    p_msk += tile_width;
+		continue;
+	    }
+	  geo_x = tile_minx - x_res2;
+	  for (x = 0; x < tile_width; x++)
+	    {
+		geo_x += x_res;
+		out_x = (geo_x - minx) / x_res;
+		if (out_x < 0 || out_x >= width)
+		  {
+		      p_in += num_bands;
+		      if (p_msk != NULL)
+			  p_msk++;
+		      continue;
+		  }
+		p_out =
+		    outbuf + (out_y * width * out_num_bands) +
+		    (out_x * out_num_bands);
+		transparent = 0;
+		if (p_msk != NULL)
+		  {
+		      if (*p_msk++ == 0)
+			  transparent = 1;
+		  }
+		if (transparent || ignore_no_data)
+		  {
+		      /* already transparent or missing NO-DATA value */
+		      if (transparent)
+			{
+			    /* skipping a transparent pixel */
+			    for (ib = 0; ib < out_num_bands; ib++)
+				p_out++;
+			}
+		      else
+			{
+			    /* opaque pixel */
+			    p_out =
+				ndvi_uint8_pixel_handler (p_in, p_out,
+							  red_band, nir_band,
+							  ndvi_handling);
+			}
+		  }
+		else
+		  {
+		      /* testing for NO-DATA values */
+		      int match = 0;
+		      const unsigned char *p_save = p_in;
+		      for (b = 0; b < num_bands; b++)
+			{
+			    unsigned char sample = 0;
+			    rl2_get_pixel_sample_uint8 (no_data, b, &sample);
+			    if (sample == *p_save++)
+				match++;
+			}
+		      if (match != num_bands)
+			{
+			    /* opaque pixel */
+			    p_out =
+				ndvi_uint8_pixel_handler (p_in, p_out,
+							  red_band, nir_band,
+							  ndvi_handling);
+			}
+		      else
+			{
+			    /* NO-DATA pixel */
+			    for (ib = 0; ib < out_num_bands; ib++)
+				p_out++;
+			}
+		  }
+		p_in += num_bands;
+	    }
+      }
+}
+
+static unsigned char *
+ndvi_uint16_pixel_handler (const unsigned short *p_in, unsigned char *p_out,
+			   unsigned char red_band, unsigned char nir_band,
+			   rl2BandHandlingPtr ndvi_handling)
+{
+/* styling an opaque NDVI pixel - UINT16 */
+    unsigned short red = *(p_in + red_band);
+    unsigned short nir = *(p_in + nir_band);
+    double ndvi = ((double) nir - (double) red) / ((double) nir + (double) red);
+/* applying the ColorMap */
+    return apply_color_map (ndvi, p_out, ndvi_handling);
+}
+
+static void
+copy_uint16_ndvi_pixels (const unsigned short *buffer,
+			 const unsigned char *mask, unsigned char *outbuf,
+			 unsigned short width, unsigned short height,
+			 unsigned char out_num_bands,
+			 unsigned char num_bands, double x_res,
+			 double y_res, double minx, double maxy,
+			 double tile_minx, double tile_maxy,
+			 unsigned short tile_width,
+			 unsigned short tile_height, rl2PixelPtr no_data,
+			 unsigned char red_band, unsigned char nir_band,
+			 rl2BandHandlingPtr ndvi_handling)
+{
+/* copying UINT16 NDVI pixels from the DBMS tile into the output image */
+    int x;
+    int y;
+    int b;
+    int out_x;
+    int out_y;
+    double geo_x;
+    double geo_y;
+    const unsigned short *p_in = buffer;
+    const unsigned char *p_msk = mask;
+    unsigned char *p_out;
+    int ib;
+    int transparent;
+    unsigned char sample_type;
+    unsigned char pixel_type;
+    unsigned char nbands;
+    int ignore_no_data = 1;
+    double y_res2 = y_res / 2.0;
+    double x_res2 = x_res / 2.0;
+
+    if (no_data != NULL)
+      {
+	  ignore_no_data = 0;
+	  if (rl2_get_pixel_type (no_data, &sample_type, &pixel_type, &nbands)
+	      != RL2_OK)
+	      ignore_no_data = 1;
+	  if (nbands != num_bands)
+	      ignore_no_data = 1;
+	  if (sample_type == RL2_SAMPLE_UINT16)
+	      ;
+	  else
+	      ignore_no_data = 1;
+      }
+
+    geo_y = tile_maxy + y_res2;
+    for (y = 0; y < tile_height; y++)
+      {
+	  geo_y -= y_res;
+	  out_y = (maxy - geo_y) / y_res;
+	  if (out_y < 0 || out_y >= height)
+	    {
+		p_in += tile_width * num_bands;
+		if (p_msk != NULL)
+		    p_msk += tile_width;
+		continue;
+	    }
+	  geo_x = tile_minx - x_res2;
+	  for (x = 0; x < tile_width; x++)
+	    {
+		geo_x += x_res;
+		out_x = (geo_x - minx) / x_res;
+		if (out_x < 0 || out_x >= width)
+		  {
+		      p_in += num_bands;
+		      if (p_msk != NULL)
+			  p_msk++;
+		      continue;
+		  }
+		p_out =
+		    outbuf + (out_y * width * out_num_bands) +
+		    (out_x * out_num_bands);
+		transparent = 0;
+		if (p_msk != NULL)
+		  {
+		      if (*p_msk++ == 0)
+			  transparent = 1;
+		  }
+		if (transparent || ignore_no_data)
+		  {
+		      /* already transparent or missing NO-DATA value */
+		      if (transparent)
+			{
+			    /* skipping a transparent pixel */
+			    for (ib = 0; ib < out_num_bands; ib++)
+				p_out++;
+			}
+		      else
+			{
+			    /* opaque pixel */
+			    p_out =
+				ndvi_uint16_pixel_handler (p_in, p_out,
+							   red_band, nir_band,
+							   ndvi_handling);
+			}
+		  }
+		else
+		  {
+		      /* testing for NO-DATA values */
+		      int match = 0;
+		      const unsigned short *p_save = p_in;
+		      for (b = 0; b < num_bands; b++)
+			{
+			    unsigned short sample = 0;
+			    rl2_get_pixel_sample_uint16 (no_data, b, &sample);
+			    if (sample == *p_save++)
+				match++;
+			}
+		      if (match != num_bands)
+			{
+			    /* opaque pixel */
+			    p_out =
+				ndvi_uint16_pixel_handler (p_in, p_out,
+							   red_band, nir_band,
+							   ndvi_handling);
+			}
+		      else
+			{
+			    /* NO-DATA pixel */
+			    for (ib = 0; ib < out_num_bands; ib++)
+				p_out++;
+			}
+		  }
+		p_in += num_bands;
+	    }
+      }
+}
+
+static unsigned char *
 apply_contrast_enhancement (double mono, unsigned char *p_out,
 			    rl2BandHandlingPtr mono_handling)
 {
@@ -272,23 +563,6 @@ apply_contrast_enhancement (double mono, unsigned char *p_out,
 		*p_out++ = (unsigned char) scaled;
 	    }
       }
-    else if (mono_handling->contrastEnhancement ==
-	     RL2_CONTRAST_ENHANCEMENT_HISTOGRAM)
-      {
-	  /* applying Histogram Equalization */
-	  if (mono <= mono_handling->minValue)
-	      *p_out++ = mono_handling->look_up[0];
-	  else if (mono >= mono_handling->maxValue)
-	      *p_out++ = mono_handling->look_up[255];
-	  else
-	    {
-		scaled =
-		    1.0 +
-		    (((double) mono -
-		      mono_handling->minValue) / mono_handling->scaleFactor);
-		*p_out++ = mono_handling->look_up[(unsigned char) scaled];
-	    }
-      }
     else
       {
 	  /* applying Trivial Normalization */
@@ -420,7 +694,8 @@ copy_int8_raw_mono_pixels (const char *buffer,
 			{
 			    /* opaque pixel */
 			    p_out =
-				mono_int8_pixel_handler (p_in, p_out, mono_band,
+				mono_int8_pixel_handler (p_in, p_out,
+							 mono_band,
 							 mono_handling);
 			}
 		  }
@@ -437,7 +712,8 @@ copy_int8_raw_mono_pixels (const char *buffer,
 			{
 			    /* opaque pixel */
 			    p_out =
-				mono_int8_pixel_handler (p_in, p_out, mono_band,
+				mono_int8_pixel_handler (p_in, p_out,
+							 mono_band,
 							 mono_handling);
 			}
 		      else
@@ -488,7 +764,8 @@ copy_uint8_raw_pixels (const unsigned char *buffer, const unsigned char *mask,
 	      ignore_no_data = 1;
 	  if (nbands != num_bands)
 	      ignore_no_data = 1;
-	  if (sample_type == RL2_SAMPLE_1_BIT || sample_type == RL2_SAMPLE_2_BIT
+	  if (sample_type == RL2_SAMPLE_1_BIT
+	      || sample_type == RL2_SAMPLE_2_BIT
 	      || sample_type == RL2_SAMPLE_4_BIT
 	      || sample_type == RL2_SAMPLE_UINT8)
 	      ;
@@ -607,12 +884,13 @@ static void
 copy_uint8_raw_selected_pixels (const unsigned char *buffer,
 				const unsigned char *mask,
 				unsigned char *outbuf, unsigned short width,
-				unsigned short height, unsigned char num_bands,
-				double x_res, double y_res, double minx,
-				double maxy, double tile_minx, double tile_maxy,
+				unsigned short height,
+				unsigned char num_bands, double x_res,
+				double y_res, double minx, double maxy,
+				double tile_minx, double tile_maxy,
 				unsigned short tile_width,
-				unsigned short tile_height, rl2PixelPtr no_data,
-				unsigned char red_band,
+				unsigned short tile_height,
+				rl2PixelPtr no_data, unsigned char red_band,
 				unsigned char green_band,
 				unsigned char blue_band,
 				rl2BandHandlingPtr red_handling,
@@ -695,7 +973,8 @@ copy_uint8_raw_selected_pixels (const unsigned char *buffer,
 			{
 			    /* opaque pixel */
 			    p_out =
-				mono_uint8_pixel_handler (p_in, p_out, red_band,
+				mono_uint8_pixel_handler (p_in, p_out,
+							  red_band,
 							  red_handling);
 			    p_out =
 				mono_uint8_pixel_handler (p_in, p_out,
@@ -723,7 +1002,8 @@ copy_uint8_raw_selected_pixels (const unsigned char *buffer,
 			{
 			    /* opaque pixel */
 			    p_out =
-				mono_uint8_pixel_handler (p_in, p_out, red_band,
+				mono_uint8_pixel_handler (p_in, p_out,
+							  red_band,
 							  red_handling);
 			    p_out =
 				mono_uint8_pixel_handler (p_in, p_out,
@@ -750,9 +1030,10 @@ copy_uint8_raw_mono_pixels (const unsigned char *buffer,
 			    const unsigned char *mask, unsigned char *outbuf,
 			    unsigned short width, unsigned short height,
 			    unsigned char out_num_bands,
-			    unsigned char num_bands, double x_res, double y_res,
-			    double minx, double maxy, double tile_minx,
-			    double tile_maxy, unsigned short tile_width,
+			    unsigned char num_bands, double x_res,
+			    double y_res, double minx, double maxy,
+			    double tile_minx, double tile_maxy,
+			    unsigned short tile_width,
 			    unsigned short tile_height, rl2PixelPtr no_data,
 			    unsigned char mono_band,
 			    rl2BandHandlingPtr mono_handling)
@@ -1123,13 +1404,13 @@ copy_int16_raw_mono_pixels (const short *buffer,
 }
 
 static void
-copy_uint16_raw_pixels (const unsigned short *buffer, const unsigned char *mask,
-			unsigned short *outbuf, unsigned short width,
-			unsigned short height, unsigned char num_bands,
-			double x_res, double y_res, double minx, double maxy,
-			double tile_minx, double tile_maxy,
-			unsigned short tile_width, unsigned short tile_height,
-			rl2PixelPtr no_data)
+copy_uint16_raw_pixels (const unsigned short *buffer,
+			const unsigned char *mask, unsigned short *outbuf,
+			unsigned short width, unsigned short height,
+			unsigned char num_bands, double x_res, double y_res,
+			double minx, double maxy, double tile_minx,
+			double tile_maxy, unsigned short tile_width,
+			unsigned short tile_height, rl2PixelPtr no_data)
 {
 /* copying UINT16 raw pixels from the DBMS tile into the output image */
     int x;
@@ -1260,10 +1541,11 @@ static void
 copy_uint16_raw_selected_pixels (const unsigned short *buffer,
 				 const unsigned char *mask,
 				 unsigned char *outbuf, unsigned short width,
-				 unsigned short height, unsigned char num_bands,
-				 double x_res, double y_res, double minx,
-				 double maxy, double tile_minx,
-				 double tile_maxy, unsigned short tile_width,
+				 unsigned short height,
+				 unsigned char num_bands, double x_res,
+				 double y_res, double minx, double maxy,
+				 double tile_minx, double tile_maxy,
+				 unsigned short tile_width,
 				 unsigned short tile_height,
 				 rl2PixelPtr no_data, unsigned char red_band,
 				 unsigned char green_band,
@@ -2531,8 +2813,8 @@ compute_stretching (rl2PrivBandStatisticsPtr band, double *min, double *max,
     double sum = 0.0;
     double percentile_2;
     double percentile_98;
-    double vmin;
-    double vmax;
+    double vmin = DBL_MAX;
+    double vmax = 0.0 - DBL_MAX;
     double range;
 
     for (i = 0; i < band->nHistogram; i++)
@@ -2572,7 +2854,7 @@ compute_stretching (rl2PrivBandStatisticsPtr band, double *min, double *max,
 }
 
 static void
-build_triple_band_handling (rl2PrivRasterStylePtr style,
+build_triple_band_handling (rl2PrivRasterSymbolizerPtr style,
 			    rl2PrivRasterStatisticsPtr stats,
 			    unsigned char red_band, unsigned char green_band,
 			    unsigned char blue_band,
@@ -2805,8 +3087,8 @@ build_triple_band_handling (rl2PrivRasterStylePtr style,
 		      r->colorMap = NULL;
 		      r->contrastEnhancement =
 			  RL2_CONTRAST_ENHANCEMENT_NORMALIZE;
-		      compute_stretching (band, &(r->minValue), &(r->maxValue),
-					  &(r->scaleFactor));
+		      compute_stretching (band, &(r->minValue),
+					  &(r->maxValue), &(r->scaleFactor));
 		  }
 		else if (style->contrastEnhancement ==
 			 RL2_CONTRAST_ENHANCEMENT_NONE)
@@ -2891,8 +3173,8 @@ build_triple_band_handling (rl2PrivRasterStylePtr style,
 		      g->colorMap = NULL;
 		      g->contrastEnhancement =
 			  RL2_CONTRAST_ENHANCEMENT_NORMALIZE;
-		      compute_stretching (band, &(g->minValue), &(g->maxValue),
-					  &(g->scaleFactor));
+		      compute_stretching (band, &(g->minValue),
+					  &(g->maxValue), &(g->scaleFactor));
 		  }
 		else if (style->contrastEnhancement ==
 			 RL2_CONTRAST_ENHANCEMENT_NONE)
@@ -2977,8 +3259,8 @@ build_triple_band_handling (rl2PrivRasterStylePtr style,
 		      b->colorMap = NULL;
 		      b->contrastEnhancement =
 			  RL2_CONTRAST_ENHANCEMENT_NORMALIZE;
-		      compute_stretching (band, &(b->minValue), &(b->maxValue),
-					  &(b->scaleFactor));
+		      compute_stretching (band, &(b->minValue),
+					  &(b->maxValue), &(b->scaleFactor));
 		  }
 		else if (style->contrastEnhancement ==
 			 RL2_CONTRAST_ENHANCEMENT_NONE)
@@ -3077,7 +3359,7 @@ add_color_rule (rl2ColorMapItemPtr c, rl2ColorMapRefPtr col)
 }
 
 static void
-build_mono_band_handling (rl2PrivRasterStylePtr style,
+build_mono_band_handling (rl2PrivRasterSymbolizerPtr style,
 			  rl2PrivRasterStatisticsPtr stats,
 			  unsigned char mono_band,
 			  rl2BandHandlingPtr * mono_handling)
@@ -3329,8 +3611,8 @@ build_mono_band_handling (rl2PrivRasterStylePtr style,
 		      g->colorMap = NULL;
 		      g->contrastEnhancement =
 			  RL2_CONTRAST_ENHANCEMENT_NORMALIZE;
-		      compute_stretching (band, &(g->minValue), &(g->maxValue),
-					  &(g->scaleFactor));
+		      compute_stretching (band, &(g->minValue),
+					  &(g->maxValue), &(g->scaleFactor));
 		  }
 		else if (style->contrastEnhancement ==
 			 RL2_CONTRAST_ENHANCEMENT_NONE)
@@ -3405,23 +3687,206 @@ build_mono_band_handling (rl2PrivRasterStylePtr style,
 		  }
 	    }
       }
-    *mono_handling = g;
+    *mono_handling = g;
+}
+
+static void
+destroy_mono_handling (rl2BandHandlingPtr mono)
+{
+/* memory cleanup - destroying a MONO handler */
+    if (mono == NULL)
+	return;
+    if (mono->colorMap != NULL)
+      {
+	  int i;
+	  for (i = 0; i < 256; i++)
+	    {
+		rl2ColorMapRefPtr rule;
+		rl2ColorMapRefPtr n_rule;
+		rl2ColorMapItemPtr item = &(mono->colorMap->look_up[i]);
+		rule = item->first;
+		while (rule != NULL)
+		  {
+		      n_rule = rule->next;
+		      free (rule);
+		      rule = n_rule;
+		  }
+	    }
+	  free (mono->colorMap);
+      }
+    free (mono);
+}
+
+static void
+build_ndvi_handling (rl2PrivRasterSymbolizerPtr style,
+		     rl2BandHandlingPtr * ndvi_handling)
+{
+/* creating NDVI helper structs */
+    int i;
+    rl2BandHandlingPtr g = NULL;
+    rl2PrivColorMapPointPtr color;
+    rl2PrivColorMapPointPtr prev_color;
+    if (style->categorize != NULL)
+      {
+	  /* using the Categorize ColorMap */
+	  g = malloc (sizeof (rl2BandHandling));
+	  g->minValue = 1.0;
+	  g->maxValue = 1.0;
+	  g->scaleFactor = 2.0 / 256.0;
+	  g->colorMap = malloc (sizeof (rl2ColorMapLocator));
+	  g->colorMap->interpolate = 0;
+	  for (i = 0; i < 256; i++)
+	    {
+		rl2ColorMapItemPtr c = &(g->colorMap->look_up[i]);
+		c->first = NULL;
+		c->last = NULL;
+	    }
+	  g->colorMap->red = style->categorize->dfltRed;
+	  g->colorMap->green = style->categorize->dfltGreen;
+	  g->colorMap->blue = style->categorize->dfltBlue;
+	  color = style->categorize->first;
+	  prev_color = NULL;
+	  while (color != NULL)
+	    {
+		rl2ColorMapRef col;
+		if (prev_color == NULL)
+		  {
+		      /* first category */
+		      col.min = 0.0 - DBL_MAX;
+		      col.max = color->value;
+		      col.red = style->categorize->baseRed;
+		      col.green = style->categorize->baseGreen;
+		      col.blue = style->categorize->baseBlue;
+		      for (i = 0; i < 256; i++)
+			{
+			    rl2ColorMapItemPtr c = &(g->colorMap->look_up[i]);
+			    double v1 = -1.0 + ((double) i * g->scaleFactor);
+			    double v2 =
+				-1.0 + ((double) (i + 1) * g->scaleFactor);
+			    if ((v1 >= col.min && v1 < col.max)
+				|| (v2 >= col.min && v2 < col.max)
+				|| (col.min >= v1 && col.min < v2)
+				|| (col.max >= v2 && col.max < v2))
+				add_color_rule (c, &col);
+			}
+		  }
+		else
+		  {
+		      /* any other category */
+		      col.min = prev_color->value;
+		      col.max = color->value;
+		      col.red = prev_color->red;
+		      col.green = prev_color->green;
+		      col.blue = prev_color->blue;
+		      for (i = 0; i < 256; i++)
+			{
+			    rl2ColorMapItemPtr c = &(g->colorMap->look_up[i]);
+			    double v1 = -1.0 + ((double) i * g->scaleFactor);
+			    double v2 =
+				-1.0 + ((double) (i + 1) * g->scaleFactor);
+			    if ((v1 >= col.min && v1 < col.max)
+				|| (v2 >= col.min && v2 < col.max)
+				|| (col.min >= v1 && col.min < v2)
+				|| (col.max >= v2 && col.max < v2))
+				add_color_rule (c, &col);
+			}
+		  }
+		if (color->next == NULL)
+		  {
+		      /* last category */
+		      col.min = color->value;
+		      col.max = DBL_MAX;
+		      col.red = color->red;
+		      col.green = color->green;
+		      col.blue = color->blue;
+		      for (i = 0; i < 256; i++)
+			{
+			    rl2ColorMapItemPtr c = &(g->colorMap->look_up[i]);
+			    double v1 = -1.0 + ((double) i * g->scaleFactor);
+			    double v2 =
+				-1.0 + ((double) (i + 1) * g->scaleFactor);
+			    if ((v1 >= col.min && v1 < col.max)
+				|| (v2 >= col.min && v2 < col.max)
+				|| (col.min >= v1 && col.min < v2)
+				|| (col.max >= v2 && col.max < v2))
+				add_color_rule (c, &col);
+			}
+		  }
+		prev_color = color;
+		color = color->next;
+	    }
+	  *ndvi_handling = g;
+	  return;
+      }
+    if (style->interpolate != NULL)
+      {
+	  /* using the Interpolate ColorMap */
+	  g = malloc (sizeof (rl2BandHandling));
+	  g->minValue = -1.0;
+	  g->maxValue = 1.0;
+	  g->scaleFactor = 2.0 / 256.0;
+	  g->colorMap = malloc (sizeof (rl2ColorMapLocator));
+	  g->colorMap->interpolate = 1;
+	  for (i = 0; i < 256; i++)
+	    {
+		rl2ColorMapItemPtr c = &(g->colorMap->look_up[i]);
+		c->first = NULL;
+		c->last = NULL;
+	    }
+	  g->colorMap->red = style->interpolate->dfltRed;
+	  g->colorMap->green = style->interpolate->dfltGreen;
+	  g->colorMap->blue = style->interpolate->dfltBlue;
+	  color = style->interpolate->first;
+	  prev_color = NULL;
+	  while (color != NULL)
+	    {
+		rl2ColorMapRef col;
+		if (prev_color != NULL)
+		  {
+		      col.min = prev_color->value;
+		      col.max = color->value;
+		      col.red = prev_color->red;
+		      col.green = prev_color->green;
+		      col.blue = prev_color->blue;
+		      col.maxRed = color->red;
+		      col.maxGreen = color->green;
+		      col.maxBlue = color->blue;
+		      for (i = 0; i < 256; i++)
+			{
+			    rl2ColorMapItemPtr c = &(g->colorMap->look_up[i]);
+			    double v1 = -1.0 + ((double) i * g->scaleFactor);
+			    double v2 =
+				-1.0 + ((double) (i + 1) * g->scaleFactor);
+			    if ((v1 >= col.min && v1 < col.max)
+				|| (v2 >= col.min && v2 < col.max)
+				|| (col.min >= v1 && col.min < v2)
+				|| (col.max >= v2 && col.max < v2))
+				add_color_rule (c, &col);
+			}
+		  }
+		prev_color = color;
+		color = color->next;
+	    }
+	  *ndvi_handling = g;
+	  return;
+      }
+    *ndvi_handling = g;
 }
 
 static void
-destroy_mono_handling (rl2BandHandlingPtr mono)
+destroy_ndvi_handling (rl2BandHandlingPtr ndvi)
 {
-/* memory cleanup - destroying a MONO handler */
-    if (mono == NULL)
+/* memory cleanup - destroying an NDVI handler */
+    if (ndvi == NULL)
 	return;
-    if (mono->colorMap != NULL)
+    if (ndvi->colorMap != NULL)
       {
 	  int i;
 	  for (i = 0; i < 256; i++)
 	    {
 		rl2ColorMapRefPtr rule;
 		rl2ColorMapRefPtr n_rule;
-		rl2ColorMapItemPtr item = &(mono->colorMap->look_up[i]);
+		rl2ColorMapItemPtr item = &(ndvi->colorMap->look_up[i]);
 		rule = item->first;
 		while (rule != NULL)
 		  {
@@ -3430,19 +3895,366 @@ destroy_mono_handling (rl2BandHandlingPtr mono)
 		      rule = n_rule;
 		  }
 	    }
-	  free (mono->colorMap);
+	  free (ndvi->colorMap);
       }
-    free (mono);
+    free (ndvi);
+}
+
+static int
+do_copy_raw_selected_pixels (rl2PrivRasterPtr rst, unsigned char *outbuf,
+			     unsigned int width, unsigned int height,
+			     double x_res, double y_res, double minx,
+			     double maxy, double tile_minx, double tile_maxy,
+			     unsigned int tile_width,
+			     unsigned int tile_height, rl2PixelPtr no_data,
+			     unsigned char red_band, unsigned char green_band,
+			     unsigned char blue_band,
+			     rl2BandHandlingPtr red_handling,
+			     rl2BandHandlingPtr green_handling,
+			     rl2BandHandlingPtr blue_handling)
+{
+    switch (rst->sampleType)
+      {
+      case RL2_SAMPLE_UINT8:
+	  copy_uint8_raw_selected_pixels ((const unsigned char
+					   *)
+					  (rst->rasterBuffer),
+					  (const unsigned char
+					   *)
+					  (rst->maskBuffer),
+					  (unsigned char *)
+					  outbuf, width,
+					  height, rst->nBands,
+					  x_res, y_res, minx,
+					  maxy, tile_minx,
+					  tile_maxy,
+					  tile_width,
+					  tile_height,
+					  no_data, red_band,
+					  green_band,
+					  blue_band,
+					  red_handling,
+					  green_handling, blue_handling);
+	  if (red_handling != NULL)
+	      free (red_handling);
+	  if (green_handling != NULL)
+	      free (green_handling);
+	  if (blue_handling != NULL)
+	      free (blue_handling);
+	  return 1;
+      case RL2_SAMPLE_UINT16:
+	  copy_uint16_raw_selected_pixels ((const unsigned
+					    short
+					    *)
+					   (rst->rasterBuffer),
+					   (const unsigned
+					    char
+					    *)
+					   (rst->maskBuffer),
+					   (unsigned char *)
+					   outbuf, width,
+					   height,
+					   rst->nBands, x_res,
+					   y_res, minx, maxy,
+					   tile_minx,
+					   tile_maxy,
+					   tile_width,
+					   tile_height,
+					   no_data, red_band,
+					   green_band,
+					   blue_band,
+					   red_handling,
+					   green_handling, blue_handling);
+	  if (red_handling != NULL)
+	      free (red_handling);
+	  if (green_handling != NULL)
+	      free (green_handling);
+	  if (blue_handling != NULL)
+	      free (blue_handling);
+	  return 1;
+      };
+    return 0;
+}
+
+static int
+do_copy_raw_mono_pixels (rl2PrivRasterPtr rst, unsigned char *outbuf,
+			 unsigned int width, unsigned int height,
+			 unsigned char num_bands, double x_res, double y_res,
+			 double minx, double maxy, double tile_minx,
+			 double tile_maxy, unsigned int tile_width,
+			 unsigned int tile_height, rl2PixelPtr no_data,
+			 unsigned char mono_band,
+			 rl2BandHandlingPtr mono_handling)
+{
+    switch (rst->sampleType)
+      {
+      case RL2_SAMPLE_INT8:
+	  copy_int8_raw_mono_pixels ((const char
+				      *) (rst->rasterBuffer),
+				     (const unsigned char
+				      *) (rst->maskBuffer),
+				     (unsigned char *) outbuf,
+				     width, height, num_bands,
+				     x_res, y_res, minx, maxy,
+				     tile_minx, tile_maxy,
+				     tile_width, tile_height,
+				     no_data, mono_band, mono_handling);
+	  if (mono_handling != NULL)
+	      destroy_mono_handling (mono_handling);
+	  return 1;
+      case RL2_SAMPLE_UINT8:
+	  copy_uint8_raw_mono_pixels ((const unsigned char
+				       *) (rst->rasterBuffer),
+				      (const unsigned char
+				       *) (rst->maskBuffer),
+				      (unsigned char *)
+				      outbuf, width, height,
+				      num_bands, rst->nBands,
+				      x_res, y_res, minx,
+				      maxy, tile_minx,
+				      tile_maxy, tile_width,
+				      tile_height, no_data,
+				      mono_band, mono_handling);
+	  if (mono_handling != NULL)
+	      destroy_mono_handling (mono_handling);
+	  return 1;
+      case RL2_SAMPLE_INT16:
+	  copy_int16_raw_mono_pixels ((const short
+				       *) (rst->rasterBuffer),
+				      (const unsigned char
+				       *) (rst->maskBuffer),
+				      (unsigned char *)
+				      outbuf, width, height,
+				      num_bands, x_res, y_res,
+				      minx, maxy, tile_minx,
+				      tile_maxy, tile_width,
+				      tile_height, no_data,
+				      mono_band, mono_handling);
+	  if (mono_handling != NULL)
+	      destroy_mono_handling (mono_handling);
+	  return 1;
+      case RL2_SAMPLE_UINT16:
+	  copy_uint16_raw_mono_pixels ((const unsigned short
+					*)
+				       (rst->rasterBuffer),
+				       (const unsigned char
+					*) (rst->maskBuffer),
+				       (unsigned char *)
+				       outbuf, width, height,
+				       num_bands, rst->nBands,
+				       x_res, y_res, minx,
+				       maxy, tile_minx,
+				       tile_maxy, tile_width,
+				       tile_height, no_data,
+				       mono_band, mono_handling);
+	  if (mono_handling != NULL)
+	      destroy_mono_handling (mono_handling);
+	  return 1;
+      case RL2_SAMPLE_INT32:
+	  copy_int32_raw_mono_pixels ((const int
+				       *) (rst->rasterBuffer),
+				      (const unsigned char
+				       *) (rst->maskBuffer),
+				      (unsigned char *)
+				      outbuf, width, height,
+				      num_bands, x_res, y_res,
+				      minx, maxy, tile_minx,
+				      tile_maxy, tile_width,
+				      tile_height, no_data,
+				      mono_band, mono_handling);
+	  if (mono_handling != NULL)
+	      destroy_mono_handling (mono_handling);
+	  return 1;
+      case RL2_SAMPLE_UINT32:
+	  copy_uint32_raw_mono_pixels ((const unsigned int
+					*)
+				       (rst->rasterBuffer),
+				       (const unsigned char
+					*) (rst->maskBuffer),
+				       (unsigned char *)
+				       outbuf, width, height,
+				       num_bands, x_res,
+				       y_res, minx, maxy,
+				       tile_minx, tile_maxy,
+				       tile_width,
+				       tile_height, no_data,
+				       mono_band, mono_handling);
+	  if (mono_handling != NULL)
+	      destroy_mono_handling (mono_handling);
+	  return 1;
+      case RL2_SAMPLE_FLOAT:
+	  copy_float_raw_mono_pixels ((const float
+				       *) (rst->rasterBuffer),
+				      (const unsigned char
+				       *) (rst->maskBuffer),
+				      (unsigned char *)
+				      outbuf, width, height,
+				      num_bands, x_res, y_res,
+				      minx, maxy, tile_minx,
+				      tile_maxy, tile_width,
+				      tile_height, no_data,
+				      mono_band, mono_handling);
+	  if (mono_handling != NULL)
+	      destroy_mono_handling (mono_handling);
+	  return 1;
+      case RL2_SAMPLE_DOUBLE:
+	  copy_double_raw_mono_pixels ((const double
+					*)
+				       (rst->rasterBuffer),
+				       (const unsigned char
+					*) (rst->maskBuffer),
+				       (unsigned char *)
+				       outbuf, width, height,
+				       num_bands, x_res,
+				       y_res, minx, maxy,
+				       tile_minx, tile_maxy,
+				       tile_width,
+				       tile_height, no_data,
+				       mono_band, mono_handling);
+	  if (mono_handling != NULL)
+	      destroy_mono_handling (mono_handling);
+	  return 1;
+      };
+    return 0;
+}
+
+static int
+do_auto_ndvi_pixels (rl2PrivRasterPtr rst, unsigned char *outbuf,
+		     unsigned int width, unsigned int height,
+		     unsigned char num_bands, double x_res, double y_res,
+		     double minx, double maxy, double tile_minx,
+		     double tile_maxy, unsigned int tile_width,
+		     unsigned int tile_height, rl2PixelPtr no_data,
+		     unsigned char red_band, unsigned char nir_band,
+		     rl2BandHandlingPtr ndvi_handling)
+{
+    switch (rst->sampleType)
+      {
+      case RL2_SAMPLE_UINT8:
+	  copy_uint8_ndvi_pixels ((const unsigned char
+				   *) (rst->rasterBuffer),
+				  (const unsigned char
+				   *) (rst->maskBuffer),
+				  (unsigned char *)
+				  outbuf, width, height,
+				  num_bands, rst->nBands,
+				  x_res, y_res, minx,
+				  maxy, tile_minx,
+				  tile_maxy, tile_width,
+				  tile_height, no_data,
+				  red_band, nir_band, ndvi_handling);
+	  if (ndvi_handling != NULL)
+	      destroy_ndvi_handling (ndvi_handling);
+	  return 1;
+      case RL2_SAMPLE_UINT16:
+	  copy_uint16_ndvi_pixels ((const unsigned short
+				    *)
+				   (rst->rasterBuffer),
+				   (const unsigned char
+				    *) (rst->maskBuffer),
+				   (unsigned char *)
+				   outbuf, width, height,
+				   num_bands, rst->nBands,
+				   x_res, y_res, minx,
+				   maxy, tile_minx,
+				   tile_maxy, tile_width,
+				   tile_height, no_data,
+				   red_band, nir_band, ndvi_handling);
+	  if (ndvi_handling != NULL)
+	      destroy_ndvi_handling (ndvi_handling);
+	  return 1;
+      };
+    return 0;
+}
+
+static int
+do_copy_raw_pixels (rl2PrivRasterPtr rst, unsigned char *outbuf,
+		    unsigned int width, unsigned int height,
+		    unsigned char sample_type, unsigned char num_bands,
+		    double x_res, double y_res, double minx, double maxy,
+		    double tile_minx, double tile_maxy,
+		    unsigned int tile_width, unsigned int tile_height,
+		    rl2PixelPtr no_data)
+{
+
+
+    switch (sample_type)
+      {
+      case RL2_SAMPLE_INT8:
+	  copy_int8_raw_pixels ((const char *) (rst->rasterBuffer),
+				(const unsigned char *) (rst->maskBuffer),
+				(char *) outbuf, width, height,
+				x_res, y_res, minx, maxy, tile_minx,
+				tile_maxy, tile_width, tile_height, no_data);
+	  return 1;
+      case RL2_SAMPLE_INT16:
+	  copy_int16_raw_pixels ((const short *) (rst->rasterBuffer),
+				 (const unsigned char *) (rst->maskBuffer),
+				 (short *) outbuf, width, height,
+				 x_res, y_res, minx, maxy, tile_minx,
+				 tile_maxy, tile_width, tile_height, no_data);
+	  return 1;
+      case RL2_SAMPLE_UINT16:
+	  copy_uint16_raw_pixels ((const unsigned short
+				   *) (rst->rasterBuffer),
+				  (const unsigned char *) (rst->maskBuffer),
+				  (unsigned short *) outbuf, width, height,
+				  num_bands, x_res, y_res, minx, maxy,
+				  tile_minx, tile_maxy, tile_width,
+				  tile_height, no_data);
+	  return 1;
+      case RL2_SAMPLE_INT32:
+	  copy_int32_raw_pixels ((const int *) (rst->rasterBuffer),
+				 (const unsigned char *) (rst->maskBuffer),
+				 (int *) outbuf, width, height,
+				 x_res, y_res, minx, maxy, tile_minx,
+				 tile_maxy, tile_width, tile_height, no_data);
+	  return 1;
+      case RL2_SAMPLE_UINT32:
+	  copy_uint32_raw_pixels ((const unsigned int *) (rst->rasterBuffer),
+				  (const unsigned char *) (rst->maskBuffer),
+				  (unsigned int *) outbuf, width, height,
+				  x_res, y_res, minx, maxy,
+				  tile_minx, tile_maxy, tile_width,
+				  tile_height, no_data);
+	  return 1;
+      case RL2_SAMPLE_FLOAT:
+	  copy_float_raw_pixels ((const float *) (rst->rasterBuffer),
+				 (const unsigned char *) (rst->maskBuffer),
+				 (float *) outbuf, width, height,
+				 x_res, y_res, minx, maxy, tile_minx,
+				 tile_maxy, tile_width, tile_height, no_data);
+	  return 1;
+      case RL2_SAMPLE_DOUBLE:
+	  copy_double_raw_pixels ((const double *) (rst->rasterBuffer),
+				  (const unsigned char *) (rst->maskBuffer),
+				  (double *) outbuf, width, height,
+				  x_res, y_res, minx, maxy,
+				  tile_minx, tile_maxy, tile_width,
+				  tile_height, no_data);
+	  return 1;
+      default:
+	  copy_uint8_raw_pixels ((const unsigned char *) (rst->rasterBuffer),
+				 (const unsigned char *) (rst->maskBuffer),
+				 (unsigned char *) outbuf, width, height,
+				 num_bands, x_res, y_res, minx, maxy,
+				 tile_minx, tile_maxy, tile_width,
+				 tile_height, no_data);
+	  return 1;
+      };
+    return 0;
 }
 
 RL2_PRIVATE int
-copy_raw_pixels (rl2RasterPtr raster, unsigned char *outbuf,
-		 unsigned int width,
-		 unsigned int height, unsigned char sample_type,
-		 unsigned char num_bands, double x_res, double y_res,
-		 double minx, double maxy, double tile_minx, double tile_maxy,
-		 rl2PixelPtr no_data, rl2RasterStylePtr style,
-		 rl2RasterStatisticsPtr stats)
+rl2_copy_raw_pixels (rl2RasterPtr raster, unsigned char *outbuf,
+		     unsigned int width,
+		     unsigned int height, unsigned char sample_type,
+		     unsigned char num_bands, unsigned char auto_ndvi,
+		     unsigned char red_band_index,
+		     unsigned char nir_band_index, double x_res, double y_res,
+		     double minx, double maxy, double tile_minx,
+		     double tile_maxy, rl2PixelPtr no_data,
+		     rl2RasterSymbolizerPtr style, rl2RasterStatisticsPtr stats)
 {
 /* copying raw pixels into the output buffer */
     unsigned int tile_width;
@@ -3455,8 +4267,10 @@ copy_raw_pixels (rl2RasterPtr raster, unsigned char *outbuf,
       {
 	  /* attempting to apply a RasterSymbolizer */
 	  int yes_no;
-	  if (rl2_is_raster_style_triple_band_selected (style, &yes_no) ==
-	      RL2_OK)
+	  int categorize;
+	  int interpolate;
+	  if (rl2_is_raster_symbolizer_triple_band_selected (style, &yes_no)
+	      == RL2_OK)
 	    {
 		if ((rst->sampleType == RL2_SAMPLE_UINT8
 		     || rst->sampleType == RL2_SAMPLE_UINT16)
@@ -3470,7 +4284,7 @@ copy_raw_pixels (rl2RasterPtr raster, unsigned char *outbuf,
 		      rl2BandHandlingPtr red_handling = NULL;
 		      rl2BandHandlingPtr green_handling = NULL;
 		      rl2BandHandlingPtr blue_handling = NULL;
-		      if (rl2_get_raster_style_triple_band_selection
+		      if (rl2_get_raster_symbolizer_triple_band_selection
 			  (style, &red_band, &green_band, &blue_band) != RL2_OK)
 			  return 0;
 		      if (red_band >= rst->nBands)
@@ -3479,7 +4293,8 @@ copy_raw_pixels (rl2RasterPtr raster, unsigned char *outbuf,
 			  return 0;
 		      if (blue_band >= rst->nBands)
 			  return 0;
-		      build_triple_band_handling ((rl2PrivRasterStylePtr) style,
+		      build_triple_band_handling ((rl2PrivRasterSymbolizerPtr)
+						  style,
 						  (rl2PrivRasterStatisticsPtr)
 						  stats, red_band, green_band,
 						  blue_band, &red_handling,
@@ -3488,72 +4303,45 @@ copy_raw_pixels (rl2RasterPtr raster, unsigned char *outbuf,
 		      if (red_handling == NULL || green_handling == NULL
 			  || blue_handling == NULL)
 			  return 0;
-		      switch (rst->sampleType)
-			{
-			case RL2_SAMPLE_UINT8:
-			    copy_uint8_raw_selected_pixels ((const unsigned char
-							     *)
-							    (rst->rasterBuffer),
-							    (const unsigned char
-							     *)
-							    (rst->maskBuffer),
-							    (unsigned char *)
-							    outbuf, width,
-							    height, rst->nBands,
-							    x_res, y_res, minx,
-							    maxy, tile_minx,
-							    tile_maxy,
-							    tile_width,
-							    tile_height,
-							    no_data, red_band,
-							    green_band,
-							    blue_band,
-							    red_handling,
-							    green_handling,
-							    blue_handling);
-			    if (red_handling != NULL)
-				free (red_handling);
-			    if (green_handling != NULL)
-				free (green_handling);
-			    if (blue_handling != NULL)
-				free (blue_handling);
-			    return 1;
-			case RL2_SAMPLE_UINT16:
-			    copy_uint16_raw_selected_pixels ((const unsigned
-							      short
-							      *)
-							     (rst->rasterBuffer),
-							     (const unsigned
-							      char
-							      *)
-							     (rst->maskBuffer),
-							     (unsigned char *)
-							     outbuf, width,
-							     height,
-							     rst->nBands, x_res,
-							     y_res, minx, maxy,
-							     tile_minx,
-							     tile_maxy,
-							     tile_width,
-							     tile_height,
-							     no_data, red_band,
-							     green_band,
-							     blue_band,
-							     red_handling,
-							     green_handling,
-							     blue_handling);
-			    if (red_handling != NULL)
-				free (red_handling);
-			    if (green_handling != NULL)
-				free (green_handling);
-			    if (blue_handling != NULL)
-				free (blue_handling);
-			    return 1;
-			};
+		      if (do_copy_raw_selected_pixels
+			  (rst, outbuf, width, height, x_res, y_res, minx,
+			   maxy, tile_minx, tile_maxy, tile_width,
+			   tile_height, no_data, red_band, green_band,
+			   blue_band, red_handling, green_handling,
+			   blue_handling))
+			  return 1;
+		      if (red_handling != NULL)
+			  free (red_handling);
+		      if (green_handling != NULL)
+			  free (green_handling);
+		      if (blue_handling != NULL)
+			  free (blue_handling);
+
 		  }
 	    }
-	  if (rl2_is_raster_style_mono_band_selected (style, &yes_no) == RL2_OK)
+	  if (rl2_is_raster_symbolizer_mono_band_selected
+	      (style, &yes_no, &categorize, &interpolate) == RL2_OK)
 	    {
+		if ((rst->sampleType == RL2_SAMPLE_UINT8
+		     || rst->sampleType == RL2_SAMPLE_UINT16)
+		    && rst->pixelType == RL2_PIXEL_MULTIBAND && auto_ndvi
+		    && (categorize || interpolate))
+		  {
+		      /* applying Auto NDVI */
+		      rl2BandHandlingPtr ndvi_handling = NULL;
+		      build_ndvi_handling ((rl2PrivRasterSymbolizerPtr)
+					   style, &ndvi_handling);
+		      if (ndvi_handling == NULL)
+			  return 0;
+		      if (do_auto_ndvi_pixels
+			  (rst, outbuf, width, height, num_bands, x_res,
+			   y_res, minx, maxy, tile_minx, tile_maxy,
+			   tile_width, tile_height, no_data, red_band_index,
+			   nir_band_index, ndvi_handling))
+			  return 1;
+		      if (ndvi_handling != NULL)
+			  destroy_ndvi_handling (ndvi_handling);
+		  }
 		if (((rst->sampleType == RL2_SAMPLE_UINT8
 		      || rst->sampleType == RL2_SAMPLE_UINT16)
 		     || rst->pixelType == RL2_PIXEL_DATAGRID) && yes_no)
@@ -3561,220 +4349,34 @@ copy_raw_pixels (rl2RasterPtr raster, unsigned char *outbuf,
 		      /* mono band selection - false color Grayscale */
 		      unsigned char mono_band;
 		      rl2BandHandlingPtr mono_handling = NULL;
-		      if (rl2_get_raster_style_mono_band_selection
+		      if (rl2_get_raster_symbolizer_mono_band_selection
 			  (style, &mono_band) != RL2_OK)
 			  return 0;
 		      if (mono_band >= rst->nBands)
 			  return 0;
-		      build_mono_band_handling ((rl2PrivRasterStylePtr) style,
+		      build_mono_band_handling ((rl2PrivRasterSymbolizerPtr)
+						style,
 						(rl2PrivRasterStatisticsPtr)
 						stats, mono_band,
 						&mono_handling);
 		      if (mono_handling == NULL)
 			  return 0;
-		      switch (rst->sampleType)
-			{
-			case RL2_SAMPLE_INT8:
-			    copy_int8_raw_mono_pixels ((const char
-							*) (rst->rasterBuffer),
-						       (const unsigned char
-							*) (rst->maskBuffer),
-						       (unsigned char *) outbuf,
-						       width, height, num_bands,
-						       x_res, y_res, minx, maxy,
-						       tile_minx, tile_maxy,
-						       tile_width, tile_height,
-						       no_data, mono_band,
-						       mono_handling);
-			    if (mono_handling != NULL)
-				destroy_mono_handling (mono_handling);
-			    return 1;
-			case RL2_SAMPLE_UINT8:
-			    copy_uint8_raw_mono_pixels ((const unsigned char
-							 *) (rst->rasterBuffer),
-							(const unsigned char
-							 *) (rst->maskBuffer),
-							(unsigned char *)
-							outbuf, width, height,
-							num_bands, rst->nBands,
-							x_res, y_res, minx,
-							maxy, tile_minx,
-							tile_maxy, tile_width,
-							tile_height, no_data,
-							mono_band,
-							mono_handling);
-			    if (mono_handling != NULL)
-				destroy_mono_handling (mono_handling);
-			    return 1;
-			case RL2_SAMPLE_INT16:
-			    copy_int16_raw_mono_pixels ((const short
-							 *) (rst->rasterBuffer),
-							(const unsigned char
-							 *) (rst->maskBuffer),
-							(unsigned char *)
-							outbuf, width, height,
-							num_bands, x_res, y_res,
-							minx, maxy, tile_minx,
-							tile_maxy, tile_width,
-							tile_height, no_data,
-							mono_band,
-							mono_handling);
-			    if (mono_handling != NULL)
-				destroy_mono_handling (mono_handling);
-			    return 1;
-			case RL2_SAMPLE_UINT16:
-			    copy_uint16_raw_mono_pixels ((const unsigned short
-							  *)
-							 (rst->rasterBuffer),
-							 (const unsigned char
-							  *) (rst->maskBuffer),
-							 (unsigned char *)
-							 outbuf, width, height,
-							 num_bands, rst->nBands,
-							 x_res, y_res, minx,
-							 maxy, tile_minx,
-							 tile_maxy, tile_width,
-							 tile_height, no_data,
-							 mono_band,
-							 mono_handling);
-			    if (mono_handling != NULL)
-				destroy_mono_handling (mono_handling);
-			    return 1;
-			case RL2_SAMPLE_INT32:
-			    copy_int32_raw_mono_pixels ((const int
-							 *) (rst->rasterBuffer),
-							(const unsigned char
-							 *) (rst->maskBuffer),
-							(unsigned char *)
-							outbuf, width, height,
-							num_bands, x_res, y_res,
-							minx, maxy, tile_minx,
-							tile_maxy, tile_width,
-							tile_height, no_data,
-							mono_band,
-							mono_handling);
-			    if (mono_handling != NULL)
-				destroy_mono_handling (mono_handling);
-			    return 1;
-			case RL2_SAMPLE_UINT32:
-			    copy_uint32_raw_mono_pixels ((const unsigned int
-							  *)
-							 (rst->rasterBuffer),
-							 (const unsigned char
-							  *) (rst->maskBuffer),
-							 (unsigned char *)
-							 outbuf, width, height,
-							 num_bands, x_res,
-							 y_res, minx, maxy,
-							 tile_minx, tile_maxy,
-							 tile_width,
-							 tile_height, no_data,
-							 mono_band,
-							 mono_handling);
-			    if (mono_handling != NULL)
-				destroy_mono_handling (mono_handling);
-			    return 1;
-			case RL2_SAMPLE_FLOAT:
-			    copy_float_raw_mono_pixels ((const float
-							 *) (rst->rasterBuffer),
-							(const unsigned char
-							 *) (rst->maskBuffer),
-							(unsigned char *)
-							outbuf, width, height,
-							num_bands, x_res, y_res,
-							minx, maxy, tile_minx,
-							tile_maxy, tile_width,
-							tile_height, no_data,
-							mono_band,
-							mono_handling);
-			    if (mono_handling != NULL)
-				destroy_mono_handling (mono_handling);
-			    return 1;
-			case RL2_SAMPLE_DOUBLE:
-			    copy_double_raw_mono_pixels ((const double
-							  *)
-							 (rst->rasterBuffer),
-							 (const unsigned char
-							  *) (rst->maskBuffer),
-							 (unsigned char *)
-							 outbuf, width, height,
-							 num_bands, x_res,
-							 y_res, minx, maxy,
-							 tile_minx, tile_maxy,
-							 tile_width,
-							 tile_height, no_data,
-							 mono_band,
-							 mono_handling);
-			    if (mono_handling != NULL)
-				destroy_mono_handling (mono_handling);
-			    return 1;
-			};
+		      if (do_copy_raw_mono_pixels
+			  (rst, outbuf, width, height, num_bands, x_res,
+			   y_res, minx, maxy, tile_minx, tile_maxy,
+			   tile_width, tile_height, no_data, mono_band,
+			   mono_handling))
+			  return 1;
+		      if (mono_handling != NULL)
+			  destroy_mono_handling (mono_handling);
 		  }
 	    }
       }
 
-    switch (sample_type)
-      {
-      case RL2_SAMPLE_INT8:
-	  copy_int8_raw_pixels ((const char *) (rst->rasterBuffer),
-				(const unsigned char *) (rst->maskBuffer),
-				(char *) outbuf, width, height,
-				x_res, y_res, minx, maxy, tile_minx,
-				tile_maxy, tile_width, tile_height, no_data);
-	  return 1;
-      case RL2_SAMPLE_INT16:
-	  copy_int16_raw_pixels ((const short *) (rst->rasterBuffer),
-				 (const unsigned char *) (rst->maskBuffer),
-				 (short *) outbuf, width, height,
-				 x_res, y_res, minx, maxy, tile_minx,
-				 tile_maxy, tile_width, tile_height, no_data);
-	  return 1;
-      case RL2_SAMPLE_UINT16:
-	  copy_uint16_raw_pixels ((const unsigned short *) (rst->rasterBuffer),
-				  (const unsigned char *) (rst->maskBuffer),
-				  (unsigned short *) outbuf, width, height,
-				  num_bands, x_res, y_res, minx, maxy,
-				  tile_minx, tile_maxy, tile_width,
-				  tile_height, no_data);
-	  return 1;
-      case RL2_SAMPLE_INT32:
-	  copy_int32_raw_pixels ((const int *) (rst->rasterBuffer),
-				 (const unsigned char *) (rst->maskBuffer),
-				 (int *) outbuf, width, height,
-				 x_res, y_res, minx, maxy, tile_minx,
-				 tile_maxy, tile_width, tile_height, no_data);
-	  return 1;
-      case RL2_SAMPLE_UINT32:
-	  copy_uint32_raw_pixels ((const unsigned int *) (rst->rasterBuffer),
-				  (const unsigned char *) (rst->maskBuffer),
-				  (unsigned int *) outbuf, width, height,
-				  x_res, y_res, minx, maxy,
-				  tile_minx, tile_maxy, tile_width,
-				  tile_height, no_data);
-	  return 1;
-      case RL2_SAMPLE_FLOAT:
-	  copy_float_raw_pixels ((const float *) (rst->rasterBuffer),
-				 (const unsigned char *) (rst->maskBuffer),
-				 (float *) outbuf, width, height,
-				 x_res, y_res, minx, maxy, tile_minx,
-				 tile_maxy, tile_width, tile_height, no_data);
-	  return 1;
-      case RL2_SAMPLE_DOUBLE:
-	  copy_double_raw_pixels ((const double *) (rst->rasterBuffer),
-				  (const unsigned char *) (rst->maskBuffer),
-				  (double *) outbuf, width, height,
-				  x_res, y_res, minx, maxy,
-				  tile_minx, tile_maxy, tile_width,
-				  tile_height, no_data);
-	  return 1;
-      default:
-	  copy_uint8_raw_pixels ((const unsigned char *) (rst->rasterBuffer),
-				 (const unsigned char *) (rst->maskBuffer),
-				 (unsigned char *) outbuf, width, height,
-				 num_bands, x_res, y_res, minx, maxy, tile_minx,
-				 tile_maxy, tile_width, tile_height, no_data);
-	  return 1;
-      };
+    if (do_copy_raw_pixels
+	(rst, outbuf, width, height, sample_type, num_bands, x_res, y_res,
+	 minx, maxy, tile_minx, tile_maxy, tile_width, tile_height, no_data))
+	return 1;
 
     return 0;
 }
@@ -3868,9 +4470,9 @@ get_uint8_ennuple (const unsigned char *rawbuf, unsigned short row,
 }
 
 static void
-get_int16_ennuple (const short *rawbuf, unsigned short row, unsigned short col,
-		   unsigned short row_stride, rl2PixelPtr no_data,
-		   double ennuple[], int *has_no_data)
+get_int16_ennuple (const short *rawbuf, unsigned short row,
+		   unsigned short col, unsigned short row_stride,
+		   rl2PixelPtr no_data, double ennuple[], int *has_no_data)
 {
 /* extracting a 3x3 "super-pixel" - INT16 */
     const short *p_in;
@@ -4044,9 +4646,9 @@ get_uint32_ennuple (const unsigned int *rawbuf, unsigned short row,
 }
 
 static void
-get_float_ennuple (const float *rawbuf, unsigned short row, unsigned short col,
-		   unsigned short row_stride, rl2PixelPtr no_data,
-		   double ennuple[], int *has_no_data)
+get_float_ennuple (const float *rawbuf, unsigned short row,
+		   unsigned short col, unsigned short row_stride,
+		   rl2PixelPtr no_data, double ennuple[], int *has_no_data)
 {
 /* extracting a 3x3 "super-pixel" - FLOAT */
     const float *p_in;
@@ -4218,13 +4820,148 @@ shaded_relief_value (double relief_factor, double scale_factor,
 				  azRadians, ennuple);
 }
 
+#ifdef _WIN32
+DWORD WINAPI
+doRunShadowerThread (void *arg)
+#else
+void *
+doRunShadowerThread (void *arg)
+#endif
+{
+/* threaded function: decoding a Tile */
+    float *p_out;
+    unsigned short row;
+    unsigned short col;
+    rl2AuxShadowerPtr shadower = (rl2AuxShadowerPtr) arg;
+    for (row = shadower->start_row; row < shadower->height;
+	 row += shadower->row_increment)
+      {
+	  p_out = shadower->sr_mask + (row * shadower->width);
+	  for (col = 0; col < shadower->width; col++)
+	      *p_out++ =
+		  shaded_relief_value (shadower->relief_factor,
+				       shadower->scale_factor,
+				       shadower->altRadians,
+				       shadower->azRadians, shadower->rawbuf,
+				       row, col, shadower->row_stride,
+				       shadower->sample_type,
+				       (rl2PixelPtr) (shadower->no_data));
+      }
+#ifdef _WIN32
+    return 0;
+#else
+    pthread_exit (NULL);
+#endif
+}
+
+static void
+start_shadower_thread (rl2AuxShadowerPtr shadower)
+{
+/* starting a concurrent thread */
+#ifdef _WIN32
+    HANDLE thread_handle;
+    HANDLE *p_thread;
+    DWORD dwThreadId;
+    thread_handle =
+	CreateThread (NULL, 0, doRunShadowerThread, shadower, 0, &dwThreadId);
+    SetThreadPriority (thread_handle, THREAD_PRIORITY_IDLE);
+    p_thread = malloc (sizeof (HANDLE));
+    *p_thread = thread_handle;
+    shadower->opaque_thread_id = p_thread;
+#else
+    pthread_t thread_id;
+    pthread_t *p_thread;
+    int ok_prior = 0;
+    int policy;
+    int min_prio;
+    pthread_attr_t attr;
+    struct sched_param sp;
+    pthread_attr_init (&attr);
+    if (pthread_attr_setschedpolicy (&attr, SCHED_RR) == 0)
+      {
+	  /* attempting to set the lowest priority */
+	  if (pthread_attr_getschedpolicy (&attr, &policy) == 0)
+	    {
+		min_prio = sched_get_priority_min (policy);
+		sp.sched_priority = min_prio;
+		if (pthread_attr_setschedparam (&attr, &sp) == 0)
+		  {
+		      /* ok, setting the lowest priority */
+		      ok_prior = 1;
+		      pthread_create (&thread_id, &attr, doRunShadowerThread,
+				      shadower);
+		  }
+	    }
+      }
+    if (!ok_prior)
+      {
+	  /* failure: using standard priority */
+	  pthread_create (&thread_id, NULL, doRunShadowerThread, shadower);
+      }
+    p_thread = malloc (sizeof (pthread_t));
+    *p_thread = thread_id;
+    shadower->opaque_thread_id = p_thread;
+#endif
+}
+
+static void
+do_run_concurrent_shadower (rl2AuxShadowerPtr aux, int max_threads)
+{
+/* concurrent execution of all shadower children threads */
+    rl2AuxShadowerPtr shadower;
+    int i;
+#ifdef _WIN32
+    HANDLE *handles;
+#endif
+
+    for (i = 0; i < max_threads; i++)
+      {
+	  /* starting all children threads */
+	  shadower = aux + i;
+	  start_shadower_thread (shadower);
+      }
+
+/* waiting until all child threads exit */
+#ifdef _WIN32
+    handles = malloc (sizeof (HANDLE) * max_threads);
+    for (i = 0; i < max_threads; i++)
+      {
+	  /* initializing the HANDLEs array */
+	  HANDLE *pOpaque;
+	  shadower = aux + i;
+	  pOpaque = (HANDLE *) (shadower->opaque_thread_id);
+	  *(handles + i) = *pOpaque;
+      }
+    WaitForMultipleObjects (max_threads, handles, TRUE, INFINITE);
+    free (handles);
+#else
+    for (i = 0; i < max_threads; i++)
+      {
+	  pthread_t *pOpaque;
+	  shadower = aux + i;
+	  pOpaque = (pthread_t *) (shadower->opaque_thread_id);
+	  pthread_join (*pOpaque, NULL);
+      }
+#endif
+
+/* all children threads have now finished: resuming the main thread */
+    for (i = 0; i < max_threads; i++)
+      {
+	  /* cleaning up a request slot */
+	  if (shadower->opaque_thread_id != NULL)
+	      free (shadower->opaque_thread_id);
+	  shadower->opaque_thread_id = NULL;
+      }
+}
+
 RL2_PRIVATE int
-rl2_build_shaded_relief_mask (sqlite3 * handle, rl2CoveragePtr cvg,
-			      double relief_factor, double scale_factor,
-			      unsigned int width, unsigned int height,
-			      double minx, double miny, double maxx,
-			      double maxy, double x_res, double y_res,
-			      float **shaded_relief, int *shaded_relief_sz)
+rl2_build_shaded_relief_mask (sqlite3 * handle, int max_threads,
+			      rl2CoveragePtr cvg, double relief_factor,
+			      double scale_factor, unsigned int width,
+			      unsigned int height, double minx, double miny,
+			      double maxx, double maxy, double x_res,
+			      double y_res, float **shaded_relief,
+			      int *shaded_relief_sz)
 {
 /* attempting to return a Shaded Relief mask from the DBMS Coverage */
     rl2PixelPtr no_data = NULL;
@@ -4263,7 +5000,7 @@ rl2_build_shaded_relief_mask (sqlite3 * handle, rl2CoveragePtr cvg,
     if (coverage == NULL)
 	goto error;
     if (rl2_find_matching_resolution
-	(handle, cvg, &xx_res, &yy_res, &level, &scale) != RL2_OK)
+	(handle, cvg, 0, 0, &xx_res, &yy_res, &level, &scale) != RL2_OK)
 	goto error;
     if (rl2_get_coverage_type (cvg, &sample_type, &pixel_type, &num_bands) !=
 	RL2_OK)
@@ -4276,14 +5013,13 @@ rl2_build_shaded_relief_mask (sqlite3 * handle, rl2CoveragePtr cvg,
 
 /* preparing the "tiles" SQL query */
     xtiles = sqlite3_mprintf ("%s_tiles", coverage);
-    xxtiles = gaiaDoubleQuotedSql (xtiles);
+    xxtiles = rl2_double_quoted_sql (xtiles);
     sql =
-	sqlite3_mprintf ("SELECT tile_id, MbrMinX(geometry), MbrMaxY(geometry) "
-			 "FROM \"%s\" "
-			 "WHERE pyramid_level = ? AND ROWID IN ( "
-			 "SELECT ROWID FROM SpatialIndex WHERE f_table_name = %Q "
-			 "AND search_frame = BuildMBR(?, ?, ?, ?))", xxtiles,
-			 xtiles);
+	sqlite3_mprintf
+	("SELECT tile_id, MbrMinX(geometry), MbrMaxY(geometry) "
+	 "FROM \"%s\" " "WHERE pyramid_level = ? AND ROWID IN ( "
+	 "SELECT ROWID FROM SpatialIndex WHERE f_table_name = %Q "
+	 "AND search_frame = BuildMBR(?, ?, ?, ?))", xxtiles, xtiles);
     sqlite3_free (xtiles);
     free (xxtiles);
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt_tiles, NULL);
@@ -4299,7 +5035,7 @@ rl2_build_shaded_relief_mask (sqlite3 * handle, rl2CoveragePtr cvg,
       {
 	  /* preparing the data SQL query - both ODD and EVEN */
 	  xdata = sqlite3_mprintf ("%s_tile_data", coverage);
-	  xxdata = gaiaDoubleQuotedSql (xdata);
+	  xxdata = rl2_double_quoted_sql (xdata);
 	  sqlite3_free (xdata);
 	  sql = sqlite3_mprintf ("SELECT tile_data_odd, tile_data_even "
 				 "FROM \"%s\" WHERE tile_id = ?", xxdata);
@@ -4318,7 +5054,7 @@ rl2_build_shaded_relief_mask (sqlite3 * handle, rl2CoveragePtr cvg,
       {
 	  /* preparing the data SQL query - only ODD */
 	  xdata = sqlite3_mprintf ("%s_tile_data", coverage);
-	  xxdata = gaiaDoubleQuotedSql (xdata);
+	  xxdata = rl2_double_quoted_sql (xdata);
 	  sqlite3_free (xdata);
 	  sql = sqlite3_mprintf ("SELECT tile_data_odd "
 				 "FROM \"%s\" WHERE tile_id = ?", xxdata);
@@ -4360,16 +5096,22 @@ rl2_build_shaded_relief_mask (sqlite3 * handle, rl2CoveragePtr cvg,
 	  goto error;
       }
     void_raw_buffer (rawbuf, width + 2, height + 2, sample_type, 1, no_data);
-    if (!load_dbms_tiles
-	(handle, stmt_tiles, stmt_data, rawbuf, width + 2, height + 2,
-	 sample_type, 1, xx_res, yy_res, minx - xx_res, miny - yy_res,
-	 maxx + xx_res, maxy + yy_res, level, scale, NULL, no_data, NULL, NULL))
+    if (!rl2_load_dbms_tiles
+	(handle, max_threads, stmt_tiles, stmt_data, rawbuf, width + 2,
+	 height + 2, sample_type, 1, 0, 0, 0, xx_res, yy_res, minx - xx_res,
+	 miny - yy_res, maxx + xx_res, maxy + yy_res, level, scale, NULL,
+	 no_data, NULL, NULL))
 	goto error;
     sqlite3_finalize (stmt_tiles);
     sqlite3_finalize (stmt_data);
     stmt_tiles = NULL;
     stmt_data = NULL;
 
+    if (max_threads < 1)
+	max_threads = 1;
+    if (max_threads > 64)
+	max_threads = 64;
+
 /* preparing the Shaded Relief mask */
     sr_mask_size = sizeof (float) * width * height;
     sr_mask = malloc (sr_mask_size);
@@ -4379,14 +5121,50 @@ rl2_build_shaded_relief_mask (sqlite3 * handle, rl2CoveragePtr cvg,
 		   "rl2_build_shaded_relief_mask: Insufficient Memory !!!\n");
 	  goto error;
       }
-    p_out = sr_mask;
-    for (row = 0; row < height; row++)
+    if (max_threads == 1)
       {
-	  for (col = 0; col < width; col++)
-	      *p_out++ =
-		  shaded_relief_value (relief_factor, scale_factor, altRadians,
-				       azRadians, rawbuf, row, col, row_stride,
-				       sample_type, no_data);
+	  /* executing in a single thread */
+	  p_out = sr_mask;
+	  for (row = 0; row < height; row++)
+	    {
+		for (col = 0; col < width; col++)
+		    *p_out++ =
+			shaded_relief_value (relief_factor, scale_factor,
+					     altRadians, azRadians, rawbuf,
+					     row, col, row_stride,
+					     sample_type, no_data);
+	    }
+      }
+    else
+      {
+	  /* executing as many concurrent threads */
+	  rl2AuxShadowerPtr aux = NULL;
+	  rl2AuxShadowerPtr shadower;
+	  int iaux;
+	  aux = malloc (sizeof (rl2AuxShadower) * max_threads);
+	  if (aux == NULL)
+	      return 0;
+	  for (iaux = 0; iaux < max_threads; iaux++)
+	    {
+		/* initializing an empty AuxShadower slot */
+		shadower = aux + iaux;
+		shadower->opaque_thread_id = NULL;
+		shadower->width = width;
+		shadower->height = height;
+		shadower->relief_factor = relief_factor;
+		shadower->scale_factor = scale_factor;
+		shadower->altRadians = altRadians;
+		shadower->azRadians = azRadians;
+		shadower->rawbuf = rawbuf;
+		shadower->start_row = iaux;
+		shadower->row_increment = max_threads;
+		shadower->row_stride = row_stride;
+		shadower->sample_type = sample_type;
+		shadower->no_data = (rl2PrivPixelPtr) no_data;
+		shadower->sr_mask = sr_mask;
+	    }
+	  do_run_concurrent_shadower (aux, max_threads);
+	  free (aux);
       }
 
     free (rawbuf);
diff --git a/src/rl2raw.c b/src/rl2raw.c
index d5f5ce7..70bccd0 100644
--- a/src/rl2raw.c
+++ b/src/rl2raw.c
@@ -20,7 +20,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -53,6 +53,7 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #endif
 
 #include "rasterlite2/rasterlite2.h"
+#include "rasterlite2/rl2tiff.h"
 #include "rasterlite2_private.h"
 
 static int
@@ -370,8 +371,8 @@ rl2_raster_data_to_RGBA (rl2RasterPtr ptr, unsigned char **buffer,
 				  &transpR, &transpG, &transpB);
 		break;
 	    case RL2_PIXEL_RGB:
-		rl2_get_pixel_sample_uint8 ((rl2PixelPtr) no_data, RL2_RED_BAND,
-					    &transpR);
+		rl2_get_pixel_sample_uint8 ((rl2PixelPtr) no_data,
+					    RL2_RED_BAND, &transpR);
 		rl2_get_pixel_sample_uint8 ((rl2PixelPtr) no_data,
 					    RL2_GREEN_BAND, &transpG);
 		rl2_get_pixel_sample_uint8 ((rl2PixelPtr) no_data,
@@ -456,8 +457,13 @@ rl2_raster_data_to_RGBA (rl2RasterPtr ptr, unsigned char **buffer,
 		      a = 255;
 		      if (p_mask != NULL)
 			{
-			    if (*p_mask++ == 0)
-				a = 0;
+			    if (rst->alpha_mask)
+				a = *p_mask++;
+			    else
+			      {
+				  if (*p_mask++ == 0)
+				      a = 0;
+			      }
 			}
 		      if (rst->noData != NULL)
 			{
@@ -478,8 +484,13 @@ rl2_raster_data_to_RGBA (rl2RasterPtr ptr, unsigned char **buffer,
 		      a = 255;
 		      if (p_mask != NULL)
 			{
-			    if (*p_mask++ == 0)
-				a = 0;
+			    if (rst->alpha_mask)
+				a = *p_mask++;
+			    else
+			      {
+				  if (*p_mask++ == 0)
+				      a = 0;
+			      }
 			}
 		      if (rst->noData != NULL)
 			{
@@ -594,8 +605,8 @@ rl2_raster_data_to_ARGB (rl2RasterPtr ptr, unsigned char **buffer,
 				  &transpR, &transpG, &transpB);
 		break;
 	    case RL2_PIXEL_RGB:
-		rl2_get_pixel_sample_uint8 ((rl2PixelPtr) no_data, RL2_RED_BAND,
-					    &transpR);
+		rl2_get_pixel_sample_uint8 ((rl2PixelPtr) no_data,
+					    RL2_RED_BAND, &transpR);
 		rl2_get_pixel_sample_uint8 ((rl2PixelPtr) no_data,
 					    RL2_GREEN_BAND, &transpG);
 		rl2_get_pixel_sample_uint8 ((rl2PixelPtr) no_data,
@@ -607,6 +618,7 @@ rl2_raster_data_to_ARGB (rl2RasterPtr ptr, unsigned char **buffer,
     p_in = rst->rasterBuffer;
     p_mask = rst->maskBuffer;
     p_out = buf;
+    p_alpha = NULL;
     for (row = 0; row < rst->height; row++)
       {
 	  for (col = 0; col < rst->width; col++)
@@ -673,7 +685,8 @@ rl2_raster_data_to_ARGB (rl2RasterPtr ptr, unsigned char **buffer,
 				(r, g, b, transpR, transpG, transpB))
 				a = 0;
 			}
-		      *p_alpha = a;
+		      if (p_alpha != NULL)
+			  *p_alpha = a;
 		  }
 	    }
       }
@@ -880,8 +893,8 @@ rl2_raster_data_to_BGRA (rl2RasterPtr ptr, unsigned char **buffer,
 				  &transpR, &transpG, &transpB);
 		break;
 	    case RL2_PIXEL_RGB:
-		rl2_get_pixel_sample_uint8 ((rl2PixelPtr) no_data, RL2_RED_BAND,
-					    &transpR);
+		rl2_get_pixel_sample_uint8 ((rl2PixelPtr) no_data,
+					    RL2_RED_BAND, &transpR);
 		rl2_get_pixel_sample_uint8 ((rl2PixelPtr) no_data,
 					    RL2_GREEN_BAND, &transpG);
 		rl2_get_pixel_sample_uint8 ((rl2PixelPtr) no_data,
@@ -1497,8 +1510,8 @@ rl2_raster_band_to_uint8 (rl2RasterPtr ptr, int band, unsigned char **buffer,
 }
 
 RL2_DECLARE int
-rl2_raster_band_to_uint16 (rl2RasterPtr ptr, int band, unsigned short **buffer,
-			   int *buf_size)
+rl2_raster_band_to_uint16 (rl2RasterPtr ptr, int band,
+			   unsigned short **buffer, int *buf_size)
 {
 /* attempting to export Raster BAND data as a UINT-16 array */
     unsigned short *buf;
@@ -1579,9 +1592,9 @@ rl2_raster_bands_to_RGB (rl2RasterPtr ptr, int bandR, int bandG, int bandB,
       {
 	  for (col = 0; col < rst->width; col++)
 	    {
-		unsigned char red;
-		unsigned char green;
-		unsigned char blue;
+		unsigned char red = 0;
+		unsigned char green = 0;
+		unsigned char blue = 0;
 		for (nBand = 0; nBand < rst->nBands; nBand++)
 		  {
 		      if (nBand == bandR)
@@ -1602,3 +1615,1091 @@ rl2_raster_bands_to_RGB (rl2RasterPtr ptr, int bandR, int bandG, int bandB,
     *buf_size = sz;
     return RL2_OK;
 }
+
+static int
+big_endian_cpu ()
+{
+/* checking if the target CPU is big-endian */
+    union cvt
+    {
+	unsigned char byte[4];
+	int int_value;
+    } convert;
+    convert.int_value = 1;
+    if (convert.byte[0] == 0)
+	return 1;
+    return 0;
+}
+
+static short
+swap_i16 (short value)
+{
+/* inverting the endianness - INT16 */
+    union cvt
+    {
+	unsigned char byte[2];
+	short value;
+    };
+    union cvt in;
+    union cvt out;
+    in.value = value;
+    out.byte[0] = in.byte[1];
+    out.byte[1] = in.byte[0];
+    return out.value;
+}
+
+static unsigned short
+swap_u16 (unsigned short value)
+{
+/* inverting the endianness - UINT16 */
+    union cvt
+    {
+	unsigned char byte[2];
+	unsigned short value;
+    };
+    union cvt in;
+    union cvt out;
+    in.value = value;
+    out.byte[0] = in.byte[1];
+    out.byte[1] = in.byte[0];
+    return out.value;
+}
+
+static int
+swap_i32 (int value)
+{
+/* inverting the endianness - INT32 */
+    union cvt
+    {
+	unsigned char byte[4];
+	int value;
+    };
+    union cvt in;
+    union cvt out;
+    in.value = value;
+    out.byte[0] = in.byte[3];
+    out.byte[1] = in.byte[2];
+    out.byte[2] = in.byte[1];
+    out.byte[3] = in.byte[0];
+    return out.value;
+}
+
+static unsigned int
+swap_u32 (unsigned int value)
+{
+/* inverting the endianness - UINT32 */
+    union cvt
+    {
+	unsigned char byte[4];
+	unsigned int value;
+    };
+    union cvt in;
+    union cvt out;
+    in.value = value;
+    out.byte[0] = in.byte[3];
+    out.byte[1] = in.byte[2];
+    out.byte[2] = in.byte[1];
+    out.byte[3] = in.byte[0];
+    return out.value;
+}
+
+static float
+swap_flt (float value)
+{
+/* inverting the endianness - FLOAT */
+    union cvt
+    {
+	unsigned char byte[4];
+	float value;
+    };
+    union cvt in;
+    union cvt out;
+    in.value = value;
+    out.byte[0] = in.byte[3];
+    out.byte[1] = in.byte[2];
+    out.byte[2] = in.byte[1];
+    out.byte[3] = in.byte[0];
+    return out.value;
+}
+
+static double
+swap_dbl (double value)
+{
+/* inverting the endianness - DOUBLE */
+    union cvt
+    {
+	unsigned char byte[8];
+	double value;
+    };
+    union cvt in;
+    union cvt out;
+    in.value = value;
+    out.byte[0] = in.byte[7];
+    out.byte[1] = in.byte[6];
+    out.byte[2] = in.byte[5];
+    out.byte[3] = in.byte[4];
+    out.byte[4] = in.byte[3];
+    out.byte[5] = in.byte[2];
+    out.byte[6] = in.byte[1];
+    out.byte[7] = in.byte[0];
+    return out.value;
+}
+
+static void
+copy_endian_raw_i8 (char *outbuf, const char *pixels, unsigned int width,
+		    unsigned int height, unsigned char num_bands)
+{
+/* signed int8 */
+    unsigned int x;
+    unsigned int y;
+    unsigned char b;
+    const char *p_in = pixels;
+    char *p_out = outbuf;
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		for (b = 0; b < num_bands; b++)
+		    *p_out++ = *p_in++;
+	    }
+      }
+}
+
+static void
+copy_endian_raw_u8 (unsigned char *outbuf, const unsigned char *pixels,
+		    unsigned int width, unsigned int height,
+		    unsigned char num_bands)
+{
+/* unsigned int8 */
+    unsigned int x;
+    unsigned int y;
+    unsigned char b;
+    const unsigned char *p_in = pixels;
+    unsigned char *p_out = outbuf;
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		for (b = 0; b < num_bands; b++)
+		    *p_out++ = *p_in++;
+	    }
+      }
+}
+
+static void
+copy_endian_raw_i16 (short *outbuf, const short *pixels, unsigned int width,
+		     unsigned int height, unsigned char num_bands,
+		     int big_endian)
+{
+/* signed int16 */
+    int swap = 1;
+    unsigned int x;
+    unsigned int y;
+    unsigned char b;
+    const short *p_in = pixels;
+    short *p_out = outbuf;
+    if (big_endian_cpu () && big_endian)
+	swap = 0;
+    if (!big_endian_cpu () && !big_endian)
+	swap = 0;
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		for (b = 0; b < num_bands; b++)
+		  {
+		      if (swap)
+			  *p_out++ = swap_i16 (*p_in++);
+		      else
+			  *p_out++ = *p_in++;
+		  }
+	    }
+      }
+}
+
+static void
+copy_endian_raw_u16 (unsigned short *outbuf, const unsigned short *pixels,
+		     unsigned int width, unsigned int height,
+		     unsigned char num_bands, int big_endian)
+{
+/* unsigned int16 */
+    int swap = 1;
+    unsigned int x;
+    unsigned int y;
+    unsigned char b;
+    const unsigned short *p_in = pixels;
+    unsigned short *p_out = outbuf;
+    if (big_endian_cpu () && big_endian)
+	swap = 0;
+    if (!big_endian_cpu () && !big_endian)
+	swap = 0;
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		for (b = 0; b < num_bands; b++)
+		  {
+		      if (swap)
+			  *p_out++ = swap_u16 (*p_in++);
+		      else
+			  *p_out++ = *p_in++;
+		  }
+	    }
+      }
+}
+
+static void
+copy_endian_raw_i32 (int *outbuf, const int *pixels, unsigned int width,
+		     unsigned int height, unsigned char num_bands,
+		     int big_endian)
+{
+/* signed int32 */
+    int swap = 1;
+    unsigned int x;
+    unsigned int y;
+    unsigned char b;
+    const int *p_in = pixels;
+    int *p_out = outbuf;
+    if (big_endian_cpu () && big_endian)
+	swap = 0;
+    if (!big_endian_cpu () && !big_endian)
+	swap = 0;
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		for (b = 0; b < num_bands; b++)
+		  {
+		      if (swap)
+			  *p_out++ = swap_i32 (*p_in++);
+		      else
+			  *p_out++ = *p_in++;
+		  }
+	    }
+      }
+}
+
+static void
+copy_endian_raw_u32 (unsigned int *outbuf, const unsigned int *pixels,
+		     unsigned int width, unsigned int height,
+		     unsigned char num_bands, int big_endian)
+{
+/* unsigned int32 */
+    int swap = 1;
+    unsigned int x;
+    unsigned int y;
+    unsigned char b;
+    const unsigned int *p_in = pixels;
+    unsigned int *p_out = outbuf;
+    if (big_endian_cpu () && big_endian)
+	swap = 0;
+    if (!big_endian_cpu () && !big_endian)
+	swap = 0;
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		for (b = 0; b < num_bands; b++)
+		  {
+		      if (swap)
+			  *p_out++ = swap_u32 (*p_in++);
+		      else
+			  *p_out++ = *p_in++;
+		  }
+	    }
+      }
+}
+
+static void
+copy_endian_raw_flt (float *outbuf, const float *pixels, unsigned int width,
+		     unsigned int height, unsigned char num_bands,
+		     int big_endian)
+{
+/* float */
+    int swap = 1;
+    unsigned int x;
+    unsigned int y;
+    unsigned char b;
+    const float *p_in = pixels;
+    float *p_out = outbuf;
+    if (big_endian_cpu () && big_endian)
+	swap = 0;
+    if (!big_endian_cpu () && !big_endian)
+	swap = 0;
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		for (b = 0; b < num_bands; b++)
+		  {
+		      if (swap)
+			  *p_out++ = swap_flt (*p_in++);
+		      else
+			  *p_out++ = *p_in++;
+		  }
+	    }
+      }
+}
+
+static void
+copy_endian_raw_dbl (double *outbuf, const double *pixels, unsigned int width,
+		     unsigned int height, unsigned char num_bands,
+		     int big_endian)
+{
+/* double */
+    int swap = 1;
+    unsigned int x;
+    unsigned int y;
+    unsigned char b;
+    const double *p_in = pixels;
+    double *p_out = outbuf;
+    if (big_endian_cpu () && big_endian)
+	swap = 0;
+    if (!big_endian_cpu () && !big_endian)
+	swap = 0;
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		for (b = 0; b < num_bands; b++)
+		  {
+		      if (swap)
+			  *p_out++ = swap_dbl (*p_in++);
+		      else
+			  *p_out++ = *p_in++;
+		  }
+	    }
+      }
+}
+
+RL2_PRIVATE unsigned char *
+rl2_copy_endian_raw_pixels (const unsigned char *pixels, int pixels_sz,
+			    unsigned int width, unsigned int height,
+			    unsigned char sample_type,
+			    unsigned char num_bands, int big_endian)
+{
+/* copying RAW pixels (in endian safe mode) */
+    int sample_bytes = 0;
+    int outsize = width * height * num_bands;
+    unsigned char *outbuf = NULL;
+
+    switch (sample_type)
+      {
+      case RL2_SAMPLE_1_BIT:
+      case RL2_SAMPLE_2_BIT:
+      case RL2_SAMPLE_4_BIT:
+      case RL2_SAMPLE_INT8:
+      case RL2_SAMPLE_UINT8:
+	  sample_bytes = 1;
+	  break;
+      case RL2_SAMPLE_INT16:
+      case RL2_SAMPLE_UINT16:
+	  sample_bytes = 2;
+	  break;
+      case RL2_SAMPLE_INT32:
+      case RL2_SAMPLE_UINT32:
+      case RL2_SAMPLE_FLOAT:
+	  sample_bytes = 4;
+	  break;
+      case RL2_SAMPLE_DOUBLE:
+	  sample_bytes = 8;
+	  break;
+      };
+    outsize *= sample_bytes;
+    if (pixels_sz != outsize)
+	return NULL;
+
+/* allocating the output buffer */
+    outbuf = malloc (outsize);
+    if (outbuf == NULL)
+	return NULL;
+    switch (sample_type)
+      {
+      case RL2_SAMPLE_1_BIT:
+      case RL2_SAMPLE_2_BIT:
+      case RL2_SAMPLE_4_BIT:
+      case RL2_SAMPLE_UINT8:
+	  copy_endian_raw_u8 (outbuf, pixels, width, height, num_bands);
+	  break;
+      case RL2_SAMPLE_INT8:
+	  copy_endian_raw_i8 ((char *) outbuf, (const char *) pixels, width,
+			      height, num_bands);
+	  break;
+      case RL2_SAMPLE_INT16:
+	  copy_endian_raw_i16 ((short *) outbuf, (const short *) pixels,
+			       width, height, num_bands, big_endian);
+	  break;
+      case RL2_SAMPLE_UINT16:
+	  copy_endian_raw_u16 ((unsigned short *) outbuf,
+			       (const unsigned short *) pixels, width, height,
+			       num_bands, big_endian);
+	  break;
+      case RL2_SAMPLE_INT32:
+	  copy_endian_raw_i32 ((int *) outbuf, (const int *) pixels, width,
+			       height, num_bands, big_endian);
+	  break;
+      case RL2_SAMPLE_UINT32:
+	  copy_endian_raw_u32 ((unsigned int *) outbuf,
+			       (const unsigned int *) pixels, width, height,
+			       num_bands, big_endian);
+	  break;
+      case RL2_SAMPLE_FLOAT:
+	  copy_endian_raw_flt ((float *) outbuf, (const float *) pixels,
+			       width, height, num_bands, big_endian);
+	  break;
+      case RL2_SAMPLE_DOUBLE:
+	  copy_endian_raw_dbl ((double *) outbuf, (const double *) pixels,
+			       width, height, num_bands, big_endian);
+	  break;
+      };
+    return outbuf;
+}
+
+static int
+eval_raw_pixels_compatibility (rl2PrivCoveragePtr coverage,
+			       rl2PrivRasterPtr raster)
+{
+/* checking for strict compatibility */
+    if (coverage->sampleType == raster->sampleType
+	&& coverage->pixelType == raster->pixelType
+	&& coverage->nBands == raster->nBands)
+	return 1;
+    fprintf (stderr, "Mismatching RAW pixels !!!\n");
+    return 0;
+}
+
+static void
+copy_tile_raw_i8 (const char *in, unsigned int in_width,
+		  unsigned int in_height, unsigned int startRow,
+		  unsigned int startCol, char *out, unsigned int tileWidth,
+		  unsigned int tileHeight, unsigned char num_bands)
+{
+/* signed int8 */
+    unsigned int x;
+    unsigned int y;
+    unsigned char b;
+    for (y = 0; y < tileHeight; y++)
+      {
+	  const char *p_in;
+	  if ((startRow + y) >= in_height)
+	      break;
+	  p_in =
+	      in + ((startRow + y) * in_width * num_bands) +
+	      (startCol * num_bands);
+	  for (x = 0; x < tileWidth; x++)
+	    {
+		char *p_out;
+		if ((startCol + x) >= in_width)
+		    break;
+		p_out = out + (y * tileWidth * num_bands) + (x * num_bands);
+		for (b = 0; b < num_bands; b++)
+		    *p_out++ = *p_in++;
+	    }
+      }
+}
+
+static void
+copy_tile_raw_u8 (const unsigned char *in, unsigned int in_width,
+		  unsigned int in_height, unsigned int startRow,
+		  unsigned int startCol, unsigned char *out,
+		  unsigned int tileWidth, unsigned int tileHeight,
+		  unsigned char num_bands)
+{
+/* unsigned int8 */
+    unsigned int x;
+    unsigned int y;
+    unsigned char b;
+    for (y = 0; y < tileHeight; y++)
+      {
+	  const unsigned char *p_in;
+	  if ((startRow + y) >= in_height)
+	      break;
+	  p_in =
+	      in + ((startRow + y) * in_width * num_bands) +
+	      (startCol * num_bands);
+	  for (x = 0; x < tileWidth; x++)
+	    {
+		unsigned char *p_out;
+		if ((startCol + x) >= in_width)
+		    break;
+		p_out = out + (y * tileWidth * num_bands) + (x * num_bands);
+		for (b = 0; b < num_bands; b++)
+		    *p_out++ = *p_in++;
+	    }
+      }
+}
+
+static void
+copy_tile_raw_i16 (const short *in, unsigned int in_width,
+		   unsigned int in_height, unsigned int startRow,
+		   unsigned int startCol, short *out, unsigned int tileWidth,
+		   unsigned int tileHeight, unsigned char num_bands)
+{
+/* signed int16 */
+    unsigned int x;
+    unsigned int y;
+    unsigned char b;
+    for (y = 0; y < tileHeight; y++)
+      {
+	  const short *p_in;
+	  if ((startRow + y) >= in_height)
+	      break;
+	  p_in =
+	      in + ((startRow + y) * in_width * num_bands) +
+	      (startCol * num_bands);
+	  for (x = 0; x < tileWidth; x++)
+	    {
+		short *p_out;
+		if ((startCol + x) >= in_width)
+		    break;
+		p_out = out + (y * tileWidth * num_bands) + (x * num_bands);
+		for (b = 0; b < num_bands; b++)
+		    *p_out++ = *p_in++;
+	    }
+      }
+}
+
+static void
+copy_tile_raw_u16 (const unsigned short *in, unsigned int in_width,
+		   unsigned int in_height, unsigned int startRow,
+		   unsigned int startCol, unsigned short *out,
+		   unsigned int tileWidth, unsigned int tileHeight,
+		   unsigned char num_bands)
+{
+/* unsigned int16 */
+    unsigned int x;
+    unsigned int y;
+    unsigned char b;
+    for (y = 0; y < tileHeight; y++)
+      {
+	  const unsigned short *p_in;
+	  if ((startRow + y) >= in_height)
+	      break;
+	  p_in =
+	      in + ((startRow + y) * in_width * num_bands) +
+	      (startCol * num_bands);
+	  for (x = 0; x < tileWidth; x++)
+	    {
+		unsigned short *p_out;
+		if ((startCol + x) >= in_width)
+		    break;
+		p_out = out + (y * tileWidth * num_bands) + (x * num_bands);
+		for (b = 0; b < num_bands; b++)
+		    *p_out++ = *p_in++;
+	    }
+      }
+}
+
+static void
+copy_tile_raw_i32 (const int *in, unsigned int in_width,
+		   unsigned int in_height, unsigned int startRow,
+		   unsigned int startCol, int *out, unsigned int tileWidth,
+		   unsigned int tileHeight, unsigned char num_bands)
+{
+/* signed int32 */
+    unsigned int x;
+    unsigned int y;
+    unsigned char b;
+    for (y = 0; y < tileHeight; y++)
+      {
+	  const int *p_in;
+	  if ((startRow + y) >= in_height)
+	      break;
+	  p_in =
+	      in + ((startRow + y) * in_width * num_bands) +
+	      (startCol * num_bands);
+	  for (x = 0; x < tileWidth; x++)
+	    {
+		int *p_out;
+		if ((startCol + x) >= in_width)
+		    break;
+		p_out = out + (y * tileWidth * num_bands) + (x * num_bands);
+		for (b = 0; b < num_bands; b++)
+		    *p_out++ = *p_in++;
+	    }
+      }
+}
+
+static void
+copy_tile_raw_u32 (const unsigned int *in, unsigned int in_width,
+		   unsigned int in_height, unsigned int startRow,
+		   unsigned int startCol, unsigned int *out,
+		   unsigned int tileWidth, unsigned int tileHeight,
+		   unsigned char num_bands)
+{
+/* unsigned int16 */
+    unsigned int x;
+    unsigned int y;
+    unsigned char b;
+    for (y = 0; y < tileHeight; y++)
+      {
+	  const unsigned int *p_in;
+	  if ((startRow + y) >= in_height)
+	      break;
+	  p_in =
+	      in + ((startRow + y) * in_width * num_bands) +
+	      (startCol * num_bands);
+	  for (x = 0; x < tileWidth; x++)
+	    {
+		unsigned int *p_out;
+		if ((startCol + x) >= in_width)
+		    break;
+		p_out = out + (y * tileWidth * num_bands) + (x * num_bands);
+		for (b = 0; b < num_bands; b++)
+		    *p_out++ = *p_in++;
+	    }
+      }
+}
+
+static void
+copy_tile_raw_flt (const float *in, unsigned int in_width,
+		   unsigned int in_height, unsigned int startRow,
+		   unsigned int startCol, float *out, unsigned int tileWidth,
+		   unsigned int tileHeight, unsigned char num_bands)
+{
+/* FLOAT */
+    unsigned int x;
+    unsigned int y;
+    unsigned char b;
+    for (y = 0; y < tileHeight; y++)
+      {
+	  const float *p_in;
+	  if ((startRow + y) >= in_height)
+	      break;
+	  p_in =
+	      in + ((startRow + y) * in_width * num_bands) +
+	      (startCol * num_bands);
+	  for (x = 0; x < tileWidth; x++)
+	    {
+		float *p_out;
+		if ((startCol + x) >= in_width)
+		    break;
+		p_out = out + (y * tileWidth * num_bands) + (x * num_bands);
+		for (b = 0; b < num_bands; b++)
+		    *p_out++ = *p_in++;
+	    }
+      }
+}
+
+static void
+copy_tile_raw_dbl (const double *in, unsigned int in_width,
+		   unsigned int in_height, unsigned int startRow,
+		   unsigned int startCol, double *out, unsigned int tileWidth,
+		   unsigned int tileHeight, unsigned char num_bands)
+{
+/* DOUBLE */
+    unsigned int x;
+    unsigned int y;
+    unsigned char b;
+    for (y = 0; y < tileHeight; y++)
+      {
+	  const double *p_in;
+	  if ((startRow + y) >= in_height)
+	      break;
+	  p_in =
+	      in + ((startRow + y) * in_width * num_bands) +
+	      (startCol * num_bands);
+	  for (x = 0; x < tileWidth; x++)
+	    {
+		double *p_out;
+		if ((startCol + x) >= in_width)
+		    break;
+		p_out = out + (y * tileWidth * num_bands) + (x * num_bands);
+		for (b = 0; b < num_bands; b++)
+		    *p_out++ = *p_in++;
+	    }
+      }
+}
+
+static int
+build_tile_from_raw_pixels (rl2PrivRasterPtr origin, unsigned int tileWidth,
+			    unsigned int tileHeight,
+			    unsigned char sample_type,
+			    unsigned char num_bands, unsigned int startRow,
+			    unsigned int startCol, rl2PixelPtr no_data,
+			    unsigned char **pixels, int *pixels_sz)
+{
+/* extracting a Tile from the RAW buffer */
+    unsigned char *out;
+    int outsz = tileWidth * tileHeight * num_bands;
+    unsigned char sample_sz = 1;
+    switch (sample_type)
+      {
+      case RL2_SAMPLE_INT16:
+      case RL2_SAMPLE_UINT16:
+	  sample_sz = 2;
+	  break;
+      case RL2_SAMPLE_INT32:
+      case RL2_SAMPLE_UINT32:
+      case RL2_SAMPLE_FLOAT:
+	  sample_sz = 4;
+	  break;
+      case RL2_SAMPLE_DOUBLE:
+	  sample_sz = 8;
+	  break;
+      };
+    outsz *= sample_sz;
+    out = malloc (outsz);
+    if (out == NULL)
+	return 0;
+
+    rl2_prime_void_tile (out, tileWidth, tileHeight, sample_type, num_bands,
+			 no_data);
+    switch (sample_type)
+      {
+      case RL2_SAMPLE_INT8:
+	  copy_tile_raw_i8 ((const char *) (origin->rasterBuffer),
+			    origin->width, origin->height, startRow, startCol,
+			    (char *) out, tileWidth, tileHeight, num_bands);
+	  break;
+      case RL2_SAMPLE_INT16:
+	  copy_tile_raw_i16 ((const short *) (origin->rasterBuffer),
+			     origin->width, origin->height, startRow,
+			     startCol, (short *) out, tileWidth, tileHeight,
+			     num_bands);
+	  break;
+      case RL2_SAMPLE_UINT16:
+	  copy_tile_raw_u16 ((const unsigned short *) (origin->rasterBuffer),
+			     origin->width, origin->height, startRow,
+			     startCol, (unsigned short *) out, tileWidth,
+			     tileHeight, num_bands);
+	  break;
+      case RL2_SAMPLE_INT32:
+	  copy_tile_raw_i32 ((const int *) (origin->rasterBuffer),
+			     origin->width, origin->height, startRow,
+			     startCol, (int *) out, tileWidth, tileHeight,
+			     num_bands);
+	  break;
+      case RL2_SAMPLE_UINT32:
+	  copy_tile_raw_u32 ((const unsigned int *) (origin->rasterBuffer),
+			     origin->width, origin->height, startRow,
+			     startCol, (unsigned int *) out, tileWidth,
+			     tileHeight, num_bands);
+	  break;
+      case RL2_SAMPLE_FLOAT:
+	  copy_tile_raw_flt ((const float *) (origin->rasterBuffer),
+			     origin->width, origin->height, startRow,
+			     startCol, (float *) out, tileWidth, tileHeight,
+			     num_bands);
+	  break;
+      case RL2_SAMPLE_DOUBLE:
+	  copy_tile_raw_dbl ((const double *) (origin->rasterBuffer),
+			     origin->width, origin->height, startRow,
+			     startCol, (double *) out, tileWidth, tileHeight,
+			     num_bands);
+	  break;
+      default:
+	  copy_tile_raw_u8 ((const unsigned char *) (origin->rasterBuffer),
+			    origin->width, origin->height, startRow, startCol,
+			    (unsigned char *) out, tileWidth, tileHeight,
+			    num_bands);
+	  break;
+      };
+
+    *pixels = out;
+    *pixels_sz = outsz;
+    return 1;
+}
+
+RL2_DECLARE rl2RasterPtr
+rl2_get_tile_from_raw_pixels (rl2CoveragePtr cvg, rl2RasterPtr jpeg,
+			      unsigned int startRow, unsigned int startCol)
+{
+/* attempting to create a Coverage-tile from a RAW pixel buffer */
+    unsigned int x;
+    rl2PrivCoveragePtr coverage = (rl2PrivCoveragePtr) cvg;
+    rl2PrivRasterPtr origin = (rl2PrivRasterPtr) jpeg;
+    rl2RasterPtr raster = NULL;
+    unsigned char *pixels = NULL;
+    int pixels_sz = 0;
+    unsigned char *mask = NULL;
+    int mask_size = 0;
+    unsigned int unused_width = 0;
+    unsigned int unused_height = 0;
+
+    if (coverage == NULL || origin == NULL)
+	return NULL;
+    if (!eval_raw_pixels_compatibility (coverage, origin))
+	return NULL;
+
+/* testing for tile's boundary validity */
+    if (startCol > origin->width)
+	return NULL;
+    if (startRow > origin->height)
+	return NULL;
+    x = startCol / coverage->tileWidth;
+    if ((x * coverage->tileWidth) != startCol)
+	return NULL;
+    x = startRow / coverage->tileHeight;
+    if ((x * coverage->tileHeight) != startRow)
+	return NULL;
+
+/* attempting to create the tile */
+    if (!build_tile_from_raw_pixels
+	(origin, coverage->tileWidth, coverage->tileHeight,
+	 coverage->sampleType, coverage->nBands, startRow, startCol,
+	 (rl2PixelPtr) (coverage->noData), &pixels, &pixels_sz) != RL2_OK)
+	goto error;
+    if (startCol + coverage->tileWidth > origin->width)
+	unused_width = (startCol + coverage->tileWidth) - origin->width;
+    if (startRow + coverage->tileHeight > origin->height)
+	unused_height = (startRow + coverage->tileHeight) - origin->height;
+    if (unused_width || unused_height)
+      {
+	  /* 
+	   * creating a Transparency Mask so to shadow any 
+	   * unused portion of the current tile 
+	   */
+	  unsigned int shadow_x = coverage->tileWidth - unused_width;
+	  unsigned int shadow_y = coverage->tileHeight - unused_height;
+	  unsigned int row;
+	  mask_size = coverage->tileWidth * coverage->tileHeight;
+	  mask = malloc (mask_size);
+	  if (mask == NULL)
+	      goto error;
+	  /* full Transparent mask */
+	  memset (mask, 0, coverage->tileWidth * coverage->tileHeight);
+	  for (row = 0; row < coverage->tileHeight; row++)
+	    {
+		unsigned char *p = mask + (row * coverage->tileWidth);
+		if (row < shadow_y)
+		  {
+		      /* setting opaque pixels */
+		      memset (p, 1, shadow_x);
+		  }
+	    }
+      }
+    raster =
+	rl2_create_raster (coverage->tileWidth, coverage->tileHeight,
+			   coverage->sampleType, coverage->pixelType,
+			   coverage->nBands, pixels, pixels_sz, NULL, mask,
+			   mask_size, NULL);
+    if (raster == NULL)
+	goto error;
+    return raster;
+  error:
+    if (pixels != NULL)
+	free (pixels);
+    if (mask != NULL)
+	free (mask);
+    return NULL;
+}
+
+RL2_DECLARE char *
+rl2_build_raw_pixels_xml_summary (rl2RasterPtr rst)
+{
+
+/* attempting to build an XML Summary from a RAW pixel buffer */
+    char *xml;
+    char *prev;
+    int len;
+    unsigned char bps;
+    const char *photo;
+    const char *frmt;
+    rl2PrivRasterPtr raster = (rl2PrivRasterPtr) rst;
+    if (raster == NULL)
+	return NULL;
+
+    xml = sqlite3_mprintf ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<ImportedRaster>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml =
+	sqlite3_mprintf ("%s<RasterFormat>RAW pixel buffer</RasterFormat>",
+			 prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml =
+	sqlite3_mprintf ("%s<RasterWidth>%u</RasterWidth>", prev,
+			 raster->width);
+    sqlite3_free (prev);
+    prev = xml;
+    xml =
+	sqlite3_mprintf ("%s<RasterHeight>%u</RasterHeight>", prev,
+			 raster->height);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<RowsPerStrip>1</RowsPerStrip>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    switch (raster->sampleType)
+      {
+      case RL2_SAMPLE_1_BIT:
+	  bps = 1;
+	  break;
+      case RL2_SAMPLE_2_BIT:
+	  bps = 2;
+	  break;
+      case RL2_SAMPLE_4_BIT:
+	  bps = 4;
+	  break;
+      case RL2_SAMPLE_INT8:
+      case RL2_SAMPLE_UINT8:
+	  bps = 8;
+	  break;
+      case RL2_SAMPLE_INT16:
+      case RL2_SAMPLE_UINT16:
+	  bps = 16;
+	  break;
+      case RL2_SAMPLE_INT32:
+      case RL2_SAMPLE_UINT32:
+      case RL2_SAMPLE_FLOAT:
+	  bps = 32;
+	  break;
+      case RL2_SAMPLE_DOUBLE:
+	  bps = 64;
+	  break;
+      default:
+	  bps = 0;
+	  break;
+      };
+    xml = sqlite3_mprintf ("%s<BitsPerSample>%u</BitsPerSample>", prev, bps);
+    sqlite3_free (prev);
+    prev = xml;
+    xml =
+	sqlite3_mprintf ("%s<SamplesPerPixel>%u</SamplesPerPixel>", prev,
+			 raster->nBands);
+    sqlite3_free (prev);
+    prev = xml;
+    switch (raster->pixelType)
+      {
+      case RL2_PIXEL_MONOCHROME:
+      case RL2_PIXEL_GRAYSCALE:
+      case RL2_PIXEL_MULTIBAND:
+      case RL2_PIXEL_DATAGRID:
+	  photo = "min-is-black";
+	  break;
+      case RL2_PIXEL_PALETTE:
+	  photo = "Palette";
+	  break;
+      case RL2_PIXEL_RGB:
+	  photo = "RGB";
+	  break;
+      default:
+	  photo = "unknown";
+	  break;
+      };
+    xml =
+	sqlite3_mprintf
+	("%s<PhotometricInterpretation>%s</PhotometricInterpretation>",
+	 prev, photo);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<Compression>none</Compression>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    switch (raster->sampleType)
+      {
+      case RL2_SAMPLE_1_BIT:
+      case RL2_SAMPLE_2_BIT:
+      case RL2_SAMPLE_4_BIT:
+      case RL2_SAMPLE_UINT8:
+      case RL2_SAMPLE_UINT16:
+      case RL2_SAMPLE_UINT32:
+	  frmt = "unsigned integer";
+	  break;
+      case RL2_SAMPLE_INT8:
+      case RL2_SAMPLE_INT16:
+      case RL2_SAMPLE_INT32:
+	  frmt = "signed integer";
+	  break;
+      case RL2_SAMPLE_FLOAT:
+      case RL2_SAMPLE_DOUBLE:
+	  frmt = "floating point";
+	  break;
+      default:
+	  frmt = "unknown";
+	  break;
+      };
+    xml = sqlite3_mprintf ("%s<SampleFormat>%s</SampleFormat>", prev, frmt);
+    sqlite3_free (prev);
+    prev = xml;
+    xml =
+	sqlite3_mprintf
+	("%s<PlanarConfiguration>single Raster plane</PlanarConfiguration>",
+	 prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<NoDataPixel>unknown</NoDataPixel>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<GeoReferencing>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<SpatialReferenceSystem>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<SRID>%d</SRID>", prev, raster->Srid);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<RefSysName>undeclared</RefSysName>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s</SpatialReferenceSystem>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<SpatialResolution>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml =
+	sqlite3_mprintf
+	("%s<HorizontalResolution>%1.10f</HorizontalResolution>", prev,
+	 raster->hResolution);
+    sqlite3_free (prev);
+    prev = xml;
+    xml =
+	sqlite3_mprintf
+	("%s<VerticalResolution>%1.10f</VerticalResolution>", prev,
+	 raster->vResolution);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s</SpatialResolution>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<BoundingBox>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<MinX>%1.10f</MinX>", prev, raster->minX);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<MinY>%1.10f</MinY>", prev, raster->minY);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<MaxX>%1.10f</MaxX>", prev, raster->maxX);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<MaxY>%1.10f</MaxY>", prev, raster->maxY);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s</BoundingBox>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<Extent>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml =
+	sqlite3_mprintf ("%s<HorizontalExtent>%1.10f</HorizontalExtent>",
+			 prev, raster->maxX - raster->minX);
+    sqlite3_free (prev);
+    prev = xml;
+    xml =
+	sqlite3_mprintf ("%s<VerticalExtent>%1.10f</VerticalExtent>",
+			 prev, raster->maxY - raster->minY);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s</Extent>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s</GeoReferencing>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s</ImportedRaster>", prev);
+    sqlite3_free (prev);
+    len = strlen (xml);
+    prev = xml;
+    xml = malloc (len + 1);
+    strcpy (xml, prev);
+    sqlite3_free (prev);
+    return xml;
+}
diff --git a/src/rl2sql.c b/src/rl2sql.c
index f224485..8738461 100644
--- a/src/rl2sql.c
+++ b/src/rl2sql.c
@@ -20,7 +20,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -57,17 +57,11 @@ the terms of any one of the MPL, the GPL or the LGPL.
 
 #include "config.h"
 
-#ifdef LOADABLE_EXTENSION
-#include "rasterlite2/sqlite.h"
-#endif
-
 #include "rasterlite2/rasterlite2.h"
 #include "rasterlite2/rl2wms.h"
 #include "rasterlite2/rl2graphics.h"
 #include "rasterlite2_private.h"
 
-#include <spatialite/gaiaaux.h>
-
 #define RL2_UNUSED() if (argc || argv) argc = argc;
 
 /* 64 bit integer: portable format for printf() */
@@ -77,6 +71,8 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #define ERR_FRMT64 "ERROR: unable to decode Tile ID=%lld\n"
 #endif
 
+#define MAX_FONT_SIZE	2*1024*1024
+
 static void
 fnct_rl2_version (sqlite3_context * context, int argc, sqlite3_value ** argv)
 {
@@ -93,6 +89,214 @@ fnct_rl2_version (sqlite3_context * context, int argc, sqlite3_value ** argv)
 }
 
 static void
+fnct_rl2_has_codec_none (sqlite3_context * context, int argc,
+			 sqlite3_value ** argv)
+{
+/* SQL function:
+/ rl2_has_codec_none()
+/
+/ will always return 1 (TRUE)
+*/
+    int ret = rl2_is_supported_codec (RL2_COMPRESSION_NONE);
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (ret < 0)
+	ret = 0;
+    sqlite3_result_int (context, ret);
+}
+
+static void
+fnct_rl2_has_codec_deflate (sqlite3_context * context, int argc,
+			    sqlite3_value ** argv)
+{
+/* SQL function:
+/ rl2_has_codec_deflate()
+/
+/ will always return 1 (TRUE)
+*/
+    int ret = rl2_is_supported_codec (RL2_COMPRESSION_DEFLATE);
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (ret < 0)
+	ret = 0;
+    sqlite3_result_int (context, ret);
+}
+
+static void
+fnct_rl2_has_codec_deflate_no (sqlite3_context * context, int argc,
+			       sqlite3_value ** argv)
+{
+/* SQL function:
+/ rl2_has_codec_deflate_no()
+/
+/ will always return 1 (TRUE)
+*/
+    int ret = rl2_is_supported_codec (RL2_COMPRESSION_DEFLATE_NO);
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (ret < 0)
+	ret = 0;
+    sqlite3_result_int (context, ret);
+}
+
+static void
+fnct_rl2_has_codec_png (sqlite3_context * context, int argc,
+			sqlite3_value ** argv)
+{
+/* SQL function:
+/ rl2_has_codec_png()
+/
+/ will always return 1 (TRUE)
+*/
+    int ret = rl2_is_supported_codec (RL2_COMPRESSION_PNG);
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (ret < 0)
+	ret = 0;
+    sqlite3_result_int (context, ret);
+}
+
+static void
+fnct_rl2_has_codec_jpeg (sqlite3_context * context, int argc,
+			 sqlite3_value ** argv)
+{
+/* SQL function:
+/ rl2_has_codec_jpeg()
+/
+/ will always return 1 (TRUE)
+*/
+    int ret = rl2_is_supported_codec (RL2_COMPRESSION_JPEG);
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (ret < 0)
+	ret = 0;
+    sqlite3_result_int (context, ret);
+}
+
+static void
+fnct_rl2_has_codec_fax4 (sqlite3_context * context, int argc,
+			 sqlite3_value ** argv)
+{
+/* SQL function:
+/ rl2_has_codec_fax4()
+/
+/ will always return 1 (TRUE)
+*/
+    int ret = rl2_is_supported_codec (RL2_COMPRESSION_CCITTFAX4);
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (ret < 0)
+	ret = 0;
+    sqlite3_result_int (context, ret);
+}
+
+static void
+fnct_rl2_has_codec_lzma (sqlite3_context * context, int argc,
+			 sqlite3_value ** argv)
+{
+/* SQL function:
+/ rl2_has_codec_lzma()
+/
+/ will return 1 (TRUE) or 0 (FALSE) depending of OMIT_LZMA
+*/
+    int ret = rl2_is_supported_codec (RL2_COMPRESSION_LZMA);
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (ret < 0)
+	ret = 0;
+    sqlite3_result_int (context, ret);
+}
+
+static void
+fnct_rl2_has_codec_lzma_no (sqlite3_context * context, int argc,
+			    sqlite3_value ** argv)
+{
+/* SQL function:
+/ rl2_has_codec_lzma_no()
+/
+/ will return 1 (TRUE) or 0 (FALSE) depending of OMIT_LZMA
+*/
+    int ret = rl2_is_supported_codec (RL2_COMPRESSION_LZMA_NO);
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (ret < 0)
+	ret = 0;
+    sqlite3_result_int (context, ret);
+}
+
+static void
+fnct_rl2_has_codec_charls (sqlite3_context * context, int argc,
+			   sqlite3_value ** argv)
+{
+/* SQL function:
+/ rl2_has_codec_charls()
+/
+/ will return 1 (TRUE) or 0 (FALSE) depending of OMIT_CHARLS
+*/
+    int ret = rl2_is_supported_codec (RL2_COMPRESSION_CHARLS);
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (ret < 0)
+	ret = 0;
+    sqlite3_result_int (context, ret);
+}
+
+static void
+fnct_rl2_has_codec_webp (sqlite3_context * context, int argc,
+			 sqlite3_value ** argv)
+{
+/* SQL function:
+/ rl2_has_codec_webp()
+/
+/ will return 1 (TRUE) or 0 (FALSE) depending of OMIT_WEBP
+*/
+    int ret = rl2_is_supported_codec (RL2_COMPRESSION_LOSSY_WEBP);
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (ret < 0)
+	ret = 0;
+    sqlite3_result_int (context, ret);
+}
+
+static void
+fnct_rl2_has_codec_ll_webp (sqlite3_context * context, int argc,
+			    sqlite3_value ** argv)
+{
+/* SQL function:
+/ rl2_has_codec_ll_webp()
+/
+/ will return 1 (TRUE) or 0 (FALSE) depending of OMIT_WEBP
+*/
+    int ret = rl2_is_supported_codec (RL2_COMPRESSION_LOSSLESS_WEBP);
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (ret < 0)
+	ret = 0;
+    sqlite3_result_int (context, ret);
+}
+
+static void
+fnct_rl2_has_codec_jp2 (sqlite3_context * context, int argc,
+			sqlite3_value ** argv)
+{
+/* SQL function:
+/ rl2_has_codec_jp2()
+/
+/ will return 1 (TRUE) or 0 (FALSE) depending of OMIT_OPENJPEG
+*/
+    int ret = rl2_is_supported_codec (RL2_COMPRESSION_LOSSY_JP2);
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (ret < 0)
+	ret = 0;
+    sqlite3_result_int (context, ret);
+}
+
+static void
+fnct_rl2_has_codec_ll_jp2 (sqlite3_context * context, int argc,
+			   sqlite3_value ** argv)
+{
+/* SQL function:
+/ rl2_has_codec_ll_jp2()
+/
+/ will return 1 (TRUE) or 0 (FALSE) depending of OMIT_OPENJPEG
+*/
+    int ret = rl2_is_supported_codec (RL2_COMPRESSION_LOSSLESS_JP2);
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (ret < 0)
+	ret = 0;
+    sqlite3_result_int (context, ret);
+}
+
+static void
 fnct_rl2_target_cpu (sqlite3_context * context, int argc, sqlite3_value ** argv)
 {
 /* SQL function:
@@ -108,6 +312,55 @@ fnct_rl2_target_cpu (sqlite3_context * context, int argc, sqlite3_value ** argv)
 }
 
 static void
+fnct_GetMaxThreads (sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+/* SQL function:
+/ RL2_GetMaxThreads()
+/
+/ return the currently set Max number of concurrent threads
+*/
+    int max_threads = 1;
+    struct rl2_private_data *priv_data = sqlite3_user_data (context);
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (priv_data != NULL)
+	max_threads = priv_data->max_threads;
+    sqlite3_result_int (context, max_threads);
+}
+
+static void
+fnct_SetMaxThreads (sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+/* SQL function:
+/ RL2_SetMaxThreads(INTEGER max)
+/
+/ return the currently set Max number of concurrent threads (after this call)
+/ -1 on invalid arguments
+*/
+    int max_threads = 1;
+    struct rl2_private_data *priv_data = sqlite3_user_data (context);
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (sqlite3_value_type (argv[0]) == SQLITE_INTEGER)
+	max_threads = sqlite3_value_int (argv[0]);
+    else
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+
+/* normalizing between 1 and 64 */
+    if (max_threads < 1)
+	max_threads = 1;
+    if (max_threads > 64)
+	max_threads = 64;
+
+    if (priv_data != NULL)
+	priv_data->max_threads = max_threads;
+    else
+	max_threads = 1;
+    sqlite3_result_int (context, max_threads);
+}
+
+static void
 fnct_IsValidPixel (sqlite3_context * context, int argc, sqlite3_value ** argv)
 {
 /* SQL function:
@@ -406,18 +659,19 @@ fnct_IsValidRasterTile (sqlite3_context * context, int argc,
 	  blob_even = sqlite3_value_blob (argv[3]);
 	  blob_even_sz = sqlite3_value_bytes (argv[3]);
       }
+
     if (!get_coverage_defs
-	(sqlite, coverage, &tile_width, &tile_height, &sample_type, &pixel_type,
-	 &num_bands, &compression))
+	(sqlite, coverage, &tile_width, &tile_height, &sample_type,
+	 &pixel_type, &num_bands, &compression))
       {
 	  sqlite3_result_int (context, -1);
 	  return;
       }
     ret =
-	rl2_is_valid_dbms_raster_tile (level, tile_width, tile_height, blob_odd,
-				       blob_odd_sz, blob_even, blob_even_sz,
-				       sample_type, pixel_type, num_bands,
-				       compression);
+	rl2_is_valid_dbms_raster_tile (level, tile_width, tile_height,
+				       blob_odd, blob_odd_sz, blob_even,
+				       blob_even_sz, sample_type, pixel_type,
+				       num_bands, compression);
     if (ret == RL2_OK)
 	sqlite3_result_int (context, 1);
     else
@@ -968,8 +1222,8 @@ fnct_SetPixelValue (sqlite3_context * context, int argc, sqlite3_value ** argv)
     rl2PrivPixelPtr pixel;
     rl2PrivSamplePtr sample;
     int band_id;
-    int intval;
-    double dblval;
+    int intval = 0;
+    double dblval = 0.0;
     RL2_UNUSED ();		/* LCOV_EXCL_LINE */
 
     if (sqlite3_value_type (argv[0]) != SQLITE_BLOB)
@@ -1283,8 +1537,8 @@ fnct_PixelEquals (sqlite3_context * context, int argc, sqlite3_value ** argv)
 }
 
 static void
-fnct_GetRasterStatistics_NoDataPixelsCount (sqlite3_context * context, int argc,
-					    sqlite3_value ** argv)
+fnct_GetRasterStatistics_NoDataPixelsCount (sqlite3_context * context,
+					    int argc, sqlite3_value ** argv)
 {
 /* SQL function:
 / GetRasterStatistics_NoDataPixelsCount(BLOBencoded statistics)
@@ -1318,8 +1572,8 @@ fnct_GetRasterStatistics_NoDataPixelsCount (sqlite3_context * context, int argc,
 }
 
 static void
-fnct_GetRasterStatistics_ValidPixelsCount (sqlite3_context * context, int argc,
-					   sqlite3_value ** argv)
+fnct_GetRasterStatistics_ValidPixelsCount (sqlite3_context * context,
+					   int argc, sqlite3_value ** argv)
 {
 /* SQL function:
 / GetRasterStatistics_ValidPixelsCount(BLOBencoded statistics)
@@ -1834,7 +2088,7 @@ fnct_GetBandHistogramFromImage (sqlite3_context * context, int argc,
     band_index = sqlite3_value_int (argv[2]);
 /* validating the mime-type */
     if (strcmp (mime_type, "image/png") == 0)
-	raster = rl2_raster_from_png (blob, blob_sz);
+	raster = rl2_raster_from_png (blob, blob_sz, 0);
     if (strcmp (mime_type, "image/jpeg") == 0)
 	raster = rl2_raster_from_jpeg (blob, blob_sz);
     if (raster == NULL)
@@ -1869,21 +2123,29 @@ fnct_GetBandHistogramFromImage (sqlite3_context * context, int argc,
 }
 
 static void
-fnct_CreateCoverage (sqlite3_context * context, int argc, sqlite3_value ** argv)
+fnct_CreateRasterCoverage (sqlite3_context * context, int argc,
+			   sqlite3_value ** argv)
 {
 /* SQL function:
-/ CreateCoverage(text coverage, text sample_type, text pixel_type,
-/                int num_bands, text compression, int quality,
-/                int tile_width, int tile_height, int srid,
-/                double res)
-/ CreateCoverage(text coverage, text sample_type, text pixel_type,
-/                int num_bands, text compression, int quality,
-/                int tile_width, int tile_height, int srid,
-/                double horz_res, double vert_res)
-/ CreateCoverage(text coverage, text sample_type, text pixel_type,
-/                int num_bands, text compression, int quality,
-/                int tile_width, int tile_height, int srid,
-/                double horz_res, double vert_res, BLOB no_data)
+/ CreateRasterCoverage(text coverage, text sample_type, text pixel_type,
+/                      int num_bands, text compression, int quality,
+/                      int tile_width, int tile_height, int srid,
+/                      double res)
+/ CreateRasterCoverage(text coverage, text sample_type, text pixel_type,
+/                      int num_bands, text compression, int quality,
+/                      int tile_width, int tile_height, int srid,
+/                      double horz_res, double vert_res)
+/ CreateRasterCoverage(text coverage, text sample_type, text pixel_type,
+/                      int num_bands, text compression, int quality,
+/                      int tile_width, int tile_height, int srid,
+/                      double horz_res, double vert_res, BLOB no_data)
+/ CreateRasterCoverage(text coverage, text sample_type, text pixel_type,
+/                      int num_bands, text compression, int quality,
+/                      int tile_width, int tile_height, int srid,
+/                      double horz_res, double vert_res, BLOB no_data,
+/                      int strict_resolution, int mixed_resolutions,
+/                      int section_paths, int section_md5,
+/                      int section_summary)
 /
 / will return 1 (TRUE, success) or 0 (FALSE, failure)
 / or -1 (INVALID ARGS)
@@ -1904,6 +2166,11 @@ fnct_CreateCoverage (sqlite3_context * context, int argc, sqlite3_value ** argv)
     unsigned char sample;
     unsigned char pixel;
     unsigned char compr;
+    int strict_resolution = 0;
+    int mixed_resolutions = 0;
+    int section_paths = 0;
+    int section_md5 = 0;
+    int section_summary = 0;
     sqlite3 *sqlite;
     int ret;
     rl2PixelPtr no_data = NULL;
@@ -1943,6 +2210,16 @@ fnct_CreateCoverage (sqlite3_context * context, int argc, sqlite3_value ** argv)
 	      && sqlite3_value_type (argv[11]) != SQLITE_NULL)
 	      err = 1;
       }
+    if (argc > 12 && sqlite3_value_type (argv[12]) != SQLITE_INTEGER)
+	err = 1;
+    if (argc > 13 && sqlite3_value_type (argv[13]) != SQLITE_INTEGER)
+	err = 1;
+    if (argc > 14 && sqlite3_value_type (argv[14]) != SQLITE_INTEGER)
+	err = 1;
+    if (argc > 15 && sqlite3_value_type (argv[15]) != SQLITE_INTEGER)
+	err = 1;
+    if (argc > 16 && sqlite3_value_type (argv[16]) != SQLITE_INTEGER)
+	err = 1;
     if (err)
 	goto error;
 
@@ -1984,6 +2261,36 @@ fnct_CreateCoverage (sqlite3_context * context, int argc, sqlite3_value ** argv)
 	  if (no_data == NULL)
 	      goto error;
       }
+    if (argc > 12)
+      {
+	  strict_resolution = sqlite3_value_int (argv[12]);
+	  if (strict_resolution)
+	      strict_resolution = 1;
+      }
+    if (argc > 13)
+      {
+	  mixed_resolutions = sqlite3_value_int (argv[13]);
+	  if (mixed_resolutions)
+	      mixed_resolutions = 1;
+      }
+    if (argc > 14)
+      {
+	  section_paths = sqlite3_value_int (argv[14]);
+	  if (section_paths)
+	      section_paths = 1;
+      }
+    if (argc > 15)
+      {
+	  section_md5 = sqlite3_value_int (argv[15]);
+	  if (section_md5)
+	      section_md5 = 1;
+      }
+    if (argc > 16)
+      {
+	  section_summary = sqlite3_value_int (argv[16]);
+	  if (section_summary)
+	      section_summary = 1;
+      }
 
 /* preliminary arg checking */
     if (num_bands < 1 || num_bands > 255)
@@ -2040,8 +2347,12 @@ fnct_CreateCoverage (sqlite3_context * context, int argc, sqlite3_value ** argv)
 	compr = RL2_COMPRESSION_NONE;
     if (strcasecmp (compression, "DEFLATE") == 0)
 	compr = RL2_COMPRESSION_DEFLATE;
+    if (strcasecmp (compression, "DEFLATE_NO") == 0)
+	compr = RL2_COMPRESSION_DEFLATE_NO;
     if (strcasecmp (compression, "LZMA") == 0)
 	compr = RL2_COMPRESSION_LZMA;
+    if (strcasecmp (compression, "LZMA_NO") == 0)
+	compr = RL2_COMPRESSION_LZMA_NO;
     if (strcasecmp (compression, "PNG") == 0)
 	compr = RL2_COMPRESSION_PNG;
     if (strcasecmp (compression, "GIF") == 0)
@@ -2054,6 +2365,12 @@ fnct_CreateCoverage (sqlite3_context * context, int argc, sqlite3_value ** argv)
 	compr = RL2_COMPRESSION_LOSSLESS_WEBP;
     if (strcasecmp (compression, "FAX4") == 0)
 	compr = RL2_COMPRESSION_CCITTFAX4;
+    if (strcasecmp (compression, "CHARLS") == 0)
+	compr = RL2_COMPRESSION_CHARLS;
+    if (strcasecmp (compression, "JP2") == 0)
+	compr = RL2_COMPRESSION_LOSSY_JP2;
+    if (strcasecmp (compression, "LL_JP2") == 0)
+	compr = RL2_COMPRESSION_LOSSLESS_JP2;
 
     if (no_data == NULL)
       {
@@ -2074,7 +2391,10 @@ fnct_CreateCoverage (sqlite3_context * context, int argc, sqlite3_value ** argv)
 				    compr, quality,
 				    (unsigned short) tile_width,
 				    (unsigned short) tile_height, srid,
-				    horz_res, vert_res, no_data, palette);
+				    horz_res, vert_res, no_data, palette,
+				    strict_resolution, mixed_resolutions,
+				    section_paths, section_md5,
+				    section_summary);
     if (ret == RL2_OK)
 	sqlite3_result_int (context, 1);
     else
@@ -2094,11 +2414,11 @@ fnct_CreateCoverage (sqlite3_context * context, int argc, sqlite3_value ** argv)
 }
 
 static void
-fnct_SetCoverageInfos (sqlite3_context * context, int argc,
-		       sqlite3_value ** argv)
+fnct_SetRasterCoverageInfos (sqlite3_context * context, int argc,
+			     sqlite3_value ** argv)
 {
 /* SQL function:
-/ SetCoverageInfos(String coverage_name, String title, 
+/ SetRasterCoverageInfos(String coverage_name, String title, 
 /		   String abstract)
 /
 / inserts or updates the descriptive infos supporting a Raster Coverage
@@ -2134,92 +2454,262 @@ fnct_SetCoverageInfos (sqlite3_context * context, int argc,
 }
 
 static void
-fnct_DeleteSection (sqlite3_context * context, int argc, sqlite3_value ** argv)
+fnct_SetRasterCoverageDefaultBands (sqlite3_context * context, int argc,
+				    sqlite3_value ** argv)
 {
 /* SQL function:
-/ DeleteSection(text coverage, text section)
-/ DeleteSection(text coverage, text section, int transaction)
-/
-/ will return 1 (TRUE, success) or 0 (FALSE, failure)
-/ or -1 (INVALID ARGS)
+/ SetRasterCoverageDefaultBands(String coverage_name, int red_band,
+/                               green_band, blue_band, nir_band)
 /
+/ inserts or updates the default band mapping supporting a Raster
+/ Coverage of the MULTIBAND type
+/ returns 1 on success
+/ 0 on failure, -1 on invalid arguments
 */
-    int err = 0;
-    const char *coverage;
-    const char *section;
-    int transaction = 1;
-    sqlite3 *sqlite;
-    int ret;
-    rl2CoveragePtr cvg = NULL;
-    sqlite3_int64 section_id;
+    const char *coverage_name;
+    int red;
+    int green;
+    int blue;
+    int nir;
+    sqlite3 *sqlite = sqlite3_context_db_handle (context);
     RL2_UNUSED ();		/* LCOV_EXCL_LINE */
-
     if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
-	err = 1;
-    if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
-	err = 1;
-    if (argc > 2 && sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
-	err = 1;
-    if (err)
-	goto invalid;
-
-/* retrieving the arguments */
-    sqlite = sqlite3_context_db_handle (context);
-    coverage = (const char *) sqlite3_value_text (argv[0]);
-    section = (const char *) sqlite3_value_text (argv[1]);
-    if (argc > 2)
-	transaction = sqlite3_value_int (argv[2]);
-
-    cvg = rl2_create_coverage_from_dbms (sqlite, coverage);
-    if (cvg == NULL)
-	goto error;
-    if (rl2_get_dbms_section_id (sqlite, coverage, section, &section_id) !=
-	RL2_OK)
-	goto error;
-
-    if (transaction)
       {
-	  /* starting a DBMS Transaction */
-	  ret = sqlite3_exec (sqlite, "BEGIN", NULL, NULL, NULL);
-	  if (ret != SQLITE_OK)
-	      goto error;
+	  sqlite3_result_int (context, -1);
+	  return;
       }
-
-    if (rl2_delete_dbms_section (sqlite, coverage, section_id) != RL2_OK)
-	goto error;
-
-    if (transaction)
+    if (sqlite3_value_type (argv[1]) != SQLITE_INTEGER)
       {
-	  /* committing the still pending transaction */
-	  ret = sqlite3_exec (sqlite, "COMMIT", NULL, NULL, NULL);
-	  if (ret != SQLITE_OK)
-	      goto error;
+	  sqlite3_result_int (context, -1);
+	  return;
       }
-    sqlite3_result_int (context, 1);
-    rl2_destroy_coverage (cvg);
-    return;
-
-  invalid:
-    sqlite3_result_int (context, -1);
-    return;
-  error:
-    if (cvg != NULL)
-	rl2_destroy_coverage (cvg);
-    sqlite3_result_int (context, 0);
-    if (transaction)
+    if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
       {
-	  /* invalidating the pending transaction */
-	  sqlite3_exec (sqlite, "ROLLBACK", NULL, NULL, NULL);
+	  sqlite3_result_int (context, -1);
+	  return;
       }
-    return;
-}
-
+    if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+    if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+    coverage_name = (const char *) sqlite3_value_text (argv[0]);
+    red = sqlite3_value_int (argv[1]);
+    green = sqlite3_value_int (argv[2]);
+    blue = sqlite3_value_int (argv[3]);
+    nir = sqlite3_value_int (argv[4]);
+    if (red < 0 || red > 255)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+    if (green < 0 || green > 255)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+    if (blue < 0 || blue > 255)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+    if (nir < 0 || nir > 255)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+    if (red == green || red == blue || red == nir)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+    if (green == blue || green == nir)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+    if (blue == nir)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+    if (rl2_set_dbms_coverage_default_bands
+	(sqlite, coverage_name, red, green, blue, nir) == RL2_OK)
+	sqlite3_result_int (context, 1);
+    else
+	sqlite3_result_int (context, 0);
+}
+
+static void
+fnct_EnableRasterCoverageAutoNDVI (sqlite3_context * context, int argc,
+				   sqlite3_value ** argv)
+{
+/* SQL function:
+/ EnableRasterCoverageAutoNDVI(String coverage_name, int on_off)
+/
+/ enables or disables the AutoNDVI feature on a Raster
+/ Coverage of the MULTIBAND type and explicitly declaring
+/ a default band mapping
+/ returns 1 on success
+/ 0 on failure, -1 on invalid arguments
+*/
+    const char *coverage_name;
+    int on_off;
+    sqlite3 *sqlite = sqlite3_context_db_handle (context);
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+    if (sqlite3_value_type (argv[1]) != SQLITE_INTEGER)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+    coverage_name = (const char *) sqlite3_value_text (argv[0]);
+    on_off = sqlite3_value_int (argv[1]);
+    if (rl2_enable_dbms_coverage_auto_ndvi (sqlite, coverage_name, on_off) ==
+	RL2_OK)
+	sqlite3_result_int (context, 1);
+    else
+	sqlite3_result_int (context, 0);
+}
+
+static void
+fnct_IsRasterCoverageAutoNdviEnabled (sqlite3_context * context, int argc,
+				      sqlite3_value ** argv)
+{
+/* SQL function:
+/ IsRasterCoverageAutoNdviEnabled(String coverage_name)
+/
+/ checks if a Raster Coverage do actually supports the AutoNDVI feature
+/ returns 1 (TRUE) or 0 (FALSE)
+/ -1 on invalid arguments or if the Raster Coverage isn't of the
+/ MULTIBAND type and explicitly declaring a default band mapping
+*/
+    const char *coverage_name;
+    int ret;
+    sqlite3 *sqlite = sqlite3_context_db_handle (context);
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+    coverage_name = (const char *) sqlite3_value_text (argv[0]);
+    ret = rl2_is_dbms_coverage_auto_ndvi_enabled (sqlite, coverage_name);
+    if (ret == RL2_TRUE)
+	sqlite3_result_int (context, 1);
+    else if (ret == RL2_FALSE)
+	sqlite3_result_int (context, 0);
+    else
+	sqlite3_result_int (context, -1);
+}
+
+static void
+fnct_CopyRasterCoverage (sqlite3_context * context, int argc,
+			 sqlite3_value ** argv)
+{
+/* SQL function:
+/ CopyRasterCoverage(String db_prefix, String coverage_name)
+/   or
+/ CopyRasterCoverage(String db_prefix, String coverage_name, int transaction)
+/
+/ copies a whole Raster Coverage from an Attached DB
+/ returns 1 on success
+/ 0 on failure, -1 on invalid arguments
+*/
+    int ret;
+    const char *db_prefix;
+    const char *coverage_name;
+    int transaction = 0;
+    sqlite3 *sqlite = sqlite3_context_db_handle (context);
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+    if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+    db_prefix = (const char *) sqlite3_value_text (argv[0]);
+    coverage_name = (const char *) sqlite3_value_text (argv[1]);
+    if (argc == 3)
+      {
+	  if (sqlite3_value_type (argv[2]) == SQLITE_INTEGER)
+	      transaction = sqlite3_value_int (argv[2]);
+	  else
+	    {
+		sqlite3_result_int (context, -1);
+		return;
+	    }
+      }
+
+    if (transaction)
+      {
+	  /* starting a DBMS Transaction */
+	  ret = sqlite3_exec (sqlite, "BEGIN", NULL, NULL, NULL);
+	  if (ret != SQLITE_OK)
+	    {
+		sqlite3_result_int (context, 0);
+		return;
+	    }
+      }
+
+/* just in case, attempting to (re)create raster meta-tables */
+    sqlite3_exec (sqlite, "SELECT CreateRasterCoveragesTable()", NULL, NULL,
+		  NULL);
+    sqlite3_exec (sqlite, "SELECT CreateStylingTables()", NULL, NULL, NULL);
+
+/* checks if a Raster Coverage of the same name already exists on Main */
+    if (rl2_check_raster_coverage_destination (sqlite, coverage_name) != RL2_OK)
+      {
+	  sqlite3_result_int (context, 0);
+	  return;
+      }
+/* checks if the Raster Coverage origine do really exists */
+    if (rl2_check_raster_coverage_origin (sqlite, db_prefix, coverage_name) !=
+	RL2_OK)
+      {
+	  sqlite3_result_int (context, 0);
+	  return;
+      }
+/* attemtping to copy */
+    if (rl2_copy_raster_coverage (sqlite, db_prefix, coverage_name) != RL2_OK)
+      {
+	  sqlite3_exec (sqlite, "ROLLBACK", NULL, NULL, NULL);
+	  sqlite3_result_int (context, 0);
+	  return;
+      }
+
+    if (transaction)
+      {
+	  /* committing the still pending Transaction */
+	  ret = sqlite3_exec (sqlite, "COMMIT", NULL, NULL, NULL);
+	  if (ret != SQLITE_OK)
+	    {
+		sqlite3_result_int (context, 0);
+		return;
+	    }
+      }
+    sqlite3_result_int (context, 1);
+}
+
 static void
-fnct_DropCoverage (sqlite3_context * context, int argc, sqlite3_value ** argv)
+fnct_DeleteSection (sqlite3_context * context, int argc, sqlite3_value ** argv)
 {
 /* SQL function:
-/ DropCoverage(text coverage)
-/ DropCoverage(text coverage, int transaction)
+/ DeleteSection(text coverage, integer section_id)
+/ DeleteSection(text coverage, integer section_id, int transaction)
 /
 / will return 1 (TRUE, success) or 0 (FALSE, failure)
 / or -1 (INVALID ARGS)
@@ -2227,6 +2717,7 @@ fnct_DropCoverage (sqlite3_context * context, int argc, sqlite3_value ** argv)
 */
     int err = 0;
     const char *coverage;
+    sqlite3_int64 section_id;
     int transaction = 1;
     sqlite3 *sqlite;
     int ret;
@@ -2235,7 +2726,9 @@ fnct_DropCoverage (sqlite3_context * context, int argc, sqlite3_value ** argv)
 
     if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
 	err = 1;
-    if (argc > 1 && sqlite3_value_type (argv[1]) != SQLITE_INTEGER)
+    if (sqlite3_value_type (argv[1]) != SQLITE_INTEGER)
+	err = 1;
+    if (argc > 2 && sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
 	err = 1;
     if (err)
 	goto invalid;
@@ -2243,8 +2736,9 @@ fnct_DropCoverage (sqlite3_context * context, int argc, sqlite3_value ** argv)
 /* retrieving the arguments */
     sqlite = sqlite3_context_db_handle (context);
     coverage = (const char *) sqlite3_value_text (argv[0]);
-    if (argc > 1)
-	transaction = sqlite3_value_int (argv[1]);
+    section_id = sqlite3_value_int64 (argv[1]);
+    if (argc > 2)
+	transaction = sqlite3_value_int (argv[2]);
 
     cvg = rl2_create_coverage_from_dbms (sqlite, coverage);
     if (cvg == NULL)
@@ -2258,7 +2752,7 @@ fnct_DropCoverage (sqlite3_context * context, int argc, sqlite3_value ** argv)
 	      goto error;
       }
 
-    if (rl2_drop_dbms_coverage (sqlite, coverage) != RL2_OK)
+    if (rl2_delete_dbms_section (sqlite, coverage, section_id) != RL2_OK)
 	goto error;
 
     if (transaction)
@@ -2288,445 +2782,491 @@ fnct_DropCoverage (sqlite3_context * context, int argc, sqlite3_value ** argv)
 }
 
 static void
-fnct_LoadRaster (sqlite3_context * context, int argc, sqlite3_value ** argv)
+fnct_DropRasterCoverage (sqlite3_context * context, int argc,
+			 sqlite3_value ** argv)
 {
 /* SQL function:
-/ LoadRaster(text coverage, text path_to_raster)
-/ LoadRaster(text coverage, text path_to_raster, int with_worldfile)
-/ LoadRaster(text coverage, text path_to_raster, int with_worldfile,
-/            int force_srid)
-/ LoadRaster(text coverage, text path_to_raster, int with_worldfile,
-/            int force_srid, int pyramidize)
-/ LoadRaster(text coverage, text path_to_raster, int with_worldfile,
-/            int force_srid, int pyramidize, int transaction)
+/ DropRasterCoverage(text coverage)
+/ DropRasterCoverage(text coverage, int transaction)
 /
 / will return 1 (TRUE, success) or 0 (FALSE, failure)
 / or -1 (INVALID ARGS)
 /
 */
     int err = 0;
-    const char *cvg_name;
-    const char *path;
-    int worldfile = 0;
-    int force_srid = -1;
+    const char *coverage;
     int transaction = 1;
-    int pyramidize = 1;
-    rl2CoveragePtr coverage = NULL;
     sqlite3 *sqlite;
     int ret;
+    rl2CoveragePtr cvg = NULL;
     RL2_UNUSED ();		/* LCOV_EXCL_LINE */
 
     if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
 	err = 1;
-    if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
-	err = 1;
-    if (argc > 2 && sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
-	err = 1;
-    if (argc > 3 && sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
-	err = 1;
-    if (argc > 4 && sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
-	err = 1;
-    if (argc > 5 && sqlite3_value_type (argv[5]) != SQLITE_INTEGER)
+    if (argc > 1 && sqlite3_value_type (argv[1]) != SQLITE_INTEGER)
 	err = 1;
     if (err)
-      {
-	  sqlite3_result_int (context, -1);
-	  return;
-      }
+	goto invalid;
 
 /* retrieving the arguments */
-    cvg_name = (const char *) sqlite3_value_text (argv[0]);
-    path = (const char *) sqlite3_value_text (argv[1]);
-    if (argc > 2)
-	worldfile = sqlite3_value_int (argv[2]);
-    if (argc > 3)
-	force_srid = sqlite3_value_int (argv[3]);
-    if (argc > 4)
-	pyramidize = sqlite3_value_int (argv[4]);
-    if (argc > 5)
-	transaction = sqlite3_value_int (argv[5]);
-
-
-/* attempting to load the Coverage definitions from the DBMS */
     sqlite = sqlite3_context_db_handle (context);
-    coverage = rl2_create_coverage_from_dbms (sqlite, cvg_name);
-    if (coverage == NULL)
-      {
-	  sqlite3_result_int (context, -1);
-	  return;
-      }
+    coverage = (const char *) sqlite3_value_text (argv[0]);
+    if (argc > 1)
+	transaction = sqlite3_value_int (argv[1]);
+
+    cvg = rl2_create_coverage_from_dbms (sqlite, coverage);
+    if (cvg == NULL)
+	goto error;
 
-/* attempting to load the Raster into the DBMS */
     if (transaction)
       {
 	  /* starting a DBMS Transaction */
 	  ret = sqlite3_exec (sqlite, "BEGIN", NULL, NULL, NULL);
 	  if (ret != SQLITE_OK)
-	    {
-		rl2_destroy_coverage (coverage);
-		sqlite3_result_int (context, -1);
-		return;
-	    }
+	      goto error;
       }
-    ret = rl2_load_raster_into_dbms (sqlite, path, coverage,
-				     worldfile, force_srid, pyramidize);
-    rl2_destroy_coverage (coverage);
-    if (ret != RL2_OK)
-      {
-	  sqlite3_result_int (context, 0);
-	  if (transaction)
-	    {
-		/* invalidating the pending transaction */
-		sqlite3_exec (sqlite, "ROLLBACK", NULL, NULL, NULL);
-	    }
-	  return;
-      }
-    if (transaction)
+
+    if (rl2_drop_dbms_coverage (sqlite, coverage) != RL2_OK)
+	goto error;
+
+    if (transaction)
       {
 	  /* committing the still pending transaction */
 	  ret = sqlite3_exec (sqlite, "COMMIT", NULL, NULL, NULL);
 	  if (ret != SQLITE_OK)
-	    {
-		sqlite3_result_int (context, -1);
-		return;
-	    }
+	      goto error;
       }
     sqlite3_result_int (context, 1);
+    rl2_destroy_coverage (cvg);
+    return;
+
+  invalid:
+    sqlite3_result_int (context, -1);
+    return;
+  error:
+    if (cvg != NULL)
+	rl2_destroy_coverage (cvg);
+    sqlite3_result_int (context, 0);
+    if (transaction)
+      {
+	  /* invalidating the pending transaction */
+	  sqlite3_exec (sqlite, "ROLLBACK", NULL, NULL, NULL);
+      }
+    return;
 }
 
 static void
-fnct_LoadRastersFromDir (sqlite3_context * context, int argc,
-			 sqlite3_value ** argv)
+fnct_LoadFontFromFile (sqlite3_context * context, int argc,
+		       sqlite3_value ** argv)
 {
 /* SQL function:
-/ LoadRastersFromDir(text coverage, text dir_path)
-/ LoadRastersFromDir(text coverage, text dir_path, text file_ext)
-/ LoadRastersFromDir(text coverage, text dir_path, text file_ext,
-/                    int with_worldfile)
-/ LoadRastersFromDir(text coverage, text dir_path, text file_ext,
-/                    int with_worldfile, int force_srid)
-/ LoadRastersFromDir(text coverage, text dir_path, text file_ext,
-/                    int with_worldfile, int force_srid, 
-/                    int pyramidize)
-/ LoadRastersFromDir(text coverage, text dir_path, text file_ext,
-/                    int with_worldfile, int force_srid, 
-/                    int pyramidize, int transaction)
+/ LoadFontFromFile(text font-path)
 /
 / will return 1 (TRUE, success) or 0 (FALSE, failure)
 / or -1 (INVALID ARGS)
 /
 */
-    int err = 0;
-    const char *cvg_name;
-    const char *path;
-    const char *file_ext;
-    int worldfile = 0;
-    int force_srid = -1;
-    int transaction = 1;
-    int pyramidize = 1;
-    rl2CoveragePtr coverage = NULL;
+    FILE *in = NULL;
+    unsigned char *buffer = NULL;
+    int buf_size;
+    const char *font_path;
     sqlite3 *sqlite;
-    int ret;
+    unsigned char *blob = NULL;
+    int blob_sz;
     RL2_UNUSED ();		/* LCOV_EXCL_LINE */
 
     if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
-	err = 1;
-    if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
-	err = 1;
-    if (argc > 2 && sqlite3_value_type (argv[2]) != SQLITE_TEXT)
-	err = 1;
-    if (argc > 3 && sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
-	err = 1;
-    if (argc > 4 && sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
-	err = 1;
-    if (argc > 5 && sqlite3_value_type (argv[5]) != SQLITE_INTEGER)
-	err = 1;
-    if (argc > 6 && sqlite3_value_type (argv[6]) != SQLITE_INTEGER)
-	err = 1;
-    if (err)
       {
 	  sqlite3_result_int (context, -1);
 	  return;
       }
 
-/* retrieving the arguments */
-    cvg_name = (const char *) sqlite3_value_text (argv[0]);
-    path = (const char *) sqlite3_value_text (argv[1]);
-    if (argc > 2)
-	file_ext = (const char *) sqlite3_value_text (argv[2]);
-    if (argc > 3)
-	worldfile = sqlite3_value_int (argv[3]);
-    if (argc > 4)
-	force_srid = sqlite3_value_int (argv[4]);
-    if (argc > 5)
-	pyramidize = sqlite3_value_int (argv[5]);
-    if (argc > 6)
-	transaction = sqlite3_value_int (argv[6]);
-
-/* attempting to load the Coverage definitions from the DBMS */
     sqlite = sqlite3_context_db_handle (context);
-    coverage = rl2_create_coverage_from_dbms (sqlite, cvg_name);
-    if (coverage == NULL)
-      {
-	  sqlite3_result_int (context, -1);
-	  return;
-      }
+    font_path = (const char *) sqlite3_value_text (argv[0]);
 
-/* attempting to load the Rasters into the DBMS */
-    if (transaction)
+/* loading the font from the external file */
+    in = fopen (font_path, "rb");
+    if (in == NULL)
       {
-	  /* starting a DBMS Transaction */
-	  ret = sqlite3_exec (sqlite, "BEGIN", NULL, NULL, NULL);
-	  if (ret != SQLITE_OK)
-	    {
-		rl2_destroy_coverage (coverage);
-		sqlite3_result_int (context, -1);
-		return;
-	    }
+	  sqlite3_result_int (context, 0);
+	  return;
       }
-    ret = rl2_load_mrasters_into_dbms (sqlite, path, file_ext, coverage,
-				       worldfile, force_srid, pyramidize);
-    rl2_destroy_coverage (coverage);
-    if (ret != RL2_OK)
+    buffer = malloc (MAX_FONT_SIZE);
+    if (buffer == NULL)
       {
 	  sqlite3_result_int (context, 0);
-	  if (transaction)
-	    {
-		/* invalidating the pending transaction */
-		sqlite3_exec (sqlite, "ROLLBACK", NULL, NULL, NULL);
-	    }
 	  return;
       }
-    if (transaction)
+    buf_size = fread (buffer, 1, MAX_FONT_SIZE, in);
+    fclose (in);
+
+/* attempting to encode the Font */
+    if (rl2_font_encode (buffer, buf_size, &blob, &blob_sz) != RL2_OK)
       {
-	  /* committing the still pending transaction */
-	  ret = sqlite3_exec (sqlite, "COMMIT", NULL, NULL, NULL);
-	  if (ret != SQLITE_OK)
-	    {
-		sqlite3_result_int (context, -1);
-		return;
-	    }
+	  free (buffer);
+	  sqlite3_result_int (context, 0);
+	  return;
       }
-    sqlite3_result_int (context, 1);
+    free (buffer);
+
+/* attempting to insert/update the Font */
+    if (rl2_load_font_into_dbms (sqlite, blob, blob_sz) != RL2_OK)
+	sqlite3_result_int (context, 0);
+    else
+	sqlite3_result_int (context, 1);
+    return;
 }
 
 static void
-fnct_Pyramidize (sqlite3_context * context, int argc, sqlite3_value ** argv)
+fnct_ExportFontToFile (sqlite3_context * context, int argc,
+		       sqlite3_value ** argv)
 {
 /* SQL function:
-/ Pyramidize(text coverage)
-/ Pyramidize(text coverage, text section)
-/ Pyramidize(text coverage, text section, int force_rebuild)
-/ Pyramidize(text coverage, text section, int force_rebuild,
-/            int transaction)
+/ ExportFontToFile(text facename, text font-path)
 /
 / will return 1 (TRUE, success) or 0 (FALSE, failure)
 / or -1 (INVALID ARGS)
 /
 */
-    int err = 0;
-    const char *cvg_name;
-    const char *sect_name = NULL;
-    int forced_rebuild = 0;
-    int transaction = 1;
+    FILE *out = NULL;
+    unsigned char *buffer = NULL;
+    int buf_size;
+    const char *facename;
+    const char *font_path;
     sqlite3 *sqlite;
-    int ret;
+    int wr;
     RL2_UNUSED ();		/* LCOV_EXCL_LINE */
 
     if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
-	err = 1;
-    if (argc > 1 && sqlite3_value_type (argv[1]) != SQLITE_TEXT
-	&& sqlite3_value_type (argv[1]) != SQLITE_NULL)
-	err = 1;
-    if (argc > 2 && sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
-	err = 1;
-    if (argc > 3 && sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
-	err = 1;
-    if (err)
       {
 	  sqlite3_result_int (context, -1);
 	  return;
       }
-/* attempting to (re)build Pyramid levels */
-    sqlite = sqlite3_context_db_handle (context);
-    cvg_name = (const char *) sqlite3_value_text (argv[0]);
-    if (argc > 1)
+    facename = (const char *) sqlite3_value_text (argv[0]);
+    if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
       {
-	  if (sqlite3_value_type (argv[1]) == SQLITE_TEXT)
-	      sect_name = (const char *) sqlite3_value_text (argv[1]);
+	  sqlite3_result_int (context, -1);
+	  return;
       }
-    if (argc > 2)
-	forced_rebuild = sqlite3_value_int (argv[2]);
-    if (argc > 3)
-	transaction = sqlite3_value_int (argv[3]);
-    if (transaction)
+    font_path = (const char *) sqlite3_value_text (argv[1]);
+
+    sqlite = sqlite3_context_db_handle (context);
+
+/* attempting to get the Font */
+    if (rl2_get_font_from_dbms (sqlite, facename, &buffer, &buf_size) != RL2_OK)
       {
-	  /* starting a DBMS Transaction */
-	  ret = sqlite3_exec (sqlite, "BEGIN", NULL, NULL, NULL);
-	  if (ret != SQLITE_OK)
-	    {
-		sqlite3_result_int (context, -1);
-		return;
-	    }
+	  sqlite3_result_int (context, 0);
+	  return;
       }
-    if (sect_name == NULL)
-	ret = rl2_build_all_section_pyramids (sqlite, cvg_name, forced_rebuild);
-    else
-	ret =
-	    rl2_build_section_pyramid (sqlite, cvg_name, sect_name,
-				       forced_rebuild);
-    if (ret != RL2_OK)
+
+/* creating/opening the external output file */
+    out = fopen (font_path, "wb");
+    if (out == NULL)
       {
+	  free (buffer);
 	  sqlite3_result_int (context, 0);
-	  if (transaction)
-	    {
-		/* invalidating the pending transaction */
-		sqlite3_exec (sqlite, "ROLLBACK", NULL, NULL, NULL);
-	    }
 	  return;
       }
-    if (transaction)
+/* exporting the Font */
+    wr = fwrite (buffer, 1, buf_size, out);
+    if (wr != buf_size)
       {
-	  /* committing the still pending transaction */
-	  ret = sqlite3_exec (sqlite, "COMMIT", NULL, NULL, NULL);
-	  if (ret != SQLITE_OK)
-	    {
-		sqlite3_result_int (context, -1);
-		return;
-	    }
+	  free (buffer);
+	  fclose (out);
+	  sqlite3_result_int (context, 0);
+	  return;
       }
+    free (buffer);
+    fclose (out);
     sqlite3_result_int (context, 1);
 }
 
 static void
-fnct_PyramidizeMonolithic (sqlite3_context * context, int argc,
-			   sqlite3_value ** argv)
+fnct_IsValidFont (sqlite3_context * context, int argc, sqlite3_value ** argv)
 {
 /* SQL function:
-/ PyramidizeMonolithic(text coverage)
-/ PyramidizeMonolithic(text coverage, int virt_levels)
-/ PyramidizeMonolithic(text coverage, int virt_levels, int transaction)
+/ IsValidFont(BLOB serialized-font)
 /
 / will return 1 (TRUE, success) or 0 (FALSE, failure)
 / or -1 (INVALID ARGS)
 /
 */
-    int err = 0;
-    const char *cvg_name;
-    int virt_levels = 0;
-    int transaction = 1;
-    sqlite3 *sqlite;
+    const unsigned char *blob = NULL;
+    int blob_sz;
     int ret;
     RL2_UNUSED ();		/* LCOV_EXCL_LINE */
 
-    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
-	err = 1;
-    if (argc > 1 && sqlite3_value_type (argv[1]) != SQLITE_INTEGER)
-	err = 1;
-    if (argc > 2 && sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
-	err = 1;
-    if (err)
+    if (sqlite3_value_type (argv[0]) != SQLITE_BLOB)
       {
 	  sqlite3_result_int (context, -1);
 	  return;
       }
-/* attempting to (re)build Pyramid levels */
-    sqlite = sqlite3_context_db_handle (context);
-    cvg_name = (const char *) sqlite3_value_text (argv[0]);
-    if (argc > 1)
-	virt_levels = sqlite3_value_int (argv[1]);
-    if (argc > 2)
-	transaction = sqlite3_value_int (argv[2]);
-    if (transaction)
-      {
-	  /* starting a DBMS Transaction */
-	  ret = sqlite3_exec (sqlite, "BEGIN", NULL, NULL, NULL);
-	  if (ret != SQLITE_OK)
-	    {
-		sqlite3_result_int (context, -1);
-		return;
-	    }
-      }
-    ret = rl2_build_monolithic_pyramid (sqlite, cvg_name, virt_levels);
-    if (ret != RL2_OK)
-      {
-	  sqlite3_result_int (context, 0);
-	  if (transaction)
-	    {
-		/* invalidating the pending transaction */
-		sqlite3_exec (sqlite, "ROLLBACK", NULL, NULL, NULL);
-	    }
-	  return;
-      }
-    if (transaction)
-      {
-	  /* committing the still pending transaction */
-	  ret = sqlite3_exec (sqlite, "COMMIT", NULL, NULL, NULL);
-	  if (ret != SQLITE_OK)
-	    {
-		sqlite3_result_int (context, -1);
-		return;
-	    }
-      }
-    sqlite3_result_int (context, 1);
+
+    blob = (const unsigned char *) sqlite3_value_blob (argv[0]);
+    blob_sz = sqlite3_value_bytes (argv[0]);
+    ret = rl2_is_valid_encoded_font (blob, blob_sz);
+    if (ret == RL2_OK)
+	sqlite3_result_int (context, 1);
+    else
+	sqlite3_result_int (context, 0);
 }
 
 static void
-fnct_DePyramidize (sqlite3_context * context, int argc, sqlite3_value ** argv)
+fnct_CheckFontFacename (sqlite3_context * context, int argc,
+			sqlite3_value ** argv)
 {
 /* SQL function:
-/ DePyramidize(text coverage)
-/ DePyramidize(text coverage, text section)
-/ DePyramidize(text coverage, text section, int transaction)
+/ CheckFontFacename(TEXT facename, BLOB serialized-font)
+/
+/ checks for a matching facename
 /
 / will return 1 (TRUE, success) or 0 (FALSE, failure)
 / or -1 (INVALID ARGS)
 /
 */
-    int err = 0;
-    const char *cvg_name;
-    const char *sect_name = NULL;
-    int transaction = 1;
-    sqlite3 *sqlite;
-    int ret;
+    const unsigned char *blob = NULL;
+    int blob_sz;
+    const char *facename1;
+    char *facename2;
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+
+    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+    facename1 = (const char *) sqlite3_value_text (argv[0]);
+    if (sqlite3_value_type (argv[1]) != SQLITE_BLOB)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+
+    blob = (const unsigned char *) sqlite3_value_blob (argv[1]);
+    blob_sz = sqlite3_value_bytes (argv[1]);
+    facename2 = rl2_get_encoded_font_facename (blob, blob_sz);
+    if (facename2 == NULL)
+	sqlite3_result_int (context, -1);
+    else
+      {
+	  if (strcmp (facename1, facename2) == 0)
+	      sqlite3_result_int (context, 1);
+	  else
+	      sqlite3_result_int (context, 0);
+	  free (facename2);
+      }
+}
+
+static void
+fnct_GetFontFamily (sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+/* SQL function:
+/ GetFontFamily(BLOB serialized-font)
+/
+/ will return the Font Family name (e.g. Roboto)
+/ or NULL (INVALID ARGS)
+/
+*/
+    const unsigned char *blob = NULL;
+    int blob_sz;
+    char *family_name;
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+
+    if (sqlite3_value_type (argv[0]) != SQLITE_BLOB)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+
+    blob = (const unsigned char *) sqlite3_value_blob (argv[0]);
+    blob_sz = sqlite3_value_bytes (argv[0]);
+    family_name = rl2_get_encoded_font_family (blob, blob_sz);
+    if (family_name == NULL)
+	sqlite3_result_null (context);
+    else
+	sqlite3_result_text (context, family_name, strlen (family_name), free);
+}
+
+static void
+fnct_GetFontFacename (sqlite3_context * context, int argc,
+		      sqlite3_value ** argv)
+{
+/* SQL function:
+/ GetFontFacename(BLOB serialized-font)
+/
+/ will return the Font facename (e.g. Roboto-BoldItalic)
+/ or NULL (INVALID ARGS)
+/
+*/
+    const unsigned char *blob = NULL;
+    int blob_sz;
+    char *facename;
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+
+    if (sqlite3_value_type (argv[0]) != SQLITE_BLOB)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+
+    blob = (const unsigned char *) sqlite3_value_blob (argv[0]);
+    blob_sz = sqlite3_value_bytes (argv[0]);
+    facename = rl2_get_encoded_font_facename (blob, blob_sz);
+    if (facename == NULL)
+	sqlite3_result_null (context);
+    else
+	sqlite3_result_text (context, facename, strlen (facename), free);
+}
+
+static void
+fnct_IsFontBold (sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+/* SQL function:
+/ IsFontBold(BLOB serialized-font)
+/
+/ will return 1 (TRUE, success) or 0 (FALSE, failure)
+/ or -1 (INVALID ARGS)
+/
+*/
+    const unsigned char *blob = NULL;
+    int blob_sz;
+    int ret;
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+
+    if (sqlite3_value_type (argv[0]) != SQLITE_BLOB)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+
+    blob = (const unsigned char *) sqlite3_value_blob (argv[0]);
+    blob_sz = sqlite3_value_bytes (argv[0]);
+    ret = rl2_is_encoded_font_bold (blob, blob_sz);
+    sqlite3_result_int (context, ret);
+}
+
+static void
+fnct_IsFontItalic (sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+/* SQL function:
+/ IsFontItalic(BLOB serialized-font)
+/
+/ will return 1 (TRUE, success) or 0 (FALSE, failure)
+/ or -1 (INVALID ARGS)
+/
+*/
+    const unsigned char *blob = NULL;
+    int blob_sz;
+    int ret;
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+
+    if (sqlite3_value_type (argv[0]) != SQLITE_BLOB)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+
+    blob = (const unsigned char *) sqlite3_value_blob (argv[0]);
+    blob_sz = sqlite3_value_bytes (argv[0]);
+    ret = rl2_is_encoded_font_italic (blob, blob_sz);
+    sqlite3_result_int (context, ret);
+}
+
+static void
+fnct_LoadRaster (sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+/* SQL function:
+/ LoadRaster(text coverage, text path_to_raster)
+/ LoadRaster(text coverage, text path_to_raster, int with_worldfile)
+/ LoadRaster(text coverage, text path_to_raster, int with_worldfile,
+/            int force_srid)
+/ LoadRaster(text coverage, text path_to_raster, int with_worldfile,
+/            int force_srid, int pyramidize)
+/ LoadRaster(text coverage, text path_to_raster, int with_worldfile,
+/            int force_srid, int pyramidize, int transaction)
+/
+/ will return 1 (TRUE, success) or 0 (FALSE, failure)
+/ or -1 (INVALID ARGS)
+/
+*/
+    int err = 0;
+    const char *cvg_name;
+    const char *path;
+    int worldfile = 0;
+    int force_srid = -1;
+    int transaction = 1;
+    int pyramidize = 1;
+    rl2CoveragePtr coverage = NULL;
+    sqlite3 *sqlite;
+    int ret;
+    const void *data;
+    int max_threads = 1;
     RL2_UNUSED ();		/* LCOV_EXCL_LINE */
 
     if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
 	err = 1;
-    if (argc > 1 && sqlite3_value_type (argv[1]) != SQLITE_TEXT
-	&& sqlite3_value_type (argv[1]) != SQLITE_NULL)
+    if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
 	err = 1;
     if (argc > 2 && sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
 	err = 1;
+    if (argc > 3 && sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+	err = 1;
+    if (argc > 4 && sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
+	err = 1;
+    if (argc > 5 && sqlite3_value_type (argv[5]) != SQLITE_INTEGER)
+	err = 1;
     if (err)
       {
 	  sqlite3_result_int (context, -1);
 	  return;
       }
-/* attempting to delete all Pyramid levels */
-    sqlite = sqlite3_context_db_handle (context);
+
+/* retrieving the arguments */
     cvg_name = (const char *) sqlite3_value_text (argv[0]);
-    if (argc > 1)
+    path = (const char *) sqlite3_value_text (argv[1]);
+    if (argc > 2)
+	worldfile = sqlite3_value_int (argv[2]);
+    if (argc > 3)
+	force_srid = sqlite3_value_int (argv[3]);
+    if (argc > 4)
+	pyramidize = sqlite3_value_int (argv[4]);
+    if (argc > 5)
+	transaction = sqlite3_value_int (argv[5]);
+
+/* attempting to load the Coverage definitions from the DBMS */
+    sqlite = sqlite3_context_db_handle (context);
+    data = sqlite3_user_data (context);
+    if (data != NULL)
       {
-	  if (sqlite3_value_type (argv[1]) == SQLITE_TEXT)
-	      sect_name = (const char *) sqlite3_value_text (argv[1]);
+	  struct rl2_private_data *priv_data = (struct rl2_private_data *) data;
+	  max_threads = priv_data->max_threads;
+	  if (max_threads < 1)
+	      max_threads = 1;
+	  if (max_threads > 64)
+	      max_threads = 64;
       }
-    if (argc > 2)
-	transaction = sqlite3_value_int (argv[2]);
+    coverage = rl2_create_coverage_from_dbms (sqlite, cvg_name);
+    if (coverage == NULL)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+
+/* attempting to load the Raster into the DBMS */
     if (transaction)
       {
 	  /* starting a DBMS Transaction */
 	  ret = sqlite3_exec (sqlite, "BEGIN", NULL, NULL, NULL);
 	  if (ret != SQLITE_OK)
 	    {
+		rl2_destroy_coverage (coverage);
 		sqlite3_result_int (context, -1);
 		return;
 	    }
       }
-    if (sect_name == NULL)
-	ret = rl2_delete_all_pyramids (sqlite, cvg_name);
-    else
-	ret = rl2_delete_section_pyramid (sqlite, cvg_name, sect_name);
+    ret = rl2_load_raster_into_dbms (sqlite, max_threads, path, coverage,
+				     worldfile, force_srid, pyramidize, 0);
+    rl2_destroy_coverage (coverage);
     if (ret != RL2_OK)
       {
 	  sqlite3_result_int (context, 0);
@@ -2751,35 +3291,22 @@ fnct_DePyramidize (sqlite3_context * context, int argc, sqlite3_value ** argv)
 }
 
 static void
-fnct_LoadRasterFromWMS (sqlite3_context * context, int argc,
-			sqlite3_value ** argv)
+fnct_LoadRastersFromDir (sqlite3_context * context, int argc,
+			 sqlite3_value ** argv)
 {
 /* SQL function:
-/ LoadRasterFromWMS(text coverage, text section, text getmap_url,
-/                   BLOB geom, text wms_version, text wms_layer, 
-/                   text wms_style, text wms_format, double res)
-/ LoadRasterFromWMS(text coverage, text section, text getmap_url,
-/                   BLOB geom, text wms_version, text wms_layer,
-/                   text wms_style, text wms_format, double horz_res, 
-/                   double vert_res)
-/ LoadRasterFromWMS(text coverage, text section, text getmap_url,
-/                   BLOB geom, text wms_version, text wms_layer, 
-/                   text wms_style, text wms_format, text wms_crs,
-/                   double horz_res, double vert_res, int opaque)
-/ LoadRasterFromWMS(text coverage, text section, text getmap_url,
-/                   BLOB geom, text wms_version, text wms_layer, 
-/                   text wms_style, text wms_format, double horz_res,
-/                   double vert_res, int opaque,
-/                   int swap_xy)
-/ LoadRasterFromWMS(text coverage, text section, text getmap_url,
-/                   BLOB geom, text wms_version, text wms_layer, 
-/                   text wms_style, text wms_format, double horz_res,
-/                   double vert_res, int opaque, int swap_xy, text proxy)
-/ LoadRasterFromWMS(text coverage, text section, text getmap_url,
-/                   BLOB geom, text wms_version, text wms_layer, 
-/                   text wms_style, text wms_format, double horz_res,
-/                   double vert_res,  int opaque, int swap_xy, 
-/                   text proxy, int transaction)
+/ LoadRastersFromDir(text coverage, text dir_path)
+/ LoadRastersFromDir(text coverage, text dir_path, text file_ext)
+/ LoadRastersFromDir(text coverage, text dir_path, text file_ext,
+/                    int with_worldfile)
+/ LoadRastersFromDir(text coverage, text dir_path, text file_ext,
+/                    int with_worldfile, int force_srid)
+/ LoadRastersFromDir(text coverage, text dir_path, text file_ext,
+/                    int with_worldfile, int force_srid, 
+/                    int pyramidize)
+/ LoadRastersFromDir(text coverage, text dir_path, text file_ext,
+/                    int with_worldfile, int force_srid, 
+/                    int pyramidize, int transaction)
 /
 / will return 1 (TRUE, success) or 0 (FALSE, failure)
 / or -1 (INVALID ARGS)
@@ -2787,100 +3314,32 @@ fnct_LoadRasterFromWMS (sqlite3_context * context, int argc,
 */
     int err = 0;
     const char *cvg_name;
-    const char *sect_name;
-    const char *url;
-    const char *proxy = NULL;
-    const char *wms_version;
-    const char *wms_layer;
-    const char *wms_style = NULL;
-    const char *wms_format;
-    char *wms_crs = NULL;
-    const unsigned char *blob;
-    int blob_sz;
-    double horz_res;
-    double vert_res;
-    int opaque = 0;
-    int swap_xy = 0;
-    int srid;
+    const char *path;
+    const char *file_ext = NULL;
+    int worldfile = 0;
+    int force_srid = -1;
     int transaction = 1;
-    double minx;
-    double maxx;
-    double miny;
-    double maxy;
-    int errcode = -1;
-    gaiaGeomCollPtr geom;
+    int pyramidize = 1;
     rl2CoveragePtr coverage = NULL;
-    rl2RasterStatisticsPtr section_stats = NULL;
     sqlite3 *sqlite;
     int ret;
-    int n;
-    double x;
-    double y;
-    double tilew;
-    double tileh;
-    unsigned int tile_width;
-    unsigned int tile_height;
-    WmsRetryListPtr retry_list = NULL;
-    char *table;
-    char *xtable;
-    char *sql;
-    sqlite3_stmt *stmt_data = NULL;
-    sqlite3_stmt *stmt_tils = NULL;
-    sqlite3_stmt *stmt_sect = NULL;
-    sqlite3_stmt *stmt_levl = NULL;
-    sqlite3_stmt *stmt_upd_sect = NULL;
-    int first = 1;
-    double ext_x;
-    double ext_y;
-    unsigned int width;
-    unsigned int height;
-    sqlite3_int64 section_id;
-    rl2PixelPtr no_data = NULL;
-    unsigned char sample_type;
-    unsigned char pixel_type;
-    unsigned char num_bands;
-    unsigned char compression;
-    int quality;
-    InsertWms params;
+    const void *data;
+    int max_threads;
     RL2_UNUSED ();		/* LCOV_EXCL_LINE */
 
     if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
 	err = 1;
     if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
 	err = 1;
-    if (sqlite3_value_type (argv[2]) != SQLITE_TEXT)
-	err = 1;
-    if (sqlite3_value_type (argv[3]) != SQLITE_BLOB)
-	err = 1;
-    if (sqlite3_value_type (argv[4]) != SQLITE_TEXT)
-	err = 1;
-    if (sqlite3_value_type (argv[5]) != SQLITE_TEXT)
-	err = 1;
-    if (sqlite3_value_type (argv[6]) != SQLITE_TEXT
-	&& sqlite3_value_type (argv[6]) != SQLITE_NULL)
-	err = 1;
-    if (sqlite3_value_type (argv[7]) != SQLITE_TEXT)
-	err = 1;
-    if (sqlite3_value_type (argv[8]) != SQLITE_INTEGER
-	&& sqlite3_value_type (argv[8]) != SQLITE_FLOAT)
+    if (argc > 2 && sqlite3_value_type (argv[2]) != SQLITE_TEXT)
 	err = 1;
-    if (argc > 9 && sqlite3_value_type (argv[9]) != SQLITE_INTEGER
-	&& sqlite3_value_type (argv[9]) != SQLITE_FLOAT)
+    if (argc > 3 && sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
 	err = 1;
-    if (argc > 10 && sqlite3_value_type (argv[10]) != SQLITE_INTEGER)
+    if (argc > 4 && sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
 	err = 1;
-    if (argc > 11 && sqlite3_value_type (argv[11]) != SQLITE_INTEGER)
+    if (argc > 5 && sqlite3_value_type (argv[5]) != SQLITE_INTEGER)
 	err = 1;
-    if (argc > 12)
-      {
-	  if (sqlite3_value_type (argv[12]) == SQLITE_TEXT)
-	      ;
-	  else if (sqlite3_value_type (argv[12]) == SQLITE_NULL)
-	      ;
-	  else
-	      err = 1;
-      }
-    if (argc > 13 && sqlite3_value_type (argv[13]) != SQLITE_INTEGER)
+    if (argc > 6 && sqlite3_value_type (argv[6]) != SQLITE_INTEGER)
 	err = 1;
     if (err)
       {
@@ -2888,355 +3347,235 @@ fnct_LoadRasterFromWMS (sqlite3_context * context, int argc,
 	  return;
       }
 
-/* retrieving all arguments */
+/* retrieving the arguments */
     cvg_name = (const char *) sqlite3_value_text (argv[0]);
-    sect_name = (const char *) sqlite3_value_text (argv[1]);
-    url = (const char *) sqlite3_value_text (argv[2]);
-    blob = sqlite3_value_blob (argv[3]);
-    blob_sz = sqlite3_value_bytes (argv[3]);
-    wms_version = (const char *) sqlite3_value_text (argv[4]);
-    wms_layer = (const char *) sqlite3_value_text (argv[5]);
-    if (sqlite3_value_type (argv[6]) == SQLITE_TEXT)
-	wms_style = (const char *) sqlite3_value_text (argv[6]);
-    wms_format = (const char *) sqlite3_value_text (argv[7]);
-    if (sqlite3_value_type (argv[8]) == SQLITE_INTEGER)
-      {
-	  int ival = sqlite3_value_int (argv[8]);
-	  horz_res = ival;
-      }
-    else
-	horz_res = sqlite3_value_double (argv[8]);
-    if (argc > 9)
-      {
-	  if (sqlite3_value_type (argv[9]) == SQLITE_INTEGER)
-	    {
-		int ival = sqlite3_value_int (argv[9]);
-		vert_res = ival;
-	    }
-	  else
-	      vert_res = sqlite3_value_double (argv[9]);
-      }
-    else
-	vert_res = horz_res;
-    if (argc > 10)
-	opaque = sqlite3_value_int (argv[10]);
-    if (argc > 11)
-	swap_xy = sqlite3_value_int (argv[11]);
-    if (argc > 12 && sqlite3_value_type (argv[12]) == SQLITE_TEXT)
-	proxy = (const char *) sqlite3_value_text (argv[12]);
-    if (argc > 13)
-	transaction = sqlite3_value_int (argv[13]);
-
-/* checking the Geometry */
-    geom = gaiaFromSpatiaLiteBlobWkb (blob, blob_sz);
-    if (geom == NULL)
-      {
-	  errcode = -1;
-	  goto error;
-      }
-/* retrieving the BBOX */
-    minx = geom->MinX;
-    maxx = geom->MaxX;
-    miny = geom->MinY;
-    maxy = geom->MaxY;
-    gaiaFreeGeomColl (geom);
+    path = (const char *) sqlite3_value_text (argv[1]);
+    if (argc > 2)
+	file_ext = (const char *) sqlite3_value_text (argv[2]);
+    if (argc > 3)
+	worldfile = sqlite3_value_int (argv[3]);
+    if (argc > 4)
+	force_srid = sqlite3_value_int (argv[4]);
+    if (argc > 5)
+	pyramidize = sqlite3_value_int (argv[5]);
+    if (argc > 6)
+	transaction = sqlite3_value_int (argv[6]);
 
 /* attempting to load the Coverage definitions from the DBMS */
     sqlite = sqlite3_context_db_handle (context);
+    data = sqlite3_user_data (context);
+    if (data != NULL)
+      {
+	  struct rl2_private_data *priv_data = (struct rl2_private_data *) data;
+	  max_threads = priv_data->max_threads;
+	  if (max_threads < 1)
+	      max_threads = 1;
+	  if (max_threads > 64)
+	      max_threads = 64;
+      }
     coverage = rl2_create_coverage_from_dbms (sqlite, cvg_name);
     if (coverage == NULL)
       {
 	  sqlite3_result_int (context, -1);
 	  return;
       }
-    if (rl2_get_coverage_tile_size (coverage, &tile_width, &tile_height) !=
-	RL2_OK)
+
+/* attempting to load the Rasters into the DBMS */
+    if (transaction)
       {
-	  sqlite3_result_int (context, -1);
-	  return;
+	  /* starting a DBMS Transaction */
+	  ret = sqlite3_exec (sqlite, "BEGIN", NULL, NULL, NULL);
+	  if (ret != SQLITE_OK)
+	    {
+		rl2_destroy_coverage (coverage);
+		sqlite3_result_int (context, -1);
+		return;
+	    }
       }
-    if (rl2_get_coverage_srid (coverage, &srid) != RL2_OK)
+    ret =
+	rl2_load_mrasters_into_dbms (sqlite, max_threads, path, file_ext,
+				     coverage, worldfile, force_srid,
+				     pyramidize, 0);
+    rl2_destroy_coverage (coverage);
+    if (ret != RL2_OK)
       {
-	  sqlite3_result_int (context, -1);
+	  sqlite3_result_int (context, 0);
+	  if (transaction)
+	    {
+		/* invalidating the pending transaction */
+		sqlite3_exec (sqlite, "ROLLBACK", NULL, NULL, NULL);
+	    }
 	  return;
       }
-    if (rl2_get_coverage_type (coverage, &sample_type, &pixel_type, &num_bands)
-	!= RL2_OK)
+    if (transaction)
       {
-	  sqlite3_result_int (context, -1);
-	  return;
+	  /* committing the still pending transaction */
+	  ret = sqlite3_exec (sqlite, "COMMIT", NULL, NULL, NULL);
+	  if (ret != SQLITE_OK)
+	    {
+		sqlite3_result_int (context, -1);
+		return;
+	    }
       }
-    no_data = rl2_get_coverage_no_data (coverage);
-    if (rl2_get_coverage_compression (coverage, &compression, &quality)
-	!= RL2_OK)
+    sqlite3_result_int (context, 1);
+}
+
+static void
+fnct_Pyramidize (sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+/* SQL function:
+/ Pyramidize(text coverage)
+/ Pyramidize(text coverage, integer section_id)
+/ Pyramidize(text coverage, integer section_id, int force_rebuild)
+/ Pyramidize(text coverage, integer section_id, int force_rebuild,
+/            int transaction)
+/
+/ will return 1 (TRUE, success) or 0 (FALSE, failure)
+/ or -1 (INVALID ARGS)
+/
+*/
+    int err = 0;
+    const char *cvg_name;
+    sqlite3_int64 section_id = 0;
+    int null_id = 1;
+    int forced_rebuild = 0;
+    int transaction = 1;
+    sqlite3 *sqlite;
+    int ret;
+    const void *data;
+    int max_threads = 1;
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+
+    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	err = 1;
+    if (argc > 1 && sqlite3_value_type (argv[1]) != SQLITE_INTEGER
+	&& sqlite3_value_type (argv[1]) != SQLITE_NULL)
+	err = 1;
+    if (argc > 2 && sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
+	err = 1;
+    if (argc > 3 && sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+	err = 1;
+    if (err)
       {
 	  sqlite3_result_int (context, -1);
 	  return;
       }
-
-    tilew = (double) tile_width *horz_res;
-    tileh = (double) tile_height *vert_res;
-    ext_x = maxx - minx;
-    ext_y = maxy - miny;
-    width = ext_x / horz_res;
-    height = ext_y / horz_res;
-    if (((double) width * horz_res) < ext_x)
-	width++;
-    if (((double) height * vert_res) < ext_y)
-	height++;
-    if (width < tile_width || width > UINT16_MAX)
+/* attempting to (re)build Pyramid levels */
+    sqlite = sqlite3_context_db_handle (context);
+    data = sqlite3_user_data (context);
+    if (data != NULL)
       {
-	  sqlite3_result_int (context, -1);
-	  return;
+	  struct rl2_private_data *priv_data = (struct rl2_private_data *) data;
+	  max_threads = priv_data->max_threads;
+	  if (max_threads < 1)
+	      max_threads = 1;
+	  if (max_threads > 64)
+	      max_threads = 64;
       }
-    if (height < tile_height || height > UINT16_MAX)
+    cvg_name = (const char *) sqlite3_value_text (argv[0]);
+    if (argc > 1)
       {
-	  sqlite3_result_int (context, -1);
-	  return;
+	  if (sqlite3_value_type (argv[1]) == SQLITE_INTEGER)
+	    {
+		section_id = sqlite3_value_int64 (argv[1]);
+		null_id = 0;
+	    }
       }
-
+    if (argc > 2)
+	forced_rebuild = sqlite3_value_int (argv[2]);
+    if (argc > 3)
+	transaction = sqlite3_value_int (argv[3]);
     if (transaction)
       {
 	  /* starting a DBMS Transaction */
 	  ret = sqlite3_exec (sqlite, "BEGIN", NULL, NULL, NULL);
 	  if (ret != SQLITE_OK)
 	    {
-		rl2_destroy_coverage (coverage);
 		sqlite3_result_int (context, -1);
 		return;
 	    }
       }
-
-/* SQL prepared statements */
-    table = sqlite3_mprintf ("%s_sections", cvg_name);
-    xtable = gaiaDoubleQuotedSql (table);
-    sqlite3_free (table);
-    sql =
-	sqlite3_mprintf
-	("INSERT INTO \"%s\" (section_id, section_name, file_path, "
-	 "width, height, geometry) VALUES (NULL, ?, ?, ?, ?, ?)", xtable);
-    free (xtable);
-    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt_sect, NULL);
-    sqlite3_free (sql);
-    if (ret != SQLITE_OK)
+    if (null_id)
+	ret =
+	    rl2_build_all_section_pyramids (sqlite, max_threads, cvg_name,
+					    forced_rebuild, 1);
+    else
+	ret =
+	    rl2_build_section_pyramid (sqlite, max_threads, cvg_name,
+				       section_id, forced_rebuild, 1);
+    if (ret != RL2_OK)
       {
-	  printf ("INSERT INTO sections SQL error: %s\n",
-		  sqlite3_errmsg (sqlite));
-	  goto error;
+	  sqlite3_result_int (context, 0);
+	  if (transaction)
+	    {
+		/* invalidating the pending transaction */
+		sqlite3_exec (sqlite, "ROLLBACK", NULL, NULL, NULL);
+	    }
+	  return;
       }
-
-    table = sqlite3_mprintf ("%s_sections", cvg_name);
-    xtable = gaiaDoubleQuotedSql (table);
-    sqlite3_free (table);
-    sql =
-	sqlite3_mprintf
-	("UPDATE \"%s\" SET statistics = ? WHERE section_id = ?", xtable);
-    free (xtable);
-    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt_upd_sect, NULL);
-    sqlite3_free (sql);
-    if (ret != SQLITE_OK)
+    if (transaction)
       {
-	  printf ("UPDATE sections SQL error: %s\n", sqlite3_errmsg (sqlite));
-	  goto error;
+	  /* committing the still pending transaction */
+	  ret = sqlite3_exec (sqlite, "COMMIT", NULL, NULL, NULL);
+	  if (ret != SQLITE_OK)
+	    {
+		sqlite3_result_int (context, -1);
+		return;
+	    }
       }
+    sqlite3_result_int (context, 1);
+}
 
-    table = sqlite3_mprintf ("%s_levels", cvg_name);
-    xtable = gaiaDoubleQuotedSql (table);
-    sqlite3_free (table);
-    sql =
-	sqlite3_mprintf
-	("INSERT OR IGNORE INTO \"%s\" (pyramid_level, "
-	 "x_resolution_1_1, y_resolution_1_1, "
-	 "x_resolution_1_2, y_resolution_1_2, x_resolution_1_4, "
-	 "y_resolution_1_4, x_resolution_1_8, y_resolution_1_8) "
-	 "VALUES (0, ?, ?, ?, ?, ?, ?, ?, ?)", xtable);
-    free (xtable);
-    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt_levl, NULL);
-    sqlite3_free (sql);
-    if (ret != SQLITE_OK)
-      {
-	  printf ("INSERT INTO levels SQL error: %s\n",
-		  sqlite3_errmsg (sqlite));
-	  goto error;
-      }
-
-    table = sqlite3_mprintf ("%s_tiles", cvg_name);
-    xtable = gaiaDoubleQuotedSql (table);
-    sqlite3_free (table);
-    sql =
-	sqlite3_mprintf
-	("INSERT INTO \"%s\" (tile_id, pyramid_level, section_id, geometry) "
-	 "VALUES (NULL, 0, ?, ?)", xtable);
-    free (xtable);
-    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt_tils, NULL);
-    sqlite3_free (sql);
-    if (ret != SQLITE_OK)
-      {
-	  printf ("INSERT INTO tiles SQL error: %s\n", sqlite3_errmsg (sqlite));
-	  goto error;
-      }
-
-    table = sqlite3_mprintf ("%s_tile_data", cvg_name);
-    xtable = gaiaDoubleQuotedSql (table);
-    sqlite3_free (table);
-    sql =
-	sqlite3_mprintf
-	("INSERT INTO \"%s\" (tile_id, tile_data_odd, tile_data_even) "
-	 "VALUES (?, ?, ?)", xtable);
-    free (xtable);
-    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt_data, NULL);
-    sqlite3_free (sql);
-    if (ret != SQLITE_OK)
-      {
-	  printf ("INSERT INTO tile_data SQL error: %s\n",
-		  sqlite3_errmsg (sqlite));
-	  goto error;
-      }
+static void
+fnct_PyramidizeMonolithic (sqlite3_context * context, int argc,
+			   sqlite3_value ** argv)
+{
+/* SQL function:
+/ PyramidizeMonolithic(text coverage)
+/ PyramidizeMonolithic(text coverage, int virt_levels)
+/ PyramidizeMonolithic(text coverage, int virt_levels, int transaction)
+/
+/ will return 1 (TRUE, success) or 0 (FALSE, failure)
+/ or -1 (INVALID ARGS)
+/
+*/
+    int err = 0;
+    const char *cvg_name;
+    int virt_levels = 0;
+    int transaction = 1;
+    sqlite3 *sqlite;
+    int ret;
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
 
-/* preparing the WMS requests */
-    wms_crs = sqlite3_mprintf ("EPSG:%d", srid);
-    tilew = (double) tile_width *horz_res;
-    tileh = (double) tile_height *vert_res;
-    ext_x = maxx - minx;
-    ext_y = maxy - miny;
-    width = ext_x / horz_res;
-    height = ext_y / horz_res;
-    if ((width * horz_res) < ext_x)
-	width++;
-    if ((height * vert_res) < ext_y)
-	height++;
-    retry_list = alloc_retry_list ();
-    for (y = maxy; y > miny; y -= tileh)
+    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	err = 1;
+    if (argc > 1 && sqlite3_value_type (argv[1]) != SQLITE_INTEGER)
+	err = 1;
+    if (argc > 2 && sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
+	err = 1;
+    if (err)
       {
-	  for (x = minx; x < maxx; x += tilew)
-	    {
-		char *err_msg = NULL;
-		unsigned char *rgba_tile =
-		    do_wms_GetMap_get (NULL, url, proxy, wms_version, wms_layer,
-				       wms_crs, swap_xy, x, y - tileh,
-				       x + tilew, y, tile_width, tile_height,
-				       wms_style, wms_format, opaque, 0,
-				       &err_msg);
-		if (rgba_tile == NULL)
-		  {
-		      add_retry (retry_list, x, y - tileh, x + tilew, y);
-		      continue;
-		  }
-
-		params.sqlite = sqlite;
-		params.rgba_tile = rgba_tile;
-		params.coverage = coverage;
-		params.sect_name = sect_name;
-		params.x = x;
-		params.y = y;
-		params.width = width;
-		params.height = height;
-		params.tilew = tilew;
-		params.tileh = tileh;
-		params.srid = srid;
-		params.minx = minx;
-		params.miny = miny;
-		params.maxx = maxx;
-		params.maxy = maxy;
-		params.sample_type = sample_type;
-		params.num_bands = num_bands;
-		params.compression = compression;
-		params.horz_res = horz_res;
-		params.vert_res = vert_res;
-		params.tile_width = tile_width;
-		params.tile_height = tile_height;
-		params.no_data = no_data;
-		params.stmt_sect = stmt_sect;
-		params.stmt_levl = stmt_levl;
-		params.stmt_tils = stmt_tils;
-		params.stmt_data = stmt_data;
-		if (!insert_wms_tile
-		    (&params, &first, &section_stats, &section_id))
-		    goto error;
-	    }
+	  sqlite3_result_int (context, -1);
+	  return;
       }
-    for (n = 0; n < 5; n++)
+/* attempting to (re)build Pyramid levels */
+    sqlite = sqlite3_context_db_handle (context);
+    cvg_name = (const char *) sqlite3_value_text (argv[0]);
+    if (argc > 1)
+	virt_levels = sqlite3_value_int (argv[1]);
+    if (argc > 2)
+	transaction = sqlite3_value_int (argv[2]);
+    if (transaction)
       {
-	  WmsRetryItemPtr retry = retry_list->first;
-	  while (retry != NULL)
+	  /* starting a DBMS Transaction */
+	  ret = sqlite3_exec (sqlite, "BEGIN", NULL, NULL, NULL);
+	  if (ret != SQLITE_OK)
 	    {
-		char *err_msg = NULL;
-		unsigned char *rgba_tile = NULL;
-		if (retry->done)
-		  {
-		      retry = retry->next;
-		      continue;
-		  }
-		retry->count += 1;
-		rgba_tile =
-		    do_wms_GetMap_get (NULL, url, proxy, wms_version, wms_layer,
-				       wms_crs, swap_xy, retry->minx,
-				       retry->miny, retry->maxx, retry->maxy,
-				       tile_width, tile_height, wms_style,
-				       wms_format, opaque, 0, &err_msg);
-		if (rgba_tile == NULL)
-		  {
-		      retry = retry->next;
-		      continue;
-		  }
-
-		params.sqlite = sqlite;
-		params.rgba_tile = rgba_tile;
-		params.coverage = coverage;
-		params.sect_name = sect_name;
-		params.x = x;
-		params.y = y;
-		params.width = width;
-		params.height = height;
-		params.tilew = tilew;
-		params.tileh = tileh;
-		params.srid = srid;
-		params.minx = minx;
-		params.miny = miny;
-		params.maxx = maxx;
-		params.maxy = maxy;
-		params.sample_type = sample_type;
-		params.num_bands = num_bands;
-		params.compression = compression;
-		params.horz_res = horz_res;
-		params.vert_res = vert_res;
-		params.tile_width = tile_width;
-		params.tile_height = tile_height;
-		params.no_data = no_data;
-		params.stmt_sect = stmt_sect;
-		params.stmt_levl = stmt_levl;
-		params.stmt_tils = stmt_tils;
-		params.stmt_data = stmt_data;
-		if (!insert_wms_tile
-		    (&params, &first, &section_stats, &section_id))
-		    goto error;
-		retry->done = 1;
-		retry = retry->next;
+		sqlite3_result_int (context, -1);
+		return;
 	    }
       }
-
-    if (!do_insert_stats (sqlite, section_stats, section_id, stmt_upd_sect))
-	goto error;
-    free_retry_list (retry_list);
-    retry_list = NULL;
-    sqlite3_free (wms_crs);
-    wms_crs = NULL;
-
-    sqlite3_finalize (stmt_upd_sect);
-    sqlite3_finalize (stmt_sect);
-    sqlite3_finalize (stmt_levl);
-    sqlite3_finalize (stmt_tils);
-    sqlite3_finalize (stmt_data);
-    stmt_upd_sect = NULL;
-    stmt_sect = NULL;
-    stmt_levl = NULL;
-    stmt_tils = NULL;
-    stmt_data = NULL;
-
-    rl2_destroy_raster_statistics (section_stats);
-    section_stats = NULL;
-    rl2_destroy_coverage (coverage);
-    coverage = NULL;
+    ret = rl2_build_monolithic_pyramid (sqlite, cvg_name, virt_levels, 1);
     if (ret != RL2_OK)
       {
 	  sqlite3_result_int (context, 0);
@@ -3247,13 +3586,6 @@ fnct_LoadRasterFromWMS (sqlite3_context * context, int argc,
 	    }
 	  return;
       }
-
-    if (rl2_update_dbms_coverage (sqlite, cvg_name) != RL2_OK)
-      {
-	  fprintf (stderr, "unable to update the Coverage\n");
-	  goto error;
-      }
-
     if (transaction)
       {
 	  /* committing the still pending transaction */
@@ -3265,50 +3597,15 @@ fnct_LoadRasterFromWMS (sqlite3_context * context, int argc,
 	    }
       }
     sqlite3_result_int (context, 1);
-    return;
-
-  error:
-    if (wms_crs != NULL)
-	sqlite3_free (wms_crs);
-    if (stmt_upd_sect != NULL)
-	sqlite3_finalize (stmt_upd_sect);
-    if (stmt_sect != NULL)
-	sqlite3_finalize (stmt_sect);
-    if (stmt_levl != NULL)
-	sqlite3_finalize (stmt_levl);
-    if (stmt_tils != NULL)
-	sqlite3_finalize (stmt_tils);
-    if (stmt_data != NULL)
-	sqlite3_finalize (stmt_data);
-    if (retry_list != NULL)
-	free_retry_list (retry_list);
-    if (coverage != NULL)
-	rl2_destroy_coverage (coverage);
-    if (section_stats != NULL)
-	rl2_destroy_raster_statistics (section_stats);
-    sqlite3_result_int (context, errcode);
 }
 
 static void
-fnct_WriteGeoTiff (sqlite3_context * context, int argc, sqlite3_value ** argv)
+fnct_DePyramidize (sqlite3_context * context, int argc, sqlite3_value ** argv)
 {
 /* SQL function:
-/ WriteGeoTiff(text coverage, text geotiff_path, int width,
-/              int height, BLOB geom, double resolution)
-/ WriteGeoTiff(text coverage, text geotiff_path, int width,
-/              int height, BLOB geom, double horz_res,
-/              double vert_res)
-/ WriteGeoTiff(text coverage, text geotiff_path, int width,
-/              int height, BLOB geom, double horz_res,
-/              double vert_res, int with_worldfile)
-/ WriteGeoTiff(text coverage, text geotiff_path, int width,
-/              int height, BLOB geom, double horz_res,
-/              double vert_res, int with_worldfile,
-/              text compression)
-/ WriteGeoTiff(text coverage, text geotiff_path, int width,
-/              int height, BLOB geom, double horz_res,
-/              double vert_res, int with_worldfile,
-/              text compression, int tile_sz)
+/ DePyramidize(text coverage)
+/ DePyramidize(text coverage, integer section)
+/ DePyramidize(text coverage, integer section, int transaction)
 /
 / will return 1 (TRUE, success) or 0 (FALSE, failure)
 / or -1 (INVALID ARGS)
@@ -3316,204 +3613,105 @@ fnct_WriteGeoTiff (sqlite3_context * context, int argc, sqlite3_value ** argv)
 */
     int err = 0;
     const char *cvg_name;
-    const char *path;
-    int width;
-    int height;
-    const unsigned char *blob;
-    int blob_sz;
-    double horz_res;
-    double vert_res;
-    int worldfile = 0;
-    unsigned char compression = RL2_COMPRESSION_NONE;
-    int tile_sz = 256;
-    rl2CoveragePtr coverage = NULL;
+    sqlite3_int64 section_id = 0;
+    int null_id = 1;
+    int transaction = 1;
     sqlite3 *sqlite;
     int ret;
-    int errcode = -1;
-    gaiaGeomCollPtr geom;
-    double minx;
-    double maxx;
-    double miny;
-    double maxy;
     RL2_UNUSED ();		/* LCOV_EXCL_LINE */
 
     if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
 	err = 1;
-    if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
-	err = 1;
-    if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
-	err = 1;
-    if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
-	err = 1;
-    if (sqlite3_value_type (argv[4]) != SQLITE_BLOB)
-	err = 1;
-    if (sqlite3_value_type (argv[5]) != SQLITE_INTEGER
-	&& sqlite3_value_type (argv[5]) != SQLITE_FLOAT)
-	err = 1;
-    if (argc > 6 && sqlite3_value_type (argv[6]) != SQLITE_INTEGER
-	&& sqlite3_value_type (argv[6]) != SQLITE_FLOAT)
-	err = 1;
-    if (argc > 7 && sqlite3_value_type (argv[7]) != SQLITE_INTEGER)
-	err = 1;
-    if (argc > 8 && sqlite3_value_type (argv[8]) != SQLITE_TEXT)
+    if (argc > 1 && sqlite3_value_type (argv[1]) != SQLITE_INTEGER
+	&& sqlite3_value_type (argv[1]) != SQLITE_NULL)
 	err = 1;
-    if (argc > 9 && sqlite3_value_type (argv[9]) != SQLITE_INTEGER)
+    if (argc > 2 && sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
 	err = 1;
     if (err)
       {
 	  sqlite3_result_int (context, -1);
 	  return;
       }
-
-/* retrieving all arguments */
+/* attempting to delete all Pyramid levels */
+    sqlite = sqlite3_context_db_handle (context);
     cvg_name = (const char *) sqlite3_value_text (argv[0]);
-    path = (const char *) sqlite3_value_text (argv[1]);
-    width = sqlite3_value_int (argv[2]);
-    height = sqlite3_value_int (argv[3]);
-    blob = sqlite3_value_blob (argv[4]);
-    blob_sz = sqlite3_value_bytes (argv[4]);
-    if (sqlite3_value_type (argv[5]) == SQLITE_INTEGER)
-      {
-	  int ival = sqlite3_value_int (argv[5]);
-	  horz_res = ival;
-      }
-    else
-	horz_res = sqlite3_value_double (argv[5]);
-    if (argc > 6)
+    if (argc > 1)
       {
-	  if (sqlite3_value_type (argv[6]) == SQLITE_INTEGER)
+	  if (sqlite3_value_type (argv[1]) == SQLITE_INTEGER)
 	    {
-		int ival = sqlite3_value_int (argv[6]);
-		vert_res = ival;
+		section_id = sqlite3_value_int64 (argv[1]);
+		null_id = 0;
 	    }
-	  else
-	      vert_res = sqlite3_value_double (argv[6]);
-      }
-    else
-	vert_res = horz_res;
-    if (argc > 7)
-	worldfile = sqlite3_value_int (argv[7]);
-    if (argc > 8)
-      {
-	  const char *compr = (const char *) sqlite3_value_text (argv[8]);
-	  compression = RL2_COMPRESSION_UNKNOWN;
-	  if (strcasecmp (compr, "NONE") == 0)
-	      compression = RL2_COMPRESSION_NONE;
-	  if (strcasecmp (compr, "DEFLATE") == 0)
-	      compression = RL2_COMPRESSION_DEFLATE;
-	  if (strcasecmp (compr, "LZW") == 0)
-	      compression = RL2_COMPRESSION_LZW;
-	  if (strcasecmp (compr, "JPEG") == 0)
-	      compression = RL2_COMPRESSION_JPEG;
-	  if (strcasecmp (compr, "FAX3") == 0)
-	      compression = RL2_COMPRESSION_CCITTFAX3;
-	  if (strcasecmp (compr, "FAX4") == 0)
-	      compression = RL2_COMPRESSION_CCITTFAX4;
-      }
-    if (argc > 9)
-	tile_sz = sqlite3_value_int (argv[9]);
-
-/* coarse args validation */
-    if (width < 0 || width > UINT16_MAX)
-      {
-	  errcode = -1;
-	  goto error;
-      }
-    if (height < 0 || height > UINT16_MAX)
-      {
-	  errcode = -1;
-	  goto error;
-      }
-    if (tile_sz < 64 || tile_sz > UINT16_MAX)
-      {
-	  errcode = -1;
-	  goto error;
-      }
-    if (compression == RL2_COMPRESSION_UNKNOWN)
-      {
-	  errcode = -1;
-	  goto error;
       }
-
-/* checking the Geometry */
-    geom = gaiaFromSpatiaLiteBlobWkb (blob, blob_sz);
-    if (geom == NULL)
-      {
-	  errcode = -1;
-	  goto error;
-      }
-    if (is_point (geom))
+    if (argc > 2)
+	transaction = sqlite3_value_int (argv[2]);
+    if (transaction)
       {
-	  /* assumed to be the GeoTiff Center Point */
-	  gaiaPointPtr pt = geom->FirstPoint;
-	  double ext_x = (double) width * horz_res;
-	  double ext_y = (double) height * vert_res;
-	  minx = pt->X - ext_x / 2.0;
-	  maxx = minx + ext_x;
-	  miny = pt->Y - ext_y / 2.0;
-	  maxy = miny + ext_y;
+	  /* starting a DBMS Transaction */
+	  ret = sqlite3_exec (sqlite, "BEGIN", NULL, NULL, NULL);
+	  if (ret != SQLITE_OK)
+	    {
+		sqlite3_result_int (context, -1);
+		return;
+	    }
       }
+    if (null_id)
+	ret = rl2_delete_all_pyramids (sqlite, cvg_name);
     else
+	ret = rl2_delete_section_pyramid (sqlite, cvg_name, section_id);
+    if (ret != RL2_OK)
       {
-	  /* assumed to be any possible Geometry defining a BBOX */
-	  minx = geom->MinX;
-	  maxx = geom->MaxX;
-	  miny = geom->MinY;
-	  maxy = geom->MaxY;
-      }
-    gaiaFreeGeomColl (geom);
-
-/* attempting to load the Coverage definitions from the DBMS */
-    sqlite = sqlite3_context_db_handle (context);
-    coverage = rl2_create_coverage_from_dbms (sqlite, cvg_name);
-    if (coverage == NULL)
-      {
-	  sqlite3_result_int (context, -1);
+	  sqlite3_result_int (context, 0);
+	  if (transaction)
+	    {
+		/* invalidating the pending transaction */
+		sqlite3_exec (sqlite, "ROLLBACK", NULL, NULL, NULL);
+	    }
 	  return;
       }
-
-    ret =
-	rl2_export_geotiff_from_dbms (sqlite, path, coverage, horz_res,
-				      vert_res, minx, miny, maxx, maxy, width,
-				      height, compression, tile_sz, worldfile);
-    if (ret != RL2_OK)
+    if (transaction)
       {
-	  errcode = 0;
-	  goto error;
+	  /* committing the still pending transaction */
+	  ret = sqlite3_exec (sqlite, "COMMIT", NULL, NULL, NULL);
+	  if (ret != SQLITE_OK)
+	    {
+		sqlite3_result_int (context, -1);
+		return;
+	    }
       }
-    rl2_destroy_coverage (coverage);
     sqlite3_result_int (context, 1);
-    return;
-
-  error:
-    if (coverage != NULL)
-	rl2_destroy_coverage (coverage);
-    sqlite3_result_int (context, errcode);
 }
 
 static void
-fnct_WriteTripleBandGeoTiff (sqlite3_context * context, int argc,
-			     sqlite3_value ** argv)
+fnct_LoadRasterFromWMS (sqlite3_context * context, int argc,
+			sqlite3_value ** argv)
 {
 /* SQL function:
-/ WriteTripleBandGeoTiff(text coverage, text geotiff_path, int width,
-/              int height, int red_band, int green_band, int blue_band,
-/              BLOB geom, double resolution)
-/ WriteTripleBandGeoTiff(text coverage, text geotiff_path, int width,
-/              int height, int red_band, int green_band, int blue_band, 
-/              BLOB geom, double horz_res, double vert_res)
-/ WriteTripleBandGeoTiff(text coverage, text geotiff_path, int width,
-/              int height, int red_band, int green_band, int blue_band,
-/              BLOB geom, double horz_res, double vert_res, 
-/              int with_worldfile)
-/ WriteTripleBandGeoTiff(text coverage, text geotiff_path, int width,
-/              int height, int red_band, int green_band, int blue_band, 
-/              BLOB geom, double horz_res, double vert_res, 
-/              int with_worldfile, text compression)
-/ WriteTripleBandGeoTiff(text coverage, text geotiff_path, int width,
-/              int height, int red_band, int green_band, int blue_band, 
-/              BLOB geom, double horz_res, double vert_res, 
-/              int with_worldfile, text compression, int tile_sz)
+/ LoadRasterFromWMS(text coverage, text section, text getmap_url,
+/                   BLOB geom, text wms_version, text wms_layer, 
+/                   text wms_style, text wms_format, double res)
+/ LoadRasterFromWMS(text coverage, text section, text getmap_url,
+/                   BLOB geom, text wms_version, text wms_layer,
+/                   text wms_style, text wms_format, double horz_res, 
+/                   double vert_res)
+/ LoadRasterFromWMS(text coverage, text section, text getmap_url,
+/                   BLOB geom, text wms_version, text wms_layer, 
+/                   text wms_style, text wms_format, text wms_crs,
+/                   double horz_res, double vert_res, int opaque)
+/ LoadRasterFromWMS(text coverage, text section, text getmap_url,
+/                   BLOB geom, text wms_version, text wms_layer, 
+/                   text wms_style, text wms_format, double horz_res,
+/                   double vert_res, int opaque,
+/                   int swap_xy)
+/ LoadRasterFromWMS(text coverage, text section, text getmap_url,
+/                   BLOB geom, text wms_version, text wms_layer, 
+/                   text wms_style, text wms_format, double horz_res,
+/                   double vert_res, int opaque, int swap_xy, text proxy)
+/ LoadRasterFromWMS(text coverage, text section, text getmap_url,
+/                   BLOB geom, text wms_version, text wms_layer, 
+/                   text wms_style, text wms_format, double horz_res,
+/                   double vert_res,  int opaque, int swap_xy, 
+/                   text proxy, int transaction)
 /
 / will return 1 (TRUE, success) or 0 (FALSE, failure)
 / or -1 (INVALID ARGS)
@@ -3521,45 +3719,80 @@ fnct_WriteTripleBandGeoTiff (sqlite3_context * context, int argc,
 */
     int err = 0;
     const char *cvg_name;
-    const char *path;
-    int width;
-    int height;
-    int red_band;
-    int green_band;
-    int blue_band;
+    const char *sect_name;
+    const char *url;
+    const char *proxy = NULL;
+    const char *wms_version;
+    const char *wms_layer;
+    const char *wms_style = NULL;
+    const char *wms_format;
+    char *wms_crs = NULL;
     const unsigned char *blob;
     int blob_sz;
     double horz_res;
     double vert_res;
-    int worldfile = 0;
-    unsigned char compression = RL2_COMPRESSION_NONE;
-    int tile_sz = 256;
-    rl2CoveragePtr coverage = NULL;
-    sqlite3 *sqlite;
-    int ret;
-    int errcode = -1;
-    gaiaGeomCollPtr geom;
+    int opaque = 0;
+    int swap_xy = 0;
+    int srid;
+    int transaction = 1;
     double minx;
     double maxx;
     double miny;
     double maxy;
+    int errcode = -1;
+    rl2CoveragePtr coverage = NULL;
+    rl2PrivCoveragePtr cvg;
+    rl2RasterStatisticsPtr section_stats = NULL;
+    sqlite3 *sqlite;
+    int ret;
+    int n;
+    double x = 0.0;
+    double y = 0.0;
+    double tilew;
+    double tileh;
+    unsigned int tile_width;
+    unsigned int tile_height;
+    WmsRetryListPtr retry_list = NULL;
+    char *table;
+    char *xtable;
+    char *sql;
+    sqlite3_stmt *stmt_data = NULL;
+    sqlite3_stmt *stmt_tils = NULL;
+    sqlite3_stmt *stmt_sect = NULL;
+    sqlite3_stmt *stmt_policies = NULL;
+    sqlite3_stmt *stmt_levl = NULL;
+    sqlite3_stmt *stmt_upd_sect = NULL;
+    int first = 1;
+    double ext_x;
+    double ext_y;
+    unsigned int width;
+    unsigned int height;
+    sqlite3_int64 section_id = 0;
+    rl2PixelPtr no_data = NULL;
+    unsigned char sample_type;
+    unsigned char pixel_type;
+    unsigned char num_bands;
+    unsigned char compression;
+    int quality;
+    InsertWms params;
     RL2_UNUSED ();		/* LCOV_EXCL_LINE */
 
     if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
 	err = 1;
     if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
 	err = 1;
-    if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
-	err = 1;
-    if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+    if (sqlite3_value_type (argv[2]) != SQLITE_TEXT)
 	err = 1;
-    if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
+    if (sqlite3_value_type (argv[3]) != SQLITE_BLOB)
 	err = 1;
-    if (sqlite3_value_type (argv[5]) != SQLITE_INTEGER)
+    if (sqlite3_value_type (argv[4]) != SQLITE_TEXT)
 	err = 1;
-    if (sqlite3_value_type (argv[6]) != SQLITE_INTEGER)
+    if (sqlite3_value_type (argv[5]) != SQLITE_TEXT)
 	err = 1;
-    if (sqlite3_value_type (argv[7]) != SQLITE_BLOB)
+    if (sqlite3_value_type (argv[6]) != SQLITE_TEXT
+	&& sqlite3_value_type (argv[6]) != SQLITE_NULL)
+	err = 1;
+    if (sqlite3_value_type (argv[7]) != SQLITE_TEXT)
 	err = 1;
     if (sqlite3_value_type (argv[8]) != SQLITE_INTEGER
 	&& sqlite3_value_type (argv[8]) != SQLITE_FLOAT)
@@ -3569,9 +3802,18 @@ fnct_WriteTripleBandGeoTiff (sqlite3_context * context, int argc,
 	err = 1;
     if (argc > 10 && sqlite3_value_type (argv[10]) != SQLITE_INTEGER)
 	err = 1;
-    if (argc > 11 && sqlite3_value_type (argv[11]) != SQLITE_TEXT)
+    if (argc > 11 && sqlite3_value_type (argv[11]) != SQLITE_INTEGER)
 	err = 1;
-    if (argc > 12 && sqlite3_value_type (argv[12]) != SQLITE_INTEGER)
+    if (argc > 12)
+      {
+	  if (sqlite3_value_type (argv[12]) == SQLITE_TEXT)
+	      ;
+	  else if (sqlite3_value_type (argv[12]) == SQLITE_NULL)
+	      ;
+	  else
+	      err = 1;
+      }
+    if (argc > 13 && sqlite3_value_type (argv[13]) != SQLITE_INTEGER)
 	err = 1;
     if (err)
       {
@@ -3581,14 +3823,15 @@ fnct_WriteTripleBandGeoTiff (sqlite3_context * context, int argc,
 
 /* retrieving all arguments */
     cvg_name = (const char *) sqlite3_value_text (argv[0]);
-    path = (const char *) sqlite3_value_text (argv[1]);
-    width = sqlite3_value_int (argv[2]);
-    height = sqlite3_value_int (argv[3]);
-    red_band = sqlite3_value_int (argv[4]);
-    green_band = sqlite3_value_int (argv[5]);
-    blue_band = sqlite3_value_int (argv[6]);
-    blob = sqlite3_value_blob (argv[7]);
-    blob_sz = sqlite3_value_bytes (argv[7]);
+    sect_name = (const char *) sqlite3_value_text (argv[1]);
+    url = (const char *) sqlite3_value_text (argv[2]);
+    blob = sqlite3_value_blob (argv[3]);
+    blob_sz = sqlite3_value_bytes (argv[3]);
+    wms_version = (const char *) sqlite3_value_text (argv[4]);
+    wms_layer = (const char *) sqlite3_value_text (argv[5]);
+    if (sqlite3_value_type (argv[6]) == SQLITE_TEXT)
+	wms_style = (const char *) sqlite3_value_text (argv[6]);
+    wms_format = (const char *) sqlite3_value_text (argv[7]);
     if (sqlite3_value_type (argv[8]) == SQLITE_INTEGER)
       {
 	  int ival = sqlite3_value_int (argv[8]);
@@ -3609,401 +3852,485 @@ fnct_WriteTripleBandGeoTiff (sqlite3_context * context, int argc,
     else
 	vert_res = horz_res;
     if (argc > 10)
-	worldfile = sqlite3_value_int (argv[10]);
+	opaque = sqlite3_value_int (argv[10]);
     if (argc > 11)
-      {
-	  const char *compr = (const char *) sqlite3_value_text (argv[11]);
-	  compression = RL2_COMPRESSION_UNKNOWN;
-	  if (strcasecmp (compr, "NONE") == 0)
-	      compression = RL2_COMPRESSION_NONE;
-	  if (strcasecmp (compr, "DEFLATE") == 0)
-	      compression = RL2_COMPRESSION_DEFLATE;
-	  if (strcasecmp (compr, "LZW") == 0)
-	      compression = RL2_COMPRESSION_LZW;
-	  if (strcasecmp (compr, "JPEG") == 0)
-	      compression = RL2_COMPRESSION_JPEG;
-	  if (strcasecmp (compr, "FAX3") == 0)
-	      compression = RL2_COMPRESSION_CCITTFAX3;
-	  if (strcasecmp (compr, "FAX4") == 0)
-	      compression = RL2_COMPRESSION_CCITTFAX4;
-      }
-    if (argc > 12)
-	tile_sz = sqlite3_value_int (argv[12]);
+	swap_xy = sqlite3_value_int (argv[11]);
+    if (argc > 12 && sqlite3_value_type (argv[12]) == SQLITE_TEXT)
+	proxy = (const char *) sqlite3_value_text (argv[12]);
+    if (argc > 13)
+	transaction = sqlite3_value_int (argv[13]);
 
-/* coarse args validation */
-    if (width < 0 || width > UINT16_MAX)
-      {
-	  errcode = -1;
-	  goto error;
-      }
-    if (height < 0 || height > UINT16_MAX)
-      {
-	  errcode = -1;
-	  goto error;
-      }
-    if (red_band < 0 || red_band > 255)
-      {
-	  errcode = -1;
-	  goto error;
-      }
-    if (green_band < 0 || green_band > 255)
-      {
-	  errcode = -1;
-	  goto error;
-      }
-    if (blue_band < 0 || blue_band > 255)
-      {
-	  errcode = -1;
-	  goto error;
-      }
-    if (tile_sz < 64 || tile_sz > UINT16_MAX)
-      {
-	  errcode = -1;
-	  goto error;
-      }
-    if (compression == RL2_COMPRESSION_UNKNOWN)
+/* retrieving the BBOX */
+    sqlite = sqlite3_context_db_handle (context);
+    if (rl2_parse_bbox (sqlite, blob, blob_sz, &minx, &miny, &maxx, &maxy) !=
+	RL2_OK)
       {
 	  errcode = -1;
 	  goto error;
       }
 
-/* checking the Geometry */
-    geom = gaiaFromSpatiaLiteBlobWkb (blob, blob_sz);
-    if (geom == NULL)
+/* attempting to load the Coverage definitions from the DBMS */
+    coverage = rl2_create_coverage_from_dbms (sqlite, cvg_name);
+    if (coverage == NULL)
       {
-	  errcode = -1;
-	  goto error;
+	  sqlite3_result_int (context, -1);
+	  return;
       }
-    if (is_point (geom))
+    if (rl2_get_coverage_tile_size (coverage, &tile_width, &tile_height) !=
+	RL2_OK)
       {
-	  /* assumed to be the GeoTiff Center Point */
-	  gaiaPointPtr pt = geom->FirstPoint;
-	  double ext_x = (double) width * horz_res;
-	  double ext_y = (double) height * vert_res;
-	  minx = pt->X - ext_x / 2.0;
-	  maxx = minx + ext_x;
-	  miny = pt->Y - ext_y / 2.0;
-	  maxy = miny + ext_y;
+	  sqlite3_result_int (context, -1);
+	  return;
       }
-    else
+    if (rl2_get_coverage_srid (coverage, &srid) != RL2_OK)
       {
-	  /* assumed to be any possible Geometry defining a BBOX */
-	  minx = geom->MinX;
-	  maxx = geom->MaxX;
-	  miny = geom->MinY;
-	  maxy = geom->MaxY;
+	  sqlite3_result_int (context, -1);
+	  return;
       }
-    gaiaFreeGeomColl (geom);
-
-/* attempting to load the Coverage definitions from the DBMS */
-    sqlite = sqlite3_context_db_handle (context);
-    coverage = rl2_create_coverage_from_dbms (sqlite, cvg_name);
-    if (coverage == NULL)
+    if (rl2_get_coverage_type
+	(coverage, &sample_type, &pixel_type, &num_bands) != RL2_OK)
       {
 	  sqlite3_result_int (context, -1);
 	  return;
       }
-
-    ret =
-	rl2_export_triple_band_geotiff_from_dbms (sqlite, path, coverage,
-						  horz_res, vert_res, minx,
-						  miny, maxx, maxy, width,
-						  height, red_band,
-						  green_band, blue_band,
-						  compression, tile_sz,
-						  worldfile);
-    if (ret != RL2_OK)
+    no_data = rl2_get_coverage_no_data (coverage);
+    if (rl2_get_coverage_compression (coverage, &compression, &quality)
+	!= RL2_OK)
       {
-	  errcode = 0;
-	  goto error;
+	  sqlite3_result_int (context, -1);
+	  return;
       }
-    rl2_destroy_coverage (coverage);
-    sqlite3_result_int (context, 1);
-    return;
-
-  error:
-    if (coverage != NULL)
-	rl2_destroy_coverage (coverage);
-    sqlite3_result_int (context, errcode);
-}
-
-static void
-fnct_WriteMonoBandGeoTiff (sqlite3_context * context, int argc,
-			   sqlite3_value ** argv)
-{
-/* SQL function:
-/ WriteMonoBandGeoTiff(text coverage, text geotiff_path, int width,
-/              int height, int mono_band, BLOB geom, double resolution)
-/ WriteMonoBandGeoTiff(text coverage, text geotiff_path, int width,
-/              int height, int mono_band, BLOB geom, double horz_res,
-/              double vert_res)
-/ WriteMonoBandGeoTiff(text coverage, text geotiff_path, int width,
-/              int height, int mono_band, BLOB geom, double horz_res,
-/              double vert_res, int with_worldfile)
-/ WriteMonoBandGeoTiff(text coverage, text geotiff_path, int width,
-/              int height, int mono_band, BLOB geom, double horz_res,
-/              double vert_res, int with_worldfile, text compression)
-/ WriteMonoBandGeoTiff(text coverage, text geotiff_path, int width,
-/              int height, int mono_band, BLOB geom, double horz_res,
-/              double vert_res, int with_worldfile, text compression,
-/              int tile_sz)
-/
-/ will return 1 (TRUE, success) or 0 (FALSE, failure)
-/ or -1 (INVALID ARGS)
-/
-*/
-    int err = 0;
-    const char *cvg_name;
-    const char *path;
-    int width;
-    int height;
-    int mono_band;
-    const unsigned char *blob;
-    int blob_sz;
-    double horz_res;
-    double vert_res;
-    int worldfile = 0;
-    unsigned char compression = RL2_COMPRESSION_NONE;
-    int tile_sz = 256;
-    rl2CoveragePtr coverage = NULL;
-    sqlite3 *sqlite;
-    int ret;
-    int errcode = -1;
-    gaiaGeomCollPtr geom;
-    double minx;
-    double maxx;
-    double miny;
-    double maxy;
-    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
 
-    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
-	err = 1;
-    if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
-	err = 1;
-    if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
-	err = 1;
-    if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
-	err = 1;
-    if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
-	err = 1;
-    if (sqlite3_value_type (argv[5]) != SQLITE_BLOB)
-	err = 1;
-    if (sqlite3_value_type (argv[6]) != SQLITE_INTEGER
-	&& sqlite3_value_type (argv[6]) != SQLITE_FLOAT)
-	err = 1;
-    if (argc > 7 && sqlite3_value_type (argv[7]) != SQLITE_INTEGER
-	&& sqlite3_value_type (argv[7]) != SQLITE_FLOAT)
-	err = 1;
-    if (argc > 8 && sqlite3_value_type (argv[8]) != SQLITE_INTEGER)
-	err = 1;
-    if (argc > 9 && sqlite3_value_type (argv[9]) != SQLITE_TEXT)
-	err = 1;
-    if (argc > 10 && sqlite3_value_type (argv[10]) != SQLITE_INTEGER)
-	err = 1;
-    if (err)
+    tilew = (double) tile_width *horz_res;
+    tileh = (double) tile_height *vert_res;
+    ext_x = maxx - minx;
+    ext_y = maxy - miny;
+    width = ext_x / horz_res;
+    height = ext_y / horz_res;
+    if (((double) width * horz_res) < ext_x)
+	width++;
+    if (((double) height * vert_res) < ext_y)
+	height++;
+    if (width < tile_width)
       {
 	  sqlite3_result_int (context, -1);
 	  return;
       }
-
-/* retrieving all arguments */
-    cvg_name = (const char *) sqlite3_value_text (argv[0]);
-    path = (const char *) sqlite3_value_text (argv[1]);
-    width = sqlite3_value_int (argv[2]);
-    height = sqlite3_value_int (argv[3]);
-    mono_band = sqlite3_value_int (argv[4]);
-    blob = sqlite3_value_blob (argv[5]);
-    blob_sz = sqlite3_value_bytes (argv[5]);
-    if (sqlite3_value_type (argv[6]) == SQLITE_INTEGER)
+    if (height < tile_height)
       {
-	  int ival = sqlite3_value_int (argv[6]);
-	  horz_res = ival;
+	  sqlite3_result_int (context, -1);
+	  return;
       }
-    else
-	horz_res = sqlite3_value_double (argv[6]);
-    if (argc > 7)
+
+    if (transaction)
       {
-	  if (sqlite3_value_type (argv[7]) == SQLITE_INTEGER)
+	  /* starting a DBMS Transaction */
+	  ret = sqlite3_exec (sqlite, "BEGIN", NULL, NULL, NULL);
+	  if (ret != SQLITE_OK)
 	    {
-		int ival = sqlite3_value_int (argv[7]);
-		vert_res = ival;
+		rl2_destroy_coverage (coverage);
+		sqlite3_result_int (context, -1);
+		return;
 	    }
-	  else
-	      vert_res = sqlite3_value_double (argv[7]);
-      }
-    else
-	vert_res = horz_res;
-    if (argc > 8)
-	worldfile = sqlite3_value_int (argv[8]);
-    if (argc > 9)
-      {
-	  const char *compr = (const char *) sqlite3_value_text (argv[9]);
-	  compression = RL2_COMPRESSION_UNKNOWN;
-	  if (strcasecmp (compr, "NONE") == 0)
-	      compression = RL2_COMPRESSION_NONE;
-	  if (strcasecmp (compr, "DEFLATE") == 0)
-	      compression = RL2_COMPRESSION_DEFLATE;
-	  if (strcasecmp (compr, "LZW") == 0)
-	      compression = RL2_COMPRESSION_LZW;
-	  if (strcasecmp (compr, "JPEG") == 0)
-	      compression = RL2_COMPRESSION_JPEG;
-	  if (strcasecmp (compr, "FAX3") == 0)
-	      compression = RL2_COMPRESSION_CCITTFAX3;
-	  if (strcasecmp (compr, "FAX4") == 0)
-	      compression = RL2_COMPRESSION_CCITTFAX4;
       }
-    if (argc > 10)
-	tile_sz = sqlite3_value_int (argv[10]);
 
-/* coarse args validation */
-    if (width < 0 || width > UINT16_MAX)
+/* SQL prepared statements */
+    table = sqlite3_mprintf ("%s_sections", cvg_name);
+    xtable = rl2_double_quoted_sql (table);
+    sqlite3_free (table);
+    sql =
+	sqlite3_mprintf
+	("INSERT INTO \"%s\" (section_id, section_name, file_path, "
+	 "md5_checksum, summary, width, height, geometry) "
+	 "VALUES (NULL, ?, ?, ?, ?, ?, ?, ?)", xtable);
+    free (xtable);
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt_sect, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
       {
-	  errcode = -1;
+	  printf ("INSERT INTO sections SQL error: %s\n",
+		  sqlite3_errmsg (sqlite));
 	  goto error;
       }
-    if (height < 0 || height > UINT16_MAX)
+
+    sql =
+	sqlite3_mprintf
+	("SELECT strict_resolution, mixed_resolutions, section_paths, "
+	 "section_md5, section_summary FROM raster_coverages "
+	 "WHERE coverage_name = Lower(%Q)", coverage);
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt_policies, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+	stmt_policies = NULL;
+
+    table = sqlite3_mprintf ("%s_sections", cvg_name);
+    xtable = rl2_double_quoted_sql (table);
+    sqlite3_free (table);
+    sql =
+	sqlite3_mprintf
+	("UPDATE \"%s\" SET statistics = ? WHERE section_id = ?", xtable);
+    free (xtable);
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt_upd_sect, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
       {
-	  errcode = -1;
+	  printf ("UPDATE sections SQL error: %s\n", sqlite3_errmsg (sqlite));
 	  goto error;
       }
-    if (mono_band < 0 || mono_band > 255)
-      {
-	  errcode = -1;
-	  goto error;
-      }
-    if (tile_sz < 64 || tile_sz > UINT16_MAX)
+
+    table = sqlite3_mprintf ("%s_levels", cvg_name);
+    xtable = rl2_double_quoted_sql (table);
+    sqlite3_free (table);
+    sql =
+	sqlite3_mprintf
+	("INSERT OR IGNORE INTO \"%s\" (pyramid_level, "
+	 "x_resolution_1_1, y_resolution_1_1, "
+	 "x_resolution_1_2, y_resolution_1_2, x_resolution_1_4, "
+	 "y_resolution_1_4, x_resolution_1_8, y_resolution_1_8) "
+	 "VALUES (0, ?, ?, ?, ?, ?, ?, ?, ?)", xtable);
+    free (xtable);
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt_levl, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
       {
-	  errcode = -1;
+	  printf ("INSERT INTO levels SQL error: %s\n",
+		  sqlite3_errmsg (sqlite));
 	  goto error;
       }
-    if (compression == RL2_COMPRESSION_UNKNOWN)
+
+    table = sqlite3_mprintf ("%s_tiles", cvg_name);
+    xtable = rl2_double_quoted_sql (table);
+    sqlite3_free (table);
+    sql =
+	sqlite3_mprintf
+	("INSERT INTO \"%s\" (tile_id, pyramid_level, section_id, geometry) "
+	 "VALUES (NULL, 0, ?, BuildMBR(?, ?, ?, ?, ?))", xtable);
+    free (xtable);
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt_tils, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
       {
-	  errcode = -1;
+	  printf ("INSERT INTO tiles SQL error: %s\n", sqlite3_errmsg (sqlite));
 	  goto error;
       }
 
-/* checking the Geometry */
-    geom = gaiaFromSpatiaLiteBlobWkb (blob, blob_sz);
-    if (geom == NULL)
+    table = sqlite3_mprintf ("%s_tile_data", cvg_name);
+    xtable = rl2_double_quoted_sql (table);
+    sqlite3_free (table);
+    sql =
+	sqlite3_mprintf
+	("INSERT INTO \"%s\" (tile_id, tile_data_odd, tile_data_even) "
+	 "VALUES (?, ?, ?)", xtable);
+    free (xtable);
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt_data, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
       {
-	  errcode = -1;
+	  printf ("INSERT INTO tile_data SQL error: %s\n",
+		  sqlite3_errmsg (sqlite));
 	  goto error;
       }
-    if (is_point (geom))
+
+/* preparing the WMS requests */
+    wms_crs = sqlite3_mprintf ("EPSG:%d", srid);
+    tilew = (double) tile_width *horz_res;
+    tileh = (double) tile_height *vert_res;
+    ext_x = maxx - minx;
+    ext_y = maxy - miny;
+    width = ext_x / horz_res;
+    height = ext_y / horz_res;
+    if ((width * horz_res) < ext_x)
+	width++;
+    if ((height * vert_res) < ext_y)
+	height++;
+    retry_list = alloc_retry_list ();
+    cvg = (rl2PrivCoveragePtr) coverage;
+    for (y = maxy; y > miny; y -= tileh)
       {
-	  /* assumed to be the GeoTiff Center Point */
-	  gaiaPointPtr pt = geom->FirstPoint;
-	  double ext_x = (double) width * horz_res;
-	  double ext_y = (double) height * vert_res;
-	  minx = pt->X - ext_x / 2.0;
-	  maxx = minx + ext_x;
-	  miny = pt->Y - ext_y / 2.0;
-	  maxy = miny + ext_y;
+	  for (x = minx; x < maxx; x += tilew)
+	    {
+		char *err_msg = NULL;
+		unsigned char *rgba_tile =
+		    do_wms_GetMap_get (NULL, url, proxy, wms_version,
+				       wms_layer,
+				       wms_crs, swap_xy, x, y - tileh,
+				       x + tilew, y, tile_width, tile_height,
+				       wms_style, wms_format, opaque, 0,
+				       &err_msg);
+		if (rgba_tile == NULL)
+		  {
+		      add_retry (retry_list, x, y - tileh, x + tilew, y);
+		      continue;
+		  }
+
+		params.sqlite = sqlite;
+		params.rgba_tile = rgba_tile;
+		params.coverage = coverage;
+		params.mixedResolutions = cvg->mixedResolutions;
+		params.sectionPaths = cvg->sectionPaths;
+		params.sectionMD5 = cvg->sectionMD5;
+		params.sectionSummary = cvg->sectionSummary;
+		params.sect_name = sect_name;
+		params.x = x;
+		params.y = y;
+		params.width = width;
+		params.height = height;
+		params.tilew = tilew;
+		params.tileh = tileh;
+		params.srid = srid;
+		params.minx = minx;
+		params.miny = miny;
+		params.maxx = maxx;
+		params.maxy = maxy;
+		params.sample_type = sample_type;
+		params.num_bands = num_bands;
+		params.compression = compression;
+		params.horz_res = horz_res;
+		params.vert_res = vert_res;
+		params.tile_width = tile_width;
+		params.tile_height = tile_height;
+		params.no_data = no_data;
+		params.stmt_sect = stmt_sect;
+		params.stmt_levl = stmt_levl;
+		params.stmt_tils = stmt_tils;
+		params.stmt_data = stmt_data;
+		params.xml_summary = NULL;
+		if (!insert_wms_tile
+		    (&params, &first, &section_stats, &section_id))
+		    goto error;
+	    }
       }
-    else
+    for (n = 0; n < 5; n++)
       {
-	  /* assumed to be any possible Geometry defining a BBOX */
-	  minx = geom->MinX;
-	  maxx = geom->MaxX;
-	  miny = geom->MinY;
-	  maxy = geom->MaxY;
+	  WmsRetryItemPtr retry = retry_list->first;
+	  while (retry != NULL)
+	    {
+		char *err_msg = NULL;
+		unsigned char *rgba_tile = NULL;
+		if (retry->done)
+		  {
+		      retry = retry->next;
+		      continue;
+		  }
+		retry->count += 1;
+		rgba_tile =
+		    do_wms_GetMap_get (NULL, url, proxy, wms_version,
+				       wms_layer, wms_crs, swap_xy,
+				       retry->minx, retry->miny, retry->maxx,
+				       retry->maxy, tile_width, tile_height,
+				       wms_style, wms_format, opaque, 0,
+				       &err_msg);
+		if (rgba_tile == NULL)
+		  {
+		      retry = retry->next;
+		      continue;
+		  }
+
+		params.sqlite = sqlite;
+		params.rgba_tile = rgba_tile;
+		params.coverage = coverage;
+		params.mixedResolutions = cvg->mixedResolutions;
+		params.sectionPaths = cvg->sectionPaths;
+		params.sectionMD5 = cvg->sectionMD5;
+		params.sectionSummary = cvg->sectionSummary;
+		params.sect_name = sect_name;
+		params.x = x;
+		params.y = y;
+		params.width = width;
+		params.height = height;
+		params.tilew = tilew;
+		params.tileh = tileh;
+		params.srid = srid;
+		params.minx = minx;
+		params.miny = miny;
+		params.maxx = maxx;
+		params.maxy = maxy;
+		params.sample_type = sample_type;
+		params.num_bands = num_bands;
+		params.compression = compression;
+		params.horz_res = horz_res;
+		params.vert_res = vert_res;
+		params.tile_width = tile_width;
+		params.tile_height = tile_height;
+		params.no_data = no_data;
+		params.stmt_sect = stmt_sect;
+		params.stmt_levl = stmt_levl;
+		params.stmt_tils = stmt_tils;
+		params.stmt_data = stmt_data;
+		params.xml_summary = NULL;
+		if (!insert_wms_tile
+		    (&params, &first, &section_stats, &section_id))
+		    goto error;
+		retry->done = 1;
+		retry = retry->next;
+	    }
       }
-    gaiaFreeGeomColl (geom);
 
-/* attempting to load the Coverage definitions from the DBMS */
-    sqlite = sqlite3_context_db_handle (context);
-    coverage = rl2_create_coverage_from_dbms (sqlite, cvg_name);
-    if (coverage == NULL)
+    if (!rl2_do_insert_stats (sqlite, section_stats, section_id, stmt_upd_sect))
+	goto error;
+    free_retry_list (retry_list);
+    retry_list = NULL;
+    sqlite3_free (wms_crs);
+    wms_crs = NULL;
+
+    sqlite3_finalize (stmt_upd_sect);
+    sqlite3_finalize (stmt_sect);
+    if (stmt_policies != NULL)
+	sqlite3_finalize (stmt_policies);
+    sqlite3_finalize (stmt_levl);
+    sqlite3_finalize (stmt_tils);
+    sqlite3_finalize (stmt_data);
+    stmt_upd_sect = NULL;
+    stmt_sect = NULL;
+    stmt_levl = NULL;
+    stmt_policies = NULL;
+    stmt_tils = NULL;
+    stmt_data = NULL;
+
+    rl2_destroy_raster_statistics (section_stats);
+    section_stats = NULL;
+    rl2_destroy_coverage (coverage);
+    coverage = NULL;
+    if (ret != RL2_OK)
       {
-	  sqlite3_result_int (context, -1);
+	  sqlite3_result_int (context, 0);
+	  if (transaction)
+	    {
+		/* invalidating the pending transaction */
+		sqlite3_exec (sqlite, "ROLLBACK", NULL, NULL, NULL);
+	    }
 	  return;
       }
 
-    ret =
-	rl2_export_mono_band_geotiff_from_dbms (sqlite, path, coverage,
-						horz_res, vert_res, minx,
-						miny, maxx, maxy, width,
-						height, mono_band,
-						compression, tile_sz,
-						worldfile);
-    if (ret != RL2_OK)
+    if (rl2_update_dbms_coverage (sqlite, cvg_name) != RL2_OK)
       {
-	  errcode = 0;
+	  fprintf (stderr, "unable to update the Coverage\n");
 	  goto error;
       }
-    rl2_destroy_coverage (coverage);
+
+    if (transaction)
+      {
+	  /* committing the still pending transaction */
+	  ret = sqlite3_exec (sqlite, "COMMIT", NULL, NULL, NULL);
+	  if (ret != SQLITE_OK)
+	    {
+		sqlite3_result_int (context, -1);
+		return;
+	    }
+      }
     sqlite3_result_int (context, 1);
     return;
 
   error:
+    if (wms_crs != NULL)
+	sqlite3_free (wms_crs);
+    if (stmt_upd_sect != NULL)
+	sqlite3_finalize (stmt_upd_sect);
+    if (stmt_sect != NULL)
+	sqlite3_finalize (stmt_sect);
+    if (stmt_policies != NULL)
+	sqlite3_finalize (stmt_policies);
+    if (stmt_levl != NULL)
+	sqlite3_finalize (stmt_levl);
+    if (stmt_tils != NULL)
+	sqlite3_finalize (stmt_tils);
+    if (stmt_data != NULL)
+	sqlite3_finalize (stmt_data);
+    if (retry_list != NULL)
+	free_retry_list (retry_list);
     if (coverage != NULL)
 	rl2_destroy_coverage (coverage);
+    if (section_stats != NULL)
+	rl2_destroy_raster_statistics (section_stats);
     sqlite3_result_int (context, errcode);
 }
 
 static void
-common_write_tiff (int with_worldfile, sqlite3_context * context, int argc,
-		   sqlite3_value ** argv)
+common_write_geotiff (int by_section, sqlite3_context * context, int argc,
+		      sqlite3_value ** argv)
 {
-/* SQL function:
-/ WriteTiff?(text coverage, text tiff_path, int width,
-/            int height, BLOB geom, double resolution)
-/ WriteTiff?(text coverage, text tiff_path, int width,
-/            int height, BLOB geom, double horz_res,
-/            double vert_res)
-/ WriteTiff?(text coverage, text tiff_path, int width,
-/            int height, BLOB geom, double horz_res,
-/            double vert_res, text compression)
-/ WriteTiff?(text coverage, text tiff_path, int width,
-/            int height, BLOB geom, double horz_res,
-/            double vert_res, text compression, int tile_sz)
-/
-/ will return 1 (TRUE, success) or 0 (FALSE, failure)
-/ or -1 (INVALID ARGS)
-/
-*/
+/* common implementation for Write GeoTIFF */
     int err = 0;
     const char *cvg_name;
     const char *path;
+    sqlite3_int64 section_id = 0;
     int width;
     int height;
     const unsigned char *blob;
     int blob_sz;
     double horz_res;
     double vert_res;
+    int worldfile = 0;
     unsigned char compression = RL2_COMPRESSION_NONE;
     int tile_sz = 256;
     rl2CoveragePtr coverage = NULL;
     sqlite3 *sqlite;
+    const void *data;
+    int max_threads = 1;
     int ret;
     int errcode = -1;
-    gaiaGeomCollPtr geom;
+    double pt_x;
+    double pt_y;
     double minx;
     double maxx;
     double miny;
     double maxy;
     RL2_UNUSED ();		/* LCOV_EXCL_LINE */
 
-    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
-	err = 1;
-    if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
-	err = 1;
-    if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
-	err = 1;
-    if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
-	err = 1;
-    if (sqlite3_value_type (argv[4]) != SQLITE_BLOB)
-	err = 1;
-    if (sqlite3_value_type (argv[5]) != SQLITE_INTEGER
-	&& sqlite3_value_type (argv[5]) != SQLITE_FLOAT)
-	err = 1;
-    if (argc > 6 && sqlite3_value_type (argv[6]) != SQLITE_INTEGER
-	&& sqlite3_value_type (argv[6]) != SQLITE_FLOAT)
-	err = 1;
-    if (argc > 7 && sqlite3_value_type (argv[7]) != SQLITE_TEXT)
-	err = 1;
-    if (argc > 8 && sqlite3_value_type (argv[8]) != SQLITE_INTEGER)
-	err = 1;
+    if (by_section)
+      {
+	  /* single Section */
+	  if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[1]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[2]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[5]) != SQLITE_BLOB)
+	      err = 1;
+	  if (sqlite3_value_type (argv[6]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[6]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 7 && sqlite3_value_type (argv[7]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[7]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 8 && sqlite3_value_type (argv[8]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (argc > 9 && sqlite3_value_type (argv[9]) != SQLITE_TEXT)
+	      err = 1;
+	  if (argc > 10 && sqlite3_value_type (argv[10]) != SQLITE_INTEGER)
+	      err = 1;
+      }
+    else
+      {
+	  /* whole Coverage */
+	  if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[4]) != SQLITE_BLOB)
+	      err = 1;
+	  if (sqlite3_value_type (argv[5]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[5]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 6 && sqlite3_value_type (argv[6]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[6]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 7 && sqlite3_value_type (argv[7]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (argc > 8 && sqlite3_value_type (argv[8]) != SQLITE_TEXT)
+	      err = 1;
+	  if (argc > 9 && sqlite3_value_type (argv[9]) != SQLITE_INTEGER)
+	      err = 1;
+      }
     if (err)
       {
 	  sqlite3_result_int (context, -1);
@@ -4011,58 +4338,115 @@ common_write_tiff (int with_worldfile, sqlite3_context * context, int argc,
       }
 
 /* retrieving all arguments */
-    cvg_name = (const char *) sqlite3_value_text (argv[0]);
-    path = (const char *) sqlite3_value_text (argv[1]);
-    width = sqlite3_value_int (argv[2]);
-    height = sqlite3_value_int (argv[3]);
-    blob = sqlite3_value_blob (argv[4]);
-    blob_sz = sqlite3_value_bytes (argv[4]);
-    if (sqlite3_value_type (argv[5]) == SQLITE_INTEGER)
-      {
-	  int ival = sqlite3_value_int (argv[5]);
-	  horz_res = ival;
-      }
-    else
-	horz_res = sqlite3_value_double (argv[5]);
-    if (argc > 6)
-      {
+    if (by_section)
+      {
+	  /* single Section */
+	  cvg_name = (const char *) sqlite3_value_text (argv[0]);
+	  section_id = sqlite3_value_int64 (argv[1]);
+	  path = (const char *) sqlite3_value_text (argv[2]);
+	  width = sqlite3_value_int (argv[3]);
+	  height = sqlite3_value_int (argv[4]);
+	  blob = sqlite3_value_blob (argv[5]);
+	  blob_sz = sqlite3_value_bytes (argv[5]);
 	  if (sqlite3_value_type (argv[6]) == SQLITE_INTEGER)
 	    {
 		int ival = sqlite3_value_int (argv[6]);
-		vert_res = ival;
+		horz_res = ival;
+	    }
+	  else
+	      horz_res = sqlite3_value_double (argv[6]);
+	  if (argc > 7)
+	    {
+		if (sqlite3_value_type (argv[7]) == SQLITE_INTEGER)
+		  {
+		      int ival = sqlite3_value_int (argv[7]);
+		      vert_res = ival;
+		  }
+		else
+		    vert_res = sqlite3_value_double (argv[7]);
 	    }
 	  else
-	      vert_res = sqlite3_value_double (argv[6]);
+	      vert_res = horz_res;
+	  if (argc > 8)
+	      worldfile = sqlite3_value_int (argv[8]);
+	  if (argc > 9)
+	    {
+		const char *compr = (const char *) sqlite3_value_text (argv[9]);
+		compression = RL2_COMPRESSION_UNKNOWN;
+		if (strcasecmp (compr, "NONE") == 0)
+		    compression = RL2_COMPRESSION_NONE;
+		if (strcasecmp (compr, "DEFLATE") == 0)
+		    compression = RL2_COMPRESSION_DEFLATE;
+		if (strcasecmp (compr, "LZW") == 0)
+		    compression = RL2_COMPRESSION_LZW;
+		if (strcasecmp (compr, "JPEG") == 0)
+		    compression = RL2_COMPRESSION_JPEG;
+		if (strcasecmp (compr, "FAX3") == 0)
+		    compression = RL2_COMPRESSION_CCITTFAX3;
+		if (strcasecmp (compr, "FAX4") == 0)
+		    compression = RL2_COMPRESSION_CCITTFAX4;
+	    }
+	  if (argc > 10)
+	      tile_sz = sqlite3_value_int (argv[10]);
       }
     else
-	vert_res = horz_res;
-    if (argc > 7)
       {
-	  const char *compr = (const char *) sqlite3_value_text (argv[7]);
-	  compression = RL2_COMPRESSION_UNKNOWN;
-	  if (strcasecmp (compr, "NONE") == 0)
-	      compression = RL2_COMPRESSION_NONE;
-	  if (strcasecmp (compr, "DEFLATE") == 0)
-	      compression = RL2_COMPRESSION_DEFLATE;
-	  if (strcasecmp (compr, "LZW") == 0)
-	      compression = RL2_COMPRESSION_LZW;
-	  if (strcasecmp (compr, "JPEG") == 0)
-	      compression = RL2_COMPRESSION_JPEG;
-	  if (strcasecmp (compr, "FAX3") == 0)
-	      compression = RL2_COMPRESSION_CCITTFAX3;
-	  if (strcasecmp (compr, "FAX4") == 0)
-	      compression = RL2_COMPRESSION_CCITTFAX4;
+	  /* whole Coverage */
+	  cvg_name = (const char *) sqlite3_value_text (argv[0]);
+	  path = (const char *) sqlite3_value_text (argv[1]);
+	  width = sqlite3_value_int (argv[2]);
+	  height = sqlite3_value_int (argv[3]);
+	  blob = sqlite3_value_blob (argv[4]);
+	  blob_sz = sqlite3_value_bytes (argv[4]);
+	  if (sqlite3_value_type (argv[5]) == SQLITE_INTEGER)
+	    {
+		int ival = sqlite3_value_int (argv[5]);
+		horz_res = ival;
+	    }
+	  else
+	      horz_res = sqlite3_value_double (argv[5]);
+	  if (argc > 6)
+	    {
+		if (sqlite3_value_type (argv[6]) == SQLITE_INTEGER)
+		  {
+		      int ival = sqlite3_value_int (argv[6]);
+		      vert_res = ival;
+		  }
+		else
+		    vert_res = sqlite3_value_double (argv[6]);
+	    }
+	  else
+	      vert_res = horz_res;
+	  if (argc > 7)
+	      worldfile = sqlite3_value_int (argv[7]);
+	  if (argc > 8)
+	    {
+		const char *compr = (const char *) sqlite3_value_text (argv[8]);
+		compression = RL2_COMPRESSION_UNKNOWN;
+		if (strcasecmp (compr, "NONE") == 0)
+		    compression = RL2_COMPRESSION_NONE;
+		if (strcasecmp (compr, "DEFLATE") == 0)
+		    compression = RL2_COMPRESSION_DEFLATE;
+		if (strcasecmp (compr, "LZW") == 0)
+		    compression = RL2_COMPRESSION_LZW;
+		if (strcasecmp (compr, "JPEG") == 0)
+		    compression = RL2_COMPRESSION_JPEG;
+		if (strcasecmp (compr, "FAX3") == 0)
+		    compression = RL2_COMPRESSION_CCITTFAX3;
+		if (strcasecmp (compr, "FAX4") == 0)
+		    compression = RL2_COMPRESSION_CCITTFAX4;
+	    }
+	  if (argc > 9)
+	      tile_sz = sqlite3_value_int (argv[9]);
       }
-    if (argc > 8)
-	tile_sz = sqlite3_value_int (argv[8]);
 
 /* coarse args validation */
-    if (width < 0 || width > UINT16_MAX)
+    if (width < 0)
       {
 	  errcode = -1;
 	  goto error;
       }
-    if (height < 0 || height > UINT16_MAX)
+    if (height < 0)
       {
 	  errcode = -1;
 	  goto error;
@@ -4078,36 +4462,43 @@ common_write_tiff (int with_worldfile, sqlite3_context * context, int argc,
 	  goto error;
       }
 
-/* checking the Geometry */
-    geom = gaiaFromSpatiaLiteBlobWkb (blob, blob_sz);
-    if (geom == NULL)
+    sqlite = sqlite3_context_db_handle (context);
+    data = sqlite3_user_data (context);
+    if (data != NULL)
       {
-	  errcode = -1;
-	  goto error;
+	  struct rl2_private_data *priv_data = (struct rl2_private_data *) data;
+	  max_threads = priv_data->max_threads;
+	  if (max_threads < 1)
+	      max_threads = 1;
+	  if (max_threads > 64)
+	      max_threads = 64;
       }
-    if (is_point (geom))
+    if (!by_section)
+      {
+	  /* excluding any Mixed Resolution Coverage */
+	  if (rl2_is_mixed_resolutions_coverage (sqlite, cvg_name) > 0)
+	      goto error;
+      }
+
+/* checking the Geometry */
+    if (rl2_parse_point (sqlite, blob, blob_sz, &pt_x, &pt_y) == RL2_OK)
       {
 	  /* assumed to be the GeoTiff Center Point */
-	  gaiaPointPtr pt = geom->FirstPoint;
 	  double ext_x = (double) width * horz_res;
 	  double ext_y = (double) height * vert_res;
-	  minx = pt->X - ext_x / 2.0;
+	  minx = pt_x - ext_x / 2.0;
 	  maxx = minx + ext_x;
-	  miny = pt->Y - ext_y / 2.0;
+	  miny = pt_y - ext_y / 2.0;
 	  maxy = miny + ext_y;
       }
-    else
+    else if (rl2_parse_bbox
+	     (sqlite, blob, blob_sz, &minx, &miny, &maxx, &maxy) != RL2_OK)
       {
-	  /* assumed to be any possible Geometry defining a BBOX */
-	  minx = geom->MinX;
-	  maxx = geom->MaxX;
-	  miny = geom->MinY;
-	  maxy = geom->MaxY;
+	  errcode = -1;
+	  goto error;
       }
-    gaiaFreeGeomColl (geom);
 
 /* attempting to load the Coverage definitions from the DBMS */
-    sqlite = sqlite3_context_db_handle (context);
     coverage = rl2_create_coverage_from_dbms (sqlite, cvg_name);
     if (coverage == NULL)
       {
@@ -4115,23 +4506,26 @@ common_write_tiff (int with_worldfile, sqlite3_context * context, int argc,
 	  return;
       }
 
-    if (with_worldfile)
+    if (by_section)
       {
-	  /* TIFF + Worldfile */
+	  /* single Section */
 	  ret =
-	      rl2_export_tiff_worldfile_from_dbms (sqlite, path, coverage,
-						   horz_res, vert_res, minx,
-						   miny, maxx, maxy, width,
-						   height, compression,
-						   tile_sz);
+	      rl2_export_section_geotiff_from_dbms (sqlite, max_threads, path,
+						    coverage, section_id,
+						    horz_res, vert_res, minx,
+						    miny, maxx, maxy, width,
+						    height, compression,
+						    tile_sz, worldfile);
       }
     else
       {
-	  /* plain TIFF, no Worldfile */
+	  /* whole Coverage */
 	  ret =
-	      rl2_export_tiff_from_dbms (sqlite, path, coverage, horz_res,
-					 vert_res, minx, miny, maxx, maxy,
-					 width, height, compression, tile_sz);
+	      rl2_export_geotiff_from_dbms (sqlite, max_threads, path,
+					    coverage, horz_res, vert_res,
+					    minx, miny, maxx, maxy, width,
+					    height, compression, tile_sz,
+					    worldfile);
       }
     if (ret != RL2_OK)
       {
@@ -4149,108 +4543,161 @@ common_write_tiff (int with_worldfile, sqlite3_context * context, int argc,
 }
 
 static void
-fnct_WriteTiffTfw (sqlite3_context * context, int argc, sqlite3_value ** argv)
+fnct_WriteGeoTiff (sqlite3_context * context, int argc, sqlite3_value ** argv)
 {
 /* SQL function:
-/ WriteTiffTfw(text coverage, text tiff_path, int width,
+/ WriteGeoTiff(text coverage, text geotiff_path, int width,
 /              int height, BLOB geom, double resolution)
-/ WriteTiffTfw(text coverage, text tiff_path, int width,
+/ WriteGeoTiff(text coverage, text geotiff_path, int width,
 /              int height, BLOB geom, double horz_res,
 /              double vert_res)
-/ WriteTiffTfw(text coverage, text tiff_path, int width,
+/ WriteGeoTiff(text coverage, text geotiff_path, int width,
 /              int height, BLOB geom, double horz_res,
-/              double vert_res, text compression)
-/ WriteTiffTfw(text coverage, text tiff_path, int width,
+/              double vert_res, int with_worldfile)
+/ WriteGeoTiff(text coverage, text geotiff_path, int width,
 /              int height, BLOB geom, double horz_res,
-/              double vert_res, text compression, int tile_sz)
+/              double vert_res, int with_worldfile,
+/              text compression)
+/ WriteGeoTiff(text coverage, text geotiff_path, int width,
+/              int height, BLOB geom, double horz_res,
+/              double vert_res, int with_worldfile,
+/              text compression, int tile_sz)
 /
 / will return 1 (TRUE, success) or 0 (FALSE, failure)
 / or -1 (INVALID ARGS)
 /
 */
-    common_write_tiff (1, context, argc, argv);
+    common_write_geotiff (0, context, argc, argv);
 }
 
 static void
-fnct_WriteTiff (sqlite3_context * context, int argc, sqlite3_value ** argv)
+fnct_WriteSectionGeoTiff (sqlite3_context * context, int argc,
+			  sqlite3_value ** argv)
 {
 /* SQL function:
-/ WriteTiff(text coverage, text tiff_path, int width,
-/           int height, BLOB geom, double resolution)
-/ WriteTiff(text coverage, text tiff_path, int width,
-/           int height, BLOB geom, double horz_res,
-/              double vert_res)
-/ WriteTiff(text coverage, text tiff_path, int width,
-/           int height, BLOB geom, double horz_res,
-/              double vert_res, text compression)
-/ WriteTiff(text coverage, text tiff_path, int width,
-/           int height, BLOB geom, double horz_res,
-/           double vert_res, text compression, int tile_sz)
+/ WriteSectionGeoTiff(text coverage, int section_id, text geotiff_path,
+/                     int width, int height, BLOB geom, double resolution)
+/ WriteSectionGeoTiff(text coverage, int section_id, text geotiff_path,
+/                     int width, int height, BLOB geom, double horz_res,
+/                     double vert_res)
+/ WriteSectionGeoTiff(text coverage, int section_id, text geotiff_path,
+/                     int width, int height, BLOB geom, double horz_res,
+/                     double vert_res, int with_worldfile)
+/ WriteSectionGeoTiff(text coverage, int section_id, text geotiff_path,
+/                     int width, int height, BLOB geom, double horz_res,
+/                     double vert_res, int with_worldfile,
+/                     text compression)
+/ WriteSectionGeoTiff(text coverage, int section_id, text geotiff_path, 
+/                     int width, int height, BLOB geom, double horz_res,
+/                     double vert_res, int with_worldfile,
+/                    text compression, int tile_sz)
 /
 / will return 1 (TRUE, success) or 0 (FALSE, failure)
 / or -1 (INVALID ARGS)
 /
 */
-    common_write_tiff (0, context, argc, argv);
+    common_write_geotiff (1, context, argc, argv);
 }
 
 static void
-common_write_jpeg (int with_worldfile, sqlite3_context * context, int argc,
-		   sqlite3_value ** argv)
+common_write_triple_band_geotiff (int by_section, sqlite3_context * context,
+				  int argc, sqlite3_value ** argv)
 {
-/* SQL function:
-/ WriteJpeg?(text coverage, text tiff_path, int width,
-/            int height, BLOB geom, double resolution)
-/ WriteJpeg?(text coverage, text tiff_path, int width,
-/            int height, BLOB geom, double horz_res,
-/            double vert_res)
-/ WriteJpeg?(text coverage, text tiff_path, int width,
-/            int height, BLOB geom, double horz_res,
-/            double vert_res, int quality)
-/
-/ will return 1 (TRUE, success) or 0 (FALSE, failure)
-/ or -1 (INVALID ARGS)
-/
-*/
+/* common implementation WriteTripleBandGeoTiff */
     int err = 0;
     const char *cvg_name;
+    sqlite3_int64 section_id = 0;
     const char *path;
     int width;
     int height;
+    int red_band;
+    int green_band;
+    int blue_band;
     const unsigned char *blob;
     int blob_sz;
     double horz_res;
     double vert_res;
-    int quality = 80;
+    int worldfile = 0;
+    unsigned char compression = RL2_COMPRESSION_NONE;
+    int tile_sz = 256;
     rl2CoveragePtr coverage = NULL;
     sqlite3 *sqlite;
     int ret;
     int errcode = -1;
-    gaiaGeomCollPtr geom;
+    double pt_x;
+    double pt_y;
     double minx;
     double maxx;
     double miny;
     double maxy;
     RL2_UNUSED ();		/* LCOV_EXCL_LINE */
 
-    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
-	err = 1;
-    if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
-	err = 1;
-    if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
-	err = 1;
-    if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
-	err = 1;
-    if (sqlite3_value_type (argv[4]) != SQLITE_BLOB)
-	err = 1;
-    if (sqlite3_value_type (argv[5]) != SQLITE_INTEGER
-	&& sqlite3_value_type (argv[5]) != SQLITE_FLOAT)
-	err = 1;
-    if (argc > 6 && sqlite3_value_type (argv[6]) != SQLITE_INTEGER
-	&& sqlite3_value_type (argv[6]) != SQLITE_FLOAT)
-	err = 1;
-    if (argc > 7 && sqlite3_value_type (argv[7]) != SQLITE_INTEGER)
-	err = 1;
+    if (by_section)
+      {
+	  /* single Section */
+	  if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[1]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[2]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[5]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[6]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[7]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[8]) != SQLITE_BLOB)
+	      err = 1;
+	  if (sqlite3_value_type (argv[9]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[9]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 10 && sqlite3_value_type (argv[10]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[10]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 11 && sqlite3_value_type (argv[11]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (argc > 12 && sqlite3_value_type (argv[12]) != SQLITE_TEXT)
+	      err = 1;
+	  if (argc > 13 && sqlite3_value_type (argv[13]) != SQLITE_INTEGER)
+	      err = 1;
+      }
+    else
+      {
+	  /* whole Coverage */
+	  if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[5]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[6]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[7]) != SQLITE_BLOB)
+	      err = 1;
+	  if (sqlite3_value_type (argv[8]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[8]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 9 && sqlite3_value_type (argv[9]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[9]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 10 && sqlite3_value_type (argv[10]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (argc > 11 && sqlite3_value_type (argv[11]) != SQLITE_TEXT)
+	      err = 1;
+	  if (argc > 12 && sqlite3_value_type (argv[12]) != SQLITE_INTEGER)
+	      err = 1;
+      }
     if (err)
       {
 	  sqlite3_result_int (context, -1);
@@ -4258,80 +4705,180 @@ common_write_jpeg (int with_worldfile, sqlite3_context * context, int argc,
       }
 
 /* retrieving all arguments */
-    cvg_name = (const char *) sqlite3_value_text (argv[0]);
-    path = (const char *) sqlite3_value_text (argv[1]);
-    width = sqlite3_value_int (argv[2]);
-    height = sqlite3_value_int (argv[3]);
-    blob = sqlite3_value_blob (argv[4]);
-    blob_sz = sqlite3_value_bytes (argv[4]);
-    if (sqlite3_value_type (argv[5]) == SQLITE_INTEGER)
-      {
-	  int ival = sqlite3_value_int (argv[5]);
-	  horz_res = ival;
+    if (by_section)
+      {
+	  /* single Section */
+	  cvg_name = (const char *) sqlite3_value_text (argv[0]);
+	  section_id = sqlite3_value_int64 (argv[1]);
+	  path = (const char *) sqlite3_value_text (argv[2]);
+	  width = sqlite3_value_int (argv[3]);
+	  height = sqlite3_value_int (argv[4]);
+	  red_band = sqlite3_value_int (argv[5]);
+	  green_band = sqlite3_value_int (argv[6]);
+	  blue_band = sqlite3_value_int (argv[7]);
+	  blob = sqlite3_value_blob (argv[8]);
+	  blob_sz = sqlite3_value_bytes (argv[8]);
+	  if (sqlite3_value_type (argv[9]) == SQLITE_INTEGER)
+	    {
+		int ival = sqlite3_value_int (argv[9]);
+		horz_res = ival;
+	    }
+	  else
+	      horz_res = sqlite3_value_double (argv[9]);
+	  if (argc > 10)
+	    {
+		if (sqlite3_value_type (argv[10]) == SQLITE_INTEGER)
+		  {
+		      int ival = sqlite3_value_int (argv[10]);
+		      vert_res = ival;
+		  }
+		else
+		    vert_res = sqlite3_value_double (argv[10]);
+	    }
+	  else
+	      vert_res = horz_res;
+	  if (argc > 11)
+	      worldfile = sqlite3_value_int (argv[11]);
+	  if (argc > 12)
+	    {
+		const char *compr =
+		    (const char *) sqlite3_value_text (argv[12]);
+		compression = RL2_COMPRESSION_UNKNOWN;
+		if (strcasecmp (compr, "NONE") == 0)
+		    compression = RL2_COMPRESSION_NONE;
+		if (strcasecmp (compr, "DEFLATE") == 0)
+		    compression = RL2_COMPRESSION_DEFLATE;
+		if (strcasecmp (compr, "LZW") == 0)
+		    compression = RL2_COMPRESSION_LZW;
+		if (strcasecmp (compr, "JPEG") == 0)
+		    compression = RL2_COMPRESSION_JPEG;
+		if (strcasecmp (compr, "FAX3") == 0)
+		    compression = RL2_COMPRESSION_CCITTFAX3;
+		if (strcasecmp (compr, "FAX4") == 0)
+		    compression = RL2_COMPRESSION_CCITTFAX4;
+	    }
+	  if (argc > 13)
+	      tile_sz = sqlite3_value_int (argv[13]);
       }
     else
-	horz_res = sqlite3_value_double (argv[5]);
-    if (argc > 6)
       {
-	  if (sqlite3_value_type (argv[6]) == SQLITE_INTEGER)
+	  /* whole Coverage */
+	  cvg_name = (const char *) sqlite3_value_text (argv[0]);
+	  path = (const char *) sqlite3_value_text (argv[1]);
+	  width = sqlite3_value_int (argv[2]);
+	  height = sqlite3_value_int (argv[3]);
+	  red_band = sqlite3_value_int (argv[4]);
+	  green_band = sqlite3_value_int (argv[5]);
+	  blue_band = sqlite3_value_int (argv[6]);
+	  blob = sqlite3_value_blob (argv[7]);
+	  blob_sz = sqlite3_value_bytes (argv[7]);
+	  if (sqlite3_value_type (argv[8]) == SQLITE_INTEGER)
 	    {
-		int ival = sqlite3_value_int (argv[6]);
-		vert_res = ival;
+		int ival = sqlite3_value_int (argv[8]);
+		horz_res = ival;
+	    }
+	  else
+	      horz_res = sqlite3_value_double (argv[8]);
+	  if (argc > 9)
+	    {
+		if (sqlite3_value_type (argv[9]) == SQLITE_INTEGER)
+		  {
+		      int ival = sqlite3_value_int (argv[9]);
+		      vert_res = ival;
+		  }
+		else
+		    vert_res = sqlite3_value_double (argv[9]);
 	    }
 	  else
-	      vert_res = sqlite3_value_double (argv[6]);
+	      vert_res = horz_res;
+	  if (argc > 10)
+	      worldfile = sqlite3_value_int (argv[10]);
+	  if (argc > 11)
+	    {
+		const char *compr =
+		    (const char *) sqlite3_value_text (argv[11]);
+		compression = RL2_COMPRESSION_UNKNOWN;
+		if (strcasecmp (compr, "NONE") == 0)
+		    compression = RL2_COMPRESSION_NONE;
+		if (strcasecmp (compr, "DEFLATE") == 0)
+		    compression = RL2_COMPRESSION_DEFLATE;
+		if (strcasecmp (compr, "LZW") == 0)
+		    compression = RL2_COMPRESSION_LZW;
+		if (strcasecmp (compr, "JPEG") == 0)
+		    compression = RL2_COMPRESSION_JPEG;
+		if (strcasecmp (compr, "FAX3") == 0)
+		    compression = RL2_COMPRESSION_CCITTFAX3;
+		if (strcasecmp (compr, "FAX4") == 0)
+		    compression = RL2_COMPRESSION_CCITTFAX4;
+	    }
+	  if (argc > 12)
+	      tile_sz = sqlite3_value_int (argv[12]);
+      }
+
+    sqlite = sqlite3_context_db_handle (context);
+    if (!by_section)
+      {
+	  /* excluding any Mixed Resolution Coverage */
+	  if (rl2_is_mixed_resolutions_coverage (sqlite, cvg_name) > 0)
+	      goto error;
       }
-    else
-	vert_res = horz_res;
-    if (argc > 7)
-	quality = sqlite3_value_int (argv[7]);
 
 /* coarse args validation */
-    if (width < 0 || width > UINT16_MAX)
+    if (width < 0)
       {
 	  errcode = -1;
 	  goto error;
       }
-    if (height < 0 || height > UINT16_MAX)
+    if (height < 0)
       {
 	  errcode = -1;
 	  goto error;
       }
-    if (quality < 0)
-	quality = 0;
-    if (quality > 100)
-	quality = 100;
-
-/* checking the Geometry */
-    geom = gaiaFromSpatiaLiteBlobWkb (blob, blob_sz);
-    if (geom == NULL)
+    if (red_band < 0 || red_band > 255)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+    if (green_band < 0 || green_band > 255)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+    if (blue_band < 0 || blue_band > 255)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+    if (tile_sz < 64 || tile_sz > UINT16_MAX)
       {
 	  errcode = -1;
 	  goto error;
       }
-    if (is_point (geom))
+    if (compression == RL2_COMPRESSION_UNKNOWN)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+
+/* checking the Geometry */
+    if (rl2_parse_point (sqlite, blob, blob_sz, &pt_x, &pt_y) == RL2_OK)
       {
 	  /* assumed to be the GeoTiff Center Point */
-	  gaiaPointPtr pt = geom->FirstPoint;
 	  double ext_x = (double) width * horz_res;
 	  double ext_y = (double) height * vert_res;
-	  minx = pt->X - ext_x / 2.0;
+	  minx = pt_x - ext_x / 2.0;
 	  maxx = minx + ext_x;
-	  miny = pt->Y - ext_y / 2.0;
+	  miny = pt_y - ext_y / 2.0;
 	  maxy = miny + ext_y;
       }
-    else
+    else if (rl2_parse_bbox
+	     (sqlite, blob, blob_sz, &minx, &miny, &maxx, &maxy) != RL2_OK)
       {
-	  /* assumed to be any possible Geometry defining a BBOX */
-	  minx = geom->MinX;
-	  maxx = geom->MaxX;
-	  miny = geom->MinY;
-	  maxy = geom->MaxY;
+	  errcode = -1;
+	  goto error;
       }
-    gaiaFreeGeomColl (geom);
 
 /* attempting to load the Coverage definitions from the DBMS */
-    sqlite = sqlite3_context_db_handle (context);
     coverage = rl2_create_coverage_from_dbms (sqlite, cvg_name);
     if (coverage == NULL)
       {
@@ -4339,10 +4886,39 @@ common_write_jpeg (int with_worldfile, sqlite3_context * context, int argc,
 	  return;
       }
 
-    ret =
-	rl2_export_jpeg_from_dbms (sqlite, path, coverage, horz_res,
-				   vert_res, minx, miny, maxx, maxy,
-				   width, height, quality, with_worldfile);
+    if (by_section)
+      {
+	  /* single Section */
+	  ret =
+	      rl2_export_section_triple_band_geotiff_from_dbms (sqlite, path,
+								coverage,
+								section_id,
+								horz_res,
+								vert_res,
+								minx, miny,
+								maxx, maxy,
+								width, height,
+								red_band,
+								green_band,
+								blue_band,
+								compression,
+								tile_sz,
+								worldfile);
+      }
+    else
+      {
+	  /* whole Coverage */
+
+	  ret =
+	      rl2_export_triple_band_geotiff_from_dbms (sqlite, path,
+							coverage, horz_res,
+							vert_res, minx, miny,
+							maxx, maxy, width,
+							height, red_band,
+							green_band, blue_band,
+							compression, tile_sz,
+							worldfile);
+      }
     if (ret != RL2_OK)
       {
 	  errcode = 0;
@@ -4359,120 +4935,165 @@ common_write_jpeg (int with_worldfile, sqlite3_context * context, int argc,
 }
 
 static void
-fnct_WriteJpegJgw (sqlite3_context * context, int argc, sqlite3_value ** argv)
+fnct_WriteTripleBandGeoTiff (sqlite3_context * context, int argc,
+			     sqlite3_value ** argv)
 {
 /* SQL function:
-/ WriteJpegJgw(text coverage, text tiff_path, int width,
-/              int height, BLOB geom, double resolution)
-/ WriteJpegJgw(text coverage, text tiff_path, int width,
-/              int height, BLOB geom, double horz_res,
-/              double vert_res)
-/ WriteJpegJgw(text coverage, text tiff_path, int width,
-/              int height, BLOB geom, double horz_res,
-/              double vert_res, int quality)
+/ WriteTripleBandGeoTiff(text coverage, text geotiff_path, int width,
+/                        int height, int red_band, int green_band,
+/                        int blue_band, BLOB geom, double resolution)
+/ WriteTripleBandGeoTiff(text coverage, text geotiff_path, int width,
+/                        int height, int red_band, int green_band,
+/                        int blue_band, BLOB geom, double horz_res,
+/                        double vert_res)
+/ WriteTripleBandGeoTiff(text coverage, text geotiff_path, int width,
+/                        int height, int red_band, int green_band,
+/                        int blue_band, BLOB geom, double horz_res,
+/                        double vert_res, int with_worldfile)
+/ WriteTripleBandGeoTiff(text coverage, text geotiff_path, int width,
+/                        int height, int red_band, int green_band, 
+/                        int blue_band, BLOB geom, double horz_res,
+/                        double vert_res, int with_worldfile, 
+/                        text compression)
+/ WriteTripleBandGeoTiff(text coverage, text geotiff_path, int width,
+/                        int height, int red_band, int green_band,
+/                        int blue_band, BLOB geom, double horz_res,
+/                        double vert_res, int with_worldfile,
+/                        text compression, int tile_sz)
 /
 / will return 1 (TRUE, success) or 0 (FALSE, failure)
 / or -1 (INVALID ARGS)
 /
 */
-    common_write_jpeg (1, context, argc, argv);
+    common_write_triple_band_geotiff (0, context, argc, argv);
 }
 
 static void
-fnct_WriteJpeg (sqlite3_context * context, int argc, sqlite3_value ** argv)
+fnct_WriteSectionTripleBandGeoTiff (sqlite3_context * context, int argc,
+				    sqlite3_value ** argv)
 {
 /* SQL function:
-/ WriteJpeg(text coverage, text tiff_path, int width,
-/           int height, BLOB geom, double resolution)
-/ WriteJpeg(text coverage, text tiff_path, int width,
-/           int height, BLOB geom, double horz_res,
-/              double vert_res)
-/ WriteJpeg(text coverage, text tiff_path, int width,
-/           int height, BLOB geom, double horz_res,
-/              double vert_res, int quality)
+/ WriteSectionTripleBandGeoTiff(text coverage, int section_id, 
+/                               text geotiff_path, int width, int height,
+/                               int red_band, int green_band, int blue_band,
+/                               BLOB geom, double resolution)
+/ WriteSectionTripleBandGeoTiff(text coverage, int section_id, 
+/                               text geotiff_path, int width, int height,
+/                               int red_band, int green_band, int blue_band,
+/                               BLOB geom, double horz_res, double vert_res)
+/ WriteSectionTripleBandGeoTiff(text coverage, int section_id, 
+/                               text geotiff_path, int width, int height,
+/                               int red_band, int green_band, int blue_band,
+/                               BLOB geom, double horz_res, double vert_res, 
+/                               int with_worldfile)
+/ WriteSectionTripleBandGeoTiff(text coverage, int section_id, 
+/                               text geotiff_path, int width, int height,
+/                               int red_band, int green_band, int blue_band, 
+/                               BLOB geom, double horz_res, double vert_res, 
+/                               int with_worldfile, text compression)
+/ WriteSectionTripleBandGeoTiff(text coverage, int section_id,
+/                               text geotiff_path, int width, int height,
+/                               int red_band, int green_band, int blue_band, 
+/                               BLOB geom, double horz_res, double vert_res, 
+/                               int with_worldfile, text compression, int tile_sz)
 /
 / will return 1 (TRUE, success) or 0 (FALSE, failure)
 / or -1 (INVALID ARGS)
 /
 */
-    common_write_jpeg (0, context, argc, argv);
+    common_write_triple_band_geotiff (1, context, argc, argv);
 }
 
 static void
-common_write_triple_band_tiff (int with_worldfile, sqlite3_context * context,
-			       int argc, sqlite3_value ** argv)
+common_write_mono_band_geotiff (int by_section, sqlite3_context * context,
+				int argc, sqlite3_value ** argv)
 {
-/* SQL function:
-/ WriteTripleBandTiff?(text coverage, text tiff_path, int width,
-/            int height, int red_band, int green_band, int blue_band,
-/            BLOB geom, double resolution)
-/ WriteTripleBandTiff?(text coverage, text tiff_path, int width,
-/            int height, int red_band, int green_band, int blue_band,
-/            BLOB geom, double horz_res, double vert_res)
-/ WriteTripleBandTiff?(text coverage, text tiff_path, int width,
-/            int height, int red_band, int green_band, int blue_band,
-/            BLOB geom, double horz_res, double vert_res,
-/            text compression)
-/ WriteTripleBandTiff?(text coverage, text tiff_path, int width,
-/            int height, int red_band, int green_band, int blue_band, 
-/            BLOB geom, double horz_res, double vert_res,
-/            text compression, int tile_sz)
-/
-/ will return 1 (TRUE, success) or 0 (FALSE, failure)
-/ or -1 (INVALID ARGS)
-/
+/* common implementation Write MonoBand GeoTiff
 */
     int err = 0;
     const char *cvg_name;
+    sqlite3_int64 section_id = 0;
     const char *path;
     int width;
     int height;
-    int red_band;
-    int green_band;
-    int blue_band;
+    int mono_band;
     const unsigned char *blob;
     int blob_sz;
     double horz_res;
     double vert_res;
+    int worldfile = 0;
     unsigned char compression = RL2_COMPRESSION_NONE;
     int tile_sz = 256;
     rl2CoveragePtr coverage = NULL;
     sqlite3 *sqlite;
     int ret;
     int errcode = -1;
-    gaiaGeomCollPtr geom;
+    double pt_x;
+    double pt_y;
     double minx;
     double maxx;
     double miny;
     double maxy;
     RL2_UNUSED ();		/* LCOV_EXCL_LINE */
 
-    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
-	err = 1;
-    if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
-	err = 1;
-    if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
-	err = 1;
-    if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
-	err = 1;
-    if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
-	err = 1;
-    if (sqlite3_value_type (argv[5]) != SQLITE_INTEGER)
-	err = 1;
-    if (sqlite3_value_type (argv[6]) != SQLITE_INTEGER)
-	err = 1;
-    if (sqlite3_value_type (argv[7]) != SQLITE_BLOB)
-	err = 1;
-    if (sqlite3_value_type (argv[8]) != SQLITE_INTEGER
-	&& sqlite3_value_type (argv[8]) != SQLITE_FLOAT)
-	err = 1;
-    if (argc > 9 && sqlite3_value_type (argv[9]) != SQLITE_INTEGER
-	&& sqlite3_value_type (argv[9]) != SQLITE_FLOAT)
-	err = 1;
-    if (argc > 10 && sqlite3_value_type (argv[10]) != SQLITE_TEXT)
-	err = 1;
-    if (argc > 11 && sqlite3_value_type (argv[11]) != SQLITE_INTEGER)
-	err = 1;
+    if (by_section)
+      {
+	  /* single Section */
+	  if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[1]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[2]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[5]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[6]) != SQLITE_BLOB)
+	      err = 1;
+	  if (sqlite3_value_type (argv[7]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[7]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 8 && sqlite3_value_type (argv[8]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[8]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 9 && sqlite3_value_type (argv[9]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (argc > 10 && sqlite3_value_type (argv[10]) != SQLITE_TEXT)
+	      err = 1;
+	  if (argc > 11 && sqlite3_value_type (argv[11]) != SQLITE_INTEGER)
+	      err = 1;
+      }
+    else
+      {
+	  /* whole Coverage */
+	  if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[5]) != SQLITE_BLOB)
+	      err = 1;
+	  if (sqlite3_value_type (argv[6]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[6]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 7 && sqlite3_value_type (argv[7]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[7]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 8 && sqlite3_value_type (argv[8]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (argc > 9 && sqlite3_value_type (argv[9]) != SQLITE_TEXT)
+	      err = 1;
+	  if (argc > 10 && sqlite3_value_type (argv[10]) != SQLITE_INTEGER)
+	      err = 1;
+      }
     if (err)
       {
 	  sqlite3_result_int (context, -1);
@@ -4480,76 +5101,131 @@ common_write_triple_band_tiff (int with_worldfile, sqlite3_context * context,
       }
 
 /* retrieving all arguments */
-    cvg_name = (const char *) sqlite3_value_text (argv[0]);
-    path = (const char *) sqlite3_value_text (argv[1]);
-    width = sqlite3_value_int (argv[2]);
-    height = sqlite3_value_int (argv[3]);
-    red_band = sqlite3_value_int (argv[4]);
-    green_band = sqlite3_value_int (argv[5]);
-    blue_band = sqlite3_value_int (argv[6]);
-    blob = sqlite3_value_blob (argv[7]);
-    blob_sz = sqlite3_value_bytes (argv[7]);
-    if (sqlite3_value_type (argv[8]) == SQLITE_INTEGER)
-      {
-	  int ival = sqlite3_value_int (argv[8]);
-	  horz_res = ival;
+    if (by_section)
+      {
+	  /* single Section */
+	  cvg_name = (const char *) sqlite3_value_text (argv[0]);
+	  section_id = sqlite3_value_int64 (argv[1]);
+	  path = (const char *) sqlite3_value_text (argv[2]);
+	  width = sqlite3_value_int (argv[3]);
+	  height = sqlite3_value_int (argv[4]);
+	  mono_band = sqlite3_value_int (argv[5]);
+	  blob = sqlite3_value_blob (argv[6]);
+	  blob_sz = sqlite3_value_bytes (argv[6]);
+	  if (sqlite3_value_type (argv[7]) == SQLITE_INTEGER)
+	    {
+		int ival = sqlite3_value_int (argv[7]);
+		horz_res = ival;
+	    }
+	  else
+	      horz_res = sqlite3_value_double (argv[7]);
+	  if (argc > 8)
+	    {
+		if (sqlite3_value_type (argv[8]) == SQLITE_INTEGER)
+		  {
+		      int ival = sqlite3_value_int (argv[8]);
+		      vert_res = ival;
+		  }
+		else
+		    vert_res = sqlite3_value_double (argv[8]);
+	    }
+	  else
+	      vert_res = horz_res;
+	  if (argc > 9)
+	      worldfile = sqlite3_value_int (argv[9]);
+	  if (argc > 10)
+	    {
+		const char *compr =
+		    (const char *) sqlite3_value_text (argv[10]);
+		compression = RL2_COMPRESSION_UNKNOWN;
+		if (strcasecmp (compr, "NONE") == 0)
+		    compression = RL2_COMPRESSION_NONE;
+		if (strcasecmp (compr, "DEFLATE") == 0)
+		    compression = RL2_COMPRESSION_DEFLATE;
+		if (strcasecmp (compr, "LZW") == 0)
+		    compression = RL2_COMPRESSION_LZW;
+		if (strcasecmp (compr, "JPEG") == 0)
+		    compression = RL2_COMPRESSION_JPEG;
+		if (strcasecmp (compr, "FAX3") == 0)
+		    compression = RL2_COMPRESSION_CCITTFAX3;
+		if (strcasecmp (compr, "FAX4") == 0)
+		    compression = RL2_COMPRESSION_CCITTFAX4;
+	    }
+	  if (argc > 11)
+	      tile_sz = sqlite3_value_int (argv[11]);
       }
     else
-	horz_res = sqlite3_value_double (argv[8]);
-    if (argc > 9)
       {
-	  if (sqlite3_value_type (argv[9]) == SQLITE_INTEGER)
+	  /* whole Coverage */
+	  cvg_name = (const char *) sqlite3_value_text (argv[0]);
+	  path = (const char *) sqlite3_value_text (argv[1]);
+	  width = sqlite3_value_int (argv[2]);
+	  height = sqlite3_value_int (argv[3]);
+	  mono_band = sqlite3_value_int (argv[4]);
+	  blob = sqlite3_value_blob (argv[5]);
+	  blob_sz = sqlite3_value_bytes (argv[5]);
+	  if (sqlite3_value_type (argv[6]) == SQLITE_INTEGER)
 	    {
-		int ival = sqlite3_value_int (argv[9]);
-		vert_res = ival;
+		int ival = sqlite3_value_int (argv[6]);
+		horz_res = ival;
 	    }
 	  else
-	      vert_res = sqlite3_value_double (argv[9]);
+	      horz_res = sqlite3_value_double (argv[6]);
+	  if (argc > 7)
+	    {
+		if (sqlite3_value_type (argv[7]) == SQLITE_INTEGER)
+		  {
+		      int ival = sqlite3_value_int (argv[7]);
+		      vert_res = ival;
+		  }
+		else
+		    vert_res = sqlite3_value_double (argv[7]);
+	    }
+	  else
+	      vert_res = horz_res;
+	  if (argc > 8)
+	      worldfile = sqlite3_value_int (argv[8]);
+	  if (argc > 9)
+	    {
+		const char *compr = (const char *) sqlite3_value_text (argv[9]);
+		compression = RL2_COMPRESSION_UNKNOWN;
+		if (strcasecmp (compr, "NONE") == 0)
+		    compression = RL2_COMPRESSION_NONE;
+		if (strcasecmp (compr, "DEFLATE") == 0)
+		    compression = RL2_COMPRESSION_DEFLATE;
+		if (strcasecmp (compr, "LZW") == 0)
+		    compression = RL2_COMPRESSION_LZW;
+		if (strcasecmp (compr, "JPEG") == 0)
+		    compression = RL2_COMPRESSION_JPEG;
+		if (strcasecmp (compr, "FAX3") == 0)
+		    compression = RL2_COMPRESSION_CCITTFAX3;
+		if (strcasecmp (compr, "FAX4") == 0)
+		    compression = RL2_COMPRESSION_CCITTFAX4;
+	    }
+	  if (argc > 10)
+	      tile_sz = sqlite3_value_int (argv[10]);
       }
-    else
-	vert_res = horz_res;
-    if (argc > 10)
+
+    sqlite = sqlite3_context_db_handle (context);
+    if (!by_section)
       {
-	  const char *compr = (const char *) sqlite3_value_text (argv[10]);
-	  compression = RL2_COMPRESSION_UNKNOWN;
-	  if (strcasecmp (compr, "NONE") == 0)
-	      compression = RL2_COMPRESSION_NONE;
-	  if (strcasecmp (compr, "DEFLATE") == 0)
-	      compression = RL2_COMPRESSION_DEFLATE;
-	  if (strcasecmp (compr, "LZW") == 0)
-	      compression = RL2_COMPRESSION_LZW;
-	  if (strcasecmp (compr, "JPEG") == 0)
-	      compression = RL2_COMPRESSION_JPEG;
-	  if (strcasecmp (compr, "FAX3") == 0)
-	      compression = RL2_COMPRESSION_CCITTFAX3;
-	  if (strcasecmp (compr, "FAX4") == 0)
-	      compression = RL2_COMPRESSION_CCITTFAX4;
+	  /* excluding any Mixed Resolution Coverage */
+	  if (rl2_is_mixed_resolutions_coverage (sqlite, cvg_name) > 0)
+	      goto error;
       }
-    if (argc > 11)
-	tile_sz = sqlite3_value_int (argv[11]);
 
 /* coarse args validation */
-    if (width < 0 || width > UINT16_MAX)
-      {
-	  errcode = -1;
-	  goto error;
-      }
-    if (height < 0 || height > UINT16_MAX)
-      {
-	  errcode = -1;
-	  goto error;
-      }
-    if (red_band < 0 || red_band > 255)
+    if (width < 0)
       {
 	  errcode = -1;
 	  goto error;
       }
-    if (green_band < 0 || green_band > 255)
+    if (height < 0)
       {
 	  errcode = -1;
 	  goto error;
       }
-    if (blue_band < 0 || blue_band > 255)
+    if (mono_band < 0 || mono_band > 255)
       {
 	  errcode = -1;
 	  goto error;
@@ -4566,35 +5242,24 @@ common_write_triple_band_tiff (int with_worldfile, sqlite3_context * context,
       }
 
 /* checking the Geometry */
-    geom = gaiaFromSpatiaLiteBlobWkb (blob, blob_sz);
-    if (geom == NULL)
-      {
-	  errcode = -1;
-	  goto error;
-      }
-    if (is_point (geom))
+    if (rl2_parse_point (sqlite, blob, blob_sz, &pt_x, &pt_y) == RL2_OK)
       {
 	  /* assumed to be the GeoTiff Center Point */
-	  gaiaPointPtr pt = geom->FirstPoint;
 	  double ext_x = (double) width * horz_res;
 	  double ext_y = (double) height * vert_res;
-	  minx = pt->X - ext_x / 2.0;
+	  minx = pt_x - ext_x / 2.0;
 	  maxx = minx + ext_x;
-	  miny = pt->Y - ext_y / 2.0;
+	  miny = pt_y - ext_y / 2.0;
 	  maxy = miny + ext_y;
       }
-    else
+    else if (rl2_parse_bbox
+	     (sqlite, blob, blob_sz, &minx, &miny, &maxx, &maxy) != RL2_OK)
       {
-	  /* assumed to be any possible Geometry defining a BBOX */
-	  minx = geom->MinX;
-	  maxx = geom->MaxX;
-	  miny = geom->MinY;
-	  maxy = geom->MaxY;
+	  errcode = -1;
+	  goto error;
       }
-    gaiaFreeGeomColl (geom);
 
 /* attempting to load the Coverage definitions from the DBMS */
-    sqlite = sqlite3_context_db_handle (context);
     coverage = rl2_create_coverage_from_dbms (sqlite, cvg_name);
     if (coverage == NULL)
       {
@@ -4602,34 +5267,35 @@ common_write_triple_band_tiff (int with_worldfile, sqlite3_context * context,
 	  return;
       }
 
-    if (with_worldfile)
+    if (by_section)
       {
-	  /* TIFF + Worldfile */
+	  /* single Section */
 	  ret =
-	      rl2_export_triple_band_tiff_worldfile_from_dbms (sqlite, path,
-							       coverage,
-							       horz_res,
-							       vert_res, minx,
-							       miny, maxx,
-							       maxy, width,
-							       height,
-							       red_band,
-							       green_band,
-							       blue_band,
-							       compression,
-							       tile_sz);
+	      rl2_export_section_mono_band_geotiff_from_dbms (sqlite, path,
+							      coverage,
+							      section_id,
+							      horz_res,
+							      vert_res, minx,
+							      miny, maxx,
+							      maxy, width,
+							      height,
+							      mono_band,
+							      compression,
+							      tile_sz,
+							      worldfile);
       }
     else
       {
-	  /* plain TIFF, no Worldfile */
+	  /* whole Coverage */
 	  ret =
-	      rl2_export_triple_band_tiff_from_dbms (sqlite, path, coverage,
-						     horz_res, vert_res, minx,
-						     miny, maxx, maxy, width,
-						     height, red_band,
-						     green_band, blue_band,
-						     compression, tile_sz);
+	      rl2_export_mono_band_geotiff_from_dbms (sqlite, path, coverage,
+						      horz_res, vert_res,
+						      minx, miny, maxx, maxy,
+						      width, height,
+						      mono_band, compression,
+						      tile_sz, worldfile);
       }
+
     if (ret != RL2_OK)
       {
 	  errcode = 0;
@@ -4646,86 +5312,75 @@ common_write_triple_band_tiff (int with_worldfile, sqlite3_context * context,
 }
 
 static void
-fnct_WriteTripleBandTiffTfw (sqlite3_context * context, int argc,
-			     sqlite3_value ** argv)
+fnct_WriteMonoBandGeoTiff (sqlite3_context * context, int argc,
+			   sqlite3_value ** argv)
 {
 /* SQL function:
-/ WriteTripleBandTiffTfw(text coverage, text tiff_path, int width,
-/              int height, int red_band, int green_band, int blue_band,
-/              BLOB geom, double resolution)
-/ WriteTripleBandTiffTfw(text coverage, text tiff_path, int width,
-/              int height, int red_band, int green_band, int blue_band,
-/              BLOB geom, double horz_res, double vert_res)
-/ WriteTripleBandTiffTfw(text coverage, text tiff_path, int width,
-/              int height, int red_band, int green_band, int blue_band,
-/              BLOB geom, double horz_res, double vert_res, 
-/              text compression)
-/ WriteTripleBandTiffTfw(text coverage, text tiff_path, int width,
-/              int height, int red_band, int green_band, int blue_band,
-/              BLOB geom, double horz_res, double vert_res, 
-/              text compression, int tile_sz)
+/ WriteMonoBandGeoTiff(text coverage, text geotiff_path, int width,
+/              int height, int mono_band, BLOB geom, double resolution)
+/ WriteMonoBandGeoTiff(text coverage, text geotiff_path, int width,
+/              int height, int mono_band, BLOB geom, double horz_res,
+/              double vert_res)
+/ WriteMonoBandGeoTiff(text coverage, text geotiff_path, int width,
+/              int height, int mono_band, BLOB geom, double horz_res,
+/              double vert_res, int with_worldfile)
+/ WriteMonoBandGeoTiff(text coverage, text geotiff_path, int width,
+/              int height, int mono_band, BLOB geom, double horz_res,
+/              double vert_res, int with_worldfile, text compression)
+/ WriteMonoBandGeoTiff(text coverage, text geotiff_path, int width,
+/              int height, int mono_band, BLOB geom, double horz_res,
+/              double vert_res, int with_worldfile, text compression,
+/              int tile_sz)
 /
 / will return 1 (TRUE, success) or 0 (FALSE, failure)
 / or -1 (INVALID ARGS)
 /
 */
-    common_write_triple_band_tiff (1, context, argc, argv);
+    common_write_mono_band_geotiff (0, context, argc, argv);
 }
 
 static void
-fnct_WriteTripleBandTiff (sqlite3_context * context, int argc,
-			  sqlite3_value ** argv)
+fnct_WriteSectionMonoBandGeoTiff (sqlite3_context * context, int argc,
+				  sqlite3_value ** argv)
 {
 /* SQL function:
-/ WriteTripleBandTiff(text coverage, text tiff_path, int width,
-/           int height, int red_band, int green_band, int blue_band,
-/           BLOB geom, double resolution)
-/ WriteTripleBandTiff(text coverage, text tiff_path, int width,
-/           int height, int red_band, int green_band, int blue_band,
-/           BLOB geom, double horz_res, double vert_res)
-/ WriteTripleBandTiff(text coverage, text tiff_path, int width,
-/           int height, int red_band, int green_band, int blue_band,
-/           BLOB geom, double horz_res, double vert_res,
-/           text compression)
-/ WriteTripleBandTiff(text coverage, text tiff_path, int width,
-/           int height, int red_band, int green_band, int blue_band,
-/           BLOB geom, double horz_res, double vert_res,
-/           text compression, int tile_sz)
+/ WriteSectionMonoBandGeoTiff(text coverage, int section_id,
+/              text geotiff_path, int width, int height, int mono_band,
+/              BLOB geom, double resolution)
+/ WriteSectionMonoBandGeoTiff(text coverage, int section_id,
+/              text geotiff_path, int width, int height, int mono_band,
+/              BLOB geom, double horz_res, double vert_res)
+/ WriteSectionMonoBandGeoTiff(text coverage, int section_id,
+/              text geotiff_path, int width, int height, int mono_band,
+/              BLOB geom, double horz_res, double vert_res,
+/              int with_worldfile)
+/ WriteSectionMonoBandGeoTiff(text coverage, int section_id,
+/              text geotiff_path, int width, int height, int mono_band,
+/              BLOB geom, double horz_res, double vert_res,
+/              int with_worldfile, text compression)
+/ WriteSectionMonoBandGeoTiff(text coverage, int section_id,
+/              text geotiff_path, int width, int height, int mono_band,
+/              BLOB geom, double horz_res, double vert_res,
+/              int with_worldfile, text compression, int tile_sz)
 /
 / will return 1 (TRUE, success) or 0 (FALSE, failure)
 / or -1 (INVALID ARGS)
 /
 */
-    common_write_triple_band_tiff (0, context, argc, argv);
+    common_write_mono_band_geotiff (1, context, argc, argv);
 }
 
 static void
-common_write_mono_band_tiff (int with_worldfile, sqlite3_context * context,
-			     int argc, sqlite3_value ** argv)
+common_write_tiff (int by_section, int with_worldfile,
+		   sqlite3_context * context, int argc, sqlite3_value ** argv)
 {
-/* SQL function:
-/ WriteMonoBandTiff?(text coverage, text tiff_path, int width,
-/            int height, int mono_band, BLOB geom, double resolution)
-/ WriteMonoBandTiff?(text coverage, text tiff_path, int width,
-/            int height, int mono_band, BLOB geom, double horz_res,
-/            double vert_res)
-/ WriteMonoBandTiff?(text coverage, text tiff_path, int width,
-/            int height, int mono_band, BLOB geom, double horz_res,
-/            double vert_res, text compression)
-/ WriteMonoBandTiff?(text coverage, text tiff_path, int width,
-/            int height, int mono_band, BLOB geom, double horz_res,
-/            double vert_res, text compression, int tile_sz)
-/
-/ will return 1 (TRUE, success) or 0 (FALSE, failure)
-/ or -1 (INVALID ARGS)
-/
-*/
+/* common implementation Write TIFF */
     int err = 0;
     const char *cvg_name;
     const char *path;
+    sqlite3_int64 section_id = 0;
     int width;
     int height;
-    int mono_band;
     const unsigned char *blob;
     int blob_sz;
     double horz_res;
@@ -4734,37 +5389,68 @@ common_write_mono_band_tiff (int with_worldfile, sqlite3_context * context,
     int tile_sz = 256;
     rl2CoveragePtr coverage = NULL;
     sqlite3 *sqlite;
+    const void *data;
+    int max_threads = 1;
     int ret;
     int errcode = -1;
-    gaiaGeomCollPtr geom;
+    double pt_x;
+    double pt_y;
     double minx;
     double maxx;
     double miny;
     double maxy;
     RL2_UNUSED ();		/* LCOV_EXCL_LINE */
 
-    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
-	err = 1;
-    if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
-	err = 1;
-    if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
-	err = 1;
-    if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
-	err = 1;
-    if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
-	err = 1;
-    if (sqlite3_value_type (argv[5]) != SQLITE_BLOB)
-	err = 1;
-    if (sqlite3_value_type (argv[6]) != SQLITE_INTEGER
-	&& sqlite3_value_type (argv[6]) != SQLITE_FLOAT)
-	err = 1;
-    if (argc > 7 && sqlite3_value_type (argv[7]) != SQLITE_INTEGER
-	&& sqlite3_value_type (argv[7]) != SQLITE_FLOAT)
-	err = 1;
-    if (argc > 8 && sqlite3_value_type (argv[8]) != SQLITE_TEXT)
-	err = 1;
-    if (argc > 9 && sqlite3_value_type (argv[9]) != SQLITE_INTEGER)
-	err = 1;
+    if (by_section)
+      {
+	  /* filtering by Section */
+	  if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[1]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[2]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[5]) != SQLITE_BLOB)
+	      err = 1;
+	  if (sqlite3_value_type (argv[6]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[6]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 7 && sqlite3_value_type (argv[7]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[7]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 8 && sqlite3_value_type (argv[8]) != SQLITE_TEXT)
+	      err = 1;
+	  if (argc > 9 && sqlite3_value_type (argv[9]) != SQLITE_INTEGER)
+	      err = 1;
+      }
+    else
+      {
+	  /* whole Coverage */
+	  if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[4]) != SQLITE_BLOB)
+	      err = 1;
+	  if (sqlite3_value_type (argv[5]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[5]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 6 && sqlite3_value_type (argv[6]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[6]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 7 && sqlite3_value_type (argv[7]) != SQLITE_TEXT)
+	      err = 1;
+	  if (argc > 8 && sqlite3_value_type (argv[8]) != SQLITE_INTEGER)
+	      err = 1;
+      }
     if (err)
       {
 	  sqlite3_result_int (context, -1);
@@ -4772,64 +5458,111 @@ common_write_mono_band_tiff (int with_worldfile, sqlite3_context * context,
       }
 
 /* retrieving all arguments */
-    cvg_name = (const char *) sqlite3_value_text (argv[0]);
-    path = (const char *) sqlite3_value_text (argv[1]);
-    width = sqlite3_value_int (argv[2]);
-    height = sqlite3_value_int (argv[3]);
-    mono_band = sqlite3_value_int (argv[4]);
-    blob = sqlite3_value_blob (argv[5]);
-    blob_sz = sqlite3_value_bytes (argv[5]);
-    if (sqlite3_value_type (argv[6]) == SQLITE_INTEGER)
-      {
-	  int ival = sqlite3_value_int (argv[6]);
-	  horz_res = ival;
-      }
-    else
-	horz_res = sqlite3_value_double (argv[6]);
-    if (argc > 7)
-      {
-	  if (sqlite3_value_type (argv[7]) == SQLITE_INTEGER)
+    if (by_section)
+      {
+	  /* filtering by Section */
+	  cvg_name = (const char *) sqlite3_value_text (argv[0]);
+	  section_id = sqlite3_value_int64 (argv[1]);
+	  path = (const char *) sqlite3_value_text (argv[2]);
+	  width = sqlite3_value_int (argv[3]);
+	  height = sqlite3_value_int (argv[4]);
+	  blob = sqlite3_value_blob (argv[5]);
+	  blob_sz = sqlite3_value_bytes (argv[5]);
+	  if (sqlite3_value_type (argv[6]) == SQLITE_INTEGER)
 	    {
-		int ival = sqlite3_value_int (argv[7]);
-		vert_res = ival;
+		int ival = sqlite3_value_int (argv[6]);
+		horz_res = ival;
+	    }
+	  else
+	      horz_res = sqlite3_value_double (argv[6]);
+	  if (argc > 7)
+	    {
+		if (sqlite3_value_type (argv[7]) == SQLITE_INTEGER)
+		  {
+		      int ival = sqlite3_value_int (argv[7]);
+		      vert_res = ival;
+		  }
+		else
+		    vert_res = sqlite3_value_double (argv[7]);
 	    }
 	  else
-	      vert_res = sqlite3_value_double (argv[7]);
+	      vert_res = horz_res;
+	  if (argc > 8)
+	    {
+		const char *compr = (const char *) sqlite3_value_text (argv[8]);
+		compression = RL2_COMPRESSION_UNKNOWN;
+		if (strcasecmp (compr, "NONE") == 0)
+		    compression = RL2_COMPRESSION_NONE;
+		if (strcasecmp (compr, "DEFLATE") == 0)
+		    compression = RL2_COMPRESSION_DEFLATE;
+		if (strcasecmp (compr, "LZW") == 0)
+		    compression = RL2_COMPRESSION_LZW;
+		if (strcasecmp (compr, "JPEG") == 0)
+		    compression = RL2_COMPRESSION_JPEG;
+		if (strcasecmp (compr, "FAX3") == 0)
+		    compression = RL2_COMPRESSION_CCITTFAX3;
+		if (strcasecmp (compr, "FAX4") == 0)
+		    compression = RL2_COMPRESSION_CCITTFAX4;
+	    }
+	  if (argc > 9)
+	      tile_sz = sqlite3_value_int (argv[9]);
       }
     else
-	vert_res = horz_res;
-    if (argc > 8)
       {
-	  const char *compr = (const char *) sqlite3_value_text (argv[8]);
-	  compression = RL2_COMPRESSION_UNKNOWN;
-	  if (strcasecmp (compr, "NONE") == 0)
-	      compression = RL2_COMPRESSION_NONE;
-	  if (strcasecmp (compr, "DEFLATE") == 0)
-	      compression = RL2_COMPRESSION_DEFLATE;
-	  if (strcasecmp (compr, "LZW") == 0)
-	      compression = RL2_COMPRESSION_LZW;
-	  if (strcasecmp (compr, "JPEG") == 0)
-	      compression = RL2_COMPRESSION_JPEG;
-	  if (strcasecmp (compr, "FAX3") == 0)
-	      compression = RL2_COMPRESSION_CCITTFAX3;
-	  if (strcasecmp (compr, "FAX4") == 0)
-	      compression = RL2_COMPRESSION_CCITTFAX4;
+	  /* whole Coverage */
+	  cvg_name = (const char *) sqlite3_value_text (argv[0]);
+	  path = (const char *) sqlite3_value_text (argv[1]);
+	  width = sqlite3_value_int (argv[2]);
+	  height = sqlite3_value_int (argv[3]);
+	  blob = sqlite3_value_blob (argv[4]);
+	  blob_sz = sqlite3_value_bytes (argv[4]);
+	  if (sqlite3_value_type (argv[5]) == SQLITE_INTEGER)
+	    {
+		int ival = sqlite3_value_int (argv[5]);
+		horz_res = ival;
+	    }
+	  else
+	      horz_res = sqlite3_value_double (argv[5]);
+	  if (argc > 6)
+	    {
+		if (sqlite3_value_type (argv[6]) == SQLITE_INTEGER)
+		  {
+		      int ival = sqlite3_value_int (argv[6]);
+		      vert_res = ival;
+		  }
+		else
+		    vert_res = sqlite3_value_double (argv[6]);
+	    }
+	  else
+	      vert_res = horz_res;
+	  if (argc > 7)
+	    {
+		const char *compr = (const char *) sqlite3_value_text (argv[7]);
+		compression = RL2_COMPRESSION_UNKNOWN;
+		if (strcasecmp (compr, "NONE") == 0)
+		    compression = RL2_COMPRESSION_NONE;
+		if (strcasecmp (compr, "DEFLATE") == 0)
+		    compression = RL2_COMPRESSION_DEFLATE;
+		if (strcasecmp (compr, "LZW") == 0)
+		    compression = RL2_COMPRESSION_LZW;
+		if (strcasecmp (compr, "JPEG") == 0)
+		    compression = RL2_COMPRESSION_JPEG;
+		if (strcasecmp (compr, "FAX3") == 0)
+		    compression = RL2_COMPRESSION_CCITTFAX3;
+		if (strcasecmp (compr, "FAX4") == 0)
+		    compression = RL2_COMPRESSION_CCITTFAX4;
+	    }
+	  if (argc > 8)
+	      tile_sz = sqlite3_value_int (argv[8]);
       }
-    if (argc > 9)
-	tile_sz = sqlite3_value_int (argv[9]);
 
 /* coarse args validation */
-    if (width < 0 || width > UINT16_MAX)
-      {
-	  errcode = -1;
-	  goto error;
-      }
-    if (height < 0 || height > UINT16_MAX)
+    if (width < 0)
       {
 	  errcode = -1;
 	  goto error;
       }
-    if (mono_band < 0 || mono_band > 255)
+    if (height < 0)
       {
 	  errcode = -1;
 	  goto error;
@@ -4845,67 +5578,106 @@ common_write_mono_band_tiff (int with_worldfile, sqlite3_context * context,
 	  goto error;
       }
 
-/* checking the Geometry */
-    geom = gaiaFromSpatiaLiteBlobWkb (blob, blob_sz);
-    if (geom == NULL)
+    sqlite = sqlite3_context_db_handle (context);
+    data = sqlite3_user_data (context);
+    if (data != NULL)
       {
-	  errcode = -1;
-	  goto error;
+	  struct rl2_private_data *priv_data = (struct rl2_private_data *) data;
+	  max_threads = priv_data->max_threads;
+	  if (max_threads < 1)
+	      max_threads = 1;
+	  if (max_threads > 64)
+	      max_threads = 64;
+      }
+    if (!by_section)
+      {
+	  /* excluding any Mixed Resolution Coverage */
+	  if (rl2_is_mixed_resolutions_coverage (sqlite, cvg_name) > 0)
+	      goto error;
       }
-    if (is_point (geom))
+
+/* checking the Geometry */
+    if (rl2_parse_point (sqlite, blob, blob_sz, &pt_x, &pt_y) == RL2_OK)
       {
 	  /* assumed to be the GeoTiff Center Point */
-	  gaiaPointPtr pt = geom->FirstPoint;
 	  double ext_x = (double) width * horz_res;
 	  double ext_y = (double) height * vert_res;
-	  minx = pt->X - ext_x / 2.0;
+	  minx = pt_x - ext_x / 2.0;
 	  maxx = minx + ext_x;
-	  miny = pt->Y - ext_y / 2.0;
+	  miny = pt_y - ext_y / 2.0;
 	  maxy = miny + ext_y;
       }
-    else
+    else if (rl2_parse_bbox
+	     (sqlite, blob, blob_sz, &minx, &miny, &maxx, &maxy) != RL2_OK)
       {
-	  /* assumed to be any possible Geometry defining a BBOX */
-	  minx = geom->MinX;
-	  maxx = geom->MaxX;
-	  miny = geom->MinY;
-	  maxy = geom->MaxY;
+	  errcode = -1;
+	  goto error;
       }
-    gaiaFreeGeomColl (geom);
 
 /* attempting to load the Coverage definitions from the DBMS */
-    sqlite = sqlite3_context_db_handle (context);
     coverage = rl2_create_coverage_from_dbms (sqlite, cvg_name);
     if (coverage == NULL)
       {
 	  sqlite3_result_int (context, -1);
 	  return;
       }
-
-    if (with_worldfile)
+    if (by_section)
       {
-	  /* TIFF + Worldfile */
-	  ret =
-	      rl2_export_mono_band_tiff_worldfile_from_dbms (sqlite, path,
-							     coverage,
-							     horz_res,
-							     vert_res, minx,
-							     miny, maxx,
-							     maxy, width,
-							     height,
-							     mono_band,
-							     compression,
-							     tile_sz);
+	  /* only a single Section */
+	  if (with_worldfile)
+	    {
+		/* TIFF + Worldfile */
+		ret =
+		    rl2_export_section_tiff_worldfile_from_dbms (sqlite,
+								 max_threads,
+								 path,
+								 coverage,
+								 section_id,
+								 horz_res,
+								 vert_res,
+								 minx, miny,
+								 maxx, maxy,
+								 width,
+								 height,
+								 compression,
+								 tile_sz);
+	    }
+	  else
+	    {
+		/* plain TIFF, no Worldfile */
+		ret =
+		    rl2_export_section_tiff_from_dbms (sqlite, max_threads,
+						       path, coverage,
+						       section_id, horz_res,
+						       vert_res, minx, miny,
+						       maxx, maxy, width,
+						       height, compression,
+						       tile_sz);
+	    }
       }
     else
       {
-	  /* plain TIFF, no Worldfile */
-	  ret =
-	      rl2_export_mono_band_tiff_from_dbms (sqlite, path, coverage,
-						   horz_res, vert_res, minx,
-						   miny, maxx, maxy, width,
-						   height, mono_band,
-						   compression, tile_sz);
+	  /* whole Coverage */
+	  if (with_worldfile)
+	    {
+		/* TIFF + Worldfile */
+		ret =
+		    rl2_export_tiff_worldfile_from_dbms (sqlite, max_threads,
+							 path, coverage,
+							 horz_res, vert_res,
+							 minx, miny, maxx,
+							 maxy, width, height,
+							 compression, tile_sz);
+	    }
+	  else
+	    {
+		/* plain TIFF, no Worldfile */
+		ret =
+		    rl2_export_tiff_from_dbms (sqlite, max_threads, path,
+					       coverage, horz_res, vert_res,
+					       minx, miny, maxx, maxy, width,
+					       height, compression, tile_sz);
+	    }
       }
     if (ret != RL2_OK)
       {
@@ -4923,108 +5695,175 @@ common_write_mono_band_tiff (int with_worldfile, sqlite3_context * context,
 }
 
 static void
-fnct_WriteMonoBandTiffTfw (sqlite3_context * context, int argc,
-			   sqlite3_value ** argv)
+fnct_WriteTiffTfw (sqlite3_context * context, int argc, sqlite3_value ** argv)
 {
 /* SQL function:
-/ WriteMonoBandTiffTfw(text coverage, text tiff_path, int width,
-/              int height, int mono_band, BLOB geom, double resolution)
-/ WriteMonoBandTiffTfw(text coverage, text tiff_path, int width,
-/              int height, int mono_band, BLOB geom, double horz_res,
+/ WriteTiffTfw(text coverage, text tiff_path, int width,
+/              int height, BLOB geom, double resolution)
+/ WriteTiffTfw(text coverage, text tiff_path, int width,
+/              int height, BLOB geom, double horz_res,
 /              double vert_res)
-/ WriteMonoBandTiffTfw(text coverage, text tiff_path, int width,
-/              int height, int mono_band, BLOB geom, double horz_res,
+/ WriteTiffTfw(text coverage, text tiff_path, int width,
+/              int height, BLOB geom, double horz_res,
 /              double vert_res, text compression)
-/ WriteMonoBandTiffTfw(text coverage, text tiff_path, int width,
-/              int height, int mono_band, BLOB geom, double horz_res,
+/ WriteTiffTfw(text coverage, text tiff_path, int width,
+/              int height, BLOB geom, double horz_res,
 /              double vert_res, text compression, int tile_sz)
 /
 / will return 1 (TRUE, success) or 0 (FALSE, failure)
 / or -1 (INVALID ARGS)
 /
 */
-    common_write_mono_band_tiff (1, context, argc, argv);
+    common_write_tiff (0, 1, context, argc, argv);
 }
 
 static void
-fnct_WriteMonoBandTiff (sqlite3_context * context, int argc,
-			sqlite3_value ** argv)
+fnct_WriteTiff (sqlite3_context * context, int argc, sqlite3_value ** argv)
 {
 /* SQL function:
-/ WriteMonoBandTiff(text coverage, text tiff_path, int width,
-/           int height, int mono_band, BLOB geom, double resolution)
-/ WriteMonoBandTiff(text coverage, text tiff_path, int width,
-/           int height, int mono_band, BLOB geom, double horz_res,
-/           double vert_res)
-/ WriteMonoBandTiff(text coverage, text tiff_path, int width,
-/           int height, int mono_band, BLOB geom, double horz_res,
-/           double vert_res, text compression)
-/ WriteMonoBandTiff(text coverage, text tiff_path, int width,
-/           int height, int mono_band, BLOB geom, double horz_res,
+/ WriteTiff(text coverage, text tiff_path, int width,
+/           int height, BLOB geom, double resolution)
+/ WriteTiff(text coverage, text tiff_path, int width,
+/           int height, BLOB geom, double horz_res,
+/              double vert_res)
+/ WriteTiff(text coverage, text tiff_path, int width,
+/           int height, BLOB geom, double horz_res,
+/              double vert_res, text compression)
+/ WriteTiff(text coverage, text tiff_path, int width,
+/           int height, BLOB geom, double horz_res,
 /           double vert_res, text compression, int tile_sz)
 /
 / will return 1 (TRUE, success) or 0 (FALSE, failure)
 / or -1 (INVALID ARGS)
 /
 */
-    common_write_mono_band_tiff (0, context, argc, argv);
+    common_write_tiff (0, 0, context, argc, argv);
 }
 
 static void
-fnct_WriteAsciiGrid (sqlite3_context * context, int argc, sqlite3_value ** argv)
+fnct_WriteSectionTiffTfw (sqlite3_context * context, int argc,
+			  sqlite3_value ** argv)
 {
 /* SQL function:
-/ WriteAsciiGrid(text coverage, text tiff_path, int width,
-/           int height, BLOB geom, double resolution)
-/ WriteTiff(text coverage, text tiff_path, int width,
-/           int height, BLOB geom, double resolution, 
-/           int is_centered)
-/ WriteTiff(text coverage, text tiff_path, int width,
-/           int height, BLOB geom, double resolution, 
-/           int is_centered, int decimal_digits)
+/ WriteSectionTiffTfw(text coverage, int section_id, text tiff_path,
+/                     int width, int height, BLOB geom, double resolution)
+/ WriteSectionTiffTfw(text coverage, int section_id, text tiff_path,
+/                     int width, int height, BLOB geom, double horz_res,
+/                     double vert_res)
+/ WriteSectionTiffTfw(text coverage, int section_id, text tiff_path,
+/                     int width, int height, BLOB geom, double horz_res,
+/                     double vert_res, text compression)
+/ WriteSectionTiffTfw(text coverage, int section_id, text tiff_path,
+/                     int width, int height, BLOB geom, double horz_res,
+/                     double vert_res, text compression, int tile_sz)
+/
+/ will return 1 (TRUE, success) or 0 (FALSE, failure)
+/ or -1 (INVALID ARGS)
+/
+*/
+    common_write_tiff (1, 1, context, argc, argv);
+}
+
+static void
+fnct_WriteSectionTiff (sqlite3_context * context, int argc,
+		       sqlite3_value ** argv)
+{
+/* SQL function:
+/ WriteSectionTiff(text coverage, int section_id, text tiff_path,
+/                  int width, int height, BLOB geom, double resolution)
+/ WriteSectionTiff(text coverage, int section_id, text tiff_path,
+/                  int width, int height, BLOB geom, double horz_res,
+/                  double vert_res)
+/ WriteSectionTiff(text coverage, int section_id, text tiff_path,
+/                  int width, int height, BLOB geom, double horz_res,
+/                  double vert_res, text compression)
+/ WriteSectionTiff(text coverage, int section_id, text tiff_path,
+/                  int width, int height, BLOB geom, double horz_res,
+/                  double vert_res, text compression, int tile_sz)
 /
 / will return 1 (TRUE, success) or 0 (FALSE, failure)
 / or -1 (INVALID ARGS)
 /
 */
+    common_write_tiff (1, 0, context, argc, argv);
+}
+
+static void
+common_write_jpeg (int with_worldfile, int by_section,
+		   sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+/* common implementation for Write JPEG */
     int err = 0;
     const char *cvg_name;
     const char *path;
+    sqlite3_int64 section_id = 0;
     int width;
     int height;
     const unsigned char *blob;
     int blob_sz;
-    double resolution;
+    double horz_res;
+    double vert_res;
+    int quality = 80;
     rl2CoveragePtr coverage = NULL;
     sqlite3 *sqlite;
+    const void *data;
+    int max_threads = 1;
     int ret;
     int errcode = -1;
-    gaiaGeomCollPtr geom;
+    double pt_x;
+    double pt_y;
     double minx;
     double maxx;
     double miny;
     double maxy;
-    int is_centered = 1;
-    int decimal_digits = 4;
     RL2_UNUSED ();		/* LCOV_EXCL_LINE */
 
-    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
-	err = 1;
-    if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
-	err = 1;
-    if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
-	err = 1;
-    if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
-	err = 1;
-    if (sqlite3_value_type (argv[4]) != SQLITE_BLOB)
-	err = 1;
-    if (sqlite3_value_type (argv[5]) != SQLITE_INTEGER
-	&& sqlite3_value_type (argv[5]) != SQLITE_FLOAT)
-	err = 1;
-    if (argc > 6 && sqlite3_value_type (argv[6]) != SQLITE_INTEGER)
-	err = 1;
-    if (argc > 7 && sqlite3_value_type (argv[7]) != SQLITE_INTEGER)
-	err = 1;
+    if (by_section)
+      {
+	  /* single Section */
+	  if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[1]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[2]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[5]) != SQLITE_BLOB)
+	      err = 1;
+	  if (sqlite3_value_type (argv[6]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[6]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 7 && sqlite3_value_type (argv[7]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[7]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 8 && sqlite3_value_type (argv[8]) != SQLITE_INTEGER)
+	      err = 1;
+      }
+    else
+      {
+	  /* whole Coverage */
+	  if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[4]) != SQLITE_BLOB)
+	      err = 1;
+	  if (sqlite3_value_type (argv[5]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[5]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 6 && sqlite3_value_type (argv[6]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[6]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 7 && sqlite3_value_type (argv[7]) != SQLITE_INTEGER)
+	      err = 1;
+      }
     if (err)
       {
 	  sqlite3_result_int (context, -1);
@@ -5032,71 +5871,123 @@ fnct_WriteAsciiGrid (sqlite3_context * context, int argc, sqlite3_value ** argv)
       }
 
 /* retrieving all arguments */
-    cvg_name = (const char *) sqlite3_value_text (argv[0]);
-    path = (const char *) sqlite3_value_text (argv[1]);
-    width = sqlite3_value_int (argv[2]);
-    height = sqlite3_value_int (argv[3]);
-    blob = sqlite3_value_blob (argv[4]);
-    blob_sz = sqlite3_value_bytes (argv[4]);
-    if (sqlite3_value_type (argv[5]) == SQLITE_INTEGER)
-      {
-	  int ival = sqlite3_value_int (argv[5]);
-	  resolution = ival;
+    if (by_section)
+      {
+	  /* single Section */
+	  cvg_name = (const char *) sqlite3_value_text (argv[0]);
+	  section_id = sqlite3_value_int64 (argv[1]);
+	  path = (const char *) sqlite3_value_text (argv[2]);
+	  width = sqlite3_value_int (argv[3]);
+	  height = sqlite3_value_int (argv[4]);
+	  blob = sqlite3_value_blob (argv[5]);
+	  blob_sz = sqlite3_value_bytes (argv[5]);
+	  if (sqlite3_value_type (argv[6]) == SQLITE_INTEGER)
+	    {
+		int ival = sqlite3_value_int (argv[6]);
+		horz_res = ival;
+	    }
+	  else
+	      horz_res = sqlite3_value_double (argv[6]);
+	  if (argc > 7)
+	    {
+		if (sqlite3_value_type (argv[7]) == SQLITE_INTEGER)
+		  {
+		      int ival = sqlite3_value_int (argv[7]);
+		      vert_res = ival;
+		  }
+		else
+		    vert_res = sqlite3_value_double (argv[7]);
+	    }
+	  else
+	      vert_res = horz_res;
+	  if (argc > 8)
+	      quality = sqlite3_value_int (argv[8]);
       }
     else
-	resolution = sqlite3_value_double (argv[5]);
-    if (argc > 6)
-	is_centered = sqlite3_value_int (argv[6]);
-    if (argc > 7)
-	decimal_digits = sqlite3_value_int (argv[7]);
-
-    if (decimal_digits < 1)
-	decimal_digits = 0;
-    if (decimal_digits > 18)
-	decimal_digits = 18;
+      {
+	  /* whole Coverage */
+	  cvg_name = (const char *) sqlite3_value_text (argv[0]);
+	  path = (const char *) sqlite3_value_text (argv[1]);
+	  width = sqlite3_value_int (argv[2]);
+	  height = sqlite3_value_int (argv[3]);
+	  blob = sqlite3_value_blob (argv[4]);
+	  blob_sz = sqlite3_value_bytes (argv[4]);
+	  if (sqlite3_value_type (argv[5]) == SQLITE_INTEGER)
+	    {
+		int ival = sqlite3_value_int (argv[5]);
+		horz_res = ival;
+	    }
+	  else
+	      horz_res = sqlite3_value_double (argv[5]);
+	  if (argc > 6)
+	    {
+		if (sqlite3_value_type (argv[6]) == SQLITE_INTEGER)
+		  {
+		      int ival = sqlite3_value_int (argv[6]);
+		      vert_res = ival;
+		  }
+		else
+		    vert_res = sqlite3_value_double (argv[6]);
+	    }
+	  else
+	      vert_res = horz_res;
+	  if (argc > 7)
+	      quality = sqlite3_value_int (argv[7]);
+      }
 
 /* coarse args validation */
-    if (width < 0 || width > UINT16_MAX)
+    if (width < 0)
       {
 	  errcode = -1;
 	  goto error;
       }
-    if (height < 0 || height > UINT16_MAX)
+    if (height < 0)
       {
 	  errcode = -1;
 	  goto error;
       }
+    if (quality < 0)
+	quality = 0;
+    if (quality > 100)
+	quality = 100;
 
-/* checking the Geometry */
-    geom = gaiaFromSpatiaLiteBlobWkb (blob, blob_sz);
-    if (geom == NULL)
+    sqlite = sqlite3_context_db_handle (context);
+    data = sqlite3_user_data (context);
+    if (data != NULL)
       {
-	  errcode = -1;
-	  goto error;
+	  struct rl2_private_data *priv_data = (struct rl2_private_data *) data;
+	  max_threads = priv_data->max_threads;
+	  if (max_threads < 1)
+	      max_threads = 1;
+	  if (max_threads > 64)
+	      max_threads = 64;
+      }
+    if (!by_section)
+      {
+	  /* excluding any Mixed Resolution Coverage */
+	  if (rl2_is_mixed_resolutions_coverage (sqlite, cvg_name) > 0)
+	      goto error;
       }
-    if (is_point (geom))
+
+/* checking the Geometry */
+    if (rl2_parse_point (sqlite, blob, blob_sz, &pt_x, &pt_y) == RL2_OK)
       {
 	  /* assumed to be the GeoTiff Center Point */
-	  gaiaPointPtr pt = geom->FirstPoint;
-	  double ext_x = (double) width * resolution;
-	  double ext_y = (double) height * resolution;
-	  minx = pt->X - ext_x / 2.0;
+	  double ext_x = (double) width * horz_res;
+	  double ext_y = (double) height * vert_res;
+	  minx = pt_x - ext_x / 2.0;
 	  maxx = minx + ext_x;
-	  miny = pt->Y - ext_y / 2.0;
+	  miny = pt_y - ext_y / 2.0;
 	  maxy = miny + ext_y;
       }
-    else
+    else if (rl2_parse_bbox
+	     (sqlite, blob, blob_sz, &minx, &miny, &maxx, &maxy) != RL2_OK)
       {
-	  /* assumed to be any possible Geometry defining a BBOX */
-	  minx = geom->MinX;
-	  maxx = geom->MaxX;
-	  miny = geom->MinY;
-	  maxy = geom->MaxY;
+	  errcode = -1;
+	  goto error;
       }
-    gaiaFreeGeomColl (geom);
 
 /* attempting to load the Coverage definitions from the DBMS */
-    sqlite = sqlite3_context_db_handle (context);
     coverage = rl2_create_coverage_from_dbms (sqlite, cvg_name);
     if (coverage == NULL)
       {
@@ -5104,58 +5995,2250 @@ fnct_WriteAsciiGrid (sqlite3_context * context, int argc, sqlite3_value ** argv)
 	  return;
       }
 
-    ret =
-	rl2_export_ascii_grid_from_dbms (sqlite, path, coverage,
-					 resolution, minx,
-					 miny, maxx, maxy, width,
-					 height, is_centered, decimal_digits);
-    if (ret != RL2_OK)
-      {
-	  errcode = 0;
-	  goto error;
-      }
+    if (by_section)
+      {
+	  /* single Section */
+	  ret =
+	      rl2_export_section_jpeg_from_dbms (sqlite, max_threads, path,
+						 coverage, section_id,
+						 horz_res, vert_res, minx,
+						 miny, maxx, maxy, width,
+						 height, quality,
+						 with_worldfile);
+      }
+    else
+      {
+	  /* whole Coverage */
+	  ret =
+	      rl2_export_jpeg_from_dbms (sqlite, max_threads, path, coverage,
+					 horz_res, vert_res, minx, miny, maxx,
+					 maxy, width, height, quality,
+					 with_worldfile);
+      }
+    if (ret != RL2_OK)
+      {
+	  errcode = 0;
+	  goto error;
+      }
+    rl2_destroy_coverage (coverage);
+    sqlite3_result_int (context, 1);
+    return;
+
+  error:
+    if (coverage != NULL)
+	rl2_destroy_coverage (coverage);
+    sqlite3_result_int (context, errcode);
+}
+
+static void
+fnct_WriteJpegJgw (sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+/* SQL function:
+/ WriteJpegJgw(text coverage, text jpeg_path, int width,
+/              int height, BLOB geom, double resolution)
+/ WriteJpegJgw(text coverage, text jpeg_path, int width,
+/              int height, BLOB geom, double horz_res,
+/              double vert_res)
+/ WriteJpegJgw(text coverage, text jpeg_path, int width,
+/              int height, BLOB geom, double horz_res,
+/              double vert_res, int quality)
+/
+/ will return 1 (TRUE, success) or 0 (FALSE, failure)
+/ or -1 (INVALID ARGS)
+/
+*/
+    common_write_jpeg (1, 0, context, argc, argv);
+}
+
+static void
+fnct_WriteJpeg (sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+/* SQL function:
+/ WriteJpeg(text coverage, text jpeg_path, int width,
+/           int height, BLOB geom, double resolution)
+/ WriteJpeg(text coverage, text jpeg_path, int width,
+/           int height, BLOB geom, double horz_res,
+/              double vert_res)
+/ WriteJpeg(text coverage, text jpeg_path, int width,
+/           int height, BLOB geom, double horz_res,
+/              double vert_res, int quality)
+/
+/ will return 1 (TRUE, success) or 0 (FALSE, failure)
+/ or -1 (INVALID ARGS)
+/
+*/
+    common_write_jpeg (0, 0, context, argc, argv);
+}
+
+static void
+fnct_WriteSectionJpegJgw (sqlite3_context * context, int argc,
+			  sqlite3_value ** argv)
+{
+/* SQL function:
+/ WriteSectionJpegJgw(text coverage, int section_id, text jpeg_path,
+/                     int width, int height, BLOB geom, 
+/                     double resolution)
+/ WriteSectionJpegJgw(text coverage, int section_id, text jpeg_path,
+/                     int width, int height, BLOB geom,
+/                     double horz_res, double vert_res)
+/ WriteSectionJpegJgw(text coverage, int section_id, text jpeg_path,
+/                     int width, int height, BLOB geom,
+/                     double horz_res, double vert_res, int quality)
+/
+/ will return 1 (TRUE, success) or 0 (FALSE, failure)
+/ or -1 (INVALID ARGS)
+/
+*/
+    common_write_jpeg (1, 1, context, argc, argv);
+}
+
+static void
+fnct_WriteSectionJpeg (sqlite3_context * context, int argc,
+		       sqlite3_value ** argv)
+{
+/* SQL function:
+/ WriteSectionJpeg(text coverage, int section_id, text jpeg_path,
+/                  int width, int height, BLOB geom, 
+/                  double resolution)
+/ WriteSectionJpeg(text coverage, int section_id, text jpeg_path,
+/                  int width, int height, BLOB geom, 
+/                  double horz_res, double vert_res)
+/ WriteSectionJpeg(text coverage, int section_id, text jpeg_path,
+/                  int width, int height, BLOB geom, 
+/                  double horz_res, double vert_res, int quality)
+/
+/ will return 1 (TRUE, success) or 0 (FALSE, failure)
+/ or -1 (INVALID ARGS)
+/
+*/
+    common_write_jpeg (0, 1, context, argc, argv);
+}
+
+static void
+common_write_triple_band_tiff (int with_worldfile, int by_section,
+			       sqlite3_context * context, int argc,
+			       sqlite3_value ** argv)
+{
+/* common implementation Write TripleBand TIFF */
+    int err = 0;
+    const char *cvg_name;
+    sqlite3_int64 section_id = 0;
+    const char *path;
+    int width;
+    int height;
+    int red_band;
+    int green_band;
+    int blue_band;
+    const unsigned char *blob;
+    int blob_sz;
+    double horz_res;
+    double vert_res;
+    unsigned char compression = RL2_COMPRESSION_NONE;
+    int tile_sz = 256;
+    rl2CoveragePtr coverage = NULL;
+    sqlite3 *sqlite;
+    int ret;
+    int errcode = -1;
+    double pt_x;
+    double pt_y;
+    double minx;
+    double maxx;
+    double miny;
+    double maxy;
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+
+    if (by_section)
+      {
+	  /* single Section */
+	  if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[1]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[2]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[5]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[6]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[7]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[8]) != SQLITE_BLOB)
+	      err = 1;
+	  if (sqlite3_value_type (argv[9]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[9]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 10 && sqlite3_value_type (argv[10]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[10]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 11 && sqlite3_value_type (argv[11]) != SQLITE_TEXT)
+	      err = 1;
+	  if (argc > 12 && sqlite3_value_type (argv[12]) != SQLITE_INTEGER)
+	      err = 1;
+      }
+    else
+      {
+	  /* whole Coverage */
+	  if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[5]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[6]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[7]) != SQLITE_BLOB)
+	      err = 1;
+	  if (sqlite3_value_type (argv[8]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[8]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 9 && sqlite3_value_type (argv[9]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[9]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 10 && sqlite3_value_type (argv[10]) != SQLITE_TEXT)
+	      err = 1;
+	  if (argc > 11 && sqlite3_value_type (argv[11]) != SQLITE_INTEGER)
+	      err = 1;
+      }
+    if (err)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+
+/* retrieving all arguments */
+    if (by_section)
+      {
+	  /* single Section */
+	  cvg_name = (const char *) sqlite3_value_text (argv[0]);
+	  section_id = sqlite3_value_int64 (argv[1]);
+	  path = (const char *) sqlite3_value_text (argv[2]);
+	  width = sqlite3_value_int (argv[3]);
+	  height = sqlite3_value_int (argv[4]);
+	  red_band = sqlite3_value_int (argv[5]);
+	  green_band = sqlite3_value_int (argv[6]);
+	  blue_band = sqlite3_value_int (argv[7]);
+	  blob = sqlite3_value_blob (argv[8]);
+	  blob_sz = sqlite3_value_bytes (argv[8]);
+	  if (sqlite3_value_type (argv[9]) == SQLITE_INTEGER)
+	    {
+		int ival = sqlite3_value_int (argv[9]);
+		horz_res = ival;
+	    }
+	  else
+	      horz_res = sqlite3_value_double (argv[9]);
+	  if (argc > 10)
+	    {
+		if (sqlite3_value_type (argv[10]) == SQLITE_INTEGER)
+		  {
+		      int ival = sqlite3_value_int (argv[10]);
+		      vert_res = ival;
+		  }
+		else
+		    vert_res = sqlite3_value_double (argv[10]);
+	    }
+	  else
+	      vert_res = horz_res;
+	  if (argc > 11)
+	    {
+		const char *compr =
+		    (const char *) sqlite3_value_text (argv[11]);
+		compression = RL2_COMPRESSION_UNKNOWN;
+		if (strcasecmp (compr, "NONE") == 0)
+		    compression = RL2_COMPRESSION_NONE;
+		if (strcasecmp (compr, "DEFLATE") == 0)
+		    compression = RL2_COMPRESSION_DEFLATE;
+		if (strcasecmp (compr, "LZW") == 0)
+		    compression = RL2_COMPRESSION_LZW;
+		if (strcasecmp (compr, "JPEG") == 0)
+		    compression = RL2_COMPRESSION_JPEG;
+		if (strcasecmp (compr, "FAX3") == 0)
+		    compression = RL2_COMPRESSION_CCITTFAX3;
+		if (strcasecmp (compr, "FAX4") == 0)
+		    compression = RL2_COMPRESSION_CCITTFAX4;
+	    }
+	  if (argc > 12)
+	      tile_sz = sqlite3_value_int (argv[12]);
+      }
+    else
+      {
+	  /* whole Coverage */
+	  cvg_name = (const char *) sqlite3_value_text (argv[0]);
+	  path = (const char *) sqlite3_value_text (argv[1]);
+	  width = sqlite3_value_int (argv[2]);
+	  height = sqlite3_value_int (argv[3]);
+	  red_band = sqlite3_value_int (argv[4]);
+	  green_band = sqlite3_value_int (argv[5]);
+	  blue_band = sqlite3_value_int (argv[6]);
+	  blob = sqlite3_value_blob (argv[7]);
+	  blob_sz = sqlite3_value_bytes (argv[7]);
+	  if (sqlite3_value_type (argv[8]) == SQLITE_INTEGER)
+	    {
+		int ival = sqlite3_value_int (argv[8]);
+		horz_res = ival;
+	    }
+	  else
+	      horz_res = sqlite3_value_double (argv[8]);
+	  if (argc > 9)
+	    {
+		if (sqlite3_value_type (argv[9]) == SQLITE_INTEGER)
+		  {
+		      int ival = sqlite3_value_int (argv[9]);
+		      vert_res = ival;
+		  }
+		else
+		    vert_res = sqlite3_value_double (argv[9]);
+	    }
+	  else
+	      vert_res = horz_res;
+	  if (argc > 10)
+	    {
+		const char *compr =
+		    (const char *) sqlite3_value_text (argv[10]);
+		compression = RL2_COMPRESSION_UNKNOWN;
+		if (strcasecmp (compr, "NONE") == 0)
+		    compression = RL2_COMPRESSION_NONE;
+		if (strcasecmp (compr, "DEFLATE") == 0)
+		    compression = RL2_COMPRESSION_DEFLATE;
+		if (strcasecmp (compr, "LZW") == 0)
+		    compression = RL2_COMPRESSION_LZW;
+		if (strcasecmp (compr, "JPEG") == 0)
+		    compression = RL2_COMPRESSION_JPEG;
+		if (strcasecmp (compr, "FAX3") == 0)
+		    compression = RL2_COMPRESSION_CCITTFAX3;
+		if (strcasecmp (compr, "FAX4") == 0)
+		    compression = RL2_COMPRESSION_CCITTFAX4;
+	    }
+	  if (argc > 11)
+	      tile_sz = sqlite3_value_int (argv[11]);
+      }
+
+/* coarse args validation */
+    if (width < 0)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+    if (height < 0)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+    if (red_band < 0 || red_band > 255)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+    if (green_band < 0 || green_band > 255)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+    if (blue_band < 0 || blue_band > 255)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+    if (tile_sz < 64 || tile_sz > UINT16_MAX)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+    if (compression == RL2_COMPRESSION_UNKNOWN)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+
+    sqlite = sqlite3_context_db_handle (context);
+    if (!by_section)
+      {
+	  /* excluding any Mixed Resolution Coverage */
+	  if (rl2_is_mixed_resolutions_coverage (sqlite, cvg_name) > 0)
+	      goto error;
+      }
+
+/* checking the Geometry */
+    if (rl2_parse_point (sqlite, blob, blob_sz, &pt_x, &pt_y) == RL2_OK)
+      {
+	  /* assumed to be the GeoTiff Center Point */
+	  double ext_x = (double) width * horz_res;
+	  double ext_y = (double) height * vert_res;
+	  minx = pt_x - ext_x / 2.0;
+	  maxx = minx + ext_x;
+	  miny = pt_y - ext_y / 2.0;
+	  maxy = miny + ext_y;
+      }
+    else if (rl2_parse_bbox
+	     (sqlite, blob, blob_sz, &minx, &miny, &maxx, &maxy) != RL2_OK)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+
+/* attempting to load the Coverage definitions from the DBMS */
+    coverage = rl2_create_coverage_from_dbms (sqlite, cvg_name);
+    if (coverage == NULL)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+
+    if (by_section)
+      {
+	  /* single Section */
+	  if (with_worldfile)
+	    {
+		/* TIFF + Worldfile */
+		ret =
+		    rl2_export_section_triple_band_tiff_worldfile_from_dbms
+		    (sqlite, path, coverage, section_id, horz_res, vert_res,
+		     minx, miny, maxx, maxy, width, height, red_band,
+		     green_band, blue_band, compression, tile_sz);
+	    }
+	  else
+	    {
+		/* plain TIFF, no Worldfile */
+		ret =
+		    rl2_export_section_triple_band_tiff_from_dbms (sqlite,
+								   path,
+								   coverage,
+								   section_id,
+								   horz_res,
+								   vert_res,
+								   minx, miny,
+								   maxx, maxy,
+								   width,
+								   height,
+								   red_band,
+								   green_band,
+								   blue_band,
+								   compression,
+								   tile_sz);
+	    }
+      }
+    else
+      {
+	  /* whole Coverage */
+	  if (with_worldfile)
+	    {
+		/* TIFF + Worldfile */
+		ret =
+		    rl2_export_triple_band_tiff_worldfile_from_dbms (sqlite,
+								     path,
+								     coverage,
+								     horz_res,
+								     vert_res,
+								     minx,
+								     miny,
+								     maxx,
+								     maxy,
+								     width,
+								     height,
+								     red_band,
+								     green_band,
+								     blue_band,
+								     compression,
+								     tile_sz);
+	    }
+	  else
+	    {
+		/* plain TIFF, no Worldfile */
+		ret =
+		    rl2_export_triple_band_tiff_from_dbms (sqlite, path,
+							   coverage, horz_res,
+							   vert_res, minx,
+							   miny, maxx, maxy,
+							   width, height,
+							   red_band,
+							   green_band,
+							   blue_band,
+							   compression,
+							   tile_sz);
+	    }
+      }
+    if (ret != RL2_OK)
+      {
+	  errcode = 0;
+	  goto error;
+      }
+    rl2_destroy_coverage (coverage);
+    sqlite3_result_int (context, 1);
+    return;
+
+  error:
+    if (coverage != NULL)
+	rl2_destroy_coverage (coverage);
+    sqlite3_result_int (context, errcode);
+}
+
+static void
+fnct_WriteTripleBandTiffTfw (sqlite3_context * context, int argc,
+			     sqlite3_value ** argv)
+{
+/* SQL function:
+/ WriteTripleBandTiffTfw(text coverage, text tiff_path, int width,
+/              int height, int red_band, int green_band, int blue_band,
+/              BLOB geom, double resolution)
+/ WriteTripleBandTiffTfw(text coverage, text tiff_path, int width,
+/              int height, int red_band, int green_band, int blue_band,
+/              BLOB geom, double horz_res, double vert_res)
+/ WriteTripleBandTiffTfw(text coverage, text tiff_path, int width,
+/              int height, int red_band, int green_band, int blue_band,
+/              BLOB geom, double horz_res, double vert_res, 
+/              text compression)
+/ WriteTripleBandTiffTfw(text coverage, text tiff_path, int width,
+/              int height, int red_band, int green_band, int blue_band,
+/              BLOB geom, double horz_res, double vert_res, 
+/              text compression, int tile_sz)
+/
+/ will return 1 (TRUE, success) or 0 (FALSE, failure)
+/ or -1 (INVALID ARGS)
+/
+*/
+    common_write_triple_band_tiff (1, 0, context, argc, argv);
+}
+
+static void
+fnct_WriteTripleBandTiff (sqlite3_context * context, int argc,
+			  sqlite3_value ** argv)
+{
+/* SQL function:
+/ WriteTripleBandTiff(text coverage, int section_id,
+/           text tiff_path, int width, int height, int red_band,
+/           int green_band, int blue_band,
+/           BLOB geom, double resolution)
+/ WriteTripleBandTiff(text coverage, int section_id,
+/           text tiff_path, int width, int height, int red_band,
+/           int green_band, int blue_band, BLOB geom, double horz_res,
+/           double vert_res)
+/ WriteTripleBandTiff(text coverage, int section_id,
+/           text tiff_path, int width, int height, int red_band,
+/           int green_band, int blue_band, BLOB geom, double horz_res,
+/           double vert_res, text compression)
+/ WriteTripleBandTiff(text coverage, int section_id,
+/           text tiff_path, int width, int height, int red_band,
+/           int green_band, int blue_band, BLOB geom, double horz_res,
+/           double vert_res, text compression, int tile_sz)
+/
+/ will return 1 (TRUE, success) or 0 (FALSE, failure)
+/ or -1 (INVALID ARGS)
+/
+*/
+    common_write_triple_band_tiff (0, 0, context, argc, argv);
+}
+
+static void
+fnct_WriteSectionTripleBandTiffTfw (sqlite3_context * context, int argc,
+				    sqlite3_value ** argv)
+{
+/* SQL function:
+/ WriteSectionTripleBandTiffTfw(text coverage, int section_id,
+/              text tiff_path, int width, int height, int red_band,
+/              int green_band, int blue_band, BLOB geom, 
+/              double resolution)
+/ WriteSectionTripleBandTiffTfw(text coverage, int section_id,
+/              text tiff_path, int width, int height, int red_band,
+/              int green_band, int blue_band, BLOB geom, double horz_res,
+/              double vert_res)
+/ WriteSectionTripleBandTiffTfw(text coverage, int section_id,
+/              text tiff_path, int width, int height, int red_band, 
+/              int green_band, int blue_band, BLOB geom, double horz_res,
+/              double vert_res, text compression)
+/ WriteSectionTripleBandTiffTfw(text coverage, int section_id, 
+/              text tiff_path, int width, int height, int red_band,
+/              int green_band, int blue_band, BLOB geom, double horz_res,
+/              double vert_res, text compression, int tile_sz)
+/
+/ will return 1 (TRUE, success) or 0 (FALSE, failure)
+/ or -1 (INVALID ARGS)
+/
+*/
+    common_write_triple_band_tiff (1, 1, context, argc, argv);
+}
+
+static void
+fnct_WriteSectionTripleBandTiff (sqlite3_context * context, int argc,
+				 sqlite3_value ** argv)
+{
+/* SQL function:
+/ WriteSectionTripleBandTiff(text coverage, text tiff_path, int width,
+/           int height, int red_band, int green_band, int blue_band,
+/           BLOB geom, double resolution)
+/ WriteSectionTripleBandTiff(text coverage, text tiff_path, int width,
+/           int height, int red_band, int green_band, int blue_band,
+/           BLOB geom, double horz_res, double vert_res)
+/ WriteSectionTripleBandTiff(text coverage, text tiff_path, int width,
+/           int height, int red_band, int green_band, int blue_band,
+/           BLOB geom, double horz_res, double vert_res,
+/           text compression)
+/ WriteSectionTripleBandTiff(text coverage, text tiff_path, int width,
+/           int height, int red_band, int green_band, int blue_band,
+/           BLOB geom, double horz_res, double vert_res,
+/           text compression, int tile_sz)
+/
+/ will return 1 (TRUE, success) or 0 (FALSE, failure)
+/ or -1 (INVALID ARGS)
+/
+*/
+    common_write_triple_band_tiff (0, 1, context, argc, argv);
+}
+
+static void
+common_write_mono_band_tiff (int with_worldfile, int by_section,
+			     sqlite3_context * context, int argc,
+			     sqlite3_value ** argv)
+{
+/* common implementation Write Mono Band TIFF */
+    int err = 0;
+    const char *cvg_name;
+    sqlite3_int64 section_id = 0;
+    const char *path;
+    int width;
+    int height;
+    int mono_band;
+    const unsigned char *blob;
+    int blob_sz;
+    double horz_res;
+    double vert_res;
+    unsigned char compression = RL2_COMPRESSION_NONE;
+    int tile_sz = 256;
+    rl2CoveragePtr coverage = NULL;
+    sqlite3 *sqlite;
+    int ret;
+    int errcode = -1;
+    double pt_x;
+    double pt_y;
+    double minx;
+    double maxx;
+    double miny;
+    double maxy;
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+
+    if (by_section)
+      {
+	  /* single Section */
+	  if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[1]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[2]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[5]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[6]) != SQLITE_BLOB)
+	      err = 1;
+	  if (sqlite3_value_type (argv[7]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[7]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 8 && sqlite3_value_type (argv[8]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[8]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 9 && sqlite3_value_type (argv[9]) != SQLITE_TEXT)
+	      err = 1;
+	  if (argc > 10 && sqlite3_value_type (argv[10]) != SQLITE_INTEGER)
+	      err = 1;
+      }
+    else
+      {
+	  /* whole Coverage */
+	  if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[5]) != SQLITE_BLOB)
+	      err = 1;
+	  if (sqlite3_value_type (argv[6]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[6]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 7 && sqlite3_value_type (argv[7]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[7]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 8 && sqlite3_value_type (argv[8]) != SQLITE_TEXT)
+	      err = 1;
+	  if (argc > 9 && sqlite3_value_type (argv[9]) != SQLITE_INTEGER)
+	      err = 1;
+      }
+    if (err)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+
+/* retrieving all arguments */
+    if (by_section)
+      {
+	  /* single Section */
+	  cvg_name = (const char *) sqlite3_value_text (argv[0]);
+	  section_id = sqlite3_value_int64 (argv[1]);
+	  path = (const char *) sqlite3_value_text (argv[2]);
+	  width = sqlite3_value_int (argv[3]);
+	  height = sqlite3_value_int (argv[4]);
+	  mono_band = sqlite3_value_int (argv[5]);
+	  blob = sqlite3_value_blob (argv[6]);
+	  blob_sz = sqlite3_value_bytes (argv[6]);
+	  if (sqlite3_value_type (argv[7]) == SQLITE_INTEGER)
+	    {
+		int ival = sqlite3_value_int (argv[7]);
+		horz_res = ival;
+	    }
+	  else
+	      horz_res = sqlite3_value_double (argv[7]);
+	  if (argc > 8)
+	    {
+		if (sqlite3_value_type (argv[8]) == SQLITE_INTEGER)
+		  {
+		      int ival = sqlite3_value_int (argv[8]);
+		      vert_res = ival;
+		  }
+		else
+		    vert_res = sqlite3_value_double (argv[8]);
+	    }
+	  else
+	      vert_res = horz_res;
+	  if (argc > 9)
+	    {
+		const char *compr = (const char *) sqlite3_value_text (argv[9]);
+		compression = RL2_COMPRESSION_UNKNOWN;
+		if (strcasecmp (compr, "NONE") == 0)
+		    compression = RL2_COMPRESSION_NONE;
+		if (strcasecmp (compr, "DEFLATE") == 0)
+		    compression = RL2_COMPRESSION_DEFLATE;
+		if (strcasecmp (compr, "LZW") == 0)
+		    compression = RL2_COMPRESSION_LZW;
+		if (strcasecmp (compr, "JPEG") == 0)
+		    compression = RL2_COMPRESSION_JPEG;
+		if (strcasecmp (compr, "FAX3") == 0)
+		    compression = RL2_COMPRESSION_CCITTFAX3;
+		if (strcasecmp (compr, "FAX4") == 0)
+		    compression = RL2_COMPRESSION_CCITTFAX4;
+	    }
+	  if (argc > 10)
+	      tile_sz = sqlite3_value_int (argv[10]);
+      }
+    else
+      {
+	  /* whole Coverage */
+	  cvg_name = (const char *) sqlite3_value_text (argv[0]);
+	  path = (const char *) sqlite3_value_text (argv[1]);
+	  width = sqlite3_value_int (argv[2]);
+	  height = sqlite3_value_int (argv[3]);
+	  mono_band = sqlite3_value_int (argv[4]);
+	  blob = sqlite3_value_blob (argv[5]);
+	  blob_sz = sqlite3_value_bytes (argv[5]);
+	  if (sqlite3_value_type (argv[6]) == SQLITE_INTEGER)
+	    {
+		int ival = sqlite3_value_int (argv[6]);
+		horz_res = ival;
+	    }
+	  else
+	      horz_res = sqlite3_value_double (argv[6]);
+	  if (argc > 7)
+	    {
+		if (sqlite3_value_type (argv[7]) == SQLITE_INTEGER)
+		  {
+		      int ival = sqlite3_value_int (argv[7]);
+		      vert_res = ival;
+		  }
+		else
+		    vert_res = sqlite3_value_double (argv[7]);
+	    }
+	  else
+	      vert_res = horz_res;
+	  if (argc > 8)
+	    {
+		const char *compr = (const char *) sqlite3_value_text (argv[8]);
+		compression = RL2_COMPRESSION_UNKNOWN;
+		if (strcasecmp (compr, "NONE") == 0)
+		    compression = RL2_COMPRESSION_NONE;
+		if (strcasecmp (compr, "DEFLATE") == 0)
+		    compression = RL2_COMPRESSION_DEFLATE;
+		if (strcasecmp (compr, "LZW") == 0)
+		    compression = RL2_COMPRESSION_LZW;
+		if (strcasecmp (compr, "JPEG") == 0)
+		    compression = RL2_COMPRESSION_JPEG;
+		if (strcasecmp (compr, "FAX3") == 0)
+		    compression = RL2_COMPRESSION_CCITTFAX3;
+		if (strcasecmp (compr, "FAX4") == 0)
+		    compression = RL2_COMPRESSION_CCITTFAX4;
+	    }
+	  if (argc > 9)
+	      tile_sz = sqlite3_value_int (argv[9]);
+      }
+
+/* coarse args validation */
+    if (width < 0)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+    if (height < 0)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+    if (mono_band < 0 || mono_band > 255)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+    if (tile_sz < 64 || tile_sz > UINT16_MAX)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+    if (compression == RL2_COMPRESSION_UNKNOWN)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+
+    sqlite = sqlite3_context_db_handle (context);
+    if (!by_section)
+      {
+	  /* excluding any Mixed Resolution Coverage */
+	  if (rl2_is_mixed_resolutions_coverage (sqlite, cvg_name) > 0)
+	      goto error;
+      }
+
+/* checking the Geometry */
+    if (rl2_parse_point (sqlite, blob, blob_sz, &pt_x, &pt_y) == RL2_OK)
+      {
+	  /* assumed to be the GeoTiff Center Point */
+	  double ext_x = (double) width * horz_res;
+	  double ext_y = (double) height * vert_res;
+	  minx = pt_x - ext_x / 2.0;
+	  maxx = minx + ext_x;
+	  miny = pt_y - ext_y / 2.0;
+	  maxy = miny + ext_y;
+      }
+    else if (rl2_parse_bbox
+	     (sqlite, blob, blob_sz, &minx, &miny, &maxx, &maxy) != RL2_OK)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+
+/* attempting to load the Coverage definitions from the DBMS */
+    coverage = rl2_create_coverage_from_dbms (sqlite, cvg_name);
+    if (coverage == NULL)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+
+    if (by_section)
+      {
+	  /* single Section */
+	  if (with_worldfile)
+	    {
+		/* TIFF + Worldfile */
+		ret =
+		    rl2_export_section_mono_band_tiff_worldfile_from_dbms
+		    (sqlite, path, coverage, section_id, horz_res, vert_res,
+		     minx, miny, maxx, maxy, width, height, mono_band,
+		     compression, tile_sz);
+	    }
+	  else
+	    {
+		/* plain TIFF, no Worldfile */
+		ret =
+		    rl2_export_section_mono_band_tiff_from_dbms (sqlite, path,
+								 coverage,
+								 section_id,
+								 horz_res,
+								 vert_res,
+								 minx, miny,
+								 maxx, maxy,
+								 width,
+								 height,
+								 mono_band,
+								 compression,
+								 tile_sz);
+	    }
+      }
+    else
+      {
+	  /* whole Coverage */
+	  if (with_worldfile)
+	    {
+		/* TIFF + Worldfile */
+		ret =
+		    rl2_export_mono_band_tiff_worldfile_from_dbms (sqlite,
+								   path,
+								   coverage,
+								   horz_res,
+								   vert_res,
+								   minx, miny,
+								   maxx, maxy,
+								   width,
+								   height,
+								   mono_band,
+								   compression,
+								   tile_sz);
+	    }
+	  else
+	    {
+		/* plain TIFF, no Worldfile */
+		ret =
+		    rl2_export_mono_band_tiff_from_dbms (sqlite, path,
+							 coverage, horz_res,
+							 vert_res, minx, miny,
+							 maxx, maxy, width,
+							 height, mono_band,
+							 compression, tile_sz);
+	    }
+      }
+    if (ret != RL2_OK)
+      {
+	  errcode = 0;
+	  goto error;
+      }
+    rl2_destroy_coverage (coverage);
+    sqlite3_result_int (context, 1);
+    return;
+
+  error:
+    if (coverage != NULL)
+	rl2_destroy_coverage (coverage);
+    sqlite3_result_int (context, errcode);
+}
+
+static void
+fnct_WriteMonoBandTiffTfw (sqlite3_context * context, int argc,
+			   sqlite3_value ** argv)
+{
+/* SQL function:
+/ WriteMonoBandTiffTfw(text coverage, text tiff_path, int width,
+/              int height, int mono_band, BLOB geom, double resolution)
+/ WriteMonoBandTiffTfw(text coverage, text tiff_path, int width,
+/              int height, int mono_band, BLOB geom, double horz_res,
+/              double vert_res)
+/ WriteMonoBandTiffTfw(text coverage, text tiff_path, int width,
+/              int height, int mono_band, BLOB geom, double horz_res,
+/              double vert_res, text compression)
+/ WriteMonoBandTiffTfw(text coverage, text tiff_path, int width,
+/              int height, int mono_band, BLOB geom, double horz_res,
+/              double vert_res, text compression, int tile_sz)
+/
+/ will return 1 (TRUE, success) or 0 (FALSE, failure)
+/ or -1 (INVALID ARGS)
+/
+*/
+    common_write_mono_band_tiff (1, 0, context, argc, argv);
+}
+
+static void
+fnct_WriteMonoBandTiff (sqlite3_context * context, int argc,
+			sqlite3_value ** argv)
+{
+/* SQL function:
+/ WriteMonoBandTiff(text coverage, text tiff_path, int width,
+/           int height, int mono_band, BLOB geom, double resolution)
+/ WriteMonoBandTiff(text coverage, text tiff_path, int width,
+/           int height, int mono_band, BLOB geom, double horz_res,
+/           double vert_res)
+/ WriteMonoBandTiff(text coverage, text tiff_path, int width,
+/           int height, int mono_band, BLOB geom, double horz_res,
+/           double vert_res, text compression)
+/ WriteMonoBandTiff(text coverage, text tiff_path, int width,
+/           int height, int mono_band, BLOB geom, double horz_res,
+/           double vert_res, text compression, int tile_sz)
+/
+/ will return 1 (TRUE, success) or 0 (FALSE, failure)
+/ or -1 (INVALID ARGS)
+/
+*/
+    common_write_mono_band_tiff (0, 0, context, argc, argv);
+}
+
+static void
+fnct_WriteSectionMonoBandTiffTfw (sqlite3_context * context, int argc,
+				  sqlite3_value ** argv)
+{
+/* SQL function:
+/ WriteSectionMonoBandTiffTfw(text coverage, int section_id,
+/              text tiff_path, int width, int height, int mono_band,
+/              BLOB geom, double resolution)
+/ WriteSectionMonoBandTiffTfw(text coverage, int section_id,
+/              text tiff_path, int width, int height, int mono_band,
+/              BLOB geom, double horz_res, double vert_res)
+/ WriteSectionMonoBandTiffTfw(text coverage, int section_id,
+/              text tiff_path, int width, int height, int mono_band,
+/              BLOB geom, double horz_res, double vert_res,
+/              text compression)
+/ WriteSectionMonoBandTiffTfw(text coverage, int section_id,
+/              text tiff_path, int width, int height, int mono_band,
+/              BLOB geom, double horz_res, double vert_res,
+/              text compression, int tile_sz)
+/
+/ will return 1 (TRUE, success) or 0 (FALSE, failure)
+/ or -1 (INVALID ARGS)
+/
+*/
+    common_write_mono_band_tiff (1, 1, context, argc, argv);
+}
+
+static void
+fnct_WriteSectionMonoBandTiff (sqlite3_context * context, int argc,
+			       sqlite3_value ** argv)
+{
+/* SQL function:
+/ WriteSectionMonoBandTiff(text coverage, int section_id, 
+/           text tiff_path, int width, int height, int mono_band,
+/           BLOB geom, double resolution)
+/ WriteSectionMonoBandTiff(text coverage, int section_id,
+/           text tiff_path, int width, int height, int mono_band,
+/           BLOB geom, double horz_res, double vert_res)
+/ WriteSectionMonoBandTiff(text coverage, int section_id,
+/           text tiff_path, int width, int height, int mono_band,
+/           BLOB geom, double horz_res, double vert_res,
+/           text compression)
+/ WriteSectionMonoBandTiff(text coverage, int section_id,
+/           text tiff_path, int width, int height, int mono_band,
+/           BLOB geom, double horz_res, double vert_res,
+/           text compression, int tile_sz)
+/
+/ will return 1 (TRUE, success) or 0 (FALSE, failure)
+/ or -1 (INVALID ARGS)
+/
+*/
+    common_write_mono_band_tiff (0, 1, context, argc, argv);
+}
+
+static void
+common_write_ascii_grid (int by_section, sqlite3_context * context, int argc,
+			 sqlite3_value ** argv)
+{
+/* common export ASCII Grid implementation */
+    int err = 0;
+    const char *cvg_name;
+    const char *path;
+    sqlite3_int64 section_id = 0;
+    int width;
+    int height;
+    const unsigned char *blob;
+    int blob_sz;
+    double resolution;
+    rl2CoveragePtr coverage = NULL;
+    sqlite3 *sqlite;
+    const void *data;
+    int max_threads = 1;
+    int ret;
+    int errcode = -1;
+    double pt_x;
+    double pt_y;
+    double minx;
+    double maxx;
+    double miny;
+    double maxy;
+    int is_centered = 1;
+    int decimal_digits = 4;
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+
+    if (by_section)
+      {
+	  /* single Section */
+	  if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[1]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[2]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[5]) != SQLITE_BLOB)
+	      err = 1;
+	  if (sqlite3_value_type (argv[6]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[6]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 7 && sqlite3_value_type (argv[7]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (argc > 8 && sqlite3_value_type (argv[8]) != SQLITE_INTEGER)
+	      err = 1;
+      }
+    else
+      {
+	  /* whole Coverage */
+	  if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[4]) != SQLITE_BLOB)
+	      err = 1;
+	  if (sqlite3_value_type (argv[5]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[5]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 6 && sqlite3_value_type (argv[6]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (argc > 7 && sqlite3_value_type (argv[7]) != SQLITE_INTEGER)
+	      err = 1;
+      }
+    if (err)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+
+/* retrieving all arguments */
+    if (by_section)
+      {
+	  /* single Section */
+	  cvg_name = (const char *) sqlite3_value_text (argv[0]);
+	  section_id = sqlite3_value_int64 (argv[1]);
+	  path = (const char *) sqlite3_value_text (argv[2]);
+	  width = sqlite3_value_int (argv[3]);
+	  height = sqlite3_value_int (argv[4]);
+	  blob = sqlite3_value_blob (argv[5]);
+	  blob_sz = sqlite3_value_bytes (argv[5]);
+	  if (sqlite3_value_type (argv[6]) == SQLITE_INTEGER)
+	    {
+		int ival = sqlite3_value_int (argv[6]);
+		resolution = ival;
+	    }
+	  else
+	      resolution = sqlite3_value_double (argv[6]);
+	  if (argc > 7)
+	      is_centered = sqlite3_value_int (argv[7]);
+	  if (argc > 8)
+	      decimal_digits = sqlite3_value_int (argv[8]);
+      }
+    else
+      {
+	  /* whole Coverage */
+	  cvg_name = (const char *) sqlite3_value_text (argv[0]);
+	  path = (const char *) sqlite3_value_text (argv[1]);
+	  width = sqlite3_value_int (argv[2]);
+	  height = sqlite3_value_int (argv[3]);
+	  blob = sqlite3_value_blob (argv[4]);
+	  blob_sz = sqlite3_value_bytes (argv[4]);
+	  if (sqlite3_value_type (argv[5]) == SQLITE_INTEGER)
+	    {
+		int ival = sqlite3_value_int (argv[5]);
+		resolution = ival;
+	    }
+	  else
+	      resolution = sqlite3_value_double (argv[5]);
+	  if (argc > 6)
+	      is_centered = sqlite3_value_int (argv[6]);
+	  if (argc > 7)
+	      decimal_digits = sqlite3_value_int (argv[7]);
+      }
+
+    if (decimal_digits < 1)
+	decimal_digits = 0;
+    if (decimal_digits > 18)
+	decimal_digits = 18;
+
+/* coarse args validation */
+    if (width < 0)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+    if (height < 0)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+
+    sqlite = sqlite3_context_db_handle (context);
+    data = sqlite3_user_data (context);
+    if (data != NULL)
+      {
+	  struct rl2_private_data *priv_data = (struct rl2_private_data *) data;
+	  max_threads = priv_data->max_threads;
+	  if (max_threads < 1)
+	      max_threads = 1;
+	  if (max_threads > 64)
+	      max_threads = 64;
+      }
+    data = sqlite3_user_data (context);
+    if (data != NULL)
+      {
+	  struct rl2_private_data *priv_data = (struct rl2_private_data *) data;
+	  max_threads = priv_data->max_threads;
+	  if (max_threads < 1)
+	      max_threads = 1;
+	  if (max_threads > 64)
+	      max_threads = 64;
+      }
+    if (!by_section)
+      {
+	  /* excluding any Mixed Resolution Coverage */
+	  if (rl2_is_mixed_resolutions_coverage (sqlite, cvg_name) > 0)
+	      goto error;
+      }
+
+/* checking the Geometry */
+    if (rl2_parse_point (sqlite, blob, blob_sz, &pt_x, &pt_y) == RL2_OK)
+      {
+	  /* assumed to be the GeoTiff Center Point */
+	  double ext_x = (double) width * resolution;
+	  double ext_y = (double) height * resolution;
+	  minx = pt_x - ext_x / 2.0;
+	  maxx = minx + ext_x;
+	  miny = pt_y - ext_y / 2.0;
+	  maxy = miny + ext_y;
+      }
+    else if (rl2_parse_bbox
+	     (sqlite, blob, blob_sz, &minx, &miny, &maxx, &maxy) != RL2_OK)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+
+/* attempting to load the Coverage definitions from the DBMS */
+    coverage = rl2_create_coverage_from_dbms (sqlite, cvg_name);
+    if (coverage == NULL)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+
+    if (by_section)
+      {
+	  /* single Section */
+	  ret =
+	      rl2_export_section_ascii_grid_from_dbms (sqlite, max_threads,
+						       path, coverage,
+						       section_id, resolution,
+						       minx, miny, maxx, maxy,
+						       width, height,
+						       is_centered,
+						       decimal_digits);
+      }
+    else
+      {
+	  /* whole Coverage */
+	  ret =
+	      rl2_export_ascii_grid_from_dbms (sqlite, max_threads, path,
+					       coverage, resolution, minx,
+					       miny, maxx, maxy, width,
+					       height, is_centered,
+					       decimal_digits);
+      }
+    if (ret != RL2_OK)
+      {
+	  errcode = 0;
+	  goto error;
+      }
+    rl2_destroy_coverage (coverage);
+    sqlite3_result_int (context, 1);
+    return;
+
+  error:
+    if (coverage != NULL)
+	rl2_destroy_coverage (coverage);
+    sqlite3_result_int (context, errcode);
+}
+
+static void
+fnct_WriteAsciiGrid (sqlite3_context * context, int argc, sqlite3_value ** argv)
+{
+/* SQL function:
+/ WriteAsciiGrid(text coverage, text ascii_path, int width,
+/                int height, BLOB geom, double resolution)
+/ WriteAsciiGrid(text coverage, text ascii_path, int width,
+/                int height, BLOB geom, double resolution, 
+/                int is_centered)
+/ WriteAsciiGrid(text coverage, text ascii_path, int width,
+/                int height, BLOB geom, double resolution, 
+/                int is_centered, int decimal_digits)
+/
+/ will return 1 (TRUE, success) or 0 (FALSE, failure)
+/ or -1 (INVALID ARGS)
+/
+*/
+    common_write_ascii_grid (0, context, argc, argv);
+}
+
+static void
+fnct_WriteSectionAsciiGrid (sqlite3_context * context, int argc,
+			    sqlite3_value ** argv)
+{
+/* SQL function:
+/ WriteSectionAsciiGrid(text coverage, int section_id,
+/                       text ascii_path, int width, int height, 
+/                       BLOB geom, double resolution)
+/ WriteSectionAsciiGrid(text coverage, int section_id,
+/                       text ascii_path, int width, int height,
+/                       BLOB geom, double resolution, int is_centered)
+/ WriteSectionAsciiGrid(text coverage, int section_id,
+/                       text ascii_path, int width, int height,
+/                       BLOB geom, double resolution, int is_centered,
+/                       int decimal_digits)
+/
+/ will return 1 (TRUE, success) or 0 (FALSE, failure)
+/ or -1 (INVALID ARGS)
+/
+*/
+    common_write_ascii_grid (1, context, argc, argv);
+}
+
+static void
+common_write_ndvi_ascii_grid (int by_section, sqlite3_context * context,
+			      int argc, sqlite3_value ** argv)
+{
+/* common export NDVI ASCII Grid implementation */
+    int err = 0;
+    const char *cvg_name;
+    const char *path;
+    sqlite3_int64 section_id = 0;
+    int width;
+    int height;
+    int red_band;
+    int nir_band;
+    const unsigned char *blob;
+    int blob_sz;
+    double resolution;
+    rl2CoveragePtr coverage = NULL;
+    sqlite3 *sqlite;
+    const void *data;
+    int max_threads = 1;
+    int ret;
+    int errcode = -1;
+    double pt_x;
+    double pt_y;
+    double minx;
+    double maxx;
+    double miny;
+    double maxy;
+    int is_centered = 1;
+    int decimal_digits = 4;
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+
+    if (by_section)
+      {
+	  /* single Section */
+	  if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[1]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[2]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[5]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[6]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[7]) != SQLITE_BLOB)
+	      err = 1;
+	  if (sqlite3_value_type (argv[8]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[8]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 9 && sqlite3_value_type (argv[9]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (argc > 10 && sqlite3_value_type (argv[10]) != SQLITE_INTEGER)
+	      err = 1;
+      }
+    else
+      {
+	  /* whole Coverage */
+	  if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[5]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[6]) != SQLITE_BLOB)
+	      err = 1;
+	  if (sqlite3_value_type (argv[7]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[7]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 8 && sqlite3_value_type (argv[8]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (argc > 9 && sqlite3_value_type (argv[9]) != SQLITE_INTEGER)
+	      err = 1;
+      }
+    if (err)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+
+/* retrieving all arguments */
+    if (by_section)
+      {
+	  /* single Section */
+	  cvg_name = (const char *) sqlite3_value_text (argv[0]);
+	  section_id = sqlite3_value_int64 (argv[1]);
+	  path = (const char *) sqlite3_value_text (argv[2]);
+	  width = sqlite3_value_int (argv[3]);
+	  height = sqlite3_value_int (argv[4]);
+	  red_band = sqlite3_value_int (argv[5]);
+	  nir_band = sqlite3_value_int (argv[6]);
+	  blob = sqlite3_value_blob (argv[7]);
+	  blob_sz = sqlite3_value_bytes (argv[7]);
+	  if (sqlite3_value_type (argv[8]) == SQLITE_INTEGER)
+	    {
+		int ival = sqlite3_value_int (argv[8]);
+		resolution = ival;
+	    }
+	  else
+	      resolution = sqlite3_value_double (argv[8]);
+	  if (argc > 9)
+	      is_centered = sqlite3_value_int (argv[9]);
+	  if (argc > 10)
+	      decimal_digits = sqlite3_value_int (argv[10]);
+      }
+    else
+      {
+	  /* whole Coverage */
+	  cvg_name = (const char *) sqlite3_value_text (argv[0]);
+	  path = (const char *) sqlite3_value_text (argv[1]);
+	  width = sqlite3_value_int (argv[2]);
+	  height = sqlite3_value_int (argv[3]);
+	  red_band = sqlite3_value_int (argv[4]);
+	  nir_band = sqlite3_value_int (argv[5]);
+	  blob = sqlite3_value_blob (argv[6]);
+	  blob_sz = sqlite3_value_bytes (argv[6]);
+	  if (sqlite3_value_type (argv[7]) == SQLITE_INTEGER)
+	    {
+		int ival = sqlite3_value_int (argv[7]);
+		resolution = ival;
+	    }
+	  else
+	      resolution = sqlite3_value_double (argv[7]);
+	  if (argc > 8)
+	      is_centered = sqlite3_value_int (argv[8]);
+	  if (argc > 9)
+	      decimal_digits = sqlite3_value_int (argv[9]);
+      }
+
+    if (decimal_digits < 1)
+	decimal_digits = 0;
+    if (decimal_digits > 18)
+	decimal_digits = 18;
+
+/* coarse args validation */
+    if (width < 0)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+    if (height < 0)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+
+    sqlite = sqlite3_context_db_handle (context);
+    data = sqlite3_user_data (context);
+    if (data != NULL)
+      {
+	  struct rl2_private_data *priv_data = (struct rl2_private_data *) data;
+	  max_threads = priv_data->max_threads;
+	  if (max_threads < 1)
+	      max_threads = 1;
+	  if (max_threads > 64)
+	      max_threads = 64;
+      }
+    data = sqlite3_user_data (context);
+    if (data != NULL)
+      {
+	  struct rl2_private_data *priv_data = (struct rl2_private_data *) data;
+	  max_threads = priv_data->max_threads;
+	  if (max_threads < 1)
+	      max_threads = 1;
+	  if (max_threads > 64)
+	      max_threads = 64;
+      }
+    if (!by_section)
+      {
+	  /* excluding any Mixed Resolution Coverage */
+	  if (rl2_is_mixed_resolutions_coverage (sqlite, cvg_name) > 0)
+	      goto error;
+      }
+
+/* checking the Geometry */
+    if (rl2_parse_point (sqlite, blob, blob_sz, &pt_x, &pt_y) == RL2_OK)
+      {
+	  /* assumed to be the GeoTiff Center Point */
+	  double ext_x = (double) width * resolution;
+	  double ext_y = (double) height * resolution;
+	  minx = pt_x - ext_x / 2.0;
+	  maxx = minx + ext_x;
+	  miny = pt_y - ext_y / 2.0;
+	  maxy = miny + ext_y;
+      }
+    else if (rl2_parse_bbox
+	     (sqlite, blob, blob_sz, &minx, &miny, &maxx, &maxy) != RL2_OK)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+
+/* attempting to load the Coverage definitions from the DBMS */
+    coverage = rl2_create_coverage_from_dbms (sqlite, cvg_name);
+    if (coverage == NULL)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
+
+    if (by_section)
+      {
+	  /* single Section */
+	  ret =
+	      rl2_export_section_ndvi_ascii_grid_from_dbms (sqlite,
+							    max_threads, path,
+							    coverage,
+							    section_id,
+							    resolution, minx,
+							    miny, maxx, maxy,
+							    width, height,
+							    red_band,
+							    nir_band,
+							    is_centered,
+							    decimal_digits);
+      }
+    else
+      {
+	  /* whole Coverage */
+	  ret =
+	      rl2_export_ndvi_ascii_grid_from_dbms (sqlite, max_threads, path,
+						    coverage, resolution,
+						    minx, miny, maxx, maxy,
+						    width, height, red_band,
+						    nir_band, is_centered,
+						    decimal_digits);
+      }
+    if (ret != RL2_OK)
+      {
+	  errcode = 0;
+	  goto error;
+      }
+    rl2_destroy_coverage (coverage);
+    sqlite3_result_int (context, 1);
+    return;
+
+  error:
+    if (coverage != NULL)
+	rl2_destroy_coverage (coverage);
+    sqlite3_result_int (context, errcode);
+}
+
+static void
+fnct_WriteNdviAsciiGrid (sqlite3_context * context, int argc,
+			 sqlite3_value ** argv)
+{
+/* SQL function:
+/ WriteNdviAsciiGrid(text coverage, text ascii_path, int width,
+/                int height, int red_band, int nir_band, BLOB geom,
+/                double resolution)
+/ WriteNdviAsciiGrid(text coverage, text ascii_path, int width,
+/                int height, int red_band, int nir_band, BLOB geom,
+/                double resolution, int is_centered)
+/ WriteNdviAsciiGrid(text coverage, text ascii_path, int width,
+/                int height, int red_band, int nir_band, BLOB geom,
+/                double resolution, int is_centered, int decimal_digits)
+/
+/ will return 1 (TRUE, success) or 0 (FALSE, failure)
+/ or -1 (INVALID ARGS)
+/
+*/
+    common_write_ndvi_ascii_grid (0, context, argc, argv);
+}
+
+static void
+fnct_WriteSectionNdviAsciiGrid (sqlite3_context * context, int argc,
+				sqlite3_value ** argv)
+{
+/* SQL function:
+/ WriteSectionNdviAsciiGrid(text coverage, int section_id,
+/                       text ascii_path, int width, int height, 
+/                       int red_band, int nir_band, 
+/                       BLOB geom, double resolution)
+/ WriteSectionNdviAsciiGrid(text coverage, int section_id,
+/                       text ascii_path, int width, int height,
+/                       int red_band, int nir_band,
+/                       BLOB geom, double resolution, int is_centered)
+/ WriteSectionNdviAsciiGrid(text coverage, int section_id,
+/                       text ascii_path, int width, int height,
+/                       int red_band, int nir_band,
+/                       BLOB geom, double resolution, int is_centered,
+/                       int decimal_digits)
+/
+/ will return 1 (TRUE, success) or 0 (FALSE, failure)
+/ or -1 (INVALID ARGS)
+/
+*/
+    common_write_ndvi_ascii_grid (1, context, argc, argv);
+}
+
+static int
+test_geographic_srid (sqlite3 * handle, int srid)
+{
+/* testing if some SRID is of the Geographic type */
+    int ret;
+    int is_geographic = 0;
+    sqlite3_stmt *stmt = NULL;
+    const char *sql;
+
+    sql = "SELECT SridIsGeographic(?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return 0;
+
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_int (stmt, 1, srid);
+    while (1)
+      {
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	      is_geographic = sqlite3_column_int (stmt, 0);
+      }
+    sqlite3_finalize (stmt);
+    return is_geographic;
+}
+
+static double
+standard_scale (sqlite3 * handle, int srid, int width, int height,
+		double ext_x, double ext_y)
+{
+/* computing the standard (normalized) scale */
+    double linear_res;
+    double factor;
+    int is_geographic = test_geographic_srid (handle, srid);
+    if (is_geographic)
+      {
+	  /* geographic (long/lat) CRS */
+	  double metres = ext_x * (6378137.0 * 2.0 * 3.141592653589793) / 360.0;
+	  linear_res = metres / (double) width;
+      }
+    else
+      {
+	  /* planar (projected) CRS */
+	  double x_res = ext_x / (double) width;
+	  double y_res = ext_y / (double) height;
+	  linear_res = sqrt (x_res * y_res);
+      }
+    factor = linear_res / 0.000254;
+    return factor * (0.28 / 0.254);
+}
+
+static void
+fnct_GetMapImageFromRaster (sqlite3_context * context, int argc,
+			    sqlite3_value ** argv)
+{
+/* SQL function:
+/ GetMapImageFromRaster(text coverage, BLOB geom, int width, int height)
+/ GetMapImageFromRaster(text coverage, BLOB geom, int width, int height,
+/						text style)
+/ GetMapImageFromRaster(text coverage, BLOB geom, int width, int height,
+/						text style, text format)
+/ GetMapImageFromRaster(text coverage, BLOB geom, int width, int height,
+/						text style, text format, text bg_color)
+/ GetMapImageFromRaster(text coverage, BLOB geom, int width, int height,
+/						text style, text format, text bg_color,
+/                       int transparent)
+/ GetMapImageFromRaster(text coverage, BLOB geom, int width, int height,
+/						text style, text format, text bg_color,
+/                       int transparent, int quality)
+/ GetMapImageFromRaster(text coverage, BLOB geom, int width, int height,
+/						text style, text format, text bg_color,
+/                       int transparent, int quality, int reaspect)
+/
+/ will return a BLOB containing the Image payload from a Raster Coverage
+/ or NULL (INVALID ARGS)
+/
+*/
+    int err = 0;
+    const char *cvg_name;
+    rl2CoveragePtr coverage = NULL;
+    rl2PrivCoveragePtr cvg;
+    int out_srid;
+    int width;
+    int height;
+    int base_width;
+    int base_height;
+    const unsigned char *blob;
+    int blob_sz;
+    const char *style = "default";
+    const char *format = "image/png";
+    const char *bg_color = "#ffffff";
+    unsigned char bg_red;
+    unsigned char bg_green;
+    unsigned char bg_blue;
+    int transparent = 0;
+    int quality = 80;
+    int reaspect = 0;
+    sqlite3 *sqlite;
+    const void *data;
+    int max_threads = 1;
+    double minx;
+    double maxx;
+    double miny;
+    double maxy;
+    double ext_x;
+    double ext_y;
+    double x_res;
+    double y_res;
+    int srid;
+    int level_id;
+    int scale;
+    int xscale;
+    double map_scale;
+    double xx_res;
+    double yy_res;
+    double aspect_org;
+    double aspect_dst;
+    int ok_style;
+    int ok_format;
+    unsigned char *outbuf = NULL;
+    int outbuf_size;
+    unsigned char *image = NULL;
+    int image_size;
+    rl2PalettePtr palette = NULL;
+    double confidence;
+    unsigned char format_id = RL2_OUTPUT_FORMAT_UNKNOWN;
+    unsigned char out_pixel = RL2_PIXEL_UNKNOWN;
+    rl2CoverageStylePtr cvg_stl = NULL;
+    rl2RasterSymbolizerPtr symbolizer = NULL;
+    rl2RasterStatisticsPtr stats = NULL;
+    double opacity = 1.0;
+    struct aux_renderer aux;
+    int was_monochrome;
+    int by_section = 0;
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+
+/* testing arguments for validity */
+    err = 0;
+    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	err = 1;
+    if (sqlite3_value_type (argv[1]) != SQLITE_BLOB)
+	err = 1;
+    if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
+	err = 1;
+    if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+	err = 1;
+    if (argc > 4 && sqlite3_value_type (argv[4]) != SQLITE_TEXT)
+	err = 1;
+    if (argc > 5 && sqlite3_value_type (argv[5]) != SQLITE_TEXT)
+	err = 1;
+    if (argc > 6 && sqlite3_value_type (argv[6]) != SQLITE_TEXT)
+	err = 1;
+    if (argc > 7 && sqlite3_value_type (argv[7]) != SQLITE_INTEGER)
+	err = 1;
+    if (argc > 8 && sqlite3_value_type (argv[8]) != SQLITE_INTEGER)
+	err = 1;
+    if (argc > 9 && sqlite3_value_type (argv[9]) != SQLITE_INTEGER)
+	err = 1;
+    if (err != 0)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+
+/* retrieving the arguments */
+    cvg_name = (const char *) sqlite3_value_text (argv[0]);
+    blob = sqlite3_value_blob (argv[1]);
+    blob_sz = sqlite3_value_bytes (argv[1]);
+    width = sqlite3_value_int (argv[2]);
+    height = sqlite3_value_int (argv[3]);
+    if (argc > 4)
+	style = (const char *) sqlite3_value_text (argv[4]);
+    if (argc > 5)
+	format = (const char *) sqlite3_value_text (argv[5]);
+    if (argc > 6)
+	bg_color = (const char *) sqlite3_value_text (argv[6]);
+    if (argc > 7)
+	transparent = sqlite3_value_int (argv[7]);
+    if (argc > 8)
+	quality = sqlite3_value_int (argv[8]);
+    if (argc > 9)
+	reaspect = sqlite3_value_int (argv[9]);
+
+/* coarse args validation */
+    sqlite = sqlite3_context_db_handle (context);
+    data = sqlite3_user_data (context);
+    if (data != NULL)
+      {
+	  struct rl2_private_data *priv_data = (struct rl2_private_data *) data;
+	  max_threads = priv_data->max_threads;
+	  if (max_threads < 1)
+	      max_threads = 1;
+	  if (max_threads > 64)
+	      max_threads = 64;
+      }
+    if (width < 64)
+	goto error;
+    if (height < 64)
+	goto error;
+/* validating the format */
+    ok_format = 0;
+    if (strcmp (format, "image/png") == 0)
+      {
+	  format_id = RL2_OUTPUT_FORMAT_PNG;
+	  ok_format = 1;
+      }
+    if (strcmp (format, "image/jpeg") == 0)
+      {
+	  format_id = RL2_OUTPUT_FORMAT_JPEG;
+	  ok_format = 1;
+      }
+    if (strcmp (format, "image/tiff") == 0)
+      {
+	  format_id = RL2_OUTPUT_FORMAT_TIFF;
+	  ok_format = 1;
+      }
+    if (strcmp (format, "application/x-pdf") == 0)
+      {
+	  format_id = RL2_OUTPUT_FORMAT_PDF;
+	  ok_format = 1;
+      }
+    if (!ok_format)
+	goto error;
+/* parsing the background color */
+    if (rl2_parse_hexrgb (bg_color, &bg_red, &bg_green, &bg_blue) != RL2_OK)
+	goto error;
+/* checking the Geometry */
+    if (rl2_parse_bbox_srid
+	(sqlite, blob, blob_sz, &out_srid, &minx, &miny, &maxx,
+	 &maxy) != RL2_OK)
+	goto error;
+
+    ext_x = maxx - minx;
+    ext_y = maxy - miny;
+    if (ext_x <= 0.0 || ext_y <= 0.0)
+	goto error;
+    if (rl2_test_layer_group (sqlite, cvg_name))
+      {
+	  /* switching the whole task to the Group renderer */
+	  struct aux_group_renderer aux;
+	  aux.context = context;
+	  aux.group_name = cvg_name;
+	  aux.minx = minx;
+	  aux.maxx = maxx;
+	  aux.miny = miny;
+	  aux.maxy = maxy;
+	  aux.width = width;
+	  aux.height = height;
+	  aux.style = style;
+	  aux.format_id = format_id;
+	  aux.bg_red = bg_red;
+	  aux.bg_green = bg_green;
+	  aux.bg_blue = bg_blue;
+	  aux.transparent = transparent;
+	  aux.quality = quality;
+	  aux.reaspect = reaspect;
+	  rl2_aux_group_renderer (&aux);
+	  return;
+      }
+
+    x_res = ext_x / (double) width;
+    y_res = ext_y / (double) height;
+    map_scale = standard_scale (sqlite, out_srid, width, height, ext_x, ext_y);
+/* validating the style */
+    ok_style = 0;
+    if (strcasecmp (style, "default") == 0)
+	ok_style = 1;
+    else
+      {
+	  /* attempting to get a Coverage Style */
+	  cvg_stl =
+	      rl2_create_coverage_style_from_dbms (sqlite, cvg_name, style);
+	  if (cvg_stl == NULL)
+	      goto error;
+	  symbolizer =
+	      rl2_get_symbolizer_from_coverage_style (cvg_stl, map_scale);
+	  if (symbolizer == NULL)
+	    {
+		/* invisible at the currect scale */
+		if (!rl2_aux_default_image
+		    (width, height, bg_red, bg_green, bg_blue, format_id,
+		     transparent, quality, &image, &image_size))
+		    goto error;
+		goto done;
+	    }
+	  stats = rl2_create_raster_statistics_from_dbms (sqlite, cvg_name);
+	  if (stats == NULL)
+	      goto error;
+	  ok_style = 1;
+      }
+    if (!ok_style)
+	goto error;
+
+/* attempting to load the Coverage definitions from the DBMS */
+    coverage = rl2_create_coverage_from_dbms (sqlite, cvg_name);
+    if (coverage == NULL)
+	goto error;
+    if (rl2_get_coverage_srid (coverage, &srid) != RL2_OK)
+	srid = -1;
+    if (out_srid > 0 && srid > 0)
+      {
+	  if (out_srid != srid)
+	    {
+		/* raster reprojection isn't yet supported */
+		goto error;
+	    }
+      }
+    cvg = (rl2PrivCoveragePtr) coverage;
+    out_pixel = RL2_PIXEL_UNKNOWN;
+    if (cvg->sampleType == RL2_SAMPLE_UINT8 && cvg->pixelType == RL2_PIXEL_RGB
+	&& cvg->nBands == 3)
+	out_pixel = RL2_PIXEL_RGB;
+    if (cvg->sampleType == RL2_SAMPLE_UINT8
+	&& cvg->pixelType == RL2_PIXEL_GRAYSCALE && cvg->nBands == 1)
+	out_pixel = RL2_PIXEL_GRAYSCALE;
+    if (cvg->pixelType == RL2_PIXEL_PALETTE && cvg->nBands == 1)
+	out_pixel = RL2_PIXEL_PALETTE;
+    if (cvg->pixelType == RL2_PIXEL_MONOCHROME && cvg->nBands == 1)
+	out_pixel = RL2_PIXEL_MONOCHROME;
+
+    if (cvg->pixelType == RL2_PIXEL_MULTIBAND && cvg_stl == NULL)
+      {
+	  /* attempting to create a default RGB Coverage Style */
+	  unsigned char red_band;
+	  unsigned char green_band;
+	  unsigned char blue_band;
+	  unsigned char nir_band;
+	  if (rl2_get_dbms_coverage_default_bands
+	      (sqlite, cvg_name, &red_band, &green_band, &blue_band,
+	       &nir_band) == RL2_OK)
+	    {
+		/* ok, using the declared default bands */
+		rl2PrivCoverageStylePtr stl =
+		    rl2_create_default_coverage_style ();
+		rl2PrivStyleRulePtr rule = rl2_create_default_style_rule ();
+		rl2PrivRasterSymbolizerPtr symb =
+		    rl2_create_default_raster_symbolizer ();
+		symb->bandSelection = malloc (sizeof (rl2PrivBandSelection));
+		symb->bandSelection->selectionType = RL2_BAND_SELECTION_TRIPLE;
+		symb->bandSelection->redBand = red_band;
+		symb->bandSelection->greenBand = green_band;
+		symb->bandSelection->blueBand = blue_band;
+		symb->bandSelection->grayContrast =
+		    RL2_CONTRAST_ENHANCEMENT_NONE;
+		rule->style_type = RL2_RASTER_STYLE;
+		rule->style = symbolizer;
+		stl->first_rule = rule;
+		stl->last_rule = rule;
+		cvg_stl = (rl2CoverageStylePtr) stl;
+		symbolizer = (rl2RasterSymbolizerPtr) symb;
+		if (stats == NULL)
+		  {
+		      stats =
+			  rl2_create_raster_statistics_from_dbms (sqlite,
+								  cvg_name);
+		      if (stats == NULL)
+			  goto error;
+		  }
+	    }
+      }
+
+    if ((cvg->pixelType == RL2_PIXEL_DATAGRID
+	 || cvg->pixelType == RL2_PIXEL_MULTIBAND) && cvg_stl == NULL)
+      {
+	  /* creating a default Coverage Style */
+	  rl2PrivCoverageStylePtr stl = rl2_create_default_coverage_style ();
+	  rl2PrivStyleRulePtr rule = rl2_create_default_style_rule ();
+	  rl2PrivRasterSymbolizerPtr symb =
+	      rl2_create_default_raster_symbolizer ();
+	  symb->bandSelection = malloc (sizeof (rl2PrivBandSelection));
+	  symb->bandSelection->selectionType = RL2_BAND_SELECTION_MONO;
+	  symb->bandSelection->grayBand = 0;
+	  symb->bandSelection->grayContrast = RL2_CONTRAST_ENHANCEMENT_NONE;
+	  rule->style_type = RL2_RASTER_STYLE;
+	  rule->style = symbolizer;
+	  stl->first_rule = rule;
+	  stl->last_rule = rule;
+	  cvg_stl = (rl2CoverageStylePtr) stl;
+	  symbolizer = (rl2RasterSymbolizerPtr) symb;
+	  if (stats == NULL)
+	    {
+		stats =
+		    rl2_create_raster_statistics_from_dbms (sqlite, cvg_name);
+		if (stats == NULL)
+		    goto error;
+	    }
+      }
+
+    if (symbolizer != NULL)
+      {
+	  /* applying a RasterSymbolizer */
+	  int yes_no;
+	  int categorize;
+	  int interpolate;
+	  if (rl2_is_raster_symbolizer_triple_band_selected
+	      (symbolizer, &yes_no) == RL2_OK)
+	    {
+		if ((cvg->sampleType == RL2_SAMPLE_UINT8
+		     || cvg->sampleType == RL2_SAMPLE_UINT16)
+		    && (cvg->pixelType == RL2_PIXEL_RGB
+			|| cvg->pixelType == RL2_PIXEL_MULTIBAND) && yes_no)
+		    out_pixel = RL2_PIXEL_RGB;
+	    }
+	  if (rl2_is_raster_symbolizer_mono_band_selected
+	      (symbolizer, &yes_no, &categorize, &interpolate) == RL2_OK)
+	    {
+		if ((cvg->sampleType == RL2_SAMPLE_UINT8
+		     || cvg->sampleType == RL2_SAMPLE_UINT16)
+		    && (cvg->pixelType == RL2_PIXEL_RGB
+			|| cvg->pixelType == RL2_PIXEL_MULTIBAND
+			|| cvg->pixelType == RL2_PIXEL_GRAYSCALE) && yes_no)
+		    out_pixel = RL2_PIXEL_GRAYSCALE;
+		if ((cvg->sampleType == RL2_SAMPLE_UINT8
+		     || cvg->sampleType == RL2_SAMPLE_UINT16)
+		    && cvg->pixelType == RL2_PIXEL_MULTIBAND && yes_no
+		    && (categorize || interpolate))
+		    out_pixel = RL2_PIXEL_RGB;
+		if ((cvg->sampleType == RL2_SAMPLE_INT8
+		     || cvg->sampleType == RL2_SAMPLE_UINT8
+		     || cvg->sampleType == RL2_SAMPLE_INT16
+		     || cvg->sampleType == RL2_SAMPLE_UINT16
+		     || cvg->sampleType == RL2_SAMPLE_INT32
+		     || cvg->sampleType == RL2_SAMPLE_UINT32
+		     || cvg->sampleType == RL2_SAMPLE_FLOAT
+		     || cvg->sampleType == RL2_SAMPLE_DOUBLE)
+		    && cvg->pixelType == RL2_PIXEL_DATAGRID && yes_no)
+		    out_pixel = RL2_PIXEL_GRAYSCALE;
+	    }
+	  if (rl2_get_raster_symbolizer_opacity (symbolizer, &opacity) !=
+	      RL2_OK)
+	      opacity = 1.0;
+	  if (opacity > 1.0)
+	      opacity = 1.0;
+	  if (opacity < 0.0)
+	      opacity = 0.0;
+	  if (opacity < 1.0)
+	      transparent = 1;
+      }
+    if (out_pixel == RL2_PIXEL_UNKNOWN)
+      {
+	  fprintf (stderr, "*** Unsupported Pixel !!!!\n");
+	  goto error;
+      }
+
+    if (rl2_is_mixed_resolutions_coverage (sqlite, cvg_name) > 0)
+      {
+	  /* Mixed Resolutions Coverage */
+	  by_section = 1;
+	  xx_res = x_res;
+	  yy_res = y_res;
+      }
+    else
+      {
+	  /* ordinary Coverage */
+	  by_section = 0;
+	  /* retrieving the optimal resolution level */
+	  if (!rl2_find_best_resolution_level
+	      (sqlite, cvg_name, 0, 0, x_res, y_res, &level_id, &scale,
+	       &xscale, &xx_res, &yy_res))
+	      goto error;
+      }
+    base_width = (int) (ext_x / xx_res);
+    base_height = (int) (ext_y / yy_res);
+    if ((base_width <= 0 && base_width >= USHRT_MAX)
+	|| (base_height <= 0 && base_height >= USHRT_MAX))
+	goto error;
+    if ((base_width * base_height) > (8192 * 8192))
+      {
+	  /* warning: this usually implies missing Pyramid support */
+	  fprintf (stderr,
+		   "ERROR: a really huge image (%u x %u) has been requested;\n"
+		   "this is usually caused by a missing multi-resolution Pyramid.\n"
+		   "Please build a Pyramid supporting '%s'\n\n", base_width,
+		   base_height, cvg_name);
+	  goto error;
+      }
+    aspect_org = (double) base_width / (double) base_height;
+    aspect_dst = (double) width / (double) height;
+    confidence = aspect_org / 100.0;
+    if (aspect_dst >= (aspect_org - confidence)
+	|| aspect_dst <= (aspect_org + confidence))
+	;
+    else if (aspect_org != aspect_dst && !reaspect)
+	goto error;
+
+    if (by_section)
+      {
+	  /* Mixed Resolutions Coverage */
+	  was_monochrome = 0;
+	  if (out_pixel == RL2_PIXEL_MONOCHROME)
+	    {
+		out_pixel = RL2_PIXEL_GRAYSCALE;
+		was_monochrome = 1;
+	    }
+	  if (out_pixel == RL2_PIXEL_PALETTE)
+	      out_pixel = RL2_PIXEL_RGB;
+	  if (rl2_get_raw_raster_data_mixed_resolutions
+	      (sqlite, max_threads, coverage, base_width, base_height,
+	       minx, miny, maxx, maxy, xx_res, yy_res,
+	       &outbuf, &outbuf_size, &palette, &out_pixel, bg_red, bg_green,
+	       bg_blue, symbolizer, stats) != RL2_OK)
+	      goto error;
+	  if (was_monochrome && out_pixel == RL2_PIXEL_GRAYSCALE)
+	    {
+		rl2_destroy_coverage_style (cvg_stl);
+		cvg_stl = NULL;
+	    }
+      }
+    else
+      {
+	  /* ordinary Coverage */
+	  was_monochrome = 0;
+	  if (out_pixel == RL2_PIXEL_MONOCHROME)
+	    {
+		if (level_id != 0 && scale != 1)
+		  {
+		      out_pixel = RL2_PIXEL_GRAYSCALE;
+		      was_monochrome = 1;
+		  }
+	    }
+	  if (out_pixel == RL2_PIXEL_PALETTE)
+	    {
+		if (level_id != 0 && scale != 1)
+		    out_pixel = RL2_PIXEL_RGB;
+	    }
+	  if (rl2_get_raw_raster_data_bgcolor
+	      (sqlite, max_threads, coverage, base_width, base_height,
+	       minx, miny, maxx, maxy, xx_res, yy_res,
+	       &outbuf, &outbuf_size, &palette, &out_pixel, bg_red, bg_green,
+	       bg_blue, symbolizer, stats) != RL2_OK)
+	      goto error;
+	  if (was_monochrome && out_pixel == RL2_PIXEL_GRAYSCALE)
+	    {
+		rl2_destroy_coverage_style (cvg_stl);
+		cvg_stl = NULL;
+	    }
+      }
+
+/* preparing the aux struct for passing rendering arguments */
+    aux.sqlite = sqlite;
+    aux.max_threads = max_threads;
+    aux.width = width;
+    aux.height = height;
+    aux.base_width = base_width;
+    aux.base_height = base_height;
+    aux.minx = minx;
+    aux.miny = miny;
+    aux.maxx = maxx;
+    aux.maxy = maxy;
+    aux.srid = srid;
+    if (by_section)
+      {
+	  aux.by_section = 1;
+	  aux.x_res = x_res;
+	  aux.y_res = y_res;
+      }
+    else
+      {
+	  aux.by_section = 0;
+	  aux.xx_res = xx_res;
+	  aux.yy_res = yy_res;
+      }
+    aux.transparent = transparent;
+    aux.opacity = opacity;
+    aux.quality = quality;
+    aux.format_id = format_id;
+    aux.bg_red = bg_red;
+    aux.bg_green = bg_green;
+    aux.bg_blue = bg_blue;
+    aux.coverage = coverage;
+    aux.symbolizer = symbolizer;
+    aux.stats = stats;
+    aux.outbuf = outbuf;
+    aux.palette = palette;
+    aux.out_pixel = out_pixel;
+    if (!rl2_aux_render_image (&aux, &image, &image_size))
+	goto error;
+
+  done:
+    sqlite3_result_blob (context, image, image_size, free);
     rl2_destroy_coverage (coverage);
-    sqlite3_result_int (context, 1);
+    if (palette != NULL)
+	rl2_destroy_palette (palette);
+    if (cvg_stl != NULL)
+	rl2_destroy_coverage_style (cvg_stl);
+    if (stats != NULL)
+	rl2_destroy_raster_statistics (stats);
     return;
 
   error:
     if (coverage != NULL)
 	rl2_destroy_coverage (coverage);
-    sqlite3_result_int (context, errcode);
+    if (palette != NULL)
+	rl2_destroy_palette (palette);
+    if (cvg_stl != NULL)
+	rl2_destroy_coverage_style (cvg_stl);
+    if (stats != NULL)
+	rl2_destroy_raster_statistics (stats);
+    sqlite3_result_null (context);
 }
 
 static void
-fnct_GetMapImage (sqlite3_context * context, int argc, sqlite3_value ** argv)
+fnct_GetMapImageFromVector (sqlite3_context * context, int argc,
+			    sqlite3_value ** argv)
 {
 /* SQL function:
-/ GetMapImage(text coverage, BLOB geom, int width, int height)
-/ GetMapImage(text coverage, BLOB geom, int width, int height,
-/             text style)
-/ GetMapImage(text coverage, BLOB geom, int width, int height,
-/             text style, text format)
-/ GetMapImage(text coverage, BLOB geom, int width, int height,
-/             text style, text format, text bg_color)
-/ GetMapImage(text coverage, BLOB geom, int width, int height,
-/             text style, text format, text bg_color, int transparent)
-/ GetMapImage(text coverage, BLOB geom, int width, int height,
-/             text style, text format, text bg_color, int transparent,
-/             int quality)
-/ GetMapImage(text coverage, BLOB geom, int width, int height,
-/             text style, text format, text bg_color, int transparent,
-/             int quality, int reaspect)
+/ GetMapImageFromVector(text coverage, BLOB geom, int width, int height)
+/ GetMapImageFromVector(text coverage, BLOB geom, int width, int height,
+/						text style)
+/ GetMapImageFromVector(text coverage, BLOB geom, int width, int height,
+/						text style, text format)
+/ GetMapImageFromVector(text coverage, BLOB geom, int width, int height,
+/						text style, text format, text bg_color)
+/ GetMapImageFromVector(text coverage, BLOB geom, int width, int height,
+/						text style, text format, text bg_color,
+/                       int transparent)
+/ GetMapImageFromVector(text coverage, BLOB geom, int width, int height,
+/						text style, text format, text bg_color,
+/                       int transparent, int quality)
+/ GetMapImageFromVector(text coverage, BLOB geom, int width, int height,
+/						text style, text format, text bg_color,
+/                    	int transparent, int quality, int reaspect)
 /
-/ will return a BLOB containing the Image payload
+/ will return a BLOB containing the Image payload from a Vector Coverage
 / or NULL (INVALID ARGS)
 /
 */
     int err = 0;
     const char *cvg_name;
-    rl2CoveragePtr coverage = NULL;
-    rl2PrivCoveragePtr cvg;
+    rl2VectorLayerPtr layer = NULL;
+    rl2PrivVectorLayerPtr lyr;
+    int out_srid;
     int width;
     int height;
-    int base_width;
-    int base_height;
     const unsigned char *blob;
     int blob_sz;
     const char *style = "default";
@@ -5168,7 +8251,8 @@ fnct_GetMapImage (sqlite3_context * context, int argc, sqlite3_value ** argv)
     int quality = 80;
     int reaspect = 0;
     sqlite3 *sqlite;
-    gaiaGeomCollPtr geom;
+    sqlite3_stmt *stmt = NULL;
+    const void *data;
     double minx;
     double maxx;
     double miny;
@@ -5177,31 +8261,32 @@ fnct_GetMapImage (sqlite3_context * context, int argc, sqlite3_value ** argv)
     double ext_y;
     double x_res;
     double y_res;
+    double scale;
     int srid;
-    int level_id;
-    int scale;
-    int xscale;
-    double xx_res;
-    double yy_res;
-    double aspect_org;
-    double aspect_dst;
     int ok_style;
     int ok_format;
-    unsigned char *outbuf = NULL;
-    int outbuf_size;
     unsigned char *image = NULL;
     int image_size;
-    rl2PalettePtr palette = NULL;
-    double confidence;
     unsigned char format_id = RL2_OUTPUT_FORMAT_UNKNOWN;
-    unsigned char out_pixel = RL2_PIXEL_UNKNOWN;
-    rl2RasterStylePtr symbolizer = NULL;
-    rl2RasterStatisticsPtr stats = NULL;
-    double opacity = 1.0;
-    struct aux_renderer aux;
-    int was_monochrome;
+    rl2FeatureTypeStylePtr lyr_stl = NULL;
+    rl2VectorSymbolizerPtr symbolizer = NULL;
+    char *quoted;
+    char *sql;
+    char *oldsql;
+    int columns = 0;
+    int i;
+    int ret;
+    int reproject_on_the_fly;
+    int has_extra_columns;
+    rl2VariantArrayPtr variant = NULL;
+    rl2GraphicsContextPtr ctx = NULL;
+    unsigned char *rgb = NULL;
+    unsigned char *alpha = NULL;
+    int half_transparent;
     RL2_UNUSED ();		/* LCOV_EXCL_LINE */
 
+/* testing arguments for validity */
+    err = 0;
     if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
 	err = 1;
     if (sqlite3_value_type (argv[1]) != SQLITE_BLOB)
@@ -5222,7 +8307,7 @@ fnct_GetMapImage (sqlite3_context * context, int argc, sqlite3_value ** argv)
 	err = 1;
     if (argc > 9 && sqlite3_value_type (argv[9]) != SQLITE_INTEGER)
 	err = 1;
-    if (err)
+    if (err != 0)
       {
 	  sqlite3_result_null (context);
 	  return;
@@ -5249,9 +8334,10 @@ fnct_GetMapImage (sqlite3_context * context, int argc, sqlite3_value ** argv)
 
 /* coarse args validation */
     sqlite = sqlite3_context_db_handle (context);
-    if (width < 64 || width > 5000)
+    data = sqlite3_user_data (context);
+    if (width < 64)
 	goto error;
-    if (height < 64 || height > 5000)
+    if (height < 64)
 	goto error;
 /* validating the format */
     ok_format = 0;
@@ -5281,260 +8367,267 @@ fnct_GetMapImage (sqlite3_context * context, int argc, sqlite3_value ** argv)
     if (rl2_parse_hexrgb (bg_color, &bg_red, &bg_green, &bg_blue) != RL2_OK)
 	goto error;
 /* checking the Geometry */
-    geom = gaiaFromSpatiaLiteBlobWkb (blob, blob_sz);
-    if (geom == NULL)
+    if (rl2_parse_bbox_srid
+	(sqlite, blob, blob_sz, &out_srid, &minx, &miny, &maxx,
+	 &maxy) != RL2_OK)
 	goto error;
-    minx = geom->MinX;
-    maxx = geom->MaxX;
-    miny = geom->MinY;
-    maxy = geom->MaxY;
+
+/* attempting to load the VectorLayer definitions from the DBMS */
+    layer = rl2_create_vector_layer_from_dbms (sqlite, cvg_name);
+    if (layer == NULL)
+	goto error;
+    if (rl2_get_vector_srid (layer, &srid) != RL2_OK)
+	srid = -1;
+    lyr = (rl2PrivVectorLayerPtr) layer;
+    if (out_srid <= 0)
+	out_srid = srid;
+    if (srid > 0 && out_srid > 0 && out_srid != srid)
+	reproject_on_the_fly = 1;
+    else
+	reproject_on_the_fly = 0;
+
     ext_x = maxx - minx;
     ext_y = maxy - miny;
     if (ext_x <= 0.0 || ext_y <= 0.0)
 	goto error;
-    gaiaFreeGeomColl (geom);
-    if (rl2_test_layer_group (sqlite, cvg_name))
-      {
-	  /* switching the whole task to the Group renderer */
-	  struct aux_group_renderer aux;
-	  aux.context = context;
-	  aux.group_name = cvg_name;
-	  aux.minx = minx;
-	  aux.maxx = maxx;
-	  aux.miny = miny;
-	  aux.maxy = maxy;
-	  aux.width = width;
-	  aux.height = height;
-	  aux.style = style;
-	  aux.format_id = format_id;
-	  aux.bg_red = bg_red;
-	  aux.bg_green = bg_green;
-	  aux.bg_blue = bg_blue;
-	  aux.transparent = transparent;
-	  aux.quality = quality;
-	  aux.reaspect = reaspect;
-	  rl2_aux_group_renderer (&aux);
-	  return;
-      }
-
     x_res = ext_x / (double) width;
     y_res = ext_y / (double) height;
+    scale = standard_scale (sqlite, srid, width, height, ext_x, ext_y);
 /* validating the style */
     ok_style = 0;
     if (strcasecmp (style, "default") == 0)
 	ok_style = 1;
     else
       {
-	  /* attempting to get a RasterSymbolizer style */
-	  symbolizer =
-	      rl2_create_raster_style_from_dbms (sqlite, cvg_name, style);
-	  if (symbolizer == NULL)
-	      goto error;
-	  stats = rl2_create_raster_statistics_from_dbms (sqlite, cvg_name);
-	  if (stats == NULL)
+	  /* attempting to get a FeatureType Style */
+	  lyr_stl =
+	      rl2_create_feature_type_style_from_dbms (sqlite, cvg_name, style);
+	  if (lyr_stl == NULL)
 	      goto error;
 	  ok_style = 1;
       }
     if (!ok_style)
 	goto error;
 
-/* attempting to load the Coverage definitions from the DBMS */
-    coverage = rl2_create_coverage_from_dbms (sqlite, cvg_name);
-    if (coverage == NULL)
-	goto error;
-    if (rl2_get_coverage_srid (coverage, &srid) != RL2_OK)
-	srid = -1;
-    cvg = (rl2PrivCoveragePtr) coverage;
-    out_pixel = RL2_PIXEL_UNKNOWN;
-    if (cvg->sampleType == RL2_SAMPLE_UINT8 && cvg->pixelType == RL2_PIXEL_RGB
-	&& cvg->nBands == 3)
-	out_pixel = RL2_PIXEL_RGB;
-    if (cvg->sampleType == RL2_SAMPLE_UINT8
-	&& cvg->pixelType == RL2_PIXEL_GRAYSCALE && cvg->nBands == 1)
-	out_pixel = RL2_PIXEL_GRAYSCALE;
-    if (cvg->pixelType == RL2_PIXEL_PALETTE && cvg->nBands == 1)
-	out_pixel = RL2_PIXEL_PALETTE;
-    if (cvg->pixelType == RL2_PIXEL_MONOCHROME && cvg->nBands == 1)
-	out_pixel = RL2_PIXEL_MONOCHROME;
-
-    if ((cvg->pixelType == RL2_PIXEL_DATAGRID
-	 || cvg->pixelType == RL2_PIXEL_MULTIBAND) && symbolizer == NULL)
-      {
-	  /* creating a default RasterStyle */
-	  rl2PrivRasterStylePtr symb = malloc (sizeof (rl2PrivRasterStyle));
-	  symbolizer = (rl2RasterStylePtr) symb;
-	  symb->name = malloc (8);
-	  strcpy (symb->name, "default");
-	  symb->title = NULL;
-	  symb->abstract = NULL;
-	  symb->opacity = 1.0;
-	  symb->contrastEnhancement = RL2_CONTRAST_ENHANCEMENT_NONE;
-	  symb->bandSelection = malloc (sizeof (rl2PrivBandSelection));
-	  symb->bandSelection->selectionType = RL2_BAND_SELECTION_MONO;
-	  symb->bandSelection->grayBand = 0;
-	  symb->bandSelection->grayContrast = RL2_CONTRAST_ENHANCEMENT_NONE;
-	  symb->categorize = NULL;
-	  symb->interpolate = NULL;
-	  symb->shadedRelief = 0;
-	  if (stats == NULL)
+    if (lyr_stl != NULL)
+      {
+	  /* testing for style conditional visibility */
+	  if (!rl2_is_visible_style (lyr_stl, scale))
 	    {
-		stats =
-		    rl2_create_raster_statistics_from_dbms (sqlite, cvg_name);
-		if (stats == NULL)
+		ctx = rl2_graph_create_context (width, height);
+		if (ctx == NULL)
 		    goto error;
+		goto done;
 	    }
       }
 
-    if (symbolizer != NULL)
-      {
-	  /* applying a RasterSymbolizer */
-	  int yes_no;
-	  if (rl2_is_raster_style_triple_band_selected (symbolizer, &yes_no) ==
-	      RL2_OK)
-	    {
-		if ((cvg->sampleType == RL2_SAMPLE_UINT8
-		     || cvg->sampleType == RL2_SAMPLE_UINT16)
-		    && (cvg->pixelType == RL2_PIXEL_RGB
-			|| cvg->pixelType == RL2_PIXEL_MULTIBAND) && yes_no)
-		    out_pixel = RL2_PIXEL_RGB;
-	    }
-	  if (rl2_is_raster_style_mono_band_selected (symbolizer, &yes_no) ==
-	      RL2_OK)
+/* composing the SQL query */
+    quoted = rl2_double_quoted_sql (lyr->f_geometry_column);
+    if (reproject_on_the_fly)
+	sql =
+	    sqlite3_mprintf ("SELECT ST_Transform(\"%s\", %d)", quoted,
+			     out_srid);
+    else
+	sql = sqlite3_mprintf ("SELECT \"%s\"", quoted);
+    free (quoted);
+    has_extra_columns = 0;
+    if (lyr_stl != NULL)
+      {
+	  /* may be that the Symbolizer requires some extra column */
+	  columns = rl2_get_feature_type_style_columns_count (lyr_stl);
+	  for (i = 0; i < columns; i++)
 	    {
-		if ((cvg->sampleType == RL2_SAMPLE_UINT8
-		     || cvg->sampleType == RL2_SAMPLE_UINT16)
-		    && (cvg->pixelType == RL2_PIXEL_RGB
-			|| cvg->pixelType == RL2_PIXEL_MULTIBAND
-			|| cvg->pixelType == RL2_PIXEL_GRAYSCALE) && yes_no)
-		    out_pixel = RL2_PIXEL_GRAYSCALE;
-		if ((cvg->sampleType == RL2_SAMPLE_INT8
-		     || cvg->sampleType == RL2_SAMPLE_UINT8
-		     || cvg->sampleType == RL2_SAMPLE_INT16
-		     || cvg->sampleType == RL2_SAMPLE_UINT16
-		     || cvg->sampleType == RL2_SAMPLE_INT32
-		     || cvg->sampleType == RL2_SAMPLE_UINT32
-		     || cvg->sampleType == RL2_SAMPLE_FLOAT
-		     || cvg->sampleType == RL2_SAMPLE_DOUBLE)
-		    && cvg->pixelType == RL2_PIXEL_DATAGRID && yes_no)
-		    out_pixel = RL2_PIXEL_GRAYSCALE;
+		/* adding columns required by Filters and TextSymbolizers */
+		const char *col_name =
+		    rl2_get_feature_type_style_column_name (lyr_stl, i);
+		oldsql = sql;
+		quoted = rl2_double_quoted_sql (col_name);
+		sql = sqlite3_mprintf ("%s, \"%s\"", oldsql, quoted);
+		free (quoted);
+		sqlite3_free (oldsql);
+		has_extra_columns = 1;
 	    }
-	  if (rl2_get_raster_style_opacity (symbolizer, &opacity) != RL2_OK)
-	      opacity = 1.0;
-	  if (opacity > 1.0)
-	      opacity = 1.0;
-	  if (opacity < 0.0)
-	      opacity = 0.0;
-	  if (opacity < 1.0)
-	      transparent = 1;
       }
-    if (out_pixel == RL2_PIXEL_UNKNOWN)
+    quoted = rl2_double_quoted_sql (lyr->f_table_name);
+    oldsql = sql;
+    sql = sqlite3_mprintf ("%s FROM \"%s\"", oldsql, quoted);
+    free (quoted);
+    sqlite3_free (oldsql);
+    if (lyr->spatial_index)
+      {
+	  /* queryng the R*Tree Spatial Index */
+	  oldsql = sql;
+	  sql =
+	      sqlite3_mprintf
+	      ("%s WHERE ROWID IN (SELECT ROWID FROM SpatialIndex "
+	       "WHERE f_table_name = %Q AND f_geometry_column = %Q AND search_frame = ?)",
+	       oldsql, lyr->f_table_name, lyr->f_geometry_column);
+	  sqlite3_free (oldsql);
+      }
+    else
       {
-	  fprintf (stderr, "*** Unsupported Pixel !!!!\n");
-	  goto error;
+	  /* applying MBR filtering */
+	  oldsql = sql;
+	  quoted = rl2_double_quoted_sql (lyr->f_geometry_column);
+	  sql =
+	      sqlite3_mprintf ("%s WHERE MbrIntersects(\"%s\", ?)", oldsql,
+			       quoted);
+	  free (quoted);
+	  sqlite3_free (oldsql);
       }
 
-/* retrieving the optimal resolution level */
-    if (!find_best_resolution_level
-	(sqlite, cvg_name, x_res, y_res, &level_id, &scale, &xscale, &xx_res,
-	 &yy_res))
-	goto error;
-    base_width = (int) (ext_x / xx_res);
-    base_height = (int) (ext_y / yy_res);
-    if ((base_width <= 0 && base_width >= USHRT_MAX)
-	|| (base_height <= 0 && base_height >= USHRT_MAX))
-	goto error;
-    if (base_width > 8192 || base_height > 8192)
+/* preparing the SQL statement */
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
       {
-	  /* warning: this usually implies missing Pyramid support */
-	  fprintf (stderr,
-		   "ERROR: a really huge image (%u x %u) has been requested;\n"
-		   "this is usually caused by a missing multi-resolution Pyramid.\n"
-		   "Please build a Pyramid supporting '%s'\n\n", base_width,
-		   base_height, cvg_name);
+	  fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (sqlite));
 	  goto error;
       }
-    aspect_org = (double) base_width / (double) base_height;
-    aspect_dst = (double) width / (double) height;
-    confidence = aspect_org / 100.0;
-    if (aspect_dst >= (aspect_org - confidence)
-	|| aspect_dst <= (aspect_org + confidence))
-	;
-    else if (aspect_org != aspect_dst && !reaspect)
+
+/* preparing a Graphic Context */
+    ctx = rl2_graph_create_context (width, height);
+    if (ctx == NULL)
 	goto error;
 
-    was_monochrome = 0;
-    if (out_pixel == RL2_PIXEL_MONOCHROME)
+/* priming the Graphic Context */
+    if (transparent)
+	rl2_graph_set_brush (ctx, 255, 255, 255, 0);
+    else
+	rl2_graph_set_brush (ctx, bg_red, bg_green, bg_blue, 255);
+    rl2_graph_draw_rectangle (ctx, -1, -1, width + 2, height + 2);
+
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_blob (stmt, 1, blob, blob_sz, SQLITE_STATIC);
+    while (1)
       {
-	  if (level_id != 0 && scale != 1)
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
 	    {
-		out_pixel = RL2_PIXEL_GRAYSCALE;
-		was_monochrome = 1;
+		rl2GeometryPtr geom = NULL;
+		if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
+		  {
+		      /* fetching Geometry */
+		      const void *g_blob = sqlite3_column_blob (stmt, 0);
+		      int g_blob_sz = sqlite3_column_bytes (stmt, 0);
+		      geom =
+			  rl2_geometry_from_blob ((const unsigned char *)
+						  g_blob, g_blob_sz);
+		  }
+		if (has_extra_columns)
+		  {
+		      if (variant != NULL)
+			  rl2_destroy_variant_array (variant);
+		      variant = rl2_create_variant_array (columns);
+		      for (i = 0; i < columns; i++)
+			{
+			    const char *col_name =
+				rl2_get_feature_type_style_column_name (lyr_stl,
+									i);
+			    switch (sqlite3_column_type (stmt, 1 + i))
+			      {
+			      case SQLITE_INTEGER:
+				  rl2_set_variant_int (variant, i, col_name,
+						       sqlite3_column_int64
+						       (stmt, i + 1));
+				  break;
+			      case SQLITE_FLOAT:
+				  rl2_set_variant_double (variant, i,
+							  col_name,
+							  sqlite3_column_double
+							  (stmt, i + 1));
+				  break;
+			      case SQLITE_TEXT:
+				  rl2_set_variant_text (variant, i, col_name,
+							(const char *)
+							sqlite3_column_text
+							(stmt, i + 1),
+							sqlite3_column_bytes
+							(stmt, i + 1));
+				  break;
+			      case SQLITE_BLOB:
+				  rl2_set_variant_blob (variant, i, col_name,
+							sqlite3_column_blob
+							(stmt, i + 1),
+							sqlite3_column_bytes
+							(stmt, i + 1));
+				  break;
+			      default:
+				  rl2_set_variant_null (variant, i, col_name);
+				  break;
+			      };
+			}
+		  }
+		if (geom != NULL)
+		  {
+		      /* drawing a styled Feature */
+		      int scale_forbidden = 0;
+		      symbolizer = NULL;
+		      if (lyr_stl != NULL)
+			  symbolizer =
+			      rl2_get_symbolizer_from_feature_type_style
+			      (lyr_stl, scale, variant, &scale_forbidden);
+		      if (!scale_forbidden)
+			  rl2_draw_vector_feature (ctx, sqlite, data,
+						   symbolizer, height, minx,
+						   miny, maxx, maxy, x_res,
+						   y_res, geom, variant);
+		      rl2_destroy_geometry (geom);
+		  }
 	    }
       }
-    if (out_pixel == RL2_PIXEL_PALETTE)
-      {
-	  if (level_id != 0 && scale != 1)
-	      out_pixel = RL2_PIXEL_RGB;
-      }
-    if (rl2_get_raw_raster_data_bgcolor
-	(sqlite, coverage, base_width, base_height,
-	 minx, miny, maxx, maxy, xx_res, yy_res,
-	 &outbuf, &outbuf_size, &palette, &out_pixel, bg_red, bg_green,
-	 bg_blue, symbolizer, stats) != RL2_OK)
-	goto error;
-    if (was_monochrome && out_pixel == RL2_PIXEL_GRAYSCALE)
-      {
-	  rl2_destroy_raster_style (symbolizer);
-	  symbolizer = NULL;
-      }
+    sqlite3_finalize (stmt);
 
-/* preparing the aux struct for passing rendering arguments */
-    aux.sqlite = sqlite;
-    aux.width = width;
-    aux.height = height;
-    aux.base_width = base_width;
-    aux.base_height = base_height;
-    aux.minx = minx;
-    aux.miny = miny;
-    aux.maxx = maxx;
-    aux.maxy = maxy;
-    aux.srid = srid;
-    aux.xx_res = xx_res;
-    aux.yy_res = yy_res;
-    aux.transparent = transparent;
-    aux.opacity = opacity;
-    aux.quality = quality;
-    aux.format_id = format_id;
-    aux.bg_red = bg_red;
-    aux.bg_green = bg_green;
-    aux.bg_blue = bg_blue;
-    aux.coverage = coverage;
-    aux.symbolizer = symbolizer;
-    aux.stats = stats;
-    aux.outbuf = outbuf;
-    aux.palette = palette;
-    aux.out_pixel = out_pixel;
-    if (!rl2_aux_render_image (&aux, &image, &image_size))
+  done:
+    rl2_destroy_vector_layer (layer);
+    layer = NULL;
+    if (lyr_stl != NULL)
+	rl2_destroy_feature_type_style (lyr_stl);
+    lyr_stl = NULL;
+    if (variant != NULL)
+	rl2_destroy_variant_array (variant);
+    variant = NULL;
+
+    rgb = rl2_graph_get_context_rgb_array (ctx);
+    alpha = rl2_graph_get_context_alpha_array (ctx, &half_transparent);
+    if (rgb == NULL || alpha == NULL)
 	goto error;
-    sqlite3_result_blob (context, image, image_size, free);
-    rl2_destroy_coverage (coverage);
-    if (palette != NULL)
-	rl2_destroy_palette (palette);
-    if (symbolizer != NULL)
-	rl2_destroy_raster_style (symbolizer);
-    if (stats != NULL)
-	rl2_destroy_raster_statistics (stats);
-    return;
 
-  error:
-    if (coverage != NULL)
-	rl2_destroy_coverage (coverage);
-    if (palette != NULL)
-	rl2_destroy_palette (palette);
-    if (symbolizer != NULL)
-	rl2_destroy_raster_style (symbolizer);
-    if (stats != NULL)
-	rl2_destroy_raster_statistics (stats);
+    rl2_graph_destroy_context (ctx);
+    ctx = NULL;
+
+    if (!get_payload_from_rgb_rgba_transparent
+	(width, height, rgb, alpha, format_id, quality, &image, &image_size,
+	 1.0, half_transparent))
+	goto error;
+    if (rgb != NULL)
+	free (rgb);
+    if (alpha != NULL)
+	free (alpha);
+
+
+    sqlite3_result_blob (context, image, image_size, free);
+    return;
+
+  error:
+    if (rgb != NULL)
+	free (rgb);
+    if (alpha != NULL)
+	free (alpha);
+    if (ctx != NULL)
+	rl2_graph_destroy_context (ctx);
+    if (layer != NULL)
+	rl2_destroy_vector_layer (layer);
+    if (lyr_stl != NULL)
+	rl2_destroy_feature_type_style (lyr_stl);
+    if (variant != NULL)
+	rl2_destroy_variant_array (variant);
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
     sqlite3_result_null (context);
 }
 
@@ -5576,8 +8669,8 @@ fnct_GetTileImage (sqlite3_context * context, int argc, sqlite3_value ** argv)
     int ret;
     const unsigned char *blob_odd = NULL;
     const unsigned char *blob_even = NULL;
-    int blob_odd_sz;
-    int blob_even_sz;
+    int blob_odd_sz = 0;
+    int blob_even_sz = 0;
     rl2RasterPtr raster = NULL;
     rl2PrivRasterPtr rst;
     rl2PalettePtr palette = NULL;
@@ -5593,6 +8686,7 @@ fnct_GetTileImage (sqlite3_context * context, int argc, sqlite3_value ** argv)
     unsigned char *alpha = NULL;
     unsigned char sample_type;
     unsigned char pixel_type;
+    unsigned char num_bands;
     rl2PrivPixelPtr no_data = NULL;
     double opacity = 1.0;
     RL2_UNUSED ();		/* LCOV_EXCL_LINE */
@@ -5639,6 +8733,7 @@ fnct_GetTileImage (sqlite3_context * context, int argc, sqlite3_value ** argv)
       case RL2_PIXEL_GRAYSCALE:
       case RL2_PIXEL_RGB:
       case RL2_PIXEL_DATAGRID:
+      case RL2_PIXEL_MULTIBAND:
 	  break;
       default:
 	  unsupported_tile = 1;
@@ -5660,10 +8755,10 @@ fnct_GetTileImage (sqlite3_context * context, int argc, sqlite3_value ** argv)
 
 /* querying the tile */
     table_tile_data = sqlite3_mprintf ("%s_tile_data", cvg_name);
-    xtable_tile_data = gaiaDoubleQuotedSql (table_tile_data);
+    xtable_tile_data = rl2_double_quoted_sql (table_tile_data);
     sqlite3_free (table_tile_data);
     table_tiles = sqlite3_mprintf ("%s_tiles", cvg_name);
-    xtable_tiles = gaiaDoubleQuotedSql (table_tiles);
+    xtable_tiles = rl2_double_quoted_sql (table_tiles);
     sqlite3_free (table_tiles);
     sql = sqlite3_mprintf ("SELECT d.tile_data_odd, d.tile_data_even, "
 			   "t.pyramid_level FROM \"%s\" AS d "
@@ -5720,6 +8815,7 @@ fnct_GetTileImage (sqlite3_context * context, int argc, sqlite3_value ** argv)
 		height = rst->height;
 		sample_type = rst->sampleType;
 		pixel_type = rst->pixelType;
+		num_bands = rst->nBands;
 		buffer = rst->rasterBuffer;
 		mask = rst->maskBuffer;
 		palette = (rl2PalettePtr) (rst->Palette);
@@ -5746,15 +8842,16 @@ fnct_GetTileImage (sqlite3_context * context, int argc, sqlite3_value ** argv)
 		  {
 		  case RL2_PIXEL_MONOCHROME:
 		      ret =
-			  get_rgba_from_monochrome_mask (width, height, buffer,
-							 mask, no_data, rgba);
+			  get_rgba_from_monochrome_mask (width, height,
+							 buffer, mask,
+							 no_data, rgba);
 		      buffer = NULL;
 		      mask = NULL;
 		      if (!ret)
 			  goto error;
 		      if (!build_rgb_alpha
-			  (width, height, rgba, &rgb, &alpha, bg_red, bg_green,
-			   bg_blue))
+			  (width, height, rgba, &rgb, &alpha, bg_red,
+			   bg_green, bg_blue))
 			  goto error;
 		      free (rgba);
 		      rgba = NULL;
@@ -5788,8 +8885,8 @@ fnct_GetTileImage (sqlite3_context * context, int argc, sqlite3_value ** argv)
 		      if (!ret)
 			  goto error;
 		      if (!build_rgb_alpha
-			  (width, height, rgba, &rgb, &alpha, bg_red, bg_green,
-			   bg_blue))
+			  (width, height, rgba, &rgb, &alpha, bg_red,
+			   bg_green, bg_blue))
 			  goto error;
 		      free (rgba);
 		      rgba = NULL;
@@ -5798,7 +8895,7 @@ fnct_GetTileImage (sqlite3_context * context, int argc, sqlite3_value ** argv)
 			    if (!get_payload_from_rgb_rgba_transparent
 				(width, height, rgb, alpha,
 				 RL2_OUTPUT_FORMAT_PNG, 100, &image,
-				 &image_size, opacity))
+				 &image_size, opacity, 0))
 				goto error;
 			}
 		      else
@@ -5822,8 +8919,8 @@ fnct_GetTileImage (sqlite3_context * context, int argc, sqlite3_value ** argv)
 		      if (!ret)
 			  goto error;
 		      if (!build_rgb_alpha
-			  (width, height, rgba, &rgb, &alpha, bg_red, bg_green,
-			   bg_blue))
+			  (width, height, rgba, &rgb, &alpha, bg_red,
+			   bg_green, bg_blue))
 			  goto error;
 		      free (rgba);
 		      rgba = NULL;
@@ -5857,8 +8954,8 @@ fnct_GetTileImage (sqlite3_context * context, int argc, sqlite3_value ** argv)
 		      if (!ret)
 			  goto error;
 		      if (!build_rgb_alpha
-			  (width, height, rgba, &rgb, &alpha, bg_red, bg_green,
-			   bg_blue))
+			  (width, height, rgba, &rgb, &alpha, bg_red,
+			   bg_green, bg_blue))
 			  goto error;
 		      free (rgba);
 		      rgba = NULL;
@@ -5886,8 +8983,8 @@ fnct_GetTileImage (sqlite3_context * context, int argc, sqlite3_value ** argv)
 		      if (sample_type == RL2_SAMPLE_UINT16)
 			{
 			    ret =
-				get_rgba_from_multiband16 (width, height, 0, 1,
-							   2, 3,
+				get_rgba_from_multiband16 (width, height, 0,
+							   1, 2, 3,
 							   (unsigned short *)
 							   buffer, mask,
 							   no_data, rgba);
@@ -5903,8 +9000,8 @@ fnct_GetTileImage (sqlite3_context * context, int argc, sqlite3_value ** argv)
 		      if (!ret)
 			  goto error;
 		      if (!build_rgb_alpha
-			  (width, height, rgba, &rgb, &alpha, bg_red, bg_green,
-			   bg_blue))
+			  (width, height, rgba, &rgb, &alpha, bg_red,
+			   bg_green, bg_blue))
 			  goto error;
 		      free (rgba);
 		      rgba = NULL;
@@ -5913,7 +9010,7 @@ fnct_GetTileImage (sqlite3_context * context, int argc, sqlite3_value ** argv)
 			    if (!get_payload_from_rgb_rgba_transparent
 				(width, height, rgb, alpha,
 				 RL2_OUTPUT_FORMAT_PNG, 100, &image,
-				 &image_size, opacity))
+				 &image_size, opacity, 0))
 				goto error;
 			}
 		      else
@@ -5928,6 +9025,42 @@ fnct_GetTileImage (sqlite3_context * context, int argc, sqlite3_value ** argv)
 			}
 		      sqlite3_result_blob (context, image, image_size, free);
 		      break;
+		  case RL2_PIXEL_MULTIBAND:
+		      ret =
+			  get_rgba_from_multiband_mask (width, height,
+							sample_type,
+							num_bands, buffer,
+							mask, no_data, rgba);
+		      buffer = NULL;
+		      mask = NULL;
+		      if (!ret)
+			  goto error;
+		      if (!build_rgb_alpha
+			  (width, height, rgba, &rgb, &alpha, bg_red,
+			   bg_green, bg_blue))
+			  goto error;
+		      free (rgba);
+		      rgba = NULL;
+		      if (transparent)
+			{
+			    if (!get_payload_from_gray_rgba_transparent
+				(width, height, rgb, alpha,
+				 RL2_OUTPUT_FORMAT_PNG, 100, &image,
+				 &image_size, opacity))
+				goto error;
+			}
+		      else
+			{
+			    free (alpha);
+			    alpha = NULL;
+			    if (!get_payload_from_gray_rgba_opaque
+				(width, height, sqlite, 0, 0, 0, 0, -1,
+				 rgb, RL2_OUTPUT_FORMAT_PNG, 100, &image,
+				 &image_size))
+				goto error;
+			}
+		      sqlite3_result_blob (context, image, image_size, free);
+		      break;
 		  default:
 		      goto error;
 		      break;
@@ -5943,6 +9076,10 @@ fnct_GetTileImage (sqlite3_context * context, int argc, sqlite3_value ** argv)
     rl2_destroy_coverage (coverage);
     if (palette != NULL)
 	rl2_destroy_palette (palette);
+    if (rgb != NULL)
+	free (rgb);
+    if (alpha != NULL)
+	free (alpha);
     return;
 
   error:
@@ -5988,8 +9125,8 @@ get_triple_band_tile_image (sqlite3_context * context, const char *cvg_name,
     int ret;
     const unsigned char *blob_odd = NULL;
     const unsigned char *blob_even = NULL;
-    int blob_odd_sz;
-    int blob_even_sz;
+    int blob_odd_sz = 0;
+    int blob_even_sz = 0;
     rl2RasterPtr raster = NULL;
     rl2PrivRasterPtr rst;
     unsigned char *buffer = NULL;
@@ -6053,10 +9190,10 @@ get_triple_band_tile_image (sqlite3_context * context, const char *cvg_name,
 
 /* querying the tile */
     table_tile_data = sqlite3_mprintf ("%s_tile_data", cvg_name);
-    xtable_tile_data = gaiaDoubleQuotedSql (table_tile_data);
+    xtable_tile_data = rl2_double_quoted_sql (table_tile_data);
     sqlite3_free (table_tile_data);
     table_tiles = sqlite3_mprintf ("%s_tiles", cvg_name);
-    xtable_tiles = gaiaDoubleQuotedSql (table_tiles);
+    xtable_tiles = rl2_double_quoted_sql (table_tiles);
     sqlite3_free (table_tiles);
     sql = sqlite3_mprintf ("SELECT d.tile_data_odd, d.tile_data_even, "
 			   "t.pyramid_level FROM \"%s\" AS d "
@@ -6139,8 +9276,8 @@ get_triple_band_tile_image (sqlite3_context * context, const char *cvg_name,
 		      if (!ret)
 			  goto error;
 		      if (!build_rgb_alpha
-			  (width, height, rgba, &rgb, &alpha, bg_red, bg_green,
-			   bg_blue))
+			  (width, height, rgba, &rgb, &alpha, bg_red,
+			   bg_green, bg_blue))
 			  goto error;
 		      free (rgba);
 		      rgba = NULL;
@@ -6149,7 +9286,7 @@ get_triple_band_tile_image (sqlite3_context * context, const char *cvg_name,
 			    if (!get_payload_from_rgb_rgba_transparent
 				(width, height, rgb, alpha,
 				 RL2_OUTPUT_FORMAT_PNG, 100, &image,
-				 &image_size, opacity))
+				 &image_size, opacity, 0))
 				goto error;
 			}
 		      else
@@ -6169,11 +9306,12 @@ get_triple_band_tile_image (sqlite3_context * context, const char *cvg_name,
 			  get_rgba_from_multiband16 (width, height, red_band,
 						     green_band, blue_band,
 						     num_bands,
-						     (unsigned short *) buffer,
-						     mask, no_data, rgba);
+						     (unsigned short *)
+						     buffer, mask, no_data,
+						     rgba);
 		      if (!build_rgb_alpha
-			  (width, height, rgba, &rgb, &alpha, bg_red, bg_green,
-			   bg_blue))
+			  (width, height, rgba, &rgb, &alpha, bg_red,
+			   bg_green, bg_blue))
 			  goto error;
 		      free (rgba);
 		      rgba = NULL;
@@ -6182,7 +9320,7 @@ get_triple_band_tile_image (sqlite3_context * context, const char *cvg_name,
 			    if (!get_payload_from_rgb_rgba_transparent
 				(width, height, rgb, alpha,
 				 RL2_OUTPUT_FORMAT_PNG, 100, &image,
-				 &image_size, opacity))
+				 &image_size, opacity, 0))
 				goto error;
 			}
 		      else
@@ -6210,6 +9348,10 @@ get_triple_band_tile_image (sqlite3_context * context, const char *cvg_name,
     stmt = NULL;
 
     rl2_destroy_coverage (coverage);
+    if (rgb != NULL)
+	free (rgb);
+    if (alpha != NULL)
+	free (alpha);
     return 1;
 
   error:
@@ -6313,352 +9455,1191 @@ fnct_GetTripleBandTileImage (sqlite3_context * context, int argc,
 }
 
 static void
-fnct_GetMonoBandTileImage (sqlite3_context * context, int argc,
-			   sqlite3_value ** argv)
+fnct_GetMonoBandTileImage (sqlite3_context * context, int argc,
+			   sqlite3_value ** argv)
+{
+/* SQL function:
+/ GetMonoBandTileImage(text coverage, int tile_id, int mono_band)
+/ GetMonoBandTileImage(text coverage, int tile_id, int mono_band,
+/                      text bg_color)
+/ GetMonoBandTileImage(text coverage, int tile_id, int mono_band,
+/                      text bg_color, int transparent)
+/
+/ will return a BLOB containing the Image payload
+/ or NULL (INVALID ARGS)
+/
+*/
+    int err = 0;
+    const char *cvg_name;
+    sqlite3_int64 tile_id;
+    const char *bg_color = "#ffffff";
+    int transparent = 0;
+    int mono_band;
+    unsigned char bg_red;
+    unsigned char bg_green;
+    unsigned char bg_blue;
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+
+    if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	err = 1;
+    if (sqlite3_value_type (argv[1]) != SQLITE_INTEGER)
+	err = 1;
+    if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
+	err = 1;
+    if (argc > 3 && sqlite3_value_type (argv[3]) != SQLITE_TEXT)
+	err = 1;
+    if (argc > 4 && sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
+	err = 1;
+    if (err)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+
+/* retrieving the arguments */
+    cvg_name = (const char *) sqlite3_value_text (argv[0]);
+    tile_id = sqlite3_value_int64 (argv[1]);
+    mono_band = sqlite3_value_int (argv[2]);
+    if (argc > 3)
+	bg_color = (const char *) sqlite3_value_text (argv[3]);
+    if (argc > 4)
+	transparent = sqlite3_value_int (argv[4]);
+
+/* coarse args validation */
+    if (mono_band < 0 || mono_band > 255)
+	goto error;
+
+/* parsing the background color */
+    if (rl2_parse_hexrgb (bg_color, &bg_red, &bg_green, &bg_blue) != RL2_OK)
+	goto error;
+
+    if (get_triple_band_tile_image
+	(context, cvg_name, tile_id, mono_band, mono_band, mono_band, bg_red,
+	 bg_green, bg_blue, transparent))
+	return;
+
+  error:
+    sqlite3_result_null (context);
+}
+
+static void
+common_export_raw_pixels (int by_section, sqlite3_context * context, int argc,
+			  sqlite3_value ** argv)
+{
+/* common implementation Export RAW Pixels */
+    int err = 0;
+    const char *cvg_name;
+    sqlite3_int64 section_id = 0;
+    int width;
+    int height;
+    unsigned char *xblob = NULL;
+    int xblob_sz;
+    const unsigned char *blob = NULL;
+    int blob_sz;
+    double horz_res;
+    double vert_res;
+    int big_endian = 0;
+    rl2CoveragePtr coverage = NULL;
+    sqlite3 *sqlite;
+    const void *data;
+    int max_threads = 1;
+    int ret;
+    double pt_x;
+    double pt_y;
+    double minx;
+    double maxx;
+    double miny;
+    double maxy;
+    RL2_UNUSED ();		/* LCOV_EXCL_LINE */
+
+    if (by_section)
+      {
+	  /* filtering by Section */
+	  if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[1]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[4]) != SQLITE_BLOB)
+	      err = 1;
+	  if (sqlite3_value_type (argv[5]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[5]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 6 && sqlite3_value_type (argv[6]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[6]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 7 && sqlite3_value_type (argv[7]) != SQLITE_INTEGER)
+	      err = 1;
+      }
+    else
+      {
+	  /* whole Coverage */
+	  if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
+	      err = 1;
+	  if (sqlite3_value_type (argv[1]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
+	      err = 1;
+	  if (sqlite3_value_type (argv[3]) != SQLITE_BLOB)
+	      err = 1;
+	  if (sqlite3_value_type (argv[4]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[4]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 5 && sqlite3_value_type (argv[5]) != SQLITE_INTEGER
+	      && sqlite3_value_type (argv[5]) != SQLITE_FLOAT)
+	      err = 1;
+	  if (argc > 6 && sqlite3_value_type (argv[6]) != SQLITE_INTEGER)
+	      err = 1;
+      }
+    if (err)
+      {
+	  sqlite3_result_null (context);
+	  return;
+      }
+
+/* retrieving all arguments */
+    if (by_section)
+      {
+	  /* filtering by Section */
+	  cvg_name = (const char *) sqlite3_value_text (argv[0]);
+	  section_id = sqlite3_value_int64 (argv[1]);
+	  width = sqlite3_value_int (argv[2]);
+	  height = sqlite3_value_int (argv[3]);
+	  blob = (unsigned char *) sqlite3_value_blob (argv[4]);
+	  blob_sz = sqlite3_value_bytes (argv[4]);
+	  if (sqlite3_value_type (argv[5]) == SQLITE_INTEGER)
+	    {
+		int ival = sqlite3_value_int (argv[5]);
+		horz_res = ival;
+	    }
+	  else
+	      horz_res = sqlite3_value_double (argv[5]);
+	  if (argc > 6)
+	    {
+		if (sqlite3_value_type (argv[6]) == SQLITE_INTEGER)
+		  {
+		      int ival = sqlite3_value_int (argv[6]);
+		      vert_res = ival;
+		  }
+		else
+		    vert_res = sqlite3_value_double (argv[6]);
+	    }
+	  else
+	      vert_res = horz_res;
+	  if (argc > 7)
+	      big_endian = sqlite3_value_int (argv[7]);
+      }
+    else
+      {
+	  /* whole Coverage */
+	  cvg_name = (const char *) sqlite3_value_text (argv[0]);
+	  width = sqlite3_value_int (argv[1]);
+	  height = sqlite3_value_int (argv[2]);
+	  blob = (unsigned char *) sqlite3_value_blob (argv[3]);
+	  blob_sz = sqlite3_value_bytes (argv[3]);
+	  if (sqlite3_value_type (argv[4]) == SQLITE_INTEGER)
+	    {
+		int ival = sqlite3_value_int (argv[4]);
+		horz_res = ival;
+	    }
+	  else
+	      horz_res = sqlite3_value_double (argv[4]);
+	  if (argc > 5)
+	    {
+		if (sqlite3_value_type (argv[5]) == SQLITE_INTEGER)
+		  {
+		      int ival = sqlite3_value_int (argv[5]);
+		      vert_res = ival;
+		  }
+		else
+		    vert_res = sqlite3_value_double (argv[5]);
+	    }
+	  else
+	      vert_res = horz_res;
+	  if (argc > 6)
+	      big_endian = sqlite3_value_int (argv[6]);
+      }
+
+/* coarse args validation */
+    if (width < 0)
+	goto error;
+    if (height < 0)
+	goto error;
+    if (big_endian)
+	big_endian = 1;
+
+    sqlite = sqlite3_context_db_handle (context);
+    data = sqlite3_user_data (context);
+    if (data != NULL)
+      {
+	  struct rl2_private_data *priv_data = (struct rl2_private_data *) data;
+	  max_threads = priv_data->max_threads;
+	  if (max_threads < 1)
+	      max_threads = 1;
+	  if (max_threads > 64)
+	      max_threads = 64;
+      }
+    if (!by_section)
+      {
+	  /* excluding any Mixed Resolution Coverage */
+	  if (rl2_is_mixed_resolutions_coverage (sqlite, cvg_name) > 0)
+	      goto error;
+      }
+
+/* checking the Geometry */
+    if (rl2_parse_point (sqlite, blob, blob_sz, &pt_x, &pt_y) == RL2_OK)
+      {
+	  /* assumed to be the GeoTiff Center Point */
+	  double ext_x = (double) width * horz_res;
+	  double ext_y = (double) height * vert_res;
+	  minx = pt_x - ext_x / 2.0;
+	  maxx = minx + ext_x;
+	  miny = pt_y - ext_y / 2.0;
+	  maxy = miny + ext_y;
+      }
+    else if (rl2_parse_bbox
+	     (sqlite, blob, blob_sz, &minx, &miny, &maxx, &maxy) != RL2_OK)
+	goto error;
+
+/* attempting to load the Coverage definitions from the DBMS */
+    coverage = rl2_create_coverage_from_dbms (sqlite, cvg_name);
+    if (coverage == NULL)
+	goto error;
+    if (by_section)
+      {
+	  /* only a single Section */
+	  ret =
+	      rl2_export_section_raw_pixels_from_dbms (sqlite, max_threads,
+						       coverage, section_id,
+						       horz_res, vert_res,
+						       minx, miny, maxx, maxy,
+						       width, height,
+						       big_endian, &xblob,
+						       &xblob_sz);
+      }
+    else
+      {
+	  /* whole Coverage */
+	  ret =
+	      rl2_export_raw_pixels_from_dbms (sqlite, max_threads, coverage,
+					       horz_res, vert_res, minx, miny,
+					       maxx, maxy, width, height,
+					       big_endian, &xblob, &xblob_sz);
+      }
+    if (ret != RL2_OK)
+	goto error;
+    rl2_destroy_coverage (coverage);
+    sqlite3_result_blob (context, xblob, xblob_sz, free);
+    return;
+
+  error:
+    if (coverage != NULL)
+	rl2_destroy_coverage (coverage);
+    sqlite3_result_null (context);
+}
+
+static void
+fnct_ExportRawPixels (sqlite3_context * context, int argc,
+		      sqlite3_value ** argv)
+{
+/* SQL function:
+/ ExportRawPixels(text coverage, int width, int height, BLOB geom,
+/                 double resolution)
+/ ExportRawPixels(text coverage, int width, int height, BLOB geom,
+/                 double horz_res, double vert_res)
+/ ExportRawPixels(text coverage, int width, int height, BLOB geom,
+/                 double horz_res, double vert_res, int big_endian)
+/
+/ will return a BLOB pixel buffer
+/ or NULL (INVALID ARGS)
+/
+*/
+    common_export_raw_pixels (0, context, argc, argv);
+}
+
+static void
+fnct_ExportSectionRawPixels (sqlite3_context * context, int argc,
+			     sqlite3_value ** argv)
+{
+/* SQL function:
+/ ExportSectionRawPixels(text coverage, int section_id, int width,
+/                        int height, BLOB geom, double resolution)
+/ ExportSectionRawPixels(text coverage, int section_id, int width,
+/                        int height, BLOB geom, double horz_res,
+/                        double vert_res)
+/ ExportSectionRawPixels(text coverage, int section_id, int width,
+/                        int height, BLOB geom, double horz_res,
+/                        double vert_res, int big_endian)
+/
+/ will return a BLOB pixel buffer
+/ or NULL (INVALID ARGS)
+/
+*/
+    common_export_raw_pixels (1, context, argc, argv);
+}
+
+static void
+fnct_ImportSectionRawPixels (sqlite3_context * context, int argc,
+			     sqlite3_value ** argv)
 {
 /* SQL function:
-/ GetMonoBandTileImage(text coverage, int tile_id, int mono_band)
-/ GetMonoBandTileImage(text coverage, int tile_id, int mono_band,
-/                      text bg_color)
-/ GetMonoBandTileImage(text coverage, int tile_id, int mono_band,
-/                      text bg_color, int transparent)
+/ ImportSectionRawPixels(text coverage, text section_name, int width,
+/                        int height, BLOB pixels, BLOB geom)
+/ ImportSectionRawPixels(text coverage, text section_name, int width,
+/                        int height, BLOB pixels, BLOB geom,
+/                        int pyramidize)
+/ ImportSectionRawPixels(text coverage, text section_name, int width,
+/                        int height, BLOB pixels, BLOB geom,
+/                        int pyramidize, int transaction)
+/ ImportSectionRawPixels(text coverage, text section_name, int width,
+/                        int height, BLOB pixels, BLOB geom,
+/                        int pyramidize, int transaction,
+/                        int big_endian)
 /
-/ will return a BLOB containing the Image payload
-/ or NULL (INVALID ARGS)
+/ will return 1 (TRUE, success) or 0 (FALSE, failure)
+/ or -1 (INVALID ARGS)
 /
 */
     int err = 0;
     const char *cvg_name;
-    sqlite3_int64 tile_id;
-    const char *bg_color = "#ffffff";
-    int transparent = 0;
-    int mono_band;
-    unsigned char bg_red;
-    unsigned char bg_green;
-    unsigned char bg_blue;
+    const char *sctn_name;
+    int width;
+    int height;
+    const unsigned char *pixels;
+    int pixels_sz;
+    const unsigned char *blob;
+    int blob_sz;
+    int transaction = 1;
+    int pyramidize = 1;
+    int big_endian = 0;
+    int srid;
+    int cov_srid;
+    double minx;
+    double maxx;
+    double miny;
+    double maxy;
+    int sample_sz = 0;
+    int expected_sz;
+    int errcode = -1;
+    unsigned char sample_type;
+    unsigned char pixel_type;
+    unsigned char num_bands;
+    unsigned char *bufpix = NULL;
+    rl2CoveragePtr coverage = NULL;
+    rl2RasterPtr raster = NULL;
+    rl2PalettePtr plt = NULL;
+    rl2PixelPtr no_data = NULL;
+    sqlite3 *sqlite;
+    int ret;
+    int max_threads = 1;
+    const char *data;
     RL2_UNUSED ();		/* LCOV_EXCL_LINE */
 
     if (sqlite3_value_type (argv[0]) != SQLITE_TEXT)
 	err = 1;
-    if (sqlite3_value_type (argv[1]) != SQLITE_INTEGER)
+    if (sqlite3_value_type (argv[1]) != SQLITE_TEXT)
 	err = 1;
     if (sqlite3_value_type (argv[2]) != SQLITE_INTEGER)
 	err = 1;
-    if (argc > 3 && sqlite3_value_type (argv[3]) != SQLITE_TEXT)
+    if (sqlite3_value_type (argv[3]) != SQLITE_INTEGER)
 	err = 1;
-    if (argc > 4 && sqlite3_value_type (argv[4]) != SQLITE_INTEGER)
+    if (sqlite3_value_type (argv[4]) != SQLITE_BLOB)
+	err = 1;
+    if (sqlite3_value_type (argv[5]) != SQLITE_BLOB)
+	err = 1;
+    if (argc > 6 && sqlite3_value_type (argv[6]) != SQLITE_INTEGER)
+	err = 1;
+    if (argc > 7 && sqlite3_value_type (argv[7]) != SQLITE_INTEGER)
+	err = 1;
+    if (argc > 8 && sqlite3_value_type (argv[8]) != SQLITE_INTEGER)
 	err = 1;
     if (err)
       {
-	  sqlite3_result_null (context);
+	  sqlite3_result_int (context, -1);
 	  return;
       }
 
 /* retrieving the arguments */
     cvg_name = (const char *) sqlite3_value_text (argv[0]);
-    tile_id = sqlite3_value_int64 (argv[1]);
-    mono_band = sqlite3_value_int (argv[2]);
-    if (argc > 3)
-	bg_color = (const char *) sqlite3_value_text (argv[3]);
-    if (argc > 4)
-	transparent = sqlite3_value_int (argv[4]);
+    sctn_name = (const char *) sqlite3_value_text (argv[1]);
+    width = sqlite3_value_int (argv[2]);
+    height = sqlite3_value_int (argv[3]);
+    pixels = sqlite3_value_blob (argv[4]);
+    pixels_sz = sqlite3_value_bytes (argv[4]);
+    blob = sqlite3_value_blob (argv[5]);
+    blob_sz = sqlite3_value_bytes (argv[5]);
+    if (argc > 6)
+	pyramidize = sqlite3_value_int (argv[6]);
+    if (argc > 7)
+	transaction = sqlite3_value_int (argv[7]);
+    if (argc > 8)
+	big_endian = sqlite3_value_int (argv[8]);
+
+/* attempting to load the Coverage definitions from the DBMS */
+    sqlite = sqlite3_context_db_handle (context);
+
+    data = sqlite3_user_data (context);
+    if (data != NULL)
+      {
+	  struct rl2_private_data *priv_data = (struct rl2_private_data *) data;
+	  max_threads = priv_data->max_threads;
+	  if (max_threads < 1)
+	      max_threads = 1;
+	  if (max_threads > 64)
+	      max_threads = 64;
+      }
+    coverage = rl2_create_coverage_from_dbms (sqlite, cvg_name);
+    if (coverage == NULL)
+      {
+	  sqlite3_result_int (context, -1);
+	  return;
+      }
 
 /* coarse args validation */
-    if (mono_band < 0 || mono_band > 255)
-	goto error;
+    if (width < 0)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+    if (height < 0)
+      {
+	  errcode = -1;
+	  goto error;
+      }
 
-/* parsing the background color */
-    if (rl2_parse_hexrgb (bg_color, &bg_red, &bg_green, &bg_blue) != RL2_OK)
+/* checking the Geometry */
+    if (rl2_parse_bbox_srid
+	(sqlite, blob, blob_sz, &srid, &minx, &miny, &maxx, &maxy) != RL2_OK)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+
+    if (rl2_get_coverage_type
+	(coverage, &sample_type, &pixel_type, &num_bands) != RL2_OK)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+    if (rl2_get_coverage_srid (coverage, &cov_srid) != RL2_OK)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+
+    switch (sample_type)
+      {
+      case RL2_SAMPLE_1_BIT:
+      case RL2_SAMPLE_2_BIT:
+      case RL2_SAMPLE_4_BIT:
+      case RL2_SAMPLE_INT8:
+      case RL2_SAMPLE_UINT8:
+	  sample_sz = 1;
+	  break;
+      case RL2_SAMPLE_INT16:
+      case RL2_SAMPLE_UINT16:
+	  sample_sz = 2;
+	  break;
+      case RL2_SAMPLE_INT32:
+      case RL2_SAMPLE_UINT32:
+      case RL2_SAMPLE_FLOAT:
+	  sample_sz = 4;
+	  break;
+      case RL2_SAMPLE_DOUBLE:
+	  sample_sz = 8;
+	  break;
+      };
+    expected_sz = width * height * num_bands * sample_sz;
+    if (expected_sz != pixels_sz)
+      {
+	  fprintf (stderr,
+		   "RL2_ImportSectionRawPixels: mismatching BLOB size (expected %u)\n",
+		   expected_sz);
+	  goto error;
+      }
+    if (srid != cov_srid)
+      {
+	  fprintf (stderr,
+		   "RL2_ImportSectionRawPixels: mismatching SRID (expected %d)\n",
+		   cov_srid);
+	  goto error;
+      }
+    plt = rl2_get_dbms_palette (sqlite, cvg_name);
+    no_data = rl2_clone_pixel (rl2_get_coverage_no_data (coverage));
+    bufpix =
+	rl2_copy_endian_raw_pixels (pixels, pixels_sz, width, height,
+				    sample_type, num_bands, big_endian);
+    if (bufpix == NULL)
 	goto error;
+    raster =
+	rl2_create_raster (width, height, sample_type, pixel_type, num_bands,
+			   bufpix, pixels_sz, plt, NULL, 0, no_data);
+/* releasing ownership */
+    bufpix = NULL;
+    plt = NULL;
+    no_data = NULL;
+    if (raster == NULL)
+      {
+	  errcode = -1;
+	  goto error;
+      }
+/* georeferencing the raster */
+    if (rl2_raster_georeference_frame (raster, srid, minx, miny, maxx, maxy)
+	!= RL2_OK)
+      {
+	  errcode = -1;
+	  goto error;
+      }
 
-    if (get_triple_band_tile_image
-	(context, cvg_name, tile_id, mono_band, mono_band, mono_band, bg_red,
-	 bg_green, bg_blue, transparent))
-	return;
+/* attempting to load the Raster into the DBMS */
+    if (transaction)
+      {
+	  /* starting a DBMS Transaction */
+	  ret = sqlite3_exec (sqlite, "BEGIN", NULL, NULL, NULL);
+	  if (ret != SQLITE_OK)
+	    {
+		rl2_destroy_coverage (coverage);
+		sqlite3_result_int (context, -1);
+		return;
+	    }
+      }
+    ret =
+	rl2_load_raw_raster_into_dbms (sqlite, max_threads, coverage,
+				       sctn_name, raster, pyramidize);
+    rl2_destroy_coverage (coverage);
+    rl2_destroy_raster (raster);
+    if (ret != RL2_OK)
+      {
+	  if (transaction)
+	    {
+		/* invalidating the pending transaction */
+		sqlite3_exec (sqlite, "ROLLBACK", NULL, NULL, NULL);
+	    }
+	  sqlite3_result_int (context, 0);
+	  return;
+      }
+    if (transaction)
+      {
+	  /* committing the still pending transaction */
+	  ret = sqlite3_exec (sqlite, "COMMIT", NULL, NULL, NULL);
+	  if (ret != SQLITE_OK)
+	    {
+		sqlite3_result_int (context, -1);
+		return;
+	    }
+      }
+    sqlite3_result_int (context, 1);
+    return;
 
   error:
-    sqlite3_result_null (context);
+    if (raster != NULL)
+	rl2_destroy_raster (raster);
+    if (coverage != NULL)
+	rl2_destroy_coverage (coverage);
+    if (plt != NULL)
+	rl2_destroy_palette (plt);
+    if (no_data != NULL)
+	rl2_destroy_pixel (no_data);
+    if (bufpix != NULL)
+	free (bufpix);
+    sqlite3_result_int (context, errcode);
 }
 
 static void
-register_rl2_sql_functions (void *p_db)
+register_rl2_sql_functions (void *p_db, const void *p_data)
 {
     sqlite3 *db = p_db;
+    struct rl2_private_data *priv_data = (struct rl2_private_data *) p_data;
     const char *security_level;
-    sqlite3_create_function (db, "rl2_version", 0, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "rl2_version", 0,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_rl2_version, 0, 0);
-    sqlite3_create_function (db, "rl2_target_cpu", 0, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "rl2_target_cpu", 0,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_rl2_target_cpu, 0, 0);
-    sqlite3_create_function (db, "IsValidPixel", 3, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "rl2_has_codec_none", 0,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_rl2_has_codec_none, 0, 0);
+    sqlite3_create_function (db, "rl2_has_codec_deflate", 0,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_rl2_has_codec_deflate, 0, 0);
+    sqlite3_create_function (db, "rl2_has_codec_deflate_no", 0,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_rl2_has_codec_deflate_no, 0, 0);
+    sqlite3_create_function (db, "rl2_has_codec_lzma", 0,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_rl2_has_codec_lzma, 0, 0);
+    sqlite3_create_function (db, "rl2_has_codec_lzma_no", 0,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_rl2_has_codec_lzma_no, 0, 0);
+    sqlite3_create_function (db, "rl2_has_codec_jpeg", 0,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_rl2_has_codec_jpeg, 0, 0);
+    sqlite3_create_function (db, "rl2_has_codec_png", 0,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_rl2_has_codec_png, 0, 0);
+    sqlite3_create_function (db, "rl2_has_codec_fax4", 0,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_rl2_has_codec_fax4, 0, 0);
+    sqlite3_create_function (db, "rl2_has_codec_charls", 0,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_rl2_has_codec_charls, 0, 0);
+    sqlite3_create_function (db, "rl2_has_codec_webp", 0,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_rl2_has_codec_webp, 0, 0);
+    sqlite3_create_function (db, "rl2_has_codec_ll_webp", 0,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_rl2_has_codec_ll_webp, 0, 0);
+    sqlite3_create_function (db, "rl2_has_codec_jp2", 0,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_rl2_has_codec_jp2, 0, 0);
+    sqlite3_create_function (db, "rl2_has_codec_ll_jp2", 0,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_rl2_has_codec_ll_jp2, 0, 0);
+    sqlite3_create_function (db, "RL2_GetMaxThreads", 0,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMaxThreads, 0, 0);
+    sqlite3_create_function (db, "RL2_SetMaxThreads", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_SetMaxThreads, 0, 0);
+    sqlite3_create_function (db, "IsValidPixel", 3,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_IsValidPixel, 0, 0);
-    sqlite3_create_function (db, "RL2_IsValidPixel", 3, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_IsValidPixel", 3,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_IsValidPixel, 0, 0);
-    sqlite3_create_function (db, "IsValidRasterPalette", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "IsValidRasterPalette", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_IsValidRasterPalette, 0, 0);
-    sqlite3_create_function (db, "RL2_IsValidRasterPalette", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_IsValidRasterPalette", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_IsValidRasterPalette, 0, 0);
-    sqlite3_create_function (db, "IsValidRasterStatistics", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "IsValidRasterStatistics", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_IsValidRasterStatistics, 0, 0);
+    sqlite3_create_function (db, "RL2_IsValidRasterStatistics", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_IsValidRasterStatistics, 0, 0);
-    sqlite3_create_function (db, "RL2_IsValidRasterStatistics", 2, SQLITE_ANY,
-			     0, fnct_IsValidRasterStatistics, 0, 0);
-    sqlite3_create_function (db, "IsValidRasterStatistics", 3, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "IsValidRasterStatistics", 3,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_IsValidRasterStatistics, 0, 0);
-    sqlite3_create_function (db, "RL2_IsValidRasterStatistics", 3, SQLITE_ANY,
-			     0, fnct_IsValidRasterStatistics, 0, 0);
-    sqlite3_create_function (db, "IsValidRasterTile", 4, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_IsValidRasterStatistics", 3,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_IsValidRasterStatistics, 0, 0);
+    sqlite3_create_function (db, "IsValidRasterTile", 4,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_IsValidRasterTile, 0, 0);
-    sqlite3_create_function (db, "RL2_IsValidRasterTile", 4, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_IsValidRasterTile", 4,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_IsValidRasterTile, 0, 0);
-    sqlite3_create_function (db, "CreateCoverage", 10, SQLITE_ANY, 0,
-			     fnct_CreateCoverage, 0, 0);
-    sqlite3_create_function (db, "CreateCoverage", 11, SQLITE_ANY, 0,
-			     fnct_CreateCoverage, 0, 0);
-    sqlite3_create_function (db, "CreateCoverage", 12, SQLITE_ANY, 0,
-			     fnct_CreateCoverage, 0, 0);
-    sqlite3_create_function (db, "RL2_CreateCoverage", 10, SQLITE_ANY, 0,
-			     fnct_CreateCoverage, 0, 0);
-    sqlite3_create_function (db, "RL2_CreateCoverage", 11, SQLITE_ANY, 0,
-			     fnct_CreateCoverage, 0, 0);
-    sqlite3_create_function (db, "RL2_CreateCoverage", 12, SQLITE_ANY, 0,
-			     fnct_CreateCoverage, 0, 0);
-    sqlite3_create_function (db, "DeleteSection", 2, SQLITE_ANY, 0,
-			     fnct_DeleteSection, 0, 0);
-    sqlite3_create_function (db, "RL2_DeleteSection", 2, SQLITE_ANY, 0,
-			     fnct_DeleteSection, 0, 0);
-    sqlite3_create_function (db, "DeleteSection", 3, SQLITE_ANY, 0,
-			     fnct_DeleteSection, 0, 0);
-    sqlite3_create_function (db, "RL2_DeleteSection", 3, SQLITE_ANY, 0,
-			     fnct_DeleteSection, 0, 0);
-    sqlite3_create_function (db, "DropCoverage", 1, SQLITE_ANY, 0,
-			     fnct_DropCoverage, 0, 0);
-    sqlite3_create_function (db, "RL2_DropCoverage", 1, SQLITE_ANY, 0,
-			     fnct_DropCoverage, 0, 0);
-    sqlite3_create_function (db, "DropCoverage", 2, SQLITE_ANY, 0,
-			     fnct_DropCoverage, 0, 0);
-    sqlite3_create_function (db, "RL2_DropCoverage", 2, SQLITE_ANY, 0,
-			     fnct_DropCoverage, 0, 0);
-    sqlite3_create_function (db, "SetCoverageInfos", 3, SQLITE_ANY, 0,
-			     fnct_SetCoverageInfos, 0, 0);
-    sqlite3_create_function (db, "RL2_SetCoverageInfos", 3, SQLITE_ANY, 0,
-			     fnct_SetCoverageInfos, 0, 0);
-    sqlite3_create_function (db, "GetPaletteNumEntries", 1, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "CreateRasterCoverage", 10,
+			     SQLITE_UTF8, 0, fnct_CreateRasterCoverage, 0, 0);
+    sqlite3_create_function (db, "CreateRasterCoverage", 11,
+			     SQLITE_UTF8, 0, fnct_CreateRasterCoverage, 0, 0);
+    sqlite3_create_function (db, "CreateRasterCoverage", 12,
+			     SQLITE_UTF8, 0, fnct_CreateRasterCoverage, 0, 0);
+    sqlite3_create_function (db, "CreateRasterCoverage", 17,
+			     SQLITE_UTF8, 0, fnct_CreateRasterCoverage, 0, 0);
+    sqlite3_create_function (db, "RL2_CreateRasterCoverage", 10,
+			     SQLITE_UTF8, 0, fnct_CreateRasterCoverage, 0, 0);
+    sqlite3_create_function (db, "RL2_CreateRasterCoverage", 11,
+			     SQLITE_UTF8, 0, fnct_CreateRasterCoverage, 0, 0);
+    sqlite3_create_function (db, "RL2_CreateRasterCoverage", 12,
+			     SQLITE_UTF8, 0, fnct_CreateRasterCoverage, 0, 0);
+    sqlite3_create_function (db, "RL2_CreateRasterCoverage", 17,
+			     SQLITE_UTF8, 0, fnct_CreateRasterCoverage, 0, 0);
+    sqlite3_create_function (db, "CopyRasterCoverage", 2,
+			     SQLITE_UTF8, 0, fnct_CopyRasterCoverage, 0, 0);
+    sqlite3_create_function (db, "RL2_CopyRasterCoverage", 2,
+			     SQLITE_UTF8, 0, fnct_CopyRasterCoverage, 0, 0);
+    sqlite3_create_function (db, "CopyRasterCoverage", 3,
+			     SQLITE_UTF8, 0, fnct_CopyRasterCoverage, 0, 0);
+    sqlite3_create_function (db, "RL2_CopyRasterCoverage", 3,
+			     SQLITE_UTF8, 0, fnct_CopyRasterCoverage, 0, 0);
+    sqlite3_create_function (db, "DeleteSection", 2,
+			     SQLITE_UTF8, 0, fnct_DeleteSection, 0, 0);
+    sqlite3_create_function (db, "RL2_DeleteSection", 2,
+			     SQLITE_UTF8, 0, fnct_DeleteSection, 0, 0);
+    sqlite3_create_function (db, "DeleteSection", 3,
+			     SQLITE_UTF8, 0, fnct_DeleteSection, 0, 0);
+    sqlite3_create_function (db, "RL2_DeleteSection", 3,
+			     SQLITE_UTF8, 0, fnct_DeleteSection, 0, 0);
+    sqlite3_create_function (db, "DropRasterCoverage", 1,
+			     SQLITE_UTF8, 0, fnct_DropRasterCoverage, 0, 0);
+    sqlite3_create_function (db, "RL2_DropRasterCoverage", 1,
+			     SQLITE_UTF8, 0, fnct_DropRasterCoverage, 0, 0);
+    sqlite3_create_function (db, "DropRasterCoverage", 2,
+			     SQLITE_UTF8, 0, fnct_DropRasterCoverage, 0, 0);
+    sqlite3_create_function (db, "RL2_DropRasterCoverage", 2,
+			     SQLITE_UTF8, 0, fnct_DropRasterCoverage, 0, 0);
+    sqlite3_create_function (db, "SetRasterCoverageInfos", 3,
+			     SQLITE_UTF8, 0, fnct_SetRasterCoverageInfos, 0, 0);
+    sqlite3_create_function (db, "RL2_SetRasterCoverageInfos", 3, SQLITE_UTF8,
+			     0, fnct_SetRasterCoverageInfos, 0, 0);
+    sqlite3_create_function (db, "SetRasterCoverageDefaultBands", 5,
+			     SQLITE_UTF8, 0,
+			     fnct_SetRasterCoverageDefaultBands, 0, 0);
+    sqlite3_create_function (db, "RL2_SetRasterCoverageDefaultBands", 5,
+			     SQLITE_UTF8, 0,
+			     fnct_SetRasterCoverageDefaultBands, 0, 0);
+    sqlite3_create_function (db, "EnableRasterCoverageAutoNDVI", 2,
+			     SQLITE_UTF8, 0,
+			     fnct_EnableRasterCoverageAutoNDVI, 0, 0);
+    sqlite3_create_function (db, "RL2_EnableRasterCoverageAutoNDVI", 2,
+			     SQLITE_UTF8, 0,
+			     fnct_EnableRasterCoverageAutoNDVI, 0, 0);
+    sqlite3_create_function (db, "IsRasterCoverageAutoNdviEnabled", 1,
+			     SQLITE_UTF8, 0,
+			     fnct_IsRasterCoverageAutoNdviEnabled, 0, 0);
+    sqlite3_create_function (db, "RL2_IsRasterCoverageAutoNdviEnabled", 1,
+			     SQLITE_UTF8, 0,
+			     fnct_IsRasterCoverageAutoNdviEnabled, 0, 0);
+    sqlite3_create_function (db, "GetPaletteNumEntries", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_GetPaletteNumEntries, 0, 0);
-    sqlite3_create_function (db, "RL2_GetPaletteNumEntries", 1, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_GetPaletteNumEntries", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_GetPaletteNumEntries, 0, 0);
-    sqlite3_create_function (db, "GetPaletteColorEntry", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "GetPaletteColorEntry", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_GetPaletteColorEntry, 0, 0);
-    sqlite3_create_function (db, "RL2_GetPaletteColorEntry", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_GetPaletteColorEntry", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_GetPaletteColorEntry, 0, 0);
-    sqlite3_create_function (db, "SetPaletteColorEntry", 3, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "SetPaletteColorEntry", 3,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_SetPaletteColorEntry, 0, 0);
-    sqlite3_create_function (db, "RL2_SetPaletteColorEntry", 3, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_SetPaletteColorEntry", 3,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_SetPaletteColorEntry, 0, 0);
-    sqlite3_create_function (db, "PaletteEquals", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "PaletteEquals", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_PaletteEquals, 0, 0);
-    sqlite3_create_function (db, "RL2_PaletteEquals", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_PaletteEquals", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_PaletteEquals, 0, 0);
-    sqlite3_create_function (db, "CreatePixel", 3, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "CreatePixel", 3,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_CreatePixel, 0, 0);
-    sqlite3_create_function (db, "RL2_CreatePixel", 3, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_CreatePixel", 3,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_CreatePixel, 0, 0);
-    sqlite3_create_function (db, "GetPixelType", 1, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "GetPixelType", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_GetPixelType, 0, 0);
-    sqlite3_create_function (db, "RL2_GetPixelType", 1, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_GetPixelType", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_GetPixelType, 0, 0);
-    sqlite3_create_function (db, "GetPixelSampleType", 1, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "GetPixelSampleType", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_GetPixelSampleType, 0, 0);
-    sqlite3_create_function (db, "RL2_GetPixelSampleType", 1, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_GetPixelSampleType", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_GetPixelSampleType, 0, 0);
-    sqlite3_create_function (db, "GetPixelNumBands", 1, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "GetPixelNumBands", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_GetPixelNumBands, 0, 0);
-    sqlite3_create_function (db, "RL2_GetPixelNumBands", 1, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_GetPixelNumBands", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_GetPixelNumBands, 0, 0);
-    sqlite3_create_function (db, "GetPixelValue", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "GetPixelValue", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_GetPixelValue, 0, 0);
-    sqlite3_create_function (db, "RL2_GetPixelValue", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_GetPixelValue", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_GetPixelValue, 0, 0);
-    sqlite3_create_function (db, "SetPixelValue", 3, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "SetPixelValue", 3,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_SetPixelValue, 0, 0);
-    sqlite3_create_function (db, "RL2_SetPixelValue", 3, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_SetPixelValue", 3,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_SetPixelValue, 0, 0);
-    sqlite3_create_function (db, "IsTransparentPixel", 1, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "IsTransparentPixel", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_IsTransparentPixel, 0, 0);
-    sqlite3_create_function (db, "RL2_IsTransparentPixel", 1, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_IsTransparentPixel", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_IsTransparentPixel, 0, 0);
-    sqlite3_create_function (db, "IsOpaquePixel", 1, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "IsOpaquePixel", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_IsOpaquePixel, 0, 0);
-    sqlite3_create_function (db, "RL2_IsOpaquePixel", 1, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_IsOpaquePixel", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_IsOpaquePixel, 0, 0);
-    sqlite3_create_function (db, "SetTransparentPixel", 1, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "SetTransparentPixel", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_SetTransparentPixel, 0, 0);
-    sqlite3_create_function (db, "RL2_SetTransparentPixel", 1, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_SetTransparentPixel", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_SetTransparentPixel, 0, 0);
-    sqlite3_create_function (db, "SetOpaquePixel", 1, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "SetOpaquePixel", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_SetOpaquePixel, 0, 0);
-    sqlite3_create_function (db, "RL2_SetOpaquePixel", 1, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_SetOpaquePixel", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_SetOpaquePixel, 0, 0);
-    sqlite3_create_function (db, "PixelEquals", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "PixelEquals", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_PixelEquals, 0, 0);
-    sqlite3_create_function (db, "RL2_PixelEquals", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_PixelEquals", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_PixelEquals, 0, 0);
+    sqlite3_create_function (db, "IsValidFont", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_IsValidFont, 0, 0);
+    sqlite3_create_function (db, "RL2_IsValidFont", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_IsValidFont, 0, 0);
+    sqlite3_create_function (db, "CheckFontFacename", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_CheckFontFacename, 0, 0);
+    sqlite3_create_function (db, "RL2_CheckFontFacename", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_CheckFontFacename, 0, 0);
+    sqlite3_create_function (db, "GetFontFamily", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_GetFontFamily, 0, 0);
+    sqlite3_create_function (db, "RL2_GetFontFamily", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_GetFontFamily, 0, 0);
+    sqlite3_create_function (db, "GetFontFacename", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_GetFontFacename, 0, 0);
+    sqlite3_create_function (db, "RL2_GetFontFacename", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_GetFontFacename, 0, 0);
+    sqlite3_create_function (db, "IsFontBold", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_IsFontBold, 0, 0);
+    sqlite3_create_function (db, "RL2_IsFontBold", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_IsFontBold, 0, 0);
+    sqlite3_create_function (db, "IsFontItalic", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_IsFontItalic, 0, 0);
+    sqlite3_create_function (db, "RL2_IsFontItalic", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_IsFontItalic, 0, 0);
     sqlite3_create_function (db, "GetRasterStatistics_NoDataPixelsCount", 1,
-			     SQLITE_ANY, 0,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_GetRasterStatistics_NoDataPixelsCount, 0, 0);
-    sqlite3_create_function (db, "RL2_GetRasterStatistics_NoDataPixelsCount", 1,
-			     SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_GetRasterStatistics_NoDataPixelsCount",
+			     1, SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_GetRasterStatistics_NoDataPixelsCount, 0, 0);
     sqlite3_create_function (db, "GetRasterStatistics_ValidPixelsCount", 1,
-			     SQLITE_ANY, 0,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_GetRasterStatistics_ValidPixelsCount, 0, 0);
-    sqlite3_create_function (db, "RL2_GetRasterStatistics_ValidPixelsCount", 1,
-			     SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_GetRasterStatistics_ValidPixelsCount",
+			     1, SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_GetRasterStatistics_ValidPixelsCount, 0, 0);
     sqlite3_create_function (db, "GetRasterStatistics_SampleType", 1,
-			     SQLITE_ANY, 0, fnct_GetRasterStatistics_SampleType,
-			     0, 0);
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_GetRasterStatistics_SampleType, 0, 0);
     sqlite3_create_function (db, "RL2_GetRasterStatistics_SampleType", 1,
-			     SQLITE_ANY, 0, fnct_GetRasterStatistics_SampleType,
-			     0, 0);
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_GetRasterStatistics_SampleType, 0, 0);
     sqlite3_create_function (db, "GetRasterStatistics_BandsCount", 1,
-			     SQLITE_ANY, 0, fnct_GetRasterStatistics_BandsCount,
-			     0, 0);
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_GetRasterStatistics_BandsCount, 0, 0);
     sqlite3_create_function (db, "RL2_GetRasterStatistics_BandsCount", 1,
-			     SQLITE_ANY, 0, fnct_GetRasterStatistics_BandsCount,
-			     0, 0);
-    sqlite3_create_function (db, "GetBandStatistics_Min", 2, SQLITE_ANY, 0,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_GetRasterStatistics_BandsCount, 0, 0);
+    sqlite3_create_function (db, "GetBandStatistics_Min", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_GetBandStatistics_Min, 0, 0);
-    sqlite3_create_function (db, "RL2_GetBandStatistics_Min", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_GetBandStatistics_Min", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_GetBandStatistics_Min, 0, 0);
-    sqlite3_create_function (db, "GetBandStatistics_Max", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "GetBandStatistics_Max", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_GetBandStatistics_Max, 0, 0);
-    sqlite3_create_function (db, "RL2_GetBandStatistics_Max", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_GetBandStatistics_Max", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_GetBandStatistics_Max, 0, 0);
-    sqlite3_create_function (db, "GetBandStatistics_Avg", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "GetBandStatistics_Avg", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_GetBandStatistics_Avg, 0, 0);
-    sqlite3_create_function (db, "RL2_GetBandStatistics_Avg", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_GetBandStatistics_Avg", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_GetBandStatistics_Avg, 0, 0);
-    sqlite3_create_function (db, "GetBandStatistics_Var", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "GetBandStatistics_Var", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_GetBandStatistics_Var, 0, 0);
-    sqlite3_create_function (db, "RL2_GetBandStatistics_Var", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_GetBandStatistics_Var", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_GetBandStatistics_Var, 0, 0);
-    sqlite3_create_function (db, "GetBandStatistics_StdDev", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "GetBandStatistics_StdDev", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_GetBandStatistics_StdDev, 0, 0);
+    sqlite3_create_function (db, "RL2_GetBandStatistics_StdDev", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
 			     fnct_GetBandStatistics_StdDev, 0, 0);
-    sqlite3_create_function (db, "RL2_GetBandStatistics_StdDev", 2, SQLITE_ANY,
-			     0, fnct_GetBandStatistics_StdDev, 0, 0);
-    sqlite3_create_function (db, "GetBandStatistics_Histogram", 2, SQLITE_ANY,
-			     0, fnct_GetBandStatistics_Histogram, 0, 0);
+    sqlite3_create_function (db, "GetBandStatistics_Histogram", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_GetBandStatistics_Histogram, 0, 0);
     sqlite3_create_function (db, "RL2_GetBandStatistics_Histogram", 2,
-			     SQLITE_ANY, 0, fnct_GetBandStatistics_Histogram, 0,
-			     0);
-    sqlite3_create_function (db, "GetBandHistogramFromImage", 3, SQLITE_ANY,
-			     0, fnct_GetBandHistogramFromImage, 0, 0);
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_GetBandStatistics_Histogram, 0, 0);
+    sqlite3_create_function (db, "GetBandHistogramFromImage", 3,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_GetBandHistogramFromImage, 0, 0);
     sqlite3_create_function (db, "RL2_GetBandHistogramFromImage", 3,
-			     SQLITE_ANY, 0, fnct_GetBandHistogramFromImage, 0,
-			     0);
-    sqlite3_create_function (db, "Pyramidize", 1, SQLITE_ANY, 0,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, 0,
+			     fnct_GetBandHistogramFromImage, 0, 0);
+    sqlite3_create_function (db, "Pyramidize", 1,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
 			     fnct_Pyramidize, 0, 0);
-    sqlite3_create_function (db, "RL2_Pyramidize", 1, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_Pyramidize", 1, SQLITE_UTF8, priv_data,
 			     fnct_Pyramidize, 0, 0);
-    sqlite3_create_function (db, "Pyramidize", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "Pyramidize", 2, SQLITE_UTF8, priv_data,
 			     fnct_Pyramidize, 0, 0);
-    sqlite3_create_function (db, "RL2_Pyramidize", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_Pyramidize", 2, SQLITE_UTF8, priv_data,
 			     fnct_Pyramidize, 0, 0);
-    sqlite3_create_function (db, "Pyramidize", 3, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "Pyramidize", 3, SQLITE_UTF8, priv_data,
 			     fnct_Pyramidize, 0, 0);
-    sqlite3_create_function (db, "RL2_Pyramidize", 3, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_Pyramidize", 3, SQLITE_UTF8, priv_data,
 			     fnct_Pyramidize, 0, 0);
-    sqlite3_create_function (db, "Pyramidize", 4, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "Pyramidize", 4, SQLITE_UTF8, priv_data,
 			     fnct_Pyramidize, 0, 0);
-    sqlite3_create_function (db, "RL2_Pyramidize", 4, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_Pyramidize", 4, SQLITE_UTF8, priv_data,
 			     fnct_Pyramidize, 0, 0);
-    sqlite3_create_function (db, "PyramidizeMonolithic", 1, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "PyramidizeMonolithic", 1, SQLITE_UTF8, 0,
 			     fnct_PyramidizeMonolithic, 0, 0);
-    sqlite3_create_function (db, "RL2_PyramidizeMonolithic", 1, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_PyramidizeMonolithic", 1, SQLITE_UTF8,
+			     0, fnct_PyramidizeMonolithic, 0, 0);
+    sqlite3_create_function (db, "PyramidizeMonolithic", 2, SQLITE_UTF8, 0,
 			     fnct_PyramidizeMonolithic, 0, 0);
-    sqlite3_create_function (db, "PyramidizeMonolithic", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_PyramidizeMonolithic", 2, SQLITE_UTF8,
+			     0, fnct_PyramidizeMonolithic, 0, 0);
+    sqlite3_create_function (db, "PyramidizeMonolithic", 3, SQLITE_UTF8, 0,
 			     fnct_PyramidizeMonolithic, 0, 0);
-    sqlite3_create_function (db, "RL2_PyramidizeMonolithic", 2, SQLITE_ANY, 0,
-			     fnct_PyramidizeMonolithic, 0, 0);
-    sqlite3_create_function (db, "PyramidizeMonolithic", 3, SQLITE_ANY, 0,
-			     fnct_PyramidizeMonolithic, 0, 0);
-    sqlite3_create_function (db, "RL2_PyramidizeMonolithic", 3, SQLITE_ANY, 0,
-			     fnct_PyramidizeMonolithic, 0, 0);
-    sqlite3_create_function (db, "DePyramidize", 1, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_PyramidizeMonolithic", 3, SQLITE_UTF8,
+			     0, fnct_PyramidizeMonolithic, 0, 0);
+    sqlite3_create_function (db, "DePyramidize", 1, SQLITE_UTF8, 0,
 			     fnct_DePyramidize, 0, 0);
-    sqlite3_create_function (db, "RL2_DePyramidize", 1, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_DePyramidize", 1, SQLITE_UTF8, 0,
 			     fnct_DePyramidize, 0, 0);
-    sqlite3_create_function (db, "DePyramidize", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "DePyramidize", 2, SQLITE_UTF8, 0,
 			     fnct_DePyramidize, 0, 0);
-    sqlite3_create_function (db, "RL2_DePyramidize", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_DePyramidize", 2, SQLITE_UTF8, 0,
 			     fnct_DePyramidize, 0, 0);
-    sqlite3_create_function (db, "DePyramidize", 3, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "DePyramidize", 3, SQLITE_UTF8, 0,
 			     fnct_DePyramidize, 0, 0);
-    sqlite3_create_function (db, "RL2_DePyramidize", 3, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_DePyramidize", 3, SQLITE_UTF8, 0,
 			     fnct_DePyramidize, 0, 0);
-    sqlite3_create_function (db, "GetMapImage", 4, SQLITE_ANY, 0,
-			     fnct_GetMapImage, 0, 0);
-    sqlite3_create_function (db, "RL2_GetMapImage", 4, SQLITE_ANY, 0,
-			     fnct_GetMapImage, 0, 0);
-    sqlite3_create_function (db, "GetMapImage", 5, SQLITE_ANY, 0,
-			     fnct_GetMapImage, 0, 0);
-    sqlite3_create_function (db, "RL2_GetMapImage", 5, SQLITE_ANY, 0,
-			     fnct_GetMapImage, 0, 0);
-    sqlite3_create_function (db, "GetMapImage", 6, SQLITE_ANY, 0,
-			     fnct_GetMapImage, 0, 0);
-    sqlite3_create_function (db, "RL2_GetMapImage", 6, SQLITE_ANY, 0,
-			     fnct_GetMapImage, 0, 0);
-    sqlite3_create_function (db, "GetMapImage", 7, SQLITE_ANY, 0,
-			     fnct_GetMapImage, 0, 0);
-    sqlite3_create_function (db, "RL2_GetMapImage", 7, SQLITE_ANY, 0,
-			     fnct_GetMapImage, 0, 0);
-    sqlite3_create_function (db, "GetMapImage", 8, SQLITE_ANY, 0,
-			     fnct_GetMapImage, 0, 0);
-    sqlite3_create_function (db, "RL2_GetMapImage", 8, SQLITE_ANY, 0,
-			     fnct_GetMapImage, 0, 0);
-    sqlite3_create_function (db, "GetMapImage", 9, SQLITE_ANY, 0,
-			     fnct_GetMapImage, 0, 0);
-    sqlite3_create_function (db, "RL2_GetMapImage", 9, SQLITE_ANY, 0,
-			     fnct_GetMapImage, 0, 0);
-    sqlite3_create_function (db, "GetMapImage", 10, SQLITE_ANY, 0,
-			     fnct_GetMapImage, 0, 0);
-    sqlite3_create_function (db, "RL2_GetMapImage", 10, SQLITE_ANY, 0,
-			     fnct_GetMapImage, 0, 0);
-    sqlite3_create_function (db, "GetTileImage", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "GetMapImageFromRaster", 4,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromRaster, 0, 0);
+    sqlite3_create_function (db, "RL2_GetMapImageFromRaster", 4,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromRaster, 0, 0);
+    sqlite3_create_function (db, "GetMapImageFromRaster", 5,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromRaster, 0, 0);
+    sqlite3_create_function (db, "RL2_GetMapImageFromRaster", 5,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromRaster, 0, 0);
+    sqlite3_create_function (db, "GetMapImageFromRaster", 6,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromRaster, 0, 0);
+    sqlite3_create_function (db, "RL2_GetMapImageFromRaster", 6,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromRaster, 0, 0);
+    sqlite3_create_function (db, "GetMapImageFromRaster", 7,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromRaster, 0, 0);
+    sqlite3_create_function (db, "RL2_GetMapImageFromRaster", 7,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromRaster, 0, 0);
+    sqlite3_create_function (db, "GetMapImageFromRaster", 8,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromRaster, 0, 0);
+    sqlite3_create_function (db, "RL2_GetMapImageFromRaster", 8,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromRaster, 0, 0);
+    sqlite3_create_function (db, "GetMapImageFromRaster", 9,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromRaster, 0, 0);
+    sqlite3_create_function (db, "RL2_GetMapImageFromRaster", 9,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromRaster, 0, 0);
+    sqlite3_create_function (db, "GetMapImageFromRaster", 10,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromRaster, 0, 0);
+    sqlite3_create_function (db, "RL2_GetMapImageFromRaster", 10,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromRaster, 0, 0);
+    sqlite3_create_function (db, "GetMapImageFromRaster", 11,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromRaster, 0, 0);
+    sqlite3_create_function (db, "RL2_GetMapImageFromRaster", 11,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromRaster, 0, 0);
+    sqlite3_create_function (db, "GetMapImageFromVector", 4,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromVector, 0, 0);
+    sqlite3_create_function (db, "RL2_GetMapImageFromVector", 4,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromVector, 0, 0);
+    sqlite3_create_function (db, "GetMapImageFromVector", 5,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromVector, 0, 0);
+    sqlite3_create_function (db, "RL2_GetMapImageFromVector", 5,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromVector, 0, 0);
+    sqlite3_create_function (db, "GetMapImageFromVector", 6,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromVector, 0, 0);
+    sqlite3_create_function (db, "RL2_GetMapImageFromVector", 6,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromVector, 0, 0);
+    sqlite3_create_function (db, "GetMapImageFromVector", 7,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromVector, 0, 0);
+    sqlite3_create_function (db, "RL2_GetMapImageFromVector", 7,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromVector, 0, 0);
+    sqlite3_create_function (db, "GetMapImageFromVector", 8,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromVector, 0, 0);
+    sqlite3_create_function (db, "RL2_GetMapImageFromVector", 8,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromVector, 0, 0);
+    sqlite3_create_function (db, "GetMapImageFromVector", 9,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromVector, 0, 0);
+    sqlite3_create_function (db, "RL2_GetMapImageFromVector", 9,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromVector, 0, 0);
+    sqlite3_create_function (db, "GetMapImageFromVector", 10,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromVector, 0, 0);
+    sqlite3_create_function (db, "RL2_GetMapImageFromVector", 10,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromVector, 0, 0);
+    sqlite3_create_function (db, "GetMapImageFromVector", 11,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromVector, 0, 0);
+    sqlite3_create_function (db, "RL2_GetMapImageFromVector", 11,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_GetMapImageFromVector, 0, 0);
+    sqlite3_create_function (db, "GetTileImage", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
 			     fnct_GetTileImage, 0, 0);
-    sqlite3_create_function (db, "RL2_GetTileImage", 2, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_GetTileImage", 2,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
 			     fnct_GetTileImage, 0, 0);
-    sqlite3_create_function (db, "GetTileImage", 3, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "GetTileImage", 3,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
 			     fnct_GetTileImage, 0, 0);
-    sqlite3_create_function (db, "RL2_GetTileImage", 3, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_GetTileImage", 3,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
 			     fnct_GetTileImage, 0, 0);
-    sqlite3_create_function (db, "GetTileImage", 4, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "GetTileImage", 4,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
 			     fnct_GetTileImage, 0, 0);
-    sqlite3_create_function (db, "RL2_GetTileImage", 4, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_GetTileImage", 4,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
 			     fnct_GetTileImage, 0, 0);
-    sqlite3_create_function (db, "GetTripleBandTileImage", 5, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "GetTripleBandTileImage", 5,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
 			     fnct_GetTripleBandTileImage, 0, 0);
-    sqlite3_create_function (db, "RL2_GetTripleBandTileImage", 5, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_GetTripleBandTileImage", 5,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
 			     fnct_GetTripleBandTileImage, 0, 0);
-    sqlite3_create_function (db, "GetTripleBandTileImage", 6, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "GetTripleBandTileImage", 6,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
 			     fnct_GetTripleBandTileImage, 0, 0);
-    sqlite3_create_function (db, "RL2_GetTripleBandTileImage", 6, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_GetTripleBandTileImage", 6,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
 			     fnct_GetTripleBandTileImage, 0, 0);
-    sqlite3_create_function (db, "GetTripleBandTileImage", 7, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "GetTripleBandTileImage", 7,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
 			     fnct_GetTripleBandTileImage, 0, 0);
-    sqlite3_create_function (db, "RL2_GetTripleBandTileImage", 7, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_GetTripleBandTileImage", 7,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
 			     fnct_GetTripleBandTileImage, 0, 0);
-    sqlite3_create_function (db, "GetMonoBandTileImage", 3, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "GetMonoBandTileImage", 3,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
 			     fnct_GetMonoBandTileImage, 0, 0);
-    sqlite3_create_function (db, "RL2_GetMonoBandTileImage", 3, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_GetMonoBandTileImage", 3,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
 			     fnct_GetMonoBandTileImage, 0, 0);
-    sqlite3_create_function (db, "GetMonoBandTileImage", 4, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "GetMonoBandTileImage", 4,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
 			     fnct_GetMonoBandTileImage, 0, 0);
-    sqlite3_create_function (db, "RL2_GetMonoBandTileImage", 4, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_GetMonoBandTileImage", 4,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
 			     fnct_GetMonoBandTileImage, 0, 0);
-    sqlite3_create_function (db, "GetMonoBandTileImage", 5, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "GetMonoBandTileImage", 5,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
 			     fnct_GetMonoBandTileImage, 0, 0);
-    sqlite3_create_function (db, "RL2_GetMonoBandTileImage", 5, SQLITE_ANY, 0,
+    sqlite3_create_function (db, "RL2_GetMonoBandTileImage", 5,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
 			     fnct_GetMonoBandTileImage, 0, 0);
+    sqlite3_create_function (db, "ExportRawPixels", 5,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_ExportRawPixels, 0, 0);
+    sqlite3_create_function (db, "RL2_ExportRawPixels", 5,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_ExportRawPixels, 0, 0);
+    sqlite3_create_function (db, "ExportRawPixels", 6,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_ExportRawPixels, 0, 0);
+    sqlite3_create_function (db, "RL2_ExportRawPixels", 6,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_ExportRawPixels, 0, 0);
+    sqlite3_create_function (db, "ExportRawPixels", 7,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_ExportRawPixels, 0, 0);
+    sqlite3_create_function (db, "RL2_ExportRawPixels", 7,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_ExportRawPixels, 0, 0);
+    sqlite3_create_function (db, "ExportSectionRawPixels", 6,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_ExportSectionRawPixels, 0, 0);
+    sqlite3_create_function (db, "RL2_ExportSectionRawPixels", 6,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_ExportSectionRawPixels, 0, 0);
+    sqlite3_create_function (db, "ExportSectionRawPixels", 7,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_ExportSectionRawPixels, 0, 0);
+    sqlite3_create_function (db, "RL2_ExportSectionRawPixels", 7,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_ExportSectionRawPixels, 0, 0);
+    sqlite3_create_function (db, "ExportRawPixels", 8,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_ExportRawPixels, 0, 0);
+    sqlite3_create_function (db, "RL2_ExportSectionRawPixels", 8,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_ExportSectionRawPixels, 0, 0);
+    sqlite3_create_function (db, "ImportSectionRawPixels", 6,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_ImportSectionRawPixels, 0, 0);
+    sqlite3_create_function (db, "RL2_ImportSectionRawPixels", 6,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_ImportSectionRawPixels, 0, 0);
+    sqlite3_create_function (db, "ImportSectionRawPixels", 7,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_ImportSectionRawPixels, 0, 0);
+    sqlite3_create_function (db, "RL2_ImportSectionRawPixels", 7,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_ImportSectionRawPixels, 0, 0);
+    sqlite3_create_function (db, "ImportSectionRawPixels", 8,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_ImportSectionRawPixels, 0, 0);
+    sqlite3_create_function (db, "RL2_ImportSectionRawPixels", 8,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_ImportSectionRawPixels, 0, 0);
+    sqlite3_create_function (db, "ImportSectionRawPixels", 9,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_ImportSectionRawPixels, 0, 0);
+    sqlite3_create_function (db, "RL2_ImportSectionRawPixels", 9,
+			     SQLITE_UTF8 | SQLITE_DETERMINISTIC, priv_data,
+			     fnct_ImportSectionRawPixels, 0, 0);
 
 /*
 // enabling ImportRaster and ExportRaster
@@ -6686,306 +10667,619 @@ register_rl2_sql_functions (void *p_db)
 	;
     else if (strcasecmp (security_level, "relaxed") == 0)
       {
-	  sqlite3_create_function (db, "LoadRaster", 2, SQLITE_ANY, 0,
-				   fnct_LoadRaster, 0, 0);
-	  sqlite3_create_function (db, "LoadRaster", 3, SQLITE_ANY, 0,
-				   fnct_LoadRaster, 0, 0);
-	  sqlite3_create_function (db, "LoadRaster", 4, SQLITE_ANY, 0,
-				   fnct_LoadRaster, 0, 0);
-	  sqlite3_create_function (db, "LoadRaster", 5, SQLITE_ANY, 0,
-				   fnct_LoadRaster, 0, 0);
-	  sqlite3_create_function (db, "LoadRaster", 6, SQLITE_ANY, 0,
-				   fnct_LoadRaster, 0, 0);
-	  sqlite3_create_function (db, "RL2_LoadRaster", 2, SQLITE_ANY, 0,
-				   fnct_LoadRaster, 0, 0);
-	  sqlite3_create_function (db, "RL2_LoadRaster", 3, SQLITE_ANY, 0,
-				   fnct_LoadRaster, 0, 0);
-	  sqlite3_create_function (db, "RL2_LoadRaster", 4, SQLITE_ANY, 0,
-				   fnct_LoadRaster, 0, 0);
-	  sqlite3_create_function (db, "RL2_LoadRaster", 5, SQLITE_ANY, 0,
-				   fnct_LoadRaster, 0, 0);
-	  sqlite3_create_function (db, "RL2_LoadRaster", 6, SQLITE_ANY, 0,
-				   fnct_LoadRaster, 0, 0);
-	  sqlite3_create_function (db, "LoadRastersFromDir", 2, SQLITE_ANY, 0,
+	  sqlite3_create_function (db, "LoadFontFromFile", 1, SQLITE_UTF8, 0,
+				   fnct_LoadFontFromFile, 0, 0);
+	  sqlite3_create_function (db, "RL2_LoadFontFromFile", 1, SQLITE_UTF8,
+				   0, fnct_LoadFontFromFile, 0, 0);
+	  sqlite3_create_function (db, "ExportFontToFile", 2, SQLITE_UTF8, 0,
+				   fnct_ExportFontToFile, 0, 0);
+	  sqlite3_create_function (db, "RL2_ExportFontToFile", 2, SQLITE_UTF8,
+				   0, fnct_ExportFontToFile, 0, 0);
+	  sqlite3_create_function (db, "LoadRaster", 2, SQLITE_UTF8,
+				   priv_data, fnct_LoadRaster, 0, 0);
+	  sqlite3_create_function (db, "LoadRaster", 3, SQLITE_UTF8,
+				   priv_data, fnct_LoadRaster, 0, 0);
+	  sqlite3_create_function (db, "LoadRaster", 4, SQLITE_UTF8,
+				   priv_data, fnct_LoadRaster, 0, 0);
+	  sqlite3_create_function (db, "LoadRaster", 5, SQLITE_UTF8,
+				   priv_data, fnct_LoadRaster, 0, 0);
+	  sqlite3_create_function (db, "LoadRaster", 6, SQLITE_UTF8,
+				   priv_data, fnct_LoadRaster, 0, 0);
+	  sqlite3_create_function (db, "RL2_LoadRaster", 2, SQLITE_UTF8,
+				   priv_data, fnct_LoadRaster, 0, 0);
+	  sqlite3_create_function (db, "RL2_LoadRaster", 3, SQLITE_UTF8,
+				   priv_data, fnct_LoadRaster, 0, 0);
+	  sqlite3_create_function (db, "RL2_LoadRaster", 4, SQLITE_UTF8,
+				   priv_data, fnct_LoadRaster, 0, 0);
+	  sqlite3_create_function (db, "RL2_LoadRaster", 5, SQLITE_UTF8,
+				   priv_data, fnct_LoadRaster, 0, 0);
+	  sqlite3_create_function (db, "RL2_LoadRaster", 6, SQLITE_UTF8,
+				   priv_data, fnct_LoadRaster, 0, 0);
+	  sqlite3_create_function (db, "LoadRastersFromDir", 2, SQLITE_UTF8,
+				   priv_data, fnct_LoadRastersFromDir, 0, 0);
+	  sqlite3_create_function (db, "LoadRastersFromDir", 3, SQLITE_UTF8,
+				   priv_data, fnct_LoadRastersFromDir, 0, 0);
+	  sqlite3_create_function (db, "LoadRastersFromDir", 4, SQLITE_UTF8,
+				   priv_data, fnct_LoadRastersFromDir, 0, 0);
+	  sqlite3_create_function (db, "LoadRastersFromDir", 5, SQLITE_UTF8,
+				   priv_data, fnct_LoadRastersFromDir, 0, 0);
+	  sqlite3_create_function (db, "LoadRastersFromDir", 6, SQLITE_UTF8,
+				   priv_data, fnct_LoadRastersFromDir, 0, 0);
+	  sqlite3_create_function (db, "LoadRastersFromDir", 7, SQLITE_UTF8,
+				   priv_data, fnct_LoadRastersFromDir, 0, 0);
+	  sqlite3_create_function (db, "RL2_LoadRastersFromDir", 2,
+				   SQLITE_UTF8, priv_data,
 				   fnct_LoadRastersFromDir, 0, 0);
-	  sqlite3_create_function (db, "LoadRastersFromDir", 3, SQLITE_ANY, 0,
+	  sqlite3_create_function (db, "RL2_LoadRastersFromDir", 3,
+				   SQLITE_UTF8, priv_data,
 				   fnct_LoadRastersFromDir, 0, 0);
-	  sqlite3_create_function (db, "LoadRastersFromDir", 4, SQLITE_ANY, 0,
+	  sqlite3_create_function (db, "RL2_LoadRastersFromDir", 4,
+				   SQLITE_UTF8, priv_data,
 				   fnct_LoadRastersFromDir, 0, 0);
-	  sqlite3_create_function (db, "LoadRastersFromDir", 5, SQLITE_ANY, 0,
+	  sqlite3_create_function (db, "RL2_LoadRastersFromDir", 5,
+				   SQLITE_UTF8, priv_data,
 				   fnct_LoadRastersFromDir, 0, 0);
-	  sqlite3_create_function (db, "LoadRastersFromDir", 6, SQLITE_ANY, 0,
+	  sqlite3_create_function (db, "RL2_LoadRastersFromDir", 6,
+				   SQLITE_UTF8, priv_data,
 				   fnct_LoadRastersFromDir, 0, 0);
-	  sqlite3_create_function (db, "LoadRastersFromDir", 7, SQLITE_ANY, 0,
+	  sqlite3_create_function (db, "RL2_LoadRastersFromDir", 7,
+				   SQLITE_UTF8, priv_data,
 				   fnct_LoadRastersFromDir, 0, 0);
-	  sqlite3_create_function (db, "RL2_LoadRastersFromDir", 2, SQLITE_ANY,
-				   0, fnct_LoadRastersFromDir, 0, 0);
-	  sqlite3_create_function (db, "RL2_LoadRastersFromDir", 3, SQLITE_ANY,
-				   0, fnct_LoadRastersFromDir, 0, 0);
-	  sqlite3_create_function (db, "RL2_LoadRastersFromDir", 4, SQLITE_ANY,
-				   0, fnct_LoadRastersFromDir, 0, 0);
-	  sqlite3_create_function (db, "RL2_LoadRastersFromDir", 5, SQLITE_ANY,
-				   0, fnct_LoadRastersFromDir, 0, 0);
-	  sqlite3_create_function (db, "RL2_LoadRastersFromDir", 6, SQLITE_ANY,
-				   0, fnct_LoadRastersFromDir, 0, 0);
-	  sqlite3_create_function (db, "RL2_LoadRastersFromDir", 7, SQLITE_ANY,
-				   0, fnct_LoadRastersFromDir, 0, 0);
-	  sqlite3_create_function (db, "LoadRasterFromWMS", 9, SQLITE_ANY, 0,
-				   fnct_LoadRasterFromWMS, 0, 0);
-	  sqlite3_create_function (db, "RL2_LoadRasterFromWMS", 9, SQLITE_ANY,
-				   0, fnct_LoadRasterFromWMS, 0, 0);
-	  sqlite3_create_function (db, "LoadRasterFromWMS", 10, SQLITE_ANY, 0,
+	  sqlite3_create_function (db, "LoadRasterFromWMS", 9, SQLITE_UTF8,
+				   priv_data, fnct_LoadRasterFromWMS, 0, 0);
+	  sqlite3_create_function (db, "RL2_LoadRasterFromWMS", 9,
+				   SQLITE_UTF8, priv_data,
 				   fnct_LoadRasterFromWMS, 0, 0);
-	  sqlite3_create_function (db, "RL2_LoadRasterFromWMS", 10, SQLITE_ANY,
-				   0, fnct_LoadRasterFromWMS, 0, 0);
-	  sqlite3_create_function (db, "LoadRasterFromWMS", 11, SQLITE_ANY, 0,
+	  sqlite3_create_function (db, "LoadRasterFromWMS", 10, SQLITE_UTF8,
+				   priv_data, fnct_LoadRasterFromWMS, 0, 0);
+	  sqlite3_create_function (db, "RL2_LoadRasterFromWMS", 10,
+				   SQLITE_UTF8, priv_data,
 				   fnct_LoadRasterFromWMS, 0, 0);
-	  sqlite3_create_function (db, "RL2_LoadRasterFromWMS", 11, SQLITE_ANY,
-				   0, fnct_LoadRasterFromWMS, 0, 0);
-	  sqlite3_create_function (db, "LoadRasterFromWMS", 12, SQLITE_ANY, 0,
+	  sqlite3_create_function (db, "LoadRasterFromWMS", 11, SQLITE_UTF8,
+				   priv_data, fnct_LoadRasterFromWMS, 0, 0);
+	  sqlite3_create_function (db, "RL2_LoadRasterFromWMS", 11,
+				   SQLITE_UTF8, priv_data,
 				   fnct_LoadRasterFromWMS, 0, 0);
-	  sqlite3_create_function (db, "RL2_LoadRasterFromWMS", 12, SQLITE_ANY,
-				   0, fnct_LoadRasterFromWMS, 0, 0);
-	  sqlite3_create_function (db, "LoadRasterFromWMS", 13, SQLITE_ANY, 0,
+	  sqlite3_create_function (db, "LoadRasterFromWMS", 12, SQLITE_UTF8,
+				   priv_data, fnct_LoadRasterFromWMS, 0, 0);
+	  sqlite3_create_function (db, "RL2_LoadRasterFromWMS", 12,
+				   SQLITE_UTF8, priv_data,
 				   fnct_LoadRasterFromWMS, 0, 0);
-	  sqlite3_create_function (db, "RL2_LoadRasterFromWMS", 13, SQLITE_ANY,
-				   0, fnct_LoadRasterFromWMS, 0, 0);
-	  sqlite3_create_function (db, "LoadRasterFromWMS", 14, SQLITE_ANY, 0,
+	  sqlite3_create_function (db, "LoadRasterFromWMS", 13, SQLITE_UTF8,
+				   priv_data, fnct_LoadRasterFromWMS, 0, 0);
+	  sqlite3_create_function (db, "RL2_LoadRasterFromWMS", 13,
+				   SQLITE_UTF8, priv_data,
 				   fnct_LoadRasterFromWMS, 0, 0);
-	  sqlite3_create_function (db, "RL2_LoadRasterFromWMS", 14, SQLITE_ANY,
-				   0, fnct_LoadRasterFromWMS, 0, 0);
-	  sqlite3_create_function (db, "WriteGeoTiff", 6, SQLITE_ANY, 0,
-				   fnct_WriteGeoTiff, 0, 0);
-	  sqlite3_create_function (db, "RL2_WriteGeoTiff", 6, SQLITE_ANY, 0,
-				   fnct_WriteGeoTiff, 0, 0);
-	  sqlite3_create_function (db, "WriteGeoTiff", 7, SQLITE_ANY, 0,
-				   fnct_WriteGeoTiff, 0, 0);
-	  sqlite3_create_function (db, "RL2_WriteGeoTiff", 7, SQLITE_ANY, 0,
-				   fnct_WriteGeoTiff, 0, 0);
-	  sqlite3_create_function (db, "WriteGeoTiff", 8, SQLITE_ANY, 0,
-				   fnct_WriteGeoTiff, 0, 0);
-	  sqlite3_create_function (db, "RL2_WriteGeoTiff", 8, SQLITE_ANY, 0,
-				   fnct_WriteGeoTiff, 0, 0);
-	  sqlite3_create_function (db, "WriteGeoTiff", 9, SQLITE_ANY, 0,
-				   fnct_WriteGeoTiff, 0, 0);
-	  sqlite3_create_function (db, "RL2_WriteGeoTiff", 9, SQLITE_ANY, 0,
-				   fnct_WriteGeoTiff, 0, 0);
-	  sqlite3_create_function (db, "WriteGeoTiff", 10, SQLITE_ANY, 0,
-				   fnct_WriteGeoTiff, 0, 0);
-	  sqlite3_create_function (db, "RL2_WriteGeoTiff", 10, SQLITE_ANY, 0,
-				   fnct_WriteGeoTiff, 0, 0);
-	  sqlite3_create_function (db, "WriteTiffTfw", 6, SQLITE_ANY, 0,
-				   fnct_WriteTiffTfw, 0, 0);
-	  sqlite3_create_function (db, "RL2_WriteTiffTfw", 6, SQLITE_ANY, 0,
-				   fnct_WriteTiffTfw, 0, 0);
-	  sqlite3_create_function (db, "WriteTiffTfw", 7, SQLITE_ANY, 0,
-				   fnct_WriteTiffTfw, 0, 0);
-	  sqlite3_create_function (db, "RL2_WriteTiffTfw", 7, SQLITE_ANY, 0,
-				   fnct_WriteTiffTfw, 0, 0);
-	  sqlite3_create_function (db, "WriteTiffTfw", 8, SQLITE_ANY, 0,
-				   fnct_WriteTiffTfw, 0, 0);
-	  sqlite3_create_function (db, "RL2_WriteTiffTfw", 8, SQLITE_ANY, 0,
-				   fnct_WriteTiffTfw, 0, 0);
-	  sqlite3_create_function (db, "WriteTiffTfw", 9, SQLITE_ANY, 0,
-				   fnct_WriteTiffTfw, 0, 0);
-	  sqlite3_create_function (db, "RL2_WriteTiffTfw", 9, SQLITE_ANY, 0,
-				   fnct_WriteTiffTfw, 0, 0);
-	  sqlite3_create_function (db, "WriteTiff", 6, SQLITE_ANY, 0,
-				   fnct_WriteTiff, 0, 0);
-	  sqlite3_create_function (db, "RL2_WriteTiff", 6, SQLITE_ANY, 0,
-				   fnct_WriteTiff, 0, 0);
-	  sqlite3_create_function (db, "WriteTiff", 7, SQLITE_ANY, 0,
-				   fnct_WriteTiff, 0, 0);
-	  sqlite3_create_function (db, "RL2_WriteTiff", 7, SQLITE_ANY, 0,
-				   fnct_WriteTiff, 0, 0);
-	  sqlite3_create_function (db, "WriteTiff", 8, SQLITE_ANY, 0,
+	  sqlite3_create_function (db, "LoadRasterFromWMS", 14, SQLITE_UTF8,
+				   priv_data, fnct_LoadRasterFromWMS, 0, 0);
+	  sqlite3_create_function (db, "RL2_LoadRasterFromWMS", 14,
+				   SQLITE_UTF8, 0, fnct_LoadRasterFromWMS, 0,
+				   0);
+	  sqlite3_create_function (db, "WriteGeoTiff", 6, SQLITE_UTF8,
+				   priv_data, fnct_WriteGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteGeoTiff", 6, SQLITE_UTF8,
+				   priv_data, fnct_WriteGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteGeoTiff", 7, SQLITE_UTF8,
+				   priv_data, fnct_WriteGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteGeoTiff", 7, SQLITE_UTF8,
+				   priv_data, fnct_WriteGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteGeoTiff", 8, SQLITE_UTF8,
+				   priv_data, fnct_WriteGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteGeoTiff", 8, SQLITE_UTF8,
+				   priv_data, fnct_WriteGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteGeoTiff", 9, SQLITE_UTF8,
+				   priv_data, fnct_WriteGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteGeoTiff", 9, SQLITE_UTF8,
+				   priv_data, fnct_WriteGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteGeoTiff", 10, SQLITE_UTF8,
+				   priv_data, fnct_WriteGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteGeoTiff", 10, SQLITE_UTF8,
+				   priv_data, fnct_WriteGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteTiffTfw", 6, SQLITE_UTF8,
+				   priv_data, fnct_WriteTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteTiffTfw", 6, SQLITE_UTF8,
+				   priv_data, fnct_WriteTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "WriteTiffTfw", 7, SQLITE_UTF8,
+				   priv_data, fnct_WriteTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteTiffTfw", 7, SQLITE_UTF8,
+				   priv_data, fnct_WriteTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "WriteTiffTfw", 8, SQLITE_UTF8,
+				   priv_data, fnct_WriteTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteTiffTfw", 8, SQLITE_UTF8,
+				   priv_data, fnct_WriteTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "WriteTiffTfw", 9, SQLITE_UTF8,
+				   priv_data, fnct_WriteTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteTiffTfw", 9, SQLITE_UTF8,
+				   priv_data, fnct_WriteTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "WriteTiff", 6, SQLITE_UTF8, priv_data,
 				   fnct_WriteTiff, 0, 0);
-	  sqlite3_create_function (db, "RL2_WriteTiff", 8, SQLITE_ANY, 0,
+	  sqlite3_create_function (db, "RL2_WriteTiff", 6, SQLITE_UTF8,
+				   priv_data, fnct_WriteTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteTiff", 7, SQLITE_UTF8, priv_data,
 				   fnct_WriteTiff, 0, 0);
-	  sqlite3_create_function (db, "WriteTiff", 9, SQLITE_ANY, 0,
+	  sqlite3_create_function (db, "RL2_WriteTiff", 7, SQLITE_UTF8,
+				   priv_data, fnct_WriteTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteTiff", 8, SQLITE_UTF8, priv_data,
 				   fnct_WriteTiff, 0, 0);
-	  sqlite3_create_function (db, "RL2_WriteTiff", 9, SQLITE_ANY, 0,
+	  sqlite3_create_function (db, "RL2_WriteTiff", 8, SQLITE_UTF8,
+				   priv_data, fnct_WriteTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteTiff", 9, SQLITE_UTF8, priv_data,
 				   fnct_WriteTiff, 0, 0);
-	  sqlite3_create_function (db, "WriteJpegJgw", 6, SQLITE_ANY, 0,
-				   fnct_WriteJpegJgw, 0, 0);
-	  sqlite3_create_function (db, "RL2_WriteJpegJgw", 6, SQLITE_ANY, 0,
-				   fnct_WriteJpegJgw, 0, 0);
-	  sqlite3_create_function (db, "WriteJpegJgw", 7, SQLITE_ANY, 0,
-				   fnct_WriteJpegJgw, 0, 0);
-	  sqlite3_create_function (db, "RL2_WriteJpegJgw", 7, SQLITE_ANY, 0,
-				   fnct_WriteJpegJgw, 0, 0);
-	  sqlite3_create_function (db, "WriteJpegJgw", 8, SQLITE_ANY, 0,
-				   fnct_WriteJpegJgw, 0, 0);
-	  sqlite3_create_function (db, "RL2_WriteJpegJgw", 8, SQLITE_ANY, 0,
-				   fnct_WriteJpegJgw, 0, 0);
-	  sqlite3_create_function (db, "WriteJpeg", 6, SQLITE_ANY, 0,
-				   fnct_WriteJpeg, 0, 0);
-	  sqlite3_create_function (db, "RL2_WriteJpeg", 6, SQLITE_ANY, 0,
-				   fnct_WriteJpeg, 0, 0);
-	  sqlite3_create_function (db, "WriteJpeg", 7, SQLITE_ANY, 0,
-				   fnct_WriteJpeg, 0, 0);
-	  sqlite3_create_function (db, "RL2_WriteJpeg", 7, SQLITE_ANY, 0,
+	  sqlite3_create_function (db, "RL2_WriteTiff", 9, SQLITE_UTF8,
+				   priv_data, fnct_WriteTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionGeoTiff", 7, SQLITE_UTF8,
+				   priv_data, fnct_WriteSectionGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionGeoTiff", 7,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionGeoTiff", 8, SQLITE_UTF8,
+				   priv_data, fnct_WriteSectionGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionGeoTiff", 8,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionGeoTiff", 9, SQLITE_UTF8,
+				   priv_data, fnct_WriteSectionGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionGeoTiff", 9,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionGeoTiff", 10, SQLITE_UTF8,
+				   0, fnct_WriteSectionGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionGeoTiff", 10,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionGeoTiff", 11, SQLITE_UTF8,
+				   0, fnct_WriteSectionGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionGeoTiff", 11,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionTiffTfw", 7, SQLITE_UTF8,
+				   priv_data, fnct_WriteSectionTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionTiffTfw", 7,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionTiffTfw", 8, SQLITE_UTF8,
+				   priv_data, fnct_WriteTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionTiffTfw", 8,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionTiffTfw", 9, SQLITE_UTF8,
+				   priv_data, fnct_WriteSectionTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionTiffTfw", 9,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionTiffTfw", 10, SQLITE_UTF8,
+				   priv_data, fnct_WriteTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionTiffTfw", 10,
+				   SQLITE_UTF8, 0, fnct_WriteTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionTiff", 7, SQLITE_UTF8,
+				   priv_data, fnct_WriteSectionTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionTiff", 7, SQLITE_UTF8,
+				   priv_data, fnct_WriteSectionTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionTiff", 8, SQLITE_UTF8,
+				   priv_data, fnct_WriteSectionTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionTiff", 8, SQLITE_UTF8,
+				   priv_data, fnct_WriteSectionTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionTiff", 9, SQLITE_UTF8,
+				   priv_data, fnct_WriteSectionTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionTiff", 9, SQLITE_UTF8,
+				   priv_data, fnct_WriteSectionTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionTiff", 10, SQLITE_UTF8,
+				   priv_data, fnct_WriteSectionTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionTiff", 10,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteJpegJgw", 6, SQLITE_UTF8,
+				   priv_data, fnct_WriteJpegJgw, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteJpegJgw", 6, SQLITE_UTF8,
+				   priv_data, fnct_WriteJpegJgw, 0, 0);
+	  sqlite3_create_function (db, "WriteJpegJgw", 7, SQLITE_UTF8,
+				   priv_data, fnct_WriteJpegJgw, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteJpegJgw", 7, SQLITE_UTF8,
+				   priv_data, fnct_WriteJpegJgw, 0, 0);
+	  sqlite3_create_function (db, "WriteJpegJgw", 8, SQLITE_UTF8,
+				   priv_data, fnct_WriteJpegJgw, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteJpegJgw", 8, SQLITE_UTF8,
+				   priv_data, fnct_WriteJpegJgw, 0, 0);
+	  sqlite3_create_function (db, "WriteJpeg", 6, SQLITE_UTF8, priv_data,
 				   fnct_WriteJpeg, 0, 0);
-	  sqlite3_create_function (db, "WriteJpeg", 8, SQLITE_ANY, 0,
+	  sqlite3_create_function (db, "RL2_WriteJpeg", 6, SQLITE_UTF8,
+				   priv_data, fnct_WriteJpeg, 0, 0);
+	  sqlite3_create_function (db, "WriteJpeg", 7, SQLITE_UTF8, priv_data,
 				   fnct_WriteJpeg, 0, 0);
-	  sqlite3_create_function (db, "RL2_WriteJpeg", 8, SQLITE_ANY, 0,
+	  sqlite3_create_function (db, "RL2_WriteJpeg", 7, SQLITE_UTF8,
+				   priv_data, fnct_WriteJpeg, 0, 0);
+	  sqlite3_create_function (db, "WriteJpeg", 8, SQLITE_UTF8, priv_data,
 				   fnct_WriteJpeg, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteJpeg", 8, SQLITE_UTF8,
+				   priv_data, fnct_WriteJpeg, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionJpegJgw", 7, SQLITE_UTF8,
+				   priv_data, fnct_WriteSectionJpegJgw, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionJpegJgw", 7,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionJpegJgw, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionJpegJgw", 8, SQLITE_UTF8,
+				   priv_data, fnct_WriteSectionJpegJgw, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionJpegJgw", 8,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionJpegJgw, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionJpegJgw", 9, SQLITE_UTF8,
+				   priv_data, fnct_WriteSectionJpegJgw, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionJpegJgw", 9,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionJpegJgw, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionJpeg", 7, SQLITE_UTF8,
+				   priv_data, fnct_WriteSectionJpeg, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionJpeg", 7, SQLITE_UTF8,
+				   priv_data, fnct_WriteSectionJpeg, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionJpeg", 8, SQLITE_UTF8,
+				   priv_data, fnct_WriteSectionJpeg, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionJpeg", 8, SQLITE_UTF8,
+				   priv_data, fnct_WriteSectionJpeg, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionJpeg", 9, SQLITE_UTF8,
+				   priv_data, fnct_WriteSectionJpeg, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionJpeg", 9, SQLITE_UTF8,
+				   priv_data, fnct_WriteSectionJpeg, 0, 0);
 	  sqlite3_create_function (db, "WriteTripleBandGeoTiff", 9,
-				   SQLITE_ANY, 0, fnct_WriteTripleBandGeoTiff,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteTripleBandGeoTiff, 0, 0);
 	  sqlite3_create_function (db, "RL2_WriteTripleBandGeoTiff", 9,
-				   SQLITE_ANY, 0, fnct_WriteTripleBandGeoTiff,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteTripleBandGeoTiff, 0, 0);
 	  sqlite3_create_function (db, "WriteTripleBandGeoTiff", 10,
-				   SQLITE_ANY, 0, fnct_WriteTripleBandGeoTiff,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteTripleBandGeoTiff, 0, 0);
 	  sqlite3_create_function (db, "RL2_WriteTripleBandGeoTiff", 10,
-				   SQLITE_ANY, 0, fnct_WriteTripleBandGeoTiff,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteTripleBandGeoTiff, 0, 0);
 	  sqlite3_create_function (db, "WriteTripleBandGeoTiff", 11,
-				   SQLITE_ANY, 0, fnct_WriteTripleBandGeoTiff,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteTripleBandGeoTiff, 0, 0);
 	  sqlite3_create_function (db, "RL2_WriteTripleBandGeoTiff", 11,
-				   SQLITE_ANY, 0, fnct_WriteTripleBandGeoTiff,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteTripleBandGeoTiff, 0, 0);
 	  sqlite3_create_function (db, "WriteTripleBandGeoTiff", 12,
-				   SQLITE_ANY, 0, fnct_WriteTripleBandGeoTiff,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteTripleBandGeoTiff, 0, 0);
 	  sqlite3_create_function (db, "RL2_WriteTripleBandGeoTiff", 12,
-				   SQLITE_ANY, 0, fnct_WriteTripleBandGeoTiff,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteTripleBandGeoTiff, 0, 0);
 	  sqlite3_create_function (db, "WriteTripleBandGeoTiff", 13,
-				   SQLITE_ANY, 0, fnct_WriteTripleBandGeoTiff,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteTripleBandGeoTiff, 0, 0);
 	  sqlite3_create_function (db, "RL2_WriteTripleBandGeoTiff", 13,
-				   SQLITE_ANY, 0, fnct_WriteTripleBandGeoTiff,
-				   0, 0);
-	  sqlite3_create_function (db, "WriteMonoBandGeoTiff", 7,
-				   SQLITE_ANY, 0, fnct_WriteMonoBandGeoTiff,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteTripleBandGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionTripleBandGeoTiff", 10,
+				   SQLITE_UTF8, 0,
+				   fnct_WriteSectionTripleBandGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionTripleBandGeoTiff",
+				   10, SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTripleBandGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionTripleBandGeoTiff", 11,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTripleBandGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionTripleBandGeoTiff",
+				   11, SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTripleBandGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionTripleBandGeoTiff", 12,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTripleBandGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionTripleBandGeoTiff",
+				   12, SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTripleBandGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionTripleBandGeoTiff", 13,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTripleBandGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionTripleBandGeoTiff",
+				   13, SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTripleBandGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionTripleBandGeoTiff", 14,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTripleBandGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionTripleBandGeoTiff",
+				   14, SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTripleBandGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteMonoBandGeoTiff", 7, SQLITE_UTF8,
+				   0, fnct_WriteMonoBandGeoTiff, 0, 0);
 	  sqlite3_create_function (db, "RL2_WriteMonoBandGeoTiff", 7,
-				   SQLITE_ANY, 0, fnct_WriteMonoBandGeoTiff,
-				   0, 0);
-	  sqlite3_create_function (db, "WriteMonoBandGeoTiff", 8,
-				   SQLITE_ANY, 0, fnct_WriteMonoBandGeoTiff,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteMonoBandGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteMonoBandGeoTiff", 8, SQLITE_UTF8,
+				   priv_data, fnct_WriteMonoBandGeoTiff, 0, 0);
 	  sqlite3_create_function (db, "RL2_WriteMonoBandGeoTiff", 8,
-				   SQLITE_ANY, 0, fnct_WriteMonoBandGeoTiff,
-				   0, 0);
-	  sqlite3_create_function (db, "WriteMonoBandGeoTiff", 9,
-				   SQLITE_ANY, 0, fnct_WriteMonoBandGeoTiff,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteMonoBandGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteMonoBandGeoTiff", 9, SQLITE_UTF8,
+				   0, fnct_WriteMonoBandGeoTiff, 0, 0);
 	  sqlite3_create_function (db, "RL2_WriteMonoBandGeoTiff", 9,
-				   SQLITE_ANY, 0, fnct_WriteMonoBandGeoTiff,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteMonoBandGeoTiff, 0, 0);
 	  sqlite3_create_function (db, "WriteMonoBandGeoTiff", 10,
-				   SQLITE_ANY, 0, fnct_WriteMonoBandGeoTiff,
+				   SQLITE_UTF8, 0, fnct_WriteMonoBandGeoTiff,
 				   0, 0);
 	  sqlite3_create_function (db, "RL2_WriteMonoBandGeoTiff", 10,
-				   SQLITE_ANY, 0, fnct_WriteMonoBandGeoTiff,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteMonoBandGeoTiff, 0, 0);
 	  sqlite3_create_function (db, "WriteMonoBandGeoTiff", 11,
-				   SQLITE_ANY, 0, fnct_WriteMonoBandGeoTiff,
+				   SQLITE_UTF8, 0, fnct_WriteMonoBandGeoTiff,
 				   0, 0);
 	  sqlite3_create_function (db, "RL2_WriteMonoBandGeoTiff", 11,
-				   SQLITE_ANY, 0, fnct_WriteMonoBandGeoTiff,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteMonoBandGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionMonoBandGeoTiff", 8,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionMonoBandGeoTiff", 8,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionMonoBandGeoTiff", 9,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionMonoBandGeoTiff", 9,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionMonoBandGeoTiff", 10,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionMonoBandGeoTiff", 10,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionMonoBandGeoTiff", 11,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionMonoBandGeoTiff", 11,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionMonoBandGeoTiff", 12,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandGeoTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionMonoBandGeoTiff", 12,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandGeoTiff, 0, 0);
 	  sqlite3_create_function (db, "WriteTripleBandTiffTfw", 9,
-				   SQLITE_ANY, 0, fnct_WriteTripleBandTiffTfw,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteTripleBandTiffTfw, 0, 0);
 	  sqlite3_create_function (db, "RL2_WriteTripleBandTiffTfw", 9,
-				   SQLITE_ANY, 0, fnct_WriteTripleBandTiffTfw,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteTripleBandTiffTfw, 0, 0);
 	  sqlite3_create_function (db, "WriteTripleBandTiffTfw", 10,
-				   SQLITE_ANY, 0, fnct_WriteTripleBandTiffTfw,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteTripleBandTiffTfw, 0, 0);
 	  sqlite3_create_function (db, "RL2_WriteTripleBandTiffTfw", 10,
-				   SQLITE_ANY, 0, fnct_WriteTripleBandTiffTfw,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteTripleBandTiffTfw, 0, 0);
 	  sqlite3_create_function (db, "WriteTripleBandTiffTfw", 11,
-				   SQLITE_ANY, 0, fnct_WriteTripleBandTiffTfw,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteTripleBandTiffTfw, 0, 0);
 	  sqlite3_create_function (db, "RL2_WriteTripleBandTiffTfw", 11,
-				   SQLITE_ANY, 0, fnct_WriteTripleBandTiffTfw,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteTripleBandTiffTfw, 0, 0);
 	  sqlite3_create_function (db, "WriteTripleBandTiffTfw", 12,
-				   SQLITE_ANY, 0, fnct_WriteTripleBandTiffTfw,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteTripleBandTiffTfw, 0, 0);
 	  sqlite3_create_function (db, "RL2_WriteTripleBandTiffTfw", 12,
-				   SQLITE_ANY, 0, fnct_WriteTripleBandTiffTfw,
-				   0, 0);
-	  sqlite3_create_function (db, "WriteMonoBandTiffTfw", 7,
-				   SQLITE_ANY, 0, fnct_WriteMonoBandTiffTfw,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteTripleBandTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionTripleBandTiffTfw", 10,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTripleBandTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionTripleBandTiffTfw",
+				   10, SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTripleBandTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionTripleBandTiffTfw", 11,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTripleBandTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionTripleBandTiffTfw",
+				   11, SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTripleBandTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionTripleBandTiffTfw", 12,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTripleBandTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionTripleBandTiffTfw",
+				   12, SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTripleBandTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionTripleBandTiffTfw", 13,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTripleBandTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionTripleBandTiffTfw",
+				   13, SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTripleBandTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionMonoBandTiffTfw", 8,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionMonoBandTiffTfw", 8,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionMonoBandTiffTfw", 9,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionMonoBandTiffTfw", 9,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionMonoBandTiffTfw", 10,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionMonoBandTiffTfw", 10,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionMonoBandTiffTfw", 11,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionMonoBandTiffTfw", 11,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "WriteMonoBandTiffTfw", 7, SQLITE_UTF8,
+				   priv_data, fnct_WriteMonoBandTiffTfw, 0, 0);
 	  sqlite3_create_function (db, "RL2_WriteMonoBandTiffTfw", 7,
-				   SQLITE_ANY, 0, fnct_WriteMonoBandTiffTfw,
-				   0, 0);
-	  sqlite3_create_function (db, "WriteMonoBandTiffTfw", 8,
-				   SQLITE_ANY, 0, fnct_WriteMonoBandTiffTfw,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteMonoBandTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "WriteMonoBandTiffTfw", 8, SQLITE_UTF8,
+				   0, fnct_WriteMonoBandTiffTfw, 0, 0);
 	  sqlite3_create_function (db, "RL2_WriteMonoBandTiffTfw", 8,
-				   SQLITE_ANY, 0, fnct_WriteMonoBandTiffTfw,
-				   0, 0);
-	  sqlite3_create_function (db, "WriteMonoBandTiffTfw", 9,
-				   SQLITE_ANY, 0, fnct_WriteMonoBandTiffTfw,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteMonoBandTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "WriteMonoBandTiffTfw", 9, SQLITE_UTF8,
+				   priv_data, fnct_WriteMonoBandTiffTfw, 0, 0);
 	  sqlite3_create_function (db, "RL2_WriteMonoBandTiffTfw", 9,
-				   SQLITE_ANY, 0, fnct_WriteMonoBandTiffTfw,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteMonoBandTiffTfw, 0, 0);
 	  sqlite3_create_function (db, "WriteMonoBandTiffTfw", 10,
-				   SQLITE_ANY, 0, fnct_WriteMonoBandTiffTfw,
-				   0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteMonoBandTiffTfw, 0, 0);
 	  sqlite3_create_function (db, "RL2_WriteMonoBandTiffTfw", 10,
-				   SQLITE_ANY, 0, fnct_WriteMonoBandTiffTfw,
-				   0, 0);
-	  sqlite3_create_function (db, "WriteTripleBandTiff", 9, SQLITE_ANY,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteMonoBandTiffTfw, 0, 0);
+	  sqlite3_create_function (db, "WriteTripleBandTiff", 9, SQLITE_UTF8,
 				   0, fnct_WriteTripleBandTiff, 0, 0);
 	  sqlite3_create_function (db, "RL2_WriteTripleBandTiff", 9,
-				   SQLITE_ANY, 0, fnct_WriteTripleBandTiff, 0,
-				   0);
-	  sqlite3_create_function (db, "WriteTripleBandTiff", 10, SQLITE_ANY,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteTripleBandTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteTripleBandTiff", 10, SQLITE_UTF8,
 				   0, fnct_WriteTripleBandTiff, 0, 0);
 	  sqlite3_create_function (db, "RL2_WriteTripleBandTiff", 10,
-				   SQLITE_ANY, 0, fnct_WriteTripleBandTiff, 0,
-				   0);
-	  sqlite3_create_function (db, "WriteTripleBandTiff", 11, SQLITE_ANY,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteTripleBandTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteTripleBandTiff", 11, SQLITE_UTF8,
 				   0, fnct_WriteTripleBandTiff, 0, 0);
 	  sqlite3_create_function (db, "RL2_WriteTripleBandTiff", 11,
-				   SQLITE_ANY, 0, fnct_WriteTripleBandTiff, 0,
-				   0);
-	  sqlite3_create_function (db, "WriteTripleBandTiff", 12, SQLITE_ANY,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteTripleBandTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteTripleBandTiff", 12, SQLITE_UTF8,
 				   0, fnct_WriteTripleBandTiff, 0, 0);
 	  sqlite3_create_function (db, "RL2_WriteTripleBandTiff", 12,
-				   SQLITE_ANY, 0, fnct_WriteTripleBandTiff, 0,
-				   0);
-	  sqlite3_create_function (db, "WriteMonoBandTiff", 7, SQLITE_ANY,
-				   0, fnct_WriteMonoBandTiff, 0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteTripleBandTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionTripleBandTiff", 10,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTripleBandTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionTripleBandTiff", 10,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTripleBandTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionTripleBandTiff", 11,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTripleBandTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionTripleBandTiff", 11,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTripleBandTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionTripleBandTiff", 12,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTripleBandTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionTripleBandTiff", 12,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTripleBandTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionTripleBandTiff", 13,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTripleBandTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionTripleBandTiff", 13,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionTripleBandTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteMonoBandTiff", 7, SQLITE_UTF8, 0,
+				   fnct_WriteMonoBandTiff, 0, 0);
 	  sqlite3_create_function (db, "RL2_WriteMonoBandTiff", 7,
-				   SQLITE_ANY, 0, fnct_WriteMonoBandTiff, 0, 0);
-	  sqlite3_create_function (db, "WriteMonoBandTiff", 8, SQLITE_ANY,
-				   0, fnct_WriteMonoBandTiff, 0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteMonoBandTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteMonoBandTiff", 8, SQLITE_UTF8, 0,
+				   fnct_WriteMonoBandTiff, 0, 0);
 	  sqlite3_create_function (db, "RL2_WriteMonoBandTiff", 8,
-				   SQLITE_ANY, 0, fnct_WriteMonoBandTiff, 0, 0);
-	  sqlite3_create_function (db, "WriteMonoBandTiff", 9, SQLITE_ANY,
-				   0, fnct_WriteMonoBandTiff, 0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteMonoBandTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteMonoBandTiff", 9, SQLITE_UTF8,
+				   priv_data, fnct_WriteMonoBandTiff, 0, 0);
 	  sqlite3_create_function (db, "RL2_WriteMonoBandTiff", 9,
-				   SQLITE_ANY, 0, fnct_WriteMonoBandTiff, 0, 0);
-	  sqlite3_create_function (db, "WriteMonoBandTiff", 10, SQLITE_ANY,
-				   0, fnct_WriteMonoBandTiff, 0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteMonoBandTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteMonoBandTiff", 10, SQLITE_UTF8,
+				   priv_data, fnct_WriteMonoBandTiff, 0, 0);
 	  sqlite3_create_function (db, "RL2_WriteMonoBandTiff", 10,
-				   SQLITE_ANY, 0, fnct_WriteMonoBandTiff, 0, 0);
-	  sqlite3_create_function (db, "WriteAsciiGrid", 6, SQLITE_ANY, 0,
-				   fnct_WriteAsciiGrid, 0, 0);
-	  sqlite3_create_function (db, "RL2_WriteAsciiGrid", 6, SQLITE_ANY, 0,
-				   fnct_WriteAsciiGrid, 0, 0);
-	  sqlite3_create_function (db, "WriteAsciiGrid", 7, SQLITE_ANY, 0,
-				   fnct_WriteAsciiGrid, 0, 0);
-	  sqlite3_create_function (db, "RL2_WriteAsciiGrid", 7, SQLITE_ANY, 0,
-				   fnct_WriteAsciiGrid, 0, 0);
-	  sqlite3_create_function (db, "WriteAsciiGrid", 8, SQLITE_ANY, 0,
-				   fnct_WriteAsciiGrid, 0, 0);
-	  sqlite3_create_function (db, "RL2_WriteAsciiGrid", 8, SQLITE_ANY, 0,
-				   fnct_WriteAsciiGrid, 0, 0);
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteMonoBandTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionMonoBandTiff", 8,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionMonoBandTiff", 8,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionMonoBandTiff", 9,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionMonoBandTiff", 9,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionMonoBandTiff", 10,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionMonoBandTiff", 10,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionMonoBandTiff", 11,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandTiff, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionMonoBandTiff", 11,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionMonoBandTiff, 0, 0);
+	  sqlite3_create_function (db, "WriteAsciiGrid", 6, SQLITE_UTF8,
+				   priv_data, fnct_WriteAsciiGrid, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteAsciiGrid", 6, SQLITE_UTF8,
+				   priv_data, fnct_WriteAsciiGrid, 0, 0);
+	  sqlite3_create_function (db, "WriteAsciiGrid", 7, SQLITE_UTF8,
+				   priv_data, fnct_WriteAsciiGrid, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteAsciiGrid", 7, SQLITE_UTF8,
+				   priv_data, fnct_WriteAsciiGrid, 0, 0);
+	  sqlite3_create_function (db, "WriteAsciiGrid", 8, SQLITE_UTF8,
+				   priv_data, fnct_WriteAsciiGrid, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteAsciiGrid", 8, SQLITE_UTF8,
+				   priv_data, fnct_WriteAsciiGrid, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionAsciiGrid", 7,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionAsciiGrid, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionAsciiGrid", 7,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionAsciiGrid, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionAsciiGrid", 8,
+				   SQLITE_UTF8, 0, fnct_WriteSectionAsciiGrid,
+				   0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionAsciiGrid", 8,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionAsciiGrid, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionAsciiGrid", 9,
+				   SQLITE_UTF8, 0, fnct_WriteSectionAsciiGrid,
+				   0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionAsciiGrid", 9,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionAsciiGrid, 0, 0);
+	  sqlite3_create_function (db, "WriteNdviAsciiGrid", 8, SQLITE_UTF8,
+				   priv_data, fnct_WriteNdviAsciiGrid, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteNdviAsciiGrid", 8,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteNdviAsciiGrid, 0, 0);
+	  sqlite3_create_function (db, "WriteNdviAsciiGrid", 9, SQLITE_UTF8,
+				   priv_data, fnct_WriteNdviAsciiGrid, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteNdviAsciiGrid", 9,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteNdviAsciiGrid, 0, 0);
+	  sqlite3_create_function (db, "WriteNdviAsciiGrid", 10, SQLITE_UTF8,
+				   priv_data, fnct_WriteNdviAsciiGrid, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteNdviAsciiGrid", 10,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteNdviAsciiGrid, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionNdviAsciiGrid", 9,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionNdviAsciiGrid, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionNdviAsciiGrid", 9,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionNdviAsciiGrid, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionNdviAsciiGrid", 10,
+				   SQLITE_UTF8, 0,
+				   fnct_WriteSectionNdviAsciiGrid, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionNdviAsciiGrid", 10,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionNdviAsciiGrid, 0, 0);
+	  sqlite3_create_function (db, "WriteSectionNdviAsciiGrid", 11,
+				   SQLITE_UTF8, 0,
+				   fnct_WriteSectionNdviAsciiGrid, 0, 0);
+	  sqlite3_create_function (db, "RL2_WriteSectionNdviAsciiGrid", 11,
+				   SQLITE_UTF8, priv_data,
+				   fnct_WriteSectionNdviAsciiGrid, 0, 0);
       }
 }
 
@@ -7006,10 +11300,10 @@ rl2_splash_screen (int verbose)
 #ifndef LOADABLE_EXTENSION
 
 RL2_DECLARE void
-rl2_init (sqlite3 * handle, int verbose)
+rl2_init (sqlite3 * handle, const void *priv_data, int verbose)
 {
 /* used when SQLite initializes as an ordinary lib */
-    register_rl2_sql_functions (handle);
+    register_rl2_sql_functions (handle, priv_data);
     rl2_splash_screen (verbose);
 }
 
@@ -7019,9 +11313,10 @@ SQLITE_EXTENSION_INIT1 static int
 init_rl2_extension (sqlite3 * db, char **pzErrMsg,
 		    const sqlite3_api_routines * pApi)
 {
+    void *priv_data = rl2_alloc_private ();
     SQLITE_EXTENSION_INIT2 (pApi);
 
-    register_rl2_sql_functions (db);
+    register_rl2_sql_functions (db, priv_data);
     return 0;
 }
 
diff --git a/src/rl2sqlaux.c b/src/rl2sqlaux.c
index 4f862a5..cdae9f5 100644
--- a/src/rl2sqlaux.c
+++ b/src/rl2sqlaux.c
@@ -20,7 +20,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -66,8 +66,6 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include "rasterlite2/rl2graphics.h"
 #include "rasterlite2_private.h"
 
-#include <spatialite/gaiaaux.h>
-
 #define RL2_UNUSED() if (argc || argv) argc = argc;
 
 RL2_PRIVATE int
@@ -87,8 +85,9 @@ get_coverage_sample_bands (sqlite3 * sqlite, const char *coverage,
     unsigned char xnum_bands = RL2_BANDS_UNKNOWN;
 
     sql =
-	sqlite3_mprintf ("SELECT sample_type, num_bands FROM raster_coverages "
-			 "WHERE Lower(coverage_name) = Lower(%Q)", coverage);
+	sqlite3_mprintf
+	("SELECT sample_type, num_bands FROM raster_coverages "
+	 "WHERE Lower(coverage_name) = Lower(%Q)", coverage);
     ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, NULL);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -216,10 +215,12 @@ get_coverage_defs (sqlite3 * sqlite, const char *coverage,
 		    xcompression = RL2_COMPRESSION_NONE;
 		if (strcmp (compr, "DEFLATE") == 0)
 		    xcompression = RL2_COMPRESSION_DEFLATE;
+		if (strcmp (compr, "DEFLATE_NO") == 0)
+		    xcompression = RL2_COMPRESSION_DEFLATE_NO;
 		if (strcmp (compr, "LZMA") == 0)
 		    xcompression = RL2_COMPRESSION_LZMA;
-		if (strcmp (compr, "GIF") == 0)
-		    xcompression = RL2_COMPRESSION_GIF;
+		if (strcmp (compr, "LZMA_NO") == 0)
+		    xcompression = RL2_COMPRESSION_LZMA_NO;
 		if (strcmp (compr, "PNG") == 0)
 		    xcompression = RL2_COMPRESSION_PNG;
 		if (strcmp (compr, "JPEG") == 0)
@@ -230,6 +231,12 @@ get_coverage_defs (sqlite3 * sqlite, const char *coverage,
 		    xcompression = RL2_COMPRESSION_LOSSLESS_WEBP;
 		if (strcmp (compr, "CCITTFAX4") == 0)
 		    xcompression = RL2_COMPRESSION_CCITTFAX4;
+		if (strcmp (compr, "CHARLS") == 0)
+		    xcompression = RL2_COMPRESSION_CHARLS;
+		if (strcmp (compr, "LOSSY_JP2") == 0)
+		    xcompression = RL2_COMPRESSION_LOSSY_JP2;
+		if (strcmp (compr, "LOSSLESS_JP2") == 0)
+		    xcompression = RL2_COMPRESSION_LOSSLESS_JP2;
 		xtile_width = atoi (results[(i * columns) + 4]);
 		xtile_height = atoi (results[(i * columns) + 5]);
 	    }
@@ -413,41 +420,339 @@ add_retry (WmsRetryListPtr lst, double minx, double miny, double maxx,
     lst->last = p;
 }
 
-RL2_PRIVATE gaiaGeomCollPtr
-build_extent (int srid, double minx, double miny, double maxx, double maxy)
+RL2_PRIVATE int
+rl2_parse_point (sqlite3 * handle, const unsigned char *blob, int blob_sz,
+		 double *x, double *y)
 {
-/* building an MBR (Envelope) */
-    gaiaPolygonPtr pg;
-    gaiaRingPtr rng;
-    gaiaGeomCollPtr geom = gaiaAllocGeomColl ();
-    geom->Srid = srid;
-    pg = gaiaAddPolygonToGeomColl (geom, 5, 0);
-    rng = pg->Exterior;
-    gaiaSetPoint (rng->Coords, 0, minx, miny);
-    gaiaSetPoint (rng->Coords, 1, maxx, miny);
-    gaiaSetPoint (rng->Coords, 2, maxx, maxy);
-    gaiaSetPoint (rng->Coords, 3, minx, maxy);
-    gaiaSetPoint (rng->Coords, 4, minx, miny);
-    return geom;
+/* attempts to get the coordinates from a POINT */
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+    const char *sql;
+    double pt_x;
+    double pt_y;
+    int count = 0;
+
+    sql = "SELECT ST_X(?), ST_Y(?) WHERE ST_GeometryType(?) IN "
+	"('POINT', 'POINT Z', 'POINT M', 'POINT ZM')";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("SELECT rl2_parse_point SQL error: %s\n",
+		  sqlite3_errmsg (handle));
+	  goto error;
+      }
+
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_blob (stmt, 1, blob, blob_sz, SQLITE_STATIC);
+    sqlite3_bind_blob (stmt, 2, blob, blob_sz, SQLITE_STATIC);
+    sqlite3_bind_blob (stmt, 3, blob, blob_sz, SQLITE_STATIC);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	    {
+		pt_x = sqlite3_column_double (stmt, 0);
+		pt_y = sqlite3_column_double (stmt, 1);
+		count++;
+	    }
+	  else
+	    {
+		fprintf (stderr,
+			 "SELECT rl2_parse_point; sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (handle));
+		goto error;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    if (count != 1)
+	return RL2_ERROR;
+    *x = pt_x;
+    *y = pt_y;
+    return RL2_OK;
+
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    return RL2_ERROR;
 }
 
 RL2_PRIVATE int
-do_insert_wms_tile (sqlite3 * handle, unsigned char *blob_odd, int blob_odd_sz,
-		    unsigned char *blob_even, int blob_even_sz,
-		    sqlite3_int64 section_id, int srid, double res_x,
-		    double res_y, unsigned int tile_w, unsigned int tile_h,
-		    double miny, double maxx, double tile_minx,
-		    double tile_miny, double tile_maxx, double tile_maxy,
-		    rl2PalettePtr aux_palette, rl2PixelPtr no_data,
-		    sqlite3_stmt * stmt_tils, sqlite3_stmt * stmt_data,
+rl2_parse_point_generic (sqlite3 * handle, const unsigned char *blob,
+			 int blob_sz, double *x, double *y)
+{
+/* attempts to get X,Y coordinates from a generic Geometry */
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+    const char *sql;
+    double pt_x;
+    double pt_y;
+    int count = 0;
+
+    sql = "SELECT ST_X(ST_GeometryN(DissolvePoints(?), 1)), "
+	"ST_Y(ST_GeometryN(DissolvePoints(?), 1))";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("SELECT rl2_parse_point_generic SQL error: %s\n",
+		  sqlite3_errmsg (handle));
+	  goto error;
+      }
+
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_blob (stmt, 1, blob, blob_sz, SQLITE_STATIC);
+    sqlite3_bind_blob (stmt, 2, blob, blob_sz, SQLITE_STATIC);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	    {
+		pt_x = sqlite3_column_double (stmt, 0);
+		pt_y = sqlite3_column_double (stmt, 1);
+		count++;
+	    }
+	  else
+	    {
+		fprintf (stderr,
+			 "SELECT rl2_parse_point_generic; sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (handle));
+		goto error;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    if (count != 1)
+	return RL2_ERROR;
+    *x = pt_x;
+    *y = pt_y;
+    return RL2_OK;
+
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    return RL2_ERROR;
+}
+
+RL2_PRIVATE int
+rl2_parse_bbox (sqlite3 * handle, const unsigned char *blob, int blob_sz,
+		double *minx, double *miny, double *maxx, double *maxy)
+{
+/* attempts the get the BBOX from a BLOB geometry request */
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+    const char *sql;
+    double mnx;
+    double mny;
+    double mxx;
+    double mxy;
+    int count = 0;
+
+    sql = "SELECT MBRMinX(?), MBRMinY(?), MBRMaxX(?), MBRMaxY(?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("SELECT rl2_parse_bbox SQL error: %s\n",
+		  sqlite3_errmsg (handle));
+	  goto error;
+      }
+
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_blob (stmt, 1, blob, blob_sz, SQLITE_STATIC);
+    sqlite3_bind_blob (stmt, 2, blob, blob_sz, SQLITE_STATIC);
+    sqlite3_bind_blob (stmt, 3, blob, blob_sz, SQLITE_STATIC);
+    sqlite3_bind_blob (stmt, 4, blob, blob_sz, SQLITE_STATIC);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	    {
+		mnx = sqlite3_column_double (stmt, 0);
+		mny = sqlite3_column_double (stmt, 1);
+		mxx = sqlite3_column_double (stmt, 2);
+		mxy = sqlite3_column_double (stmt, 3);
+		count++;
+	    }
+	  else
+	    {
+		fprintf (stderr,
+			 "SELECT rl2_parse_bbox; sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (handle));
+		goto error;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    if (count != 1)
+	return RL2_ERROR;
+    *minx = mnx;
+    *miny = mny;
+    *maxx = mxx;
+    *maxy = mxy;
+    return RL2_OK;
+
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    return RL2_ERROR;
+}
+
+RL2_PRIVATE int
+rl2_parse_bbox_srid (sqlite3 * handle, const unsigned char *blob, int blob_sz,
+		     int *srid, double *minx, double *miny, double *maxx,
+		     double *maxy)
+{
+/* attempts the get the BBOX and SRID from a BLOB geometry request */
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+    const char *sql;
+    int srd;
+    double mnx;
+    double mny;
+    double mxx;
+    double mxy;
+    int count = 0;
+
+    sql = "SELECT ST_Srid(?), MBRMinX(?), MBRMinY(?), MBRMaxX(?), MBRMaxY(?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("SELECT rl2_parse_bbox SQL error: %s\n",
+		  sqlite3_errmsg (handle));
+	  goto error;
+      }
+
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_blob (stmt, 1, blob, blob_sz, SQLITE_STATIC);
+    sqlite3_bind_blob (stmt, 2, blob, blob_sz, SQLITE_STATIC);
+    sqlite3_bind_blob (stmt, 3, blob, blob_sz, SQLITE_STATIC);
+    sqlite3_bind_blob (stmt, 4, blob, blob_sz, SQLITE_STATIC);
+    sqlite3_bind_blob (stmt, 5, blob, blob_sz, SQLITE_STATIC);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	    {
+		srd = sqlite3_column_int (stmt, 0);
+		mnx = sqlite3_column_double (stmt, 1);
+		mny = sqlite3_column_double (stmt, 2);
+		mxx = sqlite3_column_double (stmt, 3);
+		mxy = sqlite3_column_double (stmt, 4);
+		count++;
+	    }
+	  else
+	    {
+		fprintf (stderr,
+			 "SELECT rl2_parse_bbox; sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (handle));
+		goto error;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    if (count != 1)
+	return RL2_ERROR;
+    *srid = srd;
+    *minx = mnx;
+    *miny = mny;
+    *maxx = mxx;
+    *maxy = mxy;
+    return RL2_OK;
+
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    return RL2_ERROR;
+}
+
+RL2_PRIVATE int
+rl2_build_bbox (sqlite3 * handle, int srid, double minx, double miny,
+		double maxx, double maxy, unsigned char **blob, int *blob_sz)
+{
+/* building an MBR (Envelope) */
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+    const char *sql;
+    const unsigned *x_blob;
+    unsigned char *p_blob;
+    int p_blob_sz;
+    int count = 0;
+
+    sql = "SELECT BuildMBR(?, ?, ?, ?, ?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("SELECT rl2_build_bbox SQL error: %s\n",
+		  sqlite3_errmsg (handle));
+	  goto error;
+      }
+
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_double (stmt, 1, minx);
+    sqlite3_bind_double (stmt, 2, miny);
+    sqlite3_bind_double (stmt, 3, maxx);
+    sqlite3_bind_double (stmt, 4, maxy);
+    sqlite3_bind_int (stmt, 5, srid);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	    {
+		if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
+		  {
+		      x_blob = sqlite3_column_blob (stmt, 0);
+		      p_blob_sz = sqlite3_column_bytes (stmt, 0);
+		      p_blob = malloc (p_blob_sz);
+		      memcpy (p_blob, x_blob, p_blob_sz);
+		      count++;
+		  }
+	    }
+	  else
+	    {
+		fprintf (stderr,
+			 "SELECT rl2_build_bbox; sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (handle));
+		goto error;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    if (count != 1)
+	return RL2_ERROR;
+    *blob = p_blob;
+    *blob_sz = p_blob_sz;
+    return RL2_OK;
+
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    return RL2_ERROR;
+}
+
+static int
+do_insert_wms_tile (sqlite3 * handle, unsigned char *blob_odd,
+		    int blob_odd_sz, unsigned char *blob_even,
+		    int blob_even_sz, sqlite3_int64 section_id, int srid,
+		    double res_x, double res_y, unsigned int tile_w,
+		    unsigned int tile_h, double miny, double maxx,
+		    double tile_minx, double tile_miny, double tile_maxx,
+		    double tile_maxy, rl2PalettePtr aux_palette,
+		    rl2PixelPtr no_data, sqlite3_stmt * stmt_tils,
+		    sqlite3_stmt * stmt_data,
 		    rl2RasterStatisticsPtr section_stats)
 {
 /* INSERTing the tile */
     int ret;
     sqlite3_int64 tile_id;
-    unsigned char *blob;
-    int blob_size;
-    gaiaGeomCollPtr geom;
     rl2RasterStatisticsPtr stats = NULL;
 
     stats = rl2_get_raster_statistics
@@ -464,10 +769,11 @@ do_insert_wms_tile (sqlite3 * handle, unsigned char *blob_odd, int blob_odd_sz,
     tile_miny = tile_maxy - ((double) tile_h * res_y);
     if (tile_miny < miny)
 	tile_miny = miny;
-    geom = build_extent (srid, tile_minx, tile_miny, tile_maxx, tile_maxy);
-    gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
-    gaiaFreeGeomColl (geom);
-    sqlite3_bind_blob (stmt_tils, 2, blob, blob_size, free);
+    sqlite3_bind_double (stmt_tils, 2, tile_minx);
+    sqlite3_bind_double (stmt_tils, 3, tile_miny);
+    sqlite3_bind_double (stmt_tils, 4, tile_maxx);
+    sqlite3_bind_double (stmt_tils, 5, tile_maxy);
+    sqlite3_bind_int (stmt_tils, 6, srid);
     ret = sqlite3_step (stmt_tils);
     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
 	;
@@ -507,11 +813,11 @@ do_insert_wms_tile (sqlite3 * handle, unsigned char *blob_odd, int blob_odd_sz,
 }
 
 RL2_PRIVATE int
-do_insert_levels (sqlite3 * handle, double base_res_x, double base_res_y,
-		  double factor, unsigned char sample_type,
-		  sqlite3_stmt * stmt_levl)
+rl2_do_insert_levels (sqlite3 * handle, double base_res_x, double base_res_y,
+		      double factor, unsigned char sample_type,
+		      sqlite3_stmt * stmt_levl)
 {
-/* INSERTing the base-levels */
+/* INSERTing the base-levels - single resolution Coverage */
     int ret;
     double res_x = base_res_x * factor;
     double res_y = base_res_y * factor;
@@ -554,8 +860,57 @@ do_insert_levels (sqlite3 * handle, double base_res_x, double base_res_y,
 }
 
 RL2_PRIVATE int
-do_insert_stats (sqlite3 * handle, rl2RasterStatisticsPtr section_stats,
-		 sqlite3_int64 section_id, sqlite3_stmt * stmt_upd_sect)
+rl2_do_insert_section_levels (sqlite3 * handle, sqlite3_int64 section_id,
+			      double base_res_x, double base_res_y,
+			      double factor, unsigned char sample_type,
+			      sqlite3_stmt * stmt_levl)
+{
+/* INSERTing the base-levels - mixed resolution Coverage */
+    int ret;
+    double res_x = base_res_x * factor;
+    double res_y = base_res_y * factor;
+    sqlite3_reset (stmt_levl);
+    sqlite3_clear_bindings (stmt_levl);
+    sqlite3_bind_int64 (stmt_levl, 1, section_id);
+    sqlite3_bind_double (stmt_levl, 2, res_x);
+    sqlite3_bind_double (stmt_levl, 3, res_y);
+    if (sample_type == RL2_SAMPLE_1_BIT || sample_type == RL2_SAMPLE_2_BIT
+	|| sample_type == RL2_SAMPLE_4_BIT)
+      {
+	  sqlite3_bind_null (stmt_levl, 4);
+	  sqlite3_bind_null (stmt_levl, 5);
+	  sqlite3_bind_null (stmt_levl, 6);
+	  sqlite3_bind_null (stmt_levl, 7);
+	  sqlite3_bind_null (stmt_levl, 8);
+	  sqlite3_bind_null (stmt_levl, 9);
+      }
+    else
+      {
+	  sqlite3_bind_double (stmt_levl, 4, res_x * 2.0);
+	  sqlite3_bind_double (stmt_levl, 5, res_y * 2.0);
+	  sqlite3_bind_double (stmt_levl, 6, res_x * 4.0);
+	  sqlite3_bind_double (stmt_levl, 7, res_y * 4.0);
+	  sqlite3_bind_double (stmt_levl, 8, res_x * 8.0);
+	  sqlite3_bind_double (stmt_levl, 9, res_y * 8.0);
+      }
+    ret = sqlite3_step (stmt_levl);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+	;
+    else
+      {
+	  fprintf (stderr,
+		   "INSERT INTO section_levels; sqlite3_step() error: %s\n",
+		   sqlite3_errmsg (handle));
+	  goto error;
+      }
+    return 1;
+  error:
+    return 0;
+}
+
+RL2_PRIVATE int
+rl2_do_insert_stats (sqlite3 * handle, rl2RasterStatisticsPtr section_stats,
+		     sqlite3_int64 section_id, sqlite3_stmt * stmt_upd_sect)
 {
 /* updating the Section's Statistics */
     unsigned char *blob_stats;
@@ -617,18 +972,47 @@ get_section_name (const char *src_path)
     return name;
 }
 
+RL2_DECLARE char *
+rl2_compute_file_md5_checksum (const char *src_path)
+{
+/* attempting to compute an MD5 checksum from a file */
+    size_t rd;
+    size_t blk = 1024 * 1024;
+    unsigned char *buf;
+    void *p_md5;
+    char *md5;
+    FILE *in = fopen (src_path, "rb");
+    if (in == NULL)
+	return NULL;
+    buf = malloc (blk);
+    p_md5 = rl2_CreateMD5Checksum ();
+    while (1)
+      {
+	  rd = fread (buf, 1, blk, in);
+	  if (rd == 0)
+	      break;
+	  rl2_UpdateMD5Checksum (p_md5, buf, rd);
+      }
+    free (buf);
+    fclose (in);
+    md5 = rl2_FinalizeMD5Checksum (p_md5);
+    rl2_FreeMD5Checksum (p_md5);
+    return md5;
+}
+
 RL2_PRIVATE int
-do_insert_section (sqlite3 * handle, const char *src_path,
-		   const char *section, int srid, unsigned int width,
-		   unsigned int height, double minx, double miny,
-		   double maxx, double maxy, sqlite3_stmt * stmt_sect,
-		   sqlite3_int64 * id)
+rl2_do_insert_section (sqlite3 * handle, const char *src_path,
+		       const char *section, int srid, unsigned int width,
+		       unsigned int height, double minx, double miny,
+		       double maxx, double maxy, char *xml_summary,
+		       int section_paths, int section_md5,
+		       int section_summary, sqlite3_stmt * stmt_sect,
+		       sqlite3_int64 * id)
 {
 /* INSERTing the section */
     int ret;
     unsigned char *blob;
     int blob_size;
-    gaiaGeomCollPtr geom;
     sqlite3_int64 section_id;
 
     sqlite3_reset (stmt_sect);
@@ -643,14 +1027,41 @@ do_insert_section (sqlite3 * handle, const char *src_path,
 	      sqlite3_bind_text (stmt_sect, 1, sect_name, strlen (sect_name),
 				 free);
       }
-    sqlite3_bind_text (stmt_sect, 2, src_path, strlen (src_path),
-		       SQLITE_STATIC);
-    sqlite3_bind_int (stmt_sect, 3, width);
-    sqlite3_bind_int (stmt_sect, 4, height);
-    geom = build_extent (srid, minx, miny, maxx, maxy);
-    gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
-    gaiaFreeGeomColl (geom);
-    sqlite3_bind_blob (stmt_sect, 5, blob, blob_size, free);
+    if (section_paths)
+	sqlite3_bind_text (stmt_sect, 2, src_path, strlen (src_path),
+			   SQLITE_STATIC);
+    else
+	sqlite3_bind_null (stmt_sect, 2);
+    if (section_md5)
+      {
+	  char *md5 = rl2_compute_file_md5_checksum (src_path);
+	  if (md5 == NULL)
+	      sqlite3_bind_null (stmt_sect, 3);
+	  else
+	      sqlite3_bind_text (stmt_sect, 3, md5, strlen (md5), free);
+      }
+    else
+	sqlite3_bind_null (stmt_sect, 3);
+    if (section_summary)
+      {
+	  if (xml_summary == NULL)
+	      sqlite3_bind_null (stmt_sect, 4);
+	  else
+	      sqlite3_bind_blob (stmt_sect, 4, xml_summary,
+				 strlen (xml_summary), free);
+      }
+    else
+      {
+	  sqlite3_bind_null (stmt_sect, 4);
+	  if (xml_summary != NULL)
+	      free (xml_summary);
+      }
+    sqlite3_bind_int (stmt_sect, 5, width);
+    sqlite3_bind_int (stmt_sect, 6, height);
+    if (rl2_build_bbox
+	(handle, srid, minx, miny, maxx, maxy, &blob, &blob_size) != RL2_OK)
+	goto error;
+    sqlite3_bind_blob (stmt_sect, 7, blob, blob_size, free);
     ret = sqlite3_step (stmt_sect);
     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
 	section_id = sqlite3_last_insert_rowid (handle);
@@ -730,6 +1141,7 @@ build_wms_tile (rl2CoveragePtr coverage, const unsigned char *rgba_tile)
 		      unsigned char red = *p_in++;
 		      unsigned char green = *p_in++;
 		      unsigned char blue = *p_in++;
+		      p_in++;
 		      *p_out++ = red;
 		      *p_out++ = green;
 		      *p_out++ = blue;
@@ -808,27 +1220,41 @@ insert_wms_tile (InsertWmsPtr ptr, int *first,
     double base_res_x;
     double base_res_y;
 
-    if (rl2_get_coverage_resolution (ptr->coverage, &base_res_x, &base_res_y) !=
-	RL2_OK)
+    if (rl2_get_coverage_resolution (ptr->coverage, &base_res_x, &base_res_y)
+	!= RL2_OK)
 	goto error;
     if (*first)
       {
 	  /* INSERTing the section */
 	  *first = 0;
-	  if (!do_insert_section
+	  if (!rl2_do_insert_section
 	      (ptr->sqlite, "WMS Service", ptr->sect_name, ptr->srid,
 	       ptr->width, ptr->height, ptr->minx, ptr->miny, ptr->maxx,
-	       ptr->maxy, ptr->stmt_sect, section_id))
+	       ptr->maxy, ptr->xml_summary, ptr->sectionPaths,
+	       ptr->sectionMD5, ptr->sectionSummary, ptr->stmt_sect,
+	       section_id))
 	      goto error;
 	  *section_stats =
 	      rl2_create_raster_statistics (ptr->sample_type, ptr->num_bands);
 	  if (*section_stats == NULL)
 	      goto error;
 	  /* INSERTing the base-levels */
-	  if (!do_insert_levels
-	      (ptr->sqlite, base_res_x, base_res_y, 1.0, RL2_SAMPLE_UNKNOWN,
-	       ptr->stmt_levl))
-	      goto error;
+	  if (ptr->mixedResolutions)
+	    {
+		/* multiple resolutions Coverage */
+		if (!rl2_do_insert_section_levels
+		    (ptr->sqlite, *section_id, base_res_x, base_res_y, 1.0,
+		     RL2_SAMPLE_UNKNOWN, ptr->stmt_levl))
+		    goto error;
+	    }
+	  else
+	    {
+		/* single resolution Coverage */
+		if (!rl2_do_insert_levels
+		    (ptr->sqlite, base_res_x, base_res_y, 1.0,
+		     RL2_SAMPLE_UNKNOWN, ptr->stmt_levl))
+		    goto error;
+	    }
       }
 
     /* building the raster tile */
@@ -853,9 +1279,9 @@ insert_wms_tile (InsertWmsPtr ptr, int *first,
     tile_miny = tile_maxy - ptr->tileh;
     if (!do_insert_wms_tile
 	(ptr->sqlite, blob_odd, blob_odd_sz, blob_even, blob_even_sz,
-	 *section_id, ptr->srid, ptr->horz_res, ptr->vert_res, ptr->tile_width,
-	 ptr->tile_height, ptr->minx, ptr->maxy, tile_minx, tile_miny,
-	 tile_maxx, tile_maxy, NULL, ptr->no_data, ptr->stmt_tils,
+	 *section_id, ptr->srid, ptr->horz_res, ptr->vert_res,
+	 ptr->tile_width, ptr->tile_height, ptr->miny, ptr->maxx, tile_minx,
+	 tile_miny, tile_maxx, tile_maxy, NULL, ptr->no_data, ptr->stmt_tils,
 	 ptr->stmt_data, *section_stats))
 	goto error;
     blob_odd = NULL;
@@ -876,39 +1302,6 @@ insert_wms_tile (InsertWmsPtr ptr, int *first,
     return 0;
 }
 
-RL2_PRIVATE int
-is_point (gaiaGeomCollPtr geom)
-{
-/* checking if the Geom is a simple Point */
-    int pts = 0;
-    int lns = 0;
-    int pgs = 0;
-    gaiaPointPtr pt;
-    gaiaLinestringPtr ln;
-    gaiaPolygonPtr pg;
-    pt = geom->FirstPoint;
-    while (pt != NULL)
-      {
-	  pts++;
-	  pt = pt->Next;
-      }
-    ln = geom->FirstLinestring;
-    while (ln != NULL)
-      {
-	  lns++;
-	  ln = ln->Next;
-      }
-    pg = geom->FirstPolygon;
-    while (pg != NULL)
-      {
-	  pgs++;
-	  pg = pg->Next;
-      }
-    if (pts == 1 && lns == 0 && pgs == 0)
-	return 1;
-    return 0;
-}
-
 RL2_PRIVATE ResolutionsListPtr
 alloc_resolutions_list ()
 {
@@ -975,10 +1368,11 @@ add_base_resolution (ResolutionsListPtr list, int level, int scale,
 }
 
 RL2_PRIVATE int
-find_best_resolution_level (sqlite3 * handle, const char *coverage,
-			    double x_res, double y_res, int *level_id,
-			    int *scale, int *real_scale, double *xx_res,
-			    double *yy_res)
+rl2_find_best_resolution_level (sqlite3 * handle, const char *coverage,
+				int by_section, sqlite3_int64 section_id,
+				double x_res, double y_res, int *level_id,
+				int *scale, int *real_scale, double *xx_res,
+				double *yy_res)
 {
 /* attempting to identify the optimal resolution level */
     int ret;
@@ -998,15 +1392,39 @@ find_best_resolution_level (sqlite3 * handle, const char *coverage,
     if (coverage == NULL)
 	return 0;
 
-    xcoverage = sqlite3_mprintf ("%s_levels", coverage);
-    xxcoverage = gaiaDoubleQuotedSql (xcoverage);
-    sqlite3_free (xcoverage);
-    sql =
-	sqlite3_mprintf
-	("SELECT pyramid_level, x_resolution_1_8, y_resolution_1_8, "
-	 "x_resolution_1_4, y_resolution_1_4, x_resolution_1_2, y_resolution_1_2, "
-	 "x_resolution_1_1, y_resolution_1_1 FROM \"%s\" "
-	 "ORDER BY pyramid_level DESC", xxcoverage);
+    if (by_section)
+      {
+	  /* Multi Resolution Coverage */
+	  char sctn[1024];
+#if defined(_WIN32) && !defined(__MINGW32__)
+	  sprintf (sctn, "%I64d", section_id);
+#else
+	  sprintf (sctn, "%lld", section_id);
+#endif
+	  xcoverage = sqlite3_mprintf ("%s_section_levels", coverage);
+	  xxcoverage = rl2_double_quoted_sql (xcoverage);
+	  sqlite3_free (xcoverage);
+	  sql =
+	      sqlite3_mprintf
+	      ("SELECT pyramid_level, x_resolution_1_8, y_resolution_1_8, "
+	       "x_resolution_1_4, y_resolution_1_4, x_resolution_1_2, y_resolution_1_2, "
+	       "x_resolution_1_1, y_resolution_1_1 FROM \"%s\" "
+	       "WHERE section_id = %s ORDER BY pyramid_level DESC",
+	       xxcoverage, sctn);
+      }
+    else
+      {
+	  /* ordinary Coverage */
+	  xcoverage = sqlite3_mprintf ("%s_levels", coverage);
+	  xxcoverage = rl2_double_quoted_sql (xcoverage);
+	  sqlite3_free (xcoverage);
+	  sql =
+	      sqlite3_mprintf
+	      ("SELECT pyramid_level, x_resolution_1_8, y_resolution_1_8, "
+	       "x_resolution_1_4, y_resolution_1_4, x_resolution_1_2, y_resolution_1_2, "
+	       "x_resolution_1_1, y_resolution_1_1 FROM \"%s\" "
+	       "ORDER BY pyramid_level DESC", xxcoverage);
+      }
     free (xxcoverage);
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
@@ -1202,11 +1620,11 @@ rgb_to_rgba (unsigned int width, unsigned int height, unsigned char *rgb)
 
 RL2_PRIVATE int
 get_payload_from_monochrome_opaque (unsigned int width, unsigned int height,
-				    sqlite3 * handle, double minx, double miny,
-				    double maxx, double maxy, int srid,
-				    unsigned char *pixels, unsigned char format,
-				    int quality, unsigned char **image,
-				    int *image_sz)
+				    sqlite3 * handle, double minx,
+				    double miny, double maxx, double maxy,
+				    int srid, unsigned char *pixels,
+				    unsigned char format, int quality,
+				    unsigned char **image, int *image_sz)
 {
 /* input: Monochrome    output: Grayscale */
     int ret;
@@ -1250,8 +1668,8 @@ get_payload_from_monochrome_opaque (unsigned int width, unsigned int height,
 	  if (srid > 0)
 	    {
 		if (rl2_gray_to_geotiff
-		    (width, height, handle, minx, miny, maxx, maxy, srid, gray,
-		     image, image_sz) != RL2_OK)
+		    (width, height, handle, minx, miny, maxx, maxy, srid,
+		     gray, image, image_sz) != RL2_OK)
 		    goto error;
 	    }
 	  else
@@ -1419,14 +1837,14 @@ get_payload_from_palette_opaque (unsigned int width, unsigned int height,
 		if (srid > 0)
 		  {
 		      if (rl2_rgb_to_geotiff
-			  (width, height, handle, minx, miny, maxx, maxy, srid,
-			   rgb, image, image_sz) != RL2_OK)
+			  (width, height, handle, minx, miny, maxx, maxy,
+			   srid, rgb, image, image_sz) != RL2_OK)
 			  goto error;
 		  }
 		else
 		  {
-		      if (rl2_rgb_to_tiff (width, height, rgb, image, image_sz)
-			  != RL2_OK)
+		      if (rl2_rgb_to_tiff
+			  (width, height, rgb, image, image_sz) != RL2_OK)
 			  goto error;
 		  }
 	    }
@@ -1482,8 +1900,8 @@ get_payload_from_palette_opaque (unsigned int width, unsigned int height,
 		if (srid > 0)
 		  {
 		      if (rl2_gray_to_geotiff
-			  (width, height, handle, minx, miny, maxx, maxy, srid,
-			   gray, image, image_sz) != RL2_OK)
+			  (width, height, handle, minx, miny, maxx, maxy,
+			   srid, gray, image, image_sz) != RL2_OK)
 			  goto error;
 		  }
 		else
@@ -1660,9 +2078,9 @@ RL2_PRIVATE int
 get_payload_from_grayscale_opaque (unsigned int width, unsigned int height,
 				   sqlite3 * handle, double minx, double miny,
 				   double maxx, double maxy, int srid,
-				   unsigned char *pixels, unsigned char format,
-				   int quality, unsigned char **image,
-				   int *image_sz)
+				   unsigned char *pixels,
+				   unsigned char format, int quality,
+				   unsigned char **image, int *image_sz)
 {
 /* input: Grayscale    output: Grayscale */
     int ret;
@@ -1670,8 +2088,8 @@ get_payload_from_grayscale_opaque (unsigned int width, unsigned int height,
 
     if (format == RL2_OUTPUT_FORMAT_JPEG)
       {
-	  if (rl2_gray_to_jpeg (width, height, pixels, quality, image, image_sz)
-	      != RL2_OK)
+	  if (rl2_gray_to_jpeg
+	      (width, height, pixels, quality, image, image_sz) != RL2_OK)
 	      goto error;
       }
     else if (format == RL2_OUTPUT_FORMAT_PNG)
@@ -1691,8 +2109,8 @@ get_payload_from_grayscale_opaque (unsigned int width, unsigned int height,
 	    }
 	  else
 	    {
-		if (rl2_gray_to_tiff (width, height, pixels, image, image_sz) !=
-		    RL2_OK)
+		if (rl2_gray_to_tiff (width, height, pixels, image, image_sz)
+		    != RL2_OK)
 		    goto error;
 	    }
       }
@@ -1769,124 +2187,271 @@ get_payload_from_grayscale_transparent (unsigned int width,
     return 0;
 }
 
-RL2_PRIVATE int
-get_payload_from_rgb_opaque (unsigned int width, unsigned int height,
-			     sqlite3 * handle, double minx, double miny,
-			     double maxx, double maxy, int srid,
-			     unsigned char *pixels, unsigned char format,
-			     int quality, unsigned char **image, int *image_sz)
+RL2_PRIVATE int
+get_payload_from_rgb_opaque (unsigned int width, unsigned int height,
+			     sqlite3 * handle, double minx, double miny,
+			     double maxx, double maxy, int srid,
+			     unsigned char *pixels, unsigned char format,
+			     int quality, unsigned char **image, int *image_sz)
+{
+/* input: RGB    output: RGB */
+    int ret;
+    unsigned char *rgba = NULL;
+
+    if (format == RL2_OUTPUT_FORMAT_JPEG)
+      {
+	  if (rl2_rgb_to_jpeg
+	      (width, height, pixels, quality, image, image_sz) != RL2_OK)
+	      goto error;
+      }
+    else if (format == RL2_OUTPUT_FORMAT_PNG)
+      {
+	  if (rl2_rgb_to_png (width, height, pixels, image, image_sz) != RL2_OK)
+	      goto error;
+      }
+    else if (format == RL2_OUTPUT_FORMAT_TIFF)
+      {
+	  if (srid > 0)
+	    {
+		if (rl2_rgb_to_geotiff
+		    (width, height, handle, minx, miny, maxx, maxy, srid,
+		     pixels, image, image_sz) != RL2_OK)
+		    goto error;
+	    }
+	  else
+	    {
+		if (rl2_rgb_to_tiff (width, height, pixels, image, image_sz)
+		    != RL2_OK)
+		    goto error;
+	    }
+      }
+    else if (format == RL2_OUTPUT_FORMAT_PDF)
+      {
+	  rgba = rgb_to_rgba (width, height, pixels);
+	  if (rgba == NULL)
+	      goto error;
+	  ret = rl2_rgba_to_pdf (width, height, rgba, image, image_sz);
+	  rgba = NULL;
+	  if (ret != RL2_OK)
+	      goto error;
+      }
+    else
+	goto error;
+    free (pixels);
+    return 1;
+
+  error:
+    free (pixels);
+    if (rgba != NULL)
+	free (rgba);
+    return 0;
+}
+
+RL2_PRIVATE int
+get_payload_from_rgb_transparent (unsigned int width, unsigned int height,
+				  unsigned char *pixels, unsigned char format,
+				  int quality, unsigned char **image,
+				  int *image_sz, unsigned char bg_red,
+				  unsigned char bg_green,
+				  unsigned char bg_blue, double opacity)
+{
+/* input: RGB    output: RGB */
+    unsigned char *p_in;
+    unsigned char *p_msk;
+    unsigned char *mask = NULL;
+    unsigned int row;
+    unsigned int col;
+
+    if (quality > 100)
+	quality = 100;
+    mask = malloc (width * height);
+    if (mask == NULL)
+	goto error;
+    p_in = pixels;
+    p_msk = mask;
+    for (row = 0; row < height; row++)
+      {
+	  for (col = 0; col < width; col++)
+	    {
+		unsigned char red = *p_in++;
+		unsigned char green = *p_in++;
+		unsigned char blue = *p_in++;
+		if (red == bg_red && green == bg_green && blue == bg_blue)
+		    *p_msk++ = 0;	/* Transparent */
+		else
+		    *p_msk++ = 1;	/* Opaque */
+	    }
+      }
+    if (format == RL2_OUTPUT_FORMAT_PNG)
+      {
+	  if (rl2_rgb_alpha_to_png
+	      (width, height, pixels, mask, image, image_sz, opacity) != RL2_OK)
+	      goto error;
+      }
+    else
+	goto error;
+    free (pixels);
+    free (mask);
+    return 1;
+
+  error:
+    free (pixels);
+    if (mask != NULL)
+	free (mask);
+    return 0;
+}
+
+static int
+test_no_data_8 (rl2PrivPixelPtr no_data, char *p_in)
+{
+/* testing for NO-DATA - INT8 */
+    if (no_data != NULL)
+      {
+	  unsigned char band;
+	  int match = 0;
+	  rl2PrivSamplePtr sample;
+	  for (band = 0; band < no_data->nBands; band++)
+	    {
+		sample = no_data->Samples + band;
+		if (*(p_in + band) == sample->int8)
+		    match++;
+	    }
+	  if (match == no_data->nBands)
+	      return 1;
+      }
+    return 0;
+}
+
+static int
+test_no_data_u8 (rl2PrivPixelPtr no_data, unsigned char *p_in)
+{
+/* testing for NO-DATA - UINT8 */
+    if (no_data != NULL)
+      {
+	  unsigned char band;
+	  int match = 0;
+	  rl2PrivSamplePtr sample;
+	  for (band = 0; band < no_data->nBands; band++)
+	    {
+		sample = no_data->Samples + band;
+		if (*(p_in + band) == sample->uint8)
+		    match++;
+	    }
+	  if (match == no_data->nBands)
+	      return 1;
+      }
+    return 0;
+}
+
+static int
+test_no_data_16 (rl2PrivPixelPtr no_data, short *p_in)
+{
+/* testing for NO-DATA - INT16 */
+    if (no_data != NULL)
+      {
+	  unsigned char band;
+	  int match = 0;
+	  rl2PrivSamplePtr sample;
+	  for (band = 0; band < no_data->nBands; band++)
+	    {
+		sample = no_data->Samples + band;
+		if (*(p_in + band) == sample->int16)
+		    match++;
+	    }
+	  if (match == no_data->nBands)
+	      return 1;
+      }
+    return 0;
+}
+
+static int
+test_no_data_u16 (rl2PrivPixelPtr no_data, unsigned short *p_in)
+{
+/* testing for NO-DATA - UINT16 */
+    if (no_data != NULL)
+      {
+	  unsigned char band;
+	  int match = 0;
+	  rl2PrivSamplePtr sample;
+	  for (band = 0; band < no_data->nBands; band++)
+	    {
+		sample = no_data->Samples + band;
+		if (*(p_in + band) == sample->uint16)
+		    match++;
+	    }
+	  if (match == no_data->nBands)
+	      return 1;
+      }
+    return 0;
+}
+
+static int
+test_no_data_32 (rl2PrivPixelPtr no_data, int *p_in)
+{
+/* testing for NO-DATA - INT32 */
+    if (no_data != NULL)
+      {
+	  unsigned char band;
+	  int match = 0;
+	  rl2PrivSamplePtr sample;
+	  for (band = 0; band < no_data->nBands; band++)
+	    {
+		sample = no_data->Samples + band;
+		if (*(p_in + band) == sample->int32)
+		    match++;
+	    }
+	  if (match == no_data->nBands)
+	      return 1;
+      }
+    return 0;
+}
+
+static int
+test_no_data_u32 (rl2PrivPixelPtr no_data, unsigned int *p_in)
 {
-/* input: RGB    output: RGB */
-    int ret;
-    unsigned char *rgba = NULL;
-
-    if (format == RL2_OUTPUT_FORMAT_JPEG)
-      {
-	  if (rl2_rgb_to_jpeg (width, height, pixels, quality, image, image_sz)
-	      != RL2_OK)
-	      goto error;
-      }
-    else if (format == RL2_OUTPUT_FORMAT_PNG)
-      {
-	  if (rl2_rgb_to_png (width, height, pixels, image, image_sz) != RL2_OK)
-	      goto error;
-      }
-    else if (format == RL2_OUTPUT_FORMAT_TIFF)
+/* testing for NO-DATA - UINT32 */
+    if (no_data != NULL)
       {
-	  if (srid > 0)
-	    {
-		if (rl2_rgb_to_geotiff
-		    (width, height, handle, minx, miny, maxx, maxy, srid,
-		     pixels, image, image_sz) != RL2_OK)
-		    goto error;
-	    }
-	  else
+	  unsigned char band;
+	  int match = 0;
+	  rl2PrivSamplePtr sample;
+	  for (band = 0; band < no_data->nBands; band++)
 	    {
-		if (rl2_rgb_to_tiff (width, height, pixels, image, image_sz) !=
-		    RL2_OK)
-		    goto error;
+		sample = no_data->Samples + band;
+		if (*(p_in + band) == sample->uint32)
+		    match++;
 	    }
+	  if (match == no_data->nBands)
+	      return 1;
       }
-    else if (format == RL2_OUTPUT_FORMAT_PDF)
-      {
-	  rgba = rgb_to_rgba (width, height, pixels);
-	  if (rgba == NULL)
-	      goto error;
-	  ret = rl2_rgba_to_pdf (width, height, rgba, image, image_sz);
-	  rgba = NULL;
-	  if (ret != RL2_OK)
-	      goto error;
-      }
-    else
-	goto error;
-    free (pixels);
-    return 1;
-
-  error:
-    free (pixels);
-    if (rgba != NULL)
-	free (rgba);
     return 0;
 }
 
-RL2_PRIVATE int
-get_payload_from_rgb_transparent (unsigned int width, unsigned int height,
-				  unsigned char *pixels, unsigned char format,
-				  int quality, unsigned char **image,
-				  int *image_sz, unsigned char bg_red,
-				  unsigned char bg_green, unsigned char bg_blue,
-				  double opacity)
+static int
+test_no_data_flt (rl2PrivPixelPtr no_data, float *p_in)
 {
-/* input: RGB    output: RGB */
-    unsigned char *p_in;
-    unsigned char *p_msk;
-    unsigned char *mask = NULL;
-    unsigned int row;
-    unsigned int col;
-
-    if (quality > 100)
-	quality = 100;
-    mask = malloc (width * height);
-    if (mask == NULL)
-	goto error;
-    p_in = pixels;
-    p_msk = mask;
-    for (row = 0; row < height; row++)
+/* testing for NO-DATA - FLOAT */
+    if (no_data != NULL)
       {
-	  for (col = 0; col < width; col++)
+	  unsigned char band;
+	  int match = 0;
+	  rl2PrivSamplePtr sample;
+	  for (band = 0; band < no_data->nBands; band++)
 	    {
-		unsigned char red = *p_in++;
-		unsigned char green = *p_in++;
-		unsigned char blue = *p_in++;
-		if (red == bg_red && green == bg_green && blue == bg_blue)
-		    *p_msk++ = 0;	/* Transparent */
-		else
-		    *p_msk++ = 1;	/* Opaque */
+		sample = no_data->Samples + band;
+		if (*(p_in + band) == sample->float32)
+		    match++;
 	    }
+	  if (match == no_data->nBands)
+	      return 1;
       }
-    if (format == RL2_OUTPUT_FORMAT_PNG)
-      {
-	  if (rl2_rgb_alpha_to_png
-	      (width, height, pixels, mask, image, image_sz, opacity) != RL2_OK)
-	      goto error;
-      }
-    else
-	goto error;
-    free (pixels);
-    free (mask);
-    return 1;
-
-  error:
-    free (pixels);
-    if (mask != NULL)
-	free (mask);
     return 0;
 }
 
 static int
-test_no_data_8 (rl2PrivPixelPtr no_data, unsigned char *p_in)
+test_no_data_dbl (rl2PrivPixelPtr no_data, double *p_in)
 {
-/* testing for NO-DATA */
+/* testing for NO-DATA - DOUBLE */
     if (no_data != NULL)
       {
 	  unsigned char band;
@@ -1895,7 +2460,7 @@ test_no_data_8 (rl2PrivPixelPtr no_data, unsigned char *p_in)
 	  for (band = 0; band < no_data->nBands; band++)
 	    {
 		sample = no_data->Samples + band;
-		if (*(p_in + band) == sample->uint8)
+		if (*(p_in + band) == sample->float64)
 		    match++;
 	    }
 	  if (match == no_data->nBands)
@@ -1932,7 +2497,7 @@ get_rgba_from_monochrome_mask (unsigned int width, unsigned int height,
 			  transparent = 1;
 		  }
 		if (!transparent)
-		    transparent = test_no_data_8 (no_data, p_in);
+		    transparent = test_no_data_u8 (no_data, p_in);
 		if (transparent)
 		  {
 		      p_out += 4;
@@ -2066,7 +2631,7 @@ get_rgba_from_palette_mask (unsigned int width, unsigned int height,
 				transparent = 1;
 			}
 		      if (!transparent)
-			  transparent = test_no_data_8 (no_data, p_in);
+			  transparent = test_no_data_u8 (no_data, p_in);
 		      if (transparent)
 			{
 			    p_out += 4;
@@ -2211,8 +2776,9 @@ get_rgba_from_palette_opaque (unsigned int width, unsigned int height,
 
 RL2_PRIVATE int
 get_rgba_from_palette_transparent (unsigned int width, unsigned int height,
-				   unsigned char *pixels, rl2PalettePtr palette,
-				   unsigned char *rgba, unsigned char bg_red,
+				   unsigned char *pixels,
+				   rl2PalettePtr palette, unsigned char *rgba,
+				   unsigned char bg_red,
 				   unsigned char bg_green,
 				   unsigned char bg_blue)
 {
@@ -2316,7 +2882,7 @@ get_rgba_from_grayscale_mask (unsigned int width, unsigned int height,
 			  transparent = 1;
 		  }
 		if (!transparent)
-		    transparent = test_no_data_8 (no_data, p_in);
+		    transparent = test_no_data_u8 (no_data, p_in);
 		if (transparent)
 		  {
 		      p_out += 4;
@@ -2368,8 +2934,8 @@ get_rgba_from_grayscale_opaque (unsigned int width, unsigned int height,
 RL2_PRIVATE int
 get_rgba_from_grayscale_transparent (unsigned int width,
 				     unsigned int height,
-				     unsigned char *pixels, unsigned char *rgba,
-				     unsigned char bg_gray)
+				     unsigned char *pixels,
+				     unsigned char *rgba, unsigned char bg_gray)
 {
 /* input: Grayscale    output: Grayscale */
     unsigned char *p_in;
@@ -2424,7 +2990,7 @@ get_rgba_from_rgb_mask (unsigned int width, unsigned int height,
 			  transparent = 1;
 		  }
 		if (!transparent)
-		    transparent = test_no_data_8 (no_data, p_in);
+		    transparent = test_no_data_u8 (no_data, p_in);
 		if (transparent)
 		  {
 		      p_out += 4;
@@ -2507,7 +3073,8 @@ get_rgba_from_rgb_transparent (unsigned int width, unsigned int height,
 
 RL2_PRIVATE int
 rgba_from_int8 (unsigned int width, unsigned int height,
-		char *pixels, unsigned char *mask, unsigned char *rgba)
+		char *pixels, unsigned char *mask, rl2PrivPixelPtr no_data,
+		unsigned char *rgba)
 {
 /* input: DataGrid INT8   output: Grayscale */
     char *p_in;
@@ -2524,6 +3091,7 @@ rgba_from_int8 (unsigned int width, unsigned int height,
       {
 	  for (col = 0; col < width; col++)
 	    {
+		char *p_sv = p_in;
 		char gray = 128 + *p_in++;
 		transparent = 0;
 		if (p_msk != NULL)
@@ -2531,6 +3099,8 @@ rgba_from_int8 (unsigned int width, unsigned int height,
 		      if (*p_msk++ == 0)
 			  transparent = 1;
 		  }
+		if (!transparent)
+		    transparent = test_no_data_8 (no_data, p_sv);
 		if (transparent)
 		    p_out += 4;
 		else
@@ -2551,7 +3121,7 @@ rgba_from_int8 (unsigned int width, unsigned int height,
 RL2_PRIVATE int
 rgba_from_uint8 (unsigned int width, unsigned int height,
 		 unsigned char *pixels, unsigned char *mask,
-		 unsigned char *rgba)
+		 rl2PrivPixelPtr no_data, unsigned char *rgba)
 {
 /* input: DataGrid UINT8   output: Grayscale */
     unsigned char *p_in;
@@ -2568,6 +3138,7 @@ rgba_from_uint8 (unsigned int width, unsigned int height,
       {
 	  for (col = 0; col < width; col++)
 	    {
+		unsigned char *p_sv = p_in;
 		unsigned char gray = *p_in++;
 		transparent = 0;
 		if (p_msk != NULL)
@@ -2575,6 +3146,8 @@ rgba_from_uint8 (unsigned int width, unsigned int height,
 		      if (*p_msk++ == 0)
 			  transparent = 1;
 		  }
+		if (!transparent)
+		    transparent = test_no_data_u8 (no_data, p_sv);
 		if (transparent)
 		    p_out += 4;
 		else
@@ -2594,7 +3167,8 @@ rgba_from_uint8 (unsigned int width, unsigned int height,
 
 RL2_PRIVATE int
 rgba_from_int16 (unsigned int width, unsigned int height,
-		 short *pixels, unsigned char *mask, unsigned char *rgba)
+		 short *pixels, unsigned char *mask, rl2PrivPixelPtr no_data,
+		 unsigned char *rgba)
 {
 /* input: DataGrid INT16   output: Grayscale */
     short *p_in;
@@ -2604,8 +3178,8 @@ rgba_from_int16 (unsigned int width, unsigned int height,
     unsigned int col;
     short min = SHRT_MAX;
     short max = SHRT_MIN;
-    double min2;
-    double max2;
+    double min2 = 0.0;
+    double max2 = 0.0;
     double tic;
     double tic2;
     int transparent;
@@ -2623,12 +3197,15 @@ rgba_from_int16 (unsigned int width, unsigned int height,
       {
 	  for (col = 0; col < width; col++)
 	    {
+		short *p_sv = p_in;
 		short gray = *p_in++;
 		if (p_msk != NULL)
 		  {
 		      if (*p_msk++ == 0)
 			  continue;
 		  }
+		if (test_no_data_16 (no_data, p_sv))
+		    continue;
 		if (min > gray)
 		    min = gray;
 		if (max < gray)
@@ -2648,12 +3225,15 @@ rgba_from_int16 (unsigned int width, unsigned int height,
       {
 	  for (col = 0; col < width; col++)
 	    {
+		short *p_sv = p_in;
 		double gray = (double) (*p_in++ - min) / tic;
 		if (p_msk != NULL)
 		  {
 		      if (*p_msk++ == 0)
 			  continue;
 		  }
+		if (test_no_data_16 (no_data, p_sv))
+		    continue;
 		if (gray < 0.0)
 		    gray = 0.0;
 		if (gray > 1023.0)
@@ -2697,6 +3277,8 @@ rgba_from_int16 (unsigned int width, unsigned int height,
 		      if (*p_msk++ == 0)
 			  transparent = 1;
 		  }
+		if (!transparent)
+		    transparent = test_no_data_16 (no_data, p_in);
 		if (transparent)
 		  {
 		      p_in++;
@@ -2732,7 +3314,7 @@ rgba_from_int16 (unsigned int width, unsigned int height,
 RL2_PRIVATE int
 rgba_from_uint16 (unsigned int width, unsigned int height,
 		  unsigned short *pixels, unsigned char *mask,
-		  unsigned char *rgba)
+		  rl2PrivPixelPtr no_data, unsigned char *rgba)
 {
 /* input: DataGrid UINT16   output: Grayscale */
     unsigned short *p_in;
@@ -2742,8 +3324,154 @@ rgba_from_uint16 (unsigned int width, unsigned int height,
     unsigned int col;
     unsigned short min = USHRT_MAX;
     unsigned short max = 0;
-    double min2;
-    double max2;
+    double min2 = 0.0;
+    double max2 = 0.0;
+    double tic;
+    double tic2;
+    int transparent;
+    int i;
+    int sum;
+    int total;
+    double percentile2;
+    int histogram[1024];
+
+/* identifying Min/Max values */
+    total = 0;
+    p_in = pixels;
+    p_msk = mask;
+    for (row = 0; row < height; row++)
+      {
+	  for (col = 0; col < width; col++)
+	    {
+		unsigned short *p_sv = p_in;
+		unsigned short gray = *p_in++;
+		if (p_msk != NULL)
+		  {
+		      if (*p_msk++ == 0)
+			  continue;
+		  }
+		if (test_no_data_u16 (no_data, p_sv))
+		    continue;
+		if (min > gray)
+		    min = gray;
+		if (max < gray)
+		    max = gray;
+		total++;
+	    }
+      }
+    tic = (double) (max - min) / 1024.0;
+    percentile2 = ((double) total / 100.0) * 2.0;
+
+/* building an histogram */
+    for (i = 0; i < 1024; i++)
+	histogram[i] = 0;
+    p_in = pixels;
+    p_msk = mask;
+    for (row = 0; row < height; row++)
+      {
+	  for (col = 0; col < width; col++)
+	    {
+		unsigned short *p_sv = p_in;
+		double gray = (double) (*p_in++ - min) / tic;
+		if (p_msk != NULL)
+		  {
+		      if (*p_msk++ == 0)
+			  continue;
+		  }
+		if (test_no_data_u16 (no_data, p_sv))
+		    continue;
+		if (gray < 0.0)
+		    gray = 0.0;
+		if (gray > 1023.0)
+		    gray = 1023.0;
+		histogram[(int) gray] += 1;
+	    }
+      }
+    sum = 0;
+    for (i = 0; i < 1024; i++)
+      {
+	  sum += histogram[i];
+	  if (sum >= percentile2)
+	    {
+		min2 = (double) min + ((double) i * tic);
+		break;
+	    }
+      }
+    sum = 0;
+    for (i = 1023; i >= 0; i--)
+      {
+	  sum += histogram[i];
+	  if (sum >= percentile2)
+	    {
+		max2 = (double) min + ((double) (i + 1) * tic);
+		break;
+	    }
+      }
+    tic2 = (double) (max2 - min2) / 254.0;
+
+/* rescaling gray-values 0-255 */
+    p_in = pixels;
+    p_out = rgba;
+    p_msk = mask;
+    for (row = 0; row < height; row++)
+      {
+	  for (col = 0; col < width; col++)
+	    {
+		transparent = 0;
+		if (p_msk != NULL)
+		  {
+		      if (*p_msk++ == 0)
+			  transparent = 1;
+		  }
+		if (!transparent)
+		    transparent = test_no_data_u16 (no_data, p_in);
+		if (transparent)
+		  {
+		      p_in++;
+		      p_out += 4;
+		  }
+		else
+		  {
+		      double gray;
+		      unsigned short val = *p_in++;
+		      if (val <= min2)
+			  gray = 0.0;
+		      else if (val >= max2)
+			  gray = 255.0;
+		      else
+			  gray = 1.0 + (((double) val - min2) / tic2);
+		      if (gray < 0.0)
+			  gray = 0.0;
+		      if (gray > 255.0)
+			  gray = 255.0;
+		      *p_out++ = (unsigned char) gray;	/* red */
+		      *p_out++ = (unsigned char) gray;	/* green */
+		      *p_out++ = (unsigned char) gray;	/* blue */
+		      *p_out++ = 255;	/* opaque */
+		  }
+	    }
+      }
+    free (pixels);
+    if (mask != NULL)
+	free (mask);
+    return 1;
+}
+
+RL2_PRIVATE int
+rgba_from_int32 (unsigned int width, unsigned int height,
+		 int *pixels, unsigned char *mask, rl2PrivPixelPtr no_data,
+		 unsigned char *rgba)
+{
+/* input: DataGrid INT32   output: Grayscale */
+    int *p_in;
+    unsigned char *p_out;
+    unsigned char *p_msk;
+    unsigned int row;
+    unsigned int col;
+    int min = INT_MAX;
+    int max = INT_MIN;
+    double min2 = 0.0;
+    double max2 = 0.0;
     double tic;
     double tic2;
     int transparent;
@@ -2761,12 +3489,15 @@ rgba_from_uint16 (unsigned int width, unsigned int height,
       {
 	  for (col = 0; col < width; col++)
 	    {
-		unsigned short gray = *p_in++;
+		int *p_sv = p_in;
+		int gray = *p_in++;
 		if (p_msk != NULL)
 		  {
 		      if (*p_msk++ == 0)
 			  continue;
 		  }
+		if (test_no_data_32 (no_data, p_sv))
+		    continue;
 		if (min > gray)
 		    min = gray;
 		if (max < gray)
@@ -2786,12 +3517,15 @@ rgba_from_uint16 (unsigned int width, unsigned int height,
       {
 	  for (col = 0; col < width; col++)
 	    {
+		int *p_sv = p_in;
 		double gray = (double) (*p_in++ - min) / tic;
 		if (p_msk != NULL)
 		  {
 		      if (*p_msk++ == 0)
 			  continue;
 		  }
+		if (test_no_data_32 (no_data, p_sv))
+		    continue;
 		if (gray < 0.0)
 		    gray = 0.0;
 		if (gray > 1023.0)
@@ -2835,6 +3569,8 @@ rgba_from_uint16 (unsigned int width, unsigned int height,
 		      if (*p_msk++ == 0)
 			  transparent = 1;
 		  }
+		if (!transparent)
+		    transparent = test_no_data_32 (no_data, p_in);
 		if (transparent)
 		  {
 		      p_in++;
@@ -2843,7 +3579,7 @@ rgba_from_uint16 (unsigned int width, unsigned int height,
 		else
 		  {
 		      double gray;
-		      unsigned short val = *p_in++;
+		      int val = *p_in++;
 		      if (val <= min2)
 			  gray = 0.0;
 		      else if (val >= max2)
@@ -2868,19 +3604,20 @@ rgba_from_uint16 (unsigned int width, unsigned int height,
 }
 
 RL2_PRIVATE int
-rgba_from_int32 (unsigned int width, unsigned int height,
-		 int *pixels, unsigned char *mask, unsigned char *rgba)
+rgba_from_uint32 (unsigned int width, unsigned int height,
+		  unsigned int *pixels, unsigned char *mask,
+		  rl2PrivPixelPtr no_data, unsigned char *rgba)
 {
-/* input: DataGrid INT32   output: Grayscale */
-    int *p_in;
+/* input: DataGrid UINT32   output: Grayscale */
+    unsigned int *p_in;
     unsigned char *p_out;
     unsigned char *p_msk;
     unsigned int row;
     unsigned int col;
-    int min = INT_MAX;
-    int max = INT_MIN;
-    double min2;
-    double max2;
+    unsigned int min = UINT_MAX;
+    unsigned int max = 0;
+    double min2 = 0.0;
+    double max2 = 0.0;
     double tic;
     double tic2;
     int transparent;
@@ -2898,12 +3635,15 @@ rgba_from_int32 (unsigned int width, unsigned int height,
       {
 	  for (col = 0; col < width; col++)
 	    {
-		int gray = *p_in++;
+		unsigned int *p_sv = p_in;
+		unsigned int gray = *p_in++;
 		if (p_msk != NULL)
 		  {
 		      if (*p_msk++ == 0)
 			  continue;
 		  }
+		if (test_no_data_u32 (no_data, p_sv))
+		    continue;
 		if (min > gray)
 		    min = gray;
 		if (max < gray)
@@ -2923,12 +3663,15 @@ rgba_from_int32 (unsigned int width, unsigned int height,
       {
 	  for (col = 0; col < width; col++)
 	    {
+		unsigned int *p_sv = p_in;
 		double gray = (double) (*p_in++ - min) / tic;
 		if (p_msk != NULL)
 		  {
 		      if (*p_msk++ == 0)
 			  continue;
 		  }
+		if (test_no_data_u32 (no_data, p_sv))
+		    continue;
 		if (gray < 0.0)
 		    gray = 0.0;
 		if (gray > 1023.0)
@@ -2972,6 +3715,8 @@ rgba_from_int32 (unsigned int width, unsigned int height,
 		      if (*p_msk++ == 0)
 			  transparent = 1;
 		  }
+		if (!transparent)
+		    transparent = test_no_data_u32 (no_data, p_in);
 		if (transparent)
 		  {
 		      p_in++;
@@ -2980,7 +3725,7 @@ rgba_from_int32 (unsigned int width, unsigned int height,
 		else
 		  {
 		      double gray;
-		      int val = *p_in++;
+		      unsigned int val = *p_in++;
 		      if (val <= min2)
 			  gray = 0.0;
 		      else if (val >= max2)
@@ -3005,20 +3750,20 @@ rgba_from_int32 (unsigned int width, unsigned int height,
 }
 
 RL2_PRIVATE int
-rgba_from_uint32 (unsigned int width, unsigned int height,
-		  unsigned int *pixels, unsigned char *mask,
-		  unsigned char *rgba)
+rgba_from_float (unsigned int width, unsigned int height,
+		 float *pixels, unsigned char *mask, rl2PrivPixelPtr no_data,
+		 unsigned char *rgba)
 {
-/* input: DataGrid UINT32   output: Grayscale */
-    unsigned int *p_in;
+/* input: DataGrid FLOAT   output: Grayscale */
+    float *p_in;
     unsigned char *p_out;
     unsigned char *p_msk;
     unsigned int row;
     unsigned int col;
-    unsigned int min = UINT_MAX;
-    unsigned int max = 0;
-    double min2;
-    double max2;
+    float min = FLT_MAX;
+    float max = 0.0 - FLT_MAX;
+    double min2 = 0.0;
+    double max2 = 0.0;
     double tic;
     double tic2;
     int transparent;
@@ -3036,12 +3781,15 @@ rgba_from_uint32 (unsigned int width, unsigned int height,
       {
 	  for (col = 0; col < width; col++)
 	    {
-		unsigned int gray = *p_in++;
+		float *p_sv = p_in;
+		float gray = *p_in++;
 		if (p_msk != NULL)
 		  {
 		      if (*p_msk++ == 0)
 			  continue;
 		  }
+		if (test_no_data_flt (no_data, p_sv))
+		    continue;
 		if (min > gray)
 		    min = gray;
 		if (max < gray)
@@ -3061,12 +3809,15 @@ rgba_from_uint32 (unsigned int width, unsigned int height,
       {
 	  for (col = 0; col < width; col++)
 	    {
+		float *p_sv = p_in;
 		double gray = (double) (*p_in++ - min) / tic;
 		if (p_msk != NULL)
 		  {
 		      if (*p_msk++ == 0)
 			  continue;
 		  }
+		if (test_no_data_flt (no_data, p_sv))
+		    continue;
 		if (gray < 0.0)
 		    gray = 0.0;
 		if (gray > 1023.0)
@@ -3110,6 +3861,8 @@ rgba_from_uint32 (unsigned int width, unsigned int height,
 		      if (*p_msk++ == 0)
 			  transparent = 1;
 		  }
+		if (!transparent)
+		    transparent = test_no_data_flt (no_data, p_in);
 		if (transparent)
 		  {
 		      p_in++;
@@ -3118,7 +3871,7 @@ rgba_from_uint32 (unsigned int width, unsigned int height,
 		else
 		  {
 		      double gray;
-		      unsigned int val = *p_in++;
+		      float val = *p_in++;
 		      if (val <= min2)
 			  gray = 0.0;
 		      else if (val >= max2)
@@ -3143,19 +3896,20 @@ rgba_from_uint32 (unsigned int width, unsigned int height,
 }
 
 RL2_PRIVATE int
-rgba_from_float (unsigned int width, unsigned int height,
-		 float *pixels, unsigned char *mask, unsigned char *rgba)
+rgba_from_double (unsigned int width, unsigned int height,
+		  double *pixels, unsigned char *mask,
+		  rl2PrivPixelPtr no_data, unsigned char *rgba)
 {
-/* input: DataGrid FLOAT   output: Grayscale */
-    float *p_in;
+/* input: DataGrid DOUBLE   output: Grayscale */
+    double *p_in;
     unsigned char *p_out;
     unsigned char *p_msk;
     unsigned int row;
     unsigned int col;
-    float min = FLT_MAX;
-    float max = 0.0 - FLT_MAX;
-    double min2;
-    double max2;
+    double min = DBL_MAX;
+    double max = 0.0 - DBL_MAX;
+    double min2 = 0.0;
+    double max2 = 0.0;
     double tic;
     double tic2;
     int transparent;
@@ -3173,12 +3927,15 @@ rgba_from_float (unsigned int width, unsigned int height,
       {
 	  for (col = 0; col < width; col++)
 	    {
-		float gray = *p_in++;
+		double *p_sv = p_in;
+		double gray = *p_in++;
 		if (p_msk != NULL)
 		  {
 		      if (*p_msk++ == 0)
 			  continue;
 		  }
+		if (test_no_data_dbl (no_data, p_sv))
+		    continue;
 		if (min > gray)
 		    min = gray;
 		if (max < gray)
@@ -3198,12 +3955,15 @@ rgba_from_float (unsigned int width, unsigned int height,
       {
 	  for (col = 0; col < width; col++)
 	    {
+		double *p_sv = p_in;
 		double gray = (double) (*p_in++ - min) / tic;
 		if (p_msk != NULL)
 		  {
 		      if (*p_msk++ == 0)
 			  continue;
 		  }
+		if (test_no_data_dbl (no_data, p_sv))
+		    continue;
 		if (gray < 0.0)
 		    gray = 0.0;
 		if (gray > 1023.0)
@@ -3247,6 +4007,8 @@ rgba_from_float (unsigned int width, unsigned int height,
 		      if (*p_msk++ == 0)
 			  transparent = 1;
 		  }
+		if (!transparent)
+		    transparent = test_no_data_dbl (no_data, p_in);
 		if (transparent)
 		  {
 		      p_in++;
@@ -3255,7 +4017,7 @@ rgba_from_float (unsigned int width, unsigned int height,
 		else
 		  {
 		      double gray;
-		      float val = *p_in++;
+		      double val = *p_in++;
 		      if (val <= min2)
 			  gray = 0.0;
 		      else if (val >= max2)
@@ -3280,19 +4042,124 @@ rgba_from_float (unsigned int width, unsigned int height,
 }
 
 RL2_PRIVATE int
-rgba_from_double (unsigned int width, unsigned int height,
-		  double *pixels, unsigned char *mask, unsigned char *rgba)
+get_rgba_from_datagrid_mask (unsigned int width, unsigned int height,
+			     unsigned char sample_type, void *pixels,
+			     unsigned char *mask, rl2PrivPixelPtr no_data,
+			     unsigned char *rgba)
 {
-/* input: DataGrid DOUBLE   output: Grayscale */
-    double *p_in;
+/* input: DataGrid    output: Grayscale */
+    int ret = 0;
+    switch (sample_type)
+      {
+      case RL2_SAMPLE_INT8:
+	  ret =
+	      rgba_from_int8 (width, height, (char *) pixels, mask, no_data,
+			      rgba);
+	  break;
+      case RL2_SAMPLE_UINT8:
+	  ret =
+	      rgba_from_uint8 (width, height, (unsigned char *) pixels, mask,
+			       no_data, rgba);
+	  break;
+      case RL2_SAMPLE_INT16:
+	  ret =
+	      rgba_from_int16 (width, height, (short *) pixels, mask, no_data,
+			       rgba);
+	  break;
+      case RL2_SAMPLE_UINT16:
+	  ret =
+	      rgba_from_uint16 (width, height, (unsigned short *) pixels,
+				mask, no_data, rgba);
+	  break;
+      case RL2_SAMPLE_INT32:
+	  ret =
+	      rgba_from_int32 (width, height, (int *) pixels, mask, no_data,
+			       rgba);
+	  break;
+      case RL2_SAMPLE_UINT32:
+	  ret =
+	      rgba_from_uint32 (width, height, (unsigned int *) pixels, mask,
+				no_data, rgba);
+	  break;
+      case RL2_SAMPLE_FLOAT:
+	  ret =
+	      rgba_from_float (width, height, (float *) pixels, mask, no_data,
+			       rgba);
+	  break;
+      case RL2_SAMPLE_DOUBLE:
+	  ret =
+	      rgba_from_double (width, height, (double *) pixels, mask,
+				no_data, rgba);
+	  break;
+      };
+    return ret;
+}
+
+RL2_PRIVATE int
+rgba_from_multi_uint8 (unsigned int width, unsigned int height,
+		       unsigned char num_bands, unsigned char *pixels,
+		       unsigned char *mask, rl2PrivPixelPtr no_data,
+		       unsigned char *rgba)
+{
+/* input: MultiBand UINT8   output: Grayscale */
+    unsigned char *p_in;
     unsigned char *p_out;
     unsigned char *p_msk;
     unsigned int row;
     unsigned int col;
-    double min = DBL_MAX;
-    double max = 0.0 - DBL_MAX;
-    double min2;
-    double max2;
+    int transparent;
+
+    p_in = pixels;
+    p_out = rgba;
+    p_msk = mask;
+    for (row = 0; row < height; row++)
+      {
+	  for (col = 0; col < width; col++)
+	    {
+		unsigned char *p_sv = p_in;
+		unsigned char gray = *p_in;	/* considering only Band #0 */
+		p_in += num_bands;
+		transparent = 0;
+		if (p_msk != NULL)
+		  {
+		      if (*p_msk++ == 0)
+			  transparent = 1;
+		  }
+		if (!transparent)
+		    transparent = test_no_data_u8 (no_data, p_sv);
+		if (transparent)
+		    p_out += 4;
+		else
+		  {
+		      *p_out++ = gray;	/* red */
+		      *p_out++ = gray;	/* green */
+		      *p_out++ = gray;	/* blue */
+		      *p_out++ = 255;	/* opaque */
+		  }
+	    }
+      }
+    free (pixels);
+    if (mask != NULL)
+	free (mask);
+    return 1;
+}
+
+RL2_PRIVATE int
+rgba_from_multi_uint16 (unsigned int width, unsigned int height,
+			unsigned char num_bands, unsigned short *pixels,
+			unsigned char *mask, rl2PrivPixelPtr no_data,
+			unsigned char *rgba)
+{
+/* input: MultiBand UINT16   output: Grayscale */
+    unsigned short *p_in;
+    unsigned char *p_out;
+    unsigned char *p_msk;
+    unsigned int row;
+    unsigned int col;
+    unsigned short min = USHRT_MAX;
+    unsigned short max = 0;
+    double min2 = 0.0;
+    double max2 = 0.0;
     double tic;
     double tic2;
     int transparent;
@@ -3310,12 +4177,16 @@ rgba_from_double (unsigned int width, unsigned int height,
       {
 	  for (col = 0; col < width; col++)
 	    {
-		double gray = *p_in++;
+		unsigned short *p_sv = p_in;
+		unsigned short gray = *p_in;	/* considering only Band #0 */
+		p_in += num_bands;
 		if (p_msk != NULL)
 		  {
 		      if (*p_msk++ == 0)
 			  continue;
 		  }
+		if (test_no_data_u16 (no_data, p_sv))
+		    continue;
 		if (min > gray)
 		    min = gray;
 		if (max < gray)
@@ -3335,12 +4206,16 @@ rgba_from_double (unsigned int width, unsigned int height,
       {
 	  for (col = 0; col < width; col++)
 	    {
-		double gray = (double) (*p_in++ - min) / tic;
+		unsigned short *p_sv = p_in;
+		double gray = (double) (*p_in - min) / tic;
+		p_in += num_bands;
 		if (p_msk != NULL)
 		  {
 		      if (*p_msk++ == 0)
 			  continue;
 		  }
+		if (test_no_data_u16 (no_data, p_sv))
+		    continue;
 		if (gray < 0.0)
 		    gray = 0.0;
 		if (gray > 1023.0)
@@ -3384,15 +4259,18 @@ rgba_from_double (unsigned int width, unsigned int height,
 		      if (*p_msk++ == 0)
 			  transparent = 1;
 		  }
+		if (!transparent)
+		    transparent = test_no_data_u16 (no_data, p_in);
 		if (transparent)
 		  {
-		      p_in++;
+		      p_in += num_bands;
 		      p_out += 4;
 		  }
 		else
 		  {
 		      double gray;
-		      double val = *p_in++;
+		      unsigned short val = *p_in;
+		      p_in += num_bands;	/* considering only Band #0 */
 		      if (val <= min2)
 			  gray = 0.0;
 		      else if (val >= max2)
@@ -3417,44 +4295,27 @@ rgba_from_double (unsigned int width, unsigned int height,
 }
 
 RL2_PRIVATE int
-get_rgba_from_datagrid_mask (unsigned int width, unsigned int height,
-			     unsigned char sample_type, void *pixels,
-			     unsigned char *mask, rl2PrivPixelPtr no_data,
-			     unsigned char *rgba)
+get_rgba_from_multiband_mask (unsigned int width, unsigned int height,
+			      unsigned char sample_type,
+			      unsigned char num_bands, void *pixels,
+			      unsigned char *mask, rl2PrivPixelPtr no_data,
+			      unsigned char *rgba)
 {
-/* input: DataGrid    output: Grayscale */
+/* input: MultiBand    output: Grayscale */
     int ret = 0;
     switch (sample_type)
       {
-      case RL2_SAMPLE_INT8:
-	  ret = rgba_from_int8 (width, height, (char *) pixels, mask, rgba);
-	  break;
       case RL2_SAMPLE_UINT8:
 	  ret =
-	      rgba_from_uint8 (width, height, (unsigned char *) pixels, mask,
-			       rgba);
-	  break;
-      case RL2_SAMPLE_INT16:
-	  ret = rgba_from_int16 (width, height, (short *) pixels, mask, rgba);
+	      rgba_from_multi_uint8 (width, height, num_bands,
+				     (unsigned char *) pixels, mask, no_data,
+				     rgba);
 	  break;
       case RL2_SAMPLE_UINT16:
 	  ret =
-	      rgba_from_uint16 (width, height, (unsigned short *) pixels, mask,
-				rgba);
-	  break;
-      case RL2_SAMPLE_INT32:
-	  ret = rgba_from_int32 (width, height, (int *) pixels, mask, rgba);
-	  break;
-      case RL2_SAMPLE_UINT32:
-	  ret =
-	      rgba_from_uint32 (width, height, (unsigned int *) pixels, mask,
-				rgba);
-	  break;
-      case RL2_SAMPLE_FLOAT:
-	  ret = rgba_from_float (width, height, (float *) pixels, mask, rgba);
-	  break;
-      case RL2_SAMPLE_DOUBLE:
-	  ret = rgba_from_double (width, height, (double *) pixels, mask, rgba);
+	      rgba_from_multi_uint16 (width, height, num_bands,
+				      (unsigned short *) pixels, mask,
+				      no_data, rgba);
 	  break;
       };
     return ret;
@@ -3489,8 +4350,6 @@ get_payload_from_gray_rgba_opaque (unsigned int width, unsigned int height,
 		p_in += 2;
 	    }
       }
-    free (rgb);
-    rgb = NULL;
     if (format == RL2_OUTPUT_FORMAT_JPEG)
       {
 	  if (rl2_gray_to_jpeg (width, height, gray, quality, image, image_sz)
@@ -3507,8 +4366,8 @@ get_payload_from_gray_rgba_opaque (unsigned int width, unsigned int height,
 	  if (srid > 0)
 	    {
 		if (rl2_gray_to_geotiff
-		    (width, height, handle, minx, miny, maxx, maxy, srid, gray,
-		     image, image_sz) != RL2_OK)
+		    (width, height, handle, minx, miny, maxx, maxy, srid,
+		     gray, image, image_sz) != RL2_OK)
 		    goto error;
 	    }
 	  else
@@ -3533,7 +4392,6 @@ get_payload_from_gray_rgba_opaque (unsigned int width, unsigned int height,
     free (gray);
     return 1;
   error:
-    free (rgb);
     if (gray != NULL)
 	free (gray);
     if (rgba != NULL)
@@ -3582,10 +4440,6 @@ get_payload_from_gray_rgba_transparent (unsigned int width,
 		    *p_msk++ = 0;	/* Transparent */
 	    }
       }
-    free (rgb);
-    rgb = NULL;
-    free (alpha);
-    alpha = NULL;
     if (format == RL2_OUTPUT_FORMAT_PNG)
       {
 	  if (rl2_gray_alpha_to_png
@@ -3598,7 +4452,6 @@ get_payload_from_gray_rgba_transparent (unsigned int width,
     free (mask);
     return 1;
   error:
-    free (rgb);
     if (gray != NULL)
 	free (gray);
     if (mask != NULL)
@@ -3620,8 +4473,8 @@ get_payload_from_rgb_rgba_opaque (unsigned int width, unsigned int height,
 
     if (format == RL2_OUTPUT_FORMAT_JPEG)
       {
-	  if (rl2_rgb_to_jpeg (width, height, rgb, quality, image, image_sz) !=
-	      RL2_OK)
+	  if (rl2_rgb_to_jpeg (width, height, rgb, quality, image, image_sz)
+	      != RL2_OK)
 	      goto error;
       }
     else if (format == RL2_OUTPUT_FORMAT_PNG)
@@ -3657,10 +4510,8 @@ get_payload_from_rgb_rgba_opaque (unsigned int width, unsigned int height,
       }
     else
 	goto error;
-    free (rgb);
     return 1;
   error:
-    free (rgb);
     if (rgba != NULL)
 	free (rgba);
     return 0;
@@ -3669,12 +4520,14 @@ get_payload_from_rgb_rgba_opaque (unsigned int width, unsigned int height,
 RL2_PRIVATE int
 get_payload_from_rgb_rgba_transparent (unsigned int width,
 				       unsigned int height,
-				       unsigned char *rgb, unsigned char *alpha,
+				       unsigned char *rgb,
+				       unsigned char *alpha,
 				       unsigned char format, int quality,
 				       unsigned char **image, int *image_sz,
-				       double opacity)
+				       double opacity, int half_transparency)
 {
 /* RGB, Transparent */
+    int ret;
     unsigned char *p_msk;
     unsigned char *p_alpha;
     unsigned int row;
@@ -3697,21 +4550,24 @@ get_payload_from_rgb_rgba_transparent (unsigned int width,
 		    *p_msk++ = 0;	/* Transparent */
 	    }
       }
-    free (alpha);
-    alpha = NULL;
     if (format == RL2_OUTPUT_FORMAT_PNG)
       {
-	  if (rl2_rgb_alpha_to_png
-	      (width, height, rgb, mask, image, image_sz, opacity) != RL2_OK)
+	  if (half_transparency)
+	      ret =
+		  rl2_rgb_real_alpha_to_png (width, height, rgb, alpha, image,
+					     image_sz);
+	  else
+	      ret =
+		  rl2_rgb_alpha_to_png (width, height, rgb, mask, image,
+					image_sz, opacity);
+	  if (ret != RL2_OK)
 	      goto error;
       }
     else
 	goto error;
-    free (rgb);
     free (mask);
     return 1;
   error:
-    free (rgb);
     if (mask != NULL)
 	free (mask);
     return 0;
@@ -3848,27 +4704,6 @@ get_rgba_from_multiband8 (unsigned int width, unsigned int height,
     return 1;
 }
 
-static int
-test_no_data_16 (rl2PrivPixelPtr no_data, unsigned short *p_in)
-{
-/* testing for NO-DATA */
-    if (no_data != NULL)
-      {
-	  unsigned char band;
-	  int match = 0;
-	  rl2PrivSamplePtr sample;
-	  for (band = 0; band < no_data->nBands; band++)
-	    {
-		sample = no_data->Samples + band;
-		if (*(p_in + band) == sample->uint16)
-		    match++;
-	    }
-	  if (match == no_data->nBands)
-	      return 1;
-      }
-    return 0;
-}
-
 RL2_PRIVATE int
 get_rgba_from_multiband16 (unsigned int width, unsigned int height,
 			   unsigned char red_band, unsigned char green_band,
@@ -3886,14 +4721,14 @@ get_rgba_from_multiband16 (unsigned int width, unsigned int height,
     unsigned short min = USHRT_MAX;
     unsigned short max = 0;
     double tic;
-    double red_min;
-    double red_max;
+    double red_min = DBL_MAX;
+    double red_max = 0.0 - DBL_MAX;
     double red_tic;
-    double green_min;
-    double green_max;
+    double green_min = DBL_MAX;
+    double green_max = 0.0 - DBL_MAX;
     double green_tic;
-    double blue_min;
-    double blue_max;
+    double blue_min = DBL_MAX;
+    double blue_max = 0.0 - DBL_MAX;
     double blue_tic;
     int i;
     int sum;
@@ -3918,7 +4753,7 @@ get_rgba_from_multiband16 (unsigned int width, unsigned int height,
 			    continue;
 			}
 		  }
-		if (test_no_data_16 (no_data, p_in))
+		if (test_no_data_u16 (no_data, p_in))
 		  {
 		      p_in += num_bands;
 		      continue;
@@ -3956,7 +4791,7 @@ get_rgba_from_multiband16 (unsigned int width, unsigned int height,
 			    continue;
 			}
 		  }
-		if (test_no_data_16 (no_data, p_in))
+		if (test_no_data_u16 (no_data, p_in))
 		  {
 		      p_in += num_bands;
 		      continue;
@@ -4012,7 +4847,7 @@ get_rgba_from_multiband16 (unsigned int width, unsigned int height,
 			    continue;
 			}
 		  }
-		if (test_no_data_16 (no_data, p_in))
+		if (test_no_data_u16 (no_data, p_in))
 		  {
 		      p_in += num_bands;
 		      continue;
@@ -4050,7 +4885,7 @@ get_rgba_from_multiband16 (unsigned int width, unsigned int height,
 			    continue;
 			}
 		  }
-		if (test_no_data_16 (no_data, p_in))
+		if (test_no_data_u16 (no_data, p_in))
 		  {
 		      p_in += num_bands;
 		      continue;
@@ -4106,7 +4941,7 @@ get_rgba_from_multiband16 (unsigned int width, unsigned int height,
 			    continue;
 			}
 		  }
-		if (test_no_data_16 (no_data, p_in))
+		if (test_no_data_u16 (no_data, p_in))
 		  {
 		      p_in += num_bands;
 		      continue;
@@ -4144,7 +4979,7 @@ get_rgba_from_multiband16 (unsigned int width, unsigned int height,
 			    continue;
 			}
 		  }
-		if (test_no_data_16 (no_data, p_in))
+		if (test_no_data_u16 (no_data, p_in))
 		  {
 		      p_in += num_bands;
 		      continue;
@@ -4198,7 +5033,7 @@ get_rgba_from_multiband16 (unsigned int width, unsigned int height,
 		      if (*p_msk++ == 0)
 			  transparent = 1;
 		  }
-		if (test_no_data_16 (no_data, p_in))
+		if (test_no_data_u16 (no_data, p_in))
 		    transparent = 1;
 		if (transparent)
 		  {
@@ -4314,8 +5149,11 @@ get_raster_band_histogram (rl2PrivBandStatisticsPtr band,
       }
     if (rl2_data_to_png
 	(raster, NULL, 1.0, NULL, width, height, RL2_SAMPLE_UINT8,
-	 RL2_PIXEL_GRAYSCALE, image, image_sz) == RL2_OK)
-	return RL2_OK;
+	 RL2_PIXEL_GRAYSCALE, 1, image, image_sz) == RL2_OK)
+      {
+	  free (raster);
+	  return RL2_OK;
+      }
     free (raster);
     return RL2_ERROR;
 }
@@ -4331,9 +5169,9 @@ set_coverage_infos (sqlite3 * sqlite, const char *coverage_name,
     int exists = 0;
     int retval = 0;
 
-    /* checking if the Group already exists */
+/* checking if the Coverage already exists */
     sql = "SELECT coverage_name FROM raster_coverages "
-	"WHERE coverage_name = Lower(?)";
+	"WHERE Lower(coverage_name) = Lower(?)";
     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
       {
@@ -4358,9 +5196,9 @@ set_coverage_infos (sqlite3 * sqlite, const char *coverage_name,
 
     if (!exists)
 	return 0;
-    /* update Coverage */
-    sql =
-	"UPDATE raster_coverages SET title = ?, abstract = ? WHERE coverage_name = ?";
+/* updating the Coverage */
+    sql = "UPDATE raster_coverages SET title = ?, abstract = ? "
+	"WHERE Lower(coverage_name) = Lower(?)";
     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
       {
@@ -4408,3 +5246,106 @@ rl2_test_layer_group (sqlite3 * handle, const char *name)
     sqlite3_free_table (results);
     return ok;
 }
+
+RL2_PRIVATE int
+rl2_is_mixed_resolutions_coverage (sqlite3 * handle, const char *coverage)
+{
+/* querying the Coverage Policies defs */
+    char *sql;
+    int ret;
+    sqlite3_stmt *stmt;
+    int value = -1;
+    sql =
+	"SELECT mixed_resolutions "
+	"FROM raster_coverages WHERE Lower(coverage_name) = Lower(?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "SQL error: %s\n%s\n", sql, sqlite3_errmsg (handle));
+	  return value;
+      }
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
+    while (1)
+      {
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		if (sqlite3_column_type (stmt, 0) == SQLITE_INTEGER)
+		    value = sqlite3_column_int (stmt, 0);
+	    }
+      }
+    sqlite3_finalize (stmt);
+    return value;
+}
+
+RL2_PRIVATE char *
+rl2_double_quoted_sql (const char *value)
+{
+/*
+/ returns a well formatted TEXT value for SQL
+/ 1] strips trailing spaces
+/ 2] masks any QUOTE inside the string, appending another QUOTE
+*/
+    const char *p_in;
+    const char *p_end;
+    char qt = '"';
+    char *out;
+    char *p_out;
+    int len = 0;
+    int i;
+
+    if (!value)
+	return NULL;
+
+    p_end = value;
+    for (i = (strlen (value) - 1); i >= 0; i--)
+      {
+	  /* stripping trailing spaces */
+	  p_end = value + i;
+	  if (value[i] != ' ')
+	      break;
+      }
+
+    p_in = value;
+    while (p_in <= p_end)
+      {
+	  /* computing the output length */
+	  len++;
+	  if (*p_in == qt)
+	      len++;
+	  p_in++;
+      }
+    if (len == 1 && *value == ' ')
+      {
+	  /* empty string */
+	  len = 0;
+      }
+
+    out = malloc (len + 1);
+    if (!out)
+	return NULL;
+
+    if (len == 0)
+      {
+	  /* empty string */
+	  *out = '\0';
+	  return out;
+      }
+
+    p_out = out;
+    p_in = value;
+    while (p_in <= p_end)
+      {
+	  /* creating the output string */
+	  if (*p_in == qt)
+	      *p_out++ = qt;
+	  *p_out++ = *p_in++;
+      }
+    *p_out = '\0';
+    return out;
+}
diff --git a/src/rl2svg.c b/src/rl2svg.c
index 6d5c4e4..7dacc86 100644
--- a/src/rl2svg.c
+++ b/src/rl2svg.c
@@ -20,7 +20,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -231,8 +231,10 @@ svg_set_pen (cairo_t * cairo, rl2PrivSvgStylePtr style)
 		stop = grad->first_stop;
 		while (stop)
 		  {
-		      cairo_pattern_add_color_stop_rgba (pattern, stop->offset,
-							 stop->red, stop->green,
+		      cairo_pattern_add_color_stop_rgba (pattern,
+							 stop->offset,
+							 stop->red,
+							 stop->green,
 							 stop->blue,
 							 stop->opacity *
 							 style->opacity);
@@ -261,8 +263,10 @@ svg_set_pen (cairo_t * cairo, rl2PrivSvgStylePtr style)
 		stop = grad->first_stop;
 		while (stop)
 		  {
-		      cairo_pattern_add_color_stop_rgba (pattern, stop->offset,
-							 stop->red, stop->green,
+		      cairo_pattern_add_color_stop_rgba (pattern,
+							 stop->offset,
+							 stop->red,
+							 stop->green,
 							 stop->blue,
 							 stop->opacity *
 							 style->opacity);
@@ -292,8 +296,8 @@ svg_set_pen (cairo_t * cairo, rl2PrivSvgStylePtr style)
     if (style->stroke_dashitems == 0 || style->stroke_dasharray == NULL)
 	cairo_set_dash (cairo, lengths, 0, 0.0);
     else
-	cairo_set_dash (cairo, style->stroke_dasharray, style->stroke_dashitems,
-			style->stroke_dashoffset);
+	cairo_set_dash (cairo, style->stroke_dasharray,
+			style->stroke_dashitems, style->stroke_dashoffset);
 }
 
 static void
@@ -314,8 +318,10 @@ svg_set_brush (cairo_t * cairo, rl2PrivSvgStylePtr style)
 		stop = grad->first_stop;
 		while (stop)
 		  {
-		      cairo_pattern_add_color_stop_rgba (pattern, stop->offset,
-							 stop->red, stop->green,
+		      cairo_pattern_add_color_stop_rgba (pattern,
+							 stop->offset,
+							 stop->red,
+							 stop->green,
 							 stop->blue,
 							 stop->opacity *
 							 style->opacity);
@@ -334,8 +340,10 @@ svg_set_brush (cairo_t * cairo, rl2PrivSvgStylePtr style)
 		stop = grad->first_stop;
 		while (stop)
 		  {
-		      cairo_pattern_add_color_stop_rgba (pattern, stop->offset,
-							 stop->red, stop->green,
+		      cairo_pattern_add_color_stop_rgba (pattern,
+							 stop->offset,
+							 stop->red,
+							 stop->green,
 							 stop->blue,
 							 stop->opacity *
 							 style->opacity);
@@ -850,11 +858,13 @@ svg_draw_path (cairo_t * cairo, rl2PrivSvgShapePtr shape,
 	    case RL2_SVG_CURVE_4:
 		bezier = item->data;
 		cairo_get_current_point (cairo, &x0, &y0);
-		cairo_curve_to (cairo, 2.0 / 3.0 * bezier->x1 + 1.0 / 3.0 * x0,
+		cairo_curve_to (cairo,
+				2.0 / 3.0 * bezier->x1 + 1.0 / 3.0 * x0,
 				2.0 / 3.0 * bezier->y1 + 1.0 / 3.0 * y0,
-				2.0 / 3.0 * bezier->x1 + 1.0 / 3.0 * bezier->x2,
-				2.0 / 3.0 * bezier->y1 + 1.0 / 3.0 * bezier->y2,
-				bezier->y1, bezier->y2);
+				2.0 / 3.0 * bezier->x1 +
+				1.0 / 3.0 * bezier->x2,
+				2.0 / 3.0 * bezier->y1 +
+				1.0 / 3.0 * bezier->y2, bezier->y1, bezier->y2);
 		break;
 	    case RL2_SVG_ELLIPT_ARC:
 		arc = item->data;
@@ -947,11 +957,13 @@ svg_clip_path (cairo_t * cairo, rl2PrivSvgShapePtr shape)
 	    case RL2_SVG_CURVE_4:
 		bezier = item->data;
 		cairo_get_current_point (cairo, &x0, &y0);
-		cairo_curve_to (cairo, 2.0 / 3.0 * bezier->x1 + 1.0 / 3.0 * x0,
+		cairo_curve_to (cairo,
+				2.0 / 3.0 * bezier->x1 + 1.0 / 3.0 * x0,
 				2.0 / 3.0 * bezier->y1 + 1.0 / 3.0 * y0,
-				2.0 / 3.0 * bezier->x1 + 1.0 / 3.0 * bezier->x2,
-				2.0 / 3.0 * bezier->y1 + 1.0 / 3.0 * bezier->y2,
-				bezier->y1, bezier->y2);
+				2.0 / 3.0 * bezier->x1 +
+				1.0 / 3.0 * bezier->x2,
+				2.0 / 3.0 * bezier->y1 +
+				1.0 / 3.0 * bezier->y2, bezier->y1, bezier->y2);
 		break;
 	    case RL2_SVG_ELLIPT_ARC:
 		arc = item->data;
@@ -1634,7 +1646,7 @@ svg_resolve_gradients_xlink_href (rl2PrivSvgDocumentPtr svg_doc)
 {
 /* resolving any indirect reference: Gradient xlink:href */
     rl2PrivSvgGradientPtr grad = svg_doc->first_grad;
-    rl2PrivSvgGradientPtr ret;
+    rl2PrivSvgGradientPtr ret = NULL;
 
     while (grad)
       {
diff --git a/src/rl2svgaux.c b/src/rl2svgaux.c
index 7b8eb16..5da103d 100644
--- a/src/rl2svgaux.c
+++ b/src/rl2svgaux.c
@@ -20,7 +20,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
diff --git a/src/rl2svgxml.c b/src/rl2svgxml.c
index bc67c67..e1164a2 100644
--- a/src/rl2svgxml.c
+++ b/src/rl2svgxml.c
@@ -20,7 +20,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -469,8 +469,8 @@ svg_parse_path_d (rl2PrivSvgPathPtr path, const char *value)
     double first_y = DBL_MAX;
     double last_x = DBL_MAX;
     double last_y = DBL_MAX;
-    double bezier_reflect_x;
-    double bezier_reflect_y;
+    double bezier_reflect_x = DBL_MAX;
+    double bezier_reflect_y = DBL_MAX;
     double x;
     double y;
     double x1;
diff --git a/src/rl2symbaux.c b/src/rl2symbaux.c
new file mode 100644
index 0000000..5bc109e
--- /dev/null
+++ b/src/rl2symbaux.c
@@ -0,0 +1,4360 @@
+/*
+
+ rl2symbaux -- private SQL helper methods
+
+ version 0.1, 2015 January 18
+
+ Author: Sandro Furieri a.furieri at lqt.it
+
+ -----------------------------------------------------------------------------
+ 
+ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ 
+ The contents of this file are subject to the Mozilla Public License Version
+ 1.1 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+ 
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the
+License.
+
+The Original Code is the RasterLite2 library
+
+The Initial Developer of the Original Code is Alessandro Furieri
+ 
+Portions created by the Initial Developer are Copyright (C) 2008-2013
+the Initial Developer. All Rights Reserved.
+
+Alternatively, the contents of this file may be used under the terms of
+either the GNU General Public License Version 2 or later (the "GPL"), or
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+in which case the provisions of the GPL or the LGPL are applicable instead
+of those above. If you wish to allow use of your version of this file only
+under the terms of either the GPL or the LGPL, and not to allow others to
+use your version of this file under the terms of the MPL, indicate your
+decision by deleting the provisions above and replace them with the notice
+and other provisions required by the GPL or the LGPL. If you do not delete
+the provisions above, a recipient may use your version of this file under
+the terms of any one of the MPL, the GPL or the LGPL.
+ 
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <float.h>
+#include <limits.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#ifdef _WIN32
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
+#include "config.h"
+
+#include <libxml/parser.h>
+
+#ifdef LOADABLE_EXTENSION
+#include "rasterlite2/sqlite.h"
+#endif
+
+#include "rasterlite2/rasterlite2.h"
+#include "rasterlite2_private.h"
+
+#define RL2_UNUSED() if (argc || argv) argc = argc;
+
+RL2_PRIVATE rl2PrivRasterSymbolizerPtr
+rl2_create_default_raster_symbolizer ()
+{
+/* creating a default Raster Style */
+    rl2PrivRasterSymbolizerPtr symbolizer =
+	malloc (sizeof (rl2PrivRasterSymbolizer));
+    if (symbolizer == NULL)
+	return NULL;
+    symbolizer->opacity = 1.0;
+    symbolizer->bandSelection = NULL;
+    symbolizer->categorize = NULL;
+    symbolizer->interpolate = NULL;
+    symbolizer->contrastEnhancement = RL2_CONTRAST_ENHANCEMENT_NONE;
+    symbolizer->gammaValue = 1.0;
+    symbolizer->shadedRelief = 0;
+    symbolizer->brightnessOnly = 0;
+    symbolizer->reliefFactor = 55.0;
+    return symbolizer;
+}
+
+RL2_PRIVATE rl2PrivStyleRulePtr
+rl2_create_default_style_rule ()
+{
+/* creating a default (empty) Style Rule */
+    rl2PrivStyleRulePtr rule = malloc (sizeof (rl2PrivStyleRule));
+    if (rule == NULL)
+	return NULL;
+    rule->else_rule = 0;
+    rule->min_scale = DBL_MAX;
+    rule->max_scale = DBL_MAX;
+    rule->comparison_op = RL2_COMPARISON_NONE;
+    rule->comparison_args = NULL;
+    rule->column_name = NULL;
+    rule->style_type = RL2_UNKNOWN_STYLE;
+    rule->style = NULL;
+    rule->next = NULL;
+    return rule;
+}
+
+RL2_PRIVATE rl2PrivRuleSingleArgPtr
+rl2_create_default_rule_single_arg ()
+{
+/* creating default (empty) Rule Single Arg */
+    rl2PrivRuleSingleArgPtr arg = malloc (sizeof (rl2PrivRuleSingleArg));
+    if (arg == NULL)
+	return NULL;
+    arg->value = NULL;
+    return arg;
+}
+
+RL2_PRIVATE rl2PrivRuleLikeArgsPtr
+rl2_create_default_rule_like_args ()
+{
+/* creating default (empty) Rule Like Args */
+    rl2PrivRuleLikeArgsPtr args = malloc (sizeof (rl2PrivRuleLikeArgs));
+    if (args == NULL)
+	return NULL;
+    args->wild_card = NULL;
+    args->single_char = NULL;
+    args->escape_char = NULL;
+    args->value = NULL;
+    return args;
+}
+
+RL2_PRIVATE rl2PrivRuleBetweenArgsPtr
+rl2_create_default_rule_between_args ()
+{
+/* creating default (empty) Rule Between Args */
+    rl2PrivRuleBetweenArgsPtr args = malloc (sizeof (rl2PrivRuleBetweenArgs));
+    if (args == NULL)
+	return NULL;
+    args->lower = NULL;
+    args->upper = NULL;
+    return args;
+}
+
+RL2_PRIVATE rl2PrivVectorSymbolizerPtr
+rl2_create_default_vector_symbolizer ()
+{
+/* creating a default Vector Style */
+    rl2PrivVectorSymbolizerPtr symbolizer =
+	malloc (sizeof (rl2PrivVectorSymbolizer));
+    if (symbolizer == NULL)
+	return NULL;
+    symbolizer->first = NULL;
+    symbolizer->last = NULL;
+    return symbolizer;
+}
+
+RL2_PRIVATE rl2PrivCoverageStylePtr
+rl2_create_default_coverage_style ()
+{
+/* creating a default (empty) Coverage Style */
+    rl2PrivCoverageStylePtr style = malloc (sizeof (rl2PrivCoverageStyle));
+    if (style == NULL)
+	return NULL;
+    style->name = NULL;
+    style->first_rule = NULL;
+    style->last_rule = NULL;
+    return style;
+}
+
+RL2_DECLARE void
+rl2_destroy_coverage_style (rl2CoverageStylePtr style)
+{
+/* destroying a CoverageStyle object */
+    rl2PrivStyleRulePtr pR;
+    rl2PrivStyleRulePtr pRn;
+    rl2PrivCoverageStylePtr stl = (rl2PrivCoverageStylePtr) style;
+    if (stl == NULL)
+	return;
+
+    if (stl->name != NULL)
+	free (stl->name);
+
+    pR = stl->first_rule;
+    while (pR != NULL)
+      {
+	  pRn = pR->next;
+	  rl2_destroy_style_rule (pR);
+	  pR = pRn;
+      }
+    free (stl);
+}
+
+RL2_DECLARE const char *
+rl2_get_coverage_style_name (rl2CoverageStylePtr style)
+{
+/* return the CoverageStyle Name */
+    rl2PrivCoverageStylePtr stl = (rl2PrivCoverageStylePtr) style;
+    if (stl == NULL)
+	return NULL;
+    return stl->name;
+}
+
+RL2_DECLARE rl2RasterSymbolizerPtr
+rl2_get_symbolizer_from_coverage_style (rl2CoverageStylePtr style, double scale)
+{
+/* return the RasterSymbolizer matching a given scale from a CoverageStyle */
+    rl2PrivRasterSymbolizerPtr symbolizer = NULL;
+    rl2PrivStyleRulePtr pR;
+    rl2PrivCoverageStylePtr stl = (rl2PrivCoverageStylePtr) style;
+    if (stl == NULL)
+	return NULL;
+
+    pR = stl->first_rule;
+    while (pR != NULL)
+      {
+	  if (pR->style_type == RL2_RASTER_STYLE && pR->style != NULL)
+	      ;
+	  else
+	    {
+		/* skipping any invalid rule */
+		pR = pR->next;
+		continue;
+	    }
+	  if (pR->min_scale != DBL_MAX && pR->max_scale != DBL_MAX)
+	    {
+		if (scale >= pR->min_scale && scale < pR->max_scale)
+		  {
+		      symbolizer = pR->style;
+		      break;
+		  }
+	    }
+	  else if (pR->min_scale != DBL_MAX)
+	    {
+		if (scale >= pR->min_scale)
+		  {
+		      symbolizer = pR->style;
+		      break;
+		  }
+	    }
+	  else if (pR->max_scale != DBL_MAX)
+	    {
+		if (scale < pR->max_scale)
+		  {
+		      symbolizer = pR->style;
+		      break;
+		  }
+	    }
+	  else
+	    {
+		symbolizer = pR->style;
+		break;
+	    }
+	  pR = pR->next;
+      }
+    return (rl2RasterSymbolizerPtr) symbolizer;
+}
+
+RL2_DECLARE void
+rl2_destroy_feature_type_style (rl2FeatureTypeStylePtr style)
+{
+/* destroying a FeatureTypeStyle object */
+    int i;
+    rl2PrivStyleRulePtr pR;
+    rl2PrivStyleRulePtr pRn;
+    rl2PrivFeatureTypeStylePtr stl = (rl2PrivFeatureTypeStylePtr) style;
+    if (stl == NULL)
+	return;
+
+    if (stl->name != NULL)
+	free (stl->name);
+
+    pR = stl->first_rule;
+    while (pR != NULL)
+      {
+	  pRn = pR->next;
+	  rl2_destroy_style_rule (pR);
+	  pR = pRn;
+      }
+    if (stl->else_rule != NULL)
+	rl2_destroy_style_rule (stl->else_rule);
+    if (stl->column_names != NULL)
+      {
+	  for (i = 0; i < stl->columns_count; i++)
+	    {
+		if (*(stl->column_names + i) != NULL)
+		    free (*(stl->column_names + i));
+	    }
+	  free (stl->column_names);
+      }
+    free (stl);
+}
+
+RL2_DECLARE const char *
+rl2_get_feature_type_style_name (rl2FeatureTypeStylePtr style)
+{
+/* return the FeatureTypeStyle Name */
+    rl2PrivFeatureTypeStylePtr stl = (rl2PrivFeatureTypeStylePtr) style;
+    if (stl == NULL)
+	return NULL;
+    return stl->name;
+}
+
+RL2_DECLARE int
+rl2_get_feature_type_style_columns_count (rl2FeatureTypeStylePtr style)
+{
+/* return the FeatureTypeStyle ColumnsCount */
+    rl2PrivFeatureTypeStylePtr stl = (rl2PrivFeatureTypeStylePtr) style;
+    if (stl == NULL)
+	return 0;
+    if (stl->column_names == NULL)
+	return 0;
+    return stl->columns_count;
+}
+
+RL2_DECLARE const char *
+rl2_get_feature_type_style_column_name (rl2FeatureTypeStylePtr style, int index)
+{
+/* return the Nth FeatureTypeStyle ColumnName */
+    rl2PrivFeatureTypeStylePtr stl = (rl2PrivFeatureTypeStylePtr) style;
+    if (stl == NULL)
+	return NULL;
+    if (stl->column_names != NULL && index >= 0 && index < stl->columns_count)
+	return *(stl->column_names + index);
+    return NULL;
+}
+
+static int
+is_valid_numeric_literal (const char *literal)
+{
+/* checking if a literal could be of the numeric type */
+    const char *in = literal;
+    while (1)
+      {
+	  /* skipping all whitespaces */
+	  if (*in == ' ' || *in == '\t')
+	      in++;
+	  else
+	      break;
+      }
+    if (*in == '-' || *in == '+')
+      {
+	  /* leading sign */
+	  in++;
+      }
+    while (*in != '\0')
+      {
+	  if (*in == '.')
+	    {
+		/* decimal point */
+		in++;
+		break;
+	    }
+	  if (*in >= '0' && *in <= '9')
+	    {
+		/* digit */
+		in++;
+		continue;
+	    }
+	  return 0;
+      }
+    while (*in != '\0')
+      {
+	  if (*in >= '0' && *in <= '9')
+	    {
+		/* digit */
+		in++;
+		continue;
+	    }
+	  return 0;
+      }
+    return 1;
+}
+
+static int
+eval_filter_eq (rl2PrivStyleRulePtr rule, rl2PrivVariantValuePtr val)
+{
+/* evaluating an IsEqual comparison */
+    sqlite3_int64 intval;
+    double dblval;
+    rl2PrivRuleSingleArgPtr arg =
+	(rl2PrivRuleSingleArgPtr) (rule->comparison_args);
+    if (arg == NULL)
+	return 0;
+    switch (val->sqlite3_type)
+      {
+      case SQLITE_INTEGER:
+	  if (is_valid_numeric_literal (arg->value))
+	    {
+		intval = atoll (arg->value);
+		if (intval == val->int_value)
+		    return 1;
+	    }
+	  break;
+      case SQLITE_FLOAT:
+	  if (is_valid_numeric_literal (arg->value))
+	    {
+		dblval = atof (arg->value);
+		if (dblval == val->dbl_value)
+		    return 1;
+	    }
+	  break;
+      case SQLITE_TEXT:
+	  if (strcmp (arg->value, val->text_value) == 0)
+	      return 1;
+	  break;
+      };
+    return 0;
+}
+
+static int
+eval_filter_ne (rl2PrivStyleRulePtr rule, rl2PrivVariantValuePtr val)
+{
+/* evaluating an IsNotEqual comparison */
+    sqlite3_int64 intval;
+    double dblval;
+    rl2PrivRuleSingleArgPtr arg =
+	(rl2PrivRuleSingleArgPtr) (rule->comparison_args);
+    if (arg == NULL)
+	return 1;
+    switch (val->sqlite3_type)
+      {
+      case SQLITE_INTEGER:
+	  if (is_valid_numeric_literal (arg->value))
+	    {
+		intval = atoll (arg->value);
+		if (intval == val->int_value)
+		    return 0;
+	    }
+	  break;
+      case SQLITE_FLOAT:
+	  if (is_valid_numeric_literal (arg->value))
+	    {
+		dblval = atof (arg->value);
+		if (dblval == val->dbl_value)
+		    return 0;
+	    }
+	  break;
+      case SQLITE_TEXT:
+	  if (is_valid_numeric_literal (arg->value))
+	    {
+		if (strcmp (arg->value, val->text_value) == 0)
+		    return 0;
+	    }
+	  break;
+      case SQLITE_BLOB:
+      case SQLITE_NULL:
+	  return 0;
+	  break;
+      };
+    return 1;
+}
+
+static int
+eval_filter_lt (rl2PrivStyleRulePtr rule, rl2PrivVariantValuePtr val)
+{
+/* evaluating an IsLessThan comparison */
+    sqlite3_int64 intval;
+    double dblval;
+    rl2PrivRuleSingleArgPtr arg =
+	(rl2PrivRuleSingleArgPtr) (rule->comparison_args);
+    if (arg == NULL)
+	return 0;
+    switch (val->sqlite3_type)
+      {
+      case SQLITE_INTEGER:
+	  if (is_valid_numeric_literal (arg->value))
+	    {
+		intval = atoll (arg->value);
+		if (val->int_value < intval)
+		    return 1;
+	    }
+	  break;
+      case SQLITE_FLOAT:
+	  if (is_valid_numeric_literal (arg->value))
+	    {
+		dblval = atof (arg->value);
+		if (val->dbl_value < dblval)
+		    return 1;
+	    }
+	  break;
+      case SQLITE_TEXT:
+	  if (strcmp (val->text_value, arg->value) < 0)
+	      return 1;
+	  break;
+      };
+    return 0;
+}
+
+static int
+eval_filter_gt (rl2PrivStyleRulePtr rule, rl2PrivVariantValuePtr val)
+{
+/* evaluating an IsGreaterThan comparison */
+    sqlite3_int64 intval;
+    double dblval;
+    rl2PrivRuleSingleArgPtr arg =
+	(rl2PrivRuleSingleArgPtr) (rule->comparison_args);
+    if (arg == NULL)
+	return 0;
+    switch (val->sqlite3_type)
+      {
+      case SQLITE_INTEGER:
+	  if (is_valid_numeric_literal (arg->value))
+	    {
+		intval = atoll (arg->value);
+		if (val->int_value > intval)
+		    return 1;
+	    }
+	  break;
+      case SQLITE_FLOAT:
+	  if (is_valid_numeric_literal (arg->value))
+	    {
+		dblval = atof (arg->value);
+		if (val->dbl_value > dblval)
+		    return 1;
+	    }
+	  break;
+      case SQLITE_TEXT:
+	  if (strcmp (val->text_value, arg->value) > 0)
+	      return 1;
+	  break;
+      };
+    return 0;
+}
+
+static int
+eval_filter_le (rl2PrivStyleRulePtr rule, rl2PrivVariantValuePtr val)
+{
+/* evaluating an IsLessThanOrEqualTo comparison */
+    sqlite3_int64 intval;
+    double dblval;
+    rl2PrivRuleSingleArgPtr arg =
+	(rl2PrivRuleSingleArgPtr) (rule->comparison_args);
+    if (arg == NULL)
+	return 0;
+    switch (val->sqlite3_type)
+      {
+      case SQLITE_INTEGER:
+	  if (is_valid_numeric_literal (arg->value))
+	    {
+		intval = atoll (arg->value);
+		if (val->int_value <= intval)
+		    return 1;
+	    }
+	  break;
+      case SQLITE_FLOAT:
+	  if (is_valid_numeric_literal (arg->value))
+	    {
+		dblval = atof (arg->value);
+		if (val->dbl_value <= dblval)
+		    return 1;
+	    }
+	  break;
+      case SQLITE_TEXT:
+	  if (strcmp (val->text_value, arg->value) <= 0)
+	      return 1;
+	  break;
+      };
+    return 0;
+}
+
+static int
+eval_filter_ge (rl2PrivStyleRulePtr rule, rl2PrivVariantValuePtr val)
+{
+/* evaluating an IsGreaterThanOrEqualTo comparison */
+    sqlite3_int64 intval;
+    double dblval;
+    rl2PrivRuleSingleArgPtr arg =
+	(rl2PrivRuleSingleArgPtr) (rule->comparison_args);
+    if (arg == NULL)
+	return 0;
+    switch (val->sqlite3_type)
+      {
+      case SQLITE_INTEGER:
+	  if (is_valid_numeric_literal (arg->value))
+	    {
+		intval = atoll (arg->value);
+		if (val->int_value >= intval)
+		    return 1;
+	    }
+	  break;
+      case SQLITE_FLOAT:
+	  if (is_valid_numeric_literal (arg->value))
+	    {
+		dblval = atof (arg->value);
+		if (val->dbl_value >= dblval)
+		    return 1;
+	    }
+	  break;
+      case SQLITE_TEXT:
+	  if (strcmp (val->text_value, arg->value) >= 0)
+	      return 1;
+	  break;
+      };
+    return 0;
+}
+
+static int
+eval_filter_between (rl2PrivStyleRulePtr rule, rl2PrivVariantValuePtr val)
+{
+/* evaluating a Between comparison */
+    sqlite3_int64 int_lo;
+    sqlite3_int64 int_hi;
+    double dbl_lo;
+    double dbl_hi;
+    rl2PrivRuleBetweenArgsPtr arg =
+	(rl2PrivRuleBetweenArgsPtr) (rule->comparison_args);
+    if (arg == NULL)
+	return 0;
+    switch (val->sqlite3_type)
+      {
+      case SQLITE_INTEGER:
+	  if (is_valid_numeric_literal (arg->lower)
+	      && is_valid_numeric_literal (arg->upper))
+	    {
+		int_lo = atoll (arg->lower);
+		int_hi = atoll (arg->upper);
+		if (val->int_value >= int_lo && val->int_value < int_hi)
+		    return 1;
+	    }
+	  break;
+      case SQLITE_FLOAT:
+	  if (is_valid_numeric_literal (arg->lower)
+	      && is_valid_numeric_literal (arg->upper))
+	    {
+		dbl_lo = atof (arg->lower);
+		dbl_hi = atof (arg->upper);
+		if (val->dbl_value >= dbl_lo && val->dbl_value < dbl_hi)
+		    return 1;
+	    }
+	  break;
+      case SQLITE_TEXT:
+	  if (strcmp (val->text_value, arg->lower) >= 0
+	      && strcmp (val->text_value, arg->upper) < 0)
+	      return 1;
+	  break;
+      };
+    return 0;
+}
+
+static int
+eval_filter_like (rl2PrivStyleRulePtr rule, rl2PrivVariantValuePtr val)
+{
+/* evaluating a Like comparison */
+    char *intval;
+    char *extval;
+    char *out;
+    char wild_card;
+    char single_char;
+    char escape_char;
+    char special;
+    char pending;
+    const char *in;
+    const char *intptr;
+    const char *extptr;
+    int len;
+    int escape = 0;
+    int mismatch = 0;
+    int i;
+    rl2PrivRuleLikeArgsPtr arg =
+	(rl2PrivRuleLikeArgsPtr) (rule->comparison_args);
+    if (arg == NULL)
+	return 0;
+    if (val->sqlite3_type != SQLITE_TEXT)
+	return 0;
+
+    wild_card = *(arg->wild_card);
+    single_char = *(arg->single_char);
+    escape_char = *(arg->escape_char);
+
+    extval = malloc (val->bytes + 1);
+    strcpy (extval, val->text_value);
+    for (i = 0; i < val->bytes; i++)
+      {
+	  /* transforming the external value into lowercase */
+	  if (*(extval + i) >= 'A' && *(extval + i) <= 'Z')
+	      *(extval + i) = *(extval + i) - 'A' + 'a';
+      }
+    extptr = extval;
+
+    len = strlen (arg->value);
+    intval = malloc (len + 1);
+
+    pending = '\0';
+    intptr = arg->value;
+    while (*intptr != '\0')
+      {
+	  /* identifying the substring */
+	  out = intval;
+	  in = intptr;
+	  special = '\0';
+	  while (*in != '\0')
+	    {
+		if (escape)
+		  {
+		      *out++ = *in++;
+		      escape = 0;
+		      continue;
+		  }
+		if (*in == escape_char)
+		  {
+		      in++;
+		      escape = 1;
+		      continue;
+		  }
+		if (*in == wild_card)
+		  {
+		      special = *in++;
+		      intptr = in;
+		      break;
+		  }
+		if (*in == single_char)
+		  {
+		      special = *in++;
+		      intptr = in;
+		      break;
+		  }
+		if (*in >= 'A' && *in <= 'Z')
+		    *out++ = *in++ - 'A' + 'a';
+		else
+		    *out++ = *in++;
+	    }
+	  *out = '\0';
+	  /* substring comparison */
+	  if (*extptr == '\0')
+	    {
+		mismatch = 1;
+		goto end;
+	    }
+	  if (pending == wild_card)
+	    {
+		char *ptr;
+		if (*intptr == '\0' && special != wild_card)
+		    break;
+		ptr = strstr (extptr, intval);
+		if (ptr == NULL)
+		  {
+		      mismatch = 1;
+		      goto end;
+		  }
+		len = ptr - extptr;
+		len += strlen (intval);
+		extptr += len;
+		if (special != wild_card)
+		    intptr += strlen (intval);
+	    }
+	  else
+	    {
+		len = strlen (intval);
+		if (strncmp (intval, extptr, len) != 0)
+		  {
+		      mismatch = 1;
+		      goto end;
+		  }
+		extptr += len;
+	    }
+	  if (special == single_char)
+	      extptr++;
+	  else if (special == wild_card)
+	      pending = wild_card;
+	  else
+	      pending = '\0';
+      }
+    if (pending == wild_card)
+      {
+	  /* ignoring the final input substring */
+	  while (*extptr != '\0')
+	      extptr++;
+      }
+    if (*extptr != '\0')
+	mismatch = 1;
+
+  end:
+    free (extval);
+    free (intval);
+    if (mismatch)
+	return 0;
+    return 1;
+}
+
+static int
+eval_filter (rl2PrivStyleRulePtr rule, rl2VariantArrayPtr variant)
+{
+/* evaluating a Rule Filter */
+    int i;
+    rl2PrivVariantArrayPtr var = (rl2PrivVariantArrayPtr) variant;
+    if (rule->column_name == NULL)
+	return 1;		/* there is no comparison: surely true */
+    if (var == NULL)
+	return 0;
+    for (i = 0; i < var->count; i++)
+      {
+	  rl2PrivVariantValuePtr val = *(var->array + i);
+	  if (val == NULL)
+	      return 0;
+	  if (val->column_name == NULL)
+	      return 0;
+	  if (strcasecmp (rule->column_name, val->column_name) != 0)
+	      continue;
+	  switch (rule->comparison_op)
+	    {
+	    case RL2_COMPARISON_EQ:
+		return eval_filter_eq (rule, val);
+	    case RL2_COMPARISON_NE:
+		return eval_filter_ne (rule, val);
+	    case RL2_COMPARISON_LT:
+		return eval_filter_lt (rule, val);
+	    case RL2_COMPARISON_GT:
+		return eval_filter_gt (rule, val);
+	    case RL2_COMPARISON_LE:
+		return eval_filter_le (rule, val);
+	    case RL2_COMPARISON_GE:
+		return eval_filter_ge (rule, val);
+	    case RL2_COMPARISON_LIKE:
+		return eval_filter_like (rule, val);
+	    case RL2_COMPARISON_BETWEEN:
+		return eval_filter_between (rule, val);
+	    case RL2_COMPARISON_NULL:
+		if (val->sqlite3_type == SQLITE_NULL)
+		    return 1;
+		break;
+	    };
+	  break;
+      }
+    return 0;
+}
+
+RL2_DECLARE rl2VectorSymbolizerPtr
+rl2_get_symbolizer_from_feature_type_style (rl2FeatureTypeStylePtr style,
+					    double scale,
+					    rl2VariantArrayPtr variant,
+					    int *scale_forbidden)
+{
+/* return the VectorSymbolizer matching a given scale/filter from a FeatureTypeStyle */
+    rl2PrivVectorSymbolizerPtr symbolizer = NULL;
+    rl2PrivStyleRulePtr pR;
+    rl2PrivFeatureTypeStylePtr stl = (rl2PrivFeatureTypeStylePtr) style;
+    *scale_forbidden = 0;
+    if (stl == NULL)
+	return NULL;
+
+    pR = stl->first_rule;
+    while (pR != NULL)
+      {
+	  if (pR->style_type == RL2_VECTOR_STYLE && pR->style != NULL)
+	      ;
+	  else
+	    {
+		/* skipping any invalid rule */
+		pR = pR->next;
+		continue;
+	    }
+
+	  if (eval_filter (pR, variant))
+	    {
+		*scale_forbidden = 0;
+		if (pR->min_scale != DBL_MAX && pR->max_scale != DBL_MAX)
+		  {
+		      if (scale >= pR->min_scale && scale < pR->max_scale)
+			  symbolizer = pR->style;
+		  }
+		else if (pR->min_scale != DBL_MAX)
+		  {
+		      if (scale >= pR->min_scale)
+			  symbolizer = pR->style;
+		  }
+		else if (pR->max_scale != DBL_MAX)
+		  {
+		      if (scale < pR->max_scale)
+			  symbolizer = pR->style;
+		  }
+		else
+		    symbolizer = pR->style;
+		if (symbolizer == NULL)
+		    *scale_forbidden = 1;
+		else
+		    return (rl2VectorSymbolizerPtr) symbolizer;
+	    }
+	  pR = pR->next;
+      }
+    if (stl->else_rule != NULL)
+      {
+	  /* applyhing the ELSE rule */
+	  *scale_forbidden = 0;
+	  pR = stl->else_rule;
+	  if (pR->min_scale != DBL_MAX && pR->max_scale != DBL_MAX)
+	    {
+		if (scale >= pR->min_scale && scale < pR->max_scale)
+		    symbolizer = pR->style;
+	    }
+	  else if (pR->min_scale != DBL_MAX)
+	    {
+		if (scale >= pR->min_scale)
+		    symbolizer = pR->style;
+	    }
+	  else if (pR->max_scale != DBL_MAX)
+	    {
+		if (scale < pR->max_scale)
+		    symbolizer = pR->style;
+	    }
+	  else
+	      symbolizer = pR->style;
+	  if (symbolizer == NULL)
+	      *scale_forbidden = 1;
+      }
+    return (rl2VectorSymbolizerPtr) symbolizer;
+}
+
+RL2_DECLARE int
+rl2_is_visible_style (rl2FeatureTypeStylePtr style, double scale)
+{
+/* test visibility at a given scale/filter from a FeatureTypeStyle */
+    int count = 0;
+    int visible;
+    rl2PrivStyleRulePtr pR;
+    rl2PrivFeatureTypeStylePtr stl = (rl2PrivFeatureTypeStylePtr) style;
+    if (stl == NULL)
+	return 0;
+    if (stl->first_rule == NULL)
+      {
+	  /* there are no rules: unconditional visibility */
+	  return 1;
+      }
+
+    pR = stl->first_rule;
+    while (pR != NULL)
+      {
+	  if (pR->style_type == RL2_VECTOR_STYLE && pR->style != NULL)
+	      ;
+	  else
+	    {
+		/* skipping any invalid rule */
+		pR = pR->next;
+		continue;
+	    }
+	  visible = 1;
+	  if (pR->min_scale != DBL_MAX && pR->max_scale != DBL_MAX)
+	    {
+		visible = 0;
+		if (scale >= pR->min_scale && scale < pR->max_scale)
+		    visible = 1;
+	    }
+	  else if (pR->min_scale != DBL_MAX)
+	    {
+		visible = 0;
+		if (scale >= pR->min_scale)
+		    visible = 1;
+	    }
+	  else if (pR->max_scale != DBL_MAX)
+	    {
+		visible = 0;
+		if (scale < pR->max_scale)
+		    visible = 1;
+	    }
+	  if (visible)
+	      count++;
+	  pR = pR->next;
+      }
+    if (count == 0)
+	return 0;
+    return 1;
+}
+
+RL2_PRIVATE void
+rl2_destroy_rule_like_args (rl2PrivRuleLikeArgsPtr args)
+{
+/* destroying a Rule Like arguments object */
+    if (args == NULL)
+	return;
+
+    if (args->wild_card != NULL)
+	free (args->wild_card);
+    if (args->single_char != NULL)
+	free (args->single_char);
+    if (args->escape_char != NULL)
+	free (args->escape_char);
+    if (args->value != NULL)
+	free (args->value);
+    free (args);
+}
+
+RL2_PRIVATE void
+rl2_destroy_rule_between_args (rl2PrivRuleBetweenArgsPtr args)
+{
+/* destroying a Rule Between arguments object */
+    if (args == NULL)
+	return;
+
+    if (args->lower != NULL)
+	free (args->lower);
+    if (args->upper != NULL)
+	free (args->upper);
+    free (args);
+}
+
+RL2_PRIVATE void
+rl2_destroy_rule_single_arg (rl2PrivRuleSingleArgPtr arg)
+{
+/* destroying a Rule Single argument object */
+    if (arg == NULL)
+	return;
+
+    if (arg->value != NULL)
+	free (arg->value);
+    free (arg);
+}
+
+RL2_PRIVATE void
+rl2_destroy_style_rule (rl2PrivStyleRulePtr rule)
+{
+/* destroying a StyleRule object */
+    if (rule == NULL)
+	return;
+
+    if (rule->column_name != NULL)
+	free (rule->column_name);
+    if (rule->comparison_args != NULL)
+      {
+	  if (rule->comparison_op == RL2_COMPARISON_LIKE)
+	      rl2_destroy_rule_like_args (rule->comparison_args);
+	  else if (rule->comparison_op == RL2_COMPARISON_BETWEEN)
+	      rl2_destroy_rule_between_args (rule->comparison_args);
+	  else
+	      rl2_destroy_rule_single_arg (rule->comparison_args);
+      }
+    if (rule->style != NULL)
+      {
+	  if (rule->style_type == RL2_VECTOR_STYLE)
+	      rl2_destroy_vector_symbolizer (rule->style);
+	  if (rule->style_type == RL2_RASTER_STYLE)
+	      rl2_destroy_raster_symbolizer (rule->style);
+      }
+    free (rule);
+}
+
+RL2_PRIVATE void
+rl2_destroy_raster_symbolizer (rl2PrivRasterSymbolizerPtr stl)
+{
+/* destroying a RasterSymbolizer object */
+    rl2PrivColorMapPointPtr pC;
+    rl2PrivColorMapPointPtr pCn;
+    if (stl == NULL)
+	return;
+
+    if (stl->bandSelection != NULL)
+	free (stl->bandSelection);
+    if (stl->categorize != NULL)
+      {
+	  pC = stl->categorize->first;
+	  while (pC != NULL)
+	    {
+		pCn = pC->next;
+		free (pC);
+		pC = pCn;
+	    }
+	  free (stl->categorize);
+      }
+    if (stl->interpolate != NULL)
+      {
+	  pC = stl->interpolate->first;
+	  while (pC != NULL)
+	    {
+		pCn = pC->next;
+		free (pC);
+		pC = pCn;
+	    }
+	  free (stl->interpolate);
+      }
+    free (stl);
+}
+
+RL2_DECLARE int
+rl2_get_raster_symbolizer_opacity (rl2RasterSymbolizerPtr style,
+				   double *opacity)
+{
+/* return the RasterSymbolizer Opacity */
+    rl2PrivRasterSymbolizerPtr stl = (rl2PrivRasterSymbolizerPtr) style;
+    if (stl == NULL)
+	return RL2_ERROR;
+    *opacity = stl->opacity;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_is_raster_symbolizer_mono_band_selected (rl2RasterSymbolizerPtr style,
+					     int *selected, int *categorize,
+					     int *interpolate)
+{
+/* return if the RasterSymbolizer has a MonoBand selection */
+    rl2PrivRasterSymbolizerPtr stl = (rl2PrivRasterSymbolizerPtr) style;
+    if (stl == NULL)
+	return RL2_ERROR;
+    if (stl->shadedRelief)
+      {
+	  /* Shaded Relief */
+	  *selected = 1;
+	  *categorize = 0;
+	  *interpolate = 0;
+	  return RL2_OK;
+      }
+    if (stl->bandSelection == NULL)
+      {
+	  if (stl->categorize != NULL)
+	    {
+		/* Categorize Color Map */
+		*selected = 1;
+		*categorize = 1;
+		*interpolate = 0;
+		return RL2_OK;
+	    }
+	  if (stl->interpolate != NULL)
+	    {
+		/* Interpolate Color Map */
+		*selected = 1;
+		*categorize = 0;
+		*interpolate = 1;
+		return RL2_OK;
+	    }
+	  if (stl->contrastEnhancement == RL2_CONTRAST_ENHANCEMENT_NORMALIZE
+	      || stl->contrastEnhancement ==
+	      RL2_CONTRAST_ENHANCEMENT_HISTOGRAM
+	      || stl->contrastEnhancement == RL2_CONTRAST_ENHANCEMENT_GAMMA)
+	    {
+		/* Contrast Enhancement */
+		*selected = 1;
+		*categorize = 0;
+		*interpolate = 0;
+		return RL2_OK;
+	    }
+      }
+    if (stl->bandSelection == NULL)
+	*selected = 0;
+    else if (stl->bandSelection->selectionType == RL2_BAND_SELECTION_MONO)
+	*selected = 1;
+    else
+	*selected = 0;
+    *categorize = 0;
+    *interpolate = 0;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_get_raster_symbolizer_mono_band_selection (rl2RasterSymbolizerPtr style,
+					       unsigned char *gray_band)
+{
+/* return the RasterSymbolizer MonoBand selection */
+    rl2PrivRasterSymbolizerPtr stl = (rl2PrivRasterSymbolizerPtr) style;
+    if (stl == NULL)
+	return RL2_ERROR;
+    if (stl->bandSelection == NULL)
+      {
+	  if (stl->categorize != NULL)
+	    {
+		/* Categorize Color Map */
+		*gray_band = 0;
+		return RL2_OK;
+	    }
+	  if (stl->interpolate != NULL)
+	    {
+		/* Interpolate Color Map */
+		*gray_band = 0;
+		return RL2_OK;
+	    }
+	  /* Interpolate Color Map */
+	  *gray_band = 0;
+	  return RL2_OK;
+      }
+    if (stl->bandSelection == NULL)
+	return RL2_ERROR;
+    else if (stl->bandSelection->selectionType == RL2_BAND_SELECTION_MONO)
+      {
+	  *gray_band = stl->bandSelection->grayBand;
+	  return RL2_OK;
+      }
+    else
+	return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_is_raster_symbolizer_triple_band_selected (rl2RasterSymbolizerPtr style,
+					       int *selected)
+{
+/* return if the RasterSymbolizer has a TripleBand selection */
+    rl2PrivRasterSymbolizerPtr stl = (rl2PrivRasterSymbolizerPtr) style;
+    if (stl == NULL)
+	return RL2_ERROR;
+    if (stl->bandSelection == NULL)
+      {
+	  if (stl->contrastEnhancement == RL2_CONTRAST_ENHANCEMENT_NORMALIZE
+	      || stl->contrastEnhancement ==
+	      RL2_CONTRAST_ENHANCEMENT_HISTOGRAM
+	      || stl->contrastEnhancement == RL2_CONTRAST_ENHANCEMENT_GAMMA)
+	    {
+		/* Contrast Enhancement */
+		*selected = 1;
+		return RL2_OK;
+	    }
+      }
+    if (stl->bandSelection == NULL)
+	*selected = 0;
+    else if (stl->bandSelection->selectionType == RL2_BAND_SELECTION_TRIPLE)
+	*selected = 1;
+    else
+	*selected = 0;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_get_raster_symbolizer_triple_band_selection (rl2RasterSymbolizerPtr style,
+						 unsigned char *red_band,
+						 unsigned char *green_band,
+						 unsigned char *blue_band)
+{
+/* return the RasterSymbolizer TripleBand selection */
+    rl2PrivRasterSymbolizerPtr stl = (rl2PrivRasterSymbolizerPtr) style;
+    if (stl == NULL)
+	return RL2_ERROR;
+    if (stl->bandSelection == NULL)
+      {
+	  if (stl->contrastEnhancement == RL2_CONTRAST_ENHANCEMENT_NORMALIZE
+	      || stl->contrastEnhancement ==
+	      RL2_CONTRAST_ENHANCEMENT_HISTOGRAM
+	      || stl->contrastEnhancement == RL2_CONTRAST_ENHANCEMENT_GAMMA)
+	    {
+		/* Contrast Enhancement */
+		*red_band = 0;
+		*green_band = 1;
+		*blue_band = 2;
+		return RL2_OK;
+	    }
+      }
+    if (stl->bandSelection == NULL)
+	return RL2_ERROR;
+    else if (stl->bandSelection->selectionType == RL2_BAND_SELECTION_TRIPLE)
+      {
+	  *red_band = stl->bandSelection->redBand;
+	  *green_band = stl->bandSelection->greenBand;
+	  *blue_band = stl->bandSelection->blueBand;
+	  return RL2_OK;
+      }
+    else
+	return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_get_raster_symbolizer_overall_contrast_enhancement (rl2RasterSymbolizerPtr
+							style,
+							unsigned char
+							*contrast_enhancement,
+							double *gamma_value)
+{
+/* return the RasterSymbolizer OverallContrastEnhancement */
+    rl2PrivRasterSymbolizerPtr stl = (rl2PrivRasterSymbolizerPtr) style;
+    if (stl == NULL)
+	return RL2_ERROR;
+    *contrast_enhancement = stl->contrastEnhancement;
+    *gamma_value = stl->gammaValue;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+    rl2_get_raster_symbolizer_red_band_contrast_enhancement
+    (rl2RasterSymbolizerPtr style, unsigned char *contrast_enhancement,
+     double *gamma_value)
+{
+/* return the RasterSymbolizer RedBand ContrastEnhancement */
+    rl2PrivRasterSymbolizerPtr stl = (rl2PrivRasterSymbolizerPtr) style;
+    if (stl == NULL)
+	return RL2_ERROR;
+    if (stl->bandSelection == NULL)
+	return RL2_ERROR;
+    else if (stl->bandSelection->selectionType == RL2_BAND_SELECTION_TRIPLE)
+      {
+	  *contrast_enhancement = stl->bandSelection->redContrast;
+	  *gamma_value = stl->bandSelection->redGamma;
+	  return RL2_OK;
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+    rl2_get_raster_symbolizer_green_band_contrast_enhancement
+    (rl2RasterSymbolizerPtr style, unsigned char *contrast_enhancement,
+     double *gamma_value)
+{
+/* return the RasterSymbolizer GreenBand ContrastEnhancement */
+    rl2PrivRasterSymbolizerPtr stl = (rl2PrivRasterSymbolizerPtr) style;
+    if (stl == NULL)
+	return RL2_ERROR;
+    if (stl->bandSelection == NULL)
+	return RL2_ERROR;
+    else if (stl->bandSelection->selectionType == RL2_BAND_SELECTION_TRIPLE)
+      {
+	  *contrast_enhancement = stl->bandSelection->greenContrast;
+	  *gamma_value = stl->bandSelection->greenGamma;
+	  return RL2_OK;
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+    rl2_get_raster_symbolizer_blue_band_contrast_enhancement
+    (rl2RasterSymbolizerPtr style, unsigned char *contrast_enhancement,
+     double *gamma_value)
+{
+/* return the RasterSymbolizer BlueBand ContrastEnhancement */
+    rl2PrivRasterSymbolizerPtr stl = (rl2PrivRasterSymbolizerPtr) style;
+    if (stl == NULL)
+	return RL2_ERROR;
+    if (stl->bandSelection == NULL)
+	return RL2_ERROR;
+    else if (stl->bandSelection->selectionType == RL2_BAND_SELECTION_TRIPLE)
+      {
+	  *contrast_enhancement = stl->bandSelection->blueContrast;
+	  *gamma_value = stl->bandSelection->blueGamma;
+	  return RL2_OK;
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+    rl2_get_raster_symbolizer_gray_band_contrast_enhancement
+    (rl2RasterSymbolizerPtr style, unsigned char *contrast_enhancement,
+     double *gamma_value)
+{
+/* return the RasterSymbolizer GrayBand ContrastEnhancement */
+    rl2PrivRasterSymbolizerPtr stl = (rl2PrivRasterSymbolizerPtr) style;
+    if (stl == NULL)
+	return RL2_ERROR;
+    if (stl->bandSelection == NULL)
+	return RL2_ERROR;
+    else if (stl->bandSelection->selectionType == RL2_BAND_SELECTION_MONO)
+      {
+	  *contrast_enhancement = stl->bandSelection->grayContrast;
+	  *gamma_value = stl->bandSelection->grayGamma;
+	  return RL2_OK;
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_has_raster_symbolizer_shaded_relief (rl2RasterSymbolizerPtr style,
+					 int *shaded_relief)
+{
+/* return if the RasterSymbolizer has ShadedRelief */
+    rl2PrivRasterSymbolizerPtr stl = (rl2PrivRasterSymbolizerPtr) style;
+    if (stl == NULL)
+	return RL2_ERROR;
+    *shaded_relief = stl->shadedRelief;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_get_raster_symbolizer_shaded_relief (rl2RasterSymbolizerPtr style,
+					 int *brightness_only,
+					 double *relief_factor)
+{
+/* return the RasterSymbolizer ShadedRelief parameters */
+    rl2PrivRasterSymbolizerPtr stl = (rl2PrivRasterSymbolizerPtr) style;
+    if (stl == NULL)
+	return RL2_ERROR;
+    if (stl->shadedRelief)
+      {
+	  *brightness_only = stl->brightnessOnly;
+	  *relief_factor = stl->reliefFactor;
+	  return RL2_OK;
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_has_raster_symbolizer_color_map_interpolated (rl2RasterSymbolizerPtr
+						  style, int *interpolated)
+{
+/* return if the RasterSymbolizer has an Interpolated ColorMap */
+    rl2PrivRasterSymbolizerPtr stl = (rl2PrivRasterSymbolizerPtr) style;
+    if (stl == NULL)
+	return RL2_ERROR;
+    if (stl->interpolate != NULL)
+	*interpolated = 1;
+    else
+	*interpolated = 0;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_has_raster_symbolizer_color_map_categorized (rl2RasterSymbolizerPtr style,
+						 int *categorized)
+{
+/* return if the RasterSymbolizer has a Categorized ColorMap */
+    rl2PrivRasterSymbolizerPtr stl = (rl2PrivRasterSymbolizerPtr) style;
+    if (stl == NULL)
+	return RL2_ERROR;
+    if (stl->categorize != NULL)
+	*categorized = 1;
+    else
+	*categorized = 0;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_get_raster_symbolizer_color_map_default (rl2RasterSymbolizerPtr style,
+					     unsigned char *red,
+					     unsigned char *green,
+					     unsigned char *blue)
+{
+/* return the RasterSymbolizer ColorMap Default color */
+    rl2PrivRasterSymbolizerPtr stl = (rl2PrivRasterSymbolizerPtr) style;
+    if (stl == NULL)
+	return RL2_ERROR;
+    if (stl->interpolate != NULL)
+      {
+	  *red = stl->interpolate->dfltRed;
+	  *green = stl->interpolate->dfltGreen;
+	  *blue = stl->interpolate->dfltBlue;
+	  return RL2_OK;
+      }
+    if (stl->categorize != NULL)
+      {
+	  *red = stl->categorize->dfltRed;
+	  *green = stl->categorize->dfltGreen;
+	  *blue = stl->categorize->dfltBlue;
+	  return RL2_OK;
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_get_raster_symbolizer_color_map_category_base (rl2RasterSymbolizerPtr
+						   style, unsigned char *red,
+						   unsigned char *green,
+						   unsigned char *blue)
+{
+/* return the RasterSymbolizer ColorMap Category base-color */
+    rl2PrivRasterSymbolizerPtr stl = (rl2PrivRasterSymbolizerPtr) style;
+    if (stl == NULL)
+	return RL2_ERROR;
+    if (stl->categorize != NULL)
+      {
+	  *red = stl->categorize->baseRed;
+	  *green = stl->categorize->baseGreen;
+	  *blue = stl->categorize->baseBlue;
+	  return RL2_OK;
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_get_raster_symbolizer_color_map_count (rl2RasterSymbolizerPtr style,
+					   int *count)
+{
+/* return the RasterSymbolizer ColorMap items count */
+    int cnt;
+    rl2PrivColorMapPointPtr pt;
+    rl2PrivRasterSymbolizerPtr stl = (rl2PrivRasterSymbolizerPtr) style;
+    if (stl == NULL)
+	return RL2_ERROR;
+    if (stl->categorize != NULL)
+      {
+	  cnt = 0;
+	  pt = stl->categorize->first;
+	  while (pt != NULL)
+	    {
+		cnt++;
+		pt = pt->next;
+	    }
+	  *count = cnt;
+	  return RL2_OK;
+      }
+    if (stl->interpolate != NULL)
+      {
+	  cnt = 0;
+	  pt = stl->interpolate->first;
+	  while (pt != NULL)
+	    {
+		cnt++;
+		pt = pt->next;
+	    }
+	  *count = cnt;
+	  return RL2_OK;
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_get_raster_symbolizer_color_map_entry (rl2RasterSymbolizerPtr style,
+					   int index, double *value,
+					   unsigned char *red,
+					   unsigned char *green,
+					   unsigned char *blue)
+{
+/* return the RasterSymbolizer ColorMap item values */
+    int cnt;
+    rl2PrivColorMapPointPtr pt;
+    rl2PrivRasterSymbolizerPtr stl = (rl2PrivRasterSymbolizerPtr) style;
+    if (stl == NULL)
+	return RL2_ERROR;
+    if (stl->categorize != NULL)
+      {
+	  cnt = 0;
+	  pt = stl->categorize->first;
+	  while (pt != NULL)
+	    {
+		if (index == cnt)
+		  {
+		      *value = pt->value;
+		      *red = pt->red;
+		      *green = pt->green;
+		      *blue = pt->blue;
+		      return RL2_OK;
+		  }
+		cnt++;
+		pt = pt->next;
+	    }
+      }
+    if (stl->interpolate != NULL)
+      {
+	  cnt = 0;
+	  pt = stl->interpolate->first;
+	  while (pt != NULL)
+	    {
+		if (index == cnt)
+		  {
+		      *value = pt->value;
+		      *red = pt->red;
+		      *green = pt->green;
+		      *blue = pt->blue;
+		      return RL2_OK;
+		  }
+		cnt++;
+		pt = pt->next;
+	    }
+      }
+    return RL2_ERROR;
+}
+
+RL2_PRIVATE rl2PrivColorReplacementPtr
+rl2_create_default_color_replacement ()
+{
+/* creating a default Color Replacement object */
+    rl2PrivColorReplacementPtr repl = malloc (sizeof (rl2PrivColorReplacement));
+    repl->index = 0;
+    repl->red = 0;
+    repl->green = 0;
+    repl->blue = 0;
+    repl->next = NULL;
+    return repl;
+}
+
+RL2_PRIVATE rl2PrivGraphicItemPtr
+rl2_create_default_external_graphic ()
+{
+/* creating a default Graphic Item object (ExternalGraphic) */
+    rl2PrivGraphicItemPtr item = malloc (sizeof (rl2PrivGraphicItem));
+    rl2PrivExternalGraphicPtr ext = malloc (sizeof (rl2PrivExternalGraphic));
+    ext->xlink_href = NULL;
+    ext->first = NULL;
+    ext->last = NULL;
+    item->type = RL2_EXTERNAL_GRAPHIC;
+    item->item = ext;
+    item->next = NULL;
+    return item;
+}
+
+RL2_PRIVATE rl2PrivGraphicItemPtr
+rl2_create_default_mark ()
+{
+/* creating a default Graphic Item object (Mark) */
+    rl2PrivGraphicItemPtr item = malloc (sizeof (rl2PrivGraphicItem));
+    rl2PrivMarkPtr mark = malloc (sizeof (rl2PrivMark));
+    mark->well_known_type = RL2_GRAPHIC_MARK_UNKNOWN;
+    mark->external_graphic = NULL;
+    mark->stroke = NULL;
+    mark->fill = NULL;
+    item->type = RL2_MARK_GRAPHIC;
+    item->item = mark;
+    item->next = NULL;
+    return item;
+}
+
+RL2_PRIVATE rl2PrivGraphicPtr
+rl2_create_default_graphic ()
+{
+/* creating a default Graphic object) */
+    rl2PrivGraphicPtr graphic = malloc (sizeof (rl2PrivGraphic));
+    graphic->first = NULL;
+    graphic->last = NULL;
+    graphic->opacity = 1.0;
+    graphic->size = 10.0;
+    graphic->rotation = 0.0;
+    graphic->anchor_point_x = 0.5;
+    graphic->anchor_point_y = 0.5;
+    graphic->displacement_x = 0.0;
+    graphic->displacement_y = 0.0;
+    return graphic;
+}
+
+RL2_PRIVATE rl2PrivStrokePtr
+rl2_create_default_stroke ()
+{
+/* creating a default Stroke object */
+    rl2PrivStrokePtr stroke = malloc (sizeof (rl2PrivStroke));
+    stroke->graphic = NULL;
+    stroke->red = 0;
+    stroke->green = 0;
+    stroke->blue = 0;
+    stroke->opacity = 1.0;
+    stroke->width = 1.0;
+    stroke->linejoin = RL2_STROKE_LINEJOIN_UNKNOWN;
+    stroke->linecap = RL2_STROKE_LINECAP_UNKNOWN;
+    stroke->dash_count = 0;
+    stroke->dash_list = NULL;
+    stroke->dash_offset = 0.0;
+    return stroke;
+}
+
+RL2_PRIVATE rl2PrivPointPlacementPtr
+rl2_create_default_point_placement ()
+{
+/* creating a default PointPlacement object */
+    rl2PrivPointPlacementPtr place = malloc (sizeof (rl2PrivPointPlacement));
+    place->anchor_point_x = 0.5;
+    place->anchor_point_y = 0.5;
+    place->displacement_x = 0.0;
+    place->displacement_y = 0.0;
+    place->rotation = 0.0;
+    return place;
+}
+
+RL2_PRIVATE rl2PrivLinePlacementPtr
+rl2_create_default_line_placement ()
+{
+/* creating a default LinePlacement object */
+    rl2PrivLinePlacementPtr place = malloc (sizeof (rl2PrivLinePlacement));
+    place->perpendicular_offset = 0.0;
+    place->is_repeated = 0;
+    place->initial_gap = 0.0;
+    place->gap = 0.0;
+    place->is_aligned = 0;
+    place->generalize_line = 0;
+    return place;
+}
+
+RL2_PRIVATE rl2PrivFillPtr
+rl2_create_default_fill ()
+{
+/* creating a default Fill object */
+    rl2PrivFillPtr fill = malloc (sizeof (rl2PrivFill));
+    fill->graphic = NULL;
+    fill->red = 128;
+    fill->green = 128;
+    fill->blue = 128;
+    fill->opacity = 1.0;
+    return fill;
+}
+
+RL2_PRIVATE rl2PrivHaloPtr
+rl2_create_default_halo ()
+{
+/* creating a default Halo object */
+    rl2PrivHaloPtr halo = malloc (sizeof (rl2PrivHalo));
+    halo->radius = 1.0;
+    halo->fill = NULL;
+    return halo;
+}
+
+RL2_PRIVATE rl2PrivVectorSymbolizerItemPtr
+rl2_create_default_point_symbolizer ()
+{
+/* creating a default Point Symbolizer */
+    rl2PrivVectorSymbolizerItemPtr item =
+	malloc (sizeof (rl2PrivVectorSymbolizerItem));
+    rl2PrivPointSymbolizerPtr symbolizer =
+	malloc (sizeof (rl2PrivPointSymbolizer));
+    if (symbolizer == NULL || item == NULL)
+      {
+	  if (symbolizer != NULL)
+	      free (symbolizer);
+	  if (item != NULL)
+	      free (item);
+	  return NULL;
+      }
+    symbolizer->graphic = NULL;
+    item->symbolizer_type = RL2_POINT_SYMBOLIZER;
+    item->symbolizer = symbolizer;
+    item->next = NULL;
+    return item;
+}
+
+RL2_PRIVATE rl2PrivVectorSymbolizerItemPtr
+rl2_create_default_line_symbolizer ()
+{
+/* creating a default Line Symbolizer */
+    rl2PrivVectorSymbolizerItemPtr item =
+	malloc (sizeof (rl2PrivVectorSymbolizerItem));
+    rl2PrivLineSymbolizerPtr symbolizer =
+	malloc (sizeof (rl2PrivLineSymbolizer));
+    if (symbolizer == NULL || item == NULL)
+      {
+	  if (symbolizer != NULL)
+	      free (symbolizer);
+	  if (item != NULL)
+	      free (item);
+	  return NULL;
+      }
+    symbolizer->stroke = NULL;
+    symbolizer->perpendicular_offset = 0.0;
+    item->symbolizer_type = RL2_LINE_SYMBOLIZER;
+    item->symbolizer = symbolizer;
+    item->next = NULL;
+    return item;
+}
+
+RL2_PRIVATE rl2PrivVectorSymbolizerItemPtr
+rl2_create_default_polygon_symbolizer ()
+{
+/* creating a default Polygon Symbolizer */
+    rl2PrivVectorSymbolizerItemPtr item =
+	malloc (sizeof (rl2PrivVectorSymbolizerItem));
+    rl2PrivPolygonSymbolizerPtr symbolizer =
+	malloc (sizeof (rl2PrivPolygonSymbolizer));
+    if (symbolizer == NULL || item == NULL)
+      {
+	  if (symbolizer != NULL)
+	      free (symbolizer);
+	  if (item != NULL)
+	      free (item);
+	  return NULL;
+      }
+    symbolizer->stroke = NULL;
+    symbolizer->fill = NULL;
+    symbolizer->displacement_x = 0.0;
+    symbolizer->displacement_y = 0.0;
+    symbolizer->perpendicular_offset = 0.0;
+    item->symbolizer_type = RL2_POLYGON_SYMBOLIZER;
+    item->symbolizer = symbolizer;
+    item->next = NULL;
+    return item;
+}
+
+RL2_PRIVATE rl2PrivVectorSymbolizerItemPtr
+rl2_create_default_text_symbolizer ()
+{
+/* creating a default Text Symbolizer */
+    int i;
+    rl2PrivVectorSymbolizerItemPtr item =
+	malloc (sizeof (rl2PrivVectorSymbolizerItem));
+    rl2PrivTextSymbolizerPtr symbolizer =
+	malloc (sizeof (rl2PrivTextSymbolizer));
+    if (symbolizer == NULL || item == NULL)
+      {
+	  if (symbolizer != NULL)
+	      free (symbolizer);
+	  if (item != NULL)
+	      free (item);
+	  return NULL;
+      }
+    symbolizer->label = NULL;
+    symbolizer->font_families_count = 0;
+    for (i = 0; i < RL2_MAX_FONT_FAMILIES; i++)
+	*(symbolizer->font_families + i) = NULL;
+    symbolizer->font_style = RL2_FONT_STYLE_NORMAL;
+    symbolizer->font_weight = RL2_FONT_WEIGHT_NORMAL;
+    symbolizer->font_size = 10.0;
+    symbolizer->label_placement_type = RL2_LABEL_PLACEMENT_UNKNOWN;
+    symbolizer->label_placement = NULL;
+    symbolizer->halo = NULL;
+    symbolizer->fill = NULL;
+    item->symbolizer_type = RL2_TEXT_SYMBOLIZER;
+    item->symbolizer = symbolizer;
+    item->next = NULL;
+    return item;
+}
+
+RL2_DECLARE int
+rl2_is_valid_vector_symbolizer (rl2VectorSymbolizerPtr symbolizer, int *valid)
+{
+/* testing a Vector Symbolizer for validity */
+    rl2PrivVectorSymbolizerPtr sym = (rl2PrivVectorSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->first == NULL)
+	*valid = 0;
+    else
+	*valid = 1;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_get_vector_symbolizer_count (rl2VectorSymbolizerPtr symbolizer, int *count)
+{
+/* return the total count of Vector Symbolizer Items */
+    int cnt = 0;
+    rl2PrivVectorSymbolizerItemPtr item;
+    rl2PrivVectorSymbolizerPtr sym = (rl2PrivVectorSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    item = sym->first;
+    while (item != NULL)
+      {
+	  /* counting how many Items */
+	  cnt++;
+	  item = item->next;
+      }
+    *count = cnt;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_get_vector_symbolizer_item_type (rl2VectorSymbolizerPtr symbolizer,
+				     int index, int *type)
+{
+/* return the Vector Symbolizer Item type */
+    int cnt = 0;
+    rl2PrivVectorSymbolizerItemPtr item;
+    rl2PrivVectorSymbolizerPtr sym = (rl2PrivVectorSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    item = sym->first;
+    while (item != NULL)
+      {
+	  if (cnt == index)
+	    {
+		*type = item->symbolizer_type;
+		return RL2_OK;
+	    }
+	  cnt++;
+	  item = item->next;
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE rl2PointSymbolizerPtr
+rl2_get_point_symbolizer (rl2VectorSymbolizerPtr symbolizer, int index)
+{
+/* return a Point Symbolizer */
+    int cnt = 0;
+    rl2PrivVectorSymbolizerItemPtr item;
+    rl2PrivVectorSymbolizerPtr sym = (rl2PrivVectorSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return NULL;
+    item = sym->first;
+    while (item != NULL)
+      {
+	  if (cnt == index)
+	    {
+		if (item->symbolizer_type == RL2_POINT_SYMBOLIZER)
+		    return (rl2PointSymbolizerPtr) (item->symbolizer);
+		else
+		    return NULL;
+	    }
+	  cnt++;
+	  item = item->next;
+      }
+    return NULL;
+}
+
+RL2_DECLARE rl2LineSymbolizerPtr
+rl2_get_line_symbolizer (rl2VectorSymbolizerPtr symbolizer, int index)
+{
+/* return a Line Symbolizer */
+    int cnt = 0;
+    rl2PrivVectorSymbolizerItemPtr item;
+    rl2PrivVectorSymbolizerPtr sym = (rl2PrivVectorSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return NULL;
+    item = sym->first;
+    while (item != NULL)
+      {
+	  if (cnt == index)
+	    {
+		if (item->symbolizer_type == RL2_LINE_SYMBOLIZER)
+		    return (rl2LineSymbolizerPtr) (item->symbolizer);
+		else
+		    return NULL;
+	    }
+	  cnt++;
+	  item = item->next;
+      }
+    return NULL;
+}
+
+RL2_DECLARE rl2PolygonSymbolizerPtr
+rl2_get_polygon_symbolizer (rl2VectorSymbolizerPtr symbolizer, int index)
+{
+/* return a Polygon Symbolizer */
+    int cnt = 0;
+    rl2PrivVectorSymbolizerItemPtr item;
+    rl2PrivVectorSymbolizerPtr sym = (rl2PrivVectorSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return NULL;
+    item = sym->first;
+    while (item != NULL)
+      {
+	  if (cnt == index)
+	    {
+		if (item->symbolizer_type == RL2_POLYGON_SYMBOLIZER)
+		    return (rl2PolygonSymbolizerPtr) (item->symbolizer);
+		else
+		    return NULL;
+	    }
+	  cnt++;
+	  item = item->next;
+      }
+    return NULL;
+}
+
+RL2_DECLARE rl2TextSymbolizerPtr
+rl2_get_text_symbolizer (rl2VectorSymbolizerPtr symbolizer, int index)
+{
+/* return a Text Symbolizer */
+    int cnt = 0;
+    rl2PrivVectorSymbolizerItemPtr item;
+    rl2PrivVectorSymbolizerPtr sym = (rl2PrivVectorSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return NULL;
+    item = sym->first;
+    while (item != NULL)
+      {
+	  if (cnt == index)
+	    {
+		if (item->symbolizer_type == RL2_TEXT_SYMBOLIZER)
+		    return (rl2TextSymbolizerPtr) (item->symbolizer);
+		else
+		    return NULL;
+	    }
+	  cnt++;
+	  item = item->next;
+      }
+    return NULL;
+}
+
+RL2_DECLARE int
+rl2_line_symbolizer_has_stroke (rl2LineSymbolizerPtr symbolizer, int *stroke)
+{
+/* checks if a Line Symbolizer has a Stroke */
+    rl2PrivLineSymbolizerPtr sym = (rl2PrivLineSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->stroke == NULL)
+	*stroke = 0;
+    else
+	*stroke = 1;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_line_symbolizer_has_graphic_stroke (rl2LineSymbolizerPtr symbolizer,
+					int *stroke)
+{
+/* checks if a Line Symbolizer has a Graphic Stroke */
+    rl2PrivLineSymbolizerPtr sym = (rl2PrivLineSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    *stroke = 0;
+    if (sym->stroke == NULL)
+	;
+    else
+      {
+	  if (sym->stroke->graphic != NULL)
+	    {
+		if (sym->stroke->graphic->first != NULL)
+		  {
+		      if (sym->stroke->graphic->first->type ==
+			  RL2_EXTERNAL_GRAPHIC
+			  && sym->stroke->graphic->first->item != NULL)
+			  *stroke = 1;
+		  }
+	    }
+      }
+    return RL2_OK;
+}
+
+RL2_DECLARE const char *
+rl2_line_symbolizer_get_graphic_stroke_href (rl2LineSymbolizerPtr symbolizer)
+{
+/* return an eventual Line Symbolizer Graphic Stroke xlink:href  */
+    rl2PrivExternalGraphicPtr ext;
+    rl2PrivLineSymbolizerPtr sym = (rl2PrivLineSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return NULL;
+    if (sym->stroke == NULL)
+	return NULL;
+    if (sym->stroke->graphic == NULL)
+	return NULL;
+    if (sym->stroke->graphic->first == NULL)
+	return NULL;
+    if (sym->stroke->graphic->first->type != RL2_EXTERNAL_GRAPHIC)
+	return NULL;
+    ext = (rl2PrivExternalGraphicPtr) (sym->stroke->graphic->first->item);
+    return ext->xlink_href;
+}
+
+RL2_DECLARE int
+rl2_line_symbolizer_get_graphic_stroke_recode_count (rl2LineSymbolizerPtr
+						     symbolizer, int *count)
+{
+/* return how many ColorReplacement items are in a Graphic Stroke (LineSymbolizer) */
+    rl2PrivLineSymbolizerPtr sym = (rl2PrivLineSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    *count = 0;
+    if (sym->stroke != NULL)
+      {
+	  if (sym->stroke->graphic != NULL)
+	    {
+		if (sym->stroke->graphic->first != NULL)
+		  {
+		      if (sym->stroke->graphic->first->type ==
+			  RL2_EXTERNAL_GRAPHIC
+			  && sym->stroke->graphic->first->item != NULL)
+			{
+			    int cnt = 0;
+			    rl2PrivExternalGraphicPtr ext =
+				(rl2PrivExternalGraphicPtr) (sym->
+							     stroke->graphic->
+							     first->item);
+			    rl2PrivColorReplacementPtr repl = ext->first;
+			    while (repl != NULL)
+			      {
+				  cnt++;
+				  repl = repl->next;
+			      }
+			    *count = cnt;
+			}
+		  }
+	    }
+      }
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_line_symbolizer_get_graphic_stroke_recode_color (rl2LineSymbolizerPtr
+						     symbolizer, int index,
+						     int *color_index,
+						     unsigned char *red,
+						     unsigned char *green,
+						     unsigned char *blue)
+{
+/* return a ColorReplacement item from a Graphic Stroke (LineSymbolizer) */
+    rl2PrivLineSymbolizerPtr sym = (rl2PrivLineSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->stroke != NULL)
+      {
+	  if (sym->stroke->graphic != NULL)
+	    {
+		if (sym->stroke->graphic->first != NULL)
+		  {
+		      if (sym->stroke->graphic->first->type ==
+			  RL2_EXTERNAL_GRAPHIC
+			  && sym->stroke->graphic->first->item != NULL)
+			{
+			    int cnt = 0;
+			    rl2PrivExternalGraphicPtr ext =
+				(rl2PrivExternalGraphicPtr) (sym->
+							     stroke->graphic->
+							     first->item);
+			    rl2PrivColorReplacementPtr repl = ext->first;
+			    while (repl != NULL)
+			      {
+				  if (cnt == index)
+				    {
+					*color_index = repl->index;
+					*red = repl->red;
+					*green = repl->green;
+					*blue = repl->blue;
+					return RL2_OK;
+				    }
+				  cnt++;
+				  repl = repl->next;
+			      }
+			}
+		  }
+	    }
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_line_symbolizer_get_stroke_color (rl2LineSymbolizerPtr symbolizer,
+				      unsigned char *red,
+				      unsigned char *green, unsigned char *blue)
+{
+/* return the Line Symbolizer Stroke RGB color */
+    rl2PrivLineSymbolizerPtr sym = (rl2PrivLineSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->stroke == NULL)
+	return RL2_ERROR;
+    *red = sym->stroke->red;
+    *green = sym->stroke->green;
+    *blue = sym->stroke->blue;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_line_symbolizer_get_stroke_opacity (rl2LineSymbolizerPtr symbolizer,
+					double *opacity)
+{
+/* return the Line Symbolizer Stroke opacity */
+    rl2PrivLineSymbolizerPtr sym = (rl2PrivLineSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->stroke == NULL)
+	return RL2_ERROR;
+    *opacity = sym->stroke->opacity;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_line_symbolizer_get_stroke_width (rl2LineSymbolizerPtr symbolizer,
+				      double *width)
+{
+/* return the Line Symbolizer Stroke width */
+    rl2PrivLineSymbolizerPtr sym = (rl2PrivLineSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->stroke == NULL)
+	return RL2_ERROR;
+    *width = sym->stroke->width;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_line_symbolizer_get_stroke_linejoin (rl2LineSymbolizerPtr symbolizer,
+					 unsigned char *linejoin)
+{
+/* return the Line Symbolizer Stroke Linejoin mode */
+    rl2PrivLineSymbolizerPtr sym = (rl2PrivLineSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->stroke == NULL)
+	return RL2_ERROR;
+    *linejoin = sym->stroke->linejoin;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_line_symbolizer_get_stroke_linecap (rl2LineSymbolizerPtr symbolizer,
+					unsigned char *linecap)
+{
+/* return the Line Symbolizer Stroke Linecap mode */
+    rl2PrivLineSymbolizerPtr sym = (rl2PrivLineSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->stroke == NULL)
+	return RL2_ERROR;
+    *linecap = sym->stroke->linecap;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_line_symbolizer_get_stroke_dash_count (rl2LineSymbolizerPtr symbolizer,
+					   int *count)
+{
+/* return the Line Symbolizer Stroke Dash count */
+    rl2PrivLineSymbolizerPtr sym = (rl2PrivLineSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->stroke == NULL)
+	return RL2_ERROR;
+    *count = sym->stroke->dash_count;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_line_symbolizer_get_stroke_dash_item (rl2LineSymbolizerPtr symbolizer,
+					  int index, double *item)
+{
+/* return a Line Symbolizer Stroke Dash item */
+    rl2PrivLineSymbolizerPtr sym = (rl2PrivLineSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->stroke == NULL)
+	return RL2_ERROR;
+    if (sym->stroke->dash_list == NULL)
+	return RL2_ERROR;
+    if (index >= 0 && index < sym->stroke->dash_count)
+	;
+    else
+	return RL2_ERROR;
+    *item = *(sym->stroke->dash_list + index);
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_line_symbolizer_get_stroke_dash_offset (rl2LineSymbolizerPtr symbolizer,
+					    double *offset)
+{
+/* return the Line Symbolizer Stroke Dash initial offset */
+    rl2PrivLineSymbolizerPtr sym = (rl2PrivLineSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->stroke == NULL)
+	return RL2_ERROR;
+    *offset = sym->stroke->dash_offset;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_line_symbolizer_get_perpendicular_offset (rl2LineSymbolizerPtr symbolizer,
+					      double *offset)
+{
+/* return the Line Symbolizer perpendicular offset */
+    rl2PrivLineSymbolizerPtr sym = (rl2PrivLineSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    *offset = sym->perpendicular_offset;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_polygon_symbolizer_has_stroke (rl2PolygonSymbolizerPtr symbolizer,
+				   int *stroke)
+{
+/* checks if a Polygon Symbolizer has a Stroke */
+    rl2PrivPolygonSymbolizerPtr sym = (rl2PrivPolygonSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->stroke == NULL)
+	*stroke = 0;
+    else
+	*stroke = 1;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_polygon_symbolizer_has_graphic_stroke (rl2PolygonSymbolizerPtr symbolizer,
+					   int *stroke)
+{
+/* checks if a Polygon Symbolizer has a Graphic Stroke */
+    rl2PrivPolygonSymbolizerPtr sym = (rl2PrivPolygonSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    *stroke = 0;
+    if (sym->stroke == NULL)
+	;
+    else
+      {
+	  if (sym->stroke->graphic != NULL)
+	    {
+		if (sym->stroke->graphic->first != NULL)
+		  {
+		      if (sym->stroke->graphic->first->type ==
+			  RL2_EXTERNAL_GRAPHIC
+			  && sym->stroke->graphic->first->item != NULL)
+			  *stroke = 1;
+		  }
+	    }
+      }
+    return RL2_OK;
+}
+
+RL2_DECLARE const char *
+rl2_polygon_symbolizer_get_graphic_stroke_href (rl2PolygonSymbolizerPtr
+						symbolizer)
+{
+/* return an eventual Polygon Symbolizer Graphic Stroke xlink:href  */
+    rl2PrivExternalGraphicPtr ext;
+    rl2PrivPolygonSymbolizerPtr sym = (rl2PrivPolygonSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return NULL;
+    if (sym->stroke == NULL)
+	return NULL;
+    if (sym->stroke->graphic == NULL)
+	return NULL;
+    if (sym->stroke->graphic->first == NULL)
+	return NULL;
+    if (sym->stroke->graphic->first->type != RL2_EXTERNAL_GRAPHIC)
+	return NULL;
+    ext = (rl2PrivExternalGraphicPtr) (sym->stroke->graphic->first->item);
+    return ext->xlink_href;
+}
+
+RL2_DECLARE int
+    rl2_polygon_symbolizer_get_graphic_stroke_recode_count
+    (rl2PolygonSymbolizerPtr symbolizer, int *count)
+{
+/* return how many ColorReplacement items are in a Graphic Stroke (PolygonSymbolizer) */
+    rl2PrivPolygonSymbolizerPtr sym = (rl2PrivPolygonSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    *count = 0;
+    if (sym->stroke != NULL)
+      {
+	  if (sym->stroke->graphic != NULL)
+	    {
+		if (sym->stroke->graphic->first != NULL)
+		  {
+		      if (sym->stroke->graphic->first->type ==
+			  RL2_EXTERNAL_GRAPHIC
+			  && sym->stroke->graphic->first->item != NULL)
+			{
+			    int cnt = 0;
+			    rl2PrivExternalGraphicPtr ext =
+				(rl2PrivExternalGraphicPtr) (sym->
+							     stroke->graphic->
+							     first->item);
+			    rl2PrivColorReplacementPtr repl = ext->first;
+			    while (repl != NULL)
+			      {
+				  cnt++;
+				  repl = repl->next;
+			      }
+			    *count = cnt;
+			}
+		  }
+	    }
+      }
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+    rl2_polygon_symbolizer_get_graphic_stroke_recode_color
+    (rl2PolygonSymbolizerPtr symbolizer, int index, int *color_index,
+     unsigned char *red, unsigned char *green, unsigned char *blue)
+{
+/* return a ColorReplacement item from a Graphic Stroke (PolygonSymbolizer) */
+    rl2PrivPolygonSymbolizerPtr sym = (rl2PrivPolygonSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->stroke != NULL)
+      {
+	  if (sym->stroke->graphic != NULL)
+	    {
+		if (sym->stroke->graphic->first != NULL)
+		  {
+		      if (sym->stroke->graphic->first->type ==
+			  RL2_EXTERNAL_GRAPHIC
+			  && sym->stroke->graphic->first->item != NULL)
+			{
+			    int cnt = 0;
+			    rl2PrivExternalGraphicPtr ext =
+				(rl2PrivExternalGraphicPtr) (sym->
+							     stroke->graphic->
+							     first->item);
+			    rl2PrivColorReplacementPtr repl = ext->first;
+			    while (repl != NULL)
+			      {
+				  if (cnt == index)
+				    {
+					*color_index = repl->index;
+					*red = repl->red;
+					*green = repl->green;
+					*blue = repl->blue;
+					return RL2_OK;
+				    }
+				  cnt++;
+				  repl = repl->next;
+			      }
+			}
+		  }
+	    }
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_polygon_symbolizer_get_stroke_color (rl2PolygonSymbolizerPtr symbolizer,
+					 unsigned char *red,
+					 unsigned char *green,
+					 unsigned char *blue)
+{
+/* return the Polygon Symbolizer Stroke RGB color */
+    rl2PrivPolygonSymbolizerPtr sym = (rl2PrivPolygonSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->stroke == NULL)
+	return RL2_ERROR;
+    *red = sym->stroke->red;
+    *green = sym->stroke->green;
+    *blue = sym->stroke->blue;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_polygon_symbolizer_get_stroke_opacity (rl2PolygonSymbolizerPtr symbolizer,
+					   double *opacity)
+{
+/* return the Polygon Symbolizer Stroke opacity */
+    rl2PrivPolygonSymbolizerPtr sym = (rl2PrivPolygonSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->stroke == NULL)
+	return RL2_ERROR;
+    *opacity = sym->stroke->opacity;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_polygon_symbolizer_get_stroke_width (rl2PolygonSymbolizerPtr symbolizer,
+					 double *width)
+{
+/* return the Polygon Symbolizer Stroke width */
+    rl2PrivPolygonSymbolizerPtr sym = (rl2PrivPolygonSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->stroke == NULL)
+	return RL2_ERROR;
+    *width = sym->stroke->width;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_polygon_symbolizer_get_stroke_linejoin (rl2PolygonSymbolizerPtr
+					    symbolizer, unsigned char *linejoin)
+{
+/* return the Polygon Symbolizer Stroke Linejoin mode */
+    rl2PrivPolygonSymbolizerPtr sym = (rl2PrivPolygonSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->stroke == NULL)
+	return RL2_ERROR;
+    *linejoin = sym->stroke->linejoin;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_polygon_symbolizer_get_stroke_linecap (rl2PolygonSymbolizerPtr symbolizer,
+					   unsigned char *linecap)
+{
+/* return the Polygon Symbolizer Stroke Linecap mode */
+    rl2PrivPolygonSymbolizerPtr sym = (rl2PrivPolygonSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->stroke == NULL)
+	return RL2_ERROR;
+    *linecap = sym->stroke->linecap;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_polygon_symbolizer_get_stroke_dash_count (rl2PolygonSymbolizerPtr
+					      symbolizer, int *count)
+{
+/* return the Polygon Symbolizer Stroke Dash count */
+    rl2PrivPolygonSymbolizerPtr sym = (rl2PrivPolygonSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->stroke == NULL)
+	return RL2_ERROR;
+    *count = sym->stroke->dash_count;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_polygon_symbolizer_get_stroke_dash_item (rl2PolygonSymbolizerPtr
+					     symbolizer, int index,
+					     double *item)
+{
+/* return a Polygon Symbolizer Stroke Dash item */
+    rl2PrivPolygonSymbolizerPtr sym = (rl2PrivPolygonSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->stroke == NULL)
+	return RL2_ERROR;
+    if (sym->stroke->dash_list == NULL)
+	return RL2_ERROR;
+    if (index >= 0 && index < sym->stroke->dash_count)
+	;
+    else
+	return RL2_ERROR;
+    *item = *(sym->stroke->dash_list + index);
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_polygon_symbolizer_get_stroke_dash_offset (rl2PolygonSymbolizerPtr
+					       symbolizer, double *offset)
+{
+/* return the Polygon Symbolizer Stroke Dash initial offset */
+    rl2PrivPolygonSymbolizerPtr sym = (rl2PrivPolygonSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->stroke == NULL)
+	return RL2_ERROR;
+    *offset = sym->stroke->dash_offset;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_polygon_symbolizer_has_fill (rl2PolygonSymbolizerPtr symbolizer, int *fill)
+{
+/* checks if a Polygon Symbolizer has a Fill */
+    rl2PrivPolygonSymbolizerPtr sym = (rl2PrivPolygonSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->fill == NULL)
+	*fill = 0;
+    else
+	*fill = 1;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_polygon_symbolizer_has_graphic_fill (rl2PolygonSymbolizerPtr symbolizer,
+					 int *fill)
+{
+/* checks if a Polygon Symbolizer has a Graphic Fill */
+    rl2PrivPolygonSymbolizerPtr sym = (rl2PrivPolygonSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    *fill = 0;
+    if (sym->fill == NULL)
+	;
+    else
+      {
+	  if (sym->fill->graphic != NULL)
+	    {
+		if (sym->fill->graphic->first != NULL)
+		  {
+		      if (sym->fill->graphic->first->type ==
+			  RL2_EXTERNAL_GRAPHIC
+			  && sym->fill->graphic->first->item != NULL)
+			  *fill = 1;
+		  }
+	    }
+      }
+    return RL2_OK;
+}
+
+RL2_DECLARE const char *
+rl2_polygon_symbolizer_get_graphic_fill_href (rl2PolygonSymbolizerPtr
+					      symbolizer)
+{
+/* return an eventual Polygon Symbolizer Graphic Fill xlink:href  */
+    rl2PrivExternalGraphicPtr ext;
+    rl2PrivPolygonSymbolizerPtr sym = (rl2PrivPolygonSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return NULL;
+    if (sym->fill == NULL)
+	return NULL;
+    if (sym->fill->graphic == NULL)
+	return NULL;
+    if (sym->fill->graphic->first == NULL)
+	return NULL;
+    if (sym->fill->graphic->first->type != RL2_EXTERNAL_GRAPHIC)
+	return NULL;
+    ext = (rl2PrivExternalGraphicPtr) (sym->fill->graphic->first->item);
+    return ext->xlink_href;
+}
+
+RL2_DECLARE int
+rl2_polygon_symbolizer_get_graphic_fill_recode_count (rl2PolygonSymbolizerPtr
+						      symbolizer, int *count)
+{
+/* return how many ColorReplacement items are in a Graphic Fill (PolygonSymbolizer) */
+    rl2PrivPolygonSymbolizerPtr sym = (rl2PrivPolygonSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    *count = 0;
+    if (sym->fill != NULL)
+      {
+	  if (sym->fill->graphic != NULL)
+	    {
+		if (sym->fill->graphic->first != NULL)
+		  {
+		      if (sym->fill->graphic->first->type ==
+			  RL2_EXTERNAL_GRAPHIC
+			  && sym->fill->graphic->first->item != NULL)
+			{
+			    int cnt = 0;
+			    rl2PrivExternalGraphicPtr ext =
+				(rl2PrivExternalGraphicPtr) (sym->
+							     fill->graphic->
+							     first->item);
+			    rl2PrivColorReplacementPtr repl = ext->first;
+			    while (repl != NULL)
+			      {
+				  cnt++;
+				  repl = repl->next;
+			      }
+			    *count = cnt;
+			}
+		  }
+	    }
+      }
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_polygon_symbolizer_get_graphic_fill_recode_color (rl2PolygonSymbolizerPtr
+						      symbolizer, int index,
+						      int *color_index,
+						      unsigned char *red,
+						      unsigned char *green,
+						      unsigned char *blue)
+{
+/* return a ColorReplacement item from a Graphic Fill (PolygonSymbolizer) */
+    rl2PrivPolygonSymbolizerPtr sym = (rl2PrivPolygonSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->fill != NULL)
+      {
+	  if (sym->fill->graphic != NULL)
+	    {
+		if (sym->fill->graphic->first != NULL)
+		  {
+		      if (sym->fill->graphic->first->type ==
+			  RL2_EXTERNAL_GRAPHIC
+			  && sym->fill->graphic->first->item != NULL)
+			{
+			    int cnt = 0;
+			    rl2PrivExternalGraphicPtr ext =
+				(rl2PrivExternalGraphicPtr) (sym->
+							     fill->graphic->
+							     first->item);
+			    rl2PrivColorReplacementPtr repl = ext->first;
+			    while (repl != NULL)
+			      {
+				  if (cnt == index)
+				    {
+					*color_index = repl->index;
+					*red = repl->red;
+					*green = repl->green;
+					*blue = repl->blue;
+					return RL2_OK;
+				    }
+				  cnt++;
+				  repl = repl->next;
+			      }
+			}
+		  }
+	    }
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_polygon_symbolizer_get_fill_color (rl2PolygonSymbolizerPtr symbolizer,
+				       unsigned char *red,
+				       unsigned char *green,
+				       unsigned char *blue)
+{
+/* return the Polygon Symbolizer Fill RGB color */
+    rl2PrivPolygonSymbolizerPtr sym = (rl2PrivPolygonSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->fill == NULL)
+	return RL2_ERROR;
+    *red = sym->fill->red;
+    *green = sym->fill->green;
+    *blue = sym->fill->blue;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_polygon_symbolizer_get_fill_opacity (rl2PolygonSymbolizerPtr symbolizer,
+					 double *opacity)
+{
+/* return the Polygon Symbolizer Fill opacity */
+    rl2PrivPolygonSymbolizerPtr sym = (rl2PrivPolygonSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->fill == NULL)
+	return RL2_ERROR;
+    *opacity = sym->fill->opacity;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_polygon_symbolizer_get_perpendicular_offset (rl2PolygonSymbolizerPtr
+						 symbolizer, double *offset)
+{
+/* return the Polygon Symbolizer perpendicular offset */
+    rl2PrivPolygonSymbolizerPtr sym = (rl2PrivPolygonSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    *offset = sym->perpendicular_offset;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_polygon_symbolizer_get_displacement (rl2PolygonSymbolizerPtr symbolizer,
+					 double *x, double *y)
+{
+/* return the Polygon Symbolizer Stroke perpendicula offset */
+    rl2PrivPolygonSymbolizerPtr sym = (rl2PrivPolygonSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    *x = sym->displacement_x;
+    *y = sym->displacement_y;
+    return RL2_OK;
+}
+
+RL2_DECLARE const char *
+rl2_text_symbolizer_get_label (rl2TextSymbolizerPtr symbolizer)
+{
+/* return the Text Symbolizer label name */
+    rl2PrivTextSymbolizerPtr sym = (rl2PrivTextSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return NULL;
+    return sym->label;
+}
+
+RL2_DECLARE int
+rl2_text_symbolizer_get_font_families_count (rl2TextSymbolizerPtr symbolizer,
+					     int *count)
+{
+/* return how many Font Families are defined (Text Symbolizer) */
+    rl2PrivTextSymbolizerPtr sym = (rl2PrivTextSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    *count = sym->font_families_count;
+    return RL2_OK;
+}
+
+RL2_DECLARE const char *
+rl2_text_symbolizer_get_font_family_name (rl2TextSymbolizerPtr symbolizer,
+					  int index)
+{
+/* return the Nth Text Symbolizer FontFamily name */
+    rl2PrivTextSymbolizerPtr sym = (rl2PrivTextSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return NULL;
+    if (index >= 0 && index < sym->font_families_count)
+	return *(sym->font_families + index);
+    return NULL;
+}
+
+RL2_DECLARE int
+rl2_text_symbolizer_get_font_style (rl2TextSymbolizerPtr symbolizer,
+				    unsigned char *style)
+{
+/* return the Text Symbolizer Font Style */
+    rl2PrivTextSymbolizerPtr sym = (rl2PrivTextSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->font_style == RL2_FONT_STYLE_ITALIC
+	|| sym->font_style == RL2_FONT_STYLE_OBLIQUE)
+	*style = sym->font_style;
+    else
+	*style = RL2_FONT_STYLE_NORMAL;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_text_symbolizer_get_font_weight (rl2TextSymbolizerPtr symbolizer,
+				     unsigned char *weight)
+{
+/* return the Text Symbolizer Font Weight */
+    rl2PrivTextSymbolizerPtr sym = (rl2PrivTextSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->font_weight == RL2_FONT_WEIGHT_BOLD)
+	*weight = sym->font_weight;
+    else
+	*weight = RL2_FONT_WEIGHT_NORMAL;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_text_symbolizer_get_font_size (rl2TextSymbolizerPtr symbolizer,
+				   double *size)
+{
+/* return the Text Symbolizer Font Size */
+    rl2PrivTextSymbolizerPtr sym = (rl2PrivTextSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    *size = sym->font_size;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_text_symbolizer_get_label_placement_mode (rl2TextSymbolizerPtr symbolizer,
+					      unsigned char *mode)
+{
+/* return the Text Symbolizer LabelPlacement mode */
+    rl2PrivTextSymbolizerPtr sym = (rl2PrivTextSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->label_placement == NULL)
+	*mode = RL2_LABEL_PLACEMENT_UNKNOWN;
+    else
+      {
+	  if (sym->label_placement_type == RL2_LABEL_PLACEMENT_POINT
+	      || sym->label_placement_type == RL2_LABEL_PLACEMENT_LINE)
+	      *mode = sym->label_placement_type;
+	  else
+	      *mode = RL2_LABEL_PLACEMENT_UNKNOWN;
+      }
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_text_symbolizer_get_point_placement_anchor_point (rl2TextSymbolizerPtr
+						      symbolizer, double *x,
+						      double *y)
+{
+/* return the Text Symbolizer PointPlacement AnchorPoint */
+    rl2PrivPointPlacementPtr place;
+    rl2PrivTextSymbolizerPtr sym = (rl2PrivTextSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->label_placement_type != RL2_LABEL_PLACEMENT_POINT
+	|| sym->label_placement == NULL)
+	return RL2_ERROR;
+    place = (rl2PrivPointPlacementPtr) (sym->label_placement);
+    *x = place->anchor_point_x;
+    *y = place->anchor_point_y;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_text_symbolizer_get_point_placement_displacement (rl2TextSymbolizerPtr
+						      symbolizer, double *x,
+						      double *y)
+{
+/* return the Text Symbolizer PointPlacement Displacement */
+    rl2PrivPointPlacementPtr place;
+    rl2PrivTextSymbolizerPtr sym = (rl2PrivTextSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->label_placement_type != RL2_LABEL_PLACEMENT_POINT
+	|| sym->label_placement == NULL)
+	return RL2_ERROR;
+    place = (rl2PrivPointPlacementPtr) (sym->label_placement);
+    *x = place->displacement_x;
+    *y = place->displacement_y;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_text_symbolizer_get_point_placement_rotation (rl2TextSymbolizerPtr
+						  symbolizer, double *rotation)
+{
+/* return the Text Symbolizer PointPlacement Rotation */
+    rl2PrivPointPlacementPtr place;
+    rl2PrivTextSymbolizerPtr sym = (rl2PrivTextSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->label_placement_type != RL2_LABEL_PLACEMENT_POINT
+	|| sym->label_placement == NULL)
+	return RL2_ERROR;
+    place = (rl2PrivPointPlacementPtr) (sym->label_placement);
+    *rotation = place->rotation;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+    rl2_text_symbolizer_get_line_placement_perpendicular_offset
+    (rl2TextSymbolizerPtr symbolizer, double *offset)
+{
+/* return the Text Symbolizer LinePlacement PerpendicularOffset */
+    rl2PrivLinePlacementPtr place;
+    rl2PrivTextSymbolizerPtr sym = (rl2PrivTextSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->label_placement_type != RL2_LABEL_PLACEMENT_LINE
+	|| sym->label_placement == NULL)
+	return RL2_ERROR;
+    place = (rl2PrivLinePlacementPtr) (sym->label_placement);
+    *offset = place->perpendicular_offset;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_text_symbolizer_get_line_placement_is_repeated (rl2TextSymbolizerPtr
+						    symbolizer,
+						    int *is_repeated)
+{
+/* return the Text Symbolizer LinePlacement IsRepeated */
+    rl2PrivLinePlacementPtr place;
+    rl2PrivTextSymbolizerPtr sym = (rl2PrivTextSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->label_placement_type != RL2_LABEL_PLACEMENT_LINE
+	|| sym->label_placement == NULL)
+	return RL2_ERROR;
+    place = (rl2PrivLinePlacementPtr) (sym->label_placement);
+    *is_repeated = place->is_repeated;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_text_symbolizer_get_line_placement_initial_gap (rl2TextSymbolizerPtr
+						    symbolizer, double *gap)
+{
+/* return the Text Symbolizer LinePlacement InitialGap */
+    rl2PrivLinePlacementPtr place;
+    rl2PrivTextSymbolizerPtr sym = (rl2PrivTextSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->label_placement_type != RL2_LABEL_PLACEMENT_LINE
+	|| sym->label_placement == NULL)
+	return RL2_ERROR;
+    place = (rl2PrivLinePlacementPtr) (sym->label_placement);
+    *gap = place->initial_gap;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_text_symbolizer_get_line_placement_gap (rl2TextSymbolizerPtr symbolizer,
+					    double *gap)
+{
+/* return the Text Symbolizer LinePlacement Gap */
+    rl2PrivLinePlacementPtr place;
+    rl2PrivTextSymbolizerPtr sym = (rl2PrivTextSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->label_placement_type != RL2_LABEL_PLACEMENT_LINE
+	|| sym->label_placement == NULL)
+	return RL2_ERROR;
+    place = (rl2PrivLinePlacementPtr) (sym->label_placement);
+    *gap = place->gap;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_text_symbolizer_get_line_placement_is_aligned (rl2TextSymbolizerPtr
+						   symbolizer, int *is_aligned)
+{
+/* return the Text Symbolizer LinePlacement IsAligned */
+    rl2PrivLinePlacementPtr place;
+    rl2PrivTextSymbolizerPtr sym = (rl2PrivTextSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->label_placement_type != RL2_LABEL_PLACEMENT_LINE
+	|| sym->label_placement == NULL)
+	return RL2_ERROR;
+    place = (rl2PrivLinePlacementPtr) (sym->label_placement);
+    *is_aligned = place->is_aligned;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_text_symbolizer_get_line_placement_generalize_line (rl2TextSymbolizerPtr
+							symbolizer,
+							int *generalize_line)
+{
+/* return the Text Symbolizer LinePlacement GeneralizeLine */
+    rl2PrivLinePlacementPtr place;
+    rl2PrivTextSymbolizerPtr sym = (rl2PrivTextSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->label_placement_type != RL2_LABEL_PLACEMENT_LINE
+	|| sym->label_placement == NULL)
+	return RL2_ERROR;
+    place = (rl2PrivLinePlacementPtr) (sym->label_placement);
+    *generalize_line = place->generalize_line;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_text_symbolizer_has_halo (rl2TextSymbolizerPtr symbolizer, int *halo)
+{
+/* checks if a Text Symbolizer has an Halo */
+    rl2PrivTextSymbolizerPtr sym = (rl2PrivTextSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->halo == NULL)
+	*halo = 0;
+    else
+	*halo = 1;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_text_symbolizer_get_halo_radius (rl2TextSymbolizerPtr symbolizer,
+				     double *radius)
+{
+/* return the Text Symbolizer Halo Radius */
+    rl2PrivTextSymbolizerPtr sym = (rl2PrivTextSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->halo == NULL)
+	return RL2_ERROR;
+    *radius = sym->halo->radius;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_text_symbolizer_has_halo_fill (rl2TextSymbolizerPtr symbolizer, int *fill)
+{
+/* checks if a Text Symbolizer Halo has a Fill */
+    rl2PrivTextSymbolizerPtr sym = (rl2PrivTextSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->halo == NULL)
+	return RL2_ERROR;
+    if (sym->halo->fill == NULL)
+	*fill = 0;
+    else
+	*fill = 1;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_text_symbolizer_get_halo_fill_color (rl2TextSymbolizerPtr symbolizer,
+					 unsigned char *red,
+					 unsigned char *green,
+					 unsigned char *blue)
+{
+/* return the Text Symbolizer Halo Fill RGB color */
+    rl2PrivTextSymbolizerPtr sym = (rl2PrivTextSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->halo == NULL)
+	return RL2_ERROR;
+    if (sym->halo->fill == NULL)
+	return RL2_ERROR;
+    *red = sym->halo->fill->red;
+    *green = sym->halo->fill->green;
+    *blue = sym->halo->fill->blue;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_text_symbolizer_has_fill (rl2TextSymbolizerPtr symbolizer, int *fill)
+{
+/* checks if a Text Symbolizer has a Fill */
+    rl2PrivTextSymbolizerPtr sym = (rl2PrivTextSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->fill == NULL)
+	*fill = 0;
+    else
+	*fill = 1;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_text_symbolizer_get_fill_color (rl2TextSymbolizerPtr symbolizer,
+				    unsigned char *red,
+				    unsigned char *green, unsigned char *blue)
+{
+/* return the Text Symbolizer Fill RGB color */
+    rl2PrivTextSymbolizerPtr sym = (rl2PrivTextSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->fill == NULL)
+	return RL2_ERROR;
+    *red = sym->fill->red;
+    *green = sym->fill->green;
+    *blue = sym->fill->blue;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_point_symbolizer_get_count (rl2PointSymbolizerPtr symbolizer, int *count)
+{
+/* return the Point Symbolizer items count */
+    int cnt = 0;
+    rl2PrivGraphicItemPtr item;
+    rl2PrivPointSymbolizerPtr sym = (rl2PrivPointSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->graphic == NULL)
+	return RL2_ERROR;
+    item = sym->graphic->first;
+    while (item != NULL)
+      {
+	  cnt++;
+	  item = item->next;
+      }
+    *count = cnt;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_point_symbolizer_is_graphic (rl2PointSymbolizerPtr symbolizer, int index,
+				 int *external_graphic)
+{
+/* checks if a Point Symbolizer item is an External Graphic */
+    int count = 0;
+    rl2PrivGraphicItemPtr item;
+    rl2PrivPointSymbolizerPtr sym = (rl2PrivPointSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->graphic == NULL)
+	return RL2_ERROR;
+    item = sym->graphic->first;
+    while (item != NULL)
+      {
+	  if (count == index)
+	    {
+		if (item->type == RL2_EXTERNAL_GRAPHIC && item->item != NULL)
+		    *external_graphic = 1;
+		else
+		    *external_graphic = 0;
+		return RL2_OK;
+	    }
+	  count++;
+	  item = item->next;
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE const char *
+rl2_point_symbolizer_get_graphic_href (rl2PointSymbolizerPtr symbolizer,
+				       int index)
+{
+/* return the Point Symbolizer External Graphic xlink:href */
+    int count = 0;
+    rl2PrivExternalGraphicPtr ext;
+    rl2PrivGraphicItemPtr item;
+    rl2PrivPointSymbolizerPtr sym = (rl2PrivPointSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return NULL;
+    if (sym->graphic == NULL)
+	return NULL;
+    item = sym->graphic->first;
+    while (item != NULL)
+      {
+	  if (count == index)
+	    {
+		if (item->type == RL2_EXTERNAL_GRAPHIC && item->item != NULL)
+		    ext = (rl2PrivExternalGraphicPtr) (item->item);
+		else
+		    return NULL;
+		return ext->xlink_href;
+	    }
+	  count++;
+	  item = item->next;
+      }
+    return NULL;
+}
+
+RL2_DECLARE int
+rl2_point_symbolizer_get_graphic_recode_color (rl2PointSymbolizerPtr
+					       symbolizer, int index,
+					       int repl_index,
+					       int *color_index,
+					       unsigned char *red,
+					       unsigned char *green,
+					       unsigned char *blue)
+{
+/* return a ColorReplacement item from an External Graphic (PointSymbolizer) */
+    int count = 0;
+    rl2PrivExternalGraphicPtr ext;
+    rl2PrivGraphicItemPtr item;
+    rl2PrivPointSymbolizerPtr sym = (rl2PrivPointSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->graphic == NULL)
+	return RL2_ERROR;
+    item = sym->graphic->first;
+    while (item != NULL)
+      {
+	  if (count == index)
+	    {
+		int cnt = 0;
+		rl2PrivColorReplacementPtr repl;
+		if (item->type == RL2_EXTERNAL_GRAPHIC && item->item != NULL)
+		    ext = (rl2PrivExternalGraphicPtr) (item->item);
+		else
+		    return RL2_ERROR;
+		repl = ext->first;
+		while (repl != NULL)
+		  {
+		      if (cnt == repl_index)
+			{
+			    *color_index = repl->index;
+			    *red = repl->red;
+			    *green = repl->green;
+			    *blue = repl->blue;
+			    return RL2_OK;
+			}
+		      cnt++;
+		      repl = repl->next;
+		  }
+		return RL2_ERROR;
+	    }
+	  count++;
+	  item = item->next;
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_point_symbolizer_is_mark (rl2PointSymbolizerPtr symbolizer, int index,
+			      int *mark)
+{
+/* checks if a Point Symbolizer item is a Mark */
+    int count = 0;
+    rl2PrivGraphicItemPtr item;
+    rl2PrivPointSymbolizerPtr sym = (rl2PrivPointSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->graphic == NULL)
+	return RL2_ERROR;
+    item = sym->graphic->first;
+    while (item != NULL)
+      {
+	  if (count == index)
+	    {
+		if (item->type == RL2_MARK_GRAPHIC && item->item != NULL)
+		    *mark = 1;
+		else
+		    *mark = 0;
+		return RL2_OK;
+	    }
+	  count++;
+	  item = item->next;
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_point_symbolizer_mark_get_well_known_type (rl2PointSymbolizerPtr
+					       symbolizer, int index,
+					       unsigned char *type)
+{
+/* return the Point Symbolizer Mark WellKnownType */
+    int count = 0;
+    rl2PrivMarkPtr mark;
+    rl2PrivGraphicItemPtr item;
+    rl2PrivPointSymbolizerPtr sym = (rl2PrivPointSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->graphic == NULL)
+	return RL2_ERROR;
+    item = sym->graphic->first;
+    while (item != NULL)
+      {
+	  if (count == index)
+	    {
+		if (item->type == RL2_MARK_GRAPHIC && item->item != NULL)
+		    mark = (rl2PrivMarkPtr) (item->item);
+		else
+		    return RL2_ERROR;
+		switch (mark->well_known_type)
+		  {
+		  case RL2_GRAPHIC_MARK_SQUARE:
+		  case RL2_GRAPHIC_MARK_CIRCLE:
+		  case RL2_GRAPHIC_MARK_TRIANGLE:
+		  case RL2_GRAPHIC_MARK_STAR:
+		  case RL2_GRAPHIC_MARK_CROSS:
+		  case RL2_GRAPHIC_MARK_X:
+		      *type = mark->well_known_type;
+		      break;
+		  default:
+		      *type = RL2_GRAPHIC_MARK_UNKNOWN;
+		      break;
+		  };
+		return RL2_OK;
+	    }
+	  count++;
+	  item = item->next;
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_point_symbolizer_mark_has_stroke (rl2PointSymbolizerPtr symbolizer,
+				      int index, int *stroke)
+{
+/* checks if a Point Symbolizer Mark has a Stroke */
+    int count = 0;
+    rl2PrivMarkPtr mark;
+    rl2PrivGraphicItemPtr item;
+    rl2PrivPointSymbolizerPtr sym = (rl2PrivPointSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->graphic == NULL)
+	return RL2_ERROR;
+    item = sym->graphic->first;
+    while (item != NULL)
+      {
+	  if (count == index)
+	    {
+		if (item->type == RL2_MARK_GRAPHIC && item->item != NULL)
+		    mark = (rl2PrivMarkPtr) (item->item);
+		else
+		    return RL2_ERROR;
+		if (mark->stroke == NULL)
+		    *stroke = 0;
+		else
+		    *stroke = 1;
+		return RL2_OK;
+	    }
+	  count++;
+	  item = item->next;
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_point_symbolizer_mark_get_stroke_color (rl2PointSymbolizerPtr symbolizer,
+					    int index, unsigned char *red,
+					    unsigned char *green,
+					    unsigned char *blue)
+{
+/* return the Point Symbolizer Mark Stroke RGB color */
+    int count = 0;
+    rl2PrivMarkPtr mark;
+    rl2PrivGraphicItemPtr item;
+    rl2PrivPointSymbolizerPtr sym = (rl2PrivPointSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->graphic == NULL)
+	return RL2_ERROR;
+    item = sym->graphic->first;
+    while (item != NULL)
+      {
+	  if (count == index)
+	    {
+		if (item->type == RL2_MARK_GRAPHIC && item->item != NULL)
+		    mark = (rl2PrivMarkPtr) (item->item);
+		else
+		    return RL2_ERROR;
+		if (mark->stroke == NULL)
+		    return RL2_ERROR;
+		*red = mark->stroke->red;
+		*green = mark->stroke->green;
+		*blue = mark->stroke->blue;
+		return RL2_OK;
+	    }
+	  count++;
+	  item = item->next;
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_point_symbolizer_mark_get_stroke_width (rl2PointSymbolizerPtr symbolizer,
+					    int index, double *width)
+{
+/* return the Point Symbolizer Mark Stroke width */
+    int count = 0;
+    rl2PrivMarkPtr mark;
+    rl2PrivGraphicItemPtr item;
+    rl2PrivPointSymbolizerPtr sym = (rl2PrivPointSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->graphic == NULL)
+	return RL2_ERROR;
+    item = sym->graphic->first;
+    while (item != NULL)
+      {
+	  if (count == index)
+	    {
+		if (item->type == RL2_MARK_GRAPHIC && item->item != NULL)
+		    mark = (rl2PrivMarkPtr) (item->item);
+		else
+		    return RL2_ERROR;
+		if (mark->stroke == NULL)
+		    return RL2_ERROR;
+		*width = mark->stroke->width;
+		return RL2_OK;
+	    }
+	  count++;
+	  item = item->next;
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_point_symbolizer_mark_get_stroke_linejoin (rl2PointSymbolizerPtr
+					       symbolizer, int index,
+					       unsigned char *linejoin)
+{
+/* return the Point Symbolizer Mark Stroke Linejoin mode */
+    int count = 0;
+    rl2PrivMarkPtr mark;
+    rl2PrivGraphicItemPtr item;
+    rl2PrivPointSymbolizerPtr sym = (rl2PrivPointSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->graphic == NULL)
+	return RL2_ERROR;
+    item = sym->graphic->first;
+    while (item != NULL)
+      {
+	  if (count == index)
+	    {
+		if (item->type == RL2_MARK_GRAPHIC && item->item != NULL)
+		    mark = (rl2PrivMarkPtr) (item->item);
+		else
+		    return RL2_ERROR;
+		if (mark->stroke == NULL)
+		    return RL2_ERROR;
+		*linejoin = mark->stroke->linejoin;
+		return RL2_OK;
+	    }
+	  count++;
+	  item = item->next;
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_point_symbolizer_mark_get_stroke_linecap (rl2PointSymbolizerPtr
+					      symbolizer, int index,
+					      unsigned char *linecap)
+{
+/* return the Point Symbolizer Stroke Mark Linecap mode */
+    int count = 0;
+    rl2PrivMarkPtr mark;
+    rl2PrivGraphicItemPtr item;
+    rl2PrivPointSymbolizerPtr sym = (rl2PrivPointSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->graphic == NULL)
+	return RL2_ERROR;
+    item = sym->graphic->first;
+    while (item != NULL)
+      {
+	  if (count == index)
+	    {
+		if (item->type == RL2_MARK_GRAPHIC && item->item != NULL)
+		    mark = (rl2PrivMarkPtr) (item->item);
+		else
+		    return RL2_ERROR;
+		if (mark->stroke == NULL)
+		    return RL2_ERROR;
+		*linecap = mark->stroke->linecap;
+		return RL2_OK;
+	    }
+	  count++;
+	  item = item->next;
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_point_symbolizer_mark_get_stroke_dash_count (rl2PointSymbolizerPtr
+						 symbolizer, int index,
+						 int *cnt)
+{
+/* return the Point Symbolizer Mark Stroke Dash count */
+    int count = 0;
+    rl2PrivMarkPtr mark;
+    rl2PrivGraphicItemPtr item;
+    rl2PrivPointSymbolizerPtr sym = (rl2PrivPointSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->graphic == NULL)
+	return RL2_ERROR;
+    item = sym->graphic->first;
+    while (item != NULL)
+      {
+	  if (count == index)
+	    {
+		if (item->type == RL2_MARK_GRAPHIC && item->item != NULL)
+		    mark = (rl2PrivMarkPtr) (item->item);
+		else
+		    return RL2_ERROR;
+		if (mark->stroke == NULL)
+		    return RL2_ERROR;
+		*cnt = mark->stroke->dash_count;
+		return RL2_OK;
+	    }
+	  count++;
+	  item = item->next;
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_point_symbolizer_mark_get_stroke_dash_item (rl2PointSymbolizerPtr
+						symbolizer, int index,
+						int item_index, double *item)
+{
+/* return a Point Symbolizer Mark Stroke Dash item */
+    int count = 0;
+    rl2PrivMarkPtr mark;
+    rl2PrivGraphicItemPtr itm;
+    rl2PrivPointSymbolizerPtr sym = (rl2PrivPointSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->graphic == NULL)
+	return RL2_ERROR;
+    itm = sym->graphic->first;
+    while (itm != NULL)
+      {
+	  if (count == index)
+	    {
+		if (itm->type == RL2_MARK_GRAPHIC && itm->item != NULL)
+		    mark = (rl2PrivMarkPtr) (itm->item);
+		else
+		    return RL2_ERROR;
+		if (mark->stroke == NULL)
+		    return RL2_ERROR;
+		if (mark->stroke->dash_list == NULL)
+		    return RL2_ERROR;
+		if (item_index >= 0 && item_index < mark->stroke->dash_count)
+		    ;
+		else
+		    return RL2_ERROR;
+		*item = *(mark->stroke->dash_list + item_index);
+		return RL2_OK;
+	    }
+	  count++;
+	  itm = itm->next;
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_point_symbolizer_mark_get_stroke_dash_offset (rl2PointSymbolizerPtr
+						  symbolizer, int index,
+						  double *offset)
+{
+/* return the Point Symbolizer Mark Stroke Dash initial offset */
+    int count = 0;
+    rl2PrivMarkPtr mark;
+    rl2PrivGraphicItemPtr itm;
+    rl2PrivPointSymbolizerPtr sym = (rl2PrivPointSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->graphic == NULL)
+	return RL2_ERROR;
+    itm = sym->graphic->first;
+    while (itm != NULL)
+      {
+	  if (count == index)
+	    {
+		if (itm->type == RL2_MARK_GRAPHIC && itm->item != NULL)
+		    mark = (rl2PrivMarkPtr) (itm->item);
+		else
+		    return RL2_ERROR;
+		if (mark->stroke == NULL)
+		    return RL2_ERROR;
+		*offset = mark->stroke->dash_offset;
+		return RL2_OK;
+	    }
+	  count++;
+	  itm = itm->next;
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_point_symbolizer_mark_has_fill (rl2PointSymbolizerPtr symbolizer,
+				    int index, int *fill)
+{
+/* checks if a Point Symbolizer Mark has a Fill */
+    int count = 0;
+    rl2PrivMarkPtr mark;
+    rl2PrivGraphicItemPtr item;
+    rl2PrivPointSymbolizerPtr sym = (rl2PrivPointSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->graphic == NULL)
+	return RL2_ERROR;
+    item = sym->graphic->first;
+    while (item != NULL)
+      {
+	  if (count == index)
+	    {
+		if (item->type == RL2_MARK_GRAPHIC && item->item != NULL)
+		    mark = (rl2PrivMarkPtr) (item->item);
+		else
+		    return RL2_ERROR;
+		if (mark->fill == NULL)
+		    *fill = 0;
+		else
+		    *fill = 1;
+		return RL2_OK;
+	    }
+	  count++;
+	  item = item->next;
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_point_symbolizer_mark_get_fill_color (rl2PointSymbolizerPtr symbolizer,
+					  int index, unsigned char *red,
+					  unsigned char *green,
+					  unsigned char *blue)
+{
+/* return the Point Symbolizer Mark Fill RGB color */
+    int count = 0;
+    rl2PrivMarkPtr mark;
+    rl2PrivGraphicItemPtr item;
+    rl2PrivPointSymbolizerPtr sym = (rl2PrivPointSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->graphic == NULL)
+	return RL2_ERROR;
+    item = sym->graphic->first;
+    while (item != NULL)
+      {
+	  if (count == index)
+	    {
+		if (item->type == RL2_MARK_GRAPHIC && item->item != NULL)
+		    mark = (rl2PrivMarkPtr) (item->item);
+		else
+		    return RL2_ERROR;
+		*red = mark->fill->red;
+		*green = mark->fill->green;
+		*blue = mark->fill->blue;
+		return RL2_OK;
+	    }
+	  count++;
+	  item = item->next;
+      }
+    return RL2_ERROR;
+}
+
+RL2_DECLARE int
+rl2_point_symbolizer_get_opacity (rl2PointSymbolizerPtr symbolizer,
+				  double *opacity)
+{
+/* return a Point Symbolizer Opacity */
+    rl2PrivPointSymbolizerPtr sym = (rl2PrivPointSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->graphic == NULL)
+	return RL2_ERROR;
+    *opacity = sym->graphic->opacity;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_point_symbolizer_get_size (rl2PointSymbolizerPtr symbolizer, double *size)
+{
+/* return a Point Symbolizer Size */
+    rl2PrivPointSymbolizerPtr sym = (rl2PrivPointSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->graphic == NULL)
+	return RL2_ERROR;
+    *size = sym->graphic->size;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_point_symbolizer_get_rotation (rl2PointSymbolizerPtr symbolizer,
+				   double *rotation)
+{
+/* return a Point Symbolizer Rotation */
+    rl2PrivPointSymbolizerPtr sym = (rl2PrivPointSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->graphic == NULL)
+	return RL2_ERROR;
+    *rotation = sym->graphic->rotation;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_point_symbolizer_get_anchor_point (rl2PointSymbolizerPtr symbolizer,
+				       double *x, double *y)
+{
+/* return a Point Symbolizer Anchor Point */
+    rl2PrivPointSymbolizerPtr sym = (rl2PrivPointSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->graphic == NULL)
+	return RL2_ERROR;
+    *x = sym->graphic->anchor_point_x;
+    *y = sym->graphic->anchor_point_y;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_point_symbolizer_get_displacement (rl2PointSymbolizerPtr symbolizer,
+				       double *x, double *y)
+{
+/* return a Point Symbolizer Displacement */
+    rl2PrivPointSymbolizerPtr sym = (rl2PrivPointSymbolizerPtr) symbolizer;
+    if (sym == NULL)
+	return RL2_ERROR;
+    if (sym->graphic == NULL)
+	return RL2_ERROR;
+    *x = sym->graphic->displacement_x;
+    *y = sym->graphic->displacement_y;
+    return RL2_OK;
+}
+
+RL2_PRIVATE void
+rl2_destroy_color_replacement (rl2PrivColorReplacementPtr repl)
+{
+/* destroying a Color Replacement object */
+    if (repl == NULL)
+	return;
+    free (repl);
+}
+
+RL2_PRIVATE void
+rl2_destroy_external_graphic (rl2PrivExternalGraphicPtr ext)
+{
+/* destroying an External Graphic object */
+    rl2PrivColorReplacementPtr repl;
+    rl2PrivColorReplacementPtr replN;
+    if (ext == NULL)
+	return;
+    if (ext->xlink_href != NULL)
+	free (ext->xlink_href);
+    repl = ext->first;
+    while (repl != NULL)
+      {
+	  replN = repl->next;
+	  rl2_destroy_color_replacement (repl);
+	  repl = replN;
+      }
+    free (ext);
+}
+
+RL2_PRIVATE void
+rl2_destroy_mark (rl2PrivMarkPtr mark)
+{
+/* destroying a Mark object */
+    if (mark == NULL)
+	return;
+    if (mark->external_graphic != NULL)
+	rl2_destroy_external_graphic (mark->external_graphic);
+    if (mark->stroke != NULL)
+	rl2_destroy_stroke (mark->stroke);
+    if (mark->fill != NULL)
+	rl2_destroy_fill (mark->fill);
+    free (mark);
+}
+
+RL2_PRIVATE void
+rl2_destroy_graphic_item (rl2PrivGraphicItemPtr item)
+{
+/* destroying a Graphic Item object */
+    if (item == NULL)
+	return;
+    if (item->type == RL2_EXTERNAL_GRAPHIC)
+	rl2_destroy_external_graphic ((rl2PrivExternalGraphicPtr) (item->item));
+    if (item->type == RL2_MARK_GRAPHIC)
+	rl2_destroy_mark ((rl2PrivMarkPtr) (item->item));
+    free (item);
+}
+
+RL2_PRIVATE void
+rl2_destroy_graphic (rl2PrivGraphicPtr graphic)
+{
+/* destroying a Graphic object */
+    rl2PrivGraphicItemPtr item;
+    rl2PrivGraphicItemPtr itemN;
+    if (graphic == NULL)
+	return;
+    item = graphic->first;
+    while (item != NULL)
+      {
+	  itemN = item->next;
+	  rl2_destroy_graphic_item (item);
+	  item = itemN;
+      }
+    free (graphic);
+}
+
+RL2_PRIVATE void
+rl2_destroy_stroke (rl2PrivStrokePtr stroke)
+{
+/* destroying a Stroke object */
+    if (stroke == NULL)
+	return;
+    if (stroke->graphic != NULL)
+	rl2_destroy_graphic (stroke->graphic);
+    if (stroke->dash_list != NULL)
+	free (stroke->dash_list);
+    free (stroke);
+}
+
+RL2_PRIVATE void
+rl2_destroy_fill (rl2PrivFillPtr fill)
+{
+/* destroying a Fill object */
+    if (fill == NULL)
+	return;
+    if (fill->graphic != NULL)
+	rl2_destroy_graphic (fill->graphic);
+    free (fill);
+}
+
+RL2_PRIVATE void
+rl2_destroy_point_symbolizer (rl2PrivPointSymbolizerPtr ptr)
+{
+/* destroying a Point Symbolizer */
+    if (ptr == NULL)
+	return;
+    if (ptr->graphic != NULL)
+	rl2_destroy_graphic (ptr->graphic);
+    free (ptr);
+}
+
+RL2_PRIVATE void
+rl2_destroy_line_symbolizer (rl2PrivLineSymbolizerPtr ptr)
+{
+/* destroying a Line Symbolizer */
+    if (ptr == NULL)
+	return;
+    if (ptr->stroke != NULL)
+	rl2_destroy_stroke (ptr->stroke);
+    free (ptr);
+}
+
+RL2_PRIVATE void
+rl2_destroy_polygon_symbolizer (rl2PrivPolygonSymbolizerPtr ptr)
+{
+/* destroying a Polygon Symbolizer */
+    if (ptr == NULL)
+	return;
+    if (ptr->stroke != NULL)
+	rl2_destroy_stroke (ptr->stroke);
+    if (ptr->fill != NULL)
+	rl2_destroy_fill (ptr->fill);
+    free (ptr);
+}
+
+RL2_PRIVATE void
+rl2_destroy_point_placement (rl2PrivPointPlacementPtr place)
+{
+/* destroying a PointPlacement object */
+    if (place == NULL)
+	return;
+    free (place);
+}
+
+RL2_PRIVATE void
+rl2_destroy_line_placement (rl2PrivLinePlacementPtr place)
+{
+/* destroying a LinePlacement object */
+    if (place == NULL)
+	return;
+    free (place);
+}
+
+RL2_PRIVATE void
+rl2_destroy_halo (rl2PrivHaloPtr halo)
+{
+/* destroying an Halo object */
+    if (halo == NULL)
+	return;
+    if (halo->fill != NULL)
+	rl2_destroy_fill (halo->fill);
+    free (halo);
+}
+
+RL2_PRIVATE void
+rl2_destroy_text_symbolizer (rl2PrivTextSymbolizerPtr ptr)
+{
+/* destroying a Text Symbolizer */
+    int i;
+    if (ptr == NULL)
+	return;
+    if (ptr->label != NULL)
+	free (ptr->label);
+    for (i = 0; i < RL2_MAX_FONT_FAMILIES; i++)
+      {
+	  if (*(ptr->font_families + i) != NULL)
+	      free (*(ptr->font_families + i));
+      }
+    if (ptr->label_placement_type == RL2_LABEL_PLACEMENT_POINT
+	&& ptr->label_placement != NULL)
+	rl2_destroy_point_placement ((rl2PrivPointPlacementPtr)
+				     (ptr->label_placement));
+    if (ptr->label_placement_type == RL2_LABEL_PLACEMENT_LINE
+	&& ptr->label_placement != NULL)
+	rl2_destroy_line_placement ((rl2PrivLinePlacementPtr)
+				    (ptr->label_placement));
+    if (ptr->halo != NULL)
+	rl2_destroy_halo (ptr->halo);
+    if (ptr->fill != NULL)
+	rl2_destroy_fill (ptr->fill);
+    free (ptr);
+}
+
+RL2_PRIVATE void
+rl2_destroy_vector_symbolizer_item (rl2PrivVectorSymbolizerItemPtr item)
+{
+/* destroying a VectorSymbolizerItem object */
+    if (item == NULL)
+	return;
+
+    if (item->symbolizer_type == RL2_POINT_SYMBOLIZER)
+	rl2_destroy_point_symbolizer ((rl2PrivPointSymbolizerPtr)
+				      (item->symbolizer));
+    if (item->symbolizer_type == RL2_LINE_SYMBOLIZER)
+	rl2_destroy_line_symbolizer ((rl2PrivLineSymbolizerPtr)
+				     (item->symbolizer));
+    if (item->symbolizer_type == RL2_POLYGON_SYMBOLIZER)
+	rl2_destroy_polygon_symbolizer ((rl2PrivPolygonSymbolizerPtr)
+					(item->symbolizer));
+    if (item->symbolizer_type == RL2_TEXT_SYMBOLIZER)
+	rl2_destroy_text_symbolizer ((rl2PrivTextSymbolizerPtr)
+				     (item->symbolizer));
+    free (item);
+}
+
+RL2_PRIVATE void
+rl2_destroy_vector_symbolizer (rl2PrivVectorSymbolizerPtr symbolizer)
+{
+/* destroying a VectorSymbolizer object */
+    rl2PrivVectorSymbolizerItemPtr item;
+    rl2PrivVectorSymbolizerItemPtr itemN;
+    if (symbolizer == NULL)
+	return;
+
+    item = symbolizer->first;
+    while (item != NULL)
+      {
+	  itemN = item->next;
+	  rl2_destroy_vector_symbolizer_item (item);
+	  item = itemN;
+      }
+    free (symbolizer);
+}
+
+RL2_DECLARE void
+rl2_destroy_group_style (rl2GroupStylePtr style)
+{
+/* destroying a Group Style object */
+    rl2PrivChildStylePtr child;
+    rl2PrivChildStylePtr child_n;
+    rl2PrivGroupStylePtr stl = (rl2PrivGroupStylePtr) style;
+    if (stl == NULL)
+	return;
+
+    if (stl->name != NULL)
+	free (stl->name);
+    child = stl->first;
+    while (child != NULL)
+      {
+	  child_n = child->next;
+	  if (child->namedLayer != NULL)
+	      free (child->namedLayer);
+	  if (child->namedStyle != NULL)
+	      free (child->namedStyle);
+	  free (child);
+	  child = child_n;
+      }
+    free (stl);
+}
+
+RL2_DECLARE const char *
+rl2_get_group_style_name (rl2GroupStylePtr style)
+{
+/* return the Group Style Name */
+    rl2PrivGroupStylePtr stl = (rl2PrivGroupStylePtr) style;
+    if (stl == NULL)
+	return NULL;
+    return stl->name;
+}
+
+RL2_DECLARE int
+rl2_is_valid_group_style (rl2GroupStylePtr style, int *valid)
+{
+/* testing a Group Style for validity */
+    rl2PrivGroupStylePtr stl = (rl2PrivGroupStylePtr) style;
+    if (stl == NULL)
+	return RL2_ERROR;
+    *valid = stl->valid;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_get_group_style_count (rl2GroupStylePtr style, int *count)
+{
+/* return the total count of Group Style Items */
+    int cnt = 0;
+    rl2PrivChildStylePtr child;
+    rl2PrivGroupStylePtr stl = (rl2PrivGroupStylePtr) style;
+    if (stl == NULL)
+	return RL2_ERROR;
+    child = stl->first;
+    while (child != NULL)
+      {
+	  /* counting how many Children */
+	  cnt++;
+	  child = child->next;
+      }
+    *count = cnt;
+    return RL2_OK;
+}
+
+RL2_DECLARE const char *
+rl2_get_group_named_layer (rl2GroupStylePtr style, int index)
+{
+/* return the Nth NamedLayer from a Group Style */
+    int cnt = 0;
+    const char *str = NULL;
+    rl2PrivChildStylePtr child;
+    rl2PrivGroupStylePtr stl = (rl2PrivGroupStylePtr) style;
+    if (stl == NULL)
+	return NULL;
+    if (index < 0)
+	return NULL;
+    child = stl->first;
+    while (child != NULL)
+      {
+	  /* counting how many Children */
+	  cnt++;
+	  child = child->next;
+      }
+    if (index >= cnt)
+	return NULL;
+    cnt = 0;
+    child = stl->first;
+    while (child != NULL)
+      {
+	  if (cnt == index)
+	    {
+		str = child->namedLayer;
+		break;
+	    }
+	  cnt++;
+	  child = child->next;
+      }
+    return str;
+}
+
+RL2_DECLARE const char *
+rl2_get_group_named_style (rl2GroupStylePtr style, int index)
+{
+/* return the Nth NamedStyle from a Group Style */
+    int cnt = 0;
+    const char *str = NULL;
+    rl2PrivChildStylePtr child;
+    rl2PrivGroupStylePtr stl = (rl2PrivGroupStylePtr) style;
+    if (stl == NULL)
+	return NULL;
+    if (index < 0)
+	return NULL;
+    child = stl->first;
+    while (child != NULL)
+      {
+	  /* counting how many Children */
+	  cnt++;
+	  child = child->next;
+      }
+    if (index >= cnt)
+	return NULL;
+    cnt = 0;
+    child = stl->first;
+    while (child != NULL)
+      {
+	  if (cnt == index)
+	    {
+		str = child->namedStyle;
+		break;
+	    }
+	  cnt++;
+	  child = child->next;
+      }
+    return str;
+}
+
+RL2_DECLARE int
+rl2_is_valid_group_named_layer (rl2GroupStylePtr style, int index, int *valid)
+{
+/* testing for validity the Nth NamedLayer from a Group Style */
+    int cnt = 0;
+    rl2PrivChildStylePtr child;
+    rl2PrivGroupStylePtr stl = (rl2PrivGroupStylePtr) style;
+    if (stl == NULL)
+	return RL2_ERROR;
+    if (index < 0)
+	return RL2_ERROR;
+    child = stl->first;
+    while (child != NULL)
+      {
+	  /* counting how many Children */
+	  cnt++;
+	  child = child->next;
+      }
+    if (index >= cnt)
+	return RL2_ERROR;
+    cnt = 0;
+    child = stl->first;
+    while (child != NULL)
+      {
+	  if (cnt == index)
+	    {
+		*valid = child->validLayer;
+		break;
+	    }
+	  cnt++;
+	  child = child->next;
+      }
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_is_valid_group_named_style (rl2GroupStylePtr style, int index, int *valid)
+{
+/* testing for validity the Nth NamedStyle from a Group Style */
+    int cnt = 0;
+    rl2PrivChildStylePtr child;
+    rl2PrivGroupStylePtr stl = (rl2PrivGroupStylePtr) style;
+    if (stl == NULL)
+	return RL2_ERROR;
+    if (index < 0)
+	return RL2_ERROR;
+    child = stl->first;
+    while (child != NULL)
+      {
+	  /* counting how many Children */
+	  cnt++;
+	  child = child->next;
+      }
+    if (index >= cnt)
+	return RL2_ERROR;
+    cnt = 0;
+    child = stl->first;
+    while (child != NULL)
+      {
+	  if (cnt == index)
+	    {
+		*valid = child->validStyle;
+		break;
+	    }
+	  cnt++;
+	  child = child->next;
+      }
+    return RL2_OK;
+}
+
+RL2_DECLARE void
+rl2_destroy_group_renderer (rl2GroupRendererPtr group)
+{
+/* memory cleanup - destroying a GroupRenderer object */
+    int i;
+    rl2PrivGroupRendererPtr ptr = (rl2PrivGroupRendererPtr) group;
+    if (ptr == NULL)
+	return;
+    for (i = 0; i < ptr->count; i++)
+      {
+	  rl2PrivGroupRendererLayerPtr lyr = ptr->layers + i;
+	  if (lyr->layer_name != NULL)
+	      free (lyr->layer_name);
+	  if (lyr->coverage != NULL)
+	      rl2_destroy_coverage (lyr->coverage);
+	  /*
+	     if (lyr->coverage_style != NULL)
+	     rl2_destroy_coverage_style (lyr->coverage_style);
+	   */
+	  if (lyr->raster_stats != NULL)
+	      rl2_destroy_raster_statistics ((rl2RasterStatisticsPtr)
+					     (lyr->raster_stats));
+      }
+    free (ptr->layers);
+    free (ptr);
+}
+
+RL2_DECLARE rl2VariantArrayPtr
+rl2_create_variant_array (int count)
+{
+/* creating an array of VariantValues */
+    int i;
+    rl2PrivVariantArrayPtr variant = malloc (sizeof (rl2PrivVariantArray));
+    if (variant == NULL)
+	return NULL;
+    if (count < 1)
+	return NULL;
+    variant->count = count;
+    variant->array = malloc (sizeof (rl2PrivVariantValuePtr) * count);
+    if (variant->array == NULL)
+      {
+	  free (variant);
+	  return NULL;
+      }
+    for (i = 0; i < variant->count; i++)
+	*(variant->array + i) = NULL;
+    return (rl2VariantArrayPtr) variant;
+}
+
+RL2_DECLARE void
+rl2_destroy_variant_array (rl2VariantArrayPtr variant)
+{
+/* destroying an array of VariantValues */
+    int i;
+    rl2PrivVariantArrayPtr var = (rl2PrivVariantArrayPtr) variant;
+    if (var == NULL)
+	return;
+    for (i = 0; i < var->count; i++)
+      {
+	  rl2PrivVariantValuePtr val = *(var->array + i);
+	  if (val != NULL)
+	      rl2_destroy_variant_value (val);
+      }
+    free (var->array);
+    free (var);
+}
+
+RL2_DECLARE int
+rl2_set_variant_int (rl2VariantArrayPtr variant, int index, const char *name,
+		     sqlite3_int64 value)
+{
+/* setting an INTEGER VariantValue into a VariantArray object */
+    rl2PrivVariantArrayPtr var = (rl2PrivVariantArrayPtr) variant;
+    rl2PrivVariantValuePtr val;
+    if (var == NULL)
+	return RL2_ERROR;
+    if (index >= 0 && index < var->count)
+	;
+    else
+	return RL2_ERROR;
+    val = malloc (sizeof (rl2PrivVariantValue));
+    if (val == NULL)
+	return RL2_ERROR;
+    if (name == NULL)
+	val->column_name = NULL;
+    else
+      {
+	  int len = strlen (name);
+	  val->column_name = malloc (len + 1);
+	  strcpy (val->column_name, name);
+      }
+    val->int_value = value;
+    val->text_value = NULL;
+    val->blob_value = NULL;
+    val->sqlite3_type = SQLITE_INTEGER;
+    if (*(var->array + index) != NULL)
+	rl2_destroy_variant_value (*(var->array + index));
+    *(var->array + index) = val;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_set_variant_double (rl2VariantArrayPtr variant, int index,
+			const char *name, double value)
+{
+/* setting a DOUBLE VariantValue into a VariantArray object */
+    rl2PrivVariantArrayPtr var = (rl2PrivVariantArrayPtr) variant;
+    rl2PrivVariantValuePtr val;
+    if (var == NULL)
+	return RL2_ERROR;
+    if (index >= 0 && index < var->count)
+	;
+    else
+	return RL2_ERROR;
+    val = malloc (sizeof (rl2PrivVariantValue));
+    if (val == NULL)
+	return RL2_ERROR;
+    if (name == NULL)
+	val->column_name = NULL;
+    else
+      {
+	  int len = strlen (name);
+	  val->column_name = malloc (len + 1);
+	  strcpy (val->column_name, name);
+      }
+    val->dbl_value = value;
+    val->text_value = NULL;
+    val->blob_value = NULL;
+    val->sqlite3_type = SQLITE_FLOAT;
+    if (*(var->array + index) != NULL)
+	rl2_destroy_variant_value (*(var->array + index));
+    *(var->array + index) = val;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_set_variant_text (rl2VariantArrayPtr variant, int index, const char *name,
+		      const char *value, int bytes)
+{
+/* setting a TEXT VariantValue into a VariantArray object */
+    rl2PrivVariantArrayPtr var = (rl2PrivVariantArrayPtr) variant;
+    rl2PrivVariantValuePtr val;
+    if (var == NULL)
+	return RL2_ERROR;
+    if (index >= 0 && index < var->count)
+	;
+    else
+	return RL2_ERROR;
+    val = malloc (sizeof (rl2PrivVariantValue));
+    if (val == NULL)
+	return RL2_ERROR;
+    if (name == NULL)
+	val->column_name = NULL;
+    else
+      {
+	  int len = strlen (name);
+	  val->column_name = malloc (len + 1);
+	  strcpy (val->column_name, name);
+      }
+    val->text_value = malloc (bytes + 1);
+    memcpy (val->text_value, value, bytes);
+    *(val->text_value + bytes) = '\0';
+    val->bytes = bytes;
+    val->blob_value = NULL;
+    val->sqlite3_type = SQLITE_TEXT;
+    if (*(var->array + index) != NULL)
+	rl2_destroy_variant_value (*(var->array + index));
+    *(var->array + index) = val;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_set_variant_blob (rl2VariantArrayPtr variant, int index, const char *name,
+		      const unsigned char *value, int bytes)
+{
+/* setting a BLOB VariantValue into a VariantArray object */
+    rl2PrivVariantArrayPtr var = (rl2PrivVariantArrayPtr) variant;
+    rl2PrivVariantValuePtr val;
+    if (var == NULL)
+	return RL2_ERROR;
+    if (index >= 0 && index < var->count)
+	;
+    else
+	return RL2_ERROR;
+    val = malloc (sizeof (rl2PrivVariantValue));
+    if (val == NULL)
+	return RL2_ERROR;
+    val->text_value = NULL;
+    if (name == NULL)
+	val->column_name = NULL;
+    else
+      {
+	  int len = strlen (name);
+	  val->column_name = malloc (len + 1);
+	  strcpy (val->column_name, name);
+      }
+    val->blob_value = malloc (bytes);
+    memcpy (val->blob_value, value, bytes);
+    val->bytes = bytes;
+    val->sqlite3_type = SQLITE_BLOB;
+    if (*(var->array + index) != NULL)
+	rl2_destroy_variant_value (*(var->array + index));
+    *(var->array + index) = val;
+    return RL2_OK;
+}
+
+RL2_DECLARE int
+rl2_set_variant_null (rl2VariantArrayPtr variant, int index, const char *name)
+{
+/* setting a NULL VariantValue into a VariantArray object */
+    rl2PrivVariantArrayPtr var = (rl2PrivVariantArrayPtr) variant;
+    rl2PrivVariantValuePtr val;
+    if (var == NULL)
+	return RL2_ERROR;
+    if (index >= 0 && index < var->count)
+	;
+    else
+	return RL2_ERROR;
+    val = malloc (sizeof (rl2PrivVariantValue));
+    if (val == NULL)
+	return RL2_ERROR;
+    if (name == NULL)
+	val->column_name = NULL;
+    else
+      {
+	  int len = strlen (name);
+	  val->column_name = malloc (len + 1);
+	  strcpy (val->column_name, name);
+      }
+    val->text_value = NULL;
+    val->blob_value = NULL;
+    val->sqlite3_type = SQLITE_NULL;
+    if (*(var->array + index) != NULL)
+	rl2_destroy_variant_value (*(var->array + index));
+    *(var->array + index) = val;
+    return RL2_OK;
+}
+
+RL2_PRIVATE void
+rl2_destroy_variant_value (rl2PrivVariantValuePtr value)
+{
+/* destoying a VariantValue object */
+    if (value == NULL)
+	return;
+    if (value->column_name != NULL)
+	free (value->column_name);
+    if (value->text_value != NULL)
+	free (value->text_value);
+    if (value->blob_value != NULL)
+	free (value->blob_value);
+    free (value);
+}
diff --git a/src/rl2symbolizer.c b/src/rl2symbolizer.c
index 2ecd3b7..fb3deb0 100644
--- a/src/rl2symbolizer.c
+++ b/src/rl2symbolizer.c
@@ -20,7 +20,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -66,10 +66,10 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include "rasterlite2/rasterlite2.h"
 #include "rasterlite2_private.h"
 
-#include <spatialite/gaiaaux.h>
-
 #define RL2_UNUSED() if (argc || argv) argc = argc;
 
+static void parse_graphic (xmlNodePtr node, rl2PrivGraphicPtr graphic);
+
 static void
 dummySilentError (void *ctx, const char *msg, ...)
 {
@@ -81,7 +81,59 @@ dummySilentError (void *ctx, const char *msg, ...)
 }
 
 static void
-parse_sld_se_opacity (xmlNodePtr node, rl2PrivRasterStylePtr style)
+parse_sld_se_min_scale_denominator (xmlNodePtr node, rl2PrivStyleRulePtr rule)
+{
+/* parsing Rule MinScaleDenominator */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "MinScaleDenominator") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				rule->min_scale =
+				    atof ((const char *) child->content);
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_sld_se_max_scale_denominator (xmlNodePtr node, rl2PrivStyleRulePtr rule)
+{
+/* parsing Rule MaxScaleDenominator */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "MaxScaleDenominator") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				rule->max_scale =
+				    atof ((const char *) child->content);
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_sld_se_opacity (xmlNodePtr node, rl2PrivRasterSymbolizerPtr style)
 {
 /* parsing RasterSymbolizer Opacity */
     while (node)
@@ -265,7 +317,7 @@ parse_sld_se_contrast_enhancement (xmlNodePtr node, unsigned char *mode,
 }
 
 static int
-parse_sld_se_channels (xmlNodePtr node, rl2PrivRasterStylePtr style)
+parse_sld_se_channels (xmlNodePtr node, rl2PrivRasterSymbolizerPtr style)
 {
 /* parsing RasterSymbolizer Channels */
     int has_red = 0;
@@ -492,8 +544,8 @@ parse_hex (unsigned char hi, unsigned char lo, unsigned char *val)
 }
 
 static int
-parse_sld_se_color (const char *color, unsigned char *red, unsigned char *green,
-		    unsigned char *blue)
+parse_sld_se_color (const char *color, unsigned char *red,
+		    unsigned char *green, unsigned char *blue)
 {
 /* attempting to parse a #RRGGBB hexadecimal color */
     unsigned char r;
@@ -516,7 +568,8 @@ parse_sld_se_color (const char *color, unsigned char *red, unsigned char *green,
 }
 
 static int
-parse_sld_se_channel_selection (xmlNodePtr node, rl2PrivRasterStylePtr style)
+parse_sld_se_channel_selection (xmlNodePtr node,
+				rl2PrivRasterSymbolizerPtr style)
 {
 /* parsing RasterSymbolizer ChannelSelection */
     while (node)
@@ -538,7 +591,7 @@ parse_sld_se_channel_selection (xmlNodePtr node, rl2PrivRasterStylePtr style)
 }
 
 static int
-parse_sld_se_categorize (xmlNodePtr node, rl2PrivRasterStylePtr style)
+parse_sld_se_categorize (xmlNodePtr node, rl2PrivRasterSymbolizerPtr style)
 {
 /* parsing RasterSymbolizer ColorMap Categorize */
     struct _xmlAttr *attr;
@@ -611,9 +664,8 @@ parse_sld_se_categorize (xmlNodePtr node, rl2PrivRasterStylePtr style)
 						{
 						    style->categorize->baseRed =
 							red;
-						    style->
-							categorize->baseGreen =
-							green;
+						    style->categorize->baseGreen
+							= green;
 						    style->
 							categorize->baseBlue =
 							blue;
@@ -721,13 +773,14 @@ parse_sld_se_interpolation_point_value (xmlNodePtr node, unsigned char *red,
 }
 
 static int
-parse_sld_se_interpolation_point (xmlNodePtr node, rl2PrivRasterStylePtr style)
+parse_sld_se_interpolation_point (xmlNodePtr node,
+				  rl2PrivRasterSymbolizerPtr style)
 {
 /* parsing RasterSymbolizer ColorMap InterpolationPoint */
-    double value;
-    unsigned char red;
-    unsigned char green;
-    unsigned char blue;
+    double value = 0.0;
+    unsigned char red = 0;
+    unsigned char green = 0;
+    unsigned char blue = 0;
     int has_data = 0;
     int has_value = 0;
 
@@ -773,7 +826,7 @@ parse_sld_se_interpolation_point (xmlNodePtr node, rl2PrivRasterStylePtr style)
 }
 
 static int
-parse_sld_se_interpolate (xmlNodePtr node, rl2PrivRasterStylePtr style)
+parse_sld_se_interpolate (xmlNodePtr node, rl2PrivRasterSymbolizerPtr style)
 {
 /* parsing RasterSymbolizer ColorMap Interpolate */
     struct _xmlAttr *attr;
@@ -836,7 +889,7 @@ parse_sld_se_interpolate (xmlNodePtr node, rl2PrivRasterStylePtr style)
 }
 
 static int
-parse_sld_se_color_map (xmlNodePtr node, rl2PrivRasterStylePtr style)
+parse_sld_se_color_map (xmlNodePtr node, rl2PrivRasterSymbolizerPtr style)
 {
 /* parsing RasterSymbolizer ColorMap */
     while (node)
@@ -896,7 +949,7 @@ parse_sld_se_color_map (xmlNodePtr node, rl2PrivRasterStylePtr style)
 }
 
 static void
-parse_sld_se_shaded_relief (xmlNodePtr node, rl2PrivRasterStylePtr style)
+parse_sld_se_shaded_relief (xmlNodePtr node, rl2PrivRasterSymbolizerPtr style)
 {
 /* parsing RasterSymbolizer ShadedRelief */
     xmlNodePtr text;
@@ -926,8 +979,8 @@ parse_sld_se_shaded_relief (xmlNodePtr node, rl2PrivRasterStylePtr style)
 							(const char
 							 *) (text->content);
 						    if (value != NULL)
-							style->brightnessOnly =
-							    atoi (value);
+							style->brightnessOnly
+							    = atoi (value);
 						}
 					      text = text->next;
 					  }
@@ -960,7 +1013,7 @@ parse_sld_se_shaded_relief (xmlNodePtr node, rl2PrivRasterStylePtr style)
 }
 
 static int
-parse_raster_symbolizer (xmlNodePtr node, rl2PrivRasterStylePtr style)
+parse_raster_symbolizer (xmlNodePtr node, rl2PrivRasterSymbolizerPtr style)
 {
 /* attempting to parse an SLD/SE RasterSymbolizer */
     parse_sld_se_opacity (node->children, style);
@@ -975,10 +1028,86 @@ parse_raster_symbolizer (xmlNodePtr node, rl2PrivRasterStylePtr style)
     return 1;
 }
 
+static void
+parse_raster_style_rule (xmlNodePtr node, rl2PrivStyleRulePtr rule)
+{
+/* attempting to parse an SLD/SE Style Rule (raster type) */
+    parse_sld_se_min_scale_denominator (node->children, rule);
+    parse_sld_se_max_scale_denominator (node->children, rule);
+}
+
+static int
+parse_coverage_style (xmlNodePtr node, rl2PrivCoverageStylePtr style)
+{
+/* attempting to parse an SLD/SE CoverageStyle */
+    int count = 0;
+    int ret;
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "Rule") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_ELEMENT_NODE)
+			      {
+				  name = (const char *) (child->name);
+				  if (strcmp (name, "RasterSymbolizer") == 0)
+				    {
+					rl2PrivStyleRulePtr rule =
+					    rl2_create_default_style_rule ();
+					rl2PrivRasterSymbolizerPtr symbolizer
+					    =
+					    rl2_create_default_raster_symbolizer
+					    ();
+					if (symbolizer == NULL || rule == NULL)
+					  {
+					      if (symbolizer != NULL)
+						  rl2_destroy_raster_symbolizer
+						      (symbolizer);
+					      if (rule != NULL)
+						  rl2_destroy_style_rule (rule);
+					      return 0;
+					  }
+					rule->style_type = RL2_RASTER_STYLE;
+					rule->style = symbolizer;
+					parse_raster_style_rule (node, rule);
+					ret =
+					    parse_raster_symbolizer (child,
+								     symbolizer);
+					if (ret == 0)
+					  {
+					      rl2_destroy_style_rule (rule);
+					      return 0;
+					  }
+					/* updating the linked list of rules */
+					if (style->first_rule == NULL)
+					    style->first_rule = rule;
+					if (style->last_rule != NULL)
+					    style->last_rule->next = rule;
+					style->last_rule = rule;
+					count++;
+				    }
+			      }
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+    if (count > 0)
+	return 1;
+    return 0;
+}
+
 static int
-find_raster_symbolizer (xmlNodePtr node, rl2PrivRasterStylePtr style, int *loop)
+find_coverage_style (xmlNodePtr node, rl2PrivCoverageStylePtr style, int *loop)
 {
-/* recursively searching an SLD/SE RasterSymbolizer */
+/* recursively searching an SLD/SE CoverageStyle */
+    int ret;
     while (node)
       {
 	  if (node->type == XML_ELEMENT_NODE)
@@ -986,17 +1115,31 @@ find_raster_symbolizer (xmlNodePtr node, rl2PrivRasterStylePtr style, int *loop)
 		const char *name = (const char *) (node->name);
 		if (strcmp (name, "RasterSymbolizer") == 0)
 		  {
-		      int ret = parse_raster_symbolizer (node, style);
+		      rl2PrivStyleRulePtr rule =
+			  rl2_create_default_style_rule ();
+		      rl2PrivRasterSymbolizerPtr symbolizer =
+			  rl2_create_default_raster_symbolizer ();
+		      if (symbolizer == NULL || rule == NULL)
+			{
+			    if (symbolizer != NULL)
+				rl2_destroy_raster_symbolizer (symbolizer);
+			    if (rule != NULL)
+				rl2_destroy_style_rule (rule);
+			    return 0;
+			}
+		      rule->style_type = RL2_RASTER_STYLE;
+		      rule->style = symbolizer;
+		      style->first_rule = rule;
+		      style->last_rule = rule;
+		      ret = parse_raster_symbolizer (node, symbolizer);
 		      *loop = 0;
 		      return ret;
 		  }
-		if (strcmp (name, "CoverageStyle") == 0 ||
-		    strcmp (name, "Rule") == 0)
+		if (strcmp (name, "CoverageStyle") == 0)
 		  {
-		      int ret =
-			  find_raster_symbolizer (node->children, style, loop);
-		      if (*loop == 0)
-			  return ret;
+		      ret = parse_coverage_style (node->children, style);
+		      *loop = 0;
+		      return ret;
 		  }
 	    }
 	  node = node->next;
@@ -1004,32 +1147,20 @@ find_raster_symbolizer (xmlNodePtr node, rl2PrivRasterStylePtr style, int *loop)
     return 0;
 }
 
-RL2_PRIVATE rl2RasterStylePtr
-raster_style_from_sld_se_xml (char *name, char *title, char *abstract,
-			      unsigned char *xml)
+RL2_PRIVATE rl2CoverageStylePtr
+coverage_style_from_xml (char *name, unsigned char *xml)
 {
-/* attempting to build a RasterStyle object from an SLD/SE XML style */
-    rl2PrivRasterStylePtr style = NULL;
+/* attempting to build a Coverage Style object from an SLD/SE XML style */
+    rl2PrivCoverageStylePtr style = NULL;
     xmlDocPtr xml_doc = NULL;
     xmlNodePtr root;
     int loop = 1;
     xmlGenericErrorFunc silentError = (xmlGenericErrorFunc) dummySilentError;
 
-    style = malloc (sizeof (rl2PrivRasterStyle));
+    style = rl2_create_default_coverage_style ();
     if (style == NULL)
 	return NULL;
     style->name = name;
-    style->title = title;
-    style->abstract = abstract;
-    style->opacity = 1.0;
-    style->bandSelection = NULL;
-    style->categorize = NULL;
-    style->interpolate = NULL;
-    style->contrastEnhancement = RL2_CONTRAST_ENHANCEMENT_NONE;
-    style->gammaValue = 1.0;
-    style->shadedRelief = 0;
-    style->brightnessOnly = 0;
-    style->reliefFactor = 55.0;
 
 /* parsing the XML document */
     xmlSetGenericErrorFunc (NULL, silentError);
@@ -1044,7 +1175,7 @@ raster_style_from_sld_se_xml (char *name, char *title, char *abstract,
     root = xmlDocGetRootElement (xml_doc);
     if (root == NULL)
 	goto error;
-    if (!find_raster_symbolizer (root, style, &loop))
+    if (!find_coverage_style (root, style, &loop))
 	goto error;
     xmlFreeDoc (xml_doc);
     free (xml);
@@ -1053,7 +1184,7 @@ raster_style_from_sld_se_xml (char *name, char *title, char *abstract,
     if (style->name == NULL)
 	goto error;
 
-    return (rl2RasterStylePtr) style;
+    return (rl2CoverageStylePtr) style;
 
   error:
     if (xml != NULL)
@@ -1061,528 +1192,3031 @@ raster_style_from_sld_se_xml (char *name, char *title, char *abstract,
     if (xml_doc != NULL)
 	xmlFreeDoc (xml_doc);
     if (style != NULL)
-	rl2_destroy_raster_style ((rl2RasterStylePtr) style);
+	rl2_destroy_coverage_style ((rl2CoverageStylePtr) style);
     return NULL;
 }
 
-RL2_DECLARE void
-rl2_destroy_raster_style (rl2RasterStylePtr style)
+static int
+svg_parameter_name (xmlNodePtr node, const char **name, const char **value)
 {
-/* destroying a RasterStyle object */
-    rl2PrivColorMapPointPtr pC;
-    rl2PrivColorMapPointPtr pCn;
-    rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
-    if (stl == NULL)
-	return;
+/* return the Name and Value from a <SvgParameter> */
+    struct _xmlAttr *attr;
 
-    if (stl->name != NULL)
-	free (stl->name);
-    if (stl->title != NULL)
-	free (stl->title);
-    if (stl->abstract != NULL)
-	free (stl->abstract);
-    if (stl->bandSelection != NULL)
-	free (stl->bandSelection);
-    if (stl->categorize != NULL)
+    *name = NULL;
+    *value = NULL;
+    attr = node->properties;
+    while (attr != NULL)
       {
-	  pC = stl->categorize->first;
-	  while (pC != NULL)
+	  /* attributes */
+	  if (attr->type == XML_ATTRIBUTE_NODE)
 	    {
-		pCn = pC->next;
-		free (pC);
-		pC = pCn;
+		const char *nm = (const char *) (attr->name);
+		if (strcmp (nm, "name") == 0)
+		  {
+		      xmlNode *text = attr->children;
+		      if (text != NULL)
+			{
+			    if (text->type == XML_TEXT_NODE)
+				*name = (const char *) (text->content);
+			}
+		  }
 	    }
-	  free (stl->categorize);
+	  attr = attr->next;
       }
-    if (stl->interpolate != NULL)
+    if (name != NULL)
       {
-	  pC = stl->interpolate->first;
-	  while (pC != NULL)
+	  xmlNodePtr child = node->children;
+	  while (child)
 	    {
-		pCn = pC->next;
-		free (pC);
-		pC = pCn;
+		if (child->type == XML_TEXT_NODE && child->content != NULL)
+		  {
+		      *value = (const char *) (child->content);
+		      return 1;
+		  }
+		child = child->next;
 	    }
-	  free (stl->interpolate);
       }
-    free (stl);
-}
-
-RL2_DECLARE const char *
-rl2_get_raster_style_name (rl2RasterStylePtr style)
-{
-/* return the RasterStyle Name */
-    rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
-    if (stl == NULL)
-	return NULL;
-    return stl->name;
-}
-
-RL2_DECLARE const char *
-rl2_get_raster_style_title (rl2RasterStylePtr style)
-{
-/* return the RasterStyle Title */
-    rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
-    if (stl == NULL)
-	return NULL;
-    return stl->title;
-}
-
-RL2_DECLARE const char *
-rl2_get_raster_style_abstract (rl2RasterStylePtr style)
-{
-/* return the RasterStyle Abstract */
-    rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
-    if (stl == NULL)
-	return NULL;
-    return stl->abstract;
-}
-
-RL2_DECLARE int
-rl2_get_raster_style_opacity (rl2RasterStylePtr style, double *opacity)
-{
-/* return the RasterStyle Opacity */
-    rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
-    if (stl == NULL)
-	return RL2_ERROR;
-    *opacity = stl->opacity;
-    return RL2_OK;
+    return 0;
 }
 
-RL2_DECLARE int
-rl2_is_raster_style_mono_band_selected (rl2RasterStylePtr style, int *selected)
+static int
+parse_sld_se_stroke_dasharray (const char *value, int *count, double **list)
 {
-/* return if the RasterStyle has a MonoBand selection */
-    rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
-    if (stl == NULL)
-	return RL2_ERROR;
-    if (stl->shadedRelief)
-      {
-	  /* Shaded Relief */
-	  *selected = 1;
-	  return RL2_OK;
-      }
-    if (stl->bandSelection == NULL)
+/* parsing a Stroke Dasharray */
+    const char *in = value;
+    const char *start;
+    const char *end;
+    double dblarray[128];
+    int cnt = 0;
+    int len;
+    char *buf;
+    if (value == NULL)
+	return 0;
+    while (*in != '\0')
       {
-	  if (stl->categorize != NULL)
-	    {
-		/* Categorize Color Map */
-		*selected = 1;
-		return RL2_OK;
-	    }
-	  if (stl->interpolate != NULL)
+	  start = in;
+	  end = in;
+	  while (1)
 	    {
-		/* Interpolate Color Map */
-		*selected = 1;
-		return RL2_OK;
+		if (*end == ' ' || *end == ',' || *end == '\0')
+		  {
+		      /* found an item delimiter */
+		      break;
+		  }
+		end++;
 	    }
-	  if (stl->contrastEnhancement == RL2_CONTRAST_ENHANCEMENT_NORMALIZE ||
-	      stl->contrastEnhancement == RL2_CONTRAST_ENHANCEMENT_HISTOGRAM ||
-	      stl->contrastEnhancement == RL2_CONTRAST_ENHANCEMENT_GAMMA)
+	  len = end - start;
+	  if (len > 0)
 	    {
-		/* Contrast Enhancement */
-		*selected = 1;
-		return RL2_OK;
+		buf = malloc (len + 1);
+		memcpy (buf, start, len);
+		*(buf + len) = '\0';
+		dblarray[cnt++] = atof (buf);
+		free (buf);
+		in = end;
 	    }
+	  else
+	      in++;
       }
-    if (stl->bandSelection == NULL)
-	*selected = 0;
-    else if (stl->bandSelection->selectionType == RL2_BAND_SELECTION_MONO)
-	*selected = 1;
-    else
-	*selected = 0;
-    return RL2_OK;
+    if (cnt <= 0)
+	return 0;
+/* allocating the Dash list */
+    *count = cnt;
+    *list = malloc (sizeof (double) * cnt);
+    for (len = 0; len < cnt; len++)
+	*(*list + len) = dblarray[len];
+    return 1;
 }
 
-RL2_DECLARE int
-rl2_get_raster_style_mono_band_selection (rl2RasterStylePtr style,
-					  unsigned char *gray_band)
+static char *
+parse_graphic_online_resource (xmlNodePtr node)
 {
-/* return the RasterStyle MonoBand selection */
-    rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
-    if (stl == NULL)
-	return RL2_ERROR;
-    if (stl->bandSelection == NULL)
+/* parsing OnlineResource xlink_href */
+    while (node)
       {
-	  if (stl->categorize != NULL)
-	    {
-		/* Categorize Color Map */
-		*gray_band = 0;
-		return RL2_OK;
-	    }
-	  if (stl->interpolate != NULL)
+	  if (node->type == XML_ELEMENT_NODE)
 	    {
-		/* Interpolate Color Map */
-		*gray_band = 0;
-		return RL2_OK;
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "OnlineResource") == 0)
+		  {
+		      struct _xmlAttr *attr;
+		      attr = node->properties;
+		      while (attr != NULL)
+			{
+			    /* attributes */
+			    if (attr->type == XML_ATTRIBUTE_NODE)
+			      {
+				  xmlNode *text;
+				  name = (const char *) (attr->name);
+				  if (strcmp (name, "href") == 0)
+				    {
+					text = attr->children;
+					if (text != NULL)
+					  {
+					      if (text->type == XML_TEXT_NODE)
+						{
+						    int len;
+						    char *xlink_href;
+						    const char *href =
+							(const char
+							 *) (text->content);
+						    if (href == NULL)
+							return NULL;
+						    len = strlen (href);
+						    xlink_href =
+							malloc (len + 1);
+						    strcpy (xlink_href, href);
+						    return xlink_href;
+						}
+					  }
+				    }
+			      }
+			    attr = attr->next;
+			}
+		  }
 	    }
-	  /* Interpolate Color Map */
-	  *gray_band = 0;
-	  return RL2_OK;
-      }
-    if (stl->bandSelection == NULL)
-	return RL2_ERROR;
-    else if (stl->bandSelection->selectionType == RL2_BAND_SELECTION_MONO)
-      {
-	  *gray_band = stl->bandSelection->grayBand;
-	  return RL2_OK;
+	  node = node->next;
       }
-    else
-	return RL2_ERROR;
+    return NULL;
 }
 
-RL2_DECLARE int
-rl2_is_raster_style_triple_band_selected (rl2RasterStylePtr style,
-					  int *selected)
+static int
+parse_graphic_map_item (xmlNodePtr node, rl2PrivColorReplacementPtr repl)
 {
-/* return if the RasterStyle has a TripleBand selection */
-    rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
-    if (stl == NULL)
-	return RL2_ERROR;
-    if (stl->bandSelection == NULL)
+/* parsing MapItem (ColorReplacemente/Recode) */
+    int ok_data = 0;
+    int ok_value = 0;
+    xmlNodePtr child;
+    while (node)
       {
-	  if (stl->contrastEnhancement == RL2_CONTRAST_ENHANCEMENT_NORMALIZE ||
-	      stl->contrastEnhancement == RL2_CONTRAST_ENHANCEMENT_HISTOGRAM ||
-	      stl->contrastEnhancement == RL2_CONTRAST_ENHANCEMENT_GAMMA)
+	  const char *name = (const char *) (node->name);
+	  if (strcmp (name, "Data") == 0)
 	    {
-		/* Contrast Enhancement */
-		*selected = 1;
-		return RL2_OK;
+		child = node->children;
+		while (child)
+		  {
+		      if (child->type == XML_TEXT_NODE
+			  && child->content != NULL)
+			{
+			    repl->index = atoi ((const char *) child->content);
+			    ok_data = 1;
+			}
+		      child = child->next;
+		  }
 	    }
-      }
-    if (stl->bandSelection == NULL)
-	*selected = 0;
-    else if (stl->bandSelection->selectionType == RL2_BAND_SELECTION_TRIPLE)
-	*selected = 1;
-    else
-	*selected = 0;
-    return RL2_OK;
-}
-
-RL2_DECLARE int
-rl2_get_raster_style_triple_band_selection (rl2RasterStylePtr style,
-					    unsigned char *red_band,
-					    unsigned char *green_band,
-					    unsigned char *blue_band)
-{
-/* return the RasterStyle TripleBand selection */
-    rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
-    if (stl == NULL)
-	return RL2_ERROR;
-    if (stl->bandSelection == NULL)
-      {
-	  if (stl->contrastEnhancement == RL2_CONTRAST_ENHANCEMENT_NORMALIZE ||
-	      stl->contrastEnhancement == RL2_CONTRAST_ENHANCEMENT_HISTOGRAM ||
-	      stl->contrastEnhancement == RL2_CONTRAST_ENHANCEMENT_GAMMA)
+	  if (strcmp (name, "Value") == 0)
 	    {
-		/* Contrast Enhancement */
-		*red_band = 0;
-		*green_band = 1;
-		*blue_band = 2;
-		return RL2_OK;
+		child = node->children;
+		while (child)
+		  {
+		      if (child->type == XML_TEXT_NODE
+			  && child->content != NULL)
+			{
+			    unsigned char red;
+			    unsigned char green;
+			    unsigned char blue;
+			    if (parse_sld_se_color
+				((const char *) (child->content), &red,
+				 &green, &blue))
+			      {
+				  repl->red = red;
+				  repl->green = green;
+				  repl->blue = blue;
+			      }
+			    ok_value = 1;
+			}
+		      child = child->next;
+		  }
 	    }
+	  node = node->next;
       }
-    if (stl->bandSelection == NULL)
-	return RL2_ERROR;
-    else if (stl->bandSelection->selectionType == RL2_BAND_SELECTION_TRIPLE)
-      {
-	  *red_band = stl->bandSelection->redBand;
-	  *green_band = stl->bandSelection->greenBand;
-	  *blue_band = stl->bandSelection->blueBand;
-	  return RL2_OK;
-      }
-    else
-	return RL2_ERROR;
-}
-
-RL2_DECLARE int
-rl2_get_raster_style_overall_contrast_enhancement (rl2RasterStylePtr style,
-						   unsigned char
-						   *contrast_enhancement,
-						   double *gamma_value)
-{
-/* return the RasterStyle OverallContrastEnhancement */
-    rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
-    if (stl == NULL)
-	return RL2_ERROR;
-    *contrast_enhancement = stl->contrastEnhancement;
-    *gamma_value = stl->gammaValue;
-    return RL2_OK;
+    if (ok_data && ok_value)
+	return 1;
+    return 0;
 }
 
-RL2_DECLARE int
-rl2_get_raster_style_red_band_contrast_enhancement (rl2RasterStylePtr style,
-						    unsigned char
-						    *contrast_enhancement,
-						    double *gamma_value)
+static void
+parse_graphic_color_replacement (xmlNodePtr node, rl2PrivExternalGraphicPtr ext)
 {
-/* return the RasterStyle RedBand ContrastEnhancement */
-    rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
-    if (stl == NULL)
-	return RL2_ERROR;
-    if (stl->bandSelection == NULL)
-	return RL2_ERROR;
-    else if (stl->bandSelection->selectionType == RL2_BAND_SELECTION_TRIPLE)
+/* parsing ColorReplacement (Graphic) */
+    while (node)
       {
-	  *contrast_enhancement = stl->bandSelection->redContrast;
-	  *gamma_value = stl->bandSelection->redGamma;
-	  return RL2_OK;
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "Recode") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    name = (const char *) (child->name);
+			    if (strcmp (name, "MapItem") == 0)
+			      {
+				  rl2PrivColorReplacementPtr repl =
+				      rl2_create_default_color_replacement ();
+				  if (repl == NULL)
+				      return;
+				  if (!parse_graphic_map_item
+				      (child->children, repl))
+				    {
+					rl2_destroy_color_replacement (repl);
+					return;
+				    }
+				  if (ext->first == NULL)
+				      ext->first = repl;
+				  if (ext->last != NULL)
+				      ext->last->next = repl;
+				  ext->last = repl;
+			      }
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
       }
-    return RL2_ERROR;
 }
 
-RL2_DECLARE int
-rl2_get_raster_style_green_band_contrast_enhancement (rl2RasterStylePtr style,
-						      unsigned char
-						      *contrast_enhancement,
-						      double *gamma_value)
+static int
+parse_mark_well_known_type (xmlNodePtr node)
 {
-/* return the RasterStyle GreenBand ContrastEnhancement */
-    rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
-    if (stl == NULL)
-	return RL2_ERROR;
-    if (stl->bandSelection == NULL)
-	return RL2_ERROR;
-    else if (stl->bandSelection->selectionType == RL2_BAND_SELECTION_TRIPLE)
+/* parsing Mark WellKnownName */
+    while (node)
       {
-	  *contrast_enhancement = stl->bandSelection->greenContrast;
-	  *gamma_value = stl->bandSelection->greenGamma;
-	  return RL2_OK;
-      }
-    return RL2_ERROR;
-}
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "WellKnownName") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+			      {
 
-RL2_DECLARE int
-rl2_get_raster_style_blue_band_contrast_enhancement (rl2RasterStylePtr style,
-						     unsigned char
-						     *contrast_enhancement,
-						     double *gamma_value)
-{
-/* return the RasterStyle BlueBand ContrastEnhancement */
-    rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
-    if (stl == NULL)
-	return RL2_ERROR;
-    if (stl->bandSelection == NULL)
-	return RL2_ERROR;
-    else if (stl->bandSelection->selectionType == RL2_BAND_SELECTION_TRIPLE)
-      {
-	  *contrast_enhancement = stl->bandSelection->blueContrast;
-	  *gamma_value = stl->bandSelection->blueGamma;
-	  return RL2_OK;
+				  const char *type =
+				      (const char *) (child->content);
+				  if (strcasecmp (type, "square") == 0)
+				      return RL2_GRAPHIC_MARK_SQUARE;
+				  if (strcasecmp (type, "circle") == 0)
+				      return RL2_GRAPHIC_MARK_CIRCLE;
+				  if (strcasecmp (type, "triangle") == 0)
+				      return RL2_GRAPHIC_MARK_TRIANGLE;
+				  if (strcasecmp (type, "star") == 0)
+				      return RL2_GRAPHIC_MARK_STAR;
+				  if (strcasecmp (type, "cross") == 0)
+				      return RL2_GRAPHIC_MARK_CROSS;
+				  if (strcasecmp (type, "x") == 0)
+				      return RL2_GRAPHIC_MARK_X;
+			      }
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
       }
-    return RL2_ERROR;
+    return RL2_GRAPHIC_MARK_UNKNOWN;
 }
 
-RL2_DECLARE int
-rl2_get_raster_style_gray_band_contrast_enhancement (rl2RasterStylePtr style,
-						     unsigned char
-						     *contrast_enhancement,
-						     double *gamma_value)
+static void
+parse_mark_stroke (xmlNodePtr node, rl2PrivMarkPtr mark)
 {
-/* return the RasterStyle GrayBand ContrastEnhancement */
-    rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
-    if (stl == NULL)
-	return RL2_ERROR;
-    if (stl->bandSelection == NULL)
-	return RL2_ERROR;
-    else if (stl->bandSelection->selectionType == RL2_BAND_SELECTION_MONO)
+/* parsing Mark Stroke */
+    while (node)
       {
-	  *contrast_enhancement = stl->bandSelection->grayContrast;
-	  *gamma_value = stl->bandSelection->grayGamma;
-	  return RL2_OK;
-      }
-    return RL2_ERROR;
-}
-
-RL2_DECLARE int
-rl2_has_raster_style_shaded_relief (rl2RasterStylePtr style, int *shaded_relief)
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "Stroke") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      mark->stroke = rl2_create_default_stroke ();
+		      if (mark->stroke == NULL)
+			  return;
+		      while (child)
+			{
+			    if (child->type == XML_ELEMENT_NODE)
+			      {
+				  name = (const char *) (child->name);
+				  if (strcmp (name, "GraphicStroke") == 0)
+				    {
+					xmlNodePtr grandchild = child->children;
+					while (grandchild)
+					  {
+					      name =
+						  (const char
+						   *) (grandchild->name);
+					      if (strcmp (name, "Graphic") == 0)
+						{
+						    if (mark->stroke->graphic !=
+							NULL)
+							rl2_destroy_graphic
+							    (mark->
+							     stroke->graphic);
+						    mark->stroke->graphic =
+							rl2_create_default_graphic
+							();
+						    if (mark->stroke->graphic !=
+							NULL)
+							parse_graphic
+							    (grandchild->children,
+							     mark->
+							     stroke->graphic);
+						}
+					      grandchild = grandchild->next;
+					  }
+				    }
+				  if (strcmp (name, "SvgParameter") == 0)
+				    {
+					const char *svg_name;
+					const char *svg_value;
+					if (!svg_parameter_name
+					    (child, &svg_name, &svg_value))
+					  {
+					      child = child->next;
+					      continue;
+					  }
+					if (strcmp (svg_name, "stroke") == 0)
+					  {
+					      unsigned char red;
+					      unsigned char green;
+					      unsigned char blue;
+					      if (parse_sld_se_color
+						  (svg_value, &red, &green,
+						   &blue))
+						{
+						    mark->stroke->red = red;
+						    mark->stroke->green = green;
+						    mark->stroke->blue = blue;
+						}
+					  }
+					if (strcmp (svg_name, "stroke-width")
+					    == 0)
+					    mark->stroke->width =
+						atof ((const char *) svg_value);
+					if (strcmp
+					    (svg_name, "stroke-linejoin") == 0)
+					  {
+					      if (strcmp (svg_value, "mitre")
+						  == 0)
+						  mark->stroke->linejoin =
+						      RL2_STROKE_LINEJOIN_MITRE;
+					      if (strcmp (svg_value, "round")
+						  == 0)
+						  mark->stroke->linejoin =
+						      RL2_STROKE_LINEJOIN_ROUND;
+					      if (strcmp (svg_value, "bevel")
+						  == 0)
+						  mark->stroke->linejoin =
+						      RL2_STROKE_LINEJOIN_BEVEL;
+					  }
+					if (strcmp
+					    (svg_name, "stroke-linecap") == 0)
+					  {
+					      if (strcmp (svg_value, "butt")
+						  == 0)
+						  mark->stroke->linecap =
+						      RL2_STROKE_LINECAP_BUTT;
+					      if (strcmp (svg_value, "round")
+						  == 0)
+						  mark->stroke->linecap =
+						      RL2_STROKE_LINECAP_ROUND;
+					      if (strcmp (svg_value, "square")
+						  == 0)
+						  mark->stroke->linecap =
+						      RL2_STROKE_LINECAP_SQUARE;
+					  }
+					if (strcmp
+					    (svg_name, "stroke-dasharray") == 0)
+					  {
+					      int dash_count;
+					      double *dash_list = NULL;
+					      if (parse_sld_se_stroke_dasharray
+						  (svg_value, &dash_count,
+						   &dash_list))
+						{
+						    mark->stroke->dash_count =
+							dash_count;
+						    mark->stroke->dash_list =
+							dash_list;
+						}
+					  }
+					if (strcmp
+					    (svg_name,
+					     "stroke-dashoffset") == 0)
+					    mark->stroke->dash_offset =
+						atof ((const char *) svg_value);
+				    }
+			      }
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_mark_fill (xmlNodePtr node, rl2PrivMarkPtr mark)
+{
+/* parsing Mark Fill */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "Fill") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      mark->fill = rl2_create_default_fill ();
+		      if (mark->fill == NULL)
+			  return;
+		      while (child)
+			{
+			    if (child->type == XML_ELEMENT_NODE)
+			      {
+				  name = (const char *) (child->name);
+				  if (strcmp (name, "GraphicFill") == 0)
+				    {
+					xmlNodePtr grandchild = child->children;
+					while (grandchild)
+					  {
+					      name =
+						  (const char
+						   *) (grandchild->name);
+					      if (strcmp (name, "Graphic") == 0)
+						{
+						    if (mark->fill->graphic !=
+							NULL)
+							rl2_destroy_graphic
+							    (mark->
+							     fill->graphic);
+						    mark->fill->graphic =
+							rl2_create_default_graphic
+							();
+						    if (mark->fill->graphic !=
+							NULL)
+							parse_graphic
+							    (grandchild->children,
+							     mark->
+							     fill->graphic);
+						}
+					      grandchild = grandchild->next;
+					  }
+				    }
+				  if (strcmp (name, "SvgParameter") == 0)
+				    {
+					const char *svg_name;
+					const char *svg_value;
+					if (!svg_parameter_name
+					    (child, &svg_name, &svg_value))
+					  {
+					      child = child->next;
+					      continue;
+					  }
+					if (strcmp (svg_name, "fill") == 0)
+					  {
+					      unsigned char red;
+					      unsigned char green;
+					      unsigned char blue;
+					      if (parse_sld_se_color
+						  (svg_value, &red, &green,
+						   &blue))
+						{
+						    mark->fill->red = red;
+						    mark->fill->green = green;
+						    mark->fill->blue = blue;
+						}
+					  }
+				    }
+			      }
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_graphic (xmlNodePtr node, rl2PrivGraphicPtr graphic)
+{
+/* parsing Graphic */
+    while (node)
+      {
+	  const char *name = (const char *) (node->name);
+	  if (strcmp (name, "ExternalGraphic") == 0)
+	    {
+		xmlNodePtr child = node->children;
+		rl2PrivExternalGraphicPtr ext;
+		rl2PrivGraphicItemPtr item =
+		    rl2_create_default_external_graphic ();
+		if (item == NULL)
+		    return;
+		ext = (rl2PrivExternalGraphicPtr) (item->item);
+		ext->xlink_href =
+		    parse_graphic_online_resource (node->children);
+		if (ext->xlink_href == NULL)
+		  {
+		      rl2_destroy_graphic_item (item);
+		      return;
+		  }
+		while (child)
+		  {
+		      name = (const char *) (child->name);
+		      if (strcmp (name, "ColorReplacement") == 0)
+			  parse_graphic_color_replacement (child->children,
+							   ext);
+		      child = child->next;
+		  }
+		if (graphic->first == NULL)
+		    graphic->first = item;
+		if (graphic->last != NULL)
+		    graphic->last->next = item;
+		graphic->last = item;
+	    }
+	  if (strcmp (name, "Mark") == 0)
+	    {
+		rl2PrivMarkPtr mark;
+		rl2PrivGraphicItemPtr item = rl2_create_default_mark ();
+		if (item == NULL)
+		    return;
+		mark = (rl2PrivMarkPtr) (item->item);
+		mark->well_known_type =
+		    parse_mark_well_known_type (node->children);
+		parse_mark_fill (node->children, mark);
+		parse_mark_stroke (node->children, mark);
+		if (graphic->first == NULL)
+		    graphic->first = item;
+		if (graphic->last != NULL)
+		    graphic->last->next = item;
+		graphic->last = item;
+	    }
+
+	  node = node->next;
+      }
+}
+
+static void
+parse_line_stroke (xmlNodePtr node, rl2PrivLineSymbolizerPtr sym)
+{
+/* parsing LineSymbolizer Stroke */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "Stroke") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      sym->stroke = rl2_create_default_stroke ();
+		      if (sym->stroke == NULL)
+			  return;
+		      while (child)
+			{
+			    if (child->type == XML_ELEMENT_NODE)
+			      {
+				  name = (const char *) (child->name);
+				  if (strcmp (name, "GraphicStroke") == 0)
+				    {
+					xmlNodePtr grandchild = child->children;
+					while (grandchild)
+					  {
+					      name =
+						  (const char
+						   *) (grandchild->name);
+					      if (strcmp (name, "Graphic") == 0)
+						{
+						    if (sym->stroke->graphic !=
+							NULL)
+							rl2_destroy_graphic
+							    (sym->
+							     stroke->graphic);
+						    sym->stroke->graphic =
+							rl2_create_default_graphic
+							();
+						    if (sym->stroke->graphic !=
+							NULL)
+							parse_graphic
+							    (grandchild->children,
+							     sym->
+							     stroke->graphic);
+						}
+					      grandchild = grandchild->next;
+					  }
+				    }
+				  if (strcmp (name, "SvgParameter") == 0)
+				    {
+					const char *svg_name;
+					const char *svg_value;
+					if (!svg_parameter_name
+					    (child, &svg_name, &svg_value))
+					  {
+					      child = child->next;
+					      continue;
+					  }
+					if (strcmp (svg_name, "stroke") == 0)
+					  {
+					      unsigned char red;
+					      unsigned char green;
+					      unsigned char blue;
+					      if (parse_sld_se_color
+						  (svg_value, &red, &green,
+						   &blue))
+						{
+						    sym->stroke->red = red;
+						    sym->stroke->green = green;
+						    sym->stroke->blue = blue;
+						}
+					  }
+					if (strcmp
+					    (svg_name, "stroke-opacity") == 0)
+					    sym->stroke->opacity =
+						atof ((const char *) svg_value);
+					if (strcmp (svg_name, "stroke-width")
+					    == 0)
+					    sym->stroke->width =
+						atof ((const char *) svg_value);
+					if (strcmp
+					    (svg_name, "stroke-linejoin") == 0)
+					  {
+					      if (strcmp (svg_value, "mitre")
+						  == 0)
+						  sym->stroke->linejoin =
+						      RL2_STROKE_LINEJOIN_MITRE;
+					      if (strcmp (svg_value, "round")
+						  == 0)
+						  sym->stroke->linejoin =
+						      RL2_STROKE_LINEJOIN_ROUND;
+					      if (strcmp (svg_value, "bevel")
+						  == 0)
+						  sym->stroke->linejoin =
+						      RL2_STROKE_LINEJOIN_BEVEL;
+					  }
+					if (strcmp
+					    (svg_name, "stroke-linecap") == 0)
+					  {
+					      if (strcmp (svg_value, "butt")
+						  == 0)
+						  sym->stroke->linecap =
+						      RL2_STROKE_LINECAP_BUTT;
+					      if (strcmp (svg_value, "round")
+						  == 0)
+						  sym->stroke->linecap =
+						      RL2_STROKE_LINECAP_ROUND;
+					      if (strcmp (svg_value, "square")
+						  == 0)
+						  sym->stroke->linecap =
+						      RL2_STROKE_LINECAP_SQUARE;
+					  }
+					if (strcmp
+					    (svg_name, "stroke-dasharray") == 0)
+					  {
+					      int dash_count;
+					      double *dash_list = NULL;
+					      if (parse_sld_se_stroke_dasharray
+						  (svg_value, &dash_count,
+						   &dash_list))
+						{
+						    sym->stroke->dash_count =
+							dash_count;
+						    sym->stroke->dash_list =
+							dash_list;
+						}
+					  }
+					if (strcmp
+					    (svg_name,
+					     "stroke-dashoffset") == 0)
+					    sym->stroke->dash_offset =
+						atof ((const char *) svg_value);
+				    }
+			      }
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_line_offset (xmlNodePtr node, rl2PrivLineSymbolizerPtr sym)
+{
+/* parsing LineSymbolizer PerpendicularOffset */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "PerpendicularOffset") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				sym->perpendicular_offset =
+				    atof ((const char *) child->content);
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static int
+parse_line_symbolizer (xmlNodePtr node, rl2PrivVectorSymbolizerPtr symbolizer)
+{
+/* attempting to parse an SLD/SE LineSymbolizer */
+    rl2PrivVectorSymbolizerItemPtr item;
+    rl2PrivLineSymbolizerPtr sym;
+    if (symbolizer == NULL)
+	return 0;
+
+/* allocating a default Line Symbolizer */
+    item = rl2_create_default_line_symbolizer ();
+    if (item == NULL)
+	return 0;
+    if (item->symbolizer_type != RL2_LINE_SYMBOLIZER
+	|| item->symbolizer == NULL)
+      {
+	  rl2_destroy_vector_symbolizer_item (item);
+	  return 0;
+      }
+    sym = (rl2PrivLineSymbolizerPtr) (item->symbolizer);
+    if (symbolizer->first == NULL)
+	symbolizer->first = item;
+    if (symbolizer->last != NULL)
+	symbolizer->last->next = item;
+    symbolizer->last = item;
+
+    parse_line_stroke (node->children, sym);
+    parse_line_offset (node->children, sym);
+    return 1;
+}
+
+static void
+parse_polygon_stroke (xmlNodePtr node, rl2PrivPolygonSymbolizerPtr sym)
+{
+/* parsing PolygonSymbolizer Stroke */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "Stroke") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      sym->stroke = rl2_create_default_stroke ();
+		      if (sym->stroke == NULL)
+			  return;
+		      while (child)
+			{
+			    if (child->type == XML_ELEMENT_NODE)
+			      {
+				  name = (const char *) (child->name);
+				  if (strcmp (name, "GraphicStroke") == 0)
+				    {
+					xmlNodePtr grandchild = child->children;
+					while (grandchild)
+					  {
+					      name =
+						  (const char
+						   *) (grandchild->name);
+					      if (strcmp (name, "Graphic") == 0)
+						{
+						    if (sym->stroke->graphic !=
+							NULL)
+							rl2_destroy_graphic
+							    (sym->
+							     stroke->graphic);
+						    sym->stroke->graphic =
+							rl2_create_default_graphic
+							();
+						    if (sym->stroke->graphic !=
+							NULL)
+							parse_graphic
+							    (grandchild->children,
+							     sym->
+							     stroke->graphic);
+						}
+					      grandchild = grandchild->next;
+					  }
+				    }
+				  if (strcmp (name, "SvgParameter") == 0)
+				    {
+					const char *svg_name;
+					const char *svg_value;
+					if (!svg_parameter_name
+					    (child, &svg_name, &svg_value))
+					  {
+					      child = child->next;
+					      continue;
+					  }
+					if (strcmp (svg_name, "stroke") == 0)
+					  {
+					      unsigned char red;
+					      unsigned char green;
+					      unsigned char blue;
+					      if (parse_sld_se_color
+						  (svg_value, &red, &green,
+						   &blue))
+						{
+						    sym->stroke->red = red;
+						    sym->stroke->green = green;
+						    sym->stroke->blue = blue;
+						}
+					  }
+					if (strcmp
+					    (svg_name, "stroke-opacity") == 0)
+					    sym->stroke->opacity =
+						atof ((const char *) svg_value);
+					if (strcmp (svg_name, "stroke-width")
+					    == 0)
+					    sym->stroke->width =
+						atof ((const char *) svg_value);
+					if (strcmp
+					    (svg_name, "stroke-linejoin") == 0)
+					  {
+					      if (strcmp (svg_value, "mitre")
+						  == 0)
+						  sym->stroke->linejoin =
+						      RL2_STROKE_LINEJOIN_MITRE;
+					      if (strcmp (svg_value, "round")
+						  == 0)
+						  sym->stroke->linejoin =
+						      RL2_STROKE_LINEJOIN_ROUND;
+					      if (strcmp (svg_value, "bevel")
+						  == 0)
+						  sym->stroke->linejoin =
+						      RL2_STROKE_LINEJOIN_BEVEL;
+					  }
+					if (strcmp
+					    (svg_name, "stroke-linecap") == 0)
+					  {
+					      if (strcmp (svg_value, "butt")
+						  == 0)
+						  sym->stroke->linecap =
+						      RL2_STROKE_LINECAP_BUTT;
+					      if (strcmp (svg_value, "round")
+						  == 0)
+						  sym->stroke->linecap =
+						      RL2_STROKE_LINECAP_ROUND;
+					      if (strcmp (svg_value, "square")
+						  == 0)
+						  sym->stroke->linecap =
+						      RL2_STROKE_LINECAP_SQUARE;
+					  }
+					if (strcmp
+					    (svg_name, "stroke-dasharray") == 0)
+					  {
+					      int dash_count;
+					      double *dash_list = NULL;
+					      if (parse_sld_se_stroke_dasharray
+						  (svg_value, &dash_count,
+						   &dash_list))
+						{
+						    sym->stroke->dash_count =
+							dash_count;
+						    sym->stroke->dash_list =
+							dash_list;
+						}
+					  }
+					if (strcmp
+					    (svg_name,
+					     "stroke-dashoffset") == 0)
+					    sym->stroke->dash_offset =
+						atof ((const char *) svg_value);
+				    }
+			      }
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_polygon_fill (xmlNodePtr node, rl2PrivPolygonSymbolizerPtr sym)
+{
+/* parsing PolygonSymbolizer Fill */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "Fill") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      sym->fill = rl2_create_default_fill ();
+		      if (sym->fill == NULL)
+			  return;
+		      while (child)
+			{
+			    if (child->type == XML_ELEMENT_NODE)
+			      {
+				  name = (const char *) (child->name);
+				  if (strcmp (name, "GraphicFill") == 0)
+				    {
+					xmlNodePtr grandchild = child->children;
+					while (grandchild)
+					  {
+					      name =
+						  (const char
+						   *) (grandchild->name);
+					      if (strcmp (name, "Graphic") == 0)
+						{
+						    if (sym->fill->graphic !=
+							NULL)
+							rl2_destroy_graphic
+							    (sym->
+							     fill->graphic);
+						    sym->fill->graphic =
+							rl2_create_default_graphic
+							();
+						    if (sym->fill->graphic !=
+							NULL)
+							parse_graphic
+							    (grandchild->children,
+							     sym->
+							     fill->graphic);
+						}
+					      grandchild = grandchild->next;
+					  }
+				    }
+				  if (strcmp (name, "SvgParameter") == 0)
+				    {
+					const char *svg_name;
+					const char *svg_value;
+					if (!svg_parameter_name
+					    (child, &svg_name, &svg_value))
+					  {
+					      child = child->next;
+					      continue;
+					  }
+					if (strcmp (svg_name, "fill") == 0)
+					  {
+					      unsigned char red;
+					      unsigned char green;
+					      unsigned char blue;
+					      if (parse_sld_se_color
+						  (svg_value, &red, &green,
+						   &blue))
+						{
+						    sym->fill->red = red;
+						    sym->fill->green = green;
+						    sym->fill->blue = blue;
+						}
+					  }
+					if (strcmp (svg_name, "fill-opacity")
+					    == 0)
+					    sym->fill->opacity =
+						atof (svg_value);
+				    }
+			      }
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_polygon_offset (xmlNodePtr node, rl2PrivPolygonSymbolizerPtr sym)
+{
+/* parsing PolygonSymbolizer PerpendicularOffset */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "PerpendicularOffset") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				sym->perpendicular_offset =
+				    atof ((const char *) child->content);
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_polygon_displacement_xy (xmlNodePtr node, rl2PrivPolygonSymbolizerPtr sym)
+{
+/* parsing PolygonSymbolizer Displacement */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "DisplacementX") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				sym->displacement_x =
+				    atof ((const char *) child->content);
+			    child = child->next;
+			}
+		  }
+		if (strcmp (name, "DisplacementY") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				sym->displacement_y =
+				    atof ((const char *) child->content);
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_polygon_displacement (xmlNodePtr node, rl2PrivPolygonSymbolizerPtr sym)
+{
+/* parsing PolygonSymbolizer Displacement */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "Displacement") == 0)
+		    parse_polygon_displacement_xy (node->children, sym);
+	    }
+	  node = node->next;
+      }
+}
+
+static int
+parse_polygon_symbolizer (xmlNodePtr node,
+			  rl2PrivVectorSymbolizerPtr symbolizer)
+{
+/* attempting to parse an SLD/SE PolygonSymbolizer */
+    rl2PrivVectorSymbolizerItemPtr item;
+    rl2PrivPolygonSymbolizerPtr sym;
+    if (symbolizer == NULL)
+	return 0;
+
+/* allocating a default Polygon Symbolizer */
+    item = rl2_create_default_polygon_symbolizer ();
+    if (item == NULL)
+	return 0;
+    if (item->symbolizer_type != RL2_POLYGON_SYMBOLIZER
+	|| item->symbolizer == NULL)
+      {
+	  rl2_destroy_vector_symbolizer_item (item);
+	  return 0;
+      }
+    sym = (rl2PrivPolygonSymbolizerPtr) (item->symbolizer);
+    if (symbolizer->first == NULL)
+	symbolizer->first = item;
+    if (symbolizer->last != NULL)
+	symbolizer->last->next = item;
+    symbolizer->last = item;
+
+    parse_polygon_stroke (node->children, sym);
+    parse_polygon_fill (node->children, sym);
+    parse_polygon_offset (node->children, sym);
+    parse_polygon_displacement (node->children, sym);
+    return 1;
+}
+
+static void
+parse_point_opacity (xmlNodePtr node, rl2PrivGraphicPtr graphic)
+{
+/* parsing Point Symbolizer Graphic Opacity */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "Opacity") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				graphic->opacity =
+				    atof ((const char *) child->content);
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_point_size (xmlNodePtr node, rl2PrivGraphicPtr graphic)
+{
+/* parsing Point Symbolizer Graphic Size */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "Size") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				graphic->size =
+				    atof ((const char *) child->content);
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_point_rotation (xmlNodePtr node, rl2PrivGraphicPtr graphic)
+{
+/* parsing Point Symbolizer Graphic Rotation */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "Rotation") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				graphic->rotation =
+				    atof ((const char *) child->content);
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_point_anchor_point_xy (xmlNodePtr node, rl2PrivGraphicPtr graphic)
+{
+/* parsing Point Symbolizer Graphic AnchorPoint XY */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "AnchorPointX") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				graphic->anchor_point_x =
+				    atof ((const char *) child->content);
+			    child = child->next;
+			}
+		  }
+		if (strcmp (name, "AnchorPointY") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				graphic->anchor_point_y =
+				    atof ((const char *) child->content);
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_point_anchor_point (xmlNodePtr node, rl2PrivGraphicPtr graphic)
+{
+/* parsing Point Symbolizer Graphic AnchorPoint */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "AnchorPoint") == 0)
+		    parse_point_anchor_point_xy (node->children, graphic);
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_point_displacement_xy (xmlNodePtr node, rl2PrivGraphicPtr graphic)
+{
+/* parsing Point Symbolizer Graphic Displacement */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "DisplacementX") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				graphic->displacement_x =
+				    atof ((const char *) child->content);
+			    child = child->next;
+			}
+		  }
+		if (strcmp (name, "DisplacementY") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				graphic->displacement_y =
+				    atof ((const char *) child->content);
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_point_displacement (xmlNodePtr node, rl2PrivGraphicPtr graphic)
+{
+/* parsing Point Symbolizer Graphic Displacement */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "Displacement") == 0)
+		    parse_point_displacement_xy (node->children, graphic);
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_point_graphic (xmlNodePtr node, rl2PrivGraphicPtr graphic)
+{
+/* finding the Graphic tag within a PointSymbolizer */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "Graphic") == 0)
+		  {
+		      parse_graphic (node->children, graphic);
+		      parse_point_opacity (node->children, graphic);
+		      parse_point_size (node->children, graphic);
+		      parse_point_rotation (node->children, graphic);
+		      parse_point_anchor_point (node->children, graphic);
+		      parse_point_displacement (node->children, graphic);
+		      return;
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static int
+parse_point_symbolizer (xmlNodePtr node, rl2PrivVectorSymbolizerPtr symbolizer)
+{
+/* attempting to parse an SLD/SE PointSymbolizer */
+    rl2PrivVectorSymbolizerItemPtr item;
+    rl2PrivPointSymbolizerPtr sym;
+    if (symbolizer == NULL)
+	return 0;
+
+/* allocating a default Point Symbolizer */
+    item = rl2_create_default_point_symbolizer ();
+    if (item == NULL)
+	return 0;
+    if (item->symbolizer_type != RL2_POINT_SYMBOLIZER
+	|| item->symbolizer == NULL)
+      {
+	  rl2_destroy_vector_symbolizer_item (item);
+	  return 0;
+      }
+    sym = (rl2PrivPointSymbolizerPtr) (item->symbolizer);
+    if (symbolizer->first == NULL)
+	symbolizer->first = item;
+    if (symbolizer->last != NULL)
+	symbolizer->last->next = item;
+    symbolizer->last = item;
+
+    if (sym->graphic != NULL)
+	rl2_destroy_graphic (sym->graphic);
+    sym->graphic = rl2_create_default_graphic ();
+    if (sym->graphic != NULL)
+	parse_point_graphic (node->children, sym->graphic);
+    return 1;
+}
+
+static void
+parse_text_label (xmlNodePtr node, rl2PrivTextSymbolizerPtr text)
+{
+/* parsing Text Symbolizer Label */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "Label") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+			      {
+				  int len;
+				  const char *label =
+				      (const char *) (child->content);
+				  if (text->label != NULL)
+				      free (text->label);
+				  if (label == NULL)
+				    {
+					text->label = NULL;
+					return;
+				    }
+				  len = strlen (label);
+				  text->label = malloc (len + 1);
+				  strcpy (text->label, label);
+				  return;
+			      }
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_text_font (xmlNodePtr node, rl2PrivTextSymbolizerPtr sym)
+{
+/* parsing TextSymbolizer Font */
+    int i;
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "Font") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      for (i = 0; i < RL2_MAX_FONT_FAMILIES; i++)
+			{
+			    if (*(sym->font_families + i) != NULL)
+				free (*(sym->font_families + i));
+			}
+		      sym->font_families_count = 0;
+		      for (i = 0; i < RL2_MAX_FONT_FAMILIES; i++)
+			  *(sym->font_families + i) = NULL;
+		      sym->font_style = RL2_FONT_STYLE_NORMAL;
+		      sym->font_weight = RL2_FONT_WEIGHT_NORMAL;
+		      sym->font_size = 10.0;
+		      while (child)
+			{
+			    if (child->type == XML_ELEMENT_NODE)
+			      {
+				  name = (const char *) (child->name);
+				  if (strcmp (name, "SvgParameter") == 0)
+				    {
+					const char *svg_name;
+					const char *svg_value;
+					if (!svg_parameter_name
+					    (child, &svg_name, &svg_value))
+					  {
+					      child = child->next;
+					      continue;
+					  }
+					if (strcmp (svg_name, "font-family")
+					    == 0)
+					  {
+					      if (sym->font_families_count <
+						  RL2_MAX_FONT_FAMILIES)
+						{
+						    int idx =
+							sym->font_families_count++;
+						    int len =
+							strlen (svg_value);
+						    *(sym->font_families +
+						      idx) = malloc (len + 1);
+						    strcpy (*
+							    (sym->font_families
+							     + idx), svg_value);
+						}
+					  }
+					if (strcmp (svg_name, "font-style") ==
+					    0)
+					  {
+					      if (strcasecmp
+						  (svg_value, "normal") == 0)
+						  sym->font_style =
+						      RL2_FONT_STYLE_NORMAL;
+					      if (strcasecmp
+						  (svg_value, "italic") == 0)
+						  sym->font_style =
+						      RL2_FONT_STYLE_ITALIC;
+					      if (strcasecmp
+						  (svg_value, "oblique") == 0)
+						  sym->font_style =
+						      RL2_FONT_STYLE_OBLIQUE;
+					  }
+					if (strcmp (svg_name, "font-weight")
+					    == 0)
+					  {
+					      if (strcasecmp
+						  (svg_value, "normal") == 0)
+						  sym->font_weight =
+						      RL2_FONT_WEIGHT_NORMAL;
+					      if (strcasecmp
+						  (svg_value, "bold") == 0)
+						  sym->font_weight =
+						      RL2_FONT_WEIGHT_BOLD;
+					  }
+					if (strcmp (svg_name, "font-size") == 0)
+					    sym->font_size = atof (svg_value);
+				    }
+			      }
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_label_anchor_point_xy (xmlNodePtr node, rl2PrivPointPlacementPtr place)
+{
+/* parsing TextSymbolizer label AnchorPoint XY */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "AnchorPointX") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				place->anchor_point_x =
+				    atof ((const char *) child->content);
+			    child = child->next;
+			}
+		  }
+		if (strcmp (name, "AnchorPointY") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				place->anchor_point_y =
+				    atof ((const char *) child->content);
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_label_anchor_point (xmlNodePtr node, rl2PrivPointPlacementPtr place)
+{
+/* parsing TextSymbolizer label AnchorPoint */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "AnchorPoint") == 0)
+		    parse_label_anchor_point_xy (node->children, place);
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_label_displacement_xy (xmlNodePtr node, rl2PrivPointPlacementPtr place)
+{
+/* parsing TextSymbolizer label Displacement */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "DisplacementX") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				place->displacement_x =
+				    atof ((const char *) child->content);
+			    child = child->next;
+			}
+		  }
+		if (strcmp (name, "DisplacementY") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				place->displacement_y =
+				    atof ((const char *) child->content);
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_label_displacement (xmlNodePtr node, rl2PrivPointPlacementPtr place)
+{
+/* parsing TextSymbolizer label Displacement */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "Displacement") == 0)
+		    parse_label_displacement_xy (node->children, place);
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_label_rotation (xmlNodePtr node, rl2PrivPointPlacementPtr place)
+{
+/* parsing TextSymbolizer label Rotation */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "Rotation") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				place->rotation =
+				    atof ((const char *) child->content);
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_point_placement (xmlNodePtr node, rl2PrivPointPlacementPtr place)
+{
+/* parsing Point Placement (TextSymbolizer) */
+    parse_label_anchor_point (node->children, place);
+    parse_label_displacement (node->children, place);
+    parse_label_rotation (node->children, place);
+}
+
+static void
+parse_label_perpendicular_offset (xmlNodePtr node,
+				  rl2PrivLinePlacementPtr place)
+{
+/* parsing TextSymbolizer label PerpendicularOffset */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "PerpendicularOffset") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				place->perpendicular_offset =
+				    atof ((const char *) child->content);
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_label_initial_gap (xmlNodePtr node, rl2PrivLinePlacementPtr place)
 {
-/* return if the RasterStyle has ShadedRelief */
-    rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
-    if (stl == NULL)
-	return RL2_ERROR;
-    *shaded_relief = stl->shadedRelief;
-    return RL2_OK;
+/* parsing TextSymbolizer label InitialGap */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "InitialGap") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				place->initial_gap =
+				    atof ((const char *) child->content);
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_label_gap (xmlNodePtr node, rl2PrivLinePlacementPtr place)
+{
+/* parsing TextSymbolizer label Gap */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "Gap") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				place->gap =
+				    atof ((const char *) child->content);
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_label_is_repeated (xmlNodePtr node, rl2PrivLinePlacementPtr place)
+{
+/* parsing TextSymbolizer label IsRepeated */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "IsRepeated") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+			      {
+				  const char *value =
+				      (const char *) (child->content);
+				  if (strcasecmp (value, "true") == 0)
+				      place->is_repeated = 1;
+				  if (atoi (value) != 0)
+				      place->is_repeated = 1;
+			      }
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_label_is_aligned (xmlNodePtr node, rl2PrivLinePlacementPtr place)
+{
+/* parsing TextSymbolizer label IsAligned */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "IsAligned") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+			      {
+				  const char *value =
+				      (const char *) (child->content);
+				  if (strcasecmp (value, "true") == 0)
+				      place->is_aligned = 1;
+				  if (atoi (value) != 0)
+				      place->is_aligned = 1;
+			      }
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_label_generalize_line (xmlNodePtr node, rl2PrivLinePlacementPtr place)
+{
+/* parsing TextSymbolizer label GeneralizeLine */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "GeneralizeLine") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+			      {
+				  const char *value =
+				      (const char *) (child->content);
+				  if (strcasecmp (value, "true") == 0)
+				      place->generalize_line = 1;
+				  if (atoi (value) != 0)
+				      place->generalize_line = 1;
+			      }
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_line_placement (xmlNodePtr node, rl2PrivLinePlacementPtr place)
+{
+/* parsing Line Placement (TextSymbolizer) */
+    parse_label_perpendicular_offset (node->children, place);
+    parse_label_is_repeated (node->children, place);
+    parse_label_initial_gap (node->children, place);
+    parse_label_gap (node->children, place);
+    parse_label_is_aligned (node->children, place);
+    parse_label_generalize_line (node->children, place);
+}
+
+static void
+parse_text_label_placement (xmlNodePtr node, rl2PrivTextSymbolizerPtr sym)
+{
+/* parsing TextSymbolizer LabelPlacement */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "LabelPlacement") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      if (sym->label_placement_type ==
+			  RL2_LABEL_PLACEMENT_POINT
+			  && sym->label_placement != NULL)
+			  rl2_destroy_point_placement ((rl2PrivPointPlacementPtr) (sym->label_placement));
+		      if (sym->label_placement_type ==
+			  RL2_LABEL_PLACEMENT_LINE
+			  && sym->label_placement != NULL)
+			  rl2_destroy_line_placement ((rl2PrivLinePlacementPtr)
+						      (sym->label_placement));
+		      sym->label_placement_type = RL2_LABEL_PLACEMENT_UNKNOWN;
+		      sym->label_placement = NULL;
+		      while (child)
+			{
+			    if (child->type == XML_ELEMENT_NODE)
+			      {
+				  name = (const char *) (child->name);
+				  if (strcmp (name, "PointPlacement") == 0)
+				    {
+					if (sym->label_placement_type ==
+					    RL2_LABEL_PLACEMENT_POINT
+					    && sym->label_placement != NULL)
+					    rl2_destroy_point_placement ((rl2PrivPointPlacementPtr) (sym->label_placement));
+					if (sym->label_placement_type ==
+					    RL2_LABEL_PLACEMENT_LINE
+					    && sym->label_placement != NULL)
+					    rl2_destroy_line_placement ((rl2PrivLinePlacementPtr) (sym->label_placement));
+					sym->label_placement_type =
+					    RL2_LABEL_PLACEMENT_POINT;
+					sym->label_placement =
+					    rl2_create_default_point_placement
+					    ();
+					parse_point_placement (child,
+							       (rl2PrivPointPlacementPtr)
+							       (sym->label_placement));
+				    }
+				  if (strcmp (name, "LinePlacement") == 0)
+				    {
+					if (sym->label_placement_type ==
+					    RL2_LABEL_PLACEMENT_POINT
+					    && sym->label_placement != NULL)
+					    rl2_destroy_point_placement ((rl2PrivPointPlacementPtr) (sym->label_placement));
+					if (sym->label_placement_type ==
+					    RL2_LABEL_PLACEMENT_LINE
+					    && sym->label_placement != NULL)
+					    rl2_destroy_line_placement ((rl2PrivLinePlacementPtr) (sym->label_placement));
+					sym->label_placement_type =
+					    RL2_LABEL_PLACEMENT_LINE;
+					sym->label_placement =
+					    rl2_create_default_line_placement
+					    ();
+					parse_line_placement (child,
+							      (rl2PrivLinePlacementPtr)
+							      (sym->label_placement));
+				    };
+			      }
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_halo_fill (xmlNodePtr node, rl2PrivHaloPtr halo)
+{
+/* parsing Halo Fill */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "Fill") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      if (halo->fill != NULL)
+			  rl2_destroy_fill (halo->fill);
+		      halo->fill = rl2_create_default_fill ();
+		      halo->fill->red = 0xff;
+		      halo->fill->green = 0xff;
+		      halo->fill->blue = 0xff;
+		      if (halo->fill == NULL)
+			  return;
+		      while (child)
+			{
+			    if (child->type == XML_ELEMENT_NODE)
+			      {
+				  name = (const char *) (child->name);
+				  if (strcmp (name, "SvgParameter") == 0)
+				    {
+					const char *svg_name;
+					const char *svg_value;
+					if (!svg_parameter_name
+					    (child, &svg_name, &svg_value))
+					  {
+					      child = child->next;
+					      continue;
+					  }
+					if (strcmp (svg_name, "fill") == 0)
+					  {
+					      unsigned char red;
+					      unsigned char green;
+					      unsigned char blue;
+					      if (parse_sld_se_color
+						  (svg_value, &red, &green,
+						   &blue))
+						{
+						    halo->fill->red = red;
+						    halo->fill->green = green;
+						    halo->fill->blue = blue;
+						}
+					  }
+				    }
+			      }
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_text_halo (xmlNodePtr node, rl2PrivTextSymbolizerPtr sym)
+{
+/* parsing TextSymbolizer Halo */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "Halo") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      sym->halo = rl2_create_default_halo ();
+		      if (sym->halo == NULL)
+			  return;
+		      sym->halo->fill = rl2_create_default_fill ();
+		      sym->halo->fill->red = 255;
+		      sym->halo->fill->green = 255;
+		      sym->halo->fill->blue = 255;
+		      sym->halo->fill->opacity = 1.0;
+		      while (child)
+			{
+			    if (child->type == XML_ELEMENT_NODE)
+			      {
+				  name = (const char *) (child->name);
+				  if (strcmp (name, "Radius") == 0)
+				    {
+					xmlNodePtr grandchild = child->children;
+					while (grandchild)
+					  {
+					      if (grandchild->type ==
+						  XML_TEXT_NODE
+						  && grandchild->content !=
+						  NULL)
+						{
+						    const char *radius =
+							(const char
+							 *)
+							(grandchild->content);
+						    sym->halo->radius =
+							atof (radius);
+						}
+					      grandchild = grandchild->next;
+					  }
+				    }
+				  if (strcmp (name, "Fill") == 0)
+				      parse_halo_fill (child, sym->halo);
+			      }
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_text_fill (xmlNodePtr node, rl2PrivTextSymbolizerPtr sym)
+{
+/* parsing TextSymbolizer Fill */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "Fill") == 0)
+		  {
+		      xmlNodePtr child = node->children;
+		      sym->fill = rl2_create_default_fill ();
+		      sym->fill->red = 0;
+		      sym->fill->green = 0;
+		      sym->fill->blue = 0;
+		      sym->fill->opacity = 1.0;
+		      if (sym->fill == NULL)
+			  return;
+		      while (child)
+			{
+			    if (child->type == XML_ELEMENT_NODE)
+			      {
+				  name = (const char *) (child->name);
+				  if (strcmp (name, "SvgParameter") == 0)
+				    {
+					const char *svg_name;
+					const char *svg_value;
+					if (!svg_parameter_name
+					    (child, &svg_name, &svg_value))
+					  {
+					      child = child->next;
+					      continue;
+					  }
+					if (strcmp (svg_name, "fill") == 0)
+					  {
+					      unsigned char red;
+					      unsigned char green;
+					      unsigned char blue;
+					      if (parse_sld_se_color
+						  (svg_value, &red, &green,
+						   &blue))
+						{
+						    sym->fill->red = red;
+						    sym->fill->green = green;
+						    sym->fill->blue = blue;
+						}
+					  }
+				    }
+			      }
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static int
+parse_text_symbolizer (xmlNodePtr node, rl2PrivVectorSymbolizerPtr symbolizer)
+{
+/* attempting to parse an SLD/SE TextSymbolizer */
+    rl2PrivVectorSymbolizerItemPtr item;
+    rl2PrivTextSymbolizerPtr sym;
+    if (symbolizer == NULL)
+	return 0;
+
+/* allocating a default Text Symbolizer */
+    item = rl2_create_default_text_symbolizer ();
+    if (item == NULL)
+	return 0;
+    if (item->symbolizer_type != RL2_TEXT_SYMBOLIZER
+	|| item->symbolizer == NULL)
+      {
+	  rl2_destroy_vector_symbolizer_item (item);
+	  return 0;
+      }
+    sym = (rl2PrivTextSymbolizerPtr) (item->symbolizer);
+    if (symbolizer->first == NULL)
+	symbolizer->first = item;
+    if (symbolizer->last != NULL)
+	symbolizer->last->next = item;
+    symbolizer->last = item;
+
+    parse_text_label (node->children, sym);
+    parse_text_font (node->children, sym);
+    parse_text_label_placement (node->children, sym);
+    parse_text_halo (node->children, sym);
+    parse_text_fill (node->children, sym);
+    return 1;
+}
+
+static void
+parse_sld_se_filter_single (xmlNodePtr node, rl2PrivStyleRulePtr rule)
+{
+/* parsing Rule Filter single arg */
+    const char *name = NULL;
+    const char *value = NULL;
+    rl2PrivRuleSingleArgPtr arg =
+	(rl2PrivRuleSingleArgPtr) (rule->comparison_args);
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		xmlNodePtr child;
+		const char *nm = (const char *) (node->name);
+		if (strcmp (nm, "PropertyName") == 0)
+		  {
+		      child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				name = (const char *) (child->content);
+			    child = child->next;
+			}
+		  }
+		if (strcmp (nm, "Literal") == 0)
+		  {
+		      child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				value = (const char *) (child->content);
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+    if (name == NULL || value == NULL)
+      {
+	  if (rule->column_name != NULL)
+	      free (rule->column_name);
+	  rule->column_name = NULL;
+	  if (arg->value != NULL)
+	      free (arg->value);
+	  arg->value = NULL;
+      }
+    else
+      {
+	  int len;
+	  if (rule->column_name != NULL)
+	      free (rule->column_name);
+	  if (arg->value != NULL)
+	      free (arg->value);
+	  len = strlen (name);
+	  rule->column_name = malloc (len + 1);
+	  strcpy (rule->column_name, name);
+	  len = strlen (value);
+	  arg->value = malloc (len + 1);
+	  strcpy (arg->value, value);
+      }
 }
 
-RL2_DECLARE int
-rl2_get_raster_style_shaded_relief (rl2RasterStylePtr style,
-				    int *brightness_only, double *relief_factor)
+static void
+parse_sld_se_filter_like (xmlNodePtr node, rl2PrivStyleRulePtr rule)
 {
-/* return the RasterStyle ShadedRelief parameters */
-    rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
-    if (stl == NULL)
-	return RL2_ERROR;
-    if (stl->shadedRelief)
+/* parsing Rule Filter Like arg */
+    const char *nm;
+    const char *name = NULL;
+    const char *wild_card = NULL;
+    const char *single_char = NULL;
+    const char *escape_char = NULL;
+    const char *value = NULL;
+    rl2PrivRuleLikeArgsPtr args =
+	(rl2PrivRuleLikeArgsPtr) (rule->comparison_args);
+    struct _xmlAttr *attr;
+
+    attr = node->properties;
+    while (attr != NULL)
+      {
+	  /* attributes */
+	  if (attr->type == XML_ATTRIBUTE_NODE)
+	    {
+		xmlNode *text;
+		nm = (const char *) (attr->name);
+		if (strcmp (nm, "wildCard") == 0)
+		  {
+		      text = attr->children;
+		      if (text != NULL)
+			{
+			    if (text->type == XML_TEXT_NODE)
+			      {
+				  wild_card = (const char *) (text->content);
+
+			      }
+			}
+		  }
+		if (strcmp (nm, "singleChar") == 0)
+		  {
+		      text = attr->children;
+		      if (text != NULL)
+			{
+			    if (text->type == XML_TEXT_NODE)
+			      {
+				  single_char = (const char *) (text->content);
+
+			      }
+			}
+		  }
+		if (strcmp (nm, "escapeChar") == 0)
+		  {
+		      text = attr->children;
+		      if (text != NULL)
+			{
+			    if (text->type == XML_TEXT_NODE)
+			      {
+				  escape_char = (const char *) (text->content);
+
+			      }
+			}
+		  }
+	    }
+	  attr = attr->next;
+      }
+
+    node = node->children;
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		xmlNodePtr child;
+		const char *nm = (const char *) (node->name);
+		if (strcmp (nm, "PropertyName") == 0)
+		  {
+		      child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				name = (const char *) (child->content);
+			    child = child->next;
+			}
+		  }
+		if (strcmp (nm, "Literal") == 0)
+		  {
+		      child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				value = (const char *) (child->content);
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+    if (name == NULL || wild_card == NULL || single_char == NULL
+	|| escape_char == NULL || value == NULL)
+      {
+	  if (rule->column_name != NULL)
+	      free (rule->column_name);
+	  rule->column_name = NULL;
+	  if (args->wild_card != NULL)
+	      free (args->wild_card);
+	  args->wild_card = NULL;
+	  if (args->single_char != NULL)
+	      free (args->single_char);
+	  args->single_char = NULL;
+	  if (args->escape_char != NULL)
+	      free (args->escape_char);
+	  args->escape_char = NULL;
+	  if (args->value != NULL)
+	      free (args->value);
+	  args->value = NULL;
+      }
+    else
       {
-	  *brightness_only = stl->brightnessOnly;
-	  *relief_factor = stl->reliefFactor;
-	  return RL2_OK;
+	  int len;
+	  if (rule->column_name != NULL)
+	      free (rule->column_name);
+	  if (args->wild_card != NULL)
+	      free (args->wild_card);
+	  if (args->single_char != NULL)
+	      free (args->single_char);
+	  if (args->escape_char != NULL)
+	      free (args->escape_char);
+	  if (args->value != NULL)
+	      free (args->value);
+	  if (args->value != NULL)
+	      free (args->value);
+	  len = strlen (name);
+	  rule->column_name = malloc (len + 1);
+	  strcpy (rule->column_name, name);
+	  len = strlen (wild_card);
+	  args->wild_card = malloc (len + 1);
+	  strcpy (args->wild_card, wild_card);
+	  len = strlen (single_char);
+	  args->single_char = malloc (len + 1);
+	  strcpy (args->single_char, single_char);
+	  len = strlen (escape_char);
+	  args->escape_char = malloc (len + 1);
+	  strcpy (args->escape_char, escape_char);
+	  len = strlen (value);
+	  args->value = malloc (len + 1);
+	  strcpy (args->value, value);
       }
-    return RL2_ERROR;
 }
 
-RL2_DECLARE int
-rl2_has_raster_style_color_map_interpolated (rl2RasterStylePtr style,
-					     int *interpolated)
+static void
+parse_sld_se_filter_between (xmlNodePtr node, rl2PrivStyleRulePtr rule)
 {
-/* return if the RasterStyle has an Interpolated ColorMap */
-    rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
-    if (stl == NULL)
-	return RL2_ERROR;
-    if (stl->interpolate != NULL)
-	*interpolated = 1;
+/* parsing Rule Filter between args */
+    const char *name = NULL;
+    const char *lower = NULL;
+    const char *upper = NULL;
+    rl2PrivRuleBetweenArgsPtr args =
+	(rl2PrivRuleBetweenArgsPtr) (rule->comparison_args);
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		xmlNodePtr child;
+		const char *nm = (const char *) (node->name);
+		if (strcmp (nm, "PropertyName") == 0)
+		  {
+		      child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				name = (const char *) (child->content);
+			    child = child->next;
+			}
+		  }
+		if (strcmp (nm, "LowerBoundary") == 0)
+		  {
+		      child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_ELEMENT_NODE)
+			      {
+				  nm = (const char *) (child->name);
+				  if (strcmp (nm, "Literal") == 0)
+				    {
+					xmlNodePtr grandchild = child->children;
+					while (grandchild)
+					  {
+					      if (grandchild->type ==
+						  XML_TEXT_NODE
+						  && grandchild->content !=
+						  NULL)
+						  lower =
+						      (const char
+						       *) (grandchild->content);
+					      grandchild = grandchild->next;
+					  }
+				    }
+			      }
+			    child = child->next;
+			}
+		  }
+		if (strcmp (nm, "UpperBoundary") == 0)
+		  {
+		      child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_ELEMENT_NODE)
+			      {
+				  nm = (const char *) (child->name);
+				  if (strcmp (nm, "Literal") == 0)
+				    {
+					xmlNodePtr grandchild = child->children;
+					while (grandchild)
+					  {
+					      if (grandchild->type ==
+						  XML_TEXT_NODE
+						  && grandchild->content !=
+						  NULL)
+						  upper =
+						      (const char
+						       *) (grandchild->content);
+					      grandchild = grandchild->next;
+					  }
+				    }
+			      }
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+    if (name == NULL || lower == NULL || upper == NULL)
+      {
+	  if (rule->column_name != NULL)
+	      free (rule->column_name);
+	  rule->column_name = NULL;
+	  if (args->lower != NULL)
+	      free (args->lower);
+	  args->lower = NULL;
+	  if (args->upper != NULL)
+	      free (args->upper);
+	  args->upper = NULL;
+      }
     else
-	*interpolated = 0;
-    return RL2_OK;
+      {
+	  int len;
+	  if (rule->column_name != NULL)
+	      free (rule->column_name);
+	  if (args->lower != NULL)
+	      free (args->lower);
+	  if (args->upper != NULL)
+	      free (args->upper);
+	  len = strlen (name);
+	  rule->column_name = malloc (len + 1);
+	  strcpy (rule->column_name, name);
+	  len = strlen (lower);
+	  args->lower = malloc (len + 1);
+	  strcpy (args->lower, lower);
+	  len = strlen (upper);
+	  args->upper = malloc (len + 1);
+	  strcpy (args->upper, upper);
+      }
 }
 
-RL2_DECLARE int
-rl2_has_raster_style_color_map_categorized (rl2RasterStylePtr style,
-					    int *categorized)
+static void
+parse_sld_se_filter_null (xmlNodePtr node, rl2PrivStyleRulePtr rule)
 {
-/* return if the RasterStyle has a Categorized ColorMap */
-    rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
-    if (stl == NULL)
-	return RL2_ERROR;
-    if (stl->categorize != NULL)
-	*categorized = 1;
+/* parsing Rule Filter NULL */
+    const char *name = NULL;
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		xmlNodePtr child;
+		const char *nm = (const char *) (node->name);
+		if (strcmp (nm, "PropertyName") == 0)
+		  {
+		      child = node->children;
+		      while (child)
+			{
+			    if (child->type == XML_TEXT_NODE
+				&& child->content != NULL)
+				name = (const char *) (child->content);
+			    child = child->next;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+    if (name == NULL)
+      {
+	  if (rule->column_name != NULL)
+	      free (rule->column_name);
+	  rule->column_name = NULL;
+      }
     else
-	*categorized = 0;
-    return RL2_OK;
+      {
+	  int len;
+	  if (rule->column_name != NULL)
+	      free (rule->column_name);
+	  len = strlen (name);
+	  rule->column_name = malloc (len + 1);
+	  strcpy (rule->column_name, name);
+      }
 }
 
-RL2_DECLARE int
-rl2_get_raster_style_color_map_default (rl2RasterStylePtr style,
-					unsigned char *red,
-					unsigned char *green,
-					unsigned char *blue)
+static void
+parse_sld_se_filter_args (xmlNodePtr node, rl2PrivStyleRulePtr rule)
 {
-/* return the RasterStyle ColorMap Default color */
-    rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
-    if (stl == NULL)
-	return RL2_ERROR;
-    if (stl->interpolate != NULL)
+/* parsing Rule Filter args */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "PropertyIsEqualTo") == 0)
+		  {
+		      rule->comparison_args =
+			  rl2_create_default_rule_single_arg ();
+		      rule->comparison_op = RL2_COMPARISON_EQ;
+		      parse_sld_se_filter_single (node->children, rule);
+		  }
+		if (strcmp (name, "PropertyIsNotEqualTo") == 0)
+		  {
+		      rule->comparison_args =
+			  rl2_create_default_rule_single_arg ();
+		      rule->comparison_op = RL2_COMPARISON_NE;
+		      parse_sld_se_filter_single (node->children, rule);
+		  }
+		if (strcmp (name, "PropertyIsLessThan") == 0)
+		  {
+		      rule->comparison_args =
+			  rl2_create_default_rule_single_arg ();
+		      rule->comparison_op = RL2_COMPARISON_LT;
+		      parse_sld_se_filter_single (node->children, rule);
+		  }
+		if (strcmp (name, "PropertyIsGreaterThan") == 0)
+		  {
+		      rule->comparison_args =
+			  rl2_create_default_rule_single_arg ();
+		      rule->comparison_op = RL2_COMPARISON_GT;
+		      parse_sld_se_filter_single (node->children, rule);
+		  }
+		if (strcmp (name, "PropertyIsLessThanOrEqualTo") == 0)
+		  {
+		      rule->comparison_args =
+			  rl2_create_default_rule_single_arg ();
+		      rule->comparison_op = RL2_COMPARISON_LE;
+		      parse_sld_se_filter_single (node->children, rule);
+		  }
+		if (strcmp (name, "PropertyIsGreaterThanOrEqualTo") == 0)
+		  {
+		      rule->comparison_args =
+			  rl2_create_default_rule_single_arg ();
+		      rule->comparison_op = RL2_COMPARISON_GE;
+		      parse_sld_se_filter_single (node->children, rule);
+		  }
+		if (strcmp (name, "PropertyIsLike") == 0)
+		  {
+		      rule->comparison_args =
+			  rl2_create_default_rule_like_args ();
+		      rule->comparison_op = RL2_COMPARISON_LIKE;
+		      parse_sld_se_filter_like (node, rule);
+		  }
+		if (strcmp (name, "PropertyIsBetween") == 0)
+		  {
+		      rule->comparison_args =
+			  rl2_create_default_rule_between_args ();
+		      rule->comparison_op = RL2_COMPARISON_BETWEEN;
+		      parse_sld_se_filter_between (node->children, rule);
+		  }
+		if (strcmp (name, "PropertyIsNull") == 0)
+		  {
+		      rule->comparison_op = RL2_COMPARISON_NULL;
+		      parse_sld_se_filter_null (node->children, rule);
+		  }
+	    }
+	  node = node->next;
+      }
+}
+
+static void
+parse_sld_se_filter (xmlNodePtr node, rl2PrivStyleRulePtr rule)
+{
+/* parsing Rule Filter */
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "Filter") == 0)
+		    parse_sld_se_filter_args (node->children, rule);
+		if (strcmp (name, "ElseFilter") == 0)
+		    rule->else_rule = 1;
+	    }
+	  node = node->next;
+      }
+}
+
+static int
+parse_vector_style_rule (xmlNodePtr node, rl2PrivStyleRulePtr rule)
+{
+/* attempting to parse an SLD/SE Style Rule (vector type) */
+    int ret;
+    int count = 0;
+    rl2PrivVectorSymbolizerPtr symb = rl2_create_default_vector_symbolizer ();
+    parse_sld_se_filter (node, rule);
+    parse_sld_se_min_scale_denominator (node, rule);
+    parse_sld_se_max_scale_denominator (node, rule);
+    while (node)
+      {
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "PointSymbolizer") == 0)
+		  {
+		      ret = parse_point_symbolizer (node, symb);
+		      if (ret)
+			{
+			    rule->style_type = RL2_VECTOR_STYLE;
+			    rule->style = symb;
+			    count++;
+			}
+		  }
+		if (strcmp (name, "LineSymbolizer") == 0)
+		  {
+		      ret = parse_line_symbolizer (node, symb);
+		      if (ret)
+			{
+			    rule->style_type = RL2_VECTOR_STYLE;
+			    rule->style = symb;
+			    count++;
+			}
+		  }
+		if (strcmp (name, "PolygonSymbolizer") == 0)
+		  {
+		      ret = parse_polygon_symbolizer (node, symb);
+		      if (ret)
+			{
+			    rule->style_type = RL2_VECTOR_STYLE;
+			    rule->style = symb;
+			    count++;
+			}
+		  }
+		if (strcmp (name, "TextSymbolizer") == 0)
+		  {
+		      ret = parse_text_symbolizer (node, symb);
+		      if (ret)
+			{
+			    rule->style_type = RL2_VECTOR_STYLE;
+			    rule->style = symb;
+			    count++;
+			}
+		  }
+	    }
+	  node = node->next;
+      }
+    if (count <= 0)
       {
-	  *red = stl->interpolate->dfltRed;
-	  *green = stl->interpolate->dfltGreen;
-	  *blue = stl->interpolate->dfltBlue;
-	  return RL2_OK;
+	  rl2_destroy_vector_symbolizer (symb);
+	  return 0;
       }
-    if (stl->categorize != NULL)
+    return 1;
+}
+
+static int
+parse_feature_type_style (xmlNodePtr node, rl2PrivFeatureTypeStylePtr style)
+{
+/* parsing an SLD/SE FeatureType Style */
+    int count = 0;
+    while (node)
       {
-	  *red = stl->categorize->dfltRed;
-	  *green = stl->categorize->dfltGreen;
-	  *blue = stl->categorize->dfltBlue;
-	  return RL2_OK;
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "Rule") == 0)
+		  {
+		      rl2PrivStyleRulePtr rule =
+			  rl2_create_default_style_rule ();
+		      int ret = parse_vector_style_rule (node->children, rule);
+		      if (ret)
+			{
+			    if (rule->else_rule)
+			      {
+				  /* special case: ElseRule */
+				  if (style->else_rule != NULL)
+				      rl2_destroy_style_rule (style->else_rule);
+				  style->else_rule = rule;
+			      }
+			    else
+			      {
+				  /* ordinary Rule */
+				  if (style->first_rule == NULL)
+				      style->first_rule = rule;
+				  if (style->last_rule != NULL)
+				      style->last_rule->next = rule;
+				  style->last_rule = rule;
+			      }
+			    count++;
+			}
+		      else
+			  rl2_destroy_style_rule (rule);
+		  }
+	    }
+	  node = node->next;
       }
-    return RL2_ERROR;
+    if (count <= 0)
+	return 0;
+    return 1;
 }
 
-RL2_DECLARE int
-rl2_get_raster_style_color_map_category_base (rl2RasterStylePtr style,
-					      unsigned char *red,
-					      unsigned char *green,
-					      unsigned char *blue)
+static int
+find_feature_type_style (xmlNodePtr node, rl2PrivFeatureTypeStylePtr style,
+			 int *loop)
 {
-/* return the RasterStyle ColorMap Category base-color */
-    rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
-    if (stl == NULL)
-	return RL2_ERROR;
-    if (stl->categorize != NULL)
+/* recursivly searching an SLD/SE VectorSymbolizer */
+    int ret;
+    while (node)
       {
-	  *red = stl->categorize->baseRed;
-	  *green = stl->categorize->baseGreen;
-	  *blue = stl->categorize->baseBlue;
-	  return RL2_OK;
+	  if (node->type == XML_ELEMENT_NODE)
+	    {
+		const char *name = (const char *) (node->name);
+		if (strcmp (name, "PointSymbolizer") == 0)
+		  {
+		      rl2PrivVectorSymbolizerPtr symb =
+			  rl2_create_default_vector_symbolizer ();
+		      ret = parse_point_symbolizer (node, symb);
+		      if (ret)
+			{
+			    rl2PrivStyleRulePtr rule =
+				rl2_create_default_style_rule ();
+			    if (rule == NULL)
+			      {
+				  rl2_destroy_vector_symbolizer (symb);
+				  ret = 0;
+			      }
+			    rule->style_type = RL2_VECTOR_STYLE;
+			    rule->style = symb;
+			    style->else_rule = rule;
+			}
+		      else
+			  rl2_destroy_vector_symbolizer (symb);
+		      *loop = 0;
+		      return ret;
+		  }
+		if (strcmp (name, "LineSymbolizer") == 0)
+		  {
+		      rl2PrivVectorSymbolizerPtr symb =
+			  rl2_create_default_vector_symbolizer ();
+		      ret = parse_line_symbolizer (node, symb);
+		      if (ret)
+			{
+			    rl2PrivStyleRulePtr rule =
+				rl2_create_default_style_rule ();
+			    if (rule == NULL)
+			      {
+				  rl2_destroy_vector_symbolizer (symb);
+				  ret = 0;
+			      }
+			    rule->style_type = RL2_VECTOR_STYLE;
+			    rule->style = symb;
+			    style->else_rule = rule;
+			}
+		      else
+			  rl2_destroy_vector_symbolizer (symb);
+		      *loop = 0;
+		      return ret;
+		  }
+		if (strcmp (name, "PolygonSymbolizer") == 0)
+		  {
+		      rl2PrivVectorSymbolizerPtr symb =
+			  rl2_create_default_vector_symbolizer ();
+		      ret = parse_polygon_symbolizer (node, symb);
+		      if (ret)
+			{
+			    rl2PrivStyleRulePtr rule =
+				rl2_create_default_style_rule ();
+			    if (rule == NULL)
+			      {
+				  rl2_destroy_vector_symbolizer (symb);
+				  ret = 0;
+			      }
+			    rule->style_type = RL2_VECTOR_STYLE;
+			    rule->style = symb;
+			    style->else_rule = rule;
+			}
+		      else
+			  rl2_destroy_vector_symbolizer (symb);
+		      *loop = 0;
+		      return ret;
+		  }
+		if (strcmp (name, "TextSymbolizer") == 0)
+		  {
+		      rl2PrivVectorSymbolizerPtr symb =
+			  rl2_create_default_vector_symbolizer ();
+		      ret = parse_text_symbolizer (node, symb);
+		      if (ret)
+			{
+			    rl2PrivStyleRulePtr rule =
+				rl2_create_default_style_rule ();
+			    if (rule == NULL)
+			      {
+				  rl2_destroy_vector_symbolizer (symb);
+				  ret = 0;
+			      }
+			    rule->style_type = RL2_VECTOR_STYLE;
+			    rule->style = symb;
+			    style->else_rule = rule;
+			}
+		      else
+			  rl2_destroy_vector_symbolizer (symb);
+		      *loop = 0;
+		      return ret;
+		  }
+		if (strcmp (name, "FeatureTypeStyle") == 0)
+		  {
+		      ret = parse_feature_type_style (node->children, style);
+		      *loop = 0;
+		      return ret;
+		  }
+	    }
+	  node = node->next;
       }
-    return RL2_ERROR;
+    return 0;
 }
 
-RL2_DECLARE int
-rl2_get_raster_style_color_map_count (rl2RasterStylePtr style, int *count)
+static void
+build_column_names_array (rl2PrivFeatureTypeStylePtr style)
 {
-/* return the RasterStyle ColorMap items count */
-    int cnt;
-    rl2PrivColorMapPointPtr pt;
-    rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
-    if (stl == NULL)
-	return RL2_ERROR;
-    if (stl->categorize != NULL)
+/* building the column names array - Feature Type Style */
+    char **strings;
+    char *dupl;
+    int len;
+    int count = 0;
+    int count2 = 0;
+    int i;
+    int j;
+    rl2PrivStyleRulePtr pR;
+    rl2PrivVectorSymbolizerPtr pV;
+    rl2PrivVectorSymbolizerItemPtr item;
+    rl2PrivTextSymbolizerPtr text;
+
+    pR = style->first_rule;
+    while (pR != NULL)
       {
-	  cnt = 0;
-	  pt = stl->categorize->first;
-	  while (pt != NULL)
+	  /* counting max column names */
+	  if (pR->column_name != NULL)
+	      count++;
+	  if (pR->style_type == RL2_VECTOR_STYLE && pR->style != NULL)
 	    {
-		cnt++;
-		pt = pt->next;
+		pV = (rl2PrivVectorSymbolizerPtr) (pR->style);
+		item = pV->first;
+		while (item != NULL)
+		  {
+		      if (item->symbolizer_type == RL2_TEXT_SYMBOLIZER
+			  && item->symbolizer != NULL)
+			{
+			    text =
+				(rl2PrivTextSymbolizerPtr) (item->symbolizer);
+			    if (text->label != NULL)
+				count++;
+			}
+		      item = item->next;
+		  }
 	    }
-	  *count = cnt;
-	  return RL2_OK;
+	  pR = pR->next;
       }
-    if (stl->interpolate != NULL)
+    pR = style->else_rule;
+    if (pR != NULL)
       {
-	  cnt = 0;
-	  pt = stl->interpolate->first;
-	  while (pt != NULL)
+	  if (pR->column_name != NULL)
+	      count++;
+	  if (pR->style_type == RL2_VECTOR_STYLE && pR->style != NULL)
 	    {
-		cnt++;
-		pt = pt->next;
+		pV = (rl2PrivVectorSymbolizerPtr) (pR->style);
+		item = pV->first;
+		while (item != NULL)
+		  {
+		      if (item->symbolizer_type == RL2_TEXT_SYMBOLIZER
+			  && item->symbolizer != NULL)
+			{
+			    text =
+				(rl2PrivTextSymbolizerPtr) (item->symbolizer);
+			    if (text->label != NULL)
+				count++;
+			}
+		      item = item->next;
+		  }
 	    }
-	  *count = cnt;
-	  return RL2_OK;
       }
-    return RL2_ERROR;
-}
+    if (count == 0)
+	return;
 
-RL2_DECLARE int
-rl2_get_raster_style_color_map_entry (rl2RasterStylePtr style, int index,
-				      double *value, unsigned char *red,
-				      unsigned char *green, unsigned char *blue)
-{
-/* return the RasterStyle ColorMap item values */
-    int cnt;
-    rl2PrivColorMapPointPtr pt;
-    rl2PrivRasterStylePtr stl = (rl2PrivRasterStylePtr) style;
-    if (stl == NULL)
-	return RL2_ERROR;
-    if (stl->categorize != NULL)
+    strings = malloc (sizeof (char *) * count);
+    dupl = malloc (sizeof (char) * count);
+    i = 0;
+    pR = style->first_rule;
+    while (pR != NULL)
       {
-	  cnt = 0;
-	  pt = stl->categorize->first;
-	  while (pt != NULL)
+	  /* initializing the column names temporary array */
+	  if (pR->column_name != NULL)
+	    {
+		len = strlen (pR->column_name);
+		*(strings + i) = malloc (len + 1);
+		strcpy (*(strings + i), pR->column_name);
+		*(dupl + i) = 'N';
+		i++;
+	    }
+	  if (pR->style_type == RL2_VECTOR_STYLE && pR->style != NULL)
 	    {
-		if (index == cnt)
+		pV = (rl2PrivVectorSymbolizerPtr) (pR->style);
+		item = pV->first;
+		while (item != NULL)
 		  {
-		      *value = pt->value;
-		      *red = pt->red;
-		      *green = pt->green;
-		      *blue = pt->blue;
-		      return RL2_OK;
+		      if (item->symbolizer_type == RL2_TEXT_SYMBOLIZER
+			  && item->symbolizer != NULL)
+			{
+			    text =
+				(rl2PrivTextSymbolizerPtr) (item->symbolizer);
+			    if (text->label != NULL)
+			      {
+				  len = strlen (text->label);
+				  *(strings + i) = malloc (len + 1);
+				  strcpy (*(strings + i), text->label);
+				  *(dupl + i) = 'N';
+				  i++;
+			      }
+			}
+		      item = item->next;
 		  }
-		cnt++;
-		pt = pt->next;
 	    }
+	  pR = pR->next;
       }
-    if (stl->interpolate != NULL)
+    pR = style->else_rule;
+    if (pR != NULL)
       {
-	  cnt = 0;
-	  pt = stl->interpolate->first;
-	  while (pt != NULL)
+	  if (pR->column_name != NULL)
 	    {
-		if (index == cnt)
+		len = strlen (pR->column_name);
+		*(strings + i) = malloc (len + 1);
+		strcpy (*(strings + i), pR->column_name);
+		*(dupl + i) = 'N';
+		i++;
+	    }
+	  if (pR->style_type == RL2_VECTOR_STYLE && pR->style != NULL)
+	    {
+		pV = (rl2PrivVectorSymbolizerPtr) (pR->style);
+		item = pV->first;
+		while (item != NULL)
 		  {
-		      *value = pt->value;
-		      *red = pt->red;
-		      *green = pt->green;
-		      *blue = pt->blue;
-		      return RL2_OK;
+		      if (item->symbolizer_type == RL2_TEXT_SYMBOLIZER
+			  && item->symbolizer != NULL)
+			{
+			    text =
+				(rl2PrivTextSymbolizerPtr) (item->symbolizer);
+			    if (text->label != NULL)
+			      {
+				  len = strlen (text->label);
+				  *(strings + i) = malloc (len + 1);
+				  strcpy (*(strings + i), text->label);
+				  *(dupl + i) = 'N';
+				  i++;
+			      }
+			}
+		      item = item->next;
 		  }
-		cnt++;
-		pt = pt->next;
 	    }
       }
-    return RL2_ERROR;
+
+    for (i = 0; i < count; i++)
+      {
+	  /* identifying all duplicates */
+	  if (*(dupl + i) == 'Y')
+	      continue;
+	  for (j = i + 1; j < count; j++)
+	    {
+		if (strcasecmp (*(strings + i), *(strings + j)) == 0)
+		    *(dupl + j) = 'Y';
+	    }
+      }
+
+/* allocating the final array */
+    for (i = 0; i < count; i++)
+      {
+	  if (*(dupl + i) == 'N')
+	      count2++;
+      }
+    style->columns_count = count2;
+    style->column_names = malloc (sizeof (char *) * count2);
+    j = 0;
+    for (i = 0; i < count; i++)
+      {
+	  /* initializing the final array */
+	  if (*(dupl + i) == 'N')
+	    {
+		len = strlen (*(strings + i));
+		*(style->column_names + j) = malloc (len + 1);
+		strcpy (*(style->column_names + j), *(strings + i));
+		j++;
+	    }
+      }
+
+/* final cleanup */
+    for (i = 0; i < count; i++)
+      {
+	  if (*(strings + i) != NULL)
+	      free (*(strings + i));
+      }
+    free (strings);
+    free (dupl);
+}
+
+RL2_PRIVATE rl2FeatureTypeStylePtr
+feature_type_style_from_xml (char *name, unsigned char *xml)
+{
+/* attempting to build a Feature Type Style object from an SLD/SE XML style */
+    rl2PrivFeatureTypeStylePtr style = NULL;
+    xmlDocPtr xml_doc = NULL;
+    xmlNodePtr root;
+    int loop = 1;
+    xmlGenericErrorFunc silentError = (xmlGenericErrorFunc) dummySilentError;
+
+    style = malloc (sizeof (rl2PrivFeatureTypeStyle));
+    if (style == NULL)
+	return NULL;
+    style->name = name;
+    style->first_rule = NULL;
+    style->last_rule = NULL;
+    style->else_rule = NULL;
+    style->columns_count = 0;
+    style->column_names = NULL;
+
+/* parsing the XML document */
+    xmlSetGenericErrorFunc (NULL, silentError);
+    xml_doc =
+	xmlReadMemory ((const char *) xml, strlen ((const char *) xml),
+		       "noname.xml", NULL, 0);
+    if (xml_doc == NULL)
+      {
+	  /* parsing error; not a well-formed XML */
+	  goto error;
+      }
+    root = xmlDocGetRootElement (xml_doc);
+    if (root == NULL)
+	goto error;
+    if (!find_feature_type_style (root, style, &loop))
+	goto error;
+    xmlFreeDoc (xml_doc);
+    free (xml);
+    xml = NULL;
+
+    if (style->name == NULL)
+	goto error;
+    build_column_names_array (style);
+
+    return (rl2FeatureTypeStylePtr) style;
+
+  error:
+    if (xml != NULL)
+	free (xml);
+    if (xml_doc != NULL)
+	xmlFreeDoc (xml_doc);
+    if (style != NULL)
+	rl2_destroy_feature_type_style ((rl2FeatureTypeStylePtr) style);
+    return NULL;
 }
 
 static void
@@ -1715,8 +4349,7 @@ parse_group_style (xmlNodePtr node, rl2PrivGroupStylePtr style)
 }
 
 RL2_PRIVATE rl2GroupStylePtr
-group_style_from_sld_xml (char *name, char *title, char *abstract,
-			  unsigned char *xml)
+group_style_from_sld_xml (char *name, unsigned char *xml)
 {
 /* attempting to build a Layer Group Style object from an SLD XML style */
     rl2PrivGroupStylePtr style = NULL;
@@ -1728,8 +4361,6 @@ group_style_from_sld_xml (char *name, char *title, char *abstract,
     if (style == NULL)
 	return NULL;
     style->name = name;
-    style->title = title;
-    style->abstract = abstract;
     style->first = NULL;
     style->last = NULL;
     style->valid = 0;
@@ -1768,239 +4399,6 @@ group_style_from_sld_xml (char *name, char *title, char *abstract,
     return NULL;
 }
 
-RL2_DECLARE void
-rl2_destroy_group_style (rl2GroupStylePtr style)
-{
-/* destroying a Group Style object */
-    rl2PrivChildStylePtr child;
-    rl2PrivChildStylePtr child_n;
-    rl2PrivGroupStylePtr stl = (rl2PrivGroupStylePtr) style;
-    if (stl == NULL)
-	return;
-
-    if (stl->name != NULL)
-	free (stl->name);
-    if (stl->title != NULL)
-	free (stl->title);
-    if (stl->abstract != NULL)
-	free (stl->abstract);
-    child = stl->first;
-    while (child != NULL)
-      {
-	  child_n = child->next;
-	  if (child->namedLayer != NULL)
-	      free (child->namedLayer);
-	  if (child->namedStyle != NULL)
-	      free (child->namedStyle);
-	  free (child);
-	  child = child_n;
-      }
-    free (stl);
-}
-
-RL2_DECLARE const char *
-rl2_get_group_style_name (rl2GroupStylePtr style)
-{
-/* return the Group Style Name */
-    rl2PrivGroupStylePtr stl = (rl2PrivGroupStylePtr) style;
-    if (stl == NULL)
-	return NULL;
-    return stl->name;
-}
-
-RL2_DECLARE const char *
-rl2_get_group_style_title (rl2GroupStylePtr style)
-{
-/* return the Group Style Title */
-    rl2PrivGroupStylePtr stl = (rl2PrivGroupStylePtr) style;
-    if (stl == NULL)
-	return NULL;
-    return stl->title;
-}
-
-RL2_DECLARE const char *
-rl2_get_group_style_abstract (rl2GroupStylePtr style)
-{
-/* return the Group Style Abstract */
-    rl2PrivGroupStylePtr stl = (rl2PrivGroupStylePtr) style;
-    if (stl == NULL)
-	return NULL;
-    return stl->abstract;
-}
-
-RL2_DECLARE int
-rl2_is_valid_group_style (rl2GroupStylePtr style, int *valid)
-{
-/* testing a Group Style for validity */
-    rl2PrivGroupStylePtr stl = (rl2PrivGroupStylePtr) style;
-    if (stl == NULL)
-	return RL2_ERROR;
-    *valid = stl->valid;
-    return RL2_OK;
-}
-
-RL2_DECLARE int
-rl2_get_group_style_count (rl2GroupStylePtr style, int *count)
-{
-/* return the total count of Group Style Items */
-    int cnt = 0;
-    rl2PrivChildStylePtr child;
-    rl2PrivGroupStylePtr stl = (rl2PrivGroupStylePtr) style;
-    if (stl == NULL)
-	return RL2_ERROR;
-    child = stl->first;
-    while (child != NULL)
-      {
-	  /* counting how many Children */
-	  cnt++;
-	  child = child->next;
-      }
-    *count = cnt;
-    return RL2_OK;
-}
-
-RL2_DECLARE const char *
-rl2_get_group_named_layer (rl2GroupStylePtr style, int index)
-{
-/* return the Nth NamedLayer from a Group Style */
-    int cnt = 0;
-    const char *str;
-    rl2PrivChildStylePtr child;
-    rl2PrivGroupStylePtr stl = (rl2PrivGroupStylePtr) style;
-    if (stl == NULL)
-	return NULL;
-    if (index < 0)
-	return NULL;
-    child = stl->first;
-    while (child != NULL)
-      {
-	  /* counting how many Children */
-	  cnt++;
-	  child = child->next;
-      }
-    if (index >= cnt)
-	return NULL;
-    cnt = 0;
-    child = stl->first;
-    while (child != NULL)
-      {
-	  if (cnt == index)
-	    {
-		str = child->namedLayer;
-		break;
-	    }
-	  cnt++;
-	  child = child->next;
-      }
-    return str;
-}
-
-RL2_DECLARE const char *
-rl2_get_group_named_style (rl2GroupStylePtr style, int index)
-{
-/* return the Nth NamedStyle from a Group Style */
-    int cnt = 0;
-    const char *str;
-    rl2PrivChildStylePtr child;
-    rl2PrivGroupStylePtr stl = (rl2PrivGroupStylePtr) style;
-    if (stl == NULL)
-	return NULL;
-    if (index < 0)
-	return NULL;
-    child = stl->first;
-    while (child != NULL)
-      {
-	  /* counting how many Children */
-	  cnt++;
-	  child = child->next;
-      }
-    if (index >= cnt)
-	return NULL;
-    cnt = 0;
-    child = stl->first;
-    while (child != NULL)
-      {
-	  if (cnt == index)
-	    {
-		str = child->namedStyle;
-		break;
-	    }
-	  cnt++;
-	  child = child->next;
-      }
-    return str;
-}
-
-RL2_DECLARE int
-rl2_is_valid_group_named_layer (rl2GroupStylePtr style, int index, int *valid)
-{
-/* testing for validity the Nth NamedLayer from a Group Style */
-    int cnt = 0;
-    rl2PrivChildStylePtr child;
-    rl2PrivGroupStylePtr stl = (rl2PrivGroupStylePtr) style;
-    if (stl == NULL)
-	return RL2_ERROR;
-    if (index < 0)
-	return RL2_ERROR;
-    child = stl->first;
-    while (child != NULL)
-      {
-	  /* counting how many Children */
-	  cnt++;
-	  child = child->next;
-      }
-    if (index >= cnt)
-	return RL2_ERROR;
-    cnt = 0;
-    child = stl->first;
-    while (child != NULL)
-      {
-	  if (cnt == index)
-	    {
-		*valid = child->validLayer;
-		break;
-	    }
-	  cnt++;
-	  child = child->next;
-      }
-    return RL2_OK;
-}
-
-RL2_DECLARE int
-rl2_is_valid_group_named_style (rl2GroupStylePtr style, int index, int *valid)
-{
-/* testing for validity the Nth NamedStyle from a Group Style */
-    int cnt = 0;
-    rl2PrivChildStylePtr child;
-    rl2PrivGroupStylePtr stl = (rl2PrivGroupStylePtr) style;
-    if (stl == NULL)
-	return RL2_ERROR;
-    if (index < 0)
-	return RL2_ERROR;
-    child = stl->first;
-    while (child != NULL)
-      {
-	  /* counting how many Children */
-	  cnt++;
-	  child = child->next;
-      }
-    if (index >= cnt)
-	return RL2_ERROR;
-    cnt = 0;
-    child = stl->first;
-    while (child != NULL)
-      {
-	  if (cnt == index)
-	    {
-		*valid = child->validStyle;
-		break;
-	    }
-	  cnt++;
-	  child = child->next;
-      }
-    return RL2_OK;
-}
-
 static rl2PrivGroupRendererPtr
 rl2_alloc_group_renderer (int count)
 {
@@ -2025,7 +4423,7 @@ rl2_alloc_group_renderer (int count)
 	  lyr->layer_type = 0;
 	  lyr->layer_name = NULL;
 	  lyr->coverage = NULL;
-	  lyr->style_name = NULL;
+	  lyr->raster_style_id = -1;
 	  lyr->raster_symbolizer = NULL;
 	  lyr->raster_stats = NULL;
       }
@@ -2034,9 +4432,10 @@ rl2_alloc_group_renderer (int count)
 
 static int
 rl2_group_renderer_set_raster (rl2PrivGroupRendererPtr group, int index,
-			       const char *layer_name, rl2CoveragePtr coverage,
-			       const char *style_name,
-			       rl2RasterStylePtr symbolizer,
+			       const char *layer_name,
+			       rl2CoveragePtr coverage,
+			       sqlite3_int64 style_id,
+			       rl2RasterSymbolizerPtr symbolizer,
 			       rl2RasterStatisticsPtr stats)
 {
 /* setting up one of the Layers within the Group */
@@ -2066,19 +4465,10 @@ rl2_group_renderer_set_raster (rl2PrivGroupRendererPtr group, int index,
     if (lyr->coverage != NULL)
 	rl2_destroy_coverage (lyr->coverage);
     lyr->coverage = (rl2CoveragePtr) coverage;
-    if (lyr->style_name != NULL)
-	free (lyr->style_name);
-    if (style_name == NULL)
-	lyr->style_name = NULL;
-    else
-      {
-	  len = strlen (style_name);
-	  lyr->style_name = malloc (len + 1);
-	  strcpy (lyr->style_name, style_name);
-      }
+    lyr->raster_style_id = style_id;
     if (lyr->raster_symbolizer != NULL)
-	rl2_destroy_raster_style ((rl2RasterStylePtr) (lyr->raster_symbolizer));
-    lyr->raster_symbolizer = (rl2PrivRasterStylePtr) symbolizer;
+	rl2_destroy_raster_symbolizer (lyr->raster_symbolizer);
+    lyr->raster_symbolizer = (rl2PrivRasterSymbolizerPtr) symbolizer;
     if (lyr->raster_stats != NULL)
 	rl2_destroy_raster_statistics ((rl2RasterStatisticsPtr)
 				       (lyr->raster_stats));
@@ -2113,7 +4503,7 @@ rl2_is_valid_group_renderer (rl2PrivGroupRendererPtr ptr, int *valid)
 		    && lyr->raster_symbolizer == NULL)
 		    error = 1;
 	    }
-	  if (lyr->style_name == NULL)
+	  if (lyr->raster_style_id <= 0)
 	      error = 1;
 	  if (lyr->raster_stats == NULL)
 	      error = 1;
@@ -2146,10 +4536,12 @@ rl2_create_group_renderer (sqlite3 * sqlite, rl2GroupStylePtr group_style)
     for (i = 0; i < count; i++)
       {
 	  /* testing individual layers/styles */
-	  rl2RasterStylePtr symbolizer = NULL;
+	  rl2CoverageStylePtr cvg_stl = NULL;
 	  rl2RasterStatisticsPtr stats = NULL;
 	  const char *layer_name = rl2_get_group_named_layer (group_style, i);
-	  const char *layer_style = rl2_get_group_named_style (group_style, i);
+	  const char *layer_style_name =
+	      rl2_get_group_named_style (group_style, i);
+	  sqlite3_int64 layer_style_id = -1;
 	  rl2CoveragePtr coverage =
 	      rl2_create_coverage_from_dbms (sqlite, layer_name);
 	  rl2PrivCoveragePtr cvg = (rl2PrivCoveragePtr) coverage;
@@ -2158,17 +4550,15 @@ rl2_create_group_renderer (sqlite3 * sqlite, rl2GroupStylePtr group_style)
 		if (valid)
 		  {
 		      /* validating the style */
-		      if (layer_style == NULL)
-			  layer_style = "default";
-		      if (strcasecmp (layer_style, "default") == 0)
-			  ;
-		      else
+		      if (layer_style_id > 0)
 			{
-			    /* attempting to get a RasterSymbolizer style */
-			    symbolizer =
-				rl2_create_raster_style_from_dbms (sqlite,
-								   layer_name,
-								   layer_style);
+			    /* attempting to get a Coverage Style */
+			    /*
+			       cvg_stl =
+			       rl2_create_coverage_style_from_dbms (sqlite,
+			       layer_name,
+			       layer_style_id);
+			     */
 			}
 		      stats =
 			  rl2_create_raster_statistics_from_dbms (sqlite,
@@ -2176,32 +4566,34 @@ rl2_create_group_renderer (sqlite3 * sqlite, rl2GroupStylePtr group_style)
 		  }
 		if ((cvg->pixelType == RL2_PIXEL_DATAGRID
 		     || cvg->pixelType == RL2_PIXEL_MULTIBAND)
-		    && symbolizer == NULL)
+		    && cvg_stl == NULL)
 		  {
 		      /* creating a default RasterStyle */
-		      rl2PrivRasterStylePtr symb =
-			  malloc (sizeof (rl2PrivRasterStyle));
-		      symbolizer = (rl2RasterStylePtr) symb;
-		      symb->name = malloc (8);
-		      strcpy (symb->name, "default");
-		      symb->title = NULL;
-		      symb->abstract = NULL;
-		      symb->opacity = 1.0;
-		      symb->contrastEnhancement = RL2_CONTRAST_ENHANCEMENT_NONE;
-		      symb->bandSelection =
-			  malloc (sizeof (rl2PrivBandSelection));
-		      symb->bandSelection->selectionType =
-			  RL2_BAND_SELECTION_MONO;
-		      symb->bandSelection->grayBand = 0;
-		      symb->bandSelection->grayContrast =
-			  RL2_CONTRAST_ENHANCEMENT_NONE;
-		      symb->categorize = NULL;
-		      symb->interpolate = NULL;
-		      symb->shadedRelief = 0;
+		      /*
+		         rl2PrivRasterSymbolizerPtr symb =
+		         malloc (sizeof (rl2PrivRasterSymbolizer));
+		         symbolizer = (rl2RasterSymbolizerPtr) symb;
+		         symb->name = malloc (8);
+		         strcpy (symb->name, "default");
+		         symb->title = NULL;
+		         symb->abstract = NULL;
+		         symb->opacity = 1.0;
+		         symb->contrastEnhancement = RL2_CONTRAST_ENHANCEMENT_NONE;
+		         symb->bandSelection =
+		         malloc (sizeof (rl2PrivBandSelection));
+		         symb->bandSelection->selectionType =
+		         RL2_BAND_SELECTION_MONO;
+		         symb->bandSelection->grayBand = 0;
+		         symb->bandSelection->grayContrast =
+		         RL2_CONTRAST_ENHANCEMENT_NONE;
+		         symb->categorize = NULL;
+		         symb->interpolate = NULL;
+		         symb->shadedRelief = 0;
+		       */
 		  }
 	    }
 	  rl2_group_renderer_set_raster (group, i, layer_name, coverage,
-					 layer_style, symbolizer, stats);
+					 layer_style_id, NULL, stats);
       }
     if (rl2_is_valid_group_renderer (group, &valid) != RL2_OK)
 	goto error;
@@ -2214,31 +4606,3 @@ rl2_create_group_renderer (sqlite3 * sqlite, rl2GroupStylePtr group_style)
 	rl2_destroy_group_renderer ((rl2GroupRendererPtr) group);
     return NULL;
 }
-
-RL2_DECLARE void
-rl2_destroy_group_renderer (rl2GroupRendererPtr group)
-{
-/* memory cleanup - destroying a GroupRenderer object */
-    int i;
-    rl2PrivGroupRendererPtr ptr = (rl2PrivGroupRendererPtr) group;
-    if (ptr == NULL)
-	return;
-    for (i = 0; i < ptr->count; i++)
-      {
-	  rl2PrivGroupRendererLayerPtr lyr = ptr->layers + i;
-	  if (lyr->layer_name != NULL)
-	      free (lyr->layer_name);
-	  if (lyr->coverage != NULL)
-	      rl2_destroy_coverage (lyr->coverage);
-	  if (lyr->style_name != NULL)
-	      free (lyr->style_name);
-	  if (lyr->raster_symbolizer != NULL)
-	      rl2_destroy_raster_style ((rl2RasterStylePtr)
-					(lyr->raster_symbolizer));
-	  if (lyr->raster_stats != NULL)
-	      rl2_destroy_raster_statistics ((rl2RasterStatisticsPtr)
-					     (lyr->raster_stats));
-      }
-    free (ptr->layers);
-    free (ptr);
-}
diff --git a/src/rl2tiff.c b/src/rl2tiff.c
index 2227a15..a9bd0f8 100644
--- a/src/rl2tiff.c
+++ b/src/rl2tiff.c
@@ -20,7 +20,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -298,33 +298,20 @@ rl2_destroy_tiff_origin (rl2TiffOriginPtr tiff)
 }
 
 static void
-origin_set_tfw_path (const char *path, rl2PrivTiffOriginPtr origin)
+origin_set_tfw_path (const char *path, const char *suffix,
+		     rl2PrivTiffOriginPtr origin)
 {
 /* building the TFW path (WorldFile) */
-    char *tfw;
-    const char *x = NULL;
-    const char *p = path;
-    int len = strlen (path);
-    len -= 1;
-    while (*p != '\0')
-      {
-	  if (*p == '.')
-	      x = p;
-	  p++;
-      }
-    if (x > path)
-	len = x - path;
-    tfw = malloc (len + 5);
-    memcpy (tfw, path, len);
-    memcpy (tfw + len, ".tfw", 4);
-    *(tfw + len + 4) = '\0';
-    origin->tfw_path = tfw;
+    if (origin->tfw_path != NULL)
+	free (origin->tfw_path);
+    origin->tfw_path = NULL;
+    origin->tfw_path = rl2_build_worldfile_path (path, suffix);
 }
 
 static int
 is_valid_float (char *str)
 {
-/* testing for a valid worlodfile float value */
+/* testing for a valid worldfile float value */
     char *p = str;
     int point = 0;
     int sign = 0;
@@ -391,10 +378,10 @@ parse_worldfile (FILE * in, double *px, double *py, double *pres_x,
     int ok_y = 0;
     char buf[1024];
     char *p = buf;
-    double x;
-    double y;
-    double res_x;
-    double res_y;
+    double x = 0.0;
+    double y = 0.0;
+    double res_x = 0.0;
+    double res_y = 0.0;
 
     if (in == NULL)
 	return 0;
@@ -467,9 +454,21 @@ worldfile_tiff_origin (const char *path, rl2PrivTiffOriginPtr origin, int srid)
     double x;
     double y;
 
-    origin_set_tfw_path (path, origin);
+    origin_set_tfw_path (path, ".tfw", origin);
     tfw = fopen (origin->tfw_path, "r");
     if (tfw == NULL)
+      {
+	  /* trying the ".tifw" suffix */
+	  origin_set_tfw_path (path, ".tifw", origin);
+	  tfw = fopen (origin->tfw_path, "r");
+      }
+    if (tfw == NULL)
+      {
+	  /* trying the ".wld" suffix */
+	  origin_set_tfw_path (path, ".wld", origin);
+	  tfw = fopen (origin->tfw_path, "r");
+      }
+    if (tfw == NULL)
 	goto error;
     if (!parse_worldfile (tfw, &x, &y, &res_x, &res_y))
 	goto error;
@@ -491,6 +490,56 @@ worldfile_tiff_origin (const char *path, rl2PrivTiffOriginPtr origin, int srid)
 }
 
 static void
+recover_incomplete_geotiff (rl2PrivTiffOriginPtr origin, TIFF * in,
+			    uint32 width, uint32 height, int force_srid)
+{
+/* final desperate attempt to recover an imcomplete GeoTIFF */
+    double *tie_points;
+    double *scale;
+    uint16 count;
+    double res_x = DBL_MAX;
+    double res_y = DBL_MAX;
+    double x = DBL_MAX;
+    double y = DBL_MAX;
+
+
+    if (force_srid <= 0)
+	return;
+
+    if (TIFFGetField (in, TIFFTAG_GEOPIXELSCALE, &count, &scale))
+      {
+	  if (count >= 2 && scale[0] != 0.0 && scale[1] != 0.0)
+	    {
+		res_x = scale[0];
+		res_y = scale[1];
+	    }
+      }
+    if (TIFFGetField (in, TIFFTAG_GEOTIEPOINTS, &count, &tie_points))
+      {
+	  int i;
+	  int max_count = count / 6;
+	  for (i = 0; i < max_count; i++)
+	    {
+		x = tie_points[i * 6 + 3];
+		y = tie_points[i * 6 + 4];
+	    }
+      }
+    if (x == DBL_MAX || y == DBL_MAX || res_x == DBL_MAX || res_y == DBL_MAX)
+	return;
+
+/* computing the pixel resolution */
+    origin->Srid = force_srid;
+    origin->minX = x;
+    origin->maxX = x + ((double) width * res_x);
+    origin->minY = y - ((double) height * res_y);
+    origin->maxY = y;
+    origin->hResolution = (origin->maxX - origin->minX) / (double) width;
+    origin->vResolution = (origin->maxY - origin->minY) / (double) height;
+    origin->isGeoReferenced = 1;
+    origin->isGeoTiff = 1;
+}
+
+static void
 geo_tiff_origin (const char *path, rl2PrivTiffOriginPtr origin, int force_srid)
 {
 /* attempting to retrieve georeferencing from a GeoTIFF origin */
@@ -501,6 +550,7 @@ geo_tiff_origin (const char *path, rl2PrivTiffOriginPtr origin, int force_srid)
     GTIFDefn definition;
     char *pString;
     int len;
+    int basic = 0;
     TIFF *in = (TIFF *) 0;
     GTIF *gtif = (GTIF *) 0;
 
@@ -516,6 +566,12 @@ geo_tiff_origin (const char *path, rl2PrivTiffOriginPtr origin, int force_srid)
     if (gtif == NULL)
 	goto error;
 
+/* retrieving the TIFF dimensions */
+    TIFFGetField (in, TIFFTAG_IMAGELENGTH, &height);
+    TIFFGetField (in, TIFFTAG_IMAGEWIDTH, &width);
+    basic = 1;
+
+
     if (!GTIFGetDefn (gtif, &definition))
 	goto error;
 /* retrieving the EPSG code */
@@ -568,10 +624,6 @@ geo_tiff_origin (const char *path, rl2PrivTiffOriginPtr origin, int force_srid)
 	  CPLFree (pString);
       }
 
-/* retrieving the TIFF dimensions */
-    TIFFGetField (in, TIFFTAG_IMAGELENGTH, &height);
-    TIFFGetField (in, TIFFTAG_IMAGEWIDTH, &width);
-
 /* computing the corners coords */
     cx = 0.0;
     cy = 0.0;
@@ -594,6 +646,8 @@ geo_tiff_origin (const char *path, rl2PrivTiffOriginPtr origin, int force_srid)
     origin->isGeoTiff = 1;
 
   error:
+    if (basic && origin->isGeoTiff == 0)
+	recover_incomplete_geotiff (origin, in, width, height, force_srid);
     if (in != (TIFF *) 0)
 	XTIFFClose (in);
     if (gtif != (GTIF *) 0)
@@ -1365,7 +1419,8 @@ init_tiff_origin (const char *path, rl2PrivTiffOriginPtr origin)
     else
 	origin->planarConfig = value16;
 
-    if (origin->bitsPerSample == 16 && origin->sampleFormat == SAMPLEFORMAT_UINT
+    if (origin->bitsPerSample == 16
+	&& origin->sampleFormat == SAMPLEFORMAT_UINT
 	&& origin->planarConfig == PLANARCONFIG_SEPARATE)
 	;
     else if (origin->bitsPerSample == 8
@@ -2037,7 +2092,7 @@ rl2_get_tiff_origin_compression (rl2TiffOriginPtr tiff,
 
 RL2_DECLARE int
 rl2_eval_tiff_origin_compatibility (rl2CoveragePtr cvg, rl2TiffOriginPtr tiff,
-				    int force_srid)
+				    int force_srid, int verbose)
 {
 /* testing if a Coverage and a TIFF origin are mutually compatible */
     unsigned char sample_type;
@@ -2067,11 +2122,23 @@ rl2_eval_tiff_origin_compatibility (rl2CoveragePtr cvg, rl2TiffOriginPtr tiff,
 	pixel_type = RL2_PIXEL_DATAGRID;
 
     if (coverage->sampleType != sample_type)
-	return RL2_FALSE;
+      {
+	  if (verbose)
+	      fprintf (stderr, "Mismatching SampleType !!!\n");
+	  return RL2_FALSE;
+      }
     if (coverage->pixelType != pixel_type)
-	return RL2_FALSE;
+      {
+	  if (verbose)
+	      fprintf (stderr, "Mismatching PixelType !!!\n");
+	  return RL2_FALSE;
+      }
     if (coverage->nBands != num_bands)
-	return RL2_FALSE;
+      {
+	  if (verbose)
+	      fprintf (stderr, "Mismatching Number of Bands !!!\n");
+	  return RL2_FALSE;
+      }
 
     if (coverage->Srid == RL2_GEOREFERENCING_NONE)
 	return RL2_TRUE;
@@ -2084,22 +2151,64 @@ rl2_eval_tiff_origin_compatibility (rl2CoveragePtr cvg, rl2TiffOriginPtr tiff,
 	  if (force_srid > 0)
 	    {
 		if (coverage->Srid != force_srid)
-		    return RL2_FALSE;
+		  {
+		      if (verbose)
+			  fprintf (stderr, "Mismatching SRID !!!\n");
+		      return RL2_FALSE;
+		  }
 	    }
 	  else
-	      return RL2_FALSE;
+	    {
+		if (verbose)
+		    fprintf (stderr, "Mismatching SRID !!!\n");
+		return RL2_FALSE;
+	    }
       }
     if (rl2_get_tiff_origin_resolution (tiff, &hResolution, &vResolution) !=
 	RL2_OK)
 	return RL2_FALSE;
-    confidence = coverage->hResolution / 100.0;
-    if (hResolution < (coverage->hResolution - confidence)
-	|| hResolution > (coverage->hResolution + confidence))
-	return RL2_FALSE;
-    confidence = coverage->vResolution / 100.0;
-    if (vResolution < (coverage->vResolution - confidence)
-	|| vResolution > (coverage->vResolution + confidence))
-	return RL2_FALSE;
+    if (coverage->mixedResolutions)
+      {
+	  /* accepting any resolution */
+      }
+    else if (coverage->strictResolution)
+      {
+	  /* enforcing Strict Resolution check */
+	  if (hResolution != coverage->hResolution)
+	    {
+		if (verbose)
+		    fprintf (stderr,
+			     "Mismatching Horizontal Resolution (Strict) !!!\n");
+		return RL2_FALSE;
+	    }
+	  if (vResolution != coverage->vResolution)
+	    {
+		if (verbose)
+		    fprintf (stderr,
+			     "Mismatching Vertical Resolution (Strict) !!!\n");
+		return RL2_FALSE;
+	    }
+      }
+    else
+      {
+	  /* permissive Resolution check */
+	  confidence = coverage->hResolution / 100.0;
+	  if (hResolution < (coverage->hResolution - confidence)
+	      || hResolution > (coverage->hResolution + confidence))
+	    {
+		if (verbose)
+		    fprintf (stderr, "Mismatching Horizontal Resolution !!!\n");
+		return RL2_FALSE;
+	    }
+	  confidence = coverage->vResolution / 100.0;
+	  if (vResolution < (coverage->vResolution - confidence)
+	      || vResolution > (coverage->vResolution + confidence))
+	    {
+		if (verbose)
+		    fprintf (stderr, "Mismatching Vertical Resolution !!!\n");
+		return RL2_FALSE;
+	    }
+      }
     return RL2_TRUE;
 }
 
@@ -2176,22 +2285,22 @@ copy_convert_tile (rl2PrivTiffOriginPtr origin, void *in, void *out,
 		   uint32 tile_x, unsigned char convert)
 {
 /* copying pixels by applying a format conversion */
-    char *p_in_8;
-    char *p_out_8;
-    unsigned char *p_in_u8;
-    unsigned char *p_out_u8;
-    short *p_in_16;
-    short *p_out_16;
-    unsigned short *p_in_u16;
-    unsigned short *p_out_u16;
-    int *p_in_32;
-    int *p_out_32;
-    unsigned int *p_in_u32;
-    unsigned int *p_out_u32;
-    float *p_in_flt;
-    float *p_out_flt;
-    double *p_in_dbl;
-    double *p_out_dbl;
+    char *p_in_8 = NULL;
+    char *p_out_8 = NULL;
+    unsigned char *p_in_u8 = NULL;
+    unsigned char *p_out_u8 = NULL;
+    short *p_in_16 = NULL;
+    short *p_out_16 = NULL;
+    unsigned short *p_in_u16 = NULL;
+    unsigned short *p_out_u16 = NULL;
+    int *p_in_32 = NULL;
+    int *p_out_32 = NULL;
+    unsigned int *p_in_u32 = NULL;
+    unsigned int *p_out_u32 = NULL;
+    float *p_in_flt = NULL;
+    float *p_out_flt = NULL;
+    double *p_in_dbl = NULL;
+    double *p_out_dbl = NULL;
     uint32 x;
     uint32 y;
     unsigned int dest_x;
@@ -2572,22 +2681,22 @@ read_raw_tiles (rl2PrivTiffOriginPtr origin, unsigned short width,
     uint32 x;
     uint32 y;
     uint32 *tiff_tile = NULL;
-    char *p_in_8;
-    char *p_out_8;
-    unsigned char *p_in_u8;
-    unsigned char *p_out_u8;
-    short *p_in_16;
-    short *p_out_16;
-    unsigned short *p_in_u16;
-    unsigned short *p_out_u16;
-    int *p_in_32;
-    int *p_out_32;
-    unsigned int *p_in_u32;
-    unsigned int *p_out_u32;
-    float *p_in_flt;
-    float *p_out_flt;
-    double *p_in_dbl;
-    double *p_out_dbl;
+    char *p_in_8 = NULL;
+    char *p_out_8 = NULL;
+    unsigned char *p_in_u8 = NULL;
+    unsigned char *p_out_u8 = NULL;
+    short *p_in_16 = NULL;
+    short *p_out_16 = NULL;
+    unsigned short *p_in_u16 = NULL;
+    unsigned short *p_out_u16 = NULL;
+    int *p_in_32 = NULL;
+    int *p_out_32 = NULL;
+    unsigned int *p_in_u32 = NULL;
+    unsigned int *p_out_u32 = NULL;
+    float *p_in_flt = NULL;
+    float *p_out_flt = NULL;
+    double *p_in_dbl = NULL;
+    double *p_out_dbl = NULL;
     unsigned int dest_x;
     unsigned int dest_y;
     int skip;
@@ -2628,8 +2737,8 @@ read_raw_tiles (rl2PrivTiffOriginPtr origin, unsigned short width,
 		      /* skipping any not required tile */
 		      continue;
 		  }
-		if (TIFFReadTile (origin->in, tiff_tile, tile_x, tile_y, 0, 0) <
-		    0)
+		if (TIFFReadTile (origin->in, tiff_tile, tile_x, tile_y, 0, 0)
+		    < 0)
 		    goto error;
 		if (convert != RL2_CONVERT_NO)
 		  {
@@ -2658,8 +2767,8 @@ read_raw_tiles (rl2PrivTiffOriginPtr origin, unsigned short width,
 				  p_in_8 += x;
 				  p_out_8 = (char *) pixels;
 				  p_out_8 +=
-				      ((dest_y - startRow) * width) + (dest_x -
-								       startCol);
+				      ((dest_y - startRow) * width) +
+				      (dest_x - startCol);
 				  break;
 			      case RL2_SAMPLE_UINT8:
 				  p_in_u8 = (unsigned char *) tiff_tile;
@@ -2677,8 +2786,8 @@ read_raw_tiles (rl2PrivTiffOriginPtr origin, unsigned short width,
 				  p_in_16 += x;
 				  p_out_16 = (short *) pixels;
 				  p_out_16 +=
-				      ((dest_y - startRow) * width) + (dest_x -
-								       startCol);
+				      ((dest_y - startRow) * width) +
+				      (dest_x - startCol);
 				  break;
 			      case RL2_SAMPLE_UINT16:
 				  p_in_u16 = (unsigned short *) tiff_tile;
@@ -2696,8 +2805,8 @@ read_raw_tiles (rl2PrivTiffOriginPtr origin, unsigned short width,
 				  p_in_32 += x;
 				  p_out_32 = (int *) pixels;
 				  p_out_32 +=
-				      ((dest_y - startRow) * width) + (dest_x -
-								       startCol);
+				      ((dest_y - startRow) * width) +
+				      (dest_x - startCol);
 				  break;
 			      case RL2_SAMPLE_UINT32:
 				  p_in_u32 = (unsigned int *) tiff_tile;
@@ -2705,8 +2814,8 @@ read_raw_tiles (rl2PrivTiffOriginPtr origin, unsigned short width,
 				  p_in_u32 += x;
 				  p_out_u32 = (unsigned int *) pixels;
 				  p_out_u32 +=
-				      ((dest_y - startRow) * width) + (dest_x -
-								       startCol);
+				      ((dest_y - startRow) * width) +
+				      (dest_x - startCol);
 				  break;
 			      case RL2_SAMPLE_FLOAT:
 				  p_in_flt = (float *) tiff_tile;
@@ -2714,8 +2823,8 @@ read_raw_tiles (rl2PrivTiffOriginPtr origin, unsigned short width,
 				  p_in_flt += x;
 				  p_out_flt = (float *) pixels;
 				  p_out_flt +=
-				      ((dest_y - startRow) * width) + (dest_x -
-								       startCol);
+				      ((dest_y - startRow) * width) +
+				      (dest_x - startCol);
 				  break;
 			      case RL2_SAMPLE_DOUBLE:
 				  p_in_dbl = (double *) tiff_tile;
@@ -2723,8 +2832,8 @@ read_raw_tiles (rl2PrivTiffOriginPtr origin, unsigned short width,
 				  p_in_dbl += x;
 				  p_out_dbl = (double *) pixels;
 				  p_out_dbl +=
-				      ((dest_y - startRow) * width) + (dest_x -
-								       startCol);
+				      ((dest_y - startRow) * width) +
+				      (dest_x - startCol);
 				  break;
 			      };
 			    for (bnd = 0; bnd < num_bands; bnd++)
@@ -2776,22 +2885,22 @@ copy_convert_scanline (rl2PrivTiffOriginPtr origin, void *in, void *out,
 		       unsigned int width, unsigned char convert)
 {
 /* copying pixels by applying a format conversion */
-    char *p_in_8;
-    char *p_out_8;
-    unsigned char *p_in_u8;
-    unsigned char *p_out_u8;
-    short *p_in_16;
-    short *p_out_16;
-    unsigned short *p_in_u16;
-    unsigned short *p_out_u16;
-    int *p_in_32;
-    int *p_out_32;
-    unsigned int *p_in_u32;
-    unsigned int *p_out_u32;
-    float *p_in_flt;
-    float *p_out_flt;
-    double *p_in_dbl;
-    double *p_out_dbl;
+    char *p_in_8 = NULL;
+    char *p_out_8 = NULL;
+    unsigned char *p_in_u8 = NULL;
+    unsigned char *p_out_u8 = NULL;
+    short *p_in_16 = NULL;
+    short *p_out_16 = NULL;
+    unsigned short *p_in_u16 = NULL;
+    unsigned short *p_out_u16 = NULL;
+    int *p_in_32 = NULL;
+    int *p_out_32 = NULL;
+    unsigned int *p_in_u32 = NULL;
+    unsigned int *p_out_u32 = NULL;
+    float *p_in_flt = NULL;
+    float *p_out_flt = NULL;
+    double *p_in_dbl = NULL;
+    double *p_out_dbl = NULL;
     uint32 x;
 
     switch (convert)
@@ -3223,22 +3332,22 @@ read_raw_scanlines (rl2PrivTiffOriginPtr origin, unsigned short width,
     uint32 x;
     uint32 y;
     uint32 *tiff_scanline = NULL;
-    char *p_in_8;
-    char *p_out_8;
-    unsigned char *p_in_u8;
-    unsigned char *p_out_u8;
-    short *p_in_16;
-    short *p_out_16;
-    unsigned short *p_in_u16;
-    unsigned short *p_out_u16;
-    int *p_in_32;
-    int *p_out_32;
-    unsigned int *p_in_u32;
-    unsigned int *p_out_u32;
-    float *p_in_flt;
-    float *p_out_flt;
-    double *p_in_dbl;
-    double *p_out_dbl;
+    char *p_in_8 = NULL;
+    char *p_out_8 = NULL;
+    unsigned char *p_in_u8 = NULL;
+    unsigned char *p_out_u8 = NULL;
+    short *p_in_16 = NULL;
+    short *p_out_16 = NULL;
+    unsigned short *p_in_u16 = NULL;
+    unsigned short *p_out_u16 = NULL;
+    int *p_in_32 = NULL;
+    int *p_out_32 = NULL;
+    unsigned int *p_in_u32 = NULL;
+    unsigned int *p_out_u32 = NULL;
+    float *p_in_flt = NULL;
+    float *p_out_flt = NULL;
+    double *p_in_dbl = NULL;
+    double *p_out_dbl = NULL;
     unsigned char bnd;
     unsigned char convert = origin->forced_conversion;
     TIFF *in = (TIFF *) 0;
@@ -3537,8 +3646,8 @@ read_raw_separate_tiles (rl2PrivTiffOriginPtr origin, unsigned short width,
 					p_out_u16 +=
 					    ((dest_y -
 					      startRow) * width * num_bands) +
-					    ((dest_x - startCol) * num_bands) +
-					    band;
+					    ((dest_x -
+					      startCol) * num_bands) + band;
 					*p_out_u16 = *p_in_u16;
 				    }
 				  if (sample_type == RL2_SAMPLE_UINT8)
@@ -3550,8 +3659,8 @@ read_raw_separate_tiles (rl2PrivTiffOriginPtr origin, unsigned short width,
 					p_out_u8 +=
 					    ((dest_y -
 					      startRow) * width * num_bands) +
-					    ((dest_x - startCol) * num_bands) +
-					    band;
+					    ((dest_x -
+					      startCol) * num_bands) + band;
 					*p_out_u8 = *p_in_u8;
 				    }
 			      }
@@ -3569,8 +3678,9 @@ read_raw_separate_tiles (rl2PrivTiffOriginPtr origin, unsigned short width,
 }
 
 static int
-read_raw_separate_scanlines (rl2PrivTiffOriginPtr origin, unsigned short width,
-			     unsigned short height, unsigned char sample_type,
+read_raw_separate_scanlines (rl2PrivTiffOriginPtr origin,
+			     unsigned short width, unsigned short height,
+			     unsigned char sample_type,
 			     unsigned char num_bands, unsigned int startRow,
 			     unsigned int startCol, void *pixels)
 {
@@ -3579,12 +3689,12 @@ read_raw_separate_scanlines (rl2PrivTiffOriginPtr origin, unsigned short width,
     uint32 x;
     uint32 y;
     uint32 *tiff_scanline = NULL;
-    unsigned char *p_in_u8;
-    unsigned char *p_out_u8;
-    unsigned char *p_out_u8_base;
-    unsigned short *p_in_u16;
-    unsigned short *p_out_u16;
-    unsigned short *p_out_u16_base;
+    unsigned char *p_in_u8 = NULL;
+    unsigned char *p_out_u8 = NULL;
+    unsigned char *p_out_u8_base = NULL;
+    unsigned short *p_in_u16 = NULL;
+    unsigned short *p_out_u16 = NULL;
+    unsigned short *p_out_u16_base = NULL;
     unsigned char band;
     TIFF *in = (TIFF *) 0;
 
@@ -4068,7 +4178,8 @@ read_from_tiff (rl2PrivTiffOriginPtr origin, unsigned short width,
 	  /* contiguous planar configuration */
 	  if (origin->bitsPerSample <= 8
 	      && origin->sampleFormat == SAMPLEFORMAT_UINT
-	      && (origin->samplesPerPixel == 1 || origin->samplesPerPixel == 3)
+	      && (origin->samplesPerPixel == 1
+		  || origin->samplesPerPixel == 3)
 	      && (pixel_type == RL2_PIXEL_MONOCHROME
 		  || pixel_type == RL2_PIXEL_PALETTE
 		  || pixel_type == RL2_PIXEL_GRAYSCALE
@@ -4098,9 +4209,9 @@ read_from_tiff (rl2PrivTiffOriginPtr origin, unsigned short width,
 					bufPixels);
 		else
 		    ret =
-			read_raw_scanlines (origin, width, height, sample_type,
-					    num_bands, startRow, startCol,
-					    bufPixels);
+			read_raw_scanlines (origin, width, height,
+					    sample_type, num_bands, startRow,
+					    startCol, bufPixels);
 		if (ret != RL2_OK)
 		    goto error;
 	    }
@@ -4181,7 +4292,7 @@ build_remap (rl2PrivTiffOriginPtr origin)
 RL2_DECLARE rl2RasterPtr
 rl2_get_tile_from_tiff_origin (rl2CoveragePtr cvg, rl2TiffOriginPtr tiff,
 			       unsigned int startRow, unsigned int startCol,
-			       int force_srid)
+			       int force_srid, int verbose)
 {
 /* attempting to create a Coverage-tile from a Tiff origin */
     unsigned int x;
@@ -4198,7 +4309,8 @@ rl2_get_tile_from_tiff_origin (rl2CoveragePtr cvg, rl2TiffOriginPtr tiff,
 
     if (coverage == NULL || tiff == NULL)
 	return NULL;
-    if (rl2_eval_tiff_origin_compatibility (cvg, tiff, force_srid) != RL2_TRUE)
+    if (rl2_eval_tiff_origin_compatibility (cvg, tiff, force_srid, verbose) !=
+	RL2_TRUE)
 	return NULL;
 
 /* testing for tile's boundary validity */
@@ -4251,7 +4363,7 @@ rl2_get_tile_from_tiff_origin (rl2CoveragePtr cvg, rl2TiffOriginPtr tiff,
 	  if (origin->remapMaxPalette > 0)
 	    {
 		palette = rl2_create_palette (origin->remapMaxPalette);
-		for (x = 0; x < origin->maxPalette; x++)
+		for (x = 0; x < origin->remapMaxPalette; x++)
 		  {
 		      rl2_set_palette_color (palette, x,
 					     origin->remapRed[x],
@@ -4277,8 +4389,8 @@ rl2_get_tile_from_tiff_origin (rl2CoveragePtr cvg, rl2TiffOriginPtr tiff,
 /* attempting to create the tile */
     if (read_from_tiff
 	(origin, coverage->tileWidth, coverage->tileHeight,
-	 coverage->sampleType, coverage->pixelType, coverage->nBands, startRow,
-	 startCol, &pixels, &pixels_sz, palette) != RL2_OK)
+	 coverage->sampleType, coverage->pixelType, coverage->nBands,
+	 startRow, startCol, &pixels, &pixels_sz, palette) != RL2_OK)
 	goto error;
     if (startCol + coverage->tileWidth > origin->width)
 	unused_width = (startCol + coverage->tileWidth) - origin->width;
@@ -4973,9 +5085,10 @@ set_tiff_destination (rl2PrivTiffDestinationPtr destination,
 RL2_DECLARE rl2TiffDestinationPtr
 rl2_create_tiff_destination (const char *path, unsigned int width,
 			     unsigned int height, unsigned char sample_type,
-			     unsigned char pixel_type, unsigned char num_bands,
-			     rl2PalettePtr plt, unsigned char tiff_compression,
-			     int tiled, unsigned int tile_size)
+			     unsigned char pixel_type,
+			     unsigned char num_bands, rl2PalettePtr plt,
+			     unsigned char tiff_compression, int tiled,
+			     unsigned int tile_size)
 {
 /* attempting to create a file-based TIFF destination (no georeferencing) */
     rl2PrivTiffDestinationPtr destination = NULL;
@@ -5655,8 +5768,8 @@ tiff_write_strip_rgb (rl2PrivTiffDestinationPtr tiff, rl2PrivRasterPtr raster,
 }
 
 static int
-tiff_write_strip_gray (rl2PrivTiffDestinationPtr tiff, rl2PrivRasterPtr raster,
-		       unsigned int row)
+tiff_write_strip_gray (rl2PrivTiffDestinationPtr tiff,
+		       rl2PrivRasterPtr raster, unsigned int row)
 {
 /* writing a TIFF Grayscale scanline */
     unsigned int x;
@@ -6058,8 +6171,9 @@ tiff_write_tile_multiband16 (rl2PrivTiffDestinationPtr tiff,
 }
 
 static int
-tiff_write_tile_rgb_u8 (rl2PrivTiffDestinationPtr tiff, rl2PrivRasterPtr raster,
-			unsigned int row, unsigned int col)
+tiff_write_tile_rgb_u8 (rl2PrivTiffDestinationPtr tiff,
+			rl2PrivRasterPtr raster, unsigned int row,
+			unsigned int col)
 {
 /* writing a TIFF RGB tile - UINT8 */
     unsigned int y;
@@ -6434,7 +6548,8 @@ rl2_write_tiff_tile (rl2TiffDestinationPtr tiff, rl2RasterPtr raster,
 	    tiff_write_tile_multiband16 (destination, rst, startRow, startCol);
     else if (destination->sampleFormat == SAMPLEFORMAT_UINT
 	     && destination->samplesPerPixel == 1
-	     && destination->photometric < 2 && destination->bitsPerSample == 8
+	     && destination->photometric < 2
+	     && destination->bitsPerSample == 8
 	     && rst->sampleType == RL2_SAMPLE_UINT8
 	     && rst->pixelType == RL2_PIXEL_GRAYSCALE && rst->nBands == 1
 	     && destination->tileWidth == rst->width
@@ -6553,7 +6668,8 @@ rl2_write_tiff_worldfile (rl2TiffDestinationPtr tiff)
     tfw = fopen (destination->tfw_path, "w");
     if (tfw == NULL)
       {
-	  fprintf (stderr, "RL2-TIFF writer: unable to open Worldfile \"%s\"\n",
+	  fprintf (stderr,
+		   "RL2-TIFF writer: unable to open Worldfile \"%s\"\n",
 		   destination->tfw_path);
 	  return RL2_ERROR;
       }
@@ -6870,8 +6986,8 @@ rl2_decode_tiff_mono4 (const unsigned char *tiff, int tiff_sz,
 }
 
 static int
-rgb_tiff_common (TIFF * out, const unsigned char *buffer, unsigned short width,
-		 unsigned short height)
+rgb_tiff_common (TIFF * out, const unsigned char *buffer,
+		 unsigned short width, unsigned short height)
 {
 /* common implementation of RGB TIFF export */
     tsize_t buf_size;
@@ -7153,8 +7269,8 @@ static int
 output_palette_tiff (const unsigned char *buffer,
 		     unsigned short width,
 		     unsigned short height, unsigned char *red,
-		     unsigned char *green, unsigned char *blue, int max_palette,
-		     unsigned char **blob, int *blob_size)
+		     unsigned char *green, unsigned char *blue,
+		     int max_palette, unsigned char **blob, int *blob_size)
 {
 /* generating a PALETTE TIFF - actual work */
     struct memfile clientdata;
@@ -7402,8 +7518,8 @@ rl2_rgb_to_geotiff (unsigned int width, unsigned int height,
 }
 
 static int
-gray_tiff_common (TIFF * out, const unsigned char *buffer, unsigned short width,
-		  unsigned short height)
+gray_tiff_common (TIFF * out, const unsigned char *buffer,
+		  unsigned short width, unsigned short height)
 {
 /* common implementation of Grayscale TIFF export */
     tsize_t buf_size;
@@ -7630,8 +7746,8 @@ rl2_raster_from_tiff (const unsigned char *blob, int blob_size)
     unsigned int y;
     unsigned int row;
     uint32 *rgba;
-    unsigned char *rgb;
-    unsigned char *mask;
+    unsigned char *rgb = NULL;
+    unsigned char *mask = NULL;
     int rgb_size;
     int mask_size;
     uint32 *p_in;
@@ -7727,3 +7843,279 @@ rl2_raster_from_tiff (const unsigned char *blob, int blob_size)
 	free (mask);
     return NULL;
 }
+
+RL2_DECLARE char *
+rl2_build_tiff_xml_summary (rl2TiffOriginPtr tiff)
+{
+/* attempting to build an XML Summary from a (geo)TIFF */
+    char *xml;
+    char *prev;
+    int len;
+    rl2PrivTiffOriginPtr org = (rl2PrivTiffOriginPtr) tiff;
+    if (org == NULL)
+	return NULL;
+
+    xml = sqlite3_mprintf ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<ImportedRaster>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    if (org->isGeoTiff)
+	xml = sqlite3_mprintf ("%s<RasterFormat>GeoTIFF</RasterFormat>", prev);
+    else if (org->isGeoReferenced)
+	xml =
+	    sqlite3_mprintf ("%s<RasterFormat>TIFF+WorldFile</RasterFormat>",
+			     prev);
+    else
+	xml = sqlite3_mprintf ("%s<RasterFormat>TIFF</RasterFormat>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<RasterWidth>%u</RasterWidth>", prev, org->width);
+    sqlite3_free (prev);
+    prev = xml;
+    xml =
+	sqlite3_mprintf ("%s<RasterHeight>%u</RasterHeight>", prev,
+			 org->height);
+    sqlite3_free (prev);
+    prev = xml;
+    if (org->isTiled)
+      {
+	  xml =
+	      sqlite3_mprintf ("%s<TileWidth>%u</TileWidth>", prev,
+			       org->tileWidth);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml =
+	      sqlite3_mprintf ("%s<TileHeight>%u</TileHeight>", prev,
+			       org->tileHeight);
+	  sqlite3_free (prev);
+	  prev = xml;
+      }
+    else
+      {
+	  xml =
+	      sqlite3_mprintf ("%s<RowsPerStrip>%u</RowsPerStrip>", prev,
+			       org->rowsPerStrip);
+	  sqlite3_free (prev);
+	  prev = xml;
+      }
+    xml =
+	sqlite3_mprintf ("%s<BitsPerSample>%u</BitsPerSample>", prev,
+			 org->bitsPerSample);
+    sqlite3_free (prev);
+    prev = xml;
+    xml =
+	sqlite3_mprintf ("%s<SamplesPerPixel>%u</SamplesPerPixel>", prev,
+			 org->samplesPerPixel);
+    sqlite3_free (prev);
+    prev = xml;
+    if (org->photometric == PHOTOMETRIC_MINISBLACK)
+	xml =
+	    sqlite3_mprintf
+	    ("%s<PhotometricInterpretation>min-is-black</PhotometricInterpretation>",
+	     prev);
+    else if (org->photometric == PHOTOMETRIC_MINISWHITE)
+	xml =
+	    sqlite3_mprintf
+	    ("%s<PhotometricInterpretation>min-is-white</PhotometricInterpretation>",
+	     prev);
+    else if (org->photometric == PHOTOMETRIC_RGB)
+	xml =
+	    sqlite3_mprintf
+	    ("%s<PhotometricInterpretation>RGB</PhotometricInterpretation>",
+	     prev);
+    else if (org->photometric == PHOTOMETRIC_PALETTE)
+	xml =
+	    sqlite3_mprintf
+	    ("%s<PhotometricInterpretation>Palette</PhotometricInterpretation>",
+	     prev);
+    else if (org->photometric == PHOTOMETRIC_MASK)
+	xml =
+	    sqlite3_mprintf
+	    ("%s<PhotometricInterpretation>Mask</PhotometricInterpretation>",
+	     prev);
+    else if (org->photometric == PHOTOMETRIC_SEPARATED)
+	xml =
+	    sqlite3_mprintf
+	    ("%s<PhotometricInterpretation>Separated (CMYC)</PhotometricInterpretation>",
+	     prev);
+    else if (org->photometric == PHOTOMETRIC_YCBCR)
+	xml =
+	    sqlite3_mprintf
+	    ("%s<PhotometricInterpretation>YCbCr</PhotometricInterpretation>",
+	     prev);
+    else if (org->photometric == PHOTOMETRIC_CIELAB)
+	xml =
+	    sqlite3_mprintf
+	    ("%s<PhotometricInterpretation>CIE L*a*b*</PhotometricInterpretation>",
+	     prev);
+    else if (org->photometric == PHOTOMETRIC_ICCLAB)
+	xml =
+	    sqlite3_mprintf
+	    ("%s<PhotometricInterpretation>alternate CIE L*a*b*</PhotometricInterpretation>",
+	     prev);
+    else if (org->photometric == PHOTOMETRIC_ITULAB)
+	xml =
+	    sqlite3_mprintf
+	    ("%s<PhotometricInterpretation>ITU L*a*b</PhotometricInterpretation>",
+	     prev);
+    else
+	xml =
+	    sqlite3_mprintf
+	    ("%s<PhotometricInterpretation>%u</PhotometricInterpretation>",
+	     prev, org->photometric);
+    sqlite3_free (prev);
+    prev = xml;
+    if (org->compression == COMPRESSION_NONE)
+	xml = sqlite3_mprintf ("%s<Compression>none</Compression>", prev);
+    else if (org->compression == COMPRESSION_CCITTRLE)
+	xml = sqlite3_mprintf ("%s<Compression>CCITT RLE</Compression>", prev);
+    else if (org->compression == COMPRESSION_CCITTFAX3)
+	xml = sqlite3_mprintf ("%s<Compression>CCITT Fax3</Compression>", prev);
+    else if (org->compression == COMPRESSION_CCITTFAX4)
+	xml = sqlite3_mprintf ("%s<Compression>CCITT Fax4</Compression>", prev);
+    else if (org->compression == COMPRESSION_LZW)
+	xml = sqlite3_mprintf ("%s<Compression>LZW</Compression>", prev);
+    else if (org->compression == COMPRESSION_OJPEG)
+	xml = sqlite3_mprintf ("%s<Compression>old JPEG</Compression>", prev);
+    else if (org->compression == COMPRESSION_JPEG)
+	xml = sqlite3_mprintf ("%s<Compression>JPEG</Compression>", prev);
+    else if (org->compression == COMPRESSION_DEFLATE)
+	xml = sqlite3_mprintf ("%s<Compression>DEFLATE</Compression>", prev);
+    else if (org->compression == COMPRESSION_ADOBE_DEFLATE)
+	xml =
+	    sqlite3_mprintf ("%s<Compression>Adobe DEFLATE</Compression>",
+			     prev);
+    else if (org->compression == COMPRESSION_JBIG)
+	xml = sqlite3_mprintf ("%s<Compression>JBIG</Compression>", prev);
+    else if (org->compression == COMPRESSION_JP2000)
+	xml = sqlite3_mprintf ("%s<Compression>JPEG 2000</Compression>", prev);
+    else
+	xml =
+	    sqlite3_mprintf ("%s<Compression>%u</Compression>", prev,
+			     org->compression);
+    sqlite3_free (prev);
+    prev = xml;
+    if (org->sampleFormat == SAMPLEFORMAT_UINT)
+	xml =
+	    sqlite3_mprintf
+	    ("%s<SampleFormat>unsigned integer</SampleFormat>", prev);
+    else if (org->sampleFormat == SAMPLEFORMAT_INT)
+	xml =
+	    sqlite3_mprintf ("%s<SampleFormat>signed integer</SampleFormat>",
+			     prev);
+    else if (org->sampleFormat == SAMPLEFORMAT_IEEEFP)
+	xml =
+	    sqlite3_mprintf ("%s<SampleFormat>floating point</SampleFormat>",
+			     prev);
+    else
+	xml =
+	    sqlite3_mprintf ("%s<SampleFormat>%u</SampleFormat>", prev,
+			     org->sampleFormat);
+    sqlite3_free (prev);
+    prev = xml;
+    if (org->sampleFormat == PLANARCONFIG_SEPARATE)
+	xml =
+	    sqlite3_mprintf
+	    ("%s<PlanarConfiguration>separate Raster planes</PlanarConfiguration>",
+	     prev);
+    else
+	xml =
+	    sqlite3_mprintf
+	    ("%s<PlanarConfiguration>single Raster plane</PlanarConfiguration>",
+	     prev);
+    sqlite3_free (prev);
+    prev = xml;
+    xml = sqlite3_mprintf ("%s<NoDataPixel>unknown</NoDataPixel>", prev);
+    sqlite3_free (prev);
+    prev = xml;
+    if (org->isGeoReferenced)
+      {
+	  xml = sqlite3_mprintf ("%s<GeoReferencing>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<SpatialReferenceSystem>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<SRID>%d</SRID>", prev, org->Srid);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  if (org->srsName != NULL)
+	      xml =
+		  sqlite3_mprintf ("%s<RefSysName>%s</RefSysName>", prev,
+				   org->srsName);
+	  else
+	      xml =
+		  sqlite3_mprintf ("%s<RefSysName>undeclared</RefSysName>",
+				   prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s</SpatialReferenceSystem>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<SpatialResolution>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml =
+	      sqlite3_mprintf
+	      ("%s<HorizontalResolution>%1.10f</HorizontalResolution>", prev,
+	       org->hResolution);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml =
+	      sqlite3_mprintf
+	      ("%s<VerticalResolution>%1.10f</VerticalResolution>", prev,
+	       org->vResolution);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s</SpatialResolution>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<BoundingBox>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<MinX>%1.10f</MinX>", prev, org->minX);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<MinY>%1.10f</MinY>", prev, org->minY);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<MaxX>%1.10f</MaxX>", prev, org->maxX);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<MaxY>%1.10f</MaxY>", prev, org->maxY);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s</BoundingBox>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s<Extent>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml =
+	      sqlite3_mprintf
+	      ("%s<HorizontalExtent>%1.10f</HorizontalExtent>", prev,
+	       org->maxX - org->minX);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml =
+	      sqlite3_mprintf ("%s<VerticalExtent>%1.10f</VerticalExtent>",
+			       prev, org->maxY - org->minY);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s</Extent>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+	  xml = sqlite3_mprintf ("%s</GeoReferencing>", prev);
+	  sqlite3_free (prev);
+	  prev = xml;
+      }
+    xml = sqlite3_mprintf ("%s</ImportedRaster>", prev);
+    sqlite3_free (prev);
+    len = strlen (xml);
+    prev = xml;
+    xml = malloc (len + 1);
+    strcpy (xml, prev);
+    sqlite3_free (prev);
+    return xml;
+}
diff --git a/src/rl2version.c b/src/rl2version.c
index fec21a6..6aa25d6 100644
--- a/src/rl2version.c
+++ b/src/rl2version.c
@@ -19,7 +19,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
diff --git a/src/rl2webp.c b/src/rl2webp.c
index f7e47b0..03f5159 100644
--- a/src/rl2webp.c
+++ b/src/rl2webp.c
@@ -20,7 +20,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -45,8 +45,6 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include <stdio.h>
 #include <string.h>
 
-#include <webp/decode.h>
-#include <webp/encode.h>
 
 #include "config.h"
 
@@ -57,6 +55,11 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include "rasterlite2/rasterlite2.h"
 #include "rasterlite2_private.h"
 
+#ifndef OMIT_WEBP		/* only if WebP is enabled */
+
+#include <webp/decode.h>
+#include <webp/encode.h>
+
 static int
 check_webp_compatibility (unsigned char sample_type, unsigned char pixel_type,
 			  unsigned char num_samples)
@@ -78,6 +81,7 @@ check_webp_compatibility (unsigned char sample_type, unsigned char pixel_type,
       case RL2_PIXEL_PALETTE:
       case RL2_PIXEL_GRAYSCALE:
       case RL2_PIXEL_RGB:
+      case RL2_PIXEL_MULTIBAND:
 	  break;
       default:
 	  return RL2_ERROR;
@@ -136,6 +140,140 @@ check_webp_compatibility (unsigned char sample_type, unsigned char pixel_type,
 	  if (num_samples != 3)
 	      return RL2_ERROR;
       }
+    if (pixel_type == RL2_PIXEL_MULTIBAND)
+      {
+	  switch (sample_type)
+	    {
+	    case RL2_SAMPLE_UINT8:
+		break;
+	    default:
+		return RL2_ERROR;
+	    };
+	  if (num_samples == 3 || num_samples == 4)
+	      ;
+	  else
+	      return RL2_ERROR;
+      }
+    return RL2_OK;
+}
+
+static void
+copy_pixels (unsigned char *out, const unsigned char *in, int width,
+	     int height, int num_bands)
+{
+/* copying pixels */
+    int x;
+    int y;
+    int ib;
+    const unsigned char *p_in = in;
+    unsigned char *p_out = out;
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		for (ib = 0; ib < num_bands; ib++)
+		    *p_out++ = *p_in++;
+	    }
+      }
+}
+
+static int
+compress_lossy_3bands_webp (rl2PrivRasterPtr rst, unsigned char **webp,
+			    int *webp_size, int quality)
+{
+/* compressing a WebP (lossy) image (MULTIBAND 3-bands) */
+    int size;
+    unsigned char *output;
+    unsigned char *buf = malloc (rst->width * rst->height * 3);
+
+    *webp = NULL;
+    *webp_size = 0;
+    copy_pixels (buf, rst->rasterBuffer, rst->width, rst->height, rst->nBands);
+    if (quality > 100)
+	quality = 100;
+    if (quality < 0)
+	quality = 75;
+    size =
+	WebPEncodeRGB (buf, rst->width, rst->height, rst->width * 3, quality,
+		       &output);
+    free (buf);
+    if (size == 0)
+	return RL2_ERROR;
+    *webp = output;
+    *webp_size = size;
+    return RL2_OK;
+}
+
+static int
+compress_lossy_4bands_webp (rl2PrivRasterPtr rst, unsigned char **webp,
+			    int *webp_size, int quality)
+{
+/* compressing a WebP (lossy) image (MULTIBAND 4-bands) */
+    int size;
+    unsigned char *output;
+    unsigned char *buf = malloc (rst->width * rst->height * 4);
+
+    *webp = NULL;
+    *webp_size = 0;
+    copy_pixels (buf, rst->rasterBuffer, rst->width, rst->height, rst->nBands);
+    if (quality > 100)
+	quality = 100;
+    if (quality < 0)
+	quality = 75;
+    size =
+	WebPEncodeRGBA (buf, rst->width, rst->height, rst->width * 4, quality,
+			&output);
+    free (buf);
+    if (size == 0)
+	return RL2_ERROR;
+    *webp = output;
+    *webp_size = size;
+    return RL2_OK;
+}
+
+static int
+compress_lossless_3bands_webp (rl2PrivRasterPtr rst, unsigned char **webp,
+			       int *webp_size)
+{
+/* compressing a WebP (lossless) image (MULTIBAND 3-bands) */
+    int size;
+    unsigned char *output;
+    unsigned char *buf = malloc (rst->width * rst->height * 3);
+
+    *webp = NULL;
+    *webp_size = 0;
+    copy_pixels (buf, rst->rasterBuffer, rst->width, rst->height, rst->nBands);
+    size =
+	WebPEncodeLosslessRGB (buf, rst->width, rst->height, rst->width * 3,
+			       &output);
+    free (buf);
+    if (size == 0)
+	return RL2_ERROR;
+    *webp = output;
+    *webp_size = size;
+    return RL2_OK;
+}
+
+static int
+compress_lossless_4bands_webp (rl2PrivRasterPtr rst, unsigned char **webp,
+			       int *webp_size)
+{
+/* compressing a WebP (lossless) image (MULTIBAND 4-bands) */
+    int size;
+    unsigned char *output;
+    unsigned char *buf = malloc (rst->width * rst->height * 4);
+
+    *webp = NULL;
+    *webp_size = 0;
+    copy_pixels (buf, rst->rasterBuffer, rst->width, rst->height, rst->nBands);
+    size =
+	WebPEncodeLosslessRGBA (buf, rst->width, rst->height, rst->width * 4,
+				&output);
+    free (buf);
+    if (size == 0)
+	return RL2_ERROR;
+    *webp = output;
+    *webp_size = size;
     return RL2_OK;
 }
 
@@ -159,8 +297,8 @@ compress_lossy_alpha_webp (rl2PrivRasterPtr rst, unsigned char **webp,
     if (quality < 0)
 	quality = 75;
     size =
-	WebPEncodeRGBA (rgba, rst->width, rst->height, rst->width * 4, quality,
-			&output);
+	WebPEncodeRGBA (rgba, rst->width, rst->height, rst->width * 4,
+			quality, &output);
     free (rgba);
     if (size == 0)
 	return RL2_ERROR;
@@ -179,6 +317,14 @@ compress_lossy_webp (rl2RasterPtr ptr, unsigned char **webp, int *webp_size,
     int rgb_size;
     unsigned char *rgb;
     rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
+    if (rst->pixelType == RL2_PIXEL_MULTIBAND)
+      {
+	  if (rst->nBands == 3)
+	      return compress_lossy_3bands_webp (rst, webp, webp_size, quality);
+	  if (rst->nBands == 4)
+	      return compress_lossy_4bands_webp (rst, webp, webp_size, quality);
+	  return RL2_ERROR;
+      }
     if (rst->maskBuffer != NULL || rst->noData != NULL)
 	return compress_lossy_alpha_webp (rst, webp, webp_size, quality);
 
@@ -237,6 +383,14 @@ compress_lossless_webp (rl2RasterPtr ptr, unsigned char **webp, int *webp_size)
     int rgb_size;
     unsigned char *rgb;
     rl2PrivRasterPtr rst = (rl2PrivRasterPtr) ptr;
+    if (rst->pixelType == RL2_PIXEL_MULTIBAND)
+      {
+	  if (rst->nBands == 3)
+	      return compress_lossless_3bands_webp (rst, webp, webp_size);
+	  if (rst->nBands == 4)
+	      return compress_lossless_4bands_webp (rst, webp, webp_size);
+	  return RL2_ERROR;
+      }
     if (rst->maskBuffer != NULL || rst->noData != NULL)
 	return compress_lossless_alpha_webp (rst, webp, webp_size);
 
@@ -306,7 +460,6 @@ rl2_raster_to_lossy_webp (rl2RasterPtr rst, unsigned char **webp,
     return RL2_OK;
 }
 
-
 RL2_DECLARE int
 rl2_section_to_lossless_webp (rl2SectionPtr scn, const char *path)
 {
@@ -485,38 +638,48 @@ rl2_decode_webp_scaled (int scale, const unsigned char *webp, int webp_size,
 	  config.output.is_external_memory = 1;
       }
 
-    if (features.has_alpha)
+    if (pixel_type == RL2_PIXEL_MULTIBAND)
       {
 	  if (WebPDecode (webp, webp_size, &config) != VP8_STATUS_OK)
 	      goto error;
-	  buf_size = width * height * 3;
-	  mask_size = width * height;
-	  mask = malloc (mask_size);
-	  if (mask == NULL)
-	      goto error;
-	  p_mask = mask;
-	  p_in = buf;
-	  p_out = buf;
-	  for (row = 0; row < height; row++)
+	  mask = NULL;
+	  mask_size = 0;
+      }
+    else
+      {
+	  if (features.has_alpha)
 	    {
-		for (col = 0; col < width; col++)
+		if (WebPDecode (webp, webp_size, &config) != VP8_STATUS_OK)
+		    goto error;
+		buf_size = width * height * 3;
+		mask_size = width * height;
+		mask = malloc (mask_size);
+		if (mask == NULL)
+		    goto error;
+		p_mask = mask;
+		p_in = buf;
+		p_out = buf;
+		for (row = 0; row < height; row++)
 		  {
-		      *p_out++ = *p_in++;
-		      *p_out++ = *p_in++;
-		      *p_out++ = *p_in++;
-		      if (*p_in++ < 128)
-			  *p_mask++ = 0;
-		      else
-			  *p_mask++ = 1;
+		      for (col = 0; col < width; col++)
+			{
+			    *p_out++ = *p_in++;
+			    *p_out++ = *p_in++;
+			    *p_out++ = *p_in++;
+			    if (*p_in++ < 128)
+				*p_mask++ = 0;
+			    else
+				*p_mask++ = 1;
+			}
 		  }
 	    }
-      }
-    else
-      {
-	  if (WebPDecode (webp, webp_size, &config) != VP8_STATUS_OK)
-	      goto error;
-	  mask = NULL;
-	  mask_size = 0;
+	  else
+	    {
+		if (WebPDecode (webp, webp_size, &config) != VP8_STATUS_OK)
+		    goto error;
+		mask = NULL;
+		mask_size = 0;
+	    }
       }
 
     if (pixel_type == RL2_PIXEL_GRAYSCALE)
@@ -557,3 +720,5 @@ rl2_decode_webp_scaled (int scale, const unsigned char *webp, int webp_size,
 	free (mask);
     return RL2_ERROR;
 }
+
+#endif /* end WebP conditional */
diff --git a/src/rl2wms.c b/src/rl2wms.c
index 5d160fc..fafa6e6 100644
--- a/src/rl2wms.c
+++ b/src/rl2wms.c
@@ -54,6 +54,7 @@ the terms of any one of the MPL, the GPL or the LGPL.
 
 #include "rasterlite2/rasterlite2.h"
 #include "rasterlite2/rl2wms.h"
+#include "rasterlite2_private.h"
 
 #define WMS_FORMAT_UNKNOWN	0
 #define WMS_FORMAT_GIF		1
@@ -278,7 +279,8 @@ typedef struct wmsFeatureAttributeStruct
 /* a struct wrapping a GML FeatureAtrribute */
     char *name;
     char *value;
-    gaiaGeomCollPtr geometry;
+    unsigned char *blob;
+    int blob_size;
     struct wmsFeatureAttributeStruct *next;
 } wmsFeatureAttribute;
 typedef wmsFeatureAttribute *wmsFeatureAttributePtr;
@@ -536,8 +538,8 @@ wmsCacheUpdate (wmsCachePtr cache)
 	  pos++;
 	  pI = pI->Next;
       }
-    qsort (cache->SortedByUrl, cache->NumCachedItems, sizeof (wmsCachedItemPtr),
-	   compare_url);
+    qsort (cache->SortedByUrl, cache->NumCachedItems,
+	   sizeof (wmsCachedItemPtr), compare_url);
 }
 
 static void
@@ -594,8 +596,8 @@ wmsAddCachedCapabilities (wmsCachePtr cache, const char *url,
 
 
 static void
-wmsAddCachedItem (wmsCachePtr cache, const char *url, const unsigned char *item,
-		  int size, const char *image_format)
+wmsAddCachedItem (wmsCachePtr cache, const char *url,
+		  const unsigned char *item, int size, const char *image_format)
 {
 /* adding a new WMS Cached Item */
     wmsCachedItemPtr ptr;
@@ -1101,8 +1103,8 @@ add_url_argument (wmsTilePatternPtr ptr, const char *pattern)
 }
 
 static void
-parse_pattern_bbox (const char *value, double *minx, double *miny, double *maxx,
-		    double *maxy)
+parse_pattern_bbox (const char *value, double *minx, double *miny,
+		    double *maxx, double *maxy)
 {
 /* parsing a BBOX arg [minx,miny,maxx,maxy] */
     int step = 0;
@@ -1462,7 +1464,8 @@ wmsAllocFeatureAttribute (const char *name, char *value)
     attr->name = malloc (len + 1);
     strcpy (attr->name, name);
     attr->value = value;
-    attr->geometry = NULL;
+    attr->blob = NULL;
+    attr->blob_size = 0;
     attr->next = NULL;
     return attr;
 }
@@ -1477,8 +1480,8 @@ wmsFreeFeatureAttribute (wmsFeatureAttributePtr attr)
 	free (attr->name);
     if (attr->value != NULL)
 	free (attr->value);
-    if (attr->geometry != NULL)
-	gaiaFreeGeomColl (attr->geometry);
+    if (attr->blob != NULL)
+	free (attr->blob);
     free (attr);
 }
 
@@ -2028,11 +2031,11 @@ clean_xml (wmsMemBuffer * in)
 	    {
 		/* masking XML special characters */
 		if (*(p_in + i) == '<')
-		    wmsMemBufferAppend (&outbuf, (const unsigned char *) "<",
-					4);
+		    wmsMemBufferAppend (&outbuf,
+					(const unsigned char *) "<", 4);
 		else if (*(p_in + i) == '>')
-		    wmsMemBufferAppend (&outbuf, (const unsigned char *) ">",
-					4);
+		    wmsMemBufferAppend (&outbuf,
+					(const unsigned char *) ">", 4);
 		else if (*(p_in + i) == '&')
 		    wmsMemBufferAppend (&outbuf,
 					(const unsigned char *) "&", 5);
@@ -2120,11 +2123,11 @@ clean_xml_str (const char *p_in)
 	    {
 		/* masking XML special characters */
 		if (*(p_in + i) == '<')
-		    wmsMemBufferAppend (&outbuf, (const unsigned char *) "<",
-					4);
+		    wmsMemBufferAppend (&outbuf,
+					(const unsigned char *) "<", 4);
 		else if (*(p_in + i) == '>')
-		    wmsMemBufferAppend (&outbuf, (const unsigned char *) ">",
-					4);
+		    wmsMemBufferAppend (&outbuf,
+					(const unsigned char *) ">", 4);
 		else if (*(p_in + i) == '&')
 		    wmsMemBufferAppend (&outbuf,
 					(const unsigned char *) "&", 5);
@@ -2706,8 +2709,8 @@ parse_wms_contact_person (xmlNodePtr node, const char **contact_person,
 				    (const char *) (child_node->content);
 			}
 		  }
-		if (strcmp ((const char *) (cur_node->name), "ContactPerson") ==
-		    0)
+		if (strcmp ((const char *) (cur_node->name), "ContactPerson")
+		    == 0)
 		  {
 		      child_node = cur_node->children;
 		      if (child_node != NULL)
@@ -2753,8 +2756,8 @@ parse_wms_contact_address (xmlNodePtr node, const char **postal_address,
 				*city = (const char *) (child_node->content);
 			}
 		  }
-		if (strcmp ((const char *) (cur_node->name), "StateOrProvince")
-		    == 0)
+		if (strcmp
+		    ((const char *) (cur_node->name), "StateOrProvince") == 0)
 		  {
 		      child_node = cur_node->children;
 		      if (child_node != NULL)
@@ -2806,8 +2809,8 @@ parse_wms_contact_information (xmlNodePtr node, const char **contact_person,
       {
 	  if (cur_node->type == XML_ELEMENT_NODE)
 	    {
-		if (strcmp ((const char *) (cur_node->name), "ContactPosition")
-		    == 0)
+		if (strcmp
+		    ((const char *) (cur_node->name), "ContactPosition") == 0)
 		  {
 		      child_node = cur_node->children;
 		      if (child_node != NULL)
@@ -2935,8 +2938,9 @@ parse_wms_service (xmlNodePtr node, wmsCapabilitiesPtr cap)
 						   &contact_organization,
 						   &contact_position,
 						   &postal_address, &city,
-						   &state_province, &post_code,
-						   &country, &voice_telephone,
+						   &state_province,
+						   &post_code, &country,
+						   &voice_telephone,
 						   &fax_telephone,
 						   &email_address);
 		if (strcmp ((const char *) (cur_node->name), "Fees") == 0)
@@ -3246,8 +3250,9 @@ parse_wms_GetTileService_HTTP_Get (xmlNodePtr node, wmsCapabilitiesPtr cap)
 					      len = strlen (p);
 					      cap->GetTileServiceURLGet =
 						  malloc (len + 1);
-					      strcpy (cap->GetTileServiceURLGet,
-						      p);
+					      strcpy
+						  (cap->GetTileServiceURLGet,
+						   p);
 					  }
 				    }
 			      }
@@ -3285,8 +3290,8 @@ parse_wms_GetTileService_HTTP_Post (xmlNodePtr node, wmsCapabilitiesPtr cap)
 					xmlNodePtr text = attr->children;
 					if (text->type == XML_TEXT_NODE)
 					  {
-					      if (cap->GetTileServiceURLPost !=
-						  NULL)
+					      if (cap->GetTileServiceURLPost
+						  != NULL)
 						{
 						    free (cap->
 							  GetTileServiceURLPost);
@@ -3350,8 +3355,9 @@ parse_wms_GetInfo_HTTP_Get (xmlNodePtr node, wmsCapabilitiesPtr cap)
 					      len = strlen (p);
 					      cap->GetFeatureInfoURLGet =
 						  malloc (len + 1);
-					      strcpy (cap->GetFeatureInfoURLGet,
-						      p);
+					      strcpy
+						  (cap->GetFeatureInfoURLGet,
+						   p);
 					  }
 				    }
 			      }
@@ -3389,8 +3395,8 @@ parse_wms_GetInfo_HTTP_Post (xmlNodePtr node, wmsCapabilitiesPtr cap)
 					xmlNodePtr text = attr->children;
 					if (text->type == XML_TEXT_NODE)
 					  {
-					      if (cap->GetFeatureInfoURLPost !=
-						  NULL)
+					      if (cap->GetFeatureInfoURLPost
+						  != NULL)
 						{
 						    free (cap->GetFeatureInfoURLPost);
 						    cap->GetFeatureInfoURLPost =
@@ -3583,8 +3589,8 @@ parse_wms_getInfo (xmlNodePtr node, wmsCapabilitiesPtr cap)
 					    ok = 1;
 					if (strcmp
 					    (format,
-					     "application/vnd.ogc.gml/3.1.1") ==
-					    0)
+					     "application/vnd.ogc.gml/3.1.1")
+					    == 0)
 					    ok = 1;
 					if (ok)
 					  {
@@ -4278,7 +4284,7 @@ parse_tile_service_info (xmlNodePtr node, wmsCapabilitiesPtr cap)
 	    {
 		int len;
 		xmlNodePtr child_node;
-		const char *value;
+		const char *value = NULL;
 		if (strcmp ((const char *) (cur_node->name), "Name") == 0)
 		  {
 		      if (cap->TileServiceName != NULL)
@@ -4378,8 +4384,8 @@ parse_tile_service (xmlNodePtr node, wmsCapabilitiesPtr cap)
 	    {
 		if (strcmp ((const char *) (cur_node->name), "Service") == 0)
 		    parse_tile_service_info (cur_node, cap);
-		if (strcmp ((const char *) (cur_node->name), "TiledPatterns") ==
-		    0)
+		if (strcmp ((const char *) (cur_node->name), "TiledPatterns")
+		    == 0)
 		    parse_tiled_patterns (cur_node, cap);
 	    }
       }
@@ -4760,8 +4766,8 @@ parse_feature_collection (xmlNodePtr node, wmsFeatureCollectionPtr coll)
       {
 	  if (cur_node->type == XML_ELEMENT_NODE)
 	    {
-		if (strcmp ((const char *) (cur_node->name), "featureMember") ==
-		    0)
+		if (strcmp ((const char *) (cur_node->name), "featureMember")
+		    == 0)
 		    parse_wms_feature_member (cur_node->children, coll);
 	    }
       }
@@ -4830,8 +4836,8 @@ parse_wms_feature_collection (const char *buf)
 }
 
 static int
-query_TileService (rl2WmsCachePtr cache_handle, wmsCapabilitiesPtr capabilities,
-		   const char *proxy)
+query_TileService (rl2WmsCachePtr cache_handle,
+		   wmsCapabilitiesPtr capabilities, const char *proxy)
 {
 /* attempting to get and parse a WMS GetTileService request */
     CURL *curl = NULL;
@@ -5942,6 +5948,8 @@ get_wms_tile_pattern_sample_url (rl2WmsTilePatternPtr handle)
 {
 /* return the sample URL for some TilePattern */
     char *url = NULL;
+    int len;
+    char *xurl;
     wmsUrlArgumentPtr arg;
     wmsTilePatternPtr ptr = (wmsTilePatternPtr) handle;
     if (ptr == NULL)
@@ -5972,7 +5980,11 @@ get_wms_tile_pattern_sample_url (rl2WmsTilePatternPtr handle)
 	    }
 	  arg = arg->next;
       }
-    return url;
+    len = strlen (url);
+    xurl = malloc (len + 1);
+    strcpy (xurl, url);
+    sqlite3_free (url);
+    return xurl;
 }
 
 RL2_DECLARE char *
@@ -6512,139 +6524,266 @@ destroy_wms_feature_collection (rl2WmsFeatureCollectionPtr handle)
 }
 
 static int
-check_swap (gaiaGeomCollPtr geom, double point_x, double point_y)
+check_swap (sqlite3 * sqlite, const unsigned char *blob, int blob_sz,
+	    double point_x, double point_y)
 {
 /* checking if X and Y axes should be flipped */
     double x;
     double y;
-    double z;
-    double m;
     double dist;
     double dist_flip;
-    gaiaPointPtr pt;
-    gaiaLinestringPtr ln;
-    gaiaPolygonPtr pg;
-    pt = geom->FirstPoint;
-    if (pt != NULL)
+
+    if (rl2_parse_point_generic (sqlite, blob, blob_sz, &x, &y) != RL2_OK)
+	return 0;
+
+    dist =
+	sqrt (((x - point_x) * (x - point_x)) +
+	      ((y - point_y) * (y - point_y)));
+    dist_flip =
+	sqrt (((x - point_y) * (x - point_y)) +
+	      ((y - point_x) * (y - point_x)));
+    if (dist_flip < dist)
+	return 1;
+    return 0;
+}
+
+static int
+reproject (sqlite3 * handle, const unsigned char *blob_in, int blob_in_sz,
+	   int srid, unsigned char **blob_out, int *blob_out_sz)
+{
+/* attempting to reproject into a different CRS */
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+    const char *sql;
+    const unsigned char *x_blob;
+    unsigned char *p_blob;
+    int p_blob_sz;
+    int count = 0;
+
+    sql = "SELECT ST_Transform(?, ?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
       {
-	  x = pt->X;
-	  y = pt->Y;
-	  goto eval;
+	  printf ("SELECT wms_reproject SQL error: %s\n",
+		  sqlite3_errmsg (handle));
+	  goto error;
       }
-    ln = geom->FirstLinestring;
-    if (ln != NULL)
+
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_blob (stmt, 1, blob_in, blob_in_sz, SQLITE_STATIC);
+    sqlite3_bind_int (stmt, 2, srid);
+    while (1)
       {
-	  if (ln->DimensionModel == GAIA_XY_Z)
-	    {
-		gaiaGetPointXYZ (ln->Coords, 0, &x, &y, &z);
-	    }
-	  else if (ln->DimensionModel == GAIA_XY_M)
-	    {
-		gaiaGetPointXYM (ln->Coords, 0, &x, &y, &m);
-	    }
-	  else if (ln->DimensionModel == GAIA_XY_Z_M)
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
 	    {
-		gaiaGetPointXYZM (ln->Coords, 0, &x, &y, &z, &m);
+		if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
+		  {
+		      x_blob = sqlite3_column_blob (stmt, 0);
+		      p_blob_sz = sqlite3_column_bytes (stmt, 0);
+		      p_blob = malloc (p_blob_sz);
+		      memcpy (p_blob, x_blob, p_blob_sz);
+		      count++;
+		  }
 	    }
 	  else
 	    {
-		gaiaGetPoint (ln->Coords, 0, &x, &y);
+		fprintf (stderr,
+			 "SELECT wms_reproject; sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (handle));
+		goto error;
 	    }
-	  goto eval;
       }
-    pg = geom->FirstPolygon;
-    if (pg != NULL)
+    sqlite3_finalize (stmt);
+    if (count != 1)
+	return RL2_ERROR;
+    *blob_out = p_blob;
+    *blob_out_sz = p_blob_sz;
+    return RL2_OK;
+
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    return RL2_ERROR;
+}
+
+static int
+parse_gml (sqlite3 * handle, const char *gml, unsigned char **blob_out,
+	   int *blob_out_sz)
+{
+/* attempring to parse a GML expression */
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+    const char *sql;
+    const unsigned char *x_blob;
+    unsigned char *p_blob;
+    int p_blob_sz;
+    int count = 0;
+
+    sql = "SELECT GeomFromGML(?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
       {
-	  gaiaRingPtr ring = pg->Exterior;
-	  if (ring->DimensionModel == GAIA_XY_Z)
-	    {
-		gaiaGetPointXYZ (ring->Coords, 0, &x, &y, &z);
-	    }
-	  else if (ring->DimensionModel == GAIA_XY_M)
-	    {
-		gaiaGetPointXYM (ring->Coords, 0, &x, &y, &m);
-	    }
-	  else if (ring->DimensionModel == GAIA_XY_Z_M)
+	  printf ("SELECT wms_parse_gml SQL error: %s\n",
+		  sqlite3_errmsg (handle));
+	  goto error;
+      }
+
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, gml, strlen (gml), SQLITE_STATIC);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
 	    {
-		gaiaGetPointXYZM (ring->Coords, 0, &x, &y, &z, &m);
+		if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
+		  {
+		      x_blob = sqlite3_column_blob (stmt, 0);
+		      p_blob_sz = sqlite3_column_bytes (stmt, 0);
+		      p_blob = malloc (p_blob_sz);
+		      memcpy (p_blob, x_blob, p_blob_sz);
+		      count++;
+		  }
 	    }
 	  else
 	    {
-		gaiaGetPoint (ring->Coords, 0, &x, &y);
+		fprintf (stderr,
+			 "SELECT wms_parse_gml; sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (handle));
+		goto error;
 	    }
-	  goto eval;
       }
-    return 0;
-  eval:
-    dist =
-	sqrt (((x - point_x) * (x - point_x)) +
-	      ((y - point_y) * (y - point_y)));
-    dist_flip =
-	sqrt (((x - point_y) * (x - point_y)) +
-	      ((y - point_x) * (y - point_x)));
-    if (dist_flip < dist)
-	return 1;
-    return 0;
+    sqlite3_finalize (stmt);
+    if (count != 1)
+	return RL2_ERROR;
+    *blob_out = p_blob;
+    *blob_out_sz = p_blob_sz;
+    return RL2_OK;
+
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    return RL2_ERROR;
 }
 
-static void
-getProjParams (void *p_sqlite, int srid, char **proj_params)
-{
-/* retrieves the PROJ params from SPATIAL_SYS_REF table, if possible */
-    sqlite3 *sqlite = (sqlite3 *) p_sqlite;
-    char *sql;
-    char **results;
-    int rows;
-    int columns;
-    int i;
+RL2_PRIVATE int
+get_srid_from_blob (sqlite3 * handle, const unsigned char *blob, int blob_sz)
+{
+/* attempts to retrieve the SRID from a Geometry */
     int ret;
-    int len;
-    const char *proj4text;
-    char *errMsg = NULL;
-    *proj_params = NULL;
-    sql = sqlite3_mprintf
-	("SELECT proj4text FROM spatial_ref_sys WHERE srid = %d", srid);
-    ret = sqlite3_get_table (sqlite, sql, &results, &rows, &columns, &errMsg);
-    sqlite3_free (sql);
+    sqlite3_stmt *stmt = NULL;
+    const char *sql;
+    int srid = -1;
+
+    sql = "SELECT ST_Srid(?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "unknown SRID: %d\t<%s>\n", srid, errMsg);
-	  sqlite3_free (errMsg);
-	  return;
+	  printf ("SELECT wms_srid_from_blob SQL error: %s\n",
+		  sqlite3_errmsg (handle));
+	  goto error;
       }
-    for (i = 1; i <= rows; i++)
+
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_blob (stmt, 1, blob, blob_sz, SQLITE_STATIC);
+    while (1)
       {
-	  proj4text = results[(i * columns)];
-	  if (proj4text != NULL)
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	      srid = sqlite3_column_int (stmt, 0);
+	  else
 	    {
-		len = strlen (proj4text);
-		*proj_params = malloc (len + 1);
-		strcpy (*proj_params, proj4text);
+		fprintf (stderr,
+			 "SELECT wms_srid_from_blob; sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (handle));
+		goto error;
 	    }
       }
-    if (*proj_params == NULL)
-	fprintf (stderr, "unknown SRID: %d\n", srid);
-    sqlite3_free_table (results);
+    sqlite3_finalize (stmt);
+    return srid;
+
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    return srid;
 }
 
-static gaiaGeomCollPtr
-reproject (gaiaGeomCollPtr geom, int srid, sqlite3 * sqlite)
+static void
+swap_coords (sqlite3 * handle, const unsigned char *blob_in, int blob_in_sz,
+	     unsigned char **blob_out, int *blob_out_sz)
 {
-/* attempting to reproject into a different CRS */
-    char *proj_from;
-    char *proj_to;
-    gaiaGeomCollPtr g2 = NULL;
-    getProjParams (sqlite, geom->Srid, &proj_from);
-    getProjParams (sqlite, srid, &proj_to);
-    if (proj_to == NULL || proj_from == NULL)
-	;
+/* attempting to swap the X,Y coordinates */
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+    const char *sql;
+    const unsigned char *x_blob;
+    unsigned char *p_blob;
+    int p_blob_sz;
+    int count = 0;
+
+    sql = "SELECT SwaoCoords(?)";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  printf ("SELECT wms_swap_coords SQL error: %s\n",
+		  sqlite3_errmsg (handle));
+	  goto error;
+      }
+
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_blob (stmt, 1, blob_in, blob_in_sz, SQLITE_STATIC);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	    {
+		if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
+		  {
+		      x_blob = sqlite3_column_blob (stmt, 0);
+		      p_blob_sz = sqlite3_column_bytes (stmt, 0);
+		      p_blob = malloc (p_blob_sz);
+		      memcpy (p_blob, x_blob, p_blob_sz);
+		      count++;
+		  }
+	    }
+	  else
+	    {
+		fprintf (stderr,
+			 "SELECT wms_swap_coords; sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (handle));
+		goto error;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    if (count != 1)
+      {
+	  *blob_out = NULL;
+	  *blob_out_sz = 0;
+      }
     else
-	g2 = gaiaTransform (geom, proj_from, proj_to);
-    if (proj_from)
-	free (proj_from);
-    if (proj_to)
-	free (proj_to);
-    return g2;
+      {
+	  *blob_out = p_blob;
+	  *blob_out_sz = p_blob_sz;
+      }
+    return;
+
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    *blob_out = NULL;
+    *blob_out_sz = 0;
 }
 
 RL2_DECLARE void
@@ -6670,40 +6809,58 @@ wms_feature_collection_parse_geometries (rl2WmsFeatureCollectionPtr
 		if (attr->value != NULL)
 		  {
 		      /* attempting to parse a possible GML Geometry */
-		      gaiaGeomCollPtr geom =
-			  gaiaParseGml ((const unsigned char *) (attr->value),
-					sqlite);
-		      if (geom != NULL)
+		      unsigned char *blob;
+		      int blob_sz;
+		      if (parse_gml (sqlite, attr->value, &blob, &blob_sz) ==
+			  RL2_OK)
 			{
-			    if (geom->Srid > 0 && srid > 0
-				&& geom->Srid != srid)
+			    unsigned char *blob_out;
+			    int blob_out_sz;
+			    int srid2 =
+				get_srid_from_blob (sqlite, blob, blob_sz);
+			    if (srid2 > 0 && srid > 0 && srid2 != srid)
 			      {
 				  /* attempting to reproject into the Map CRS */
-				  gaiaGeomCollPtr g2 =
-				      reproject (geom, srid, sqlite);
-				  if (g2 != NULL)
+				  if (reproject
+				      (sqlite, blob, blob_sz, srid, &blob_out,
+				       &blob_out_sz) == RL2_OK)
 				    {
-					if (check_swap (g2, point_x, point_y))
+					free (blob);
+					if (check_swap
+					    (sqlite, blob_out, blob_out_sz,
+					     point_x, point_y))
 					  {
-					      gaiaFreeGeomColl (g2);
-					      gaiaSwapCoords (geom);
-					      g2 = reproject (geom, srid,
-							      sqlite);
-					      attr->geometry = g2;
-					      gaiaFreeGeomColl (geom);
+					      swap_coords (sqlite, blob_out,
+							   blob_out_sz, &blob,
+							   &blob_sz);
+					      attr->blob = blob;
+					      attr->blob_size = blob_sz;
+					      free (blob_out);
 					  }
 					else
 					  {
-					      attr->geometry = g2;
-					      gaiaFreeGeomColl (geom);
+					      attr->blob = blob_out;
+					      attr->blob_size = blob_out_sz;
+					      free (blob);
 					  }
 				    }
 			      }
 			    else
 			      {
-				  if (check_swap (geom, point_x, point_y))
-				      gaiaSwapCoords (geom);
-				  attr->geometry = geom;
+				  if (check_swap
+				      (sqlite, blob, blob_sz, point_x, point_y))
+				    {
+					swap_coords (sqlite, blob, blob_sz,
+						     &blob_out, &blob_out_sz);
+					attr->blob = blob_out;
+					attr->blob_size = blob_out_sz;
+					free (blob);
+				    }
+				  else
+				    {
+					attr->blob = blob;
+					attr->blob_size = blob_sz;
+				    }
 			      }
 			}
 		  }
@@ -6793,25 +6950,34 @@ get_wms_feature_attribute_name (rl2WmsFeatureMemberPtr handle, int index)
     return NULL;
 }
 
-RL2_DECLARE gaiaGeomCollPtr
-get_wms_feature_attribute_geometry (rl2WmsFeatureMemberPtr handle, int index)
+RL2_DECLARE int
+get_wms_feature_attribute_blob_geometry (rl2WmsFeatureMemberPtr handle,
+					 int index,
+					 const unsigned char **blob,
+					 int *blob_size)
 {
 /* attempting to get the Nth FeatureAttribute (Geometry) from some WMS-FeatureMember object */
     int count = 0;
     wmsFeatureAttributePtr attr;
     wmsFeatureMemberPtr ptr = (wmsFeatureMemberPtr) handle;
     if (ptr == NULL)
-	return NULL;
+	return RL2_ERROR;
 
     attr = ptr->first;
     while (attr != NULL)
       {
 	  if (count == index)
-	      return attr->geometry;
+	    {
+		if (attr->blob == NULL || attr->blob_size == 0)
+		    return RL2_ERROR;
+		*blob = attr->blob;
+		*blob_size = attr->blob_size;
+		return RL2_OK;
+	    }
 	  count++;
 	  attr = attr->next;
       }
-    return NULL;
+    return RL2_ERROR;
 }
 
 RL2_DECLARE const char *
@@ -6905,18 +7071,18 @@ do_wms_GetMap_get (rl2WmsCachePtr cache_handle, const char *url,
 				   "&LAYERS=%s&%s=%s&BBOX=%1.6f,%1.6f,%1.6f,%1.6f"
 				   "&WIDTH=%d&HEIGHT=%d&STYLES=%s&FORMAT=%s"
 				   "&TRANSPARENT=%s&BGCOLOR=0xFFFFFF", url,
-				   version, layer, crs_prefix, crs, miny, minx,
-				   maxy, maxx, width, height, style, format,
-				   (opaque == 0) ? "TRUE" : "FALSE");
+				   version, layer, crs_prefix, crs, miny,
+				   minx, maxy, maxx, width, height, style,
+				   format, (opaque == 0) ? "TRUE" : "FALSE");
 	  else
 	      request =
 		  sqlite3_mprintf ("%s?SERVICE=WMS&REQUEST=GetMap&VERSION=%s"
 				   "&LAYERS=%s&%s=%s&BBOX=%1.6f,%1.6f,%1.6f,%1.6f"
 				   "&WIDTH=%d&HEIGHT=%d&STYLES=%s&FORMAT=%s"
 				   "&TRANSPARENT=%s&BGCOLOR=0xFFFFFF", url,
-				   version, layer, crs_prefix, crs, minx, miny,
-				   maxx, maxy, width, height, style, format,
-				   (opaque == 0) ? "TRUE" : "FALSE");
+				   version, layer, crs_prefix, crs, minx,
+				   miny, maxx, maxy, width, height, style,
+				   format, (opaque == 0) ? "TRUE" : "FALSE");
       }
     else
       {
@@ -6927,18 +7093,18 @@ do_wms_GetMap_get (rl2WmsCachePtr cache_handle, const char *url,
 				   "&LAYERS=%s&%s=%s&BBOX=%1.6f,%1.6f,%1.6f,%1.6f"
 				   "&WIDTH=%d&HEIGHT=%d&STYLES=%s&FORMAT=%s"
 				   "&TRANSPARENT=%s&BGCOLOR=0xFFFFFF", url,
-				   version, layer, crs_prefix, crs, miny, minx,
-				   maxy, maxx, width, height, style, format,
-				   (opaque == 0) ? "TRUE" : "FALSE");
+				   version, layer, crs_prefix, crs, miny,
+				   minx, maxy, maxx, width, height, style,
+				   format, (opaque == 0) ? "TRUE" : "FALSE");
 	  else
 	      request =
 		  sqlite3_mprintf ("%sSERVICE=WMS&REQUEST=GetMap&VERSION=%s"
 				   "&LAYERS=%s&%s=%s&BBOX=%1.6f,%1.6f,%1.6f,%1.6f"
 				   "&WIDTH=%d&HEIGHT=%d&STYLES=%s&FORMAT=%s"
 				   "&TRANSPARENT=%s&BGCOLOR=0xFFFFFF", url,
-				   version, layer, crs_prefix, crs, minx, miny,
-				   maxx, maxy, width, height, style, format,
-				   (opaque == 0) ? "TRUE" : "FALSE");
+				   version, layer, crs_prefix, crs, minx,
+				   miny, maxx, maxy, width, height, style,
+				   format, (opaque == 0) ? "TRUE" : "FALSE");
       }
 
     if (cache != NULL)
@@ -6959,7 +7125,7 @@ do_wms_GetMap_get (rl2WmsCachePtr cache_handle, const char *url,
 		if (cachedItem->ImageFormat == WMS_FORMAT_PNG)
 		    raster =
 			rl2_raster_from_png (cachedItem->Item,
-					     cachedItem->Size);
+					     cachedItem->Size, 1);
 		if (cachedItem->ImageFormat == WMS_FORMAT_JPEG)
 		    raster =
 			rl2_raster_from_jpeg (cachedItem->Item,
@@ -7060,7 +7226,7 @@ do_wms_GetMap_get (rl2WmsCachePtr cache_handle, const char *url,
 		  rl2_raster_from_gif (bodyBuf.Buffer, bodyBuf.WriteOffset);
 	  if (strcmp (image_format, "image/png") == 0)
 	      raster =
-		  rl2_raster_from_png (bodyBuf.Buffer, bodyBuf.WriteOffset);
+		  rl2_raster_from_png (bodyBuf.Buffer, bodyBuf.WriteOffset, 1);
 	  if (strcmp (image_format, "image/jpeg") == 0)
 	      raster =
 		  rl2_raster_from_jpeg (bodyBuf.Buffer, bodyBuf.WriteOffset);
@@ -7113,11 +7279,11 @@ do_wms_GetMap_post (rl2WmsCachePtr cache_handle, const char *url,
 /* attempting to execute a WMS GepMap request [method POST] */
 
 /* not yet implemented: just a stupid placeholder always returning NULL */
-    if (cache_handle == NULL || url == NULL || proxy == NULL || version == NULL
-	|| layer == NULL || crs == NULL)
+    if (cache_handle == NULL || url == NULL || proxy == NULL
+	|| version == NULL || layer == NULL || crs == NULL)
 	return NULL;
-    if (minx == miny || maxx == maxy || width == height || opaque == from_cache
-	|| width == swap_xy)
+    if (minx == miny || maxx == maxy || width == height
+	|| opaque == from_cache || width == swap_xy)
 	return NULL;
     if (style == NULL || format == NULL || err_msg == NULL)
 	return NULL;
@@ -7167,7 +7333,7 @@ do_wms_GetMap_TileService_get (rl2WmsCachePtr cache_handle, const char *url,
 		if (cachedItem->ImageFormat == WMS_FORMAT_PNG)
 		    raster =
 			rl2_raster_from_png (cachedItem->Item,
-					     cachedItem->Size);
+					     cachedItem->Size, 1);
 		if (cachedItem->ImageFormat == WMS_FORMAT_JPEG)
 		    raster =
 			rl2_raster_from_jpeg (cachedItem->Item,
@@ -7265,7 +7431,7 @@ do_wms_GetMap_TileService_get (rl2WmsCachePtr cache_handle, const char *url,
 		  rl2_raster_from_gif (bodyBuf.Buffer, bodyBuf.WriteOffset);
 	  if (strcmp (image_format, "image/png") == 0)
 	      raster =
-		  rl2_raster_from_png (bodyBuf.Buffer, bodyBuf.WriteOffset);
+		  rl2_raster_from_png (bodyBuf.Buffer, bodyBuf.WriteOffset, 1);
 	  if (strcmp (image_format, "image/jpeg") == 0)
 	      raster =
 		  rl2_raster_from_jpeg (bodyBuf.Buffer, bodyBuf.WriteOffset);
@@ -7371,18 +7537,18 @@ do_wms_GetFeatureInfo_get (const char *url, const char *proxy,
 		  ("%s?SERVICE=WMS&REQUEST=GetFeatureInfo&VERSION=%s&LAYERS=%s"
 		   "&QUERY_LAYERS=%s&%s=%s&BBOX=%1.6f,%1.6f,%1.6f,%1.6f"
 		   "&WIDTH=%d&HEIGHT=%d&X=%d&Y=%d&INFO_FORMAT=%s"
-		   "&FEATURE_COUNT=50", url, version, layer, layer, crs_prefix,
-		   crs, miny, minx, maxy, maxx, width, height, mouse_x,
-		   mouse_y, format);
+		   "&FEATURE_COUNT=50", url, version, layer, layer,
+		   crs_prefix, crs, miny, minx, maxy, maxx, width, height,
+		   mouse_x, mouse_y, format);
 	  else
 	      request =
 		  sqlite3_mprintf
 		  ("%s?SERVICE=WMS&REQUEST=GetFeatureInfo&VERSION=%s&LAYERS=%s"
 		   "&QUERY_LAYERS=%s&%s=%s&BBOX=%1.6f,%1.6f,%1.6f,%1.6f"
 		   "&WIDTH=%d&HEIGHT=%d&X=%d&Y=%d&INFO_FORMAT=%s"
-		   "&FEATURE_COUNT=50", url, version, layer, layer, crs_prefix,
-		   crs, minx, miny, maxx, maxy, width, height, mouse_x,
-		   mouse_y, format);
+		   "&FEATURE_COUNT=50", url, version, layer, layer,
+		   crs_prefix, crs, minx, miny, maxx, maxy, width, height,
+		   mouse_x, mouse_y, format);
       }
     else
       {
@@ -7392,18 +7558,18 @@ do_wms_GetFeatureInfo_get (const char *url, const char *proxy,
 		  ("%sSERVICE=WMS&REQUEST=GetFeatureInfo&VERSION=%s&LAYERS=%s"
 		   "&QUERY_LAYERS=%s&%s=%s&BBOX=%1.6f,%1.6f,%1.6f,%1.6f"
 		   "&WIDTH=%d&HEIGHT=%d&X=%d&Y=%d&INFO_FORMAT=%s"
-		   "&FEATURE_COUNT=50", url, version, layer, layer, crs_prefix,
-		   crs, miny, minx, maxy, maxx, width, height, mouse_x,
-		   mouse_y, format);
+		   "&FEATURE_COUNT=50", url, version, layer, layer,
+		   crs_prefix, crs, miny, minx, maxy, maxx, width, height,
+		   mouse_x, mouse_y, format);
 	  else
 	      request =
 		  sqlite3_mprintf
 		  ("%sSERVICE=WMS&REQUEST=GetFeatureInfo&VERSION=%s&LAYERS=%s"
 		   "&QUERY_LAYERS=%s&%s=%s&BBOX=%1.6f,%1.6f,%1.6f,%1.6f"
 		   "&WIDTH=%d&HEIGHT=%d&X=%d&Y=%d&INFO_FORMAT=%s"
-		   "&FEATURE_COUNT=50", url, version, layer, layer, crs_prefix,
-		   crs, minx, miny, maxx, maxy, width, height, mouse_x,
-		   mouse_y, format);
+		   "&FEATURE_COUNT=50", url, version, layer, layer,
+		   crs_prefix, crs, minx, miny, maxx, maxy, width, height,
+		   mouse_x, mouse_y, format);
       }
 
     curl = curl_easy_init ();
@@ -7541,9 +7707,9 @@ RL2_DECLARE rl2WmsFeatureCollectionPtr
 do_wms_GetFeatureInfo_post (const char *url, const char *proxy,
 			    const char *version, const char *format,
 			    const char *layer, const char *crs, int swap_xy,
-			    double minx, double miny, double maxx, double maxy,
-			    int width, int height, int mouse_x, int mouse_y,
-			    char **err_msg)
+			    double minx, double miny, double maxx,
+			    double maxy, int width, int height, int mouse_x,
+			    int mouse_y, char **err_msg)
 {
 /* attempting to execute a WMS GepFeatureInfo request [method POST] */
 
diff --git a/test/Cevennes2.jp2 b/test/Cevennes2.jp2
new file mode 100644
index 0000000..b615bc9
Binary files /dev/null and b/test/Cevennes2.jp2 differ
diff --git a/test/Karla-BoldItalic.ttf b/test/Karla-BoldItalic.ttf
new file mode 100644
index 0000000..1e3d92c
Binary files /dev/null and b/test/Karla-BoldItalic.ttf differ
diff --git a/test/Makefile.am b/test/Makefile.am
index 216ae98..ca48040 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -18,12 +18,16 @@ check_PROGRAMS = test_coverage test_palette \
 	test_map_noref test_map_trento \
 	test_map_trieste test_map_infrared \
 	test_map_orbetello test_raster_symbolizer \
-	test_svg
+	test_svg test_raw test_openjpeg \
+	test_line_symbolizer test_polygon_symbolizer \
+	test_point_symbolizer test_text_symbolizer \
+	test_vectors test_font test_copy_rastercov
 
 AM_CPPFLAGS = -I at srcdir@/../headers @LIBXML2_CFLAGS@
 AM_LDFLAGS = -L../src -lrasterlite2 @LIBCAIRO_LIBS@ @LIBPNG_LIBS@ \
 	@LIBWEBP_LIBS@ @LIBLZMA_LIBS@ @LIBSPATIALITE_LIBS@ \
-	@LIBCURL_LIBS@ @LIBXML2_LIBS@ $(GCOV_FLAGS)
+	@LIBCURL_LIBS@ @LIBXML2_LIBS@  @LIBFREETYPE2_LIBS@ \
+	$(GCOV_FLAGS)
 
 TESTS = $(check_PROGRAMS)
 
@@ -87,10 +91,11 @@ EXTRA_DIST = jpeg1.jpg jpeg2.jpg png1.png mask1.png \
 	ir_false_color2.xml ir_false_color1_gamma.xml \
 	ir_false_color2_gamma.xml rgb_histogram.xml \
 	rgb_normalize.xml gray_gamma.xml gray_histogram.xml \
-	gray_normalize.xml rgb_normalize2.xml \
+	gray_normalize.xml rgb_normalize2.xml ndvi.xml \
 	rgb_histogram2.xml rgb_gamma.xml gray_normalize2.xml \
 	gray_histogram2.xml gray_gamma2.xml group_style_1.xml \
-	group_style_2.xml bicycle.svg car_repair.svg \
+	coverage_style.xml group_style_2.xml \
+	symbolizers.sqlite bicycle.svg car_repair.svg \
 	Car_Yellow.svg Circle_and_quadratic_bezier.svg \
 	Coat_of_arms_Holy_See.svg doctors.svg fastfood.svg \
 	Flag_of_the_United_Kingdom.svg Flag_of_the_United_States.svg \
@@ -100,7 +105,7 @@ EXTRA_DIST = jpeg1.jpg jpeg2.jpg png1.png mask1.png \
 	Roundel_of_the_Royal_Canadian_Air_Force_(1946-1965).svg \
 	Roundel_of_the_Syrian_Air_Force.svg \
 	Royal_Coat_of_Arms_of_the_United_Kingdom.svg \
-	supermarket.svg tobacco.svg
+	supermarket.svg tobacco.svg Cevennes2.jp2 Karla-BoldItalic.ttf
 
 SUBDIRS = sql_stmt_security_tests sql_stmt_tests 
 
diff --git a/test/Makefile.in b/test/Makefile.in
index cdb3113..cae749f 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# Makefile.in generated by automake 1.15 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,7 +14,17 @@
 
 @SET_MAKE@
 VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -98,10 +108,12 @@ check_PROGRAMS = test_coverage$(EXEEXT) test_palette$(EXEEXT) \
 	test_map_noref$(EXEEXT) test_map_trento$(EXEEXT) \
 	test_map_trieste$(EXEEXT) test_map_infrared$(EXEEXT) \
 	test_map_orbetello$(EXEEXT) test_raster_symbolizer$(EXEEXT) \
-	test_svg$(EXEEXT)
+	test_svg$(EXEEXT) test_raw$(EXEEXT) test_openjpeg$(EXEEXT) \
+	test_line_symbolizer$(EXEEXT) test_polygon_symbolizer$(EXEEXT) \
+	test_point_symbolizer$(EXEEXT) test_text_symbolizer$(EXEEXT) \
+	test_vectors$(EXEEXT) test_font$(EXEEXT) \
+	test_copy_rastercov$(EXEEXT)
 subdir = test
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
-	$(top_srcdir)/depcomp $(top_srcdir)/test-driver
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
@@ -109,6 +121,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -180,12 +193,21 @@ test8_LDADD = $(LDADD)
 test9_SOURCES = test9.c
 test9_OBJECTS = test9.$(OBJEXT)
 test9_LDADD = $(LDADD)
+test_copy_rastercov_SOURCES = test_copy_rastercov.c
+test_copy_rastercov_OBJECTS = test_copy_rastercov.$(OBJEXT)
+test_copy_rastercov_LDADD = $(LDADD)
 test_coverage_SOURCES = test_coverage.c
 test_coverage_OBJECTS = test_coverage.$(OBJEXT)
 test_coverage_LDADD = $(LDADD)
+test_font_SOURCES = test_font.c
+test_font_OBJECTS = test_font.$(OBJEXT)
+test_font_LDADD = $(LDADD)
 test_gif_SOURCES = test_gif.c
 test_gif_OBJECTS = test_gif.$(OBJEXT)
 test_gif_LDADD = $(LDADD)
+test_line_symbolizer_SOURCES = test_line_symbolizer.c
+test_line_symbolizer_OBJECTS = test_line_symbolizer.$(OBJEXT)
+test_line_symbolizer_LDADD = $(LDADD)
 test_load_wms_SOURCES = test_load_wms.c
 test_load_wms_OBJECTS = test_load_wms.$(OBJEXT)
 test_load_wms_LDADD = $(LDADD)
@@ -246,27 +268,45 @@ test_map_trieste_LDADD = $(LDADD)
 test_mask_SOURCES = test_mask.c
 test_mask_OBJECTS = test_mask.$(OBJEXT)
 test_mask_LDADD = $(LDADD)
+test_openjpeg_SOURCES = test_openjpeg.c
+test_openjpeg_OBJECTS = test_openjpeg.$(OBJEXT)
+test_openjpeg_LDADD = $(LDADD)
 test_paint_SOURCES = test_paint.c
 test_paint_OBJECTS = test_paint.$(OBJEXT)
 test_paint_LDADD = $(LDADD)
 test_palette_SOURCES = test_palette.c
 test_palette_OBJECTS = test_palette.$(OBJEXT)
 test_palette_LDADD = $(LDADD)
+test_point_symbolizer_SOURCES = test_point_symbolizer.c
+test_point_symbolizer_OBJECTS = test_point_symbolizer.$(OBJEXT)
+test_point_symbolizer_LDADD = $(LDADD)
+test_polygon_symbolizer_SOURCES = test_polygon_symbolizer.c
+test_polygon_symbolizer_OBJECTS = test_polygon_symbolizer.$(OBJEXT)
+test_polygon_symbolizer_LDADD = $(LDADD)
 test_raster_SOURCES = test_raster.c
 test_raster_OBJECTS = test_raster.$(OBJEXT)
 test_raster_LDADD = $(LDADD)
 test_raster_symbolizer_SOURCES = test_raster_symbolizer.c
 test_raster_symbolizer_OBJECTS = test_raster_symbolizer.$(OBJEXT)
 test_raster_symbolizer_LDADD = $(LDADD)
+test_raw_SOURCES = test_raw.c
+test_raw_OBJECTS = test_raw.$(OBJEXT)
+test_raw_LDADD = $(LDADD)
 test_section_SOURCES = test_section.c
 test_section_OBJECTS = test_section.$(OBJEXT)
 test_section_LDADD = $(LDADD)
 test_svg_SOURCES = test_svg.c
 test_svg_OBJECTS = test_svg.$(OBJEXT)
 test_svg_LDADD = $(LDADD)
+test_text_symbolizer_SOURCES = test_text_symbolizer.c
+test_text_symbolizer_OBJECTS = test_text_symbolizer.$(OBJEXT)
+test_text_symbolizer_LDADD = $(LDADD)
 test_tifin_SOURCES = test_tifin.c
 test_tifin_OBJECTS = test_tifin.$(OBJEXT)
 test_tifin_LDADD = $(LDADD)
+test_vectors_SOURCES = test_vectors.c
+test_vectors_OBJECTS = test_vectors.$(OBJEXT)
+test_vectors_LDADD = $(LDADD)
 test_webp_SOURCES = test_webp.c
 test_webp_OBJECTS = test_webp.$(OBJEXT)
 test_webp_LDADD = $(LDADD)
@@ -316,30 +356,36 @@ am__v_CCLD_1 =
 SOURCES = check_sql_stmt.c test1.c test10.c test11.c test12.c test13.c \
 	test14.c test15.c test16.c test17.c test18.c test19.c test2.c \
 	test20.c test3.c test4.c test5.c test6.c test7.c test8.c \
-	test9.c test_coverage.c test_gif.c test_load_wms.c \
+	test9.c test_copy_rastercov.c test_coverage.c test_font.c \
+	test_gif.c test_line_symbolizer.c test_load_wms.c \
 	test_map_ascii.c test_map_gray.c test_map_indiana.c \
 	test_map_infrared.c test_map_mono.c test_map_nile_32.c \
 	test_map_nile_8.c test_map_nile_dbl.c test_map_nile_flt.c \
 	test_map_nile_u16.c test_map_nile_u32.c test_map_nile_u8.c \
 	test_map_noref.c test_map_orbetello.c test_map_rgb.c \
 	test_map_srtm.c test_map_trento.c test_map_trieste.c \
-	test_mask.c test_paint.c test_palette.c test_raster.c \
-	test_raster_symbolizer.c test_section.c test_svg.c \
-	test_tifin.c test_webp.c test_wms1.c test_wms2.c \
+	test_mask.c test_openjpeg.c test_paint.c test_palette.c \
+	test_point_symbolizer.c test_polygon_symbolizer.c \
+	test_raster.c test_raster_symbolizer.c test_raw.c \
+	test_section.c test_svg.c test_text_symbolizer.c test_tifin.c \
+	test_vectors.c test_webp.c test_wms1.c test_wms2.c \
 	test_wr_tiff.c
 DIST_SOURCES = check_sql_stmt.c test1.c test10.c test11.c test12.c \
 	test13.c test14.c test15.c test16.c test17.c test18.c test19.c \
 	test2.c test20.c test3.c test4.c test5.c test6.c test7.c \
-	test8.c test9.c test_coverage.c test_gif.c test_load_wms.c \
+	test8.c test9.c test_copy_rastercov.c test_coverage.c \
+	test_font.c test_gif.c test_line_symbolizer.c test_load_wms.c \
 	test_map_ascii.c test_map_gray.c test_map_indiana.c \
 	test_map_infrared.c test_map_mono.c test_map_nile_32.c \
 	test_map_nile_8.c test_map_nile_dbl.c test_map_nile_flt.c \
 	test_map_nile_u16.c test_map_nile_u32.c test_map_nile_u8.c \
 	test_map_noref.c test_map_orbetello.c test_map_rgb.c \
 	test_map_srtm.c test_map_trento.c test_map_trieste.c \
-	test_mask.c test_paint.c test_palette.c test_raster.c \
-	test_raster_symbolizer.c test_section.c test_svg.c \
-	test_tifin.c test_webp.c test_wms1.c test_wms2.c \
+	test_mask.c test_openjpeg.c test_paint.c test_palette.c \
+	test_point_symbolizer.c test_polygon_symbolizer.c \
+	test_raster.c test_raster_symbolizer.c test_raw.c \
+	test_section.c test_svg.c test_text_symbolizer.c test_tifin.c \
+	test_vectors.c test_webp.c test_wms1.c test_wms2.c \
 	test_wr_tiff.c
 RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
 	ctags-recursive dvi-recursive html-recursive info-recursive \
@@ -585,6 +631,8 @@ TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
 TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
 	$(TEST_LOG_FLAGS)
 DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \
+	$(top_srcdir)/test-driver
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 am__relativize = \
   dir0=`pwd`; \
@@ -641,6 +689,8 @@ ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
+FREETYPE2_CFLAGS = @FREETYPE2_CFLAGS@
+FREETYPE2_LIBS = @FREETYPE2_LIBS@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
@@ -653,6 +703,8 @@ LIBCAIRO_CFLAGS = @LIBCAIRO_CFLAGS@
 LIBCAIRO_LIBS = @LIBCAIRO_LIBS@
 LIBCURL_CFLAGS = @LIBCURL_CFLAGS@
 LIBCURL_LIBS = @LIBCURL_LIBS@
+LIBFREETYPE2_CFLAGS = @LIBFREETYPE2_CFLAGS@
+LIBFREETYPE2_LIBS = @LIBFREETYPE2_LIBS@
 LIBLZMA_CFLAGS = @LIBLZMA_CFLAGS@
 LIBLZMA_LIBS = @LIBLZMA_LIBS@
 LIBOBJS = @LIBOBJS@
@@ -752,7 +804,8 @@ top_srcdir = @top_srcdir@
 AM_CPPFLAGS = -I at srcdir@/../headers @LIBXML2_CFLAGS@
 AM_LDFLAGS = -L../src -lrasterlite2 @LIBCAIRO_LIBS@ @LIBPNG_LIBS@ \
 	@LIBWEBP_LIBS@ @LIBLZMA_LIBS@ @LIBSPATIALITE_LIBS@ \
-	@LIBCURL_LIBS@ @LIBXML2_LIBS@ $(GCOV_FLAGS)
+	@LIBCURL_LIBS@ @LIBXML2_LIBS@  @LIBFREETYPE2_LIBS@ \
+	$(GCOV_FLAGS)
 
 TESTS = $(check_PROGRAMS)
 MOSTLYCLEANFILES = *.gcna *.gcno *.gcda
@@ -814,10 +867,11 @@ EXTRA_DIST = jpeg1.jpg jpeg2.jpg png1.png mask1.png \
 	ir_false_color2.xml ir_false_color1_gamma.xml \
 	ir_false_color2_gamma.xml rgb_histogram.xml \
 	rgb_normalize.xml gray_gamma.xml gray_histogram.xml \
-	gray_normalize.xml rgb_normalize2.xml \
+	gray_normalize.xml rgb_normalize2.xml ndvi.xml \
 	rgb_histogram2.xml rgb_gamma.xml gray_normalize2.xml \
 	gray_histogram2.xml gray_gamma2.xml group_style_1.xml \
-	group_style_2.xml bicycle.svg car_repair.svg \
+	coverage_style.xml group_style_2.xml \
+	symbolizers.sqlite bicycle.svg car_repair.svg \
 	Car_Yellow.svg Circle_and_quadratic_bezier.svg \
 	Coat_of_arms_Holy_See.svg doctors.svg fastfood.svg \
 	Flag_of_the_United_Kingdom.svg Flag_of_the_United_States.svg \
@@ -827,7 +881,7 @@ EXTRA_DIST = jpeg1.jpg jpeg2.jpg png1.png mask1.png \
 	Roundel_of_the_Royal_Canadian_Air_Force_(1946-1965).svg \
 	Roundel_of_the_Syrian_Air_Force.svg \
 	Royal_Coat_of_Arms_of_the_United_Kingdom.svg \
-	supermarket.svg tobacco.svg
+	supermarket.svg tobacco.svg Cevennes2.jp2 Karla-BoldItalic.ttf
 
 SUBDIRS = sql_stmt_security_tests sql_stmt_tests 
 all: all-recursive
@@ -846,7 +900,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__confi
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu test/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu test/Makefile
-.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -958,14 +1011,26 @@ test9$(EXEEXT): $(test9_OBJECTS) $(test9_DEPENDENCIES) $(EXTRA_test9_DEPENDENCIE
 	@rm -f test9$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(test9_OBJECTS) $(test9_LDADD) $(LIBS)
 
+test_copy_rastercov$(EXEEXT): $(test_copy_rastercov_OBJECTS) $(test_copy_rastercov_DEPENDENCIES) $(EXTRA_test_copy_rastercov_DEPENDENCIES) 
+	@rm -f test_copy_rastercov$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_copy_rastercov_OBJECTS) $(test_copy_rastercov_LDADD) $(LIBS)
+
 test_coverage$(EXEEXT): $(test_coverage_OBJECTS) $(test_coverage_DEPENDENCIES) $(EXTRA_test_coverage_DEPENDENCIES) 
 	@rm -f test_coverage$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(test_coverage_OBJECTS) $(test_coverage_LDADD) $(LIBS)
 
+test_font$(EXEEXT): $(test_font_OBJECTS) $(test_font_DEPENDENCIES) $(EXTRA_test_font_DEPENDENCIES) 
+	@rm -f test_font$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_font_OBJECTS) $(test_font_LDADD) $(LIBS)
+
 test_gif$(EXEEXT): $(test_gif_OBJECTS) $(test_gif_DEPENDENCIES) $(EXTRA_test_gif_DEPENDENCIES) 
 	@rm -f test_gif$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(test_gif_OBJECTS) $(test_gif_LDADD) $(LIBS)
 
+test_line_symbolizer$(EXEEXT): $(test_line_symbolizer_OBJECTS) $(test_line_symbolizer_DEPENDENCIES) $(EXTRA_test_line_symbolizer_DEPENDENCIES) 
+	@rm -f test_line_symbolizer$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_line_symbolizer_OBJECTS) $(test_line_symbolizer_LDADD) $(LIBS)
+
 test_load_wms$(EXEEXT): $(test_load_wms_OBJECTS) $(test_load_wms_DEPENDENCIES) $(EXTRA_test_load_wms_DEPENDENCIES) 
 	@rm -f test_load_wms$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(test_load_wms_OBJECTS) $(test_load_wms_LDADD) $(LIBS)
@@ -1046,6 +1111,10 @@ test_mask$(EXEEXT): $(test_mask_OBJECTS) $(test_mask_DEPENDENCIES) $(EXTRA_test_
 	@rm -f test_mask$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(test_mask_OBJECTS) $(test_mask_LDADD) $(LIBS)
 
+test_openjpeg$(EXEEXT): $(test_openjpeg_OBJECTS) $(test_openjpeg_DEPENDENCIES) $(EXTRA_test_openjpeg_DEPENDENCIES) 
+	@rm -f test_openjpeg$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_openjpeg_OBJECTS) $(test_openjpeg_LDADD) $(LIBS)
+
 test_paint$(EXEEXT): $(test_paint_OBJECTS) $(test_paint_DEPENDENCIES) $(EXTRA_test_paint_DEPENDENCIES) 
 	@rm -f test_paint$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(test_paint_OBJECTS) $(test_paint_LDADD) $(LIBS)
@@ -1054,6 +1123,14 @@ test_palette$(EXEEXT): $(test_palette_OBJECTS) $(test_palette_DEPENDENCIES) $(EX
 	@rm -f test_palette$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(test_palette_OBJECTS) $(test_palette_LDADD) $(LIBS)
 
+test_point_symbolizer$(EXEEXT): $(test_point_symbolizer_OBJECTS) $(test_point_symbolizer_DEPENDENCIES) $(EXTRA_test_point_symbolizer_DEPENDENCIES) 
+	@rm -f test_point_symbolizer$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_point_symbolizer_OBJECTS) $(test_point_symbolizer_LDADD) $(LIBS)
+
+test_polygon_symbolizer$(EXEEXT): $(test_polygon_symbolizer_OBJECTS) $(test_polygon_symbolizer_DEPENDENCIES) $(EXTRA_test_polygon_symbolizer_DEPENDENCIES) 
+	@rm -f test_polygon_symbolizer$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_polygon_symbolizer_OBJECTS) $(test_polygon_symbolizer_LDADD) $(LIBS)
+
 test_raster$(EXEEXT): $(test_raster_OBJECTS) $(test_raster_DEPENDENCIES) $(EXTRA_test_raster_DEPENDENCIES) 
 	@rm -f test_raster$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(test_raster_OBJECTS) $(test_raster_LDADD) $(LIBS)
@@ -1062,6 +1139,10 @@ test_raster_symbolizer$(EXEEXT): $(test_raster_symbolizer_OBJECTS) $(test_raster
 	@rm -f test_raster_symbolizer$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(test_raster_symbolizer_OBJECTS) $(test_raster_symbolizer_LDADD) $(LIBS)
 
+test_raw$(EXEEXT): $(test_raw_OBJECTS) $(test_raw_DEPENDENCIES) $(EXTRA_test_raw_DEPENDENCIES) 
+	@rm -f test_raw$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_raw_OBJECTS) $(test_raw_LDADD) $(LIBS)
+
 test_section$(EXEEXT): $(test_section_OBJECTS) $(test_section_DEPENDENCIES) $(EXTRA_test_section_DEPENDENCIES) 
 	@rm -f test_section$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(test_section_OBJECTS) $(test_section_LDADD) $(LIBS)
@@ -1070,10 +1151,18 @@ test_svg$(EXEEXT): $(test_svg_OBJECTS) $(test_svg_DEPENDENCIES) $(EXTRA_test_svg
 	@rm -f test_svg$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(test_svg_OBJECTS) $(test_svg_LDADD) $(LIBS)
 
+test_text_symbolizer$(EXEEXT): $(test_text_symbolizer_OBJECTS) $(test_text_symbolizer_DEPENDENCIES) $(EXTRA_test_text_symbolizer_DEPENDENCIES) 
+	@rm -f test_text_symbolizer$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_text_symbolizer_OBJECTS) $(test_text_symbolizer_LDADD) $(LIBS)
+
 test_tifin$(EXEEXT): $(test_tifin_OBJECTS) $(test_tifin_DEPENDENCIES) $(EXTRA_test_tifin_DEPENDENCIES) 
 	@rm -f test_tifin$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(test_tifin_OBJECTS) $(test_tifin_LDADD) $(LIBS)
 
+test_vectors$(EXEEXT): $(test_vectors_OBJECTS) $(test_vectors_DEPENDENCIES) $(EXTRA_test_vectors_DEPENDENCIES) 
+	@rm -f test_vectors$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_vectors_OBJECTS) $(test_vectors_LDADD) $(LIBS)
+
 test_webp$(EXEEXT): $(test_webp_OBJECTS) $(test_webp_DEPENDENCIES) $(EXTRA_test_webp_DEPENDENCIES) 
 	@rm -f test_webp$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(test_webp_OBJECTS) $(test_webp_LDADD) $(LIBS)
@@ -1117,8 +1206,11 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test7.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test8.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test9.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_copy_rastercov.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_coverage.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_font.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_gif.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_line_symbolizer.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_load_wms.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_map_ascii.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_map_gray.Po at am__quote@
@@ -1139,13 +1231,19 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_map_trento.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_map_trieste.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_mask.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_openjpeg.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_paint.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_palette.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_point_symbolizer.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_polygon_symbolizer.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_raster.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_raster_symbolizer.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_raw.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_section.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_svg.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_text_symbolizer.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_tifin.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_vectors.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_webp.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_wms1.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_wms2.Po at am__quote@
@@ -1156,14 +1254,14 @@ distclean-compile:
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c $<
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ $<
 
 .c.obj:
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
 
 .c.lo:
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -1307,7 +1405,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS)
 	if test -n "$$am__remaking_logs"; then \
 	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
 	       "recursion detected" >&2; \
-	else \
+	elif test -n "$$redo_logs"; then \
 	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
 	fi; \
 	if $(am__make_dryrun); then :; else \
@@ -1796,6 +1894,69 @@ test_svg.log: test_svg$(EXEEXT)
 	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_raw.log: test_raw$(EXEEXT)
+	@p='test_raw$(EXEEXT)'; \
+	b='test_raw'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_openjpeg.log: test_openjpeg$(EXEEXT)
+	@p='test_openjpeg$(EXEEXT)'; \
+	b='test_openjpeg'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_line_symbolizer.log: test_line_symbolizer$(EXEEXT)
+	@p='test_line_symbolizer$(EXEEXT)'; \
+	b='test_line_symbolizer'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_polygon_symbolizer.log: test_polygon_symbolizer$(EXEEXT)
+	@p='test_polygon_symbolizer$(EXEEXT)'; \
+	b='test_polygon_symbolizer'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_point_symbolizer.log: test_point_symbolizer$(EXEEXT)
+	@p='test_point_symbolizer$(EXEEXT)'; \
+	b='test_point_symbolizer'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_text_symbolizer.log: test_text_symbolizer$(EXEEXT)
+	@p='test_text_symbolizer$(EXEEXT)'; \
+	b='test_text_symbolizer'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_vectors.log: test_vectors$(EXEEXT)
+	@p='test_vectors$(EXEEXT)'; \
+	b='test_vectors'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_font.log: test_font$(EXEEXT)
+	@p='test_font$(EXEEXT)'; \
+	b='test_font'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_copy_rastercov.log: test_copy_rastercov$(EXEEXT)
+	@p='test_copy_rastercov$(EXEEXT)'; \
+	b='test_copy_rastercov'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
 .test.log:
 	@p='$<'; \
 	$(am__set_b); \
@@ -1995,6 +2156,8 @@ uninstall-am:
 	mostlyclean-libtool pdf pdf-am ps ps-am recheck tags tags-am \
 	uninstall uninstall-am
 
+.PRECIOUS: Makefile
+
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/test/check_sql_stmt.c b/test/check_sql_stmt.c
index 4df231a..f8ecf60 100644
--- a/test/check_sql_stmt.c
+++ b/test/check_sql_stmt.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -79,7 +79,8 @@ struct db_conn
     sqlite3 *db_handle;
     char *db_path;
     int read_only;
-    const void *cache;
+    void *cache;
+    void *priv_data;
 };
 
 static void
@@ -255,7 +256,8 @@ do_one_case (struct db_conn *conn, const struct test_data *data,
       {
 	  if (conn->cache != NULL)
 	      spatialite_init_ex (db_handle, conn->cache, 0);
-	  rl2_init (db_handle, 0);
+	  if (conn->priv_data != NULL)
+	      rl2_init (db_handle, conn->priv_data, 0);
       }
     save_connection (conn, data->database_name, db_handle, read_only, empty_db);
 
@@ -582,11 +584,13 @@ main (int argc, char *argv[])
 {
     int result = 0;
     void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
     char *old_SPATIALITE_SECURITY_ENV = NULL;
     struct db_conn conn;
     conn.db_path = NULL;
     conn.db_handle = NULL;
     conn.cache = cache;
+    conn.priv_data = priv_data;
 
     old_SPATIALITE_SECURITY_ENV = getenv ("SPATIALITE_SECURITY");
 #ifdef _WIN32
@@ -615,6 +619,9 @@ main (int argc, char *argv[])
     close_connection (&conn);
     spatialite_cleanup_ex (conn.cache);
     conn.cache = NULL;
+    rl2_cleanup_private (conn.priv_data);
+    priv_data = rl2_alloc_private ();
+    conn.priv_data = priv_data;
 
     if (result == 0)
       {
@@ -648,6 +655,7 @@ main (int argc, char *argv[])
 	  close_connection (&conn);
       }
 
+    rl2_cleanup_private (conn.priv_data);
     spatialite_shutdown ();
     if (old_SPATIALITE_SECURITY_ENV)
       {
diff --git a/test/coverage_style.xml b/test/coverage_style.xml
new file mode 100644
index 0000000..befecb2
--- /dev/null
+++ b/test/coverage_style.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CoverageStyle version="1.1.0" xsi:schemaLocation="http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/FeatureStyle.xsd" xmlns="http://www.opengis.net/se" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+	<Name>coverage_style</Name>
+	<Description>
+		<Title>coverage title</Title>
+		<Abstract>coverage abstract</Abstract>
+	</Description>
+	<Rule>
+		<MaxScaleDenominator>1000000</MaxScaleDenominator>
+		<RasterSymbolizer>
+			<Name>coverage_ir_normalize</Name>
+			<Description>
+				<Title>False Color InfraRed - Normalize</Title>
+			</Description>
+			<Opacity>1.0</Opacity>
+			<ChannelSelection>
+				<RedChannel>
+					<SourceChannelName>4</SourceChannelName>
+				</RedChannel>
+				<GreenChannel>
+					<SourceChannelName>3</SourceChannelName>
+				</GreenChannel>
+				<BlueChannel>
+					<SourceChannelName>2</SourceChannelName>
+				</BlueChannel>
+			</ChannelSelection>
+			<ContrastEnhancement>
+				<Normalize/>
+			</ContrastEnhancement>
+		</RasterSymbolizer>
+	</Rule>
+	<Rule>
+		<Name> rule name</Name>
+		<Description>
+			<Title>rule title</Title>
+			<Abstract>rule abstract</Abstract>
+		</Description>
+		<MinScaleDenominator>1000000</MinScaleDenominator>
+		<MaxScaleDenominator>10000000</MaxScaleDenominator>
+		<RasterSymbolizer>
+			<Name>coverage_ir_normalize</Name>
+			<Description>
+				<Title>False Color InfraRed - Normalize</Title>
+				<Abstract>a styled 16-bit multi-band raster. False Colors: Infrared, Red, Green bands. Contrast Enhancement: Normalize method</Abstract>
+			</Description>
+			<Opacity>0.5</Opacity>
+			<ChannelSelection>
+				<RedChannel>
+					<SourceChannelName>4</SourceChannelName>
+				</RedChannel>
+				<GreenChannel>
+					<SourceChannelName>2</SourceChannelName>
+				</GreenChannel>
+				<BlueChannel>
+					<SourceChannelName>1</SourceChannelName>
+				</BlueChannel>
+			</ChannelSelection>
+			<ContrastEnhancement>
+				<Normalize/>
+			</ContrastEnhancement>
+		</RasterSymbolizer>
+	</Rule>
+	<Rule>
+		<MinScaleDenominator>10000000</MinScaleDenominator>
+		<RasterSymbolizer>
+			<Opacity>0.5</Opacity>
+			<ChannelSelection>
+				<RedChannel>
+					<SourceChannelName>3</SourceChannelName>
+				</RedChannel>
+				<GreenChannel>
+					<SourceChannelName>2</SourceChannelName>
+				</GreenChannel>
+				<BlueChannel>
+					<SourceChannelName>1</SourceChannelName>
+				</BlueChannel>
+			</ChannelSelection>
+			<ContrastEnhancement>
+				<Normalize/>
+			</ContrastEnhancement>
+		</RasterSymbolizer>
+	</Rule>
+</CoverageStyle>
diff --git a/test/ndvi.xml b/test/ndvi.xml
new file mode 100644
index 0000000..436adc5
--- /dev/null
+++ b/test/ndvi.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<RasterSymbolizer version="1.1.0" xsi:schemaLocation="http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/Symbolizer.xsd" xmlns="http://www.opengis.net/se" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+	<Name>ndvi</Name>
+	<Description>
+		<Title>NDVI Color Map (Normalized Difference Vegetation Index)</Title>
+		<Abstract>derived from the original "ndvi" color rule (GRASS GIS)</Abstract>
+	</Description>
+	<Opacity>1.0</Opacity>
+	<ColorMap>
+		<Interpolate fallbackValue="#ffffff">
+			<LookupValue>Rasterdata</LookupValue>
+			<InterpolationPoint>
+				<Data>-1.00000000</Data>
+				<Value>#051852</Value>
+			</InterpolationPoint>
+			<InterpolationPoint>
+				<Data>-0.30000000</Data>
+				<Value>#051852</Value>
+			</InterpolationPoint>
+			<InterpolationPoint>
+				<Data>-0.18000000</Data>
+				<Value>#ffffff</Value>
+			</InterpolationPoint>
+			<InterpolationPoint>
+				<Data>0.00000000</Data>
+				<Value>#ffffff</Value>
+			</InterpolationPoint>
+			<InterpolationPoint>
+				<Data>0.02500000</Data>
+				<Value>#cec5b4</Value>
+			</InterpolationPoint>
+			<InterpolationPoint>
+				<Data>0.07500000</Data>
+				<Value>#bfa37c</Value>
+			</InterpolationPoint>
+			<InterpolationPoint>
+				<Data>0.12500000</Data>
+				<Value>#b3ae60</Value>
+			</InterpolationPoint>
+			<InterpolationPoint>
+				<Data>0.15000000</Data>
+				<Value>#a3b550</Value>
+			</InterpolationPoint>
+			<InterpolationPoint>
+				<Data>0.17500000</Data>
+				<Value>#90aa3c</Value>
+			</InterpolationPoint>
+			<InterpolationPoint>
+				<Data>0.23300000</Data>
+				<Value>#a6c31d</Value>
+			</InterpolationPoint>
+			<InterpolationPoint>
+				<Data>0.26600000</Data>
+				<Value>#87b703</Value>
+			</InterpolationPoint>
+			<InterpolationPoint>
+				<Data>0.33300000</Data>
+				<Value>#79af01</Value>
+			</InterpolationPoint>
+			<InterpolationPoint>
+				<Data>0.36600000</Data>
+				<Value>#65a300</Value>
+			</InterpolationPoint>
+			<InterpolationPoint>
+				<Data>0.43300000</Data>
+				<Value>#4e9700</Value>
+			</InterpolationPoint>
+			<InterpolationPoint>
+				<Data>0.46600000</Data>
+				<Value>#2b8404</Value>
+			</InterpolationPoint>
+			<InterpolationPoint>
+				<Data>0.55000000</Data>
+				<Value>#007200</Value>
+			</InterpolationPoint>
+			<InterpolationPoint>
+				<Data>0.65000000</Data>
+				<Value>#005a01</Value>
+			</InterpolationPoint>
+			<InterpolationPoint>
+				<Data>0.75000000</Data>
+				<Value>#004900</Value>
+			</InterpolationPoint>
+			<InterpolationPoint>
+				<Data>0.85000000</Data>
+				<Value>#003800</Value>
+			</InterpolationPoint>
+			<InterpolationPoint>
+				<Data>0.95000000</Data>
+				<Value>#001f00</Value>
+			</InterpolationPoint>
+			<InterpolationPoint>
+				<Data>1.00000000</Data>
+				<Value>#000000</Value>
+			</InterpolationPoint>
+		</Interpolate>
+	</ColorMap>
+</RasterSymbolizer>
diff --git a/test/raster_symbolizer_4.xml b/test/raster_symbolizer_4.xml
index e2ebd18..8921aed 100644
--- a/test/raster_symbolizer_4.xml
+++ b/test/raster_symbolizer_4.xml
@@ -1,11 +1,16 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <CoverageStyle version="1.1.0" xsi:schemaLocation="http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/FeatureStyle.xsd" xmlns="http://www.opengis.net/se" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-	<Name>style1</Name>
+	<Name>style4</Name>
 	<Description>
 		<Title>Coverage Style Title</Title>
 	</Description>
 	<Rule>
+		<Name>some rule</Name>
 		<RasterSymbolizer>
+			<Name>style</Name>
+			<Description>
+				<Title>Title</Title>
+			</Description>
 			<Opacity>1.0</Opacity>
 			<OverlapBehavior>AVERAGE</OverlapBehavior>
 			<ColorMap>
@@ -50,10 +55,10 @@
 					<Value>#ffffff</Value>
 					<Threshold>13000</Threshold>
 					<Value>#ffffff</Value>
-			</Categorize>
+				</Categorize>
 			</ColorMap>
 			<ShadedRelief>
-				<BrightnessOnly>0</BrightnessOnly>
+			<BrightnessOnly>0</BrightnessOnly>
 				<ReliefFactor>33.5</ReliefFactor>
 			</ShadedRelief>
 		</RasterSymbolizer>
diff --git a/test/raster_symbolizer_5.xml b/test/raster_symbolizer_5.xml
index f4b5364..3992add 100644
--- a/test/raster_symbolizer_5.xml
+++ b/test/raster_symbolizer_5.xml
@@ -1,18 +1,12 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <CoverageStyle version="1.1.0" xsi:schemaLocation="http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/FeatureStyle.xsd" xmlns="http://www.opengis.net/se" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-	<Name>style2</Name>
+	<Name>style5</Name>
 	<Description>
 		<Title>Coverage Style Title</Title>
 		<Abstract>Coverage Style Abstract</Abstract>
 	</Description>
 	<Rule>
-		<Name>ChannelSelection</Name>
-		<Description>
-			<Title>RGB channel mapping</Title>
-			<Abstract>Abstract: RGB channel mapping</Abstract>
-		</Description>
 		<RasterSymbolizer>
-			<Name>style2</Name>
 			<Opacity>0.8</Opacity>
 			<ChannelSelection>
 				<RedChannel>
diff --git a/test/raster_symbolizer_6.xml b/test/raster_symbolizer_6.xml
index a8ae8ab..2806a62 100644
--- a/test/raster_symbolizer_6.xml
+++ b/test/raster_symbolizer_6.xml
@@ -1,11 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <CoverageStyle version="1.1.0" xsi:schemaLocation="http://www.opengis.net/se http://schemas.opengis.net/se/1.1.0/FeatureStyle.xsd" xmlns="http://www.opengis.net/se" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-	<Name>style3</Name>
+	<Name>style6</Name>
 	<Rule>
-		<Name>ChannelSelection</Name>
-		<Description>
-			<Title>Gray channel mapping</Title>
-		</Description>
 		<RasterSymbolizer>
 			<ChannelSelection>
 				<GrayChannel>
diff --git a/test/sql_stmt_security_tests/Makefile.am b/test/sql_stmt_security_tests/Makefile.am
index 804a448..99a965b 100644
--- a/test/sql_stmt_security_tests/Makefile.am
+++ b/test/sql_stmt_security_tests/Makefile.am
@@ -1,5 +1,19 @@
 
-EXTRA_DIST = loadraster1.testcase \
+EXTRA_DIST = exportfont1.testcase \
+	exportfont2.testcase \
+	exportfont3.testcase \
+	exportfont4.testcase \
+	exportfont9.testcase \
+	exportfont10.testcase \
+	exportfont11.testcase \
+	exportfont12.testcase \
+	exportfont13.testcase \
+	loadfont1.testcase \
+	loadfont2.testcase \
+	loadfont3.testcase \
+	loadfont4.testcase \
+	loadfont5.testcase \
+	loadraster1.testcase \
 	loadraster2.testcase \
 	loadraster3.testcase \
 	loadraster4.testcase \
@@ -87,6 +101,62 @@ EXTRA_DIST = loadraster1.testcase \
 	writeascii16.testcase \
 	writeascii17.testcase \
 	writeascii18.testcase \
+	writesectionascii1.testcase \
+	writesectionascii2.testcase \
+	writesectionascii3.testcase \
+	writesectionascii4.testcase \
+	writesectionascii5.testcase \
+	writesectionascii6.testcase \
+	writesectionascii7.testcase \
+	writesectionascii9.testcase \
+	writesectionascii10.testcase \
+	writesectionascii11.testcase \
+	writesectionascii12.testcase \
+	writesectionascii13.testcase \
+	writesectionascii14.testcase \
+	writesectionascii15.testcase \
+	writesectionascii16.testcase \
+	writesectionascii17.testcase \
+	writesectionascii18.testcase \
+	writesectionascii18.testcase \
+	writendviascii1.testcase \
+	writendviascii2.testcase \
+	writendviascii3.testcase \
+	writendviascii4.testcase \
+	writendviascii5.testcase \
+	writendviascii6.testcase \
+	writendviascii7.testcase \
+	writendviascii8.testcase \
+	writendviascii9.testcase \
+	writendviascii10.testcase \
+	writendviascii11.testcase \
+	writendviascii12.testcase \
+	writendviascii13.testcase \
+	writendviascii14.testcase \
+	writendviascii15.testcase \
+	writendviascii16.testcase \
+	writendviascii17.testcase \
+	writendviascii18.testcase \
+	writesectionndviascii1.testcase \
+	writesectionndviascii2.testcase \
+	writesectionndviascii3.testcase \
+	writesectionndviascii4.testcase \
+	writesectionndviascii5.testcase \
+	writesectionndviascii6.testcase \
+	writesectionndviascii7.testcase \
+	writesectionndviascii8.testcase \
+	writesectionndviascii9.testcase \
+	writesectionndviascii10.testcase \
+	writesectionndviascii11.testcase \
+	writesectionndviascii12.testcase \
+	writesectionndviascii13.testcase \
+	writesectionndviascii14.testcase \
+	writesectionndviascii15.testcase \
+	writesectionndviascii16.testcase \
+	writesectionndviascii17.testcase \
+	writesectionndviascii18.testcase \
+	writesectionndviascii19.testcase \
+	writesectionndviascii20.testcase \
 	writebandtiff1.testcase \
 	writebandtiff2.testcase \
 	writebandtiff3.testcase \
@@ -114,6 +184,89 @@ EXTRA_DIST = loadraster1.testcase \
 	writebandtiff25.testcase \
 	writebandtiff26.testcase \
 	writebandtiff27.testcase \
+	writebandtifftfw1.testcase \
+	writebandtifftfw2.testcase \
+	writebandtifftfw3.testcase \
+	writebandtifftfw4.testcase \
+	writebandtifftfw5.testcase \
+	writebandtifftfw6.testcase \
+	writebandtifftfw7.testcase \
+	writebandtifftfw8.testcase \
+	writebandtifftfw9.testcase \
+	writebandtifftfw10.testcase \
+	writebandtifftfw11.testcase \
+	writebandtifftfw12.testcase \
+	writebandtifftfw13.testcase \
+	writebandtifftfw14.testcase \
+	writebandtifftfw15.testcase \
+	writebandtifftfw16.testcase \
+	writebandtifftfw17.testcase \
+	writebandtifftfw18.testcase \
+	writebandtifftfw19.testcase \
+	writebandtifftfw20.testcase \
+	writebandtifftfw21.testcase \
+	writebandtifftfw22.testcase \
+	writebandtifftfw23.testcase \
+	writebandtifftfw24.testcase \
+	writebandtifftfw25.testcase \
+	writebandtifftfw26.testcase \
+	writebandtifftfw27.testcase \
+	writesectionbandtiff1.testcase \
+	writesectionbandtiff2.testcase \
+	writesectionbandtiff3.testcase \
+	writesectionbandtiff4.testcase \
+	writesectionbandtiff5.testcase \
+	writesectionbandtiff6.testcase \
+	writesectionbandtiff7.testcase \
+	writesectionbandtiff8.testcase \
+	writesectionbandtiff9.testcase \
+	writesectionbandtiff10.testcase \
+	writesectionbandtiff11.testcase \
+	writesectionbandtiff12.testcase \
+	writesectionbandtiff13.testcase \
+	writesectionbandtiff14.testcase \
+	writesectionbandtiff15.testcase \
+	writesectionbandtiff16.testcase \
+	writesectionbandtiff17.testcase \
+	writesectionbandtiff18.testcase \
+	writesectionbandtiff19.testcase \
+	writesectionbandtiff20.testcase \
+	writesectionbandtiff21.testcase \
+	writesectionbandtiff22.testcase \
+	writesectionbandtiff23.testcase \
+	writesectionbandtiff24.testcase \
+	writesectionbandtiff25.testcase \
+	writesectionbandtiff26.testcase \
+	writesectionbandtiff27.testcase \
+	writesectionbandtiff28.testcase \
+	writesectionbandtifftfw1.testcase \
+	writesectionbandtifftfw2.testcase \
+	writesectionbandtifftfw3.testcase \
+	writesectionbandtifftfw4.testcase \
+	writesectionbandtifftfw5.testcase \
+	writesectionbandtifftfw6.testcase \
+	writesectionbandtifftfw7.testcase \
+	writesectionbandtifftfw8.testcase \
+	writesectionbandtifftfw9.testcase \
+	writesectionbandtifftfw10.testcase \
+	writesectionbandtifftfw11.testcase \
+	writesectionbandtifftfw12.testcase \
+	writesectionbandtifftfw13.testcase \
+	writesectionbandtifftfw14.testcase \
+	writesectionbandtifftfw15.testcase \
+	writesectionbandtifftfw16.testcase \
+	writesectionbandtifftfw17.testcase \
+	writesectionbandtifftfw18.testcase \
+	writesectionbandtifftfw19.testcase \
+	writesectionbandtifftfw20.testcase \
+	writesectionbandtifftfw21.testcase \
+	writesectionbandtifftfw22.testcase \
+	writesectionbandtifftfw23.testcase \
+	writesectionbandtifftfw24.testcase \
+	writesectionbandtifftfw25.testcase \
+	writesectionbandtifftfw26.testcase \
+	writesectionbandtifftfw27.testcase \
+	writesectionbandtifftfw28.testcase \
 	writebandgeotiff1.testcase \
 	writebandgeotiff2.testcase \
 	writebandgeotiff3.testcase \
@@ -142,6 +295,35 @@ EXTRA_DIST = loadraster1.testcase \
 	writebandgeotiff26.testcase \
 	writebandgeotiff27.testcase \
 	writebandgeotiff28.testcase \
+	writesectionbandgeotiff1.testcase \
+	writesectionbandgeotiff2.testcase \
+	writesectionbandgeotiff3.testcase \
+	writesectionbandgeotiff4.testcase \
+	writesectionbandgeotiff5.testcase \
+	writesectionbandgeotiff6.testcase \
+	writesectionbandgeotiff7.testcase \
+	writesectionbandgeotiff8.testcase \
+	writesectionbandgeotiff9.testcase \
+	writesectionbandgeotiff10.testcase \
+	writesectionbandgeotiff11.testcase \
+	writesectionbandgeotiff12.testcase \
+	writesectionbandgeotiff13.testcase \
+	writesectionbandgeotiff14.testcase \
+	writesectionbandgeotiff15.testcase \
+	writesectionbandgeotiff16.testcase \
+	writesectionbandgeotiff17.testcase \
+	writesectionbandgeotiff18.testcase \
+	writesectionbandgeotiff19.testcase \
+	writesectionbandgeotiff20.testcase \
+	writesectionbandgeotiff21.testcase \
+	writesectionbandgeotiff22.testcase \
+	writesectionbandgeotiff23.testcase \
+	writesectionbandgeotiff24.testcase \
+	writesectionbandgeotiff25.testcase \
+	writesectionbandgeotiff26.testcase \
+	writesectionbandgeotiff27.testcase \
+	writesectionbandgeotiff28.testcase \
+	writesectionbandgeotiff29.testcase \
 	writemonotiff1.testcase \
 	writemonotiff2.testcase \
 	writemonotiff3.testcase \
@@ -163,6 +345,71 @@ EXTRA_DIST = loadraster1.testcase \
 	writemonotiff19.testcase \
 	writemonotiff20.testcase \
 	writemonotiff21.testcase \
+	writemonotifftfw1.testcase \
+	writemonotifftfw2.testcase \
+	writemonotifftfw3.testcase \
+	writemonotifftfw4.testcase \
+	writemonotifftfw5.testcase \
+	writemonotifftfw6.testcase \
+	writemonotifftfw7.testcase \
+	writemonotifftfw8.testcase \
+	writemonotifftfw9.testcase \
+	writemonotifftfw10.testcase \
+	writemonotifftfw11.testcase \
+	writemonotifftfw12.testcase \
+	writemonotifftfw13.testcase \
+	writemonotifftfw14.testcase \
+	writemonotifftfw15.testcase \
+	writemonotifftfw16.testcase \
+	writemonotifftfw17.testcase \
+	writemonotifftfw18.testcase \
+	writemonotifftfw19.testcase \
+	writemonotifftfw20.testcase \
+	writemonotifftfw21.testcase \
+	writesectionmonotiff1.testcase \
+	writesectionmonotiff2.testcase \
+	writesectionmonotiff3.testcase \
+	writesectionmonotiff4.testcase \
+	writesectionmonotiff5.testcase \
+	writesectionmonotiff6.testcase \
+	writesectionmonotiff7.testcase \
+	writesectionmonotiff8.testcase \
+	writesectionmonotiff9.testcase \
+	writesectionmonotiff10.testcase \
+	writesectionmonotiff11.testcase \
+	writesectionmonotiff12.testcase \
+	writesectionmonotiff13.testcase \
+	writesectionmonotiff14.testcase \
+	writesectionmonotiff15.testcase \
+	writesectionmonotiff16.testcase \
+	writesectionmonotiff17.testcase \
+	writesectionmonotiff18.testcase \
+	writesectionmonotiff19.testcase \
+	writesectionmonotiff20.testcase \
+	writesectionmonotiff21.testcase \
+	writesectionmonotiff22.testcase \
+	writesectionmonotifftfw1.testcase \
+	writesectionmonotifftfw2.testcase \
+	writesectionmonotifftfw3.testcase \
+	writesectionmonotifftfw4.testcase \
+	writesectionmonotifftfw5.testcase \
+	writesectionmonotifftfw6.testcase \
+	writesectionmonotifftfw7.testcase \
+	writesectionmonotifftfw8.testcase \
+	writesectionmonotifftfw9.testcase \
+	writesectionmonotifftfw10.testcase \
+	writesectionmonotifftfw11.testcase \
+	writesectionmonotifftfw12.testcase \
+	writesectionmonotifftfw13.testcase \
+	writesectionmonotifftfw14.testcase \
+	writesectionmonotifftfw15.testcase \
+	writesectionmonotifftfw16.testcase \
+	writesectionmonotifftfw17.testcase \
+	writesectionmonotifftfw18.testcase \
+	writesectionmonotifftfw19.testcase \
+	writesectionmonotifftfw20.testcase \
+	writesectionmonotifftfw21.testcase \
+	writesectionmonotifftfw22.testcase \
 	writemonogeotiff1.testcase \
 	writemonogeotiff2.testcase \
 	writemonogeotiff3.testcase \
@@ -185,6 +432,29 @@ EXTRA_DIST = loadraster1.testcase \
 	writemonogeotiff20.testcase \
 	writemonogeotiff21.testcase \
 	writemonogeotiff22.testcase \
+	writesectionmonogeotiff1.testcase \
+	writesectionmonogeotiff2.testcase \
+	writesectionmonogeotiff3.testcase \
+	writesectionmonogeotiff4.testcase \
+	writesectionmonogeotiff5.testcase \
+	writesectionmonogeotiff6.testcase \
+	writesectionmonogeotiff7.testcase \
+	writesectionmonogeotiff8.testcase \
+	writesectionmonogeotiff9.testcase \
+	writesectionmonogeotiff10.testcase \
+	writesectionmonogeotiff11.testcase \
+	writesectionmonogeotiff12.testcase \
+	writesectionmonogeotiff13.testcase \
+	writesectionmonogeotiff14.testcase \
+	writesectionmonogeotiff15.testcase \
+	writesectionmonogeotiff16.testcase \
+	writesectionmonogeotiff17.testcase \
+	writesectionmonogeotiff18.testcase \
+	writesectionmonogeotiff19.testcase \
+	writesectionmonogeotiff20.testcase \
+	writesectionmonogeotiff21.testcase \
+	writesectionmonogeotiff22.testcase \
+	writesectionmonogeotiff23.testcase \
 	writegeotiff1.testcase \
 	writegeotiff2.testcase \
 	writegeotiff3.testcase \
@@ -204,6 +474,26 @@ EXTRA_DIST = loadraster1.testcase \
 	writegeotiff17.testcase \
 	writegeotiff18.testcase \
 	writegeotiff19.testcase \
+	writesectiongeotiff1.testcase \
+	writesectiongeotiff2.testcase \
+	writesectiongeotiff3.testcase \
+	writesectiongeotiff4.testcase \
+	writesectiongeotiff5.testcase \
+	writesectiongeotiff6.testcase \
+	writesectiongeotiff7.testcase \
+	writesectiongeotiff8.testcase \
+	writesectiongeotiff9.testcase \
+	writesectiongeotiff10.testcase \
+	writesectiongeotiff11.testcase \
+	writesectiongeotiff12.testcase \
+	writesectiongeotiff13.testcase \
+	writesectiongeotiff14.testcase \
+	writesectiongeotiff15.testcase \
+	writesectiongeotiff16.testcase \
+	writesectiongeotiff17.testcase \
+	writesectiongeotiff18.testcase \
+	writesectiongeotiff19.testcase \
+	writesectiongeotiff20.testcase \
 	writejpeg1.testcase \
 	writejpeg2.testcase \
 	writejpeg3.testcase \
@@ -219,6 +509,53 @@ EXTRA_DIST = loadraster1.testcase \
 	writejpeg13.testcase \
 	writejpeg14.testcase \
 	writejpeg15.testcase \
+	writejpegjgw1.testcase \
+	writejpegjgw2.testcase \
+	writejpegjgw3.testcase \
+	writejpegjgw4.testcase \
+	writejpegjgw5.testcase \
+	writejpegjgw6.testcase \
+	writejpegjgw7.testcase \
+	writejpegjgw8.testcase \
+	writejpegjgw9.testcase \
+	writejpegjgw10.testcase \
+	writejpegjgw11.testcase \
+	writejpegjgw12.testcase \
+	writejpegjgw13.testcase \
+	writejpegjgw14.testcase \
+	writejpegjgw15.testcase \
+	writesectionjpeg1.testcase \
+	writesectionjpeg2.testcase \
+	writesectionjpeg3.testcase \
+	writesectionjpeg4.testcase \
+	writesectionjpeg5.testcase \
+	writesectionjpeg6.testcase \
+	writesectionjpeg7.testcase \
+	writesectionjpeg8.testcase \
+	writesectionjpeg9.testcase \
+	writesectionjpeg10.testcase \
+	writesectionjpeg11.testcase \
+	writesectionjpeg12.testcase \
+	writesectionjpeg13.testcase \
+	writesectionjpeg14.testcase \
+	writesectionjpeg15.testcase \
+	writesectionjpeg16.testcase \
+	writesectionjpegjgw1.testcase \
+	writesectionjpegjgw2.testcase \
+	writesectionjpegjgw3.testcase \
+	writesectionjpegjgw4.testcase \
+	writesectionjpegjgw5.testcase \
+	writesectionjpegjgw6.testcase \
+	writesectionjpegjgw7.testcase \
+	writesectionjpegjgw8.testcase \
+	writesectionjpegjgw9.testcase \
+	writesectionjpegjgw10.testcase \
+	writesectionjpegjgw11.testcase \
+	writesectionjpegjgw12.testcase \
+	writesectionjpegjgw13.testcase \
+	writesectionjpegjgw14.testcase \
+	writesectionjpegjgw15.testcase \
+	writesectionjpegjgw16.testcase \
 	writetiff1.testcase \
 	writetiff2.testcase \
 	writetiff3.testcase \
@@ -236,7 +573,63 @@ EXTRA_DIST = loadraster1.testcase \
 	writetiff15.testcase \
 	writetiff16.testcase \
 	writetiff17.testcase \
-	writetiff18.testcase
+	writetiff18.testcase \
+	writesectiontiff1.testcase \
+	writesectiontiff2.testcase \
+	writesectiontiff3.testcase \
+	writesectiontiff4.testcase \
+	writesectiontiff5.testcase \
+	writesectiontiff6.testcase \
+	writesectiontiff7.testcase \
+	writesectiontiff8.testcase \
+	writesectiontiff9.testcase \
+	writesectiontiff10.testcase \
+	writesectiontiff11.testcase \
+	writesectiontiff12.testcase \
+	writesectiontiff13.testcase \
+	writesectiontiff14.testcase \
+	writesectiontiff15.testcase \
+	writesectiontiff16.testcase \
+	writesectiontiff17.testcase \
+	writesectiontiff18.testcase \
+	writesectiontiff19.testcase \
+	writetifftfw1.testcase \
+	writetifftfw2.testcase \
+	writetifftfw3.testcase \
+	writetifftfw4.testcase \
+	writetifftfw5.testcase \
+	writetifftfw6.testcase \
+	writetifftfw7.testcase \
+	writetifftfw8.testcase \
+	writetifftfw9.testcase \
+	writetifftfw10.testcase \
+	writetifftfw11.testcase \
+	writetifftfw12.testcase \
+	writetifftfw13.testcase \
+	writetifftfw14.testcase \
+	writetifftfw15.testcase \
+	writetifftfw16.testcase \
+	writetifftfw17.testcase \
+	writetifftfw18.testcase \
+	writesectiontifftfw1.testcase \
+	writesectiontifftfw2.testcase \
+	writesectiontifftfw3.testcase \
+	writesectiontifftfw4.testcase \
+	writesectiontifftfw5.testcase \
+	writesectiontifftfw6.testcase \
+	writesectiontifftfw7.testcase \
+	writesectiontifftfw8.testcase \
+	writesectiontifftfw9.testcase \
+	writesectiontifftfw10.testcase \
+	writesectiontifftfw11.testcase \
+	writesectiontifftfw12.testcase \
+	writesectiontifftfw13.testcase \
+	writesectiontifftfw14.testcase \
+	writesectiontifftfw15.testcase \
+	writesectiontifftfw16.testcase \
+	writesectiontifftfw17.testcase \
+	writesectiontifftfw18.testcase \
+	writesectiontifftfw19.testcase 
 
 
 
diff --git a/test/sql_stmt_security_tests/Makefile.in b/test/sql_stmt_security_tests/Makefile.in
index f2b5958..14017fc 100644
--- a/test/sql_stmt_security_tests/Makefile.in
+++ b/test/sql_stmt_security_tests/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# Makefile.in generated by automake 1.15 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,7 +14,17 @@
 
 @SET_MAKE@
 VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -78,7 +88,6 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = test/sql_stmt_security_tests
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
@@ -86,6 +95,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -110,6 +120,7 @@ am__can_run_installinfo = \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -141,6 +152,8 @@ ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
+FREETYPE2_CFLAGS = @FREETYPE2_CFLAGS@
+FREETYPE2_LIBS = @FREETYPE2_LIBS@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
@@ -153,6 +166,8 @@ LIBCAIRO_CFLAGS = @LIBCAIRO_CFLAGS@
 LIBCAIRO_LIBS = @LIBCAIRO_LIBS@
 LIBCURL_CFLAGS = @LIBCURL_CFLAGS@
 LIBCURL_LIBS = @LIBCURL_LIBS@
+LIBFREETYPE2_CFLAGS = @LIBFREETYPE2_CFLAGS@
+LIBFREETYPE2_LIBS = @LIBFREETYPE2_LIBS@
 LIBLZMA_CFLAGS = @LIBLZMA_CFLAGS@
 LIBLZMA_LIBS = @LIBLZMA_LIBS@
 LIBOBJS = @LIBOBJS@
@@ -249,7 +264,21 @@ target_alias = @target_alias@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-EXTRA_DIST = loadraster1.testcase \
+EXTRA_DIST = exportfont1.testcase \
+	exportfont2.testcase \
+	exportfont3.testcase \
+	exportfont4.testcase \
+	exportfont9.testcase \
+	exportfont10.testcase \
+	exportfont11.testcase \
+	exportfont12.testcase \
+	exportfont13.testcase \
+	loadfont1.testcase \
+	loadfont2.testcase \
+	loadfont3.testcase \
+	loadfont4.testcase \
+	loadfont5.testcase \
+	loadraster1.testcase \
 	loadraster2.testcase \
 	loadraster3.testcase \
 	loadraster4.testcase \
@@ -337,6 +366,62 @@ EXTRA_DIST = loadraster1.testcase \
 	writeascii16.testcase \
 	writeascii17.testcase \
 	writeascii18.testcase \
+	writesectionascii1.testcase \
+	writesectionascii2.testcase \
+	writesectionascii3.testcase \
+	writesectionascii4.testcase \
+	writesectionascii5.testcase \
+	writesectionascii6.testcase \
+	writesectionascii7.testcase \
+	writesectionascii9.testcase \
+	writesectionascii10.testcase \
+	writesectionascii11.testcase \
+	writesectionascii12.testcase \
+	writesectionascii13.testcase \
+	writesectionascii14.testcase \
+	writesectionascii15.testcase \
+	writesectionascii16.testcase \
+	writesectionascii17.testcase \
+	writesectionascii18.testcase \
+	writesectionascii18.testcase \
+	writendviascii1.testcase \
+	writendviascii2.testcase \
+	writendviascii3.testcase \
+	writendviascii4.testcase \
+	writendviascii5.testcase \
+	writendviascii6.testcase \
+	writendviascii7.testcase \
+	writendviascii8.testcase \
+	writendviascii9.testcase \
+	writendviascii10.testcase \
+	writendviascii11.testcase \
+	writendviascii12.testcase \
+	writendviascii13.testcase \
+	writendviascii14.testcase \
+	writendviascii15.testcase \
+	writendviascii16.testcase \
+	writendviascii17.testcase \
+	writendviascii18.testcase \
+	writesectionndviascii1.testcase \
+	writesectionndviascii2.testcase \
+	writesectionndviascii3.testcase \
+	writesectionndviascii4.testcase \
+	writesectionndviascii5.testcase \
+	writesectionndviascii6.testcase \
+	writesectionndviascii7.testcase \
+	writesectionndviascii8.testcase \
+	writesectionndviascii9.testcase \
+	writesectionndviascii10.testcase \
+	writesectionndviascii11.testcase \
+	writesectionndviascii12.testcase \
+	writesectionndviascii13.testcase \
+	writesectionndviascii14.testcase \
+	writesectionndviascii15.testcase \
+	writesectionndviascii16.testcase \
+	writesectionndviascii17.testcase \
+	writesectionndviascii18.testcase \
+	writesectionndviascii19.testcase \
+	writesectionndviascii20.testcase \
 	writebandtiff1.testcase \
 	writebandtiff2.testcase \
 	writebandtiff3.testcase \
@@ -364,6 +449,89 @@ EXTRA_DIST = loadraster1.testcase \
 	writebandtiff25.testcase \
 	writebandtiff26.testcase \
 	writebandtiff27.testcase \
+	writebandtifftfw1.testcase \
+	writebandtifftfw2.testcase \
+	writebandtifftfw3.testcase \
+	writebandtifftfw4.testcase \
+	writebandtifftfw5.testcase \
+	writebandtifftfw6.testcase \
+	writebandtifftfw7.testcase \
+	writebandtifftfw8.testcase \
+	writebandtifftfw9.testcase \
+	writebandtifftfw10.testcase \
+	writebandtifftfw11.testcase \
+	writebandtifftfw12.testcase \
+	writebandtifftfw13.testcase \
+	writebandtifftfw14.testcase \
+	writebandtifftfw15.testcase \
+	writebandtifftfw16.testcase \
+	writebandtifftfw17.testcase \
+	writebandtifftfw18.testcase \
+	writebandtifftfw19.testcase \
+	writebandtifftfw20.testcase \
+	writebandtifftfw21.testcase \
+	writebandtifftfw22.testcase \
+	writebandtifftfw23.testcase \
+	writebandtifftfw24.testcase \
+	writebandtifftfw25.testcase \
+	writebandtifftfw26.testcase \
+	writebandtifftfw27.testcase \
+	writesectionbandtiff1.testcase \
+	writesectionbandtiff2.testcase \
+	writesectionbandtiff3.testcase \
+	writesectionbandtiff4.testcase \
+	writesectionbandtiff5.testcase \
+	writesectionbandtiff6.testcase \
+	writesectionbandtiff7.testcase \
+	writesectionbandtiff8.testcase \
+	writesectionbandtiff9.testcase \
+	writesectionbandtiff10.testcase \
+	writesectionbandtiff11.testcase \
+	writesectionbandtiff12.testcase \
+	writesectionbandtiff13.testcase \
+	writesectionbandtiff14.testcase \
+	writesectionbandtiff15.testcase \
+	writesectionbandtiff16.testcase \
+	writesectionbandtiff17.testcase \
+	writesectionbandtiff18.testcase \
+	writesectionbandtiff19.testcase \
+	writesectionbandtiff20.testcase \
+	writesectionbandtiff21.testcase \
+	writesectionbandtiff22.testcase \
+	writesectionbandtiff23.testcase \
+	writesectionbandtiff24.testcase \
+	writesectionbandtiff25.testcase \
+	writesectionbandtiff26.testcase \
+	writesectionbandtiff27.testcase \
+	writesectionbandtiff28.testcase \
+	writesectionbandtifftfw1.testcase \
+	writesectionbandtifftfw2.testcase \
+	writesectionbandtifftfw3.testcase \
+	writesectionbandtifftfw4.testcase \
+	writesectionbandtifftfw5.testcase \
+	writesectionbandtifftfw6.testcase \
+	writesectionbandtifftfw7.testcase \
+	writesectionbandtifftfw8.testcase \
+	writesectionbandtifftfw9.testcase \
+	writesectionbandtifftfw10.testcase \
+	writesectionbandtifftfw11.testcase \
+	writesectionbandtifftfw12.testcase \
+	writesectionbandtifftfw13.testcase \
+	writesectionbandtifftfw14.testcase \
+	writesectionbandtifftfw15.testcase \
+	writesectionbandtifftfw16.testcase \
+	writesectionbandtifftfw17.testcase \
+	writesectionbandtifftfw18.testcase \
+	writesectionbandtifftfw19.testcase \
+	writesectionbandtifftfw20.testcase \
+	writesectionbandtifftfw21.testcase \
+	writesectionbandtifftfw22.testcase \
+	writesectionbandtifftfw23.testcase \
+	writesectionbandtifftfw24.testcase \
+	writesectionbandtifftfw25.testcase \
+	writesectionbandtifftfw26.testcase \
+	writesectionbandtifftfw27.testcase \
+	writesectionbandtifftfw28.testcase \
 	writebandgeotiff1.testcase \
 	writebandgeotiff2.testcase \
 	writebandgeotiff3.testcase \
@@ -392,6 +560,35 @@ EXTRA_DIST = loadraster1.testcase \
 	writebandgeotiff26.testcase \
 	writebandgeotiff27.testcase \
 	writebandgeotiff28.testcase \
+	writesectionbandgeotiff1.testcase \
+	writesectionbandgeotiff2.testcase \
+	writesectionbandgeotiff3.testcase \
+	writesectionbandgeotiff4.testcase \
+	writesectionbandgeotiff5.testcase \
+	writesectionbandgeotiff6.testcase \
+	writesectionbandgeotiff7.testcase \
+	writesectionbandgeotiff8.testcase \
+	writesectionbandgeotiff9.testcase \
+	writesectionbandgeotiff10.testcase \
+	writesectionbandgeotiff11.testcase \
+	writesectionbandgeotiff12.testcase \
+	writesectionbandgeotiff13.testcase \
+	writesectionbandgeotiff14.testcase \
+	writesectionbandgeotiff15.testcase \
+	writesectionbandgeotiff16.testcase \
+	writesectionbandgeotiff17.testcase \
+	writesectionbandgeotiff18.testcase \
+	writesectionbandgeotiff19.testcase \
+	writesectionbandgeotiff20.testcase \
+	writesectionbandgeotiff21.testcase \
+	writesectionbandgeotiff22.testcase \
+	writesectionbandgeotiff23.testcase \
+	writesectionbandgeotiff24.testcase \
+	writesectionbandgeotiff25.testcase \
+	writesectionbandgeotiff26.testcase \
+	writesectionbandgeotiff27.testcase \
+	writesectionbandgeotiff28.testcase \
+	writesectionbandgeotiff29.testcase \
 	writemonotiff1.testcase \
 	writemonotiff2.testcase \
 	writemonotiff3.testcase \
@@ -413,6 +610,71 @@ EXTRA_DIST = loadraster1.testcase \
 	writemonotiff19.testcase \
 	writemonotiff20.testcase \
 	writemonotiff21.testcase \
+	writemonotifftfw1.testcase \
+	writemonotifftfw2.testcase \
+	writemonotifftfw3.testcase \
+	writemonotifftfw4.testcase \
+	writemonotifftfw5.testcase \
+	writemonotifftfw6.testcase \
+	writemonotifftfw7.testcase \
+	writemonotifftfw8.testcase \
+	writemonotifftfw9.testcase \
+	writemonotifftfw10.testcase \
+	writemonotifftfw11.testcase \
+	writemonotifftfw12.testcase \
+	writemonotifftfw13.testcase \
+	writemonotifftfw14.testcase \
+	writemonotifftfw15.testcase \
+	writemonotifftfw16.testcase \
+	writemonotifftfw17.testcase \
+	writemonotifftfw18.testcase \
+	writemonotifftfw19.testcase \
+	writemonotifftfw20.testcase \
+	writemonotifftfw21.testcase \
+	writesectionmonotiff1.testcase \
+	writesectionmonotiff2.testcase \
+	writesectionmonotiff3.testcase \
+	writesectionmonotiff4.testcase \
+	writesectionmonotiff5.testcase \
+	writesectionmonotiff6.testcase \
+	writesectionmonotiff7.testcase \
+	writesectionmonotiff8.testcase \
+	writesectionmonotiff9.testcase \
+	writesectionmonotiff10.testcase \
+	writesectionmonotiff11.testcase \
+	writesectionmonotiff12.testcase \
+	writesectionmonotiff13.testcase \
+	writesectionmonotiff14.testcase \
+	writesectionmonotiff15.testcase \
+	writesectionmonotiff16.testcase \
+	writesectionmonotiff17.testcase \
+	writesectionmonotiff18.testcase \
+	writesectionmonotiff19.testcase \
+	writesectionmonotiff20.testcase \
+	writesectionmonotiff21.testcase \
+	writesectionmonotiff22.testcase \
+	writesectionmonotifftfw1.testcase \
+	writesectionmonotifftfw2.testcase \
+	writesectionmonotifftfw3.testcase \
+	writesectionmonotifftfw4.testcase \
+	writesectionmonotifftfw5.testcase \
+	writesectionmonotifftfw6.testcase \
+	writesectionmonotifftfw7.testcase \
+	writesectionmonotifftfw8.testcase \
+	writesectionmonotifftfw9.testcase \
+	writesectionmonotifftfw10.testcase \
+	writesectionmonotifftfw11.testcase \
+	writesectionmonotifftfw12.testcase \
+	writesectionmonotifftfw13.testcase \
+	writesectionmonotifftfw14.testcase \
+	writesectionmonotifftfw15.testcase \
+	writesectionmonotifftfw16.testcase \
+	writesectionmonotifftfw17.testcase \
+	writesectionmonotifftfw18.testcase \
+	writesectionmonotifftfw19.testcase \
+	writesectionmonotifftfw20.testcase \
+	writesectionmonotifftfw21.testcase \
+	writesectionmonotifftfw22.testcase \
 	writemonogeotiff1.testcase \
 	writemonogeotiff2.testcase \
 	writemonogeotiff3.testcase \
@@ -435,6 +697,29 @@ EXTRA_DIST = loadraster1.testcase \
 	writemonogeotiff20.testcase \
 	writemonogeotiff21.testcase \
 	writemonogeotiff22.testcase \
+	writesectionmonogeotiff1.testcase \
+	writesectionmonogeotiff2.testcase \
+	writesectionmonogeotiff3.testcase \
+	writesectionmonogeotiff4.testcase \
+	writesectionmonogeotiff5.testcase \
+	writesectionmonogeotiff6.testcase \
+	writesectionmonogeotiff7.testcase \
+	writesectionmonogeotiff8.testcase \
+	writesectionmonogeotiff9.testcase \
+	writesectionmonogeotiff10.testcase \
+	writesectionmonogeotiff11.testcase \
+	writesectionmonogeotiff12.testcase \
+	writesectionmonogeotiff13.testcase \
+	writesectionmonogeotiff14.testcase \
+	writesectionmonogeotiff15.testcase \
+	writesectionmonogeotiff16.testcase \
+	writesectionmonogeotiff17.testcase \
+	writesectionmonogeotiff18.testcase \
+	writesectionmonogeotiff19.testcase \
+	writesectionmonogeotiff20.testcase \
+	writesectionmonogeotiff21.testcase \
+	writesectionmonogeotiff22.testcase \
+	writesectionmonogeotiff23.testcase \
 	writegeotiff1.testcase \
 	writegeotiff2.testcase \
 	writegeotiff3.testcase \
@@ -454,6 +739,26 @@ EXTRA_DIST = loadraster1.testcase \
 	writegeotiff17.testcase \
 	writegeotiff18.testcase \
 	writegeotiff19.testcase \
+	writesectiongeotiff1.testcase \
+	writesectiongeotiff2.testcase \
+	writesectiongeotiff3.testcase \
+	writesectiongeotiff4.testcase \
+	writesectiongeotiff5.testcase \
+	writesectiongeotiff6.testcase \
+	writesectiongeotiff7.testcase \
+	writesectiongeotiff8.testcase \
+	writesectiongeotiff9.testcase \
+	writesectiongeotiff10.testcase \
+	writesectiongeotiff11.testcase \
+	writesectiongeotiff12.testcase \
+	writesectiongeotiff13.testcase \
+	writesectiongeotiff14.testcase \
+	writesectiongeotiff15.testcase \
+	writesectiongeotiff16.testcase \
+	writesectiongeotiff17.testcase \
+	writesectiongeotiff18.testcase \
+	writesectiongeotiff19.testcase \
+	writesectiongeotiff20.testcase \
 	writejpeg1.testcase \
 	writejpeg2.testcase \
 	writejpeg3.testcase \
@@ -469,6 +774,53 @@ EXTRA_DIST = loadraster1.testcase \
 	writejpeg13.testcase \
 	writejpeg14.testcase \
 	writejpeg15.testcase \
+	writejpegjgw1.testcase \
+	writejpegjgw2.testcase \
+	writejpegjgw3.testcase \
+	writejpegjgw4.testcase \
+	writejpegjgw5.testcase \
+	writejpegjgw6.testcase \
+	writejpegjgw7.testcase \
+	writejpegjgw8.testcase \
+	writejpegjgw9.testcase \
+	writejpegjgw10.testcase \
+	writejpegjgw11.testcase \
+	writejpegjgw12.testcase \
+	writejpegjgw13.testcase \
+	writejpegjgw14.testcase \
+	writejpegjgw15.testcase \
+	writesectionjpeg1.testcase \
+	writesectionjpeg2.testcase \
+	writesectionjpeg3.testcase \
+	writesectionjpeg4.testcase \
+	writesectionjpeg5.testcase \
+	writesectionjpeg6.testcase \
+	writesectionjpeg7.testcase \
+	writesectionjpeg8.testcase \
+	writesectionjpeg9.testcase \
+	writesectionjpeg10.testcase \
+	writesectionjpeg11.testcase \
+	writesectionjpeg12.testcase \
+	writesectionjpeg13.testcase \
+	writesectionjpeg14.testcase \
+	writesectionjpeg15.testcase \
+	writesectionjpeg16.testcase \
+	writesectionjpegjgw1.testcase \
+	writesectionjpegjgw2.testcase \
+	writesectionjpegjgw3.testcase \
+	writesectionjpegjgw4.testcase \
+	writesectionjpegjgw5.testcase \
+	writesectionjpegjgw6.testcase \
+	writesectionjpegjgw7.testcase \
+	writesectionjpegjgw8.testcase \
+	writesectionjpegjgw9.testcase \
+	writesectionjpegjgw10.testcase \
+	writesectionjpegjgw11.testcase \
+	writesectionjpegjgw12.testcase \
+	writesectionjpegjgw13.testcase \
+	writesectionjpegjgw14.testcase \
+	writesectionjpegjgw15.testcase \
+	writesectionjpegjgw16.testcase \
 	writetiff1.testcase \
 	writetiff2.testcase \
 	writetiff3.testcase \
@@ -486,7 +838,63 @@ EXTRA_DIST = loadraster1.testcase \
 	writetiff15.testcase \
 	writetiff16.testcase \
 	writetiff17.testcase \
-	writetiff18.testcase
+	writetiff18.testcase \
+	writesectiontiff1.testcase \
+	writesectiontiff2.testcase \
+	writesectiontiff3.testcase \
+	writesectiontiff4.testcase \
+	writesectiontiff5.testcase \
+	writesectiontiff6.testcase \
+	writesectiontiff7.testcase \
+	writesectiontiff8.testcase \
+	writesectiontiff9.testcase \
+	writesectiontiff10.testcase \
+	writesectiontiff11.testcase \
+	writesectiontiff12.testcase \
+	writesectiontiff13.testcase \
+	writesectiontiff14.testcase \
+	writesectiontiff15.testcase \
+	writesectiontiff16.testcase \
+	writesectiontiff17.testcase \
+	writesectiontiff18.testcase \
+	writesectiontiff19.testcase \
+	writetifftfw1.testcase \
+	writetifftfw2.testcase \
+	writetifftfw3.testcase \
+	writetifftfw4.testcase \
+	writetifftfw5.testcase \
+	writetifftfw6.testcase \
+	writetifftfw7.testcase \
+	writetifftfw8.testcase \
+	writetifftfw9.testcase \
+	writetifftfw10.testcase \
+	writetifftfw11.testcase \
+	writetifftfw12.testcase \
+	writetifftfw13.testcase \
+	writetifftfw14.testcase \
+	writetifftfw15.testcase \
+	writetifftfw16.testcase \
+	writetifftfw17.testcase \
+	writetifftfw18.testcase \
+	writesectiontifftfw1.testcase \
+	writesectiontifftfw2.testcase \
+	writesectiontifftfw3.testcase \
+	writesectiontifftfw4.testcase \
+	writesectiontifftfw5.testcase \
+	writesectiontifftfw6.testcase \
+	writesectiontifftfw7.testcase \
+	writesectiontifftfw8.testcase \
+	writesectiontifftfw9.testcase \
+	writesectiontifftfw10.testcase \
+	writesectiontifftfw11.testcase \
+	writesectiontifftfw12.testcase \
+	writesectiontifftfw13.testcase \
+	writesectiontifftfw14.testcase \
+	writesectiontifftfw15.testcase \
+	writesectiontifftfw16.testcase \
+	writesectiontifftfw17.testcase \
+	writesectiontifftfw18.testcase \
+	writesectiontifftfw19.testcase 
 
 all: all-am
 
@@ -503,7 +911,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__confi
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu test/sql_stmt_security_tests/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu test/sql_stmt_security_tests/Makefile
-.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -678,6 +1085,8 @@ uninstall-am:
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	tags-am uninstall uninstall-am
 
+.PRECIOUS: Makefile
+
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/test/sql_stmt_security_tests/exportfont1.testcase b/test/sql_stmt_security_tests/exportfont1.testcase
new file mode 100644
index 0000000..055d5d9
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportfont1.testcase
@@ -0,0 +1,7 @@
+RL2_ExportFontToFile - NULL facename
+:memory: #use in-memory database
+SELECT RL2_ExportFontToFile(NULL, 'wonderfulFree-font.ttf');
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportFontToFile(NULL, 'wonderfulFree-font.ttf')
+-1
diff --git a/test/sql_stmt_security_tests/exportfont10.testcase b/test/sql_stmt_security_tests/exportfont10.testcase
new file mode 100644
index 0000000..e6f4c9e
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportfont10.testcase
@@ -0,0 +1,7 @@
+RL2_ExportFontToFile - INTEGER path
+:memory: #use in-memory database
+SELECT RL2_ExportFontToFile('wonderfulFree-Regular', 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportFontToFile('wonderfulFree-Regular', 1)
+-1
diff --git a/test/sql_stmt_security_tests/exportfont11.testcase b/test/sql_stmt_security_tests/exportfont11.testcase
new file mode 100644
index 0000000..f202665
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportfont11.testcase
@@ -0,0 +1,7 @@
+RL2_ExportFontToFile - DOUBLE path
+:memory: #use in-memory database
+SELECT RL2_ExportFontToFile('wonderfulFree-Regular', 1.1);
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportFontToFile('wonderfulFree-Regular', 1.1)
+-1
diff --git a/test/sql_stmt_security_tests/exportfont12.testcase b/test/sql_stmt_security_tests/exportfont12.testcase
new file mode 100644
index 0000000..c00887b
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportfont12.testcase
@@ -0,0 +1,7 @@
+RL2_ExportFontToFile - BLOB path
+:memory: #use in-memory database
+SELECT RL2_ExportFontToFile('wonderfulFree-Regular', zeroblob(20));
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportFontToFile('wonderfulFree-Regular', zeroblob(20))
+-1
diff --git a/test/sql_stmt_security_tests/exportfont13.testcase b/test/sql_stmt_security_tests/exportfont13.testcase
new file mode 100644
index 0000000..b0e68e3
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportfont13.testcase
@@ -0,0 +1,7 @@
+RL2_ExportFontToFile - TEXT path
+:memory: #use in-memory database
+SELECT RL2_ExportFontToFile('wonderfulFree-Regular', 'wonderfulFree-font.ttf');
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportFontToFile('wonderfulFree-Regular', 'wonderfulFree-font.ttf')
+0
diff --git a/test/sql_stmt_security_tests/exportfont2.testcase b/test/sql_stmt_security_tests/exportfont2.testcase
new file mode 100644
index 0000000..7f844d4
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportfont2.testcase
@@ -0,0 +1,7 @@
+RL2_ExportFontToFile - INTEGER facename
+:memory: #use in-memory database
+SELECT RL2_ExportFontToFile(1, 'wonderfulFree-font.ttf');
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportFontToFile(1, 'wonderfulFree-font.ttf')
+-1
diff --git a/test/sql_stmt_security_tests/exportfont3.testcase b/test/sql_stmt_security_tests/exportfont3.testcase
new file mode 100644
index 0000000..e95ce3f
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportfont3.testcase
@@ -0,0 +1,7 @@
+RL2_ExportFontToFile - DOUBLE facename
+:memory: #use in-memory database
+SELECT RL2_ExportFontToFile(1.1, 'wonderfulFree-font.ttf');
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportFontToFile(1.1, 'wonderfulFree-font.ttf')
+-1
diff --git a/test/sql_stmt_security_tests/exportfont4.testcase b/test/sql_stmt_security_tests/exportfont4.testcase
new file mode 100644
index 0000000..b5c3a38
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportfont4.testcase
@@ -0,0 +1,7 @@
+RL2_ExportFontToFile - BLOB facename
+:memory: #use in-memory database
+SELECT RL2_ExportFontToFile(zeroblob(10), 'wonderfulFree-font.ttf');
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportFontToFile(zeroblob(10), 'wonderfulFree-font.ttf')
+-1
diff --git a/test/sql_stmt_security_tests/exportfont9.testcase b/test/sql_stmt_security_tests/exportfont9.testcase
new file mode 100644
index 0000000..265744b
--- /dev/null
+++ b/test/sql_stmt_security_tests/exportfont9.testcase
@@ -0,0 +1,7 @@
+RL2_ExportFontToFile - NULL path
+:memory: #use in-memory database
+SELECT RL2_ExportFontToFile('wonderfulFree-Regular', NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportFontToFile('wonderfulFree-Regular', NULL)
+-1
diff --git a/test/sql_stmt_security_tests/loadfont1.testcase b/test/sql_stmt_security_tests/loadfont1.testcase
new file mode 100644
index 0000000..c50ff88
--- /dev/null
+++ b/test/sql_stmt_security_tests/loadfont1.testcase
@@ -0,0 +1,7 @@
+RL2_LoadFontFromFile - NULL path
+:memory: #use in-memory database
+SELECT RL2_LoadFontFromFile(NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_LoadFontFromFile(NULL)
+-1
diff --git a/test/sql_stmt_security_tests/loadfont2.testcase b/test/sql_stmt_security_tests/loadfont2.testcase
new file mode 100644
index 0000000..df8ebce
--- /dev/null
+++ b/test/sql_stmt_security_tests/loadfont2.testcase
@@ -0,0 +1,7 @@
+RL2_LoadFontFromFile - INTEGER path
+:memory: #use in-memory database
+SELECT RL2_LoadFontFromFile(1);
+1 # rows (not including the header row)
+1 # columns
+RL2_LoadFontFromFile(1)
+-1
diff --git a/test/sql_stmt_security_tests/loadfont3.testcase b/test/sql_stmt_security_tests/loadfont3.testcase
new file mode 100644
index 0000000..205f818
--- /dev/null
+++ b/test/sql_stmt_security_tests/loadfont3.testcase
@@ -0,0 +1,7 @@
+RL2_LoadFontFromFile - DOUBLE path
+:memory: #use in-memory database
+SELECT RL2_LoadFontFromFile(1.1);
+1 # rows (not including the header row)
+1 # columns
+RL2_LoadFontFromFile(1.1)
+-1
diff --git a/test/sql_stmt_security_tests/loadfont4.testcase b/test/sql_stmt_security_tests/loadfont4.testcase
new file mode 100644
index 0000000..aa65001
--- /dev/null
+++ b/test/sql_stmt_security_tests/loadfont4.testcase
@@ -0,0 +1,7 @@
+RL2_LoadFontFromFile - BLOB path
+:memory: #use in-memory database
+SELECT RL2_LoadFontFromFile(zeroblob(10));
+1 # rows (not including the header row)
+1 # columns
+RL2_LoadFontFromFile(zeroblob(10))
+-1
diff --git a/test/sql_stmt_security_tests/loadfont5.testcase b/test/sql_stmt_security_tests/loadfont5.testcase
new file mode 100644
index 0000000..4220816
--- /dev/null
+++ b/test/sql_stmt_security_tests/loadfont5.testcase
@@ -0,0 +1,7 @@
+RL2_LoadFontFromFile - invalid path
+:memory: #use in-memory database
+SELECT RL2_LoadFontFromFile('wonderfulFree-font.ttf');
+1 # rows (not including the header row)
+1 # columns
+RL2_LoadFontFromFile('wonderfulFree-font.ttf')
+0
diff --git a/test/sql_stmt_security_tests/writebandtifftfw1.testcase b/test/sql_stmt_security_tests/writebandtifftfw1.testcase
new file mode 100644
index 0000000..b10ebf9
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw1.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - NULL Coverage
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw(NULL, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw(NULL, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw10.testcase b/test/sql_stmt_security_tests/writebandtifftfw10.testcase
new file mode 100644
index 0000000..9778d59
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw10.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - NULL tile-size
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'JPEG', NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'JPEG', NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw11.testcase b/test/sql_stmt_security_tests/writebandtifftfw11.testcase
new file mode 100644
index 0000000..bbf7d0d
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw11.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - invalid width (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 4, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'PNG', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 4, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'PNG', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw12.testcase b/test/sql_stmt_security_tests/writebandtifftfw12.testcase
new file mode 100644
index 0000000..d43f532
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw12.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - invalid width (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1000004, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'FAX4', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1000004, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'FAX4', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw13.testcase b/test/sql_stmt_security_tests/writebandtifftfw13.testcase
new file mode 100644
index 0000000..aa182bb
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw13.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - invalid height (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 4, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'FAX3', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 4, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'FAX3', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw14.testcase b/test/sql_stmt_security_tests/writebandtifftfw14.testcase
new file mode 100644
index 0000000..a8cac4e
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw14.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - invalid height (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1000004, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'DEFLATE', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1000004, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'DEFLATE', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw15.testcase b/test/sql_stmt_security_tests/writebandtifftfw15.testcase
new file mode 100644
index 0000000..e10aa87
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw15.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - invalid tile-size (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'LZW', 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'LZW', 2)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw16.testcase b/test/sql_stmt_security_tests/writebandtifftfw16.testcase
new file mode 100644
index 0000000..36a192f
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw16.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - invalid tile-size (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'LZMA', 2000000);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'LZMA', 2000000)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw17.testcase b/test/sql_stmt_security_tests/writebandtifftfw17.testcase
new file mode 100644
index 0000000..ea4f51b
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw17.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - not existing coverage (1)
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw18.testcase b/test/sql_stmt_security_tests/writebandtifftfw18.testcase
new file mode 100644
index 0000000..1ece763
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw18.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - not existing coverage (2)
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw19.testcase b/test/sql_stmt_security_tests/writebandtifftfw19.testcase
new file mode 100644
index 0000000..8542302
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw19.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - NULL red band
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, NULL, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, NULL, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw2.testcase b/test/sql_stmt_security_tests/writebandtifftfw2.testcase
new file mode 100644
index 0000000..adeee95
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw2.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - NULL Path
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', NULL, 1024, 1024, 0, 1, 2, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', NULL, 1024, 1024, 0, 1, 2, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw20.testcase b/test/sql_stmt_security_tests/writebandtifftfw20.testcase
new file mode 100644
index 0000000..620d38f
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw20.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - invalid red band (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, -1, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, -1, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw21.testcase b/test/sql_stmt_security_tests/writebandtifftfw21.testcase
new file mode 100644
index 0000000..1109a51
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw21.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - invalid red band (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 500, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 500, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw22.testcase b/test/sql_stmt_security_tests/writebandtifftfw22.testcase
new file mode 100644
index 0000000..91ac174
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw22.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - NULL green band
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, NULL, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, NULL, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw23.testcase b/test/sql_stmt_security_tests/writebandtifftfw23.testcase
new file mode 100644
index 0000000..a9eede6
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw23.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - invalid green band (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, -1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, -1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw24.testcase b/test/sql_stmt_security_tests/writebandtifftfw24.testcase
new file mode 100644
index 0000000..ecda344
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw24.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - invalid green band (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 500, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 500, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw25.testcase b/test/sql_stmt_security_tests/writebandtifftfw25.testcase
new file mode 100644
index 0000000..9e15c43
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw25.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - NULL blue band 
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, NULL, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, NULL, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw26.testcase b/test/sql_stmt_security_tests/writebandtifftfw26.testcase
new file mode 100644
index 0000000..16e5437
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw26.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - invalid blue band (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, -1, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, -1, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw27.testcase b/test/sql_stmt_security_tests/writebandtifftfw27.testcase
new file mode 100644
index 0000000..1d9f427
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw27.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - invalid blue band (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, 500, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, 500, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw3.testcase b/test/sql_stmt_security_tests/writebandtifftfw3.testcase
new file mode 100644
index 0000000..0377ece
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw3.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - NULL Width
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', './test.tif', NULL, 1024, 0, 1, 2, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', './test.tif', NULL, 1024, 0, 1, 2, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw4.testcase b/test/sql_stmt_security_tests/writebandtifftfw4.testcase
new file mode 100644
index 0000000..19bb9d1
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw4.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandiffTfw - NULL Height
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, NULL, 0, 1, 2, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, NULL, 0, 1, 2, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw5.testcase b/test/sql_stmt_security_tests/writebandtifftfw5.testcase
new file mode 100644
index 0000000..8c4b774
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw5.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - NULL Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, 2, NULL, 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, 2, NULL, 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw6.testcase b/test/sql_stmt_security_tests/writebandtifftfw6.testcase
new file mode 100644
index 0000000..e0679fc
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw6.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - Invalid BLOB Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, 2, zeroblob(100), 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, 2, zeroblob(100), 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw7.testcase b/test/sql_stmt_security_tests/writebandtifftfw7.testcase
new file mode 100644
index 0000000..758c1f9
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw7.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - NULL resolution
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw8.testcase b/test/sql_stmt_security_tests/writebandtifftfw8.testcase
new file mode 100644
index 0000000..036f317
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw8.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - NULL vertical resolution
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writebandtifftfw9.testcase b/test/sql_stmt_security_tests/writebandtifftfw9.testcase
new file mode 100644
index 0000000..5b9b7e6
--- /dev/null
+++ b/test/sql_stmt_security_tests/writebandtifftfw9.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTripleBandTiffTfw - NULL compression
+:memory: #use in-memory database
+SELECT RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTripleBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writejpegjgw1.testcase b/test/sql_stmt_security_tests/writejpegjgw1.testcase
new file mode 100644
index 0000000..7b733ed
--- /dev/null
+++ b/test/sql_stmt_security_tests/writejpegjgw1.testcase
@@ -0,0 +1,7 @@
+RL2_WriteJpegJgw - NULL Coverage
+:memory: #use in-memory database
+SELECT RL2_WriteJpegJgw(NULL, './test.jpg', 1024, 1024, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteJpegJgw(NULL, './test.jpg', 1024, 1024, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writejpegjgw10.testcase b/test/sql_stmt_security_tests/writejpegjgw10.testcase
new file mode 100644
index 0000000..57644e4
--- /dev/null
+++ b/test/sql_stmt_security_tests/writejpegjgw10.testcase
@@ -0,0 +1,7 @@
+RL2_WriteJpegJgw - invalid width (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteJpegJgw('alpha', './test.jpg', 4, 1024, MakePoint(1, 1), 0.5, 0.5, 80);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteJpegJgw('alpha', './test.jpg', 4, 1024, MakePoint(1, 1), 0.5, 0.5, 80)
+-1
diff --git a/test/sql_stmt_security_tests/writejpegjgw11.testcase b/test/sql_stmt_security_tests/writejpegjgw11.testcase
new file mode 100644
index 0000000..e157a8a
--- /dev/null
+++ b/test/sql_stmt_security_tests/writejpegjgw11.testcase
@@ -0,0 +1,7 @@
+RL2_WriteJpegJgw - invalid width (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteJpegJgw('alpha', './test.jpg', 1000004, 1024, MakePoint(1, 1), 0.5, 0.5, 80);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteJpegJgw('alpha', './test.jpg', 1000004, 1024, MakePoint(1, 1), 0.5, 0.5, 80)
+-1
diff --git a/test/sql_stmt_security_tests/writejpegjgw12.testcase b/test/sql_stmt_security_tests/writejpegjgw12.testcase
new file mode 100644
index 0000000..51abfc7
--- /dev/null
+++ b/test/sql_stmt_security_tests/writejpegjgw12.testcase
@@ -0,0 +1,7 @@
+RL2_WriteJpegJgw - invalid height (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteJpegJgw('alpha', './test.jpg', 1024, 4, MakePoint(1, 1), 0.5, 0.5, 80);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteJpegJgw('alpha', './test.jpg', 1024, 4, MakePoint(1, 1), 0.5, 0.5, 80)
+-1
diff --git a/test/sql_stmt_security_tests/writejpegjgw13.testcase b/test/sql_stmt_security_tests/writejpegjgw13.testcase
new file mode 100644
index 0000000..908faf4
--- /dev/null
+++ b/test/sql_stmt_security_tests/writejpegjgw13.testcase
@@ -0,0 +1,7 @@
+RL2_WriteJpegJgW - invalid height (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteJpegJgw('alpha', './test.jpg', 1024, 1000004, MakePoint(1, 1), 0.5, 0.5, 80);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteJpegJgw('alpha', './test.jpg', 1024, 1000004, MakePoint(1, 1), 0.5, 0.5, 80)
+-1
diff --git a/test/sql_stmt_security_tests/writejpegjgw14.testcase b/test/sql_stmt_security_tests/writejpegjgw14.testcase
new file mode 100644
index 0000000..a3fe55d
--- /dev/null
+++ b/test/sql_stmt_security_tests/writejpegjgw14.testcase
@@ -0,0 +1,7 @@
+RL2_WriteJpegJgw - not existing coverage (1)
+:memory: #use in-memory database
+SELECT RL2_WriteJpegJgw('alpha', './test.jpg', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 101);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteJpegJgw('alpha', './test.jpg', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 101)
+-1
diff --git a/test/sql_stmt_security_tests/writejpegjgw15.testcase b/test/sql_stmt_security_tests/writejpegjgw15.testcase
new file mode 100644
index 0000000..e7c4daf
--- /dev/null
+++ b/test/sql_stmt_security_tests/writejpegjgw15.testcase
@@ -0,0 +1,7 @@
+RL2_WriteJpeg - not existing coverage (2)
+:memory: #use in-memory database
+SELECT RL2_WriteJpeg('alpha', './test.jpg', 1024, 1024, BuildMbr(1, 1, 10, 10), 1, 1, -1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteJpeg('alpha', './test.jpg', 1024, 1024, BuildMbr(1, 1, 10, 10), 1, 1, -1)
+-1
diff --git a/test/sql_stmt_security_tests/writejpegjgw2.testcase b/test/sql_stmt_security_tests/writejpegjgw2.testcase
new file mode 100644
index 0000000..2af2eb3
--- /dev/null
+++ b/test/sql_stmt_security_tests/writejpegjgw2.testcase
@@ -0,0 +1,7 @@
+RL2_WriteJpegJgw - NULL Path
+:memory: #use in-memory database
+SELECT RL2_WriteJpegJgw('alpha', NULL, 1024, 1024, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteJpegJgw('alpha', NULL, 1024, 1024, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writejpegjgw3.testcase b/test/sql_stmt_security_tests/writejpegjgw3.testcase
new file mode 100644
index 0000000..9b68f6b
--- /dev/null
+++ b/test/sql_stmt_security_tests/writejpegjgw3.testcase
@@ -0,0 +1,7 @@
+RL2_WriteJpegJgw - NULL Width
+:memory: #use in-memory database
+SELECT RL2_WriteJpegJgw('alpha', './test.jpg', NULL, 1024, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteJpegJgw('alpha', './test.jpg', NULL, 1024, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writejpegjgw4.testcase b/test/sql_stmt_security_tests/writejpegjgw4.testcase
new file mode 100644
index 0000000..ec32ba9
--- /dev/null
+++ b/test/sql_stmt_security_tests/writejpegjgw4.testcase
@@ -0,0 +1,7 @@
+RL2_WriteJpegJgw - NULL Height
+:memory: #use in-memory database
+SELECT RL2_WriteJpegJgw('alpha', './test.jpg', 1024, NULL, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteJpegJgw('alpha', './test.jpg', 1024, NULL, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writejpegjgw5.testcase b/test/sql_stmt_security_tests/writejpegjgw5.testcase
new file mode 100644
index 0000000..b7502d7
--- /dev/null
+++ b/test/sql_stmt_security_tests/writejpegjgw5.testcase
@@ -0,0 +1,7 @@
+RL2_WriteJpegJgw - NULL Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteJpegJgw('alpha', './test.jpg', 1024, 1024, NULL, 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteJpegJgw('alpha', './test.jpg', 1024, 1024, NULL, 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writejpegjgw6.testcase b/test/sql_stmt_security_tests/writejpegjgw6.testcase
new file mode 100644
index 0000000..57e4f41
--- /dev/null
+++ b/test/sql_stmt_security_tests/writejpegjgw6.testcase
@@ -0,0 +1,7 @@
+RL2_WriteJpegJgw - Invalid BLOB Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteJpegJgw('alpha', './test.jpg', 1024, 1024, zeroblob(100), 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteJpegJgw('alpha', './test.jpg', 1024, 1024, zeroblob(100), 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writejpegjgw7.testcase b/test/sql_stmt_security_tests/writejpegjgw7.testcase
new file mode 100644
index 0000000..11cde6d
--- /dev/null
+++ b/test/sql_stmt_security_tests/writejpegjgw7.testcase
@@ -0,0 +1,7 @@
+RL2_WriteJpegJgw - NULL resolution
+:memory: #use in-memory database
+SELECT RL2_WriteJpegJgw('alpha', './test.jpg', 1024, 1024, MakePoint(1, 1), NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteJpegJgw('alpha', './test.jpg', 1024, 1024, MakePoint(1, 1), NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writejpegjgw8.testcase b/test/sql_stmt_security_tests/writejpegjgw8.testcase
new file mode 100644
index 0000000..c6fac7b
--- /dev/null
+++ b/test/sql_stmt_security_tests/writejpegjgw8.testcase
@@ -0,0 +1,7 @@
+RL2_WriteJpeg - NULL vertical resolution
+:memory: #use in-memory database
+SELECT RL2_WriteJpeg('alpha', './test.jpg', 1024, 1024, MakePoint(1, 1), 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteJpeg('alpha', './test.jpg', 1024, 1024, MakePoint(1, 1), 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writejpegjgw9.testcase b/test/sql_stmt_security_tests/writejpegjgw9.testcase
new file mode 100644
index 0000000..9a3a6b5
--- /dev/null
+++ b/test/sql_stmt_security_tests/writejpegjgw9.testcase
@@ -0,0 +1,7 @@
+RL2_WriteJpegJgw - NULL quality
+:memory: #use in-memory database
+SELECT RL2_WriteJpegJgw('alpha', './test.jpg', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteJpegJgw('alpha', './test.jpg', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writemonotifftfw1.testcase b/test/sql_stmt_security_tests/writemonotifftfw1.testcase
new file mode 100644
index 0000000..6092e1c
--- /dev/null
+++ b/test/sql_stmt_security_tests/writemonotifftfw1.testcase
@@ -0,0 +1,7 @@
+RL2_WriteMonoBandTiffTfw - NULL Coverage
+:memory: #use in-memory database
+SELECT RL2_WriteMonoBandTiffTfw(NULL, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteMonoBandTiffTfw(NULL, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writemonotifftfw10.testcase b/test/sql_stmt_security_tests/writemonotifftfw10.testcase
new file mode 100644
index 0000000..b5e6a0f
--- /dev/null
+++ b/test/sql_stmt_security_tests/writemonotifftfw10.testcase
@@ -0,0 +1,7 @@
+RL2_WriteMonoBandTiffTfw - NULL tile-size
+:memory: #use in-memory database
+SELECT RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'JPEG', NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'JPEG', NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writemonotifftfw11.testcase b/test/sql_stmt_security_tests/writemonotifftfw11.testcase
new file mode 100644
index 0000000..3db7421
--- /dev/null
+++ b/test/sql_stmt_security_tests/writemonotifftfw11.testcase
@@ -0,0 +1,7 @@
+RL2_WriteMonoBandTiffTfw - invalid width (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 4, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'PNG', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 4, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'PNG', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writemonotifftfw12.testcase b/test/sql_stmt_security_tests/writemonotifftfw12.testcase
new file mode 100644
index 0000000..c6ee5f4
--- /dev/null
+++ b/test/sql_stmt_security_tests/writemonotifftfw12.testcase
@@ -0,0 +1,7 @@
+RL2_WriteMonoBandTiffTfw - invalid width (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1000004, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'FAX4', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1000004, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'FAX4', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writemonotifftfw13.testcase b/test/sql_stmt_security_tests/writemonotifftfw13.testcase
new file mode 100644
index 0000000..a00c1a4
--- /dev/null
+++ b/test/sql_stmt_security_tests/writemonotifftfw13.testcase
@@ -0,0 +1,7 @@
+RL2_WriteMonoBandTiffTfw - invalid height (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 4, 0, MakePoint(1, 1), 0.5, 0.5, 'FAX3', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 4, 0, MakePoint(1, 1), 0.5, 0.5, 'FAX3', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writemonotifftfw14.testcase b/test/sql_stmt_security_tests/writemonotifftfw14.testcase
new file mode 100644
index 0000000..31401d2
--- /dev/null
+++ b/test/sql_stmt_security_tests/writemonotifftfw14.testcase
@@ -0,0 +1,7 @@
+RL2_WriteMonoBandTiffTfw - invalid height (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1000004, 0, MakePoint(1, 1), 0.5, 0.5, 'DEFLATE', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1000004, 0, MakePoint(1, 1), 0.5, 0.5, 'DEFLATE', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writemonotifftfw15.testcase b/test/sql_stmt_security_tests/writemonotifftfw15.testcase
new file mode 100644
index 0000000..f17a24c
--- /dev/null
+++ b/test/sql_stmt_security_tests/writemonotifftfw15.testcase
@@ -0,0 +1,7 @@
+RL2_WriteMonoBandTiffTfw - invalid tile-size (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'LZW', 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'LZW', 2)
+-1
diff --git a/test/sql_stmt_security_tests/writemonotifftfw16.testcase b/test/sql_stmt_security_tests/writemonotifftfw16.testcase
new file mode 100644
index 0000000..ca317bb
--- /dev/null
+++ b/test/sql_stmt_security_tests/writemonotifftfw16.testcase
@@ -0,0 +1,7 @@
+RL2_WriteMonoBandTiffTfw - invalid tile-size (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'LZMA', 2000000);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'LZMA', 2000000)
+-1
diff --git a/test/sql_stmt_security_tests/writemonotifftfw17.testcase b/test/sql_stmt_security_tests/writemonotifftfw17.testcase
new file mode 100644
index 0000000..8f1e2e9
--- /dev/null
+++ b/test/sql_stmt_security_tests/writemonotifftfw17.testcase
@@ -0,0 +1,7 @@
+RL2_WriteMonoBandTiffTfw - not existing coverage (1)
+:memory: #use in-memory database
+SELECT RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writemonotifftfw18.testcase b/test/sql_stmt_security_tests/writemonotifftfw18.testcase
new file mode 100644
index 0000000..d9dd36f
--- /dev/null
+++ b/test/sql_stmt_security_tests/writemonotifftfw18.testcase
@@ -0,0 +1,7 @@
+RL2_WriteMonoBandTiffTfw - not existing coverage (2)
+:memory: #use in-memory database
+SELECT RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writemonotifftfw19.testcase b/test/sql_stmt_security_tests/writemonotifftfw19.testcase
new file mode 100644
index 0000000..a18a78d
--- /dev/null
+++ b/test/sql_stmt_security_tests/writemonotifftfw19.testcase
@@ -0,0 +1,7 @@
+RL2_WriteMonoBandTiffTfw - NULL mono band
+:memory: #use in-memory database
+SELECT RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, NULL, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, NULL, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writemonotifftfw2.testcase b/test/sql_stmt_security_tests/writemonotifftfw2.testcase
new file mode 100644
index 0000000..d0801d4
--- /dev/null
+++ b/test/sql_stmt_security_tests/writemonotifftfw2.testcase
@@ -0,0 +1,7 @@
+RL2_WriteMonoBandTiffTfw - NULL Path
+:memory: #use in-memory database
+SELECT RL2_WriteMonoBandTiffTfw('alpha', NULL, 1024, 1024, 0, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteMonoBandTiffTfw('alpha', NULL, 1024, 1024, 0, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writemonotifftfw20.testcase b/test/sql_stmt_security_tests/writemonotifftfw20.testcase
new file mode 100644
index 0000000..27edb05
--- /dev/null
+++ b/test/sql_stmt_security_tests/writemonotifftfw20.testcase
@@ -0,0 +1,7 @@
+RL2_WriteMonoBandTiffTfw - invalid mono band (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, -1, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, -1, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writemonotifftfw21.testcase b/test/sql_stmt_security_tests/writemonotifftfw21.testcase
new file mode 100644
index 0000000..f0a15fd
--- /dev/null
+++ b/test/sql_stmt_security_tests/writemonotifftfw21.testcase
@@ -0,0 +1,7 @@
+RL2_WriteMonoBandTiffTfw - invalid mono band (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, 500, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, 500, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writemonotifftfw3.testcase b/test/sql_stmt_security_tests/writemonotifftfw3.testcase
new file mode 100644
index 0000000..6dfd5e0
--- /dev/null
+++ b/test/sql_stmt_security_tests/writemonotifftfw3.testcase
@@ -0,0 +1,7 @@
+RL2_WriteMonoBandTiffTfw - NULL Width
+:memory: #use in-memory database
+SELECT RL2_WriteMonoBandTiffTfw('alpha', './test.tif', NULL, 1024, 0, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteMonoBandTiffTfw('alpha', './test.tif', NULL, 1024, 0, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writemonotifftfw4.testcase b/test/sql_stmt_security_tests/writemonotifftfw4.testcase
new file mode 100644
index 0000000..96f0f26
--- /dev/null
+++ b/test/sql_stmt_security_tests/writemonotifftfw4.testcase
@@ -0,0 +1,7 @@
+RL2_WriteMonoBandiffTfw - NULL Height
+:memory: #use in-memory database
+SELECT RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, NULL, 0, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, NULL, 0, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writemonotifftfw5.testcase b/test/sql_stmt_security_tests/writemonotifftfw5.testcase
new file mode 100644
index 0000000..5bc71cc
--- /dev/null
+++ b/test/sql_stmt_security_tests/writemonotifftfw5.testcase
@@ -0,0 +1,7 @@
+RL2_WriteMonoBandTiffTfw - NULL Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, NULL, 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, NULL, 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writemonotifftfw6.testcase b/test/sql_stmt_security_tests/writemonotifftfw6.testcase
new file mode 100644
index 0000000..ba48518
--- /dev/null
+++ b/test/sql_stmt_security_tests/writemonotifftfw6.testcase
@@ -0,0 +1,7 @@
+RL2_WriteMonoBandTiffTfw - Invalid BLOB Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, zeroblob(100), 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, zeroblob(100), 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writemonotifftfw7.testcase b/test/sql_stmt_security_tests/writemonotifftfw7.testcase
new file mode 100644
index 0000000..7377b28
--- /dev/null
+++ b/test/sql_stmt_security_tests/writemonotifftfw7.testcase
@@ -0,0 +1,7 @@
+RL2_WriteMonoBandTiffTfw - NULL resolution
+:memory: #use in-memory database
+SELECT RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, MakePoint(1, 1), NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, MakePoint(1, 1), NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writemonotifftfw8.testcase b/test/sql_stmt_security_tests/writemonotifftfw8.testcase
new file mode 100644
index 0000000..2c5c4f1
--- /dev/null
+++ b/test/sql_stmt_security_tests/writemonotifftfw8.testcase
@@ -0,0 +1,7 @@
+RL2_WriteMonoBandTiffTfw - NULL vertical resolution
+:memory: #use in-memory database
+SELECT RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writemonotifftfw9.testcase b/test/sql_stmt_security_tests/writemonotifftfw9.testcase
new file mode 100644
index 0000000..6a9c27a
--- /dev/null
+++ b/test/sql_stmt_security_tests/writemonotifftfw9.testcase
@@ -0,0 +1,7 @@
+RL2_WriteMonoBandTiffTfw - NULL compression
+:memory: #use in-memory database
+SELECT RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteMonoBandTiffTfw('alpha', './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writendviascii1.testcase b/test/sql_stmt_security_tests/writendviascii1.testcase
new file mode 100644
index 0000000..770c66d
--- /dev/null
+++ b/test/sql_stmt_security_tests/writendviascii1.testcase
@@ -0,0 +1,7 @@
+RL2_WriteNdviAsciiGrid - NULL Coverage
+:memory: #use in-memory database
+SELECT RL2_WriteNdviAsciiGrid(NULL, './test.asc', 1024, 1024, 0, 3, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteNdviAsciiGrid(NULL, './test.asc', 1024, 1024, 0, 3, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writendviascii10.testcase b/test/sql_stmt_security_tests/writendviascii10.testcase
new file mode 100644
index 0000000..120fed7
--- /dev/null
+++ b/test/sql_stmt_security_tests/writendviascii10.testcase
@@ -0,0 +1,7 @@
+RL2_WriteNdviAsciiGrid - NULL is-centered
+:memory: #use in-memory database
+SELECT RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, 1024, 0, 3, MakePoint(1, 1), 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, 1024, 0, 3, MakePoint(1, 1), 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writendviascii11.testcase b/test/sql_stmt_security_tests/writendviascii11.testcase
new file mode 100644
index 0000000..3259d04
--- /dev/null
+++ b/test/sql_stmt_security_tests/writendviascii11.testcase
@@ -0,0 +1,7 @@
+RL2_WriteNdviAsciiGrid - NULL decimal-digits
+:memory: #use in-memory database
+SELECT RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, 1024, 0, 3, MakePoint(1, 1), 0.5, 1, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, 1024, 0, 3, MakePoint(1, 1), 0.5, 1, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writendviascii12.testcase b/test/sql_stmt_security_tests/writendviascii12.testcase
new file mode 100644
index 0000000..5a6b41e
--- /dev/null
+++ b/test/sql_stmt_security_tests/writendviascii12.testcase
@@ -0,0 +1,7 @@
+RL2_WriteNdviAsciiGrid - not existing coverage (1)
+:memory: #use in-memory database
+SELECT RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, 1024, 0, 3, MakePoint(1, 1), 0.5, 1, 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, 1024, 0, 3, MakePoint(1, 1), 0.5, 1, 2)
+-1
diff --git a/test/sql_stmt_security_tests/writendviascii13.testcase b/test/sql_stmt_security_tests/writendviascii13.testcase
new file mode 100644
index 0000000..0a51fbc
--- /dev/null
+++ b/test/sql_stmt_security_tests/writendviascii13.testcase
@@ -0,0 +1,7 @@
+RL2_WriteNdviAsciiGrid - not existing coverage (2)
+:memory: #use in-memory database
+SELECT RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, 1024, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, 1024, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, 2)
+-1
diff --git a/test/sql_stmt_security_tests/writendviascii14.testcase b/test/sql_stmt_security_tests/writendviascii14.testcase
new file mode 100644
index 0000000..1d1c914
--- /dev/null
+++ b/test/sql_stmt_security_tests/writendviascii14.testcase
@@ -0,0 +1,7 @@
+RL2_WriteNdviAsciiGrid - invalid width (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteNdviAsciiGrid('alpha', './test.asc', 4, 1024, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteNdviAsciiGrid('alpha', './test.asc', 4, 1024, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, 2)
+-1
diff --git a/test/sql_stmt_security_tests/writendviascii15.testcase b/test/sql_stmt_security_tests/writendviascii15.testcase
new file mode 100644
index 0000000..6348232
--- /dev/null
+++ b/test/sql_stmt_security_tests/writendviascii15.testcase
@@ -0,0 +1,7 @@
+RL2_WriteNdviAsciiGrid - invalid width (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1000004, 1024, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1000004, 1024, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, 2)
+-1
diff --git a/test/sql_stmt_security_tests/writendviascii16.testcase b/test/sql_stmt_security_tests/writendviascii16.testcase
new file mode 100644
index 0000000..9d41f79
--- /dev/null
+++ b/test/sql_stmt_security_tests/writendviascii16.testcase
@@ -0,0 +1,7 @@
+RL2_WriteNdviAsciiGrid - invalid height (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, 1, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, 1, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, 2)
+-1
diff --git a/test/sql_stmt_security_tests/writendviascii17.testcase b/test/sql_stmt_security_tests/writendviascii17.testcase
new file mode 100644
index 0000000..0a6d0a9
--- /dev/null
+++ b/test/sql_stmt_security_tests/writendviascii17.testcase
@@ -0,0 +1,7 @@
+RL2_WriteNdviAsciiGrid - invalid height (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, 1000000, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, 1000000, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, 2)
+-1
diff --git a/test/sql_stmt_security_tests/writendviascii18.testcase b/test/sql_stmt_security_tests/writendviascii18.testcase
new file mode 100644
index 0000000..af8a5ff
--- /dev/null
+++ b/test/sql_stmt_security_tests/writendviascii18.testcase
@@ -0,0 +1,7 @@
+RL2_WriteNdviAsciiGrid - invalid decimal precision (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, 1000000, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, -1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, 1000000, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, -1)
+-1
diff --git a/test/sql_stmt_security_tests/writendviascii2.testcase b/test/sql_stmt_security_tests/writendviascii2.testcase
new file mode 100644
index 0000000..ef23a06
--- /dev/null
+++ b/test/sql_stmt_security_tests/writendviascii2.testcase
@@ -0,0 +1,7 @@
+RL2_WriteNdviAsciiGrid - NULL Path
+:memory: #use in-memory database
+SELECT RL2_WriteNdviAsciiGrid('alpha', NULL, 1024, 1024, 0, 3, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteNdviAsciiGrid('alpha', NULL, 1024, 1024, 0, 3, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writendviascii3.testcase b/test/sql_stmt_security_tests/writendviascii3.testcase
new file mode 100644
index 0000000..f728504
--- /dev/null
+++ b/test/sql_stmt_security_tests/writendviascii3.testcase
@@ -0,0 +1,7 @@
+RL2_WriteNdviAsciiGrid - NULL Width
+:memory: #use in-memory database
+SELECT RL2_WriteNdviAsciiGrid('alpha', './test.asc', NULL, 1024, 0, 3, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteNdviAsciiGrid('alpha', './test.asc', NULL, 1024, 0, 3, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writendviascii4.testcase b/test/sql_stmt_security_tests/writendviascii4.testcase
new file mode 100644
index 0000000..5b82442
--- /dev/null
+++ b/test/sql_stmt_security_tests/writendviascii4.testcase
@@ -0,0 +1,7 @@
+RL2_WriteNdviAsciiGrid - NULL Height
+:memory: #use in-memory database
+SELECT RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, NULL, 0, 3, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, NULL, 0, 3, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writendviascii5.testcase b/test/sql_stmt_security_tests/writendviascii5.testcase
new file mode 100644
index 0000000..59b9f9c
--- /dev/null
+++ b/test/sql_stmt_security_tests/writendviascii5.testcase
@@ -0,0 +1,7 @@
+RL2_WriteNdviAsciiGrid - NULL red band
+:memory: #use in-memory database
+SELECT RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, 1024, NULL, 3, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, 1024, NULL, 3, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writendviascii6.testcase b/test/sql_stmt_security_tests/writendviascii6.testcase
new file mode 100644
index 0000000..6264a94
--- /dev/null
+++ b/test/sql_stmt_security_tests/writendviascii6.testcase
@@ -0,0 +1,7 @@
+RL2_WriteNdviAsciiGrid - NULL NIR band
+:memory: #use in-memory database
+SELECT RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, 1024, 0, NULL, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, 1024, 0, NULL, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writendviascii7.testcase b/test/sql_stmt_security_tests/writendviascii7.testcase
new file mode 100644
index 0000000..3d3e5d7
--- /dev/null
+++ b/test/sql_stmt_security_tests/writendviascii7.testcase
@@ -0,0 +1,7 @@
+RL2_WriteNdviAsciiGrid - NULL Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, 1024, 0, 3, NULL, 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, 1024, 0, 3, NULL, 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writendviascii8.testcase b/test/sql_stmt_security_tests/writendviascii8.testcase
new file mode 100644
index 0000000..acae2ff
--- /dev/null
+++ b/test/sql_stmt_security_tests/writendviascii8.testcase
@@ -0,0 +1,7 @@
+RL2_WriteNdviAsciiGrid - Invalid BLOB Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, 1024, 0, 3, zeroblob(100), 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, 1024, 0, 3, zeroblob(100), 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writendviascii9.testcase b/test/sql_stmt_security_tests/writendviascii9.testcase
new file mode 100644
index 0000000..b31fc67
--- /dev/null
+++ b/test/sql_stmt_security_tests/writendviascii9.testcase
@@ -0,0 +1,7 @@
+RL2_WriteNdviAsciiGrid - NULL resolution
+:memory: #use in-memory database
+SELECT RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, 1024, 0, 3, MakePoint(1, 1), NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteNdviAsciiGrid('alpha', './test.asc', 1024, 1024, 0, 3, MakePoint(1, 1), NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionascii1.testcase b/test/sql_stmt_security_tests/writesectionascii1.testcase
new file mode 100644
index 0000000..1497877
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionascii1.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionAsciiGrid - NULL Coverage
+:memory: #use in-memory database
+SELECT RL2_WriteSectionAsciiGrid(NULL, 1, './test.asc', 1024, 1024, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionAsciiGrid(NULL, 1, './test.asc', 1024, 1024, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionascii10.testcase b/test/sql_stmt_security_tests/writesectionascii10.testcase
new file mode 100644
index 0000000..ce56419
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionascii10.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionAsciiGrid - NULL decimal-digits
+:memory: #use in-memory database
+SELECT RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1024, 1024, MakePoint(1, 1), 0.5, 1, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1024, 1024, MakePoint(1, 1), 0.5, 1, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionascii11.testcase b/test/sql_stmt_security_tests/writesectionascii11.testcase
new file mode 100644
index 0000000..8d66745
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionascii11.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionAsciiGrid - not existing coverage (1)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1024, 1024, MakePoint(1, 1), 0.5, 1, 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1024, 1024, MakePoint(1, 1), 0.5, 1, 2)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionascii12.testcase b/test/sql_stmt_security_tests/writesectionascii12.testcase
new file mode 100644
index 0000000..0a3fba3
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionascii12.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionAsciiGrid - not existing coverage (2)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1024, 1024, BuildMbr(1, 1, 10, 10), 1, 1, 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1024, 1024, BuildMbr(1, 1, 10, 10), 1, 1, 2)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionascii13.testcase b/test/sql_stmt_security_tests/writesectionascii13.testcase
new file mode 100644
index 0000000..a2b042a
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionascii13.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionAsciiGrid - invalid width (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 4, 1024, BuildMbr(1, 1, 10, 10), 1, 1, 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 4, 1024, BuildMbr(1, 1, 10, 10), 1, 1, 2)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionascii14.testcase b/test/sql_stmt_security_tests/writesectionascii14.testcase
new file mode 100644
index 0000000..c8992cf
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionascii14.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionAsciiGrid - invalid width (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1000004, 1024, BuildMbr(1, 1, 10, 10), 1, 1, 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1000004, 1024, BuildMbr(1, 1, 10, 10), 1, 1, 2)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionascii15.testcase b/test/sql_stmt_security_tests/writesectionascii15.testcase
new file mode 100644
index 0000000..162ba43
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionascii15.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionAsciiGrid - invalid height (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1024, 1, BuildMbr(1, 1, 10, 10), 1, 1, 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1024, 1, BuildMbr(1, 1, 10, 10), 1, 1, 2)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionascii16.testcase b/test/sql_stmt_security_tests/writesectionascii16.testcase
new file mode 100644
index 0000000..616157a
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionascii16.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionAsciiGrid - invalid height (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1024, 1000000, BuildMbr(1, 1, 10, 10), 1, 1, 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1024, 1000000, BuildMbr(1, 1, 10, 10), 1, 1, 2)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionascii17.testcase b/test/sql_stmt_security_tests/writesectionascii17.testcase
new file mode 100644
index 0000000..119ef73
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionascii17.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionAsciiGrid - invalid decimal precision (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1024, 1000000, BuildMbr(1, 1, 10, 10), 1, 1, -1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1024, 1000000, BuildMbr(1, 1, 10, 10), 1, 1, -1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionascii18.testcase b/test/sql_stmt_security_tests/writesectionascii18.testcase
new file mode 100644
index 0000000..155c22c
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionascii18.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionAsciiGrid - invalid decimal precision (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1024, 1000000, BuildMbr(1, 1, 10, 10), 1, 1, 50);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1024, 1000000, BuildMbr(1, 1, 10, 10), 1, 1, 50)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionascii2.testcase b/test/sql_stmt_security_tests/writesectionascii2.testcase
new file mode 100644
index 0000000..44aaeee
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionascii2.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionAsciiGrid - NULL Path
+:memory: #use in-memory database
+SELECT RL2_WriteSectionAsciiGrid('alpha', 1, NULL, 1024, 1024, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionAsciiGrid('alpha', 1, NULL, 1024, 1024, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionascii3.testcase b/test/sql_stmt_security_tests/writesectionascii3.testcase
new file mode 100644
index 0000000..2d47697
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionascii3.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionAsciiGrid - NULL Width
+:memory: #use in-memory database
+SELECT RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', NULL, 1024, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', NULL, 1024, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionascii4.testcase b/test/sql_stmt_security_tests/writesectionascii4.testcase
new file mode 100644
index 0000000..64d1646
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionascii4.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionAsciiGrid - NULL Height
+:memory: #use in-memory database
+SELECT RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1024, NULL, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1024, NULL, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionascii5.testcase b/test/sql_stmt_security_tests/writesectionascii5.testcase
new file mode 100644
index 0000000..21f49a7
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionascii5.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionAsciiGrid - NULL Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1024, 1024, NULL, 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1024, 1024, NULL, 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionascii6.testcase b/test/sql_stmt_security_tests/writesectionascii6.testcase
new file mode 100644
index 0000000..91f0fce
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionascii6.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionAsciiGrid - Invalid BLOB Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1024, 1024, zeroblob(100), 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1024, 1024, zeroblob(100), 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionascii7.testcase b/test/sql_stmt_security_tests/writesectionascii7.testcase
new file mode 100644
index 0000000..9e30c40
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionascii7.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionAsciiGrid - NULL resolution
+:memory: #use in-memory database
+SELECT RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1024, 1024, MakePoint(1, 1), NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1024, 1024, MakePoint(1, 1), NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionascii9.testcase b/test/sql_stmt_security_tests/writesectionascii9.testcase
new file mode 100644
index 0000000..6db1a1f
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionascii9.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionAsciiGrid - NULL is-centered
+:memory: #use in-memory database
+SELECT RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1024, 1024, MakePoint(1, 1), 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionAsciiGrid('alpha', 1, './test.asc', 1024, 1024, MakePoint(1, 1), 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff1.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff1.testcase
new file mode 100644
index 0000000..04a7cb9
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff1.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - NULL Coverage
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff(NULL, 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff(NULL, 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff10.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff10.testcase
new file mode 100644
index 0000000..52f41a2
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff10.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - NULL compression
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff11.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff11.testcase
new file mode 100644
index 0000000..d8ae1f6
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff11.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - NULL tile-size
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'JPEG', NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'JPEG', NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff12.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff12.testcase
new file mode 100644
index 0000000..be6c8b8
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff12.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - invalid width (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 4, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'PNG', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 4, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'PNG', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff13.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff13.testcase
new file mode 100644
index 0000000..f65eecd
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff13.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - invalid width (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1000004, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'FAX4', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1000004, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'FAX4', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff14.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff14.testcase
new file mode 100644
index 0000000..f55b666
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff14.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - invalid height (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 4, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'FAX3', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 4, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'FAX3', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff15.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff15.testcase
new file mode 100644
index 0000000..9e3ee3e
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff15.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - invalid height (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1000004, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'DEFLATE', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1000004, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'DEFLATE', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff16.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff16.testcase
new file mode 100644
index 0000000..a107255
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff16.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - invalid tile-size (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'LZW', 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'LZW', 2)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff17.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff17.testcase
new file mode 100644
index 0000000..f2a08f3
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff17.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - invalid tile-size (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'LZMA', 2000000);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'LZMA', 2000000)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff18.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff18.testcase
new file mode 100644
index 0000000..16b2654
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff18.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - not existing coverage (1)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff19.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff19.testcase
new file mode 100644
index 0000000..c4796ff
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff19.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - not existing coverage (2)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 1, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 1, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff2.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff2.testcase
new file mode 100644
index 0000000..8a73555
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff2.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - NULL Path
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, NULL, 1024, 1024, 0, 1, 2, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, NULL, 1024, 1024, 0, 1, 2, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff20.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff20.testcase
new file mode 100644
index 0000000..4e303f6
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff20.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - NULL red band
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, NULL, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, NULL, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff21.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff21.testcase
new file mode 100644
index 0000000..4c7dd39
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff21.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - invalid red band (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, -1, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, -1, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff22.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff22.testcase
new file mode 100644
index 0000000..f5d7974
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff22.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - invalid red band (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 500, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 500, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff23.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff23.testcase
new file mode 100644
index 0000000..7dca896
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff23.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - NULL green band
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, NULL, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, NULL, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff24.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff24.testcase
new file mode 100644
index 0000000..d1e75ef
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff24.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - invalid green band (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, -1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, -1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff25.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff25.testcase
new file mode 100644
index 0000000..3203082
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff25.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - invalid green band (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 500, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 500, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff26.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff26.testcase
new file mode 100644
index 0000000..b22517b
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff26.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - NULL blue band 
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, NULL, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, NULL, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff27.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff27.testcase
new file mode 100644
index 0000000..92dfb30
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff27.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - invalid blue band (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, -1, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, -1, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff28.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff28.testcase
new file mode 100644
index 0000000..cb952e3
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff28.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - invalid blue band (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 500, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 500, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff29.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff29.testcase
new file mode 100644
index 0000000..508fefc
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff29.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - NULL Section
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', NULL, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', NULL, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff3.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff3.testcase
new file mode 100644
index 0000000..44a9399
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff3.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - NULL Width
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', NULL, 1024, 0, 1, 2, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', NULL, 1024, 0, 1, 2, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff4.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff4.testcase
new file mode 100644
index 0000000..1a4403d
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff4.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - NULL Height
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, NULL, 0, 1, 2, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, NULL, 0, 1, 2, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff5.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff5.testcase
new file mode 100644
index 0000000..b60e87e
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff5.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - NULL Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, NULL, 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, NULL, 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff6.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff6.testcase
new file mode 100644
index 0000000..66e21b4
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff6.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - Invalid BLOB Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, zeroblob(100), 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, zeroblob(100), 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff7.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff7.testcase
new file mode 100644
index 0000000..3f9c35d
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff7.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - NULL resolution
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff8.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff8.testcase
new file mode 100644
index 0000000..1d9cd5b
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff8.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - NULL vertical resolution
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandgeotiff9.testcase b/test/sql_stmt_security_tests/writesectionbandgeotiff9.testcase
new file mode 100644
index 0000000..48e07cf
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandgeotiff9.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandGeoTiff - NULL with-worldfile
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 1, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 1, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff1.testcase b/test/sql_stmt_security_tests/writesectionbandtiff1.testcase
new file mode 100644
index 0000000..2fae6d1
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff1.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - NULL Coverage
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff(NULL, 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff(NULL, 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff10.testcase b/test/sql_stmt_security_tests/writesectionbandtiff10.testcase
new file mode 100644
index 0000000..8d8b7f2
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff10.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - NULL tile-size
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'JPEG', NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'JPEG', NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff11.testcase b/test/sql_stmt_security_tests/writesectionbandtiff11.testcase
new file mode 100644
index 0000000..bbb9537
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff11.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - invalid width (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 4, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'PNG', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 4, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'PNG', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff12.testcase b/test/sql_stmt_security_tests/writesectionbandtiff12.testcase
new file mode 100644
index 0000000..90c4810
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff12.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - invalid width (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1000004, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'FAX4', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1000004, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'FAX4', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff13.testcase b/test/sql_stmt_security_tests/writesectionbandtiff13.testcase
new file mode 100644
index 0000000..1d79544
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff13.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - invalid height (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 4, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'FAX3', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 4, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'FAX3', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff14.testcase b/test/sql_stmt_security_tests/writesectionbandtiff14.testcase
new file mode 100644
index 0000000..f8a8ec5
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff14.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - invalid height (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1000004, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'DEFLATE', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1000004, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'DEFLATE', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff15.testcase b/test/sql_stmt_security_tests/writesectionbandtiff15.testcase
new file mode 100644
index 0000000..12af91c
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff15.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - invalid tile-size (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'LZW', 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'LZW', 2)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff16.testcase b/test/sql_stmt_security_tests/writesectionbandtiff16.testcase
new file mode 100644
index 0000000..17d7d74
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff16.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - invalid tile-size (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'LZMA', 2000000);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'LZMA', 2000000)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff17.testcase b/test/sql_stmt_security_tests/writesectionbandtiff17.testcase
new file mode 100644
index 0000000..25decaa
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff17.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - not existing coverage (1)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff18.testcase b/test/sql_stmt_security_tests/writesectionbandtiff18.testcase
new file mode 100644
index 0000000..53fb610
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff18.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - not existing coverage (2)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff19.testcase b/test/sql_stmt_security_tests/writesectionbandtiff19.testcase
new file mode 100644
index 0000000..e7cd248
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff19.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - NULL red band
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, NULL, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, NULL, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff2.testcase b/test/sql_stmt_security_tests/writesectionbandtiff2.testcase
new file mode 100644
index 0000000..b284030
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff2.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - NULL Path
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, NULL, 1024, 1024, 0, 1, 2, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, NULL, 1024, 1024, 0, 1, 2, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff20.testcase b/test/sql_stmt_security_tests/writesectionbandtiff20.testcase
new file mode 100644
index 0000000..02d4e95
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff20.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - invalid red band (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, -1, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, -1, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff21.testcase b/test/sql_stmt_security_tests/writesectionbandtiff21.testcase
new file mode 100644
index 0000000..a8b7990
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff21.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - invalid red band (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 500, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 500, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff22.testcase b/test/sql_stmt_security_tests/writesectionbandtiff22.testcase
new file mode 100644
index 0000000..34206d8
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff22.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - NULL green band
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, NULL, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, NULL, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff23.testcase b/test/sql_stmt_security_tests/writesectionbandtiff23.testcase
new file mode 100644
index 0000000..59cc543
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff23.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - invalid green band (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, -1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, -1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff24.testcase b/test/sql_stmt_security_tests/writesectionbandtiff24.testcase
new file mode 100644
index 0000000..16960b9
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff24.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - invalid green band (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 500, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 500, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff25.testcase b/test/sql_stmt_security_tests/writesectionbandtiff25.testcase
new file mode 100644
index 0000000..88f0839
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff25.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - NULL blue band 
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, NULL, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, NULL, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff26.testcase b/test/sql_stmt_security_tests/writesectionbandtiff26.testcase
new file mode 100644
index 0000000..273bd00
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff26.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - invalid blue band (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, -1, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, -1, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff27.testcase b/test/sql_stmt_security_tests/writesectionbandtiff27.testcase
new file mode 100644
index 0000000..88d93c1
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff27.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - invalid blue band (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 500, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 500, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff28.testcase b/test/sql_stmt_security_tests/writesectionbandtiff28.testcase
new file mode 100644
index 0000000..9ad37b4
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff28.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - NULL Section
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', NULL, './test.tif', 1024, 1024, 0, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', NULL, './test.tif', 1024, 1024, 0, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff3.testcase b/test/sql_stmt_security_tests/writesectionbandtiff3.testcase
new file mode 100644
index 0000000..4aca6cd
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff3.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - NULL Width
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', NULL, 1024, 0, 1, 2, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', NULL, 1024, 0, 1, 2, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff4.testcase b/test/sql_stmt_security_tests/writesectionbandtiff4.testcase
new file mode 100644
index 0000000..93fdd86
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff4.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandiff - NULL Height
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, NULL, 0, 1, 2, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, NULL, 0, 1, 2, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff5.testcase b/test/sql_stmt_security_tests/writesectionbandtiff5.testcase
new file mode 100644
index 0000000..887298f
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff5.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - NULL Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, NULL, 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, NULL, 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff6.testcase b/test/sql_stmt_security_tests/writesectionbandtiff6.testcase
new file mode 100644
index 0000000..81ae5d4
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff6.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - Invalid BLOB Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, zeroblob(100), 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, zeroblob(100), 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff7.testcase b/test/sql_stmt_security_tests/writesectionbandtiff7.testcase
new file mode 100644
index 0000000..210138a
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff7.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - NULL resolution
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff8.testcase b/test/sql_stmt_security_tests/writesectionbandtiff8.testcase
new file mode 100644
index 0000000..62627e3
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff8.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - NULL vertical resolution
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtiff9.testcase b/test/sql_stmt_security_tests/writesectionbandtiff9.testcase
new file mode 100644
index 0000000..efa8f41
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtiff9.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiff - NULL compression
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw1.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw1.testcase
new file mode 100644
index 0000000..b32be16
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw1.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - NULL Coverage
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw(NULL, 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw(NULL, 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw10.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw10.testcase
new file mode 100644
index 0000000..38a6506
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw10.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - NULL tile-size
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'JPEG', NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'JPEG', NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw11.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw11.testcase
new file mode 100644
index 0000000..0b203d9
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw11.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - invalid width (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 4, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'PNG', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 4, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'PNG', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw12.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw12.testcase
new file mode 100644
index 0000000..bcdb582
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw12.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - invalid width (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1000004, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'FAX4', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1000004, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'FAX4', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw13.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw13.testcase
new file mode 100644
index 0000000..b77e548
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw13.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - invalid height (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 4, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'FAX3', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 4, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'FAX3', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw14.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw14.testcase
new file mode 100644
index 0000000..a857959
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw14.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - invalid height (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1000004, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'DEFLATE', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1000004, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'DEFLATE', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw15.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw15.testcase
new file mode 100644
index 0000000..374e048
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw15.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - invalid tile-size (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'LZW', 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'LZW', 2)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw16.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw16.testcase
new file mode 100644
index 0000000..fa884f4
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw16.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - invalid tile-size (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'LZMA', 2000000);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'LZMA', 2000000)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw17.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw17.testcase
new file mode 100644
index 0000000..0bc499d
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw17.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - not existing coverage (1)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw18.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw18.testcase
new file mode 100644
index 0000000..96c4901
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw18.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - not existing coverage (2)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw19.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw19.testcase
new file mode 100644
index 0000000..6d54347
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw19.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - NULL red band
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, NULL, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, NULL, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw2.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw2.testcase
new file mode 100644
index 0000000..e69238f
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw2.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - NULL Path
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, NULL, 1024, 1024, 0, 1, 2, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, NULL, 1024, 1024, 0, 1, 2, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw20.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw20.testcase
new file mode 100644
index 0000000..410a850
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw20.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - invalid red band (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, -1, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, -1, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw21.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw21.testcase
new file mode 100644
index 0000000..dea28b8
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw21.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - invalid red band (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 500, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 500, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw22.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw22.testcase
new file mode 100644
index 0000000..70ff23a
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw22.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - NULL green band
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, NULL, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, NULL, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw23.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw23.testcase
new file mode 100644
index 0000000..ff93ad3
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw23.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - invalid green band (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, -1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, -1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw24.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw24.testcase
new file mode 100644
index 0000000..9dfafe7
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw24.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - invalid green band (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 500, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 500, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw25.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw25.testcase
new file mode 100644
index 0000000..408beeb
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw25.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - NULL blue band 
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, NULL, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, NULL, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw26.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw26.testcase
new file mode 100644
index 0000000..f21b9ac
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw26.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - invalid blue band (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, -1, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, -1, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw27.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw27.testcase
new file mode 100644
index 0000000..023dcab
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw27.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - invalid blue band (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, 500, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, 500, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw28.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw28.testcase
new file mode 100644
index 0000000..b9c85e0
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw28.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - NULL Section
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', NULL, './test.tif', 1024, 1024, 0, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', NULL, './test.tif', 1024, 1024, 0, 1, 2, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw3.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw3.testcase
new file mode 100644
index 0000000..e01745e
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw3.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - NULL Width
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', NULL, 1024, 0, 1, 2, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', NULL, 1024, 0, 1, 2, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw4.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw4.testcase
new file mode 100644
index 0000000..25a51d4
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw4.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - NULL Height
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, NULL, 0, 1, 2, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, NULL, 0, 1, 2, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw5.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw5.testcase
new file mode 100644
index 0000000..94cc4c3
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw5.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - NULL Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, NULL, 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, NULL, 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw6.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw6.testcase
new file mode 100644
index 0000000..cf5be3d
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw6.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - Invalid BLOB Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, zeroblob(100), 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, zeroblob(100), 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw7.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw7.testcase
new file mode 100644
index 0000000..420f03b
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw7.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - NULL resolution
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw8.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw8.testcase
new file mode 100644
index 0000000..6064b10
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw8.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - NULL vertical resolution
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionbandtifftfw9.testcase b/test/sql_stmt_security_tests/writesectionbandtifftfw9.testcase
new file mode 100644
index 0000000..ca83527
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionbandtifftfw9.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTripleBandTiffTfw - NULL compression
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTripleBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, 1, 2, MakePoint(1, 1), 0.5, 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiongeotiff1.testcase b/test/sql_stmt_security_tests/writesectiongeotiff1.testcase
new file mode 100644
index 0000000..0d306f1
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiongeotiff1.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionGeoTiff - NULL Coverage
+:memory: #use in-memory database
+SELECT RL2_WriteSectionGeoTiff(NULL, 1, './test.tif', 1024, 1024, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionGeoTiff(NULL, 1, './test.tif', 1024, 1024, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiongeotiff10.testcase b/test/sql_stmt_security_tests/writesectiongeotiff10.testcase
new file mode 100644
index 0000000..a5f0abf
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiongeotiff10.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionGeoTiff - NULL compression
+:memory: #use in-memory database
+SELECT RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 1, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 1, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiongeotiff11.testcase b/test/sql_stmt_security_tests/writesectiongeotiff11.testcase
new file mode 100644
index 0000000..dfa6bd5
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiongeotiff11.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionGeoTiff - NULL tile-size
+:memory: #use in-memory database
+SELECT RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 1, 'JPEG', NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 1, 'JPEG', NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiongeotiff12.testcase b/test/sql_stmt_security_tests/writesectiongeotiff12.testcase
new file mode 100644
index 0000000..8c27c9b
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiongeotiff12.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionGeoTiff - invalid width (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 4, 1024, MakePoint(1, 1), 0.5, 0.5, 1, 'PNG', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 4, 1024, MakePoint(1, 1), 0.5, 0.5, 1, 'PNG', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiongeotiff13.testcase b/test/sql_stmt_security_tests/writesectiongeotiff13.testcase
new file mode 100644
index 0000000..2a022bd
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiongeotiff13.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionGeoTiff - invalid width (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1000004, 1024, MakePoint(1, 1), 0.5, 0.5, 1, 'FAX4', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1000004, 1024, MakePoint(1, 1), 0.5, 0.5, 1, 'FAX4', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiongeotiff14.testcase b/test/sql_stmt_security_tests/writesectiongeotiff14.testcase
new file mode 100644
index 0000000..5302e7c
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiongeotiff14.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionGeoTiff - invalid height (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 4, MakePoint(1, 1), 0.5, 0.5, 1, 'FAX3', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 4, MakePoint(1, 1), 0.5, 0.5, 1, 'FAX3', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiongeotiff15.testcase b/test/sql_stmt_security_tests/writesectiongeotiff15.testcase
new file mode 100644
index 0000000..fa7d7c5
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiongeotiff15.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionGeoTiff - invalid height (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 1000004, MakePoint(1, 1), 0.5, 0.5, 1, 'DEFLATE', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 1000004, MakePoint(1, 1), 0.5, 0.5, 1, 'DEFLATE', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiongeotiff16.testcase b/test/sql_stmt_security_tests/writesectiongeotiff16.testcase
new file mode 100644
index 0000000..049b01a
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiongeotiff16.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionGeoTiff - invalid tile-size (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 1, 'LZW', 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 1, 'LZW', 2)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiongeotiff17.testcase b/test/sql_stmt_security_tests/writesectiongeotiff17.testcase
new file mode 100644
index 0000000..947215d
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiongeotiff17.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionGeoTiff - invalid tile-size (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 1, 'LZMA', 2000000);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 1, 'LZMA', 2000000)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiongeotiff18.testcase b/test/sql_stmt_security_tests/writesectiongeotiff18.testcase
new file mode 100644
index 0000000..3e48289
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiongeotiff18.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionGeoTiff - not existing coverage (1)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiongeotiff19.testcase b/test/sql_stmt_security_tests/writesectiongeotiff19.testcase
new file mode 100644
index 0000000..3247de6
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiongeotiff19.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionGeoTiff - not existing coverage (2)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 1024, BuildMbr(1, 1, 10, 10), 1, 1, 1, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 1024, BuildMbr(1, 1, 10, 10), 1, 1, 1, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiongeotiff2.testcase b/test/sql_stmt_security_tests/writesectiongeotiff2.testcase
new file mode 100644
index 0000000..42dcaa9
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiongeotiff2.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionGeoTiff - NULL Path
+:memory: #use in-memory database
+SELECT RL2_WriteSectionGeoTiff('alpha', 1, NULL, 1024, 1024, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionGeoTiff('alpha', 1, NULL, 1024, 1024, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiongeotiff20.testcase b/test/sql_stmt_security_tests/writesectiongeotiff20.testcase
new file mode 100644
index 0000000..cd7f7e8
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiongeotiff20.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionGeoTiff - NULL section
+:memory: #use in-memory database
+SELECT RL2_WriteSectionGeoTiff('alpha', NULL, './test.tif', 1024, 1024, BuildMbr(1, 1, 10, 10), 1, 1, 1, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionGeoTiff('alpha', NULL, './test.tif', 1024, 1024, BuildMbr(1, 1, 10, 10), 1, 1, 1, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiongeotiff3.testcase b/test/sql_stmt_security_tests/writesectiongeotiff3.testcase
new file mode 100644
index 0000000..e7f12a1
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiongeotiff3.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionGeoTiff - NULL Width
+:memory: #use in-memory database
+SELECT RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', NULL, 1024, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', NULL, 1024, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiongeotiff4.testcase b/test/sql_stmt_security_tests/writesectiongeotiff4.testcase
new file mode 100644
index 0000000..e17c860
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiongeotiff4.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionGeoTiff - NULL Height
+:memory: #use in-memory database
+SELECT RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, NULL, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, NULL, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiongeotiff5.testcase b/test/sql_stmt_security_tests/writesectiongeotiff5.testcase
new file mode 100644
index 0000000..25632c0
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiongeotiff5.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionGeoTiff - NULL Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 1024, NULL, 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 1024, NULL, 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiongeotiff6.testcase b/test/sql_stmt_security_tests/writesectiongeotiff6.testcase
new file mode 100644
index 0000000..bb28783
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiongeotiff6.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionGeoTiff - Invalid BLOB Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 1024, zeroblob(100), 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 1024, zeroblob(100), 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiongeotiff7.testcase b/test/sql_stmt_security_tests/writesectiongeotiff7.testcase
new file mode 100644
index 0000000..8cd1404
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiongeotiff7.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionGeoTiff - NULL resolution
+:memory: #use in-memory database
+SELECT RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiongeotiff8.testcase b/test/sql_stmt_security_tests/writesectiongeotiff8.testcase
new file mode 100644
index 0000000..1b47f69
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiongeotiff8.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionGeoTiff - NULL vertical resolution
+:memory: #use in-memory database
+SELECT RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiongeotiff9.testcase b/test/sql_stmt_security_tests/writesectiongeotiff9.testcase
new file mode 100644
index 0000000..6374d93
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiongeotiff9.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionGeoTiff - NULL with-worldfile
+:memory: #use in-memory database
+SELECT RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 1, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionGeoTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 1, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpeg1.testcase b/test/sql_stmt_security_tests/writesectionjpeg1.testcase
new file mode 100644
index 0000000..bd92c11
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpeg1.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpeg - NULL Coverage
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpeg(NULL, 1, './test.jpg', 1024, 1024, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpeg(NULL, 1, './test.jpg', 1024, 1024, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpeg10.testcase b/test/sql_stmt_security_tests/writesectionjpeg10.testcase
new file mode 100644
index 0000000..e5a9a4a
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpeg10.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpeg - invalid width (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 4, 1024, MakePoint(1, 1), 0.5, 0.5, 80);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 4, 1024, MakePoint(1, 1), 0.5, 0.5, 80)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpeg11.testcase b/test/sql_stmt_security_tests/writesectionjpeg11.testcase
new file mode 100644
index 0000000..d46ded3
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpeg11.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpeg - invalid width (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1000004, 1024, MakePoint(1, 1), 0.5, 0.5, 80);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1000004, 1024, MakePoint(1, 1), 0.5, 0.5, 80)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpeg12.testcase b/test/sql_stmt_security_tests/writesectionjpeg12.testcase
new file mode 100644
index 0000000..212dc9f
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpeg12.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpeg - invalid height (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1024, 4, MakePoint(1, 1), 0.5, 0.5, 80);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1024, 4, MakePoint(1, 1), 0.5, 0.5, 80)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpeg13.testcase b/test/sql_stmt_security_tests/writesectionjpeg13.testcase
new file mode 100644
index 0000000..afda1f6
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpeg13.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpeg - invalid height (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1024, 1000004, MakePoint(1, 1), 0.5, 0.5, 80);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1024, 1000004, MakePoint(1, 1), 0.5, 0.5, 80)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpeg14.testcase b/test/sql_stmt_security_tests/writesectionjpeg14.testcase
new file mode 100644
index 0000000..c557c86
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpeg14.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpeg - not existing coverage (1)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 101);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 101)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpeg15.testcase b/test/sql_stmt_security_tests/writesectionjpeg15.testcase
new file mode 100644
index 0000000..0ed3f47
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpeg15.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpeg - not existing coverage (2)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1024, 1024, BuildMbr(1, 1, 10, 10), 1, 1, -1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1024, 1024, BuildMbr(1, 1, 10, 10), 1, 1, -1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpeg16.testcase b/test/sql_stmt_security_tests/writesectionjpeg16.testcase
new file mode 100644
index 0000000..3a2f319
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpeg16.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpeg - NULL Section
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpeg('alpha', NULL, './test.jpg', 1024, 1024, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpeg('alpha', NULL, './test.jpg', 1024, 1024, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpeg2.testcase b/test/sql_stmt_security_tests/writesectionjpeg2.testcase
new file mode 100644
index 0000000..baedda4
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpeg2.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpeg - NULL Path
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpeg('alpha', 1, NULL, 1024, 1024, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpeg('alpha', 1, NULL, 1024, 1024, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpeg3.testcase b/test/sql_stmt_security_tests/writesectionjpeg3.testcase
new file mode 100644
index 0000000..dfb984f
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpeg3.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpeg - NULL Width
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpeg('alpha', 1, './test.jpg', NULL, 1024, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpeg('alpha', 1, './test.jpg', NULL, 1024, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpeg4.testcase b/test/sql_stmt_security_tests/writesectionjpeg4.testcase
new file mode 100644
index 0000000..c4967ca
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpeg4.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpeg - NULL Height
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1024, NULL, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1024, NULL, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpeg5.testcase b/test/sql_stmt_security_tests/writesectionjpeg5.testcase
new file mode 100644
index 0000000..1fe3133
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpeg5.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpeg - NULL Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1024, 1024, NULL, 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1024, 1024, NULL, 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpeg6.testcase b/test/sql_stmt_security_tests/writesectionjpeg6.testcase
new file mode 100644
index 0000000..853327e
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpeg6.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpeg - Invalid BLOB Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1024, 1024, zeroblob(100), 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1024, 1024, zeroblob(100), 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpeg7.testcase b/test/sql_stmt_security_tests/writesectionjpeg7.testcase
new file mode 100644
index 0000000..1bcdfdd
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpeg7.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpeg - NULL resolution
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1024, 1024, MakePoint(1, 1), NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1024, 1024, MakePoint(1, 1), NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpeg8.testcase b/test/sql_stmt_security_tests/writesectionjpeg8.testcase
new file mode 100644
index 0000000..79db84d
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpeg8.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpeg - NULL vertical resolution
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1024, 1024, MakePoint(1, 1), 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1024, 1024, MakePoint(1, 1), 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpeg9.testcase b/test/sql_stmt_security_tests/writesectionjpeg9.testcase
new file mode 100644
index 0000000..e59bd18
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpeg9.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpeg - NULL quality
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpegjgw1.testcase b/test/sql_stmt_security_tests/writesectionjpegjgw1.testcase
new file mode 100644
index 0000000..ff9b6ae
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpegjgw1.testcase
@@ -0,0 +1,7 @@
+RL2_WriteJpegJgw - NULL Coverage
+:memory: #use in-memory database
+SELECT RL2_WriteJpegJgw(NULL, 1, './test.jpg', 1024, 1024, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteJpegJgw(NULL, 1, './test.jpg', 1024, 1024, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpegjgw10.testcase b/test/sql_stmt_security_tests/writesectionjpegjgw10.testcase
new file mode 100644
index 0000000..62b01a9
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpegjgw10.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpegJgw - invalid width (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpegJgw('alpha', 1, './test.jpg', 4, 1024, MakePoint(1, 1), 0.5, 0.5, 80);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpegJgw('alpha', 1, './test.jpg', 4, 1024, MakePoint(1, 1), 0.5, 0.5, 80)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpegjgw11.testcase b/test/sql_stmt_security_tests/writesectionjpegjgw11.testcase
new file mode 100644
index 0000000..2e32f19
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpegjgw11.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpegJgw - invalid width (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpegJgw('alpha', 1, './test.jpg', 1000004, 1024, MakePoint(1, 1), 0.5, 0.5, 80);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpegJgw('alpha', 1, './test.jpg', 1000004, 1024, MakePoint(1, 1), 0.5, 0.5, 80)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpegjgw12.testcase b/test/sql_stmt_security_tests/writesectionjpegjgw12.testcase
new file mode 100644
index 0000000..9b01345
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpegjgw12.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpegJgw - invalid height (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpegJgw('alpha', 1, './test.jpg', 1024, 4, MakePoint(1, 1), 0.5, 0.5, 80);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpegJgw('alpha', 1, './test.jpg', 1024, 4, MakePoint(1, 1), 0.5, 0.5, 80)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpegjgw13.testcase b/test/sql_stmt_security_tests/writesectionjpegjgw13.testcase
new file mode 100644
index 0000000..b14efed
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpegjgw13.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpegJgW - invalid height (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpegJgw('alpha', 1, './test.jpg', 1024, 1000004, MakePoint(1, 1), 0.5, 0.5, 80);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpegJgw('alpha', 1, './test.jpg', 1024, 1000004, MakePoint(1, 1), 0.5, 0.5, 80)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpegjgw14.testcase b/test/sql_stmt_security_tests/writesectionjpegjgw14.testcase
new file mode 100644
index 0000000..eb2af8b
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpegjgw14.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpegJgw - not existing coverage (1)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpegJgw('alpha', 1, './test.jpg', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 101);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpegJgw('alpha', 1, './test.jpg', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 101)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpegjgw15.testcase b/test/sql_stmt_security_tests/writesectionjpegjgw15.testcase
new file mode 100644
index 0000000..0ed3f47
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpegjgw15.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpeg - not existing coverage (2)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1024, 1024, BuildMbr(1, 1, 10, 10), 1, 1, -1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1024, 1024, BuildMbr(1, 1, 10, 10), 1, 1, -1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpegjgw16.testcase b/test/sql_stmt_security_tests/writesectionjpegjgw16.testcase
new file mode 100644
index 0000000..455ec0b
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpegjgw16.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpeg - NULL Section
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpeg('alpha', NULL, './test.jpg', 1024, 1024, BuildMbr(1, 1, 10, 10), 1, 1, -1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpeg('alpha', NULL, './test.jpg', 1024, 1024, BuildMbr(1, 1, 10, 10), 1, 1, -1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpegjgw2.testcase b/test/sql_stmt_security_tests/writesectionjpegjgw2.testcase
new file mode 100644
index 0000000..c89f323
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpegjgw2.testcase
@@ -0,0 +1,7 @@
+RL2_WriteJpegJgw - NULL Path
+:memory: #use in-memory database
+SELECT RL2_WriteJpegJgw('alpha', 1, NULL, 1024, 1024, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteJpegJgw('alpha', 1, NULL, 1024, 1024, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpegjgw3.testcase b/test/sql_stmt_security_tests/writesectionjpegjgw3.testcase
new file mode 100644
index 0000000..2b43ea5
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpegjgw3.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpegJgw - NULL Width
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpegJgw('alpha', 1, './test.jpg', NULL, 1024, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpegJgw('alpha', 1, './test.jpg', NULL, 1024, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpegjgw4.testcase b/test/sql_stmt_security_tests/writesectionjpegjgw4.testcase
new file mode 100644
index 0000000..c8bca36
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpegjgw4.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpegJgw - NULL Height
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpegJgw('alpha', 1, './test.jpg', 1024, NULL, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpegJgw('alpha', 1, './test.jpg', 1024, NULL, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpegjgw5.testcase b/test/sql_stmt_security_tests/writesectionjpegjgw5.testcase
new file mode 100644
index 0000000..f26116a
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpegjgw5.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpegJgw - NULL Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpegJgw('alpha', 1, './test.jpg', 1024, 1024, NULL, 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpegJgw('alpha', 1, './test.jpg', 1024, 1024, NULL, 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpegjgw6.testcase b/test/sql_stmt_security_tests/writesectionjpegjgw6.testcase
new file mode 100644
index 0000000..d502fb1
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpegjgw6.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpegJgw - Invalid BLOB Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpegJgw('alpha', 1, './test.jpg', 1024, 1024, zeroblob(100), 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpegJgw('alpha', 1, './test.jpg', 1024, 1024, zeroblob(100), 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpegjgw7.testcase b/test/sql_stmt_security_tests/writesectionjpegjgw7.testcase
new file mode 100644
index 0000000..a35825d
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpegjgw7.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpegJgw - NULL resolution
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpegJgw('alpha', 1, './test.jpg', 1024, 1024, MakePoint(1, 1), NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpegJgw('alpha', 1, './test.jpg', 1024, 1024, MakePoint(1, 1), NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpegjgw8.testcase b/test/sql_stmt_security_tests/writesectionjpegjgw8.testcase
new file mode 100644
index 0000000..79db84d
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpegjgw8.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpeg - NULL vertical resolution
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1024, 1024, MakePoint(1, 1), 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpeg('alpha', 1, './test.jpg', 1024, 1024, MakePoint(1, 1), 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionjpegjgw9.testcase b/test/sql_stmt_security_tests/writesectionjpegjgw9.testcase
new file mode 100644
index 0000000..9769ffd
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionjpegjgw9.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionJpegJgw - NULL quality
+:memory: #use in-memory database
+SELECT RL2_WriteSectionJpegJgw('alpha', 1, './test.jpg', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionJpegJgw('alpha', 1, './test.jpg', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonogeotiff1.testcase b/test/sql_stmt_security_tests/writesectionmonogeotiff1.testcase
new file mode 100644
index 0000000..5acbc9a
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonogeotiff1.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandGeoTiff - NULL Coverage
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandGeoTiff(NULL, 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandGeoTiff(NULL, 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonogeotiff10.testcase b/test/sql_stmt_security_tests/writesectionmonogeotiff10.testcase
new file mode 100644
index 0000000..9d9a7c2
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonogeotiff10.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandGeoTiff - NULL compression
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 1, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 1, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonogeotiff11.testcase b/test/sql_stmt_security_tests/writesectionmonogeotiff11.testcase
new file mode 100644
index 0000000..bcc3d9d
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonogeotiff11.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandGeoTiff - NULL tile-size
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 1, 'JPEG', NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 1, 'JPEG', NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonogeotiff12.testcase b/test/sql_stmt_security_tests/writesectionmonogeotiff12.testcase
new file mode 100644
index 0000000..926fe2f
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonogeotiff12.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandGeoTiff - invalid width (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 4, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 1, 'PNG', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 4, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 1, 'PNG', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonogeotiff13.testcase b/test/sql_stmt_security_tests/writesectionmonogeotiff13.testcase
new file mode 100644
index 0000000..23d72ee
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonogeotiff13.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandGeoTiff - invalid width (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1000004, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 1, 'FAX4', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1000004, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 1, 'FAX4', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonogeotiff14.testcase b/test/sql_stmt_security_tests/writesectionmonogeotiff14.testcase
new file mode 100644
index 0000000..7307560
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonogeotiff14.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandGeoTiff - invalid height (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 4, 0, MakePoint(1, 1), 0.5, 0.5, 1, 'FAX3', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 4, 0, MakePoint(1, 1), 0.5, 0.5, 1, 'FAX3', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonogeotiff15.testcase b/test/sql_stmt_security_tests/writesectionmonogeotiff15.testcase
new file mode 100644
index 0000000..2c9dd44
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonogeotiff15.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandGeoTiff - invalid height (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1000004, 0, MakePoint(1, 1), 0.5, 0.5, 1, 'DEFLATE', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1000004, 0, MakePoint(1, 1), 0.5, 0.5, 1, 'DEFLATE', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonogeotiff16.testcase b/test/sql_stmt_security_tests/writesectionmonogeotiff16.testcase
new file mode 100644
index 0000000..fd5c4b7
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonogeotiff16.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandGeoTiff - invalid tile-size (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 1, 'LZW', 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 1, 'LZW', 2)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonogeotiff17.testcase b/test/sql_stmt_security_tests/writesectionmonogeotiff17.testcase
new file mode 100644
index 0000000..49032b6
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonogeotiff17.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandGeoTiff - invalid tile-size (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 1, 'LZMA', 2000000);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 1, 'LZMA', 2000000)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonogeotiff18.testcase b/test/sql_stmt_security_tests/writesectionmonogeotiff18.testcase
new file mode 100644
index 0000000..1b21da1
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonogeotiff18.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandGeoTiff - not existing coverage (1)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonogeotiff19.testcase b/test/sql_stmt_security_tests/writesectionmonogeotiff19.testcase
new file mode 100644
index 0000000..1da008d
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonogeotiff19.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandGeoTiff - not existing coverage (2)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, BuildMbr(1, 1, 10, 10), 1, 1, 1, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, BuildMbr(1, 1, 10, 10), 1, 1, 1, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonogeotiff2.testcase b/test/sql_stmt_security_tests/writesectionmonogeotiff2.testcase
new file mode 100644
index 0000000..b55fcd2
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonogeotiff2.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandGeoTiff - NULL Path
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandGeoTiff('alpha', 1, NULL, 1024, 1024, 0, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandGeoTiff('alpha', 1, NULL, 1024, 1024, 0, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonogeotiff20.testcase b/test/sql_stmt_security_tests/writesectionmonogeotiff20.testcase
new file mode 100644
index 0000000..b277970
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonogeotiff20.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandGeoTiff - NULL mono band
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, NULL, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, NULL, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonogeotiff21.testcase b/test/sql_stmt_security_tests/writesectionmonogeotiff21.testcase
new file mode 100644
index 0000000..eaec76e
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonogeotiff21.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandGeoTiff - invalid mono band (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, -1, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, -1, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonogeotiff22.testcase b/test/sql_stmt_security_tests/writesectionmonogeotiff22.testcase
new file mode 100644
index 0000000..16c3cf0
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonogeotiff22.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandGeoTiff - invalid mono band (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 500, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 500, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonogeotiff23.testcase b/test/sql_stmt_security_tests/writesectionmonogeotiff23.testcase
new file mode 100644
index 0000000..323f760
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonogeotiff23.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandGeoTiff - NULL Section
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandGeoTiff('alpha', NULL, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandGeoTiff('alpha', NULL, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 1, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonogeotiff3.testcase b/test/sql_stmt_security_tests/writesectionmonogeotiff3.testcase
new file mode 100644
index 0000000..109a647
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonogeotiff3.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandGeoTiff - NULL Width
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', NULL, 1024, 0, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', NULL, 1024, 0, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonogeotiff4.testcase b/test/sql_stmt_security_tests/writesectionmonogeotiff4.testcase
new file mode 100644
index 0000000..87d8cb2
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonogeotiff4.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandGeoTiff - NULL Height
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, NULL, 0, 1, 2, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, NULL, 0, 1, 2, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonogeotiff5.testcase b/test/sql_stmt_security_tests/writesectionmonogeotiff5.testcase
new file mode 100644
index 0000000..8fbf3b9
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonogeotiff5.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandGeoTiff - NULL Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, NULL, 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, NULL, 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonogeotiff6.testcase b/test/sql_stmt_security_tests/writesectionmonogeotiff6.testcase
new file mode 100644
index 0000000..227755e
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonogeotiff6.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandGeoTiff - Invalid BLOB Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, zeroblob(100), 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, zeroblob(100), 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonogeotiff7.testcase b/test/sql_stmt_security_tests/writesectionmonogeotiff7.testcase
new file mode 100644
index 0000000..3e3d9f4
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonogeotiff7.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandGeoTiff - NULL resolution
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonogeotiff8.testcase b/test/sql_stmt_security_tests/writesectionmonogeotiff8.testcase
new file mode 100644
index 0000000..32cd7c6
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonogeotiff8.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandGeoTiff - NULL vertical resolution
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonogeotiff9.testcase b/test/sql_stmt_security_tests/writesectionmonogeotiff9.testcase
new file mode 100644
index 0000000..976e985
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonogeotiff9.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandGeoTiff - NULL with-worldfile
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 1, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandGeoTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 1, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotiff1.testcase b/test/sql_stmt_security_tests/writesectionmonotiff1.testcase
new file mode 100644
index 0000000..e6f5ec7
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotiff1.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiff - NULL Coverage
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiff(NULL, 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiff(NULL, 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotiff10.testcase b/test/sql_stmt_security_tests/writesectionmonotiff10.testcase
new file mode 100644
index 0000000..f21266f
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotiff10.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiff - NULL tile-size
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'JPEG', NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'JPEG', NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotiff11.testcase b/test/sql_stmt_security_tests/writesectionmonotiff11.testcase
new file mode 100644
index 0000000..495ae3f
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotiff11.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiff - invalid width (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 4, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'PNG', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 4, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'PNG', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotiff12.testcase b/test/sql_stmt_security_tests/writesectionmonotiff12.testcase
new file mode 100644
index 0000000..c8e9128
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotiff12.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiff - invalid width (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1000004, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'FAX4', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1000004, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'FAX4', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotiff13.testcase b/test/sql_stmt_security_tests/writesectionmonotiff13.testcase
new file mode 100644
index 0000000..2da6b28
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotiff13.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiff - invalid height (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 4, 0, MakePoint(1, 1), 0.5, 0.5, 'FAX3', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 4, 0, MakePoint(1, 1), 0.5, 0.5, 'FAX3', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotiff14.testcase b/test/sql_stmt_security_tests/writesectionmonotiff14.testcase
new file mode 100644
index 0000000..b353bb1
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotiff14.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiff - invalid height (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1000004, 0, MakePoint(1, 1), 0.5, 0.5, 'DEFLATE', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1000004, 0, MakePoint(1, 1), 0.5, 0.5, 'DEFLATE', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotiff15.testcase b/test/sql_stmt_security_tests/writesectionmonotiff15.testcase
new file mode 100644
index 0000000..cc6f199
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotiff15.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiff - invalid tile-size (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'LZW', 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'LZW', 2)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotiff16.testcase b/test/sql_stmt_security_tests/writesectionmonotiff16.testcase
new file mode 100644
index 0000000..dc63a7a
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotiff16.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiff - invalid tile-size (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'LZMA', 2000000);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'LZMA', 2000000)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotiff17.testcase b/test/sql_stmt_security_tests/writesectionmonotiff17.testcase
new file mode 100644
index 0000000..1c05398
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotiff17.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiff - not existing coverage (1)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotiff18.testcase b/test/sql_stmt_security_tests/writesectionmonotiff18.testcase
new file mode 100644
index 0000000..8b4e568
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotiff18.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiff - not existing coverage (2)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotiff19.testcase b/test/sql_stmt_security_tests/writesectionmonotiff19.testcase
new file mode 100644
index 0000000..4a85cb1
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotiff19.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiff - NULL mono band
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, NULL, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, NULL, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotiff2.testcase b/test/sql_stmt_security_tests/writesectionmonotiff2.testcase
new file mode 100644
index 0000000..52c47a3
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotiff2.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiff - NULL Path
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiff('alpha', 1, NULL, 1024, 1024, 0, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiff('alpha', 1, NULL, 1024, 1024, 0, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotiff20.testcase b/test/sql_stmt_security_tests/writesectionmonotiff20.testcase
new file mode 100644
index 0000000..b83497c
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotiff20.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiff - invalid mono band (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, -1, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, -1, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotiff21.testcase b/test/sql_stmt_security_tests/writesectionmonotiff21.testcase
new file mode 100644
index 0000000..7a72001
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotiff21.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiff - invalid mono band (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, 500, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, 500, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotiff22.testcase b/test/sql_stmt_security_tests/writesectionmonotiff22.testcase
new file mode 100644
index 0000000..87327de
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotiff22.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiff - NULL Section
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiff('alpha', NULL, './test.tif', 1024, 1024, 0, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiff('alpha', NULL, './test.tif', 1024, 1024, 0, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotiff3.testcase b/test/sql_stmt_security_tests/writesectionmonotiff3.testcase
new file mode 100644
index 0000000..f07619e
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotiff3.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiff - NULL Width
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', NULL, 1024, 0, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', NULL, 1024, 0, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotiff4.testcase b/test/sql_stmt_security_tests/writesectionmonotiff4.testcase
new file mode 100644
index 0000000..96eae8a
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotiff4.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandiff - NULL Height
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, NULL, 0, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, NULL, 0, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotiff5.testcase b/test/sql_stmt_security_tests/writesectionmonotiff5.testcase
new file mode 100644
index 0000000..168cbdd
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotiff5.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiff - NULL Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, NULL, 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, NULL, 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotiff6.testcase b/test/sql_stmt_security_tests/writesectionmonotiff6.testcase
new file mode 100644
index 0000000..c24cc30
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotiff6.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiff - Invalid BLOB Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, zeroblob(100), 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, zeroblob(100), 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotiff7.testcase b/test/sql_stmt_security_tests/writesectionmonotiff7.testcase
new file mode 100644
index 0000000..87d53bd
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotiff7.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiff - NULL resolution
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotiff8.testcase b/test/sql_stmt_security_tests/writesectionmonotiff8.testcase
new file mode 100644
index 0000000..1b36b80
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotiff8.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiff - NULL vertical resolution
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotiff9.testcase b/test/sql_stmt_security_tests/writesectionmonotiff9.testcase
new file mode 100644
index 0000000..c198ebe
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotiff9.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiff - NULL compression
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiff('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotifftfw1.testcase b/test/sql_stmt_security_tests/writesectionmonotifftfw1.testcase
new file mode 100644
index 0000000..5263128
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotifftfw1.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiffTfw - NULL Coverage
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiffTfw(NULL, 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiffTfw(NULL, 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotifftfw10.testcase b/test/sql_stmt_security_tests/writesectionmonotifftfw10.testcase
new file mode 100644
index 0000000..6669097
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotifftfw10.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiffTfw - NULL tile-size
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'JPEG', NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'JPEG', NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotifftfw11.testcase b/test/sql_stmt_security_tests/writesectionmonotifftfw11.testcase
new file mode 100644
index 0000000..2fbd9a2
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotifftfw11.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiffTfw - invalid width (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 4, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'PNG', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 4, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'PNG', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotifftfw12.testcase b/test/sql_stmt_security_tests/writesectionmonotifftfw12.testcase
new file mode 100644
index 0000000..3802e54
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotifftfw12.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiffTfw - invalid width (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1000004, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'FAX4', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1000004, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'FAX4', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotifftfw13.testcase b/test/sql_stmt_security_tests/writesectionmonotifftfw13.testcase
new file mode 100644
index 0000000..a7b1d45
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotifftfw13.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiffTfw - invalid height (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 4, 0, MakePoint(1, 1), 0.5, 0.5, 'FAX3', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 4, 0, MakePoint(1, 1), 0.5, 0.5, 'FAX3', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotifftfw14.testcase b/test/sql_stmt_security_tests/writesectionmonotifftfw14.testcase
new file mode 100644
index 0000000..86be910
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotifftfw14.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiffTfw - invalid height (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1000004, 0, MakePoint(1, 1), 0.5, 0.5, 'DEFLATE', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1000004, 0, MakePoint(1, 1), 0.5, 0.5, 'DEFLATE', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotifftfw15.testcase b/test/sql_stmt_security_tests/writesectionmonotifftfw15.testcase
new file mode 100644
index 0000000..439b4f9
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotifftfw15.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiffTfw - invalid tile-size (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'LZW', 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'LZW', 2)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotifftfw16.testcase b/test/sql_stmt_security_tests/writesectionmonotifftfw16.testcase
new file mode 100644
index 0000000..04c68d6
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotifftfw16.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiffTfw - invalid tile-size (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'LZMA', 2000000);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'LZMA', 2000000)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotifftfw17.testcase b/test/sql_stmt_security_tests/writesectionmonotifftfw17.testcase
new file mode 100644
index 0000000..43c7ca2
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotifftfw17.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiffTfw - not existing coverage (1)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotifftfw18.testcase b/test/sql_stmt_security_tests/writesectionmonotifftfw18.testcase
new file mode 100644
index 0000000..9109c5b
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotifftfw18.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiffTfw - not existing coverage (2)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotifftfw19.testcase b/test/sql_stmt_security_tests/writesectionmonotifftfw19.testcase
new file mode 100644
index 0000000..9066e81
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotifftfw19.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiffTfw - NULL mono band
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, NULL, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, NULL, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotifftfw2.testcase b/test/sql_stmt_security_tests/writesectionmonotifftfw2.testcase
new file mode 100644
index 0000000..14a3557
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotifftfw2.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiffTfw - NULL Path
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiffTfw('alpha', 1, NULL, 1024, 1024, 0, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiffTfw('alpha', 1, NULL, 1024, 1024, 0, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotifftfw20.testcase b/test/sql_stmt_security_tests/writesectionmonotifftfw20.testcase
new file mode 100644
index 0000000..046defe
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotifftfw20.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiffTfw - invalid mono band (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, -1, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, -1, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotifftfw21.testcase b/test/sql_stmt_security_tests/writesectionmonotifftfw21.testcase
new file mode 100644
index 0000000..24ec355
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotifftfw21.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiffTfw - invalid mono band (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 500, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 500, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotifftfw22.testcase b/test/sql_stmt_security_tests/writesectionmonotifftfw22.testcase
new file mode 100644
index 0000000..177fa92
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotifftfw22.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiffTfw - NULL Section
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiffTfw('alpha', NULL, './test.tif', 1024, 1024, 0, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiffTfw('alpha', NULL, './test.tif', 1024, 1024, 0, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotifftfw3.testcase b/test/sql_stmt_security_tests/writesectionmonotifftfw3.testcase
new file mode 100644
index 0000000..130e827
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotifftfw3.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiffTfw - NULL Width
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', NULL, 1024, 0, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', NULL, 1024, 0, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotifftfw4.testcase b/test/sql_stmt_security_tests/writesectionmonotifftfw4.testcase
new file mode 100644
index 0000000..1f08b35
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotifftfw4.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandiffTfw - NULL Height
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, NULL, 0, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, NULL, 0, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotifftfw5.testcase b/test/sql_stmt_security_tests/writesectionmonotifftfw5.testcase
new file mode 100644
index 0000000..9a209ab
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotifftfw5.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiffTfw - NULL Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, NULL, 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, NULL, 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotifftfw6.testcase b/test/sql_stmt_security_tests/writesectionmonotifftfw6.testcase
new file mode 100644
index 0000000..d2fe0af
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotifftfw6.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiffTfw - Invalid BLOB Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, zeroblob(100), 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, zeroblob(100), 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotifftfw7.testcase b/test/sql_stmt_security_tests/writesectionmonotifftfw7.testcase
new file mode 100644
index 0000000..e75e13e
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotifftfw7.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiffTfw - NULL resolution
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotifftfw8.testcase b/test/sql_stmt_security_tests/writesectionmonotifftfw8.testcase
new file mode 100644
index 0000000..59725d9
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotifftfw8.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiffTfw - NULL vertical resolution
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionmonotifftfw9.testcase b/test/sql_stmt_security_tests/writesectionmonotifftfw9.testcase
new file mode 100644
index 0000000..b60a50b
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionmonotifftfw9.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionMonoBandTiffTfw - NULL compression
+:memory: #use in-memory database
+SELECT RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionMonoBandTiffTfw('alpha', 1, './test.tif', 1024, 1024, 0, MakePoint(1, 1), 0.5, 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionndviascii1.testcase b/test/sql_stmt_security_tests/writesectionndviascii1.testcase
new file mode 100644
index 0000000..36e667c
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionndviascii1.testcase
@@ -0,0 +1,7 @@
+RL2_WriteNdviSectionAsciiGrid - NULL Coverage
+:memory: #use in-memory database
+SELECT RL2_WriteSectionNdviAsciiGrid(NULL, 1, './test.asc', 1024, 1024, 0, 3, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionNdviAsciiGrid(NULL, 1, './test.asc', 1024, 1024, 0, 3, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionndviascii10.testcase b/test/sql_stmt_security_tests/writesectionndviascii10.testcase
new file mode 100644
index 0000000..d8c17d0
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionndviascii10.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionNdviAsciiGrid - NULL is-centered
+:memory: #use in-memory database
+SELECT RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1024, 0, 3, MakePoint(1, 1), 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1024, 0, 3, MakePoint(1, 1), 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionndviascii11.testcase b/test/sql_stmt_security_tests/writesectionndviascii11.testcase
new file mode 100644
index 0000000..4270fee
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionndviascii11.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionNdviAsciiGrid - NULL decimal-digits
+:memory: #use in-memory database
+SELECT RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1024, 0, 3, MakePoint(1, 1), 0.5, 1, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1024, 0, 3, MakePoint(1, 1), 0.5, 1, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionndviascii12.testcase b/test/sql_stmt_security_tests/writesectionndviascii12.testcase
new file mode 100644
index 0000000..9c33d5b
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionndviascii12.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionNdviAsciiGrid - not existing coverage (1)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1024, 0, 3, MakePoint(1, 1), 0.5, 1, 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1024, 0, 3, MakePoint(1, 1), 0.5, 1, 2)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionndviascii13.testcase b/test/sql_stmt_security_tests/writesectionndviascii13.testcase
new file mode 100644
index 0000000..d8daa86
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionndviascii13.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionNdviAsciiGrid - not existing coverage (2)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1024, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1024, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, 2)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionndviascii14.testcase b/test/sql_stmt_security_tests/writesectionndviascii14.testcase
new file mode 100644
index 0000000..556853a
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionndviascii14.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionNdviAsciiGrid - invalid width (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 4, 1024, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 4, 1024, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, 2)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionndviascii15.testcase b/test/sql_stmt_security_tests/writesectionndviascii15.testcase
new file mode 100644
index 0000000..99dde73
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionndviascii15.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionNdviAsciiGrid - invalid width (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1000004, 1024, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1000004, 1024, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, 2)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionndviascii16.testcase b/test/sql_stmt_security_tests/writesectionndviascii16.testcase
new file mode 100644
index 0000000..bbf9f09
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionndviascii16.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionNdviAsciiGrid - invalid height (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, 2)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionndviascii17.testcase b/test/sql_stmt_security_tests/writesectionndviascii17.testcase
new file mode 100644
index 0000000..3abcb11
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionndviascii17.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionNdviAsciiGrid - invalid height (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1000000, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1000000, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, 2)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionndviascii18.testcase b/test/sql_stmt_security_tests/writesectionndviascii18.testcase
new file mode 100644
index 0000000..dcd1287
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionndviascii18.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionNdviAsciiGrid - invalid decimal precision (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1000000, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, -1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1000000, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, -1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionndviascii19.testcase b/test/sql_stmt_security_tests/writesectionndviascii19.testcase
new file mode 100644
index 0000000..dfef771
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionndviascii19.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionNdviAsciiGrid - invalid decimal precision (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1000000, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, 50);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1000000, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, 50)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionndviascii2.testcase b/test/sql_stmt_security_tests/writesectionndviascii2.testcase
new file mode 100644
index 0000000..a34ee3b
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionndviascii2.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionNdviAsciiGrid - NULL Path
+:memory: #use in-memory database
+SELECT RL2_WriteSectionNdviAsciiGrid('alpha', 1, NULL, 1024, 1024, 0, 3, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionNdviAsciiGrid('alpha', 1, NULL, 1024, 1024, 0, 3, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionndviascii20.testcase b/test/sql_stmt_security_tests/writesectionndviascii20.testcase
new file mode 100644
index 0000000..27d2156
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionndviascii20.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionNdviAsciiGrid - NULL Section
+:memory: #use in-memory database
+SELECT RL2_WriteSectionNdviAsciiGrid('alpha', NULL, './test.asc', 1024, 1024, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, 50);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionNdviAsciiGrid('alpha', NULL, './test.asc', 1024, 1024, 0, 3, BuildMbr(1, 1, 10, 10), 1, 1, 50)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionndviascii3.testcase b/test/sql_stmt_security_tests/writesectionndviascii3.testcase
new file mode 100644
index 0000000..20b7746
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionndviascii3.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionNdviAsciiGrid - NULL Width
+:memory: #use in-memory database
+SELECT RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', NULL, 1024, 0, 3, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', NULL, 1024, 0, 3, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionndviascii4.testcase b/test/sql_stmt_security_tests/writesectionndviascii4.testcase
new file mode 100644
index 0000000..5564e73
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionndviascii4.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionNdviAsciiGrid - NULL Height
+:memory: #use in-memory database
+SELECT RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, NULL, 0, 3, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, NULL, 0, 3, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionndviascii5.testcase b/test/sql_stmt_security_tests/writesectionndviascii5.testcase
new file mode 100644
index 0000000..fb65695
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionndviascii5.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionNdviAsciiGrid - NULL red band
+:memory: #use in-memory database
+SELECT RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1024, NULL, 3, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1024, NULL, 3, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionndviascii6.testcase b/test/sql_stmt_security_tests/writesectionndviascii6.testcase
new file mode 100644
index 0000000..3630a24
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionndviascii6.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionNdviAsciiGrid - NULL NIR band
+:memory: #use in-memory database
+SELECT RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1024, 0, NULL, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1024, 0, NULL, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionndviascii7.testcase b/test/sql_stmt_security_tests/writesectionndviascii7.testcase
new file mode 100644
index 0000000..b09de10
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionndviascii7.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionNdviAsciiGrid - NULL Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1024, 0, 3, NULL, 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1024, 0, 3, NULL, 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionndviascii8.testcase b/test/sql_stmt_security_tests/writesectionndviascii8.testcase
new file mode 100644
index 0000000..3da9a6f
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionndviascii8.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionNdviAsciiGrid - Invalid BLOB Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1024, 0, 3, zeroblob(100), 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1024, 0, 3, zeroblob(100), 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectionndviascii9.testcase b/test/sql_stmt_security_tests/writesectionndviascii9.testcase
new file mode 100644
index 0000000..cf29192
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectionndviascii9.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionNdviAsciiGrid - NULL resolution
+:memory: #use in-memory database
+SELECT RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1024, 0, 3, MakePoint(1, 1), NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionNdviAsciiGrid('alpha', 1, './test.asc', 1024, 1024, 0, 3, MakePoint(1, 1), NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontiff1.testcase b/test/sql_stmt_security_tests/writesectiontiff1.testcase
new file mode 100644
index 0000000..d9618f3
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontiff1.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiff - NULL Coverage
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiff(NULL, 1, './test.tif', 1024, 1024, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiff(NULL, 1, './test.tif', 1024, 1024, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontiff10.testcase b/test/sql_stmt_security_tests/writesectiontiff10.testcase
new file mode 100644
index 0000000..9c225f1
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontiff10.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiff - NULL tile-size
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 'JPEG', NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 'JPEG', NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontiff11.testcase b/test/sql_stmt_security_tests/writesectiontiff11.testcase
new file mode 100644
index 0000000..efbb20b
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontiff11.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiff - invalid width (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiff('alpha', 1, './test.tif', 4, 1024, MakePoint(1, 1), 0.5, 0.5, 'PNG', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiff('alpha', 1, './test.tif', 4, 1024, MakePoint(1, 1), 0.5, 0.5, 'PNG', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontiff12.testcase b/test/sql_stmt_security_tests/writesectiontiff12.testcase
new file mode 100644
index 0000000..623ffc8
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontiff12.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiff - invalid width (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiff('alpha', 1, './test.tif', 1000004, 1024, MakePoint(1, 1), 0.5, 0.5, 'FAX4', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiff('alpha', 1, './test.tif', 1000004, 1024, MakePoint(1, 1), 0.5, 0.5, 'FAX4', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontiff13.testcase b/test/sql_stmt_security_tests/writesectiontiff13.testcase
new file mode 100644
index 0000000..834f9e3
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontiff13.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiff - invalid height (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, 4, MakePoint(1, 1), 0.5, 0.5, 'FAX3', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, 4, MakePoint(1, 1), 0.5, 0.5, 'FAX3', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontiff14.testcase b/test/sql_stmt_security_tests/writesectiontiff14.testcase
new file mode 100644
index 0000000..b1f50aa
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontiff14.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiff - invalid height (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, 1000004, MakePoint(1, 1), 0.5, 0.5, 'DEFLATE', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, 1000004, MakePoint(1, 1), 0.5, 0.5, 'DEFLATE', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontiff15.testcase b/test/sql_stmt_security_tests/writesectiontiff15.testcase
new file mode 100644
index 0000000..d4ed3b9
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontiff15.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiff - invalid tile-size (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 'LZW', 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 'LZW', 2)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontiff16.testcase b/test/sql_stmt_security_tests/writesectiontiff16.testcase
new file mode 100644
index 0000000..106f027
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontiff16.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiff - invalid tile-size (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 'LZMA', 2000000);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 'LZMA', 2000000)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontiff17.testcase b/test/sql_stmt_security_tests/writesectiontiff17.testcase
new file mode 100644
index 0000000..6c92089
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontiff17.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiff - not existing coverage (1)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontiff18.testcase b/test/sql_stmt_security_tests/writesectiontiff18.testcase
new file mode 100644
index 0000000..4409a85
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontiff18.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiff - not existing coverage (2)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, 1024, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, 1024, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontiff19.testcase b/test/sql_stmt_security_tests/writesectiontiff19.testcase
new file mode 100644
index 0000000..c92617b
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontiff19.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiff - NULL Section
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiff('alpha', NULL, './test.tif', 1024, 1024, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiff('alpha', NULL, './test.tif', 1024, 1024, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontiff2.testcase b/test/sql_stmt_security_tests/writesectiontiff2.testcase
new file mode 100644
index 0000000..ea9ea28
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontiff2.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiff - NULL Path
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiff('alpha', 1, NULL, 1024, 1024, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiff('alpha', 1, NULL, 1024, 1024, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontiff3.testcase b/test/sql_stmt_security_tests/writesectiontiff3.testcase
new file mode 100644
index 0000000..d83dc46
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontiff3.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiff - NULL Width
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiff('alpha', 1, './test.tif', NULL, 1024, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiff('alpha', 1, './test.tif', NULL, 1024, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontiff4.testcase b/test/sql_stmt_security_tests/writesectiontiff4.testcase
new file mode 100644
index 0000000..c437997
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontiff4.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiff - NULL Height
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, NULL, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, NULL, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontiff5.testcase b/test/sql_stmt_security_tests/writesectiontiff5.testcase
new file mode 100644
index 0000000..9e7c2c5
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontiff5.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiff - NULL Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, 1024, NULL, 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, 1024, NULL, 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontiff6.testcase b/test/sql_stmt_security_tests/writesectiontiff6.testcase
new file mode 100644
index 0000000..93e879b
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontiff6.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiff - Invalid BLOB Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, 1024, zeroblob(100), 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, 1024, zeroblob(100), 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontiff7.testcase b/test/sql_stmt_security_tests/writesectiontiff7.testcase
new file mode 100644
index 0000000..72759ca
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontiff7.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiff - NULL resolution
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontiff8.testcase b/test/sql_stmt_security_tests/writesectiontiff8.testcase
new file mode 100644
index 0000000..1552426
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontiff8.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiff - NULL vertical resolution
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontiff9.testcase b/test/sql_stmt_security_tests/writesectiontiff9.testcase
new file mode 100644
index 0000000..8c1b71d
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontiff9.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiff - NULL compression
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiff('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontifftfw1.testcase b/test/sql_stmt_security_tests/writesectiontifftfw1.testcase
new file mode 100644
index 0000000..71319e7
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontifftfw1.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiffTfw - NULL Coverage
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiffTfw(NULL, 1, './test.tif', 1024, 1024, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiffTfw(NULL, 1, './test.tif', 1024, 1024, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontifftfw10.testcase b/test/sql_stmt_security_tests/writesectiontifftfw10.testcase
new file mode 100644
index 0000000..d2bfe6d
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontifftfw10.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiffTfw - NULL tile-size
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 'JPEG', NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 'JPEG', NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontifftfw11.testcase b/test/sql_stmt_security_tests/writesectiontifftfw11.testcase
new file mode 100644
index 0000000..722d764
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontifftfw11.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiffTfw - invalid width (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 4, 1024, MakePoint(1, 1), 0.5, 0.5, 'PNG', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 4, 1024, MakePoint(1, 1), 0.5, 0.5, 'PNG', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontifftfw12.testcase b/test/sql_stmt_security_tests/writesectiontifftfw12.testcase
new file mode 100644
index 0000000..140e7ec
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontifftfw12.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiffTfw - invalid width (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1000004, 1024, MakePoint(1, 1), 0.5, 0.5, 'FAX4', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1000004, 1024, MakePoint(1, 1), 0.5, 0.5, 'FAX4', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontifftfw13.testcase b/test/sql_stmt_security_tests/writesectiontifftfw13.testcase
new file mode 100644
index 0000000..055b01d
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontifftfw13.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiffTfw - invalid height (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, 4, MakePoint(1, 1), 0.5, 0.5, 'FAX3', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, 4, MakePoint(1, 1), 0.5, 0.5, 'FAX3', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontifftfw14.testcase b/test/sql_stmt_security_tests/writesectiontifftfw14.testcase
new file mode 100644
index 0000000..7501871
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontifftfw14.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiffTfw - invalid height (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, 1000004, MakePoint(1, 1), 0.5, 0.5, 'DEFLATE', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, 1000004, MakePoint(1, 1), 0.5, 0.5, 'DEFLATE', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontifftfw15.testcase b/test/sql_stmt_security_tests/writesectiontifftfw15.testcase
new file mode 100644
index 0000000..7975cf0
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontifftfw15.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiffTfw - invalid tile-size (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 'LZW', 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 'LZW', 2)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontifftfw16.testcase b/test/sql_stmt_security_tests/writesectiontifftfw16.testcase
new file mode 100644
index 0000000..5e0aedf
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontifftfw16.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiffTfw - invalid tile-size (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 'LZMA', 2000000);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 'LZMA', 2000000)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontifftfw17.testcase b/test/sql_stmt_security_tests/writesectiontifftfw17.testcase
new file mode 100644
index 0000000..9e836dd
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontifftfw17.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiffTfw - not existing coverage (1)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontifftfw18.testcase b/test/sql_stmt_security_tests/writesectiontifftfw18.testcase
new file mode 100644
index 0000000..2e796a4
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontifftfw18.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiffTfw - not existing coverage (2)
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, 1024, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, 1024, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontifftfw19.testcase b/test/sql_stmt_security_tests/writesectiontifftfw19.testcase
new file mode 100644
index 0000000..aa1753a
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontifftfw19.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiffTfw - NULL Section
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiffTfw('alpha', NULL, './test.tif', 1024, 1024, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiffTfw('alpha', NULL, './test.tif', 1024, 1024, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontifftfw2.testcase b/test/sql_stmt_security_tests/writesectiontifftfw2.testcase
new file mode 100644
index 0000000..9662d6b
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontifftfw2.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiffTfw - NULL Path
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiffTfw('alpha', 1, NULL, 1024, 1024, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiffTfw('alpha', 1, NULL, 1024, 1024, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontifftfw3.testcase b/test/sql_stmt_security_tests/writesectiontifftfw3.testcase
new file mode 100644
index 0000000..564fcee
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontifftfw3.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiffTfw - NULL Width
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', NULL, 1024, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', NULL, 1024, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontifftfw4.testcase b/test/sql_stmt_security_tests/writesectiontifftfw4.testcase
new file mode 100644
index 0000000..40c2c64
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontifftfw4.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiffTfw - NULL Height
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, NULL, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, NULL, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontifftfw5.testcase b/test/sql_stmt_security_tests/writesectiontifftfw5.testcase
new file mode 100644
index 0000000..3cf991b
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontifftfw5.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiffTfw - NULL Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, 1024, NULL, 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, 1024, NULL, 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontifftfw6.testcase b/test/sql_stmt_security_tests/writesectiontifftfw6.testcase
new file mode 100644
index 0000000..b803eb3
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontifftfw6.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiffTfw - Invalid BLOB Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, 1024, zeroblob(100), 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, 1024, zeroblob(100), 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontifftfw7.testcase b/test/sql_stmt_security_tests/writesectiontifftfw7.testcase
new file mode 100644
index 0000000..5210b98
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontifftfw7.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiffTfw - NULL resolution
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontifftfw8.testcase b/test/sql_stmt_security_tests/writesectiontifftfw8.testcase
new file mode 100644
index 0000000..4416d64
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontifftfw8.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiffTfw - NULL vertical resolution
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writesectiontifftfw9.testcase b/test/sql_stmt_security_tests/writesectiontifftfw9.testcase
new file mode 100644
index 0000000..f54faca
--- /dev/null
+++ b/test/sql_stmt_security_tests/writesectiontifftfw9.testcase
@@ -0,0 +1,7 @@
+RL2_WriteSectionTiffTfw - NULL compression
+:memory: #use in-memory database
+SELECT RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteSectionTiffTfw('alpha', 1, './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writetifftfw1.testcase b/test/sql_stmt_security_tests/writetifftfw1.testcase
new file mode 100644
index 0000000..c6f122d
--- /dev/null
+++ b/test/sql_stmt_security_tests/writetifftfw1.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTiffTfw - NULL Coverage
+:memory: #use in-memory database
+SELECT RL2_WriteTiffTfw(NULL, './test.tif', 1024, 1024, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTiffTfw(NULL, './test.tif', 1024, 1024, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writetifftfw10.testcase b/test/sql_stmt_security_tests/writetifftfw10.testcase
new file mode 100644
index 0000000..42c627c
--- /dev/null
+++ b/test/sql_stmt_security_tests/writetifftfw10.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTiffTfw - NULL tile-size
+:memory: #use in-memory database
+SELECT RL2_WriteTiffTfw('alpha', './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 'JPEG', NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTiffTfw('alpha', './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 'JPEG', NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writetifftfw11.testcase b/test/sql_stmt_security_tests/writetifftfw11.testcase
new file mode 100644
index 0000000..fabbe6f
--- /dev/null
+++ b/test/sql_stmt_security_tests/writetifftfw11.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTiffTfw - invalid width (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteTiffTfw('alpha', './test.tif', 4, 1024, MakePoint(1, 1), 0.5, 0.5, 'PNG', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTiffTfw('alpha', './test.tif', 4, 1024, MakePoint(1, 1), 0.5, 0.5, 'PNG', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writetifftfw12.testcase b/test/sql_stmt_security_tests/writetifftfw12.testcase
new file mode 100644
index 0000000..7fe3f05
--- /dev/null
+++ b/test/sql_stmt_security_tests/writetifftfw12.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTiffTfw - invalid width (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteTiffTfw('alpha', './test.tif', 1000004, 1024, MakePoint(1, 1), 0.5, 0.5, 'FAX4', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTiffTfw('alpha', './test.tif', 1000004, 1024, MakePoint(1, 1), 0.5, 0.5, 'FAX4', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writetifftfw13.testcase b/test/sql_stmt_security_tests/writetifftfw13.testcase
new file mode 100644
index 0000000..92984ce
--- /dev/null
+++ b/test/sql_stmt_security_tests/writetifftfw13.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTiffTfw - invalid height (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteTiffTfw('alpha', './test.tif', 1024, 4, MakePoint(1, 1), 0.5, 0.5, 'FAX3', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTiffTfw('alpha', './test.tif', 1024, 4, MakePoint(1, 1), 0.5, 0.5, 'FAX3', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writetifftfw14.testcase b/test/sql_stmt_security_tests/writetifftfw14.testcase
new file mode 100644
index 0000000..1d6afbb
--- /dev/null
+++ b/test/sql_stmt_security_tests/writetifftfw14.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTiffTfw - invalid height (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteTiffTfw('alpha', './test.tif', 1024, 1000004, MakePoint(1, 1), 0.5, 0.5, 'DEFLATE', 512);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTiffTfw('alpha', './test.tif', 1024, 1000004, MakePoint(1, 1), 0.5, 0.5, 'DEFLATE', 512)
+-1
diff --git a/test/sql_stmt_security_tests/writetifftfw15.testcase b/test/sql_stmt_security_tests/writetifftfw15.testcase
new file mode 100644
index 0000000..a244631
--- /dev/null
+++ b/test/sql_stmt_security_tests/writetifftfw15.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTiffTfw - invalid tile-size (too small)
+:memory: #use in-memory database
+SELECT RL2_WriteTiffTfw('alpha', './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 'LZW', 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTiffTfw('alpha', './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 'LZW', 2)
+-1
diff --git a/test/sql_stmt_security_tests/writetifftfw16.testcase b/test/sql_stmt_security_tests/writetifftfw16.testcase
new file mode 100644
index 0000000..1048748
--- /dev/null
+++ b/test/sql_stmt_security_tests/writetifftfw16.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTiffTfw - invalid tile-size (too big)
+:memory: #use in-memory database
+SELECT RL2_WriteTiffTfw('alpha', './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 'LZMA', 2000000);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTiffTfw('alpha', './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 'LZMA', 2000000)
+-1
diff --git a/test/sql_stmt_security_tests/writetifftfw17.testcase b/test/sql_stmt_security_tests/writetifftfw17.testcase
new file mode 100644
index 0000000..24f1bf2
--- /dev/null
+++ b/test/sql_stmt_security_tests/writetifftfw17.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTiffTfw - not existing coverage (1)
+:memory: #use in-memory database
+SELECT RL2_WriteTiffTfw('alpha', './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 'NONE', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTiffTfw('alpha', './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, 'NONE', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writetifftfw18.testcase b/test/sql_stmt_security_tests/writetifftfw18.testcase
new file mode 100644
index 0000000..8384656
--- /dev/null
+++ b/test/sql_stmt_security_tests/writetifftfw18.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTiffTfw - not existing coverage (2)
+:memory: #use in-memory database
+SELECT RL2_WriteTiffTfw('alpha', './test.tif', 1024, 1024, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTiffTfw('alpha', './test.tif', 1024, 1024, BuildMbr(1, 1, 10, 10), 1, 1, 'JPEG', 256)
+-1
diff --git a/test/sql_stmt_security_tests/writetifftfw2.testcase b/test/sql_stmt_security_tests/writetifftfw2.testcase
new file mode 100644
index 0000000..2de7171
--- /dev/null
+++ b/test/sql_stmt_security_tests/writetifftfw2.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTiffTfw - NULL Path
+:memory: #use in-memory database
+SELECT RL2_WriteTiffTfw('alpha', NULL, 1024, 1024, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTiffTfw('alpha', NULL, 1024, 1024, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writetifftfw3.testcase b/test/sql_stmt_security_tests/writetifftfw3.testcase
new file mode 100644
index 0000000..9572e99
--- /dev/null
+++ b/test/sql_stmt_security_tests/writetifftfw3.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTiffTfw - NULL Width
+:memory: #use in-memory database
+SELECT RL2_WriteTiffTfw('alpha', './test.tif', NULL, 1024, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTiffTfw('alpha', './test.tif', NULL, 1024, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writetifftfw4.testcase b/test/sql_stmt_security_tests/writetifftfw4.testcase
new file mode 100644
index 0000000..b25a87d
--- /dev/null
+++ b/test/sql_stmt_security_tests/writetifftfw4.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTiffTfw - NULL Height
+:memory: #use in-memory database
+SELECT RL2_WriteTiffTfw('alpha', './test.tif', 1024, NULL, MakePoint(1, 1), 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTiffTfw('alpha', './test.tif', 1024, NULL, MakePoint(1, 1), 1)
+-1
diff --git a/test/sql_stmt_security_tests/writetifftfw5.testcase b/test/sql_stmt_security_tests/writetifftfw5.testcase
new file mode 100644
index 0000000..152e4b7
--- /dev/null
+++ b/test/sql_stmt_security_tests/writetifftfw5.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTiffTfw - NULL Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteTiffTfw('alpha', './test.tif', 1024, 1024, NULL, 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTiffTfw('alpha', './test.tif', 1024, 1024, NULL, 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writetifftfw6.testcase b/test/sql_stmt_security_tests/writetifftfw6.testcase
new file mode 100644
index 0000000..1456b95
--- /dev/null
+++ b/test/sql_stmt_security_tests/writetifftfw6.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTiffTfw - Invalid BLOB Geometry
+:memory: #use in-memory database
+SELECT RL2_WriteTiffTfw('alpha', './test.tif', 1024, 1024, zeroblob(100), 0.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTiffTfw('alpha', './test.tif', 1024, 1024, zeroblob(100), 0.5)
+-1
diff --git a/test/sql_stmt_security_tests/writetifftfw7.testcase b/test/sql_stmt_security_tests/writetifftfw7.testcase
new file mode 100644
index 0000000..a72422f
--- /dev/null
+++ b/test/sql_stmt_security_tests/writetifftfw7.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTiffTfw - NULL resolution
+:memory: #use in-memory database
+SELECT RL2_WriteTiffTfw('alpha', './test.tif', 1024, 1024, MakePoint(1, 1), NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTiffTfw('alpha', './test.tif', 1024, 1024, MakePoint(1, 1), NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writetifftfw8.testcase b/test/sql_stmt_security_tests/writetifftfw8.testcase
new file mode 100644
index 0000000..6e5d38f
--- /dev/null
+++ b/test/sql_stmt_security_tests/writetifftfw8.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTiffTfw - NULL vertical resolution
+:memory: #use in-memory database
+SELECT RL2_WriteTiffTfw('alpha', './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTiffTfw('alpha', './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, NULL)
+-1
diff --git a/test/sql_stmt_security_tests/writetifftfw9.testcase b/test/sql_stmt_security_tests/writetifftfw9.testcase
new file mode 100644
index 0000000..d107bb0
--- /dev/null
+++ b/test/sql_stmt_security_tests/writetifftfw9.testcase
@@ -0,0 +1,7 @@
+RL2_WriteTiffTfw - NULL compression
+:memory: #use in-memory database
+SELECT RL2_WriteTiffTfw('alpha', './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_WriteTiffTfw('alpha', './test.tif', 1024, 1024, MakePoint(1, 1), 0.5, 0.5, NULL)
+-1
diff --git a/test/sql_stmt_tests/Makefile.am b/test/sql_stmt_tests/Makefile.am
index 753bf94..2810080 100644
--- a/test/sql_stmt_tests/Makefile.am
+++ b/test/sql_stmt_tests/Makefile.am
@@ -1,22 +1,48 @@
 
-EXTRA_DIST = createcov_16_mband1.testcase \
+EXTRA_DIST = getmaxthreads1.testcase \
+	setmaxthreads1.testcase \
+	setmaxthreads2.testcase \
+	setmaxthreads3.testcase \
+	setmaxthreads4.testcase \
+	setmaxthreads5.testcase \
+	setmaxthreads6.testcase \
+	setmaxthreads7.testcase \
+	copyrastercov1.testcase \
+	copyrastercov2.testcase \
+	copyrastercov3.testcase \
+	copyrastercov4.testcase \
+	copyrastercov5.testcase \
+	copyrastercov6.testcase \
+	copyrastercov7.testcase \
+	copyrastercov8.testcase \
+	copyrastercov9.testcase \
+	copyrastercov10.testcase \
+	copyrastercov11.testcase \
+	copyrastercov12.testcase \
+	copyrastercov13.testcase \
+	copyrastercov14.testcase \
+    createcov_16_mband1.testcase \
 	createcov_16_mband_deflate.testcase \
+	createcov_16_mband_deflateno.testcase \
 	createcov_16_mband_fax3.testcase \
 	createcov_16_mband_fax4.testcase \
 	createcov_16_mband_gif.testcase \
 	createcov_16_mband_jpeg.testcase \
 	createcov_16_mband_lzma.testcase \
+	createcov_16_mband_lzmano.testcase \
 	createcov_16_mband_png.testcase \
 	createcov_16_mband.testcase \
 	createcov_16_mband_webp1.testcase \
 	createcov_16_mband_webp2.testcase \
 	createcov_1bit_mono1.testcase \
 	createcov_1bit_mono_deflate.testcase \
+	createcov_1bit_mono_deflateno.testcase \
 	createcov_1bit_mono_fax3.testcase \
 	createcov_1bit_mono_fax4.testcase \
 	createcov_1bit_mono_gif.testcase \
 	createcov_1bit_mono_jpeg.testcase \
 	createcov_1bit_mono_lzma.testcase \
+	createcov_1bit_mono_lzmano.testcase \
 	createcov_1bit_mono_png.testcase \
 	createcov_1bit_mono.testcase \
 	createcov_1bit_mono_webp1.testcase \
@@ -49,18 +75,22 @@ EXTRA_DIST = createcov_16_mband1.testcase \
 	createcov_4bit_palette.testcase \
 	createcov_8_mband1.testcase \
 	createcov_8_mband_deflate.testcase \
+	createcov_8_mband_deflateno.testcase \
 	createcov_8_mband_fax3.testcase \
 	createcov_8_mband_fax4.testcase \
 	createcov_8_mband_gif.testcase \
 	createcov_8_mband_jpeg.testcase \
 	createcov_8_mband_lzma.testcase \
+	createcov_8_mband_lzmano.testcase \
 	createcov_8_mband_png.testcase \
 	createcov_8_mband.testcase \
 	createcov_8_mband_webp1.testcase \
 	createcov_8_mband_webp2.testcase \
 	createcov_double_grid1.testcase \
 	createcov_double_grid_deflate.testcase \
+	createcov_double_grid_deflateno.testcase \
 	createcov_double_grid_lzma.testcase \
+	createcov_double_grid_lzmano.testcase \
 	createcov_double_grid.testcase \
 	createcov_err1.testcase \
 	createcov_err2.testcase \
@@ -74,66 +104,91 @@ EXTRA_DIST = createcov_16_mband1.testcase \
 	createcov_err10.testcase \
 	createcov_err11.testcase \
 	createcov_err12.testcase \
+	createcov_err13.testcase \
+	createcov_err14.testcase \
+	createcov_err15.testcase \
+	createcov_err16.testcase \
+	createcov_err17.testcase \
 	createcov_float_grid1.testcase \
 	createcov_float_grid_deflate.testcase \
+	createcov_float_grid_deflateno.testcase \
 	createcov_float_grid_lzma.testcase \
+	createcov_float_grid_lzmano.testcase \
 	createcov_float_grid.testcase \
 	createcov_int16_grid1.testcase \
 	createcov_int16_grid_deflate.testcase \
+	createcov_int16_grid_deflateno.testcase \
 	createcov_int16_grid_lzma.testcase \
+	createcov_int16_grid_lzmano.testcase \
 	createcov_int16_grid.testcase \
 	createcov_int32_grid1.testcase \
 	createcov_int32_grid_deflate.testcase \
+	createcov_int32_grid_deflateno.testcase \
 	createcov_int32_grid_gif.testcase \
 	createcov_int32_grid_jpeg.testcase \
 	createcov_int32_grid_lzma.testcase \
+	createcov_int32_grid_lzmano.testcase \
 	createcov_int32_grid_png.testcase \
 	createcov_int32_grid.testcase \
 	createcov_int32_grid_webp1.testcase \
 	createcov_int32_grid_webp2.testcase \
 	createcov_int8_grid1.testcase \
 	createcov_int8_grid_deflate.testcase \
+	createcov_int8_grid_deflateno.testcase \
 	createcov_int8_grid_lzma.testcase \
+	createcov_int8_grid_lzmano.testcase \
 	createcov_int8_grid.testcase \
 	createcov_uint16_grid1.testcase \
 	createcov_uint16_grid_deflate.testcase \
+	createcov_uint16_grid_deflateno.testcase \
 	createcov_uint16_grid_lzma.testcase \
+	createcov_uint16_grid_lzmano.testcase \
 	createcov_uint16_grid.testcase \
 	createcov_uint32_grid1.testcase \
 	createcov_uint32_grid_deflate.testcase \
+	createcov_uint32_grid_deflateno.testcase \
 	createcov_uint32_grid_lzma.testcase \
+	createcov_uint32_grid_lzmano.testcase \
 	createcov_uint32_grid.testcase \
 	createcov_uint8_gray_deflate.testcase \
+	createcov_uint8_gray_deflateno.testcase \
 	createcov_uint8_gray_fax3.testcase \
 	createcov_uint8_gray_fax4.testcase \
 	createcov_uint8_gray_gif.testcase \
 	createcov_uint8_gray_jpeg.testcase \
 	createcov_uint8_gray_lzma.testcase \
+	createcov_uint8_gray_lzmano.testcase \
 	createcov_uint8_gray_png.testcase \
 	createcov_uint8_gray.testcase \
 	createcov_uint8_gray_webp1.testcase \
 	createcov_uint8_gray_webp2.testcase \
 	createcov_uint8_grid1.testcase \
 	createcov_uint8_grid_deflate.testcase \
+	createcov_uint8_grid_deflateno.testcase \
 	createcov_uint8_grid_lzma.testcase \
+	createcov_uint8_grid_lzmano.testcase \
 	createcov_uint8_grid.testcase \
 	createcov_uint8_palette_deflate.testcase \
+	createcov_uint8_palette_deflateno.testcase \
 	createcov_uint8_palette_fax3.testcase \
 	createcov_uint8_palette_fax4.testcase \
 	createcov_uint8_palette_gif.testcase \
 	createcov_uint8_palette_jpeg.testcase \
 	createcov_uint8_palette_lzma.testcase \
+	createcov_uint8_palette_lzmano.testcase \
 	createcov_uint8_palette_png.testcase \
 	createcov_uint8_palette.testcase \
 	createcov_uint8_palette_webp1.testcase \
 	createcov_uint8_palette_webp2.testcase \
 	createcov_uint8_rgb1.testcase \
 	createcov_uint8_rgb_deflate.testcase \
+	createcov_uint8_rgb_deflateno.testcase \
 	createcov_uint8_rgb_fax3.testcase \
 	createcov_uint8_rgb_fax4.testcase \
 	createcov_uint8_rgb_gif.testcase \
 	createcov_uint8_rgb_jpeg.testcase \
 	createcov_uint8_rgb_lzma.testcase \
+	createcov_uint8_rgb_lzmano.testcase \
 	createcov_uint8_rgb_png.testcase \
 	createcov_uint8_rgb.testcase \
 	createcov_uint8_rgb_webp1.testcase \
@@ -170,6 +225,16 @@ EXTRA_DIST = createcov_16_mband1.testcase \
 	dropcoverage1.testcase \
 	dropcoverage2.testcase \
 	dropcoverage3.testcase \
+	getfontfacename1.testcase \
+	getfontfacename2.testcase \
+	getfontfacename3.testcase \
+	getfontfacename4.testcase \
+	getfontfacename5.testcase \
+	getfontfamily1.testcase \
+	getfontfamily2.testcase \
+	getfontfamily3.testcase \
+	getfontfamily4.testcase \
+	getfontfamily5.testcase \
 	getmapimage1.testcase \
 	getmapimage2.testcase \
 	getmapimage3.testcase \
@@ -180,7 +245,7 @@ EXTRA_DIST = createcov_16_mband1.testcase \
 	getmapimage8.testcase \
 	getmapimage9.testcase \
 	getmapimage10.testcase \
-	getmapimage1.testcase \
+	getmapimage11.testcase \
 	getmapimage12.testcase \
 	getmapimage13.testcase \
 	getmapimage14.testcase \
@@ -190,6 +255,26 @@ EXTRA_DIST = createcov_16_mband1.testcase \
 	getmapimage18.testcase \
 	getmapimage19.testcase \
 	getmapimage20.testcase \
+	getvectorimage1.testcase \
+	getvectorimage2.testcase \
+	getvectorimage3.testcase \
+	getvectorimage4.testcase \
+	getvectorimage5.testcase \
+	getvectorimage6.testcase \
+	getvectorimage7.testcase \
+	getvectorimage8.testcase \
+	getvectorimage9.testcase \
+	getvectorimage10.testcase \
+	getvectorimage11.testcase \
+	getvectorimage12.testcase \
+	getvectorimage13.testcase \
+	getvectorimage14.testcase \
+	getvectorimage15.testcase \
+	getvectorimage16.testcase \
+	getvectorimage17.testcase \
+	getvectorimage18.testcase \
+	getvectorimage19.testcase \
+	getvectorimage20.testcase \
 	gettileimage1.testcase \
 	gettileimage2.testcase \
 	gettileimage3.testcase \
@@ -294,6 +379,51 @@ EXTRA_DIST = createcov_16_mband1.testcase \
 	getrasterstats24.testcase \
 	getrasterstats25.testcase \
 	getrasterstats26.testcase \
+	enableautondvi1.testcase \
+	enableautondvi2.testcase \
+	enableautondvi3.testcase \
+	exportraw1.testcase \
+	exportraw2.testcase \
+	exportraw3.testcase \
+	exportraw4.testcase \
+	exportraw5.testcase \
+	exportraw6.testcase \
+	exportraw7.testcase \
+	exportraw8.testcase \
+	exportsectraw1.testcase \
+	exportsectraw2.testcase \
+	exportsectraw3.testcase \
+	exportsectraw4.testcase \
+	exportsectraw5.testcase \
+	exportsectraw6.testcase \
+	exportsectraw7.testcase \
+	exportsectraw8.testcase \
+	exportsectraw9.testcase \
+	importraw1.testcase \
+	importraw2.testcase \
+	importraw3.testcase \
+	importraw4.testcase \
+	importraw5.testcase \
+	importraw6.testcase \
+	importraw7.testcase \
+	importraw8.testcase \
+	importraw9.testcase \
+	importraw10.testcase \
+	isautondvienabled1.testcase \
+	isautondvienabled2.testcase \
+	isautondvienabled3.testcase \
+	isautondvienabled4.testcase \
+	isautondvienabled5.testcase \
+	isfontbold1.testcase \
+	isfontbold2.testcase \
+	isfontbold3.testcase \
+	isfontbold4.testcase \
+	isfontbold5.testcase \
+	isfontitalic1.testcase \
+	isfontitalic2.testcase \
+	isfontitalic3.testcase \
+	isfontitalic4.testcase \
+	isfontitalic5.testcase \
 	ispixelopaque1.testcase \
 	ispixelopaque2.testcase \
 	ispixelopaque3.testcase \
@@ -304,6 +434,11 @@ EXTRA_DIST = createcov_16_mband1.testcase \
 	ispixeltransparent3.testcase \
 	ispixeltransparent4.testcase \
 	ispixeltransparent5.testcase \
+	isvalidfont1.testcase \
+	isvalidfont2.testcase \
+	isvalidfont3.testcase \
+	isvalidfont4.testcase \
+	isvalidfont5.testcase \
 	isvalidpalette1.testcase \
 	isvalidpalette2.testcase \
 	isvalidpalette3.testcase \
@@ -387,10 +522,33 @@ EXTRA_DIST = createcov_16_mband1.testcase \
 	pyramidize14.testcase \
 	pyramidize15.testcase \
 	pyramidize16.testcase \
+	pyramidize17.testcase \
+	pyramidize18.testcase \
+	pyramidize19.testcase \
 	setcoverageinfos1.testcase \
 	setcoverageinfos2.testcase \
 	setcoverageinfos3.testcase \
 	setcoverageinfos4.testcase \
+	setdefaultbands1.testcase \
+	setdefaultbands2.testcase \
+	setdefaultbands3.testcase \
+	setdefaultbands4.testcase \
+	setdefaultbands5.testcase \
+	setdefaultbands6.testcase \
+	setdefaultbands7.testcase \
+	setdefaultbands8.testcase \
+	setdefaultbands9.testcase \
+	setdefaultbands10.testcase \
+	setdefaultbands11.testcase \
+	setdefaultbands12.testcase \
+	setdefaultbands13.testcase \
+	setdefaultbands14.testcase \
+	setdefaultbands15.testcase \
+	setdefaultbands16.testcase \
+	setdefaultbands17.testcase \
+	setdefaultbands18.testcase \
+	setdefaultbands19.testcase \
+	setdefaultbands20.testcase \
 	setpalettecolorentry1.testcase \
 	setpalettecolorentry2.testcase \
 	setpalettecolorentry3.testcase \
diff --git a/test/sql_stmt_tests/Makefile.in b/test/sql_stmt_tests/Makefile.in
index b3e685b..980f946 100644
--- a/test/sql_stmt_tests/Makefile.in
+++ b/test/sql_stmt_tests/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# Makefile.in generated by automake 1.15 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,7 +14,17 @@
 
 @SET_MAKE@
 VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -78,7 +88,6 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = test/sql_stmt_tests
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
@@ -86,6 +95,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
@@ -110,6 +120,7 @@ am__can_run_installinfo = \
     *) (install-info --version) >/dev/null 2>&1;; \
   esac
 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__DIST_COMMON = $(srcdir)/Makefile.in
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -141,6 +152,8 @@ ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
+FREETYPE2_CFLAGS = @FREETYPE2_CFLAGS@
+FREETYPE2_LIBS = @FREETYPE2_LIBS@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
@@ -153,6 +166,8 @@ LIBCAIRO_CFLAGS = @LIBCAIRO_CFLAGS@
 LIBCAIRO_LIBS = @LIBCAIRO_LIBS@
 LIBCURL_CFLAGS = @LIBCURL_CFLAGS@
 LIBCURL_LIBS = @LIBCURL_LIBS@
+LIBFREETYPE2_CFLAGS = @LIBFREETYPE2_CFLAGS@
+LIBFREETYPE2_LIBS = @LIBFREETYPE2_LIBS@
 LIBLZMA_CFLAGS = @LIBLZMA_CFLAGS@
 LIBLZMA_LIBS = @LIBLZMA_LIBS@
 LIBOBJS = @LIBOBJS@
@@ -249,24 +264,50 @@ target_alias = @target_alias@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-EXTRA_DIST = createcov_16_mband1.testcase \
+EXTRA_DIST = getmaxthreads1.testcase \
+	setmaxthreads1.testcase \
+	setmaxthreads2.testcase \
+	setmaxthreads3.testcase \
+	setmaxthreads4.testcase \
+	setmaxthreads5.testcase \
+	setmaxthreads6.testcase \
+	setmaxthreads7.testcase \
+	copyrastercov1.testcase \
+	copyrastercov2.testcase \
+	copyrastercov3.testcase \
+	copyrastercov4.testcase \
+	copyrastercov5.testcase \
+	copyrastercov6.testcase \
+	copyrastercov7.testcase \
+	copyrastercov8.testcase \
+	copyrastercov9.testcase \
+	copyrastercov10.testcase \
+	copyrastercov11.testcase \
+	copyrastercov12.testcase \
+	copyrastercov13.testcase \
+	copyrastercov14.testcase \
+    createcov_16_mband1.testcase \
 	createcov_16_mband_deflate.testcase \
+	createcov_16_mband_deflateno.testcase \
 	createcov_16_mband_fax3.testcase \
 	createcov_16_mband_fax4.testcase \
 	createcov_16_mband_gif.testcase \
 	createcov_16_mband_jpeg.testcase \
 	createcov_16_mband_lzma.testcase \
+	createcov_16_mband_lzmano.testcase \
 	createcov_16_mband_png.testcase \
 	createcov_16_mband.testcase \
 	createcov_16_mband_webp1.testcase \
 	createcov_16_mband_webp2.testcase \
 	createcov_1bit_mono1.testcase \
 	createcov_1bit_mono_deflate.testcase \
+	createcov_1bit_mono_deflateno.testcase \
 	createcov_1bit_mono_fax3.testcase \
 	createcov_1bit_mono_fax4.testcase \
 	createcov_1bit_mono_gif.testcase \
 	createcov_1bit_mono_jpeg.testcase \
 	createcov_1bit_mono_lzma.testcase \
+	createcov_1bit_mono_lzmano.testcase \
 	createcov_1bit_mono_png.testcase \
 	createcov_1bit_mono.testcase \
 	createcov_1bit_mono_webp1.testcase \
@@ -299,18 +340,22 @@ EXTRA_DIST = createcov_16_mband1.testcase \
 	createcov_4bit_palette.testcase \
 	createcov_8_mband1.testcase \
 	createcov_8_mband_deflate.testcase \
+	createcov_8_mband_deflateno.testcase \
 	createcov_8_mband_fax3.testcase \
 	createcov_8_mband_fax4.testcase \
 	createcov_8_mband_gif.testcase \
 	createcov_8_mband_jpeg.testcase \
 	createcov_8_mband_lzma.testcase \
+	createcov_8_mband_lzmano.testcase \
 	createcov_8_mband_png.testcase \
 	createcov_8_mband.testcase \
 	createcov_8_mband_webp1.testcase \
 	createcov_8_mband_webp2.testcase \
 	createcov_double_grid1.testcase \
 	createcov_double_grid_deflate.testcase \
+	createcov_double_grid_deflateno.testcase \
 	createcov_double_grid_lzma.testcase \
+	createcov_double_grid_lzmano.testcase \
 	createcov_double_grid.testcase \
 	createcov_err1.testcase \
 	createcov_err2.testcase \
@@ -324,66 +369,91 @@ EXTRA_DIST = createcov_16_mband1.testcase \
 	createcov_err10.testcase \
 	createcov_err11.testcase \
 	createcov_err12.testcase \
+	createcov_err13.testcase \
+	createcov_err14.testcase \
+	createcov_err15.testcase \
+	createcov_err16.testcase \
+	createcov_err17.testcase \
 	createcov_float_grid1.testcase \
 	createcov_float_grid_deflate.testcase \
+	createcov_float_grid_deflateno.testcase \
 	createcov_float_grid_lzma.testcase \
+	createcov_float_grid_lzmano.testcase \
 	createcov_float_grid.testcase \
 	createcov_int16_grid1.testcase \
 	createcov_int16_grid_deflate.testcase \
+	createcov_int16_grid_deflateno.testcase \
 	createcov_int16_grid_lzma.testcase \
+	createcov_int16_grid_lzmano.testcase \
 	createcov_int16_grid.testcase \
 	createcov_int32_grid1.testcase \
 	createcov_int32_grid_deflate.testcase \
+	createcov_int32_grid_deflateno.testcase \
 	createcov_int32_grid_gif.testcase \
 	createcov_int32_grid_jpeg.testcase \
 	createcov_int32_grid_lzma.testcase \
+	createcov_int32_grid_lzmano.testcase \
 	createcov_int32_grid_png.testcase \
 	createcov_int32_grid.testcase \
 	createcov_int32_grid_webp1.testcase \
 	createcov_int32_grid_webp2.testcase \
 	createcov_int8_grid1.testcase \
 	createcov_int8_grid_deflate.testcase \
+	createcov_int8_grid_deflateno.testcase \
 	createcov_int8_grid_lzma.testcase \
+	createcov_int8_grid_lzmano.testcase \
 	createcov_int8_grid.testcase \
 	createcov_uint16_grid1.testcase \
 	createcov_uint16_grid_deflate.testcase \
+	createcov_uint16_grid_deflateno.testcase \
 	createcov_uint16_grid_lzma.testcase \
+	createcov_uint16_grid_lzmano.testcase \
 	createcov_uint16_grid.testcase \
 	createcov_uint32_grid1.testcase \
 	createcov_uint32_grid_deflate.testcase \
+	createcov_uint32_grid_deflateno.testcase \
 	createcov_uint32_grid_lzma.testcase \
+	createcov_uint32_grid_lzmano.testcase \
 	createcov_uint32_grid.testcase \
 	createcov_uint8_gray_deflate.testcase \
+	createcov_uint8_gray_deflateno.testcase \
 	createcov_uint8_gray_fax3.testcase \
 	createcov_uint8_gray_fax4.testcase \
 	createcov_uint8_gray_gif.testcase \
 	createcov_uint8_gray_jpeg.testcase \
 	createcov_uint8_gray_lzma.testcase \
+	createcov_uint8_gray_lzmano.testcase \
 	createcov_uint8_gray_png.testcase \
 	createcov_uint8_gray.testcase \
 	createcov_uint8_gray_webp1.testcase \
 	createcov_uint8_gray_webp2.testcase \
 	createcov_uint8_grid1.testcase \
 	createcov_uint8_grid_deflate.testcase \
+	createcov_uint8_grid_deflateno.testcase \
 	createcov_uint8_grid_lzma.testcase \
+	createcov_uint8_grid_lzmano.testcase \
 	createcov_uint8_grid.testcase \
 	createcov_uint8_palette_deflate.testcase \
+	createcov_uint8_palette_deflateno.testcase \
 	createcov_uint8_palette_fax3.testcase \
 	createcov_uint8_palette_fax4.testcase \
 	createcov_uint8_palette_gif.testcase \
 	createcov_uint8_palette_jpeg.testcase \
 	createcov_uint8_palette_lzma.testcase \
+	createcov_uint8_palette_lzmano.testcase \
 	createcov_uint8_palette_png.testcase \
 	createcov_uint8_palette.testcase \
 	createcov_uint8_palette_webp1.testcase \
 	createcov_uint8_palette_webp2.testcase \
 	createcov_uint8_rgb1.testcase \
 	createcov_uint8_rgb_deflate.testcase \
+	createcov_uint8_rgb_deflateno.testcase \
 	createcov_uint8_rgb_fax3.testcase \
 	createcov_uint8_rgb_fax4.testcase \
 	createcov_uint8_rgb_gif.testcase \
 	createcov_uint8_rgb_jpeg.testcase \
 	createcov_uint8_rgb_lzma.testcase \
+	createcov_uint8_rgb_lzmano.testcase \
 	createcov_uint8_rgb_png.testcase \
 	createcov_uint8_rgb.testcase \
 	createcov_uint8_rgb_webp1.testcase \
@@ -420,6 +490,16 @@ EXTRA_DIST = createcov_16_mband1.testcase \
 	dropcoverage1.testcase \
 	dropcoverage2.testcase \
 	dropcoverage3.testcase \
+	getfontfacename1.testcase \
+	getfontfacename2.testcase \
+	getfontfacename3.testcase \
+	getfontfacename4.testcase \
+	getfontfacename5.testcase \
+	getfontfamily1.testcase \
+	getfontfamily2.testcase \
+	getfontfamily3.testcase \
+	getfontfamily4.testcase \
+	getfontfamily5.testcase \
 	getmapimage1.testcase \
 	getmapimage2.testcase \
 	getmapimage3.testcase \
@@ -430,7 +510,7 @@ EXTRA_DIST = createcov_16_mband1.testcase \
 	getmapimage8.testcase \
 	getmapimage9.testcase \
 	getmapimage10.testcase \
-	getmapimage1.testcase \
+	getmapimage11.testcase \
 	getmapimage12.testcase \
 	getmapimage13.testcase \
 	getmapimage14.testcase \
@@ -440,6 +520,26 @@ EXTRA_DIST = createcov_16_mband1.testcase \
 	getmapimage18.testcase \
 	getmapimage19.testcase \
 	getmapimage20.testcase \
+	getvectorimage1.testcase \
+	getvectorimage2.testcase \
+	getvectorimage3.testcase \
+	getvectorimage4.testcase \
+	getvectorimage5.testcase \
+	getvectorimage6.testcase \
+	getvectorimage7.testcase \
+	getvectorimage8.testcase \
+	getvectorimage9.testcase \
+	getvectorimage10.testcase \
+	getvectorimage11.testcase \
+	getvectorimage12.testcase \
+	getvectorimage13.testcase \
+	getvectorimage14.testcase \
+	getvectorimage15.testcase \
+	getvectorimage16.testcase \
+	getvectorimage17.testcase \
+	getvectorimage18.testcase \
+	getvectorimage19.testcase \
+	getvectorimage20.testcase \
 	gettileimage1.testcase \
 	gettileimage2.testcase \
 	gettileimage3.testcase \
@@ -544,6 +644,51 @@ EXTRA_DIST = createcov_16_mband1.testcase \
 	getrasterstats24.testcase \
 	getrasterstats25.testcase \
 	getrasterstats26.testcase \
+	enableautondvi1.testcase \
+	enableautondvi2.testcase \
+	enableautondvi3.testcase \
+	exportraw1.testcase \
+	exportraw2.testcase \
+	exportraw3.testcase \
+	exportraw4.testcase \
+	exportraw5.testcase \
+	exportraw6.testcase \
+	exportraw7.testcase \
+	exportraw8.testcase \
+	exportsectraw1.testcase \
+	exportsectraw2.testcase \
+	exportsectraw3.testcase \
+	exportsectraw4.testcase \
+	exportsectraw5.testcase \
+	exportsectraw6.testcase \
+	exportsectraw7.testcase \
+	exportsectraw8.testcase \
+	exportsectraw9.testcase \
+	importraw1.testcase \
+	importraw2.testcase \
+	importraw3.testcase \
+	importraw4.testcase \
+	importraw5.testcase \
+	importraw6.testcase \
+	importraw7.testcase \
+	importraw8.testcase \
+	importraw9.testcase \
+	importraw10.testcase \
+	isautondvienabled1.testcase \
+	isautondvienabled2.testcase \
+	isautondvienabled3.testcase \
+	isautondvienabled4.testcase \
+	isautondvienabled5.testcase \
+	isfontbold1.testcase \
+	isfontbold2.testcase \
+	isfontbold3.testcase \
+	isfontbold4.testcase \
+	isfontbold5.testcase \
+	isfontitalic1.testcase \
+	isfontitalic2.testcase \
+	isfontitalic3.testcase \
+	isfontitalic4.testcase \
+	isfontitalic5.testcase \
 	ispixelopaque1.testcase \
 	ispixelopaque2.testcase \
 	ispixelopaque3.testcase \
@@ -554,6 +699,11 @@ EXTRA_DIST = createcov_16_mband1.testcase \
 	ispixeltransparent3.testcase \
 	ispixeltransparent4.testcase \
 	ispixeltransparent5.testcase \
+	isvalidfont1.testcase \
+	isvalidfont2.testcase \
+	isvalidfont3.testcase \
+	isvalidfont4.testcase \
+	isvalidfont5.testcase \
 	isvalidpalette1.testcase \
 	isvalidpalette2.testcase \
 	isvalidpalette3.testcase \
@@ -637,10 +787,33 @@ EXTRA_DIST = createcov_16_mband1.testcase \
 	pyramidize14.testcase \
 	pyramidize15.testcase \
 	pyramidize16.testcase \
+	pyramidize17.testcase \
+	pyramidize18.testcase \
+	pyramidize19.testcase \
 	setcoverageinfos1.testcase \
 	setcoverageinfos2.testcase \
 	setcoverageinfos3.testcase \
 	setcoverageinfos4.testcase \
+	setdefaultbands1.testcase \
+	setdefaultbands2.testcase \
+	setdefaultbands3.testcase \
+	setdefaultbands4.testcase \
+	setdefaultbands5.testcase \
+	setdefaultbands6.testcase \
+	setdefaultbands7.testcase \
+	setdefaultbands8.testcase \
+	setdefaultbands9.testcase \
+	setdefaultbands10.testcase \
+	setdefaultbands11.testcase \
+	setdefaultbands12.testcase \
+	setdefaultbands13.testcase \
+	setdefaultbands14.testcase \
+	setdefaultbands15.testcase \
+	setdefaultbands16.testcase \
+	setdefaultbands17.testcase \
+	setdefaultbands18.testcase \
+	setdefaultbands19.testcase \
+	setdefaultbands20.testcase \
 	setpalettecolorentry1.testcase \
 	setpalettecolorentry2.testcase \
 	setpalettecolorentry3.testcase \
@@ -710,7 +883,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__confi
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu test/sql_stmt_tests/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu test/sql_stmt_tests/Makefile
-.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -885,6 +1057,8 @@ uninstall-am:
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	tags-am uninstall uninstall-am
 
+.PRECIOUS: Makefile
+
 	version.testcase 
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/test/sql_stmt_tests/copyrastercov1.testcase b/test/sql_stmt_tests/copyrastercov1.testcase
new file mode 100644
index 0000000..4db1f2e
--- /dev/null
+++ b/test/sql_stmt_tests/copyrastercov1.testcase
@@ -0,0 +1,7 @@
+CopyRasterCoverage - NULL DB-prefix
+:memory: #use in-memory database
+SELECT RL2_CopyRasterCoverage(NULL, 'coverage');
+1 # rows (not including the header row)
+1 # columns
+RL2_CopyRasterCoverage(NULL, 'coverage')
+-1
diff --git a/test/sql_stmt_tests/copyrastercov10.testcase b/test/sql_stmt_tests/copyrastercov10.testcase
new file mode 100644
index 0000000..1a1973a
--- /dev/null
+++ b/test/sql_stmt_tests/copyrastercov10.testcase
@@ -0,0 +1,7 @@
+CopyRasterCoverage - NULL transaction
+:memory: #use in-memory database
+SELECT RL2_CopyRasterCoverage('prefix', 'coverage', NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_CopyRasterCoverage('prefix', 'coverage', NULL)
+-1
diff --git a/test/sql_stmt_tests/copyrastercov11.testcase b/test/sql_stmt_tests/copyrastercov11.testcase
new file mode 100644
index 0000000..606966c
--- /dev/null
+++ b/test/sql_stmt_tests/copyrastercov11.testcase
@@ -0,0 +1,7 @@
+CopyRasterCoverage - TEXT transaction
+:memory: #use in-memory database
+SELECT RL2_CopyRasterCoverage('prefix', 'coverage', 'yes');
+1 # rows (not including the header row)
+1 # columns
+RL2_CopyRasterCoverage('prefix', 'coverage', 'yes')
+-1
diff --git a/test/sql_stmt_tests/copyrastercov12.testcase b/test/sql_stmt_tests/copyrastercov12.testcase
new file mode 100644
index 0000000..c93d91b
--- /dev/null
+++ b/test/sql_stmt_tests/copyrastercov12.testcase
@@ -0,0 +1,7 @@
+CopyRasterCoverage - double transaction
+:memory: #use in-memory database
+SELECT RL2_CopyRasterCoverage('prefix', 'coverage', 1.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_CopyRasterCoverage('prefix', 'coverage', 1.5)
+-1
diff --git a/test/sql_stmt_tests/copyrastercov13.testcase b/test/sql_stmt_tests/copyrastercov13.testcase
new file mode 100644
index 0000000..c99c55a
--- /dev/null
+++ b/test/sql_stmt_tests/copyrastercov13.testcase
@@ -0,0 +1,7 @@
+CopyRasterCoverage - BLOB transaction
+:memory: #use in-memory database
+SELECT RL2_CopyRasterCoverage('prefix', 'coverage', zeroblob(4));
+1 # rows (not including the header row)
+1 # columns
+RL2_CopyRasterCoverage('prefix', 'coverage', zeroblob(4))
+-1
diff --git a/test/sql_stmt_tests/copyrastercov14.testcase b/test/sql_stmt_tests/copyrastercov14.testcase
new file mode 100644
index 0000000..d003b9f
--- /dev/null
+++ b/test/sql_stmt_tests/copyrastercov14.testcase
@@ -0,0 +1,7 @@
+CopyRasterCoverage - OK - 3 args
+:memory: #use in-memory database
+SELECT RL2_CopyRasterCoverage('prefix', 'coverage', 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_CopyRasterCoverage('prefix', 'coverage', 1)
+0
diff --git a/test/sql_stmt_tests/copyrastercov2.testcase b/test/sql_stmt_tests/copyrastercov2.testcase
new file mode 100644
index 0000000..e986383
--- /dev/null
+++ b/test/sql_stmt_tests/copyrastercov2.testcase
@@ -0,0 +1,7 @@
+CopyRasterCoverage - int DB-prefix
+:memory: #use in-memory database
+SELECT RL2_CopyRasterCoverage(1, 'coverage');
+1 # rows (not including the header row)
+1 # columns
+RL2_CopyRasterCoverage(1, 'coverage')
+-1
diff --git a/test/sql_stmt_tests/copyrastercov3.testcase b/test/sql_stmt_tests/copyrastercov3.testcase
new file mode 100644
index 0000000..fc7e270
--- /dev/null
+++ b/test/sql_stmt_tests/copyrastercov3.testcase
@@ -0,0 +1,7 @@
+CopyRasterCoverage - double DB-prefix
+:memory: #use in-memory database
+SELECT RL2_CopyRasterCoverage(1.5, 'coverage');
+1 # rows (not including the header row)
+1 # columns
+RL2_CopyRasterCoverage(1.5, 'coverage')
+-1
diff --git a/test/sql_stmt_tests/copyrastercov4.testcase b/test/sql_stmt_tests/copyrastercov4.testcase
new file mode 100644
index 0000000..c5a029b
--- /dev/null
+++ b/test/sql_stmt_tests/copyrastercov4.testcase
@@ -0,0 +1,7 @@
+CopyRasterCoverage - BLOB DB-prefix
+:memory: #use in-memory database
+SELECT RL2_CopyRasterCoverage(zeroblob(4), 'coverage');
+1 # rows (not including the header row)
+1 # columns
+RL2_CopyRasterCoverage(zeroblob(4), 'coverage')
+-1
diff --git a/test/sql_stmt_tests/copyrastercov5.testcase b/test/sql_stmt_tests/copyrastercov5.testcase
new file mode 100644
index 0000000..87e01bf
--- /dev/null
+++ b/test/sql_stmt_tests/copyrastercov5.testcase
@@ -0,0 +1,7 @@
+CopyRasterCoverage - NULL coverage
+:memory: #use in-memory database
+SELECT RL2_CopyRasterCoverage('prefix', NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_CopyRasterCoverage('prefix', NULL)
+-1
diff --git a/test/sql_stmt_tests/copyrastercov6.testcase b/test/sql_stmt_tests/copyrastercov6.testcase
new file mode 100644
index 0000000..39ba68d
--- /dev/null
+++ b/test/sql_stmt_tests/copyrastercov6.testcase
@@ -0,0 +1,7 @@
+CopyRasterCoverage - int coverage
+:memory: #use in-memory database
+SELECT RL2_CopyRasterCoverage('prefix', 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_CopyRasterCoverage('prefix', 1)
+-1
diff --git a/test/sql_stmt_tests/copyrastercov7.testcase b/test/sql_stmt_tests/copyrastercov7.testcase
new file mode 100644
index 0000000..bcae1d5
--- /dev/null
+++ b/test/sql_stmt_tests/copyrastercov7.testcase
@@ -0,0 +1,7 @@
+CopyRasterCoverage - double coverage
+:memory: #use in-memory database
+SELECT RL2_CopyRasterCoverage('prefix', 1.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_CopyRasterCoverage('prefix', 1.5)
+-1
diff --git a/test/sql_stmt_tests/copyrastercov8.testcase b/test/sql_stmt_tests/copyrastercov8.testcase
new file mode 100644
index 0000000..bcae1d5
--- /dev/null
+++ b/test/sql_stmt_tests/copyrastercov8.testcase
@@ -0,0 +1,7 @@
+CopyRasterCoverage - double coverage
+:memory: #use in-memory database
+SELECT RL2_CopyRasterCoverage('prefix', 1.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_CopyRasterCoverage('prefix', 1.5)
+-1
diff --git a/test/sql_stmt_tests/copyrastercov9.testcase b/test/sql_stmt_tests/copyrastercov9.testcase
new file mode 100644
index 0000000..846e600
--- /dev/null
+++ b/test/sql_stmt_tests/copyrastercov9.testcase
@@ -0,0 +1,7 @@
+CopyRasterCoverage - OK - 2 args
+:memory: #use in-memory database
+SELECT RL2_CopyRasterCoverage('prefix', 'coverage');
+1 # rows (not including the header row)
+1 # columns
+RL2_CopyRasterCoverage('prefix', 'coverage')
+0
diff --git a/test/sql_stmt_tests/createcov_16_mband.testcase b/test/sql_stmt_tests/createcov_16_mband.testcase
index 8e172be..a488bfd 100644
--- a/test/sql_stmt_tests/createcov_16_mband.testcase
+++ b/test/sql_stmt_tests/createcov_16_mband.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT16 MULTIBAND
+RL2_CreateRasterCoverage - UINT16 MULTIBAND
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint16_multiband', 'UINT16', 'MULTIBAND', 4, 'NONE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint16_multiband', 'UINT16', 'MULTIBAND', 4, 'NONE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint16_multiband', 'UINT16', 'MULTIBAND', 4, 'NONE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint16_multiband', 'UINT16', 'MULTIBAND', 4, 'NONE', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_16_mband1.testcase b/test/sql_stmt_tests/createcov_16_mband1.testcase
index 948942c..8c17352 100644
--- a/test/sql_stmt_tests/createcov_16_mband1.testcase
+++ b/test/sql_stmt_tests/createcov_16_mband1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT16 MULTIBAND invalid Bands
+RL2_CreateRasterCoverage - UINT16 MULTIBAND invalid Bands
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint16_multiband1', 'UINT16', 'MULTIBAND', 1, 'NONE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint16_multiband1', 'UINT16', 'MULTIBAND', 1, 'NONE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint16_multiband1', 'UINT16', 'MULTIBAND', 1, 'NONE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint16_multiband1', 'UINT16', 'MULTIBAND', 1, 'NONE', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_16_mband_deflate.testcase b/test/sql_stmt_tests/createcov_16_mband_deflate.testcase
index ce1d022..7b40c9e 100644
--- a/test/sql_stmt_tests/createcov_16_mband_deflate.testcase
+++ b/test/sql_stmt_tests/createcov_16_mband_deflate.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT16 MULTIBAND DEFLATE
+RL2_CreateRasterCoverage - UINT16 MULTIBAND DEFLATE
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint16_multiband_deflate', 'UINT16', 'MULTIBAND', 4, 'DEFLATE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint16_multiband_deflate', 'UINT16', 'MULTIBAND', 4, 'DEFLATE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint16_multiband_deflate', 'UINT16', 'MULTIBAND', 4, 'DEFLATE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint16_multiband_deflate', 'UINT16', 'MULTIBAND', 4, 'DEFLATE', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_16_mband_deflateno.testcase b/test/sql_stmt_tests/createcov_16_mband_deflateno.testcase
new file mode 100644
index 0000000..e83e392
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_16_mband_deflateno.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - UINT16 MULTIBAND DEFLATE_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('uint16_multiband_deflateno', 'UINT16', 'MULTIBAND', 4, 'DEFLATE_NO', 100, 512, 512, 3003, 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('uint16_multiband_deflateno', 'UINT16', 'MULTIBAND', 4, 'DEFLATE_NO', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_16_mband_fax3.testcase b/test/sql_stmt_tests/createcov_16_mband_fax3.testcase
index f78b49a..4dfa9ee 100644
--- a/test/sql_stmt_tests/createcov_16_mband_fax3.testcase
+++ b/test/sql_stmt_tests/createcov_16_mband_fax3.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT16 MULTIBAND FAX3
+RL2_CreateRasterCoverage - UINT16 MULTIBAND FAX3
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint16_multiband_fax3', 'UINT16', 'MULTIBAND', 4, 'FAX3', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint16_multiband_fax3', 'UINT16', 'MULTIBAND', 4, 'FAX3', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint16_multiband_fax3', 'UINT16', 'MULTIBAND', 4, 'FAX3', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint16_multiband_fax3', 'UINT16', 'MULTIBAND', 4, 'FAX3', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_16_mband_fax4.testcase b/test/sql_stmt_tests/createcov_16_mband_fax4.testcase
index f17e582..ecd0d47 100644
--- a/test/sql_stmt_tests/createcov_16_mband_fax4.testcase
+++ b/test/sql_stmt_tests/createcov_16_mband_fax4.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT16 MULTIBAND FAX4
+RL2_CreateRasterCoverage - UINT16 MULTIBAND FAX4
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint16_multiband_fax4', 'UINT16', 'MULTIBAND', 4, 'FAX4', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint16_multiband_fax4', 'UINT16', 'MULTIBAND', 4, 'FAX4', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint16_multiband_fax4', 'UINT16', 'MULTIBAND', 4, 'FAX4', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint16_multiband_fax4', 'UINT16', 'MULTIBAND', 4, 'FAX4', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_16_mband_gif.testcase b/test/sql_stmt_tests/createcov_16_mband_gif.testcase
index d425e39..4154957 100644
--- a/test/sql_stmt_tests/createcov_16_mband_gif.testcase
+++ b/test/sql_stmt_tests/createcov_16_mband_gif.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT16 MULTIBAND GIF
+RL2_CreateRasterCoverage - UINT16 MULTIBAND GIF
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint16_multiband_gif', 'UINT16', 'MULTIBAND', 4, 'GIF', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint16_multiband_gif', 'UINT16', 'MULTIBAND', 4, 'GIF', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint16_multiband_gif', 'UINT16', 'MULTIBAND', 4, 'GIF', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint16_multiband_gif', 'UINT16', 'MULTIBAND', 4, 'GIF', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_16_mband_jpeg.testcase b/test/sql_stmt_tests/createcov_16_mband_jpeg.testcase
index 3c45395..bfb5e27 100644
--- a/test/sql_stmt_tests/createcov_16_mband_jpeg.testcase
+++ b/test/sql_stmt_tests/createcov_16_mband_jpeg.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT16 MULTIBAND JPEG
+RL2_CreateRasterCoverage - UINT16 MULTIBAND JPEG
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint16_multiband_jpeg', 'UINT16', 'MULTIBAND', 4, 'JPEG', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint16_multiband_jpeg', 'UINT16', 'MULTIBAND', 4, 'JPEG', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint16_multiband_jpeg', 'UINT16', 'MULTIBAND', 4, 'JPEG', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint16_multiband_jpeg', 'UINT16', 'MULTIBAND', 4, 'JPEG', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_16_mband_lzma.testcase b/test/sql_stmt_tests/createcov_16_mband_lzma.testcase
index 6b4acb3..50bea84 100644
--- a/test/sql_stmt_tests/createcov_16_mband_lzma.testcase
+++ b/test/sql_stmt_tests/createcov_16_mband_lzma.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT16 MULTIBAND LZMA
+RL2_CreateRasterCoverage - UINT16 MULTIBAND LZMA
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint16_multiband_lzma', 'UINT16', 'MULTIBAND', 4, 'LZMA', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint16_multiband_lzma', 'UINT16', 'MULTIBAND', 4, 'LZMA', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint16_multiband_lzma', 'UINT16', 'MULTIBAND', 4, 'LZMA', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint16_multiband_lzma', 'UINT16', 'MULTIBAND', 4, 'LZMA', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_16_mband_lzmano.testcase b/test/sql_stmt_tests/createcov_16_mband_lzmano.testcase
new file mode 100644
index 0000000..35e292c
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_16_mband_lzmano.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - UINT16 MULTIBAND LZMA_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('uint16_multiband_lzmano', 'UINT16', 'MULTIBAND', 4, 'LZMA_NO', 100, 512, 512, 3003, 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('uint16_multiband_lzmano', 'UINT16', 'MULTIBAND', 4, 'LZMA_NO', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_16_mband_png.testcase b/test/sql_stmt_tests/createcov_16_mband_png.testcase
index 935d850..eff293c 100644
--- a/test/sql_stmt_tests/createcov_16_mband_png.testcase
+++ b/test/sql_stmt_tests/createcov_16_mband_png.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT16 MULTIBAND PNG
+RL2_CreateRasterCoverage - UINT16 MULTIBAND PNG
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint16_multiband_png', 'UINT16', 'MULTIBAND', 4, 'PNG', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint16_multiband_png', 'UINT16', 'MULTIBAND', 4, 'PNG', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint16_multiband_png', 'UINT16', 'MULTIBAND', 4, 'PNG', 100, 512, 512, 3003, 1.0)
-0
+RL2_CreateRasterCoverage('uint16_multiband_png', 'UINT16', 'MULTIBAND', 4, 'PNG', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_16_mband_webp1.testcase b/test/sql_stmt_tests/createcov_16_mband_webp1.testcase
index 600a90b..5075eb8 100644
--- a/test/sql_stmt_tests/createcov_16_mband_webp1.testcase
+++ b/test/sql_stmt_tests/createcov_16_mband_webp1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT16 MULTIBAND LOSSY WEBP
+RL2_CreateRasterCoverage - UINT16 MULTIBAND LOSSY WEBP
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint16_multiband_webp1', 'UINT16', 'MULTIBAND', 4, 'WEBP', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint16_multiband_webp1', 'UINT16', 'MULTIBAND', 4, 'WEBP', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint16_multiband_webp1', 'UINT16', 'MULTIBAND', 4, 'WEBP', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint16_multiband_webp1', 'UINT16', 'MULTIBAND', 4, 'WEBP', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_16_mband_webp2.testcase b/test/sql_stmt_tests/createcov_16_mband_webp2.testcase
index 14758af..a46ac90 100644
--- a/test/sql_stmt_tests/createcov_16_mband_webp2.testcase
+++ b/test/sql_stmt_tests/createcov_16_mband_webp2.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT16 MULTIBAND LOSSLESS WEBP
+RL2_CreateRasterCoverage - UINT16 MULTIBAND LOSSLESS WEBP
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint16_multiband_webp2', 'UINT16', 'MULTIBAND', 4, 'LL_WEBP', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint16_multiband_webp2', 'UINT16', 'MULTIBAND', 4, 'LL_WEBP', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint16_multiband_webp2', 'UINT16', 'MULTIBAND', 4, 'LL_WEBP', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint16_multiband_webp2', 'UINT16', 'MULTIBAND', 4, 'LL_WEBP', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_1bit_mono.testcase b/test/sql_stmt_tests/createcov_1bit_mono.testcase
index 07ad7cc..8b671a1 100644
--- a/test/sql_stmt_tests/createcov_1bit_mono.testcase
+++ b/test/sql_stmt_tests/createcov_1bit_mono.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 1-BIT MONOCHROME 
+RL2_CreateRasterCoverage - 1-BIT MONOCHROME 
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('1bit_mono', '1-BIT', 'MONOCHROME', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, RL2_SetPixelValue(RL2_CreatePixel('1-BIT', 'MONOCHROME', 1), 0, 1));
+SELECT RL2_CreateRasterCoverage('1bit_mono', '1-BIT', 'MONOCHROME', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, RL2_SetPixelValue(RL2_CreatePixel('1-BIT', 'MONOCHROME', 1), 0, 1));
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('1bit_mono', '1-BIT', 'MONOCHROME', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, RL2_SetPixelValue(RL2_CreatePixel('1-BIT', 'MONOCHROME', 1), 0, 1))
+RL2_CreateRasterCoverage('1bit_mono', '1-BIT', 'MONOCHROME', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, RL2_SetPixelValue(RL2_CreatePixel('1-BIT', 'MONOCHROME', 1), 0, 1))
 1
diff --git a/test/sql_stmt_tests/createcov_1bit_mono1.testcase b/test/sql_stmt_tests/createcov_1bit_mono1.testcase
index 6cedd9e..6ee3b5d 100644
--- a/test/sql_stmt_tests/createcov_1bit_mono1.testcase
+++ b/test/sql_stmt_tests/createcov_1bit_mono1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 1-BIT MONOCHROME invalid Bands
+RL2_CreateRasterCoverage - 1-BIT MONOCHROME invalid Bands
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('1bit_mono1', '1-BIT', 'MONOCHROME', 2, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('1bit_mono1', '1-BIT', 'MONOCHROME', 2, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('1bit_mono1', '1-BIT', 'MONOCHROME', 2, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('1bit_mono1', '1-BIT', 'MONOCHROME', 2, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL)
 0
diff --git a/test/sql_stmt_tests/createcov_1bit_mono_deflate.testcase b/test/sql_stmt_tests/createcov_1bit_mono_deflate.testcase
index 902f763..2a170fe 100644
--- a/test/sql_stmt_tests/createcov_1bit_mono_deflate.testcase
+++ b/test/sql_stmt_tests/createcov_1bit_mono_deflate.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 1-BIT MONOCHROME DEFLATE
+RL2_CreateRasterCoverage - 1-BIT MONOCHROME DEFLATE
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('1bit_mono_deflate', '1-BIT', 'MONOCHROME', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('1bit_mono_deflate', '1-BIT', 'MONOCHROME', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('1bit_mono_deflate', '1-BIT', 'MONOCHROME', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0, 1.0, NULL)
-0
+RL2_CreateRasterCoverage('1bit_mono_deflate', '1-BIT', 'MONOCHROME', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0, 1.0, NULL)
+1
diff --git a/test/sql_stmt_tests/createcov_1bit_mono_deflateno.testcase b/test/sql_stmt_tests/createcov_1bit_mono_deflateno.testcase
new file mode 100644
index 0000000..479fd5b
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_1bit_mono_deflateno.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - 1-BIT MONOCHROME DEFLATE_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('1bit_mono_deflateno', '1-BIT', 'MONOCHROME', 1, 'DEFLATE_NO', 100, 512, 512, 3003, 1.0, 1.0, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('1bit_mono_deflateno', '1-BIT', 'MONOCHROME', 1, 'DEFLATE_NO', 100, 512, 512, 3003, 1.0, 1.0, NULL)
+1
diff --git a/test/sql_stmt_tests/createcov_1bit_mono_fax3.testcase b/test/sql_stmt_tests/createcov_1bit_mono_fax3.testcase
index 5424b97..94786fc 100644
--- a/test/sql_stmt_tests/createcov_1bit_mono_fax3.testcase
+++ b/test/sql_stmt_tests/createcov_1bit_mono_fax3.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 1-BIT MONOCHROME FAX3
+RL2_CreateRasterCoverage - 1-BIT MONOCHROME FAX3
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('1bit_mono_fax3', '1-BIT', 'MONOCHROME', 1, 'FAX3', 100, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('1bit_mono_fax3', '1-BIT', 'MONOCHROME', 1, 'FAX3', 100, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('1bit_mono_fax3', '1-BIT', 'MONOCHROME', 1, 'FAX3', 100, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('1bit_mono_fax3', '1-BIT', 'MONOCHROME', 1, 'FAX3', 100, 512, 512, 3003, 1.0, 1.0, NULL)
 0
diff --git a/test/sql_stmt_tests/createcov_1bit_mono_fax4.testcase b/test/sql_stmt_tests/createcov_1bit_mono_fax4.testcase
index 544f949..bae4307 100644
--- a/test/sql_stmt_tests/createcov_1bit_mono_fax4.testcase
+++ b/test/sql_stmt_tests/createcov_1bit_mono_fax4.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 1-BIT MONOCHROME FAX4
+RL2_CreateRasterCoverage - 1-BIT MONOCHROME FAX4
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('1bit_mono_fax4', '1-BIT', 'MONOCHROME', 1, 'FAX4', 100, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('1bit_mono_fax4', '1-BIT', 'MONOCHROME', 1, 'FAX4', 100, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('1bit_mono_fax4', '1-BIT', 'MONOCHROME', 1, 'FAX4', 100, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('1bit_mono_fax4', '1-BIT', 'MONOCHROME', 1, 'FAX4', 100, 512, 512, 3003, 1.0, 1.0, NULL)
 1
diff --git a/test/sql_stmt_tests/createcov_1bit_mono_gif.testcase b/test/sql_stmt_tests/createcov_1bit_mono_gif.testcase
index 0e233c1..8995c74 100644
--- a/test/sql_stmt_tests/createcov_1bit_mono_gif.testcase
+++ b/test/sql_stmt_tests/createcov_1bit_mono_gif.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 1-BIT MONOCHROME GIF
+RL2_CreateRasterCoverage - 1-BIT MONOCHROME GIF
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('1bit_mono_gif', '1-BIT', 'MONOCHROME', 1, 'GIF', 100, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('1bit_mono_gif', '1-BIT', 'MONOCHROME', 1, 'GIF', 100, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('1bit_mono_gif', '1-BIT', 'MONOCHROME', 1, 'GIF', 100, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('1bit_mono_gif', '1-BIT', 'MONOCHROME', 1, 'GIF', 100, 512, 512, 3003, 1.0, 1.0, NULL)
 0
diff --git a/test/sql_stmt_tests/createcov_1bit_mono_jpeg.testcase b/test/sql_stmt_tests/createcov_1bit_mono_jpeg.testcase
index f4de5ee..548a772 100644
--- a/test/sql_stmt_tests/createcov_1bit_mono_jpeg.testcase
+++ b/test/sql_stmt_tests/createcov_1bit_mono_jpeg.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 1-BIT MONOCHROME JPEG
+RL2_CreateRasterCoverage - 1-BIT MONOCHROME JPEG
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('1bit_mono_jpeg', '1-BIT', 'MONOCHROME', 1, 'JPEG', 100, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('1bit_mono_jpeg', '1-BIT', 'MONOCHROME', 1, 'JPEG', 100, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('1bit_mono_jpeg', '1-BIT', 'MONOCHROME', 1, 'JPEG', 100, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('1bit_mono_jpeg', '1-BIT', 'MONOCHROME', 1, 'JPEG', 100, 512, 512, 3003, 1.0, 1.0, NULL)
 0
diff --git a/test/sql_stmt_tests/createcov_1bit_mono_lzma.testcase b/test/sql_stmt_tests/createcov_1bit_mono_lzma.testcase
index 185d0cd..4882286 100644
--- a/test/sql_stmt_tests/createcov_1bit_mono_lzma.testcase
+++ b/test/sql_stmt_tests/createcov_1bit_mono_lzma.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 1-BIT MONOCHROME LZMA
+RL2_CreateRasterCoverage - 1-BIT MONOCHROME LZMA
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('1bit_mono_lzma', '1-BIT', 'MONOCHROME', 1, 'LZMA', 100, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('1bit_mono_lzma', '1-BIT', 'MONOCHROME', 1, 'LZMA', 100, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('1bit_mono_lzma', '1-BIT', 'MONOCHROME', 1, 'LZMA', 100, 512, 512, 3003, 1.0, 1.0, NULL)
-0
+RL2_CreateRasterCoverage('1bit_mono_lzma', '1-BIT', 'MONOCHROME', 1, 'LZMA', 100, 512, 512, 3003, 1.0, 1.0, NULL)
+1
diff --git a/test/sql_stmt_tests/createcov_1bit_mono_lzmano.testcase b/test/sql_stmt_tests/createcov_1bit_mono_lzmano.testcase
new file mode 100644
index 0000000..98d7e9f
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_1bit_mono_lzmano.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - 1-BIT MONOCHROME LZMA_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('1bit_mono_lzmano', '1-BIT', 'MONOCHROME', 1, 'LZMA_NO', 100, 512, 512, 3003, 1.0, 1.0, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('1bit_mono_lzmano', '1-BIT', 'MONOCHROME', 1, 'LZMA_NO', 100, 512, 512, 3003, 1.0, 1.0, NULL)
+1
diff --git a/test/sql_stmt_tests/createcov_1bit_mono_png.testcase b/test/sql_stmt_tests/createcov_1bit_mono_png.testcase
index 2e6781c..8c2ab5e 100644
--- a/test/sql_stmt_tests/createcov_1bit_mono_png.testcase
+++ b/test/sql_stmt_tests/createcov_1bit_mono_png.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 1-BIT MONOCHROME PNG
+RL2_CreateRasterCoverage - 1-BIT MONOCHROME PNG
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('1bit_mono_gif', '1-BIT', 'MONOCHROME', 1, 'PNG', 100, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('1bit_mono_gif', '1-BIT', 'MONOCHROME', 1, 'PNG', 100, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('1bit_mono_gif', '1-BIT', 'MONOCHROME', 1, 'PNG', 100, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('1bit_mono_gif', '1-BIT', 'MONOCHROME', 1, 'PNG', 100, 512, 512, 3003, 1.0, 1.0, NULL)
 1
diff --git a/test/sql_stmt_tests/createcov_1bit_mono_webp1.testcase b/test/sql_stmt_tests/createcov_1bit_mono_webp1.testcase
index 6ed3131..0c12b18 100644
--- a/test/sql_stmt_tests/createcov_1bit_mono_webp1.testcase
+++ b/test/sql_stmt_tests/createcov_1bit_mono_webp1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 1-BIT MONOCHROME LOSSY WEBP
+RL2_CreateRasterCoverage - 1-BIT MONOCHROME LOSSY WEBP
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('1bit_mono_webp1', '1-BIT', 'MONOCHROME', 1, 'WEBP', 100, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('1bit_mono_webp1', '1-BIT', 'MONOCHROME', 1, 'WEBP', 100, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('1bit_mono_webp1', '1-BIT', 'MONOCHROME', 1, 'WEBP', 100, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('1bit_mono_webp1', '1-BIT', 'MONOCHROME', 1, 'WEBP', 100, 512, 512, 3003, 1.0, 1.0, NULL)
 0
diff --git a/test/sql_stmt_tests/createcov_1bit_mono_webp2.testcase b/test/sql_stmt_tests/createcov_1bit_mono_webp2.testcase
index 3a2d952..4578f92 100644
--- a/test/sql_stmt_tests/createcov_1bit_mono_webp2.testcase
+++ b/test/sql_stmt_tests/createcov_1bit_mono_webp2.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 1-BIT MONOCHROME LOSSLESS WEBP
+RL2_CreateRasterCoverage - 1-BIT MONOCHROME LOSSLESS WEBP
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('1bit_mono_webp2', '1-BIT', 'MONOCHROME', 1, 'LL_WEBP', 100, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('1bit_mono_webp2', '1-BIT', 'MONOCHROME', 1, 'LL_WEBP', 100, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('1bit_mono_webp2', '1-BIT', 'MONOCHROME', 1, 'LL_WEBP', 100, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('1bit_mono_webp2', '1-BIT', 'MONOCHROME', 1, 'LL_WEBP', 100, 512, 512, 3003, 1.0, 1.0, NULL)
 0
diff --git a/test/sql_stmt_tests/createcov_1bit_palette.testcase b/test/sql_stmt_tests/createcov_1bit_palette.testcase
index be9f0cc..6552592 100644
--- a/test/sql_stmt_tests/createcov_1bit_palette.testcase
+++ b/test/sql_stmt_tests/createcov_1bit_palette.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 1-BIT PALETTE
+RL2_CreateRasterCoverage - 1-BIT PALETTE
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('1bit_palette', '1-BIT', 'PALETTE', 1, 'NONE', 100, 256, 256, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('1bit_palette', '1-BIT', 'PALETTE', 1, 'NONE', 100, 256, 256, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('1bit_palette', '1-BIT', 'PALETTE', 1, 'NONE', 100, 256, 256, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('1bit_palette', '1-BIT', 'PALETTE', 1, 'NONE', 100, 256, 256, 3003, 1.0, 1.0, NULL)
 1
diff --git a/test/sql_stmt_tests/createcov_1bit_palette1.testcase b/test/sql_stmt_tests/createcov_1bit_palette1.testcase
index 86db406..e9b6103 100644
--- a/test/sql_stmt_tests/createcov_1bit_palette1.testcase
+++ b/test/sql_stmt_tests/createcov_1bit_palette1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 1-BIT PALETTE invalid Bands
+RL2_CreateRasterCoverage - 1-BIT PALETTE invalid Bands
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('1bit_palette1', '1-BIT', 'PALETTE', 2, 'NONE', 100, 256, 256, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('1bit_palette1', '1-BIT', 'PALETTE', 2, 'NONE', 100, 256, 256, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('1bit_palette1', '1-BIT', 'PALETTE', 2, 'NONE', 100, 256, 256, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('1bit_palette1', '1-BIT', 'PALETTE', 2, 'NONE', 100, 256, 256, 3003, 1.0, 1.0, NULL)
 0
diff --git a/test/sql_stmt_tests/createcov_1bit_palette_gif.testcase b/test/sql_stmt_tests/createcov_1bit_palette_gif.testcase
index 661fb82..4db9ec7 100644
--- a/test/sql_stmt_tests/createcov_1bit_palette_gif.testcase
+++ b/test/sql_stmt_tests/createcov_1bit_palette_gif.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 1-BIT PALETTE GIF
+RL2_CreateRasterCoverage - 1-BIT PALETTE GIF
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('1bit_palette_gif', '1-BIT', 'PALETTE', 1, 'GIF', 100, 256, 256, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('1bit_palette_gif', '1-BIT', 'PALETTE', 1, 'GIF', 100, 256, 256, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('1bit_palette_gif', '1-BIT', 'PALETTE', 1, 'GIF', 100, 256, 256, 3003, 1.0)
+RL2_CreateRasterCoverage('1bit_palette_gif', '1-BIT', 'PALETTE', 1, 'GIF', 100, 256, 256, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_1bit_palette_png.testcase b/test/sql_stmt_tests/createcov_1bit_palette_png.testcase
index 815bf79..7ac4a7b 100644
--- a/test/sql_stmt_tests/createcov_1bit_palette_png.testcase
+++ b/test/sql_stmt_tests/createcov_1bit_palette_png.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 1-BIT PALETTE PNG
+RL2_CreateRasterCoverage - 1-BIT PALETTE PNG
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('1bit_palette_png', '1-BIT', 'PALETTE', 1, 'PNG', 100, 256, 256, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('1bit_palette_png', '1-BIT', 'PALETTE', 1, 'PNG', 100, 256, 256, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('1bit_palette_png', '1-BIT', 'PALETTE', 1, 'PNG', 100, 256, 256, 3003, 1.0)
+RL2_CreateRasterCoverage('1bit_palette_png', '1-BIT', 'PALETTE', 1, 'PNG', 100, 256, 256, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_2bit_gray.testcase b/test/sql_stmt_tests/createcov_2bit_gray.testcase
index bbdb12d..34f8857 100644
--- a/test/sql_stmt_tests/createcov_2bit_gray.testcase
+++ b/test/sql_stmt_tests/createcov_2bit_gray.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 2-BIT GRAYSCALE
+RL2_CreateRasterCoverage - 2-BIT GRAYSCALE
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('2bit_gray', '2-BIT', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('2bit_gray', '2-BIT', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('2bit_gray', '2-BIT', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('2bit_gray', '2-BIT', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_2bit_gray1.testcase b/test/sql_stmt_tests/createcov_2bit_gray1.testcase
index ba0bcc3..092bbd4 100644
--- a/test/sql_stmt_tests/createcov_2bit_gray1.testcase
+++ b/test/sql_stmt_tests/createcov_2bit_gray1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 2-BIT GRAYSCALE invalid Bands
+RL2_CreateRasterCoverage - 2-BIT GRAYSCALE invalid Bands
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('2bit_gray1', '2-BIT', 'GRAYSCALE', 2, 'NONE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('2bit_gray1', '2-BIT', 'GRAYSCALE', 2, 'NONE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('2bit_gray1', '2-BIT', 'GRAYSCALE', 2, 'NONE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('2bit_gray1', '2-BIT', 'GRAYSCALE', 2, 'NONE', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_2bit_gray_gif.testcase b/test/sql_stmt_tests/createcov_2bit_gray_gif.testcase
index ee44b81..d7103e3 100644
--- a/test/sql_stmt_tests/createcov_2bit_gray_gif.testcase
+++ b/test/sql_stmt_tests/createcov_2bit_gray_gif.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 2-BIT GRAYSCALE GIF
+RL2_CreateRasterCoverage - 2-BIT GRAYSCALE GIF
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('2bit_gray_gif', '2-BIT', 'GRAYSCALE', 1, 'GIF', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('2bit_gray_gif', '2-BIT', 'GRAYSCALE', 1, 'GIF', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('2bit_gray_gif', '2-BIT', 'GRAYSCALE', 1, 'GIF', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('2bit_gray_gif', '2-BIT', 'GRAYSCALE', 1, 'GIF', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_2bit_gray_jpeg.testcase b/test/sql_stmt_tests/createcov_2bit_gray_jpeg.testcase
index 161d3f6..0bc38df 100644
--- a/test/sql_stmt_tests/createcov_2bit_gray_jpeg.testcase
+++ b/test/sql_stmt_tests/createcov_2bit_gray_jpeg.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 2-BIT GRAYSCALE JPEG
+RL2_CreateRasterCoverage - 2-BIT GRAYSCALE JPEG
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('2bit_gray_jpeg', '2-BIT', 'GRAYSCALE', 1, 'JPEG', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('2bit_gray_jpeg', '2-BIT', 'GRAYSCALE', 1, 'JPEG', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('2bit_gray_jpeg', '2-BIT', 'GRAYSCALE', 1, 'JPEG', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('2bit_gray_jpeg', '2-BIT', 'GRAYSCALE', 1, 'JPEG', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_2bit_gray_png.testcase b/test/sql_stmt_tests/createcov_2bit_gray_png.testcase
index ed3aa53..a4c9f33 100644
--- a/test/sql_stmt_tests/createcov_2bit_gray_png.testcase
+++ b/test/sql_stmt_tests/createcov_2bit_gray_png.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 2-BIT GRAYSCALE PNG
+RL2_CreateRasterCoverage - 2-BIT GRAYSCALE PNG
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('2bit_gray_png', '2-BIT', 'GRAYSCALE', 1, 'PNG', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('2bit_gray_png', '2-BIT', 'GRAYSCALE', 1, 'PNG', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('2bit_gray_png', '2-BIT', 'GRAYSCALE', 1, 'PNG', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('2bit_gray_png', '2-BIT', 'GRAYSCALE', 1, 'PNG', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_2bit_gray_webp1.testcase b/test/sql_stmt_tests/createcov_2bit_gray_webp1.testcase
index bde0548..241fd0e 100644
--- a/test/sql_stmt_tests/createcov_2bit_gray_webp1.testcase
+++ b/test/sql_stmt_tests/createcov_2bit_gray_webp1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 2-BIT GRAYSCALE LOSSY WEBP
+RL2_CreateRasterCoverage - 2-BIT GRAYSCALE LOSSY WEBP
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('2bit_gray_webp1', '2-BIT', 'GRAYSCALE', 1, 'WEBP', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('2bit_gray_webp1', '2-BIT', 'GRAYSCALE', 1, 'WEBP', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('2bit_gray_webp1', '2-BIT', 'GRAYSCALE', 1, 'WEBP', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('2bit_gray_webp1', '2-BIT', 'GRAYSCALE', 1, 'WEBP', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_2bit_gray_webp2.testcase b/test/sql_stmt_tests/createcov_2bit_gray_webp2.testcase
index 218d977..b4ab3f5 100644
--- a/test/sql_stmt_tests/createcov_2bit_gray_webp2.testcase
+++ b/test/sql_stmt_tests/createcov_2bit_gray_webp2.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 2-BIT GRAYSCALE LOSSLESS WEBP
+RL2_CreateRasterCoverage - 2-BIT GRAYSCALE LOSSLESS WEBP
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('2bit_gray_webp2', '2-BIT', 'GRAYSCALE', 1, 'LL_WEBP', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('2bit_gray_webp2', '2-BIT', 'GRAYSCALE', 1, 'LL_WEBP', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('2bit_gray_webp2', '2-BIT', 'GRAYSCALE', 1, 'LL_WEBP', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('2bit_gray_webp2', '2-BIT', 'GRAYSCALE', 1, 'LL_WEBP', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_2bit_palette.testcase b/test/sql_stmt_tests/createcov_2bit_palette.testcase
index 7176689..4a28b88 100644
--- a/test/sql_stmt_tests/createcov_2bit_palette.testcase
+++ b/test/sql_stmt_tests/createcov_2bit_palette.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 2-BIT PALETTE
+RL2_CreateRasterCoverage - 2-BIT PALETTE
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('2bit_palette', '2-BIT', 'PALETTE', 1, 'NONE', 100, 256, 256, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('2bit_palette', '2-BIT', 'PALETTE', 1, 'NONE', 100, 256, 256, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('2bit_palette', '2-BIT', 'PALETTE', 1, 'NONE', 100, 256, 256, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('2bit_palette', '2-BIT', 'PALETTE', 1, 'NONE', 100, 256, 256, 3003, 1.0, 1.0, NULL)
 1
diff --git a/test/sql_stmt_tests/createcov_2bit_palette1.testcase b/test/sql_stmt_tests/createcov_2bit_palette1.testcase
index 4ea8cec..1ca01c7 100644
--- a/test/sql_stmt_tests/createcov_2bit_palette1.testcase
+++ b/test/sql_stmt_tests/createcov_2bit_palette1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 2-BIT PALETTE invalid Bands
+RL2_CreateRasterCoverage - 2-BIT PALETTE invalid Bands
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('2bit_palette1', '2-BIT', 'PALETTE', 2, 'NONE', 100, 256, 256, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('2bit_palette1', '2-BIT', 'PALETTE', 2, 'NONE', 100, 256, 256, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('2bit_palette1', '2-BIT', 'PALETTE', 2, 'NONE', 100, 256, 256, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('2bit_palette1', '2-BIT', 'PALETTE', 2, 'NONE', 100, 256, 256, 3003, 1.0, 1.0, NULL)
 0
diff --git a/test/sql_stmt_tests/createcov_2bit_palette_gif.testcase b/test/sql_stmt_tests/createcov_2bit_palette_gif.testcase
index 956a553..df2b98b 100644
--- a/test/sql_stmt_tests/createcov_2bit_palette_gif.testcase
+++ b/test/sql_stmt_tests/createcov_2bit_palette_gif.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 2-BIT PALETTE GIF
+RL2_CreateRasterCoverage - 2-BIT PALETTE GIF
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('2bit_palette_gif', '2-BIT', 'PALETTE', 1, 'GIF', 100, 256, 256, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('2bit_palette_gif', '2-BIT', 'PALETTE', 1, 'GIF', 100, 256, 256, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('2bit_palette_gif', '2-BIT', 'PALETTE', 1, 'GIF', 100, 256, 256, 3003, 1.0)
+RL2_CreateRasterCoverage('2bit_palette_gif', '2-BIT', 'PALETTE', 1, 'GIF', 100, 256, 256, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_2bit_palette_png.testcase b/test/sql_stmt_tests/createcov_2bit_palette_png.testcase
index 95c0c72..630ee91 100644
--- a/test/sql_stmt_tests/createcov_2bit_palette_png.testcase
+++ b/test/sql_stmt_tests/createcov_2bit_palette_png.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 2-BIT PALETTE PNG
+RL2_CreateRasterCoverage - 2-BIT PALETTE PNG
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('2bit_palette_png', '2-BIT', 'PALETTE', 1, 'PNG', 100, 256, 256, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('2bit_palette_png', '2-BIT', 'PALETTE', 1, 'PNG', 100, 256, 256, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('2bit_palette_png', '2-BIT', 'PALETTE', 1, 'PNG', 100, 256, 256, 3003, 1.0)
+RL2_CreateRasterCoverage('2bit_palette_png', '2-BIT', 'PALETTE', 1, 'PNG', 100, 256, 256, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_4bit_gray.testcase b/test/sql_stmt_tests/createcov_4bit_gray.testcase
index 42590b1..f153549 100644
--- a/test/sql_stmt_tests/createcov_4bit_gray.testcase
+++ b/test/sql_stmt_tests/createcov_4bit_gray.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 4-BIT GRAYSCALE
+RL2_CreateRasterCoverage - 4-BIT GRAYSCALE
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('4bit_gray', '4-BIT', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('4bit_gray', '4-BIT', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('4bit_gray', '4-BIT', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('4bit_gray', '4-BIT', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_4bit_gray1.testcase b/test/sql_stmt_tests/createcov_4bit_gray1.testcase
index eb712d8..38634ff 100644
--- a/test/sql_stmt_tests/createcov_4bit_gray1.testcase
+++ b/test/sql_stmt_tests/createcov_4bit_gray1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 4-BIT GRAYSCALE invalid Bands
+RL2_CreateRasterCoverage - 4-BIT GRAYSCALE invalid Bands
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('4bit_gray1', '4-BIT', 'GRAYSCALE', 2, 'NONE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('4bit_gray1', '4-BIT', 'GRAYSCALE', 2, 'NONE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('4bit_gray1', '4-BIT', 'GRAYSCALE', 2, 'NONE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('4bit_gray1', '4-BIT', 'GRAYSCALE', 2, 'NONE', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_4bit_gray_gif.testcase b/test/sql_stmt_tests/createcov_4bit_gray_gif.testcase
index 47fa06c..8ad47cb 100644
--- a/test/sql_stmt_tests/createcov_4bit_gray_gif.testcase
+++ b/test/sql_stmt_tests/createcov_4bit_gray_gif.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 4-BIT GRAYSCALE GIF
+RL2_CreateRasterCoverage - 4-BIT GRAYSCALE GIF
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('4bit_gray_gif', '4-BIT', 'GRAYSCALE', 1, 'GIF', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('4bit_gray_gif', '4-BIT', 'GRAYSCALE', 1, 'GIF', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('4bit_gray_gif', '4-BIT', 'GRAYSCALE', 1, 'GIF', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('4bit_gray_gif', '4-BIT', 'GRAYSCALE', 1, 'GIF', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_4bit_gray_jpeg.testcase b/test/sql_stmt_tests/createcov_4bit_gray_jpeg.testcase
index 197043d..839446a 100644
--- a/test/sql_stmt_tests/createcov_4bit_gray_jpeg.testcase
+++ b/test/sql_stmt_tests/createcov_4bit_gray_jpeg.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 4-BIT GRAYSCALE JPEG
+RL2_CreateRasterCoverage - 4-BIT GRAYSCALE JPEG
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('4bit_gray_jpeg', '4-BIT', 'GRAYSCALE', 1, 'JPEG', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('4bit_gray_jpeg', '4-BIT', 'GRAYSCALE', 1, 'JPEG', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('4bit_gray_jpeg', '4-BIT', 'GRAYSCALE', 1, 'JPEG', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('4bit_gray_jpeg', '4-BIT', 'GRAYSCALE', 1, 'JPEG', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_4bit_gray_png.testcase b/test/sql_stmt_tests/createcov_4bit_gray_png.testcase
index e819086..4657b60 100644
--- a/test/sql_stmt_tests/createcov_4bit_gray_png.testcase
+++ b/test/sql_stmt_tests/createcov_4bit_gray_png.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 4-BIT GRAYSCALE PNG
+RL2_CreateRasterCoverage - 4-BIT GRAYSCALE PNG
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('4bit_gray_png', '4-BIT', 'GRAYSCALE', 1, 'PNG', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('4bit_gray_png', '4-BIT', 'GRAYSCALE', 1, 'PNG', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('4bit_gray_png', '4-BIT', 'GRAYSCALE', 1, 'PNG', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('4bit_gray_png', '4-BIT', 'GRAYSCALE', 1, 'PNG', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_4bit_gray_webp1.testcase b/test/sql_stmt_tests/createcov_4bit_gray_webp1.testcase
index a7a8813..ea16a14 100644
--- a/test/sql_stmt_tests/createcov_4bit_gray_webp1.testcase
+++ b/test/sql_stmt_tests/createcov_4bit_gray_webp1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 4-BIT GRAYSCALE LOSSY WEBP
+RL2_CreateRasterCoverage - 4-BIT GRAYSCALE LOSSY WEBP
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('4bit_gray_webp1', '4-BIT', 'GRAYSCALE', 1, 'WEBP', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('4bit_gray_webp1', '4-BIT', 'GRAYSCALE', 1, 'WEBP', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('4bit_gray_webp1', '4-BIT', 'GRAYSCALE', 1, 'WEBP', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('4bit_gray_webp1', '4-BIT', 'GRAYSCALE', 1, 'WEBP', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_4bit_gray_webp2.testcase b/test/sql_stmt_tests/createcov_4bit_gray_webp2.testcase
index 4edb57c..083e85a 100644
--- a/test/sql_stmt_tests/createcov_4bit_gray_webp2.testcase
+++ b/test/sql_stmt_tests/createcov_4bit_gray_webp2.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 4-BIT GRAYSCALE LOSSLESS WEBP
+RL2_CreateRasterCoverage - 4-BIT GRAYSCALE LOSSLESS WEBP
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('4bit_gray_webp2', '4-BIT', 'GRAYSCALE', 1, 'LL_WEBP', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('4bit_gray_webp2', '4-BIT', 'GRAYSCALE', 1, 'LL_WEBP', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('4bit_gray_webp2', '4-BIT', 'GRAYSCALE', 1, 'LL_WEBP', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('4bit_gray_webp2', '4-BIT', 'GRAYSCALE', 1, 'LL_WEBP', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_4bit_palette.testcase b/test/sql_stmt_tests/createcov_4bit_palette.testcase
index bc531d8..1af8020 100644
--- a/test/sql_stmt_tests/createcov_4bit_palette.testcase
+++ b/test/sql_stmt_tests/createcov_4bit_palette.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 4-BIT PALETTE
+RL2_CreateRasterCoverage - 4-BIT PALETTE
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('4bit_palette', '4-BIT', 'PALETTE', 1, 'NONE', 100, 256, 256, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('4bit_palette', '4-BIT', 'PALETTE', 1, 'NONE', 100, 256, 256, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('4bit_palette', '4-BIT', 'PALETTE', 1, 'NONE', 100, 256, 256, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('4bit_palette', '4-BIT', 'PALETTE', 1, 'NONE', 100, 256, 256, 3003, 1.0, 1.0, NULL)
 1
diff --git a/test/sql_stmt_tests/createcov_4bit_palette1.testcase b/test/sql_stmt_tests/createcov_4bit_palette1.testcase
index 940d172..4f3a044 100644
--- a/test/sql_stmt_tests/createcov_4bit_palette1.testcase
+++ b/test/sql_stmt_tests/createcov_4bit_palette1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 4-BIT PALETTE invalid Bands
+RL2_CreateRasterCoverage - 4-BIT PALETTE invalid Bands
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('4bit_palette1', '4-BIT', 'PALETTE', 2, 'NONE', 100, 256, 256, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('4bit_palette1', '4-BIT', 'PALETTE', 2, 'NONE', 100, 256, 256, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('4bit_palette1', '4-BIT', 'PALETTE', 2, 'NONE', 100, 256, 256, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('4bit_palette1', '4-BIT', 'PALETTE', 2, 'NONE', 100, 256, 256, 3003, 1.0, 1.0, NULL)
 0
diff --git a/test/sql_stmt_tests/createcov_4bit_palette_gif.testcase b/test/sql_stmt_tests/createcov_4bit_palette_gif.testcase
index 36038b3..e62280e 100644
--- a/test/sql_stmt_tests/createcov_4bit_palette_gif.testcase
+++ b/test/sql_stmt_tests/createcov_4bit_palette_gif.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 4-BIT PALETTE GIF
+RL2_CreateRasterCoverage - 4-BIT PALETTE GIF
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('4bit_palette_gif', '4-BIT', 'PALETTE', 1, 'GIF', 100, 256, 256, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('4bit_palette_gif', '4-BIT', 'PALETTE', 1, 'GIF', 100, 256, 256, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('4bit_palette_gif', '4-BIT', 'PALETTE', 1, 'GIF', 100, 256, 256, 3003, 1.0)
+RL2_CreateRasterCoverage('4bit_palette_gif', '4-BIT', 'PALETTE', 1, 'GIF', 100, 256, 256, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_4bit_palette_png.testcase b/test/sql_stmt_tests/createcov_4bit_palette_png.testcase
index d8bd5f1..620d923 100644
--- a/test/sql_stmt_tests/createcov_4bit_palette_png.testcase
+++ b/test/sql_stmt_tests/createcov_4bit_palette_png.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - 4-BIT PALETTE PNG
+RL2_CreateRasterCoverage - 4-BIT PALETTE PNG
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('4bit_palette_png', '4-BIT', 'PALETTE', 1, 'PNG', 100, 256, 256, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('4bit_palette_png', '4-BIT', 'PALETTE', 1, 'PNG', 100, 256, 256, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('4bit_palette_png', '4-BIT', 'PALETTE', 1, 'PNG', 100, 256, 256, 3003, 1.0)
+RL2_CreateRasterCoverage('4bit_palette_png', '4-BIT', 'PALETTE', 1, 'PNG', 100, 256, 256, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_8_mband.testcase b/test/sql_stmt_tests/createcov_8_mband.testcase
index 648368d..92ee35e 100644
--- a/test/sql_stmt_tests/createcov_8_mband.testcase
+++ b/test/sql_stmt_tests/createcov_8_mband.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 MULTIBAND
+RL2_CreateRasterCoverage - UINT8 MULTIBAND
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_multiband', 'UINT8', 'MULTIBAND', 4, 'NONE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint8_multiband', 'UINT8', 'MULTIBAND', 4, 'NONE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_multiband', 'UINT8', 'MULTIBAND', 4, 'NONE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint8_multiband', 'UINT8', 'MULTIBAND', 4, 'NONE', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_8_mband1.testcase b/test/sql_stmt_tests/createcov_8_mband1.testcase
index e21654b..6a0974b 100644
--- a/test/sql_stmt_tests/createcov_8_mband1.testcase
+++ b/test/sql_stmt_tests/createcov_8_mband1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 MULTIBAND invalid Bands
+RL2_CreateRasterCoverage - UINT8 MULTIBAND invalid Bands
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_multiband1', 'UINT8', 'MULTIBAND', 1, 'NONE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint8_multiband1', 'UINT8', 'MULTIBAND', 1, 'NONE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_multiband1', 'UINT8', 'MULTIBAND', 1, 'NONE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint8_multiband1', 'UINT8', 'MULTIBAND', 1, 'NONE', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_8_mband_deflate.testcase b/test/sql_stmt_tests/createcov_8_mband_deflate.testcase
index 8ff4135..750892e 100644
--- a/test/sql_stmt_tests/createcov_8_mband_deflate.testcase
+++ b/test/sql_stmt_tests/createcov_8_mband_deflate.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 MULTIBAND DEFLATE
+RL2_CreateRasterCoverage - UINT8 MULTIBAND DEFLATE
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_multiband_deflate', 'UINT8', 'MULTIBAND', 4, 'DEFLATE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint8_multiband_deflate', 'UINT8', 'MULTIBAND', 4, 'DEFLATE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_multiband_deflate', 'UINT8', 'MULTIBAND', 4, 'DEFLATE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint8_multiband_deflate', 'UINT8', 'MULTIBAND', 4, 'DEFLATE', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_8_mband_deflateno.testcase b/test/sql_stmt_tests/createcov_8_mband_deflateno.testcase
new file mode 100644
index 0000000..0d46077
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_8_mband_deflateno.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - UINT8 MULTIBAND DEFLATE_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('uint8_multiband_deflateno', 'UINT8', 'MULTIBAND', 4, 'DEFLATE_NO', 100, 512, 512, 3003, 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('uint8_multiband_deflateno', 'UINT8', 'MULTIBAND', 4, 'DEFLATE_NO', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_8_mband_fax3.testcase b/test/sql_stmt_tests/createcov_8_mband_fax3.testcase
index 93a1cc5..95b1ef3 100644
--- a/test/sql_stmt_tests/createcov_8_mband_fax3.testcase
+++ b/test/sql_stmt_tests/createcov_8_mband_fax3.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 MULTIBAND FAX3
+RL2_CreateRasterCoverage - UINT8 MULTIBAND FAX3
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_multiband_fax3', 'UINT8', 'MULTIBAND', 4, 'FAX3', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint8_multiband_fax3', 'UINT8', 'MULTIBAND', 4, 'FAX3', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_multiband_fax3', 'UINT8', 'MULTIBAND', 4, 'FAX3', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint8_multiband_fax3', 'UINT8', 'MULTIBAND', 4, 'FAX3', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_8_mband_fax4.testcase b/test/sql_stmt_tests/createcov_8_mband_fax4.testcase
index 3423780..dd45f40 100644
--- a/test/sql_stmt_tests/createcov_8_mband_fax4.testcase
+++ b/test/sql_stmt_tests/createcov_8_mband_fax4.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 MULTIBAND FAX4
+RL2_CreateRasterCoverage - UINT8 MULTIBAND FAX4
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_multiband_fax4', 'UINT8', 'MULTIBAND', 4, 'FAX4', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint8_multiband_fax4', 'UINT8', 'MULTIBAND', 4, 'FAX4', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_multiband_fax4', 'UINT8', 'MULTIBAND', 4, 'FAX4', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint8_multiband_fax4', 'UINT8', 'MULTIBAND', 4, 'FAX4', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_8_mband_gif.testcase b/test/sql_stmt_tests/createcov_8_mband_gif.testcase
index 771a95d..49f8491 100644
--- a/test/sql_stmt_tests/createcov_8_mband_gif.testcase
+++ b/test/sql_stmt_tests/createcov_8_mband_gif.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 MULTIBAND GIF
+RL2_CreateRasterCoverage - UINT8 MULTIBAND GIF
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_multiband_gif', 'UINT8', 'MULTIBAND', 4, 'GIF', -100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint8_multiband_gif', 'UINT8', 'MULTIBAND', 4, 'GIF', -100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_multiband_gif', 'UINT8', 'MULTIBAND', 4, 'GIF', -100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint8_multiband_gif', 'UINT8', 'MULTIBAND', 4, 'GIF', -100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_8_mband_jpeg.testcase b/test/sql_stmt_tests/createcov_8_mband_jpeg.testcase
index c921b4d..1444624 100644
--- a/test/sql_stmt_tests/createcov_8_mband_jpeg.testcase
+++ b/test/sql_stmt_tests/createcov_8_mband_jpeg.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 MULTIBAND JPEG
+RL2_CreateRasterCoverage - UINT8 MULTIBAND JPEG
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_multiband_jpeg', 'UINT8', 'MULTIBAND', 4, 'JPEG', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint8_multiband_jpeg', 'UINT8', 'MULTIBAND', 4, 'JPEG', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_multiband_jpeg', 'UINT8', 'MULTIBAND', 4, 'JPEG', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint8_multiband_jpeg', 'UINT8', 'MULTIBAND', 4, 'JPEG', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_8_mband_lzma.testcase b/test/sql_stmt_tests/createcov_8_mband_lzma.testcase
index aea4983..9012583 100644
--- a/test/sql_stmt_tests/createcov_8_mband_lzma.testcase
+++ b/test/sql_stmt_tests/createcov_8_mband_lzma.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 MULTIBAND LZMA
+RL2_CreateRasterCoverage - UINT8 MULTIBAND LZMA
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_multiband_lzma', 'UINT8', 'MULTIBAND', 4, 'LZMA', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint8_multiband_lzma', 'UINT8', 'MULTIBAND', 4, 'LZMA', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_multiband_lzma', 'UINT8', 'MULTIBAND', 4, 'LZMA', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint8_multiband_lzma', 'UINT8', 'MULTIBAND', 4, 'LZMA', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_8_mband_lzmano.testcase b/test/sql_stmt_tests/createcov_8_mband_lzmano.testcase
new file mode 100644
index 0000000..ed0d54a
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_8_mband_lzmano.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - UINT8 MULTIBAND LZMA_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('uint8_multiband_lzmano', 'UINT8', 'MULTIBAND', 4, 'LZMA_NO', 100, 512, 512, 3003, 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('uint8_multiband_lzmano', 'UINT8', 'MULTIBAND', 4, 'LZMA_NO', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_8_mband_png.testcase b/test/sql_stmt_tests/createcov_8_mband_png.testcase
index 3b61c5b..4fdc5f1 100644
--- a/test/sql_stmt_tests/createcov_8_mband_png.testcase
+++ b/test/sql_stmt_tests/createcov_8_mband_png.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 MULTIBAND PNG
+RL2_CreateRasterCoverage - UINT8 MULTIBAND PNG
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_multiband_png', 'UINT8', 'MULTIBAND', 4, 'PNG', 1000, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint8_multiband_png', 'UINT8', 'MULTIBAND', 4, 'PNG', 1000, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_multiband_png', 'UINT8', 'MULTIBAND', 4, 'PNG', 1000, 512, 512, 3003, 1.0)
-0
+RL2_CreateRasterCoverage('uint8_multiband_png', 'UINT8', 'MULTIBAND', 4, 'PNG', 1000, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_8_mband_webp1.testcase b/test/sql_stmt_tests/createcov_8_mband_webp1.testcase
index fed6700..63308d3 100644
--- a/test/sql_stmt_tests/createcov_8_mband_webp1.testcase
+++ b/test/sql_stmt_tests/createcov_8_mband_webp1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 MULTIBAND LOSSY WEBP
+RL2_CreateRasterCoverage - UINT8 MULTIBAND LOSSY WEBP
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_multiband_webp1', 'UINT8', 'MULTIBAND', 4, 'WEBP', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint8_multiband_webp1', 'UINT8', 'MULTIBAND', 4, 'WEBP', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_multiband_webp1', 'UINT8', 'MULTIBAND', 4, 'WEBP', 100, 512, 512, 3003, 1.0)
-0
+RL2_CreateRasterCoverage('uint8_multiband_webp1', 'UINT8', 'MULTIBAND', 4, 'WEBP', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_8_mband_webp2.testcase b/test/sql_stmt_tests/createcov_8_mband_webp2.testcase
index f019c84..1177bd7 100644
--- a/test/sql_stmt_tests/createcov_8_mband_webp2.testcase
+++ b/test/sql_stmt_tests/createcov_8_mband_webp2.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 MULTIBAND LOSSLESS WEBP
+RL2_CreateRasterCoverage - UINT8 MULTIBAND LOSSLESS WEBP
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_multiband_webp2', 'UINT8', 'MULTIBAND', 4, 'LL_WEBP', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint8_multiband_webp2', 'UINT8', 'MULTIBAND', 4, 'LL_WEBP', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_multiband_webp2', 'UINT8', 'MULTIBAND', 4, 'LL_WEBP', 100, 512, 512, 3003, 1.0)
-0
+RL2_CreateRasterCoverage('uint8_multiband_webp2', 'UINT8', 'MULTIBAND', 4, 'LL_WEBP', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_double_grid.testcase b/test/sql_stmt_tests/createcov_double_grid.testcase
index 66b8b65..abbaaed 100644
--- a/test/sql_stmt_tests/createcov_double_grid.testcase
+++ b/test/sql_stmt_tests/createcov_double_grid.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - DOUBLE GRID
+RL2_CreateRasterCoverage - DOUBLE GRID
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('double_grid', 'DOUBLE', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('double_grid', 'DOUBLE', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('double_grid', 'DOUBLE', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('double_grid', 'DOUBLE', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_double_grid1.testcase b/test/sql_stmt_tests/createcov_double_grid1.testcase
index 29c8eb0..61f50fe 100644
--- a/test/sql_stmt_tests/createcov_double_grid1.testcase
+++ b/test/sql_stmt_tests/createcov_double_grid1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - DOUBLE GRID invalid Bands
+RL2_CreateRasterCoverage - DOUBLE GRID invalid Bands
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('double_grid1', 'DOUBLE', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('double_grid1', 'DOUBLE', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('double_grid1', 'DOUBLE', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('double_grid1', 'DOUBLE', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_double_grid_deflate.testcase b/test/sql_stmt_tests/createcov_double_grid_deflate.testcase
index 185e466..4f9f251 100644
--- a/test/sql_stmt_tests/createcov_double_grid_deflate.testcase
+++ b/test/sql_stmt_tests/createcov_double_grid_deflate.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - DOUBLE GRID DEFLATE
+RL2_CreateRasterCoverage - DOUBLE GRID DEFLATE
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('double_grid_deflate', 'DOUBLE', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('double_grid_deflate', 'DOUBLE', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('double_grid_deflate', 'DOUBLE', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('double_grid_deflate', 'DOUBLE', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_double_grid_deflateno.testcase b/test/sql_stmt_tests/createcov_double_grid_deflateno.testcase
new file mode 100644
index 0000000..c7305ae
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_double_grid_deflateno.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - DOUBLE GRID DEFLATE_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('double_grid_deflateno', 'DOUBLE', 'DATAGRID', 1, 'DEFLATE_NO', 100, 512, 512, 3003, 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('double_grid_deflateno', 'DOUBLE', 'DATAGRID', 1, 'DEFLATE_NO', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_double_grid_lzma.testcase b/test/sql_stmt_tests/createcov_double_grid_lzma.testcase
index 0b83e10..680da87 100644
--- a/test/sql_stmt_tests/createcov_double_grid_lzma.testcase
+++ b/test/sql_stmt_tests/createcov_double_grid_lzma.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - DOUBLE GRID LZMA
+RL2_CreateRasterCoverage - DOUBLE GRID LZMA
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('double_grid_lzma', 'DOUBLE', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('double_grid_lzma', 'DOUBLE', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('double_grid_lzma', 'DOUBLE', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('double_grid_lzma', 'DOUBLE', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_double_grid_lzmano.testcase b/test/sql_stmt_tests/createcov_double_grid_lzmano.testcase
new file mode 100644
index 0000000..8533996
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_double_grid_lzmano.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - DOUBLE GRID LZMA_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('double_grid_lzmano', 'DOUBLE', 'DATAGRID', 1, 'LZMA_NO', 100, 512, 512, 3003, 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('double_grid_lzmano', 'DOUBLE', 'DATAGRID', 1, 'LZMA_NO', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_err1.testcase b/test/sql_stmt_tests/createcov_err1.testcase
index 0c6f87b..262ffc1 100644
--- a/test/sql_stmt_tests/createcov_err1.testcase
+++ b/test/sql_stmt_tests/createcov_err1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - NULL name
+RL2_CreateRasterCoverage - NULL name
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage(NULL, 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage(NULL, 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage(NULL, 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage(NULL, 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL)
 -1
diff --git a/test/sql_stmt_tests/createcov_err10.testcase b/test/sql_stmt_tests/createcov_err10.testcase
index e67e461..035664f 100644
--- a/test/sql_stmt_tests/createcov_err10.testcase
+++ b/test/sql_stmt_tests/createcov_err10.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - NULL horz-resolution
+RL2_CreateRasterCoverage - NULL horz-resolution
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, NULL, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, NULL, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, NULL, 1.0, NULL)
+RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, NULL, 1.0, NULL)
 -1
diff --git a/test/sql_stmt_tests/createcov_err11.testcase b/test/sql_stmt_tests/createcov_err11.testcase
index d51b109..032c402 100644
--- a/test/sql_stmt_tests/createcov_err11.testcase
+++ b/test/sql_stmt_tests/createcov_err11.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - NULL vert-resolution
+RL2_CreateRasterCoverage - NULL vert-resolution
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, NULL, NULL);
+SELECT RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, NULL, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, NULL, NULL)
+RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, NULL, NULL)
 -1
diff --git a/test/sql_stmt_tests/createcov_err12.testcase b/test/sql_stmt_tests/createcov_err12.testcase
index 866e4b9..a697fe4 100644
--- a/test/sql_stmt_tests/createcov_err12.testcase
+++ b/test/sql_stmt_tests/createcov_err12.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - TEXT no-data
+RL2_CreateRasterCoverage - TEXT no-data
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, 'nodata');
+SELECT RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, 'nodata');
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, 'nodata')
+RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, 'nodata')
 -1
diff --git a/test/sql_stmt_tests/createcov_err13.testcase b/test/sql_stmt_tests/createcov_err13.testcase
new file mode 100644
index 0000000..7e96dce
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_err13.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - NULL StrictResolution
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL, NULL, 0, 0, 0, 0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL, NULL, 0, 0, 0, 0)
+-1
diff --git a/test/sql_stmt_tests/createcov_err14.testcase b/test/sql_stmt_tests/createcov_err14.testcase
new file mode 100644
index 0000000..8da44e1
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_err14.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - NULL MixedResolutions
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL, 0, NULL, 0, 0, 0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL, 0, NULL, 0, 0, 0)
+-1
diff --git a/test/sql_stmt_tests/createcov_err15.testcase b/test/sql_stmt_tests/createcov_err15.testcase
new file mode 100644
index 0000000..9eca5b3
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_err15.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - NULL SectionPaths
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL, 0, 0, NULL, 0, 0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL, 0, 0, NULL, 0, 0)
+-1
diff --git a/test/sql_stmt_tests/createcov_err16.testcase b/test/sql_stmt_tests/createcov_err16.testcase
new file mode 100644
index 0000000..e19d15b
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_err16.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - NULL SectionMD5
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL, 0, 0, 0, NULL, 0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL, 0, 0, 0, NULL, 0)
+-1
diff --git a/test/sql_stmt_tests/createcov_err17.testcase b/test/sql_stmt_tests/createcov_err17.testcase
new file mode 100644
index 0000000..28d98e0
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_err17.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - NULL SectionSummary
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL, 0, 0, 0, 0, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL, 0, 0, 0, 0, NULL)
+-1
diff --git a/test/sql_stmt_tests/createcov_err2.testcase b/test/sql_stmt_tests/createcov_err2.testcase
index daf64b7..1f5484b 100644
--- a/test/sql_stmt_tests/createcov_err2.testcase
+++ b/test/sql_stmt_tests/createcov_err2.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - NULL sample
+RL2_CreateRasterCoverage - NULL sample
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('invalid', NULL, 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('invalid', NULL, 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('invalid', NULL, 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('invalid', NULL, 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL)
 -1
diff --git a/test/sql_stmt_tests/createcov_err3.testcase b/test/sql_stmt_tests/createcov_err3.testcase
index 4009c4e..f0e5d7f 100644
--- a/test/sql_stmt_tests/createcov_err3.testcase
+++ b/test/sql_stmt_tests/createcov_err3.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - NULL pixel
+RL2_CreateRasterCoverage - NULL pixel
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('invalid', 'UINT8', NULL, 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('invalid', 'UINT8', NULL, 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('invalid', 'UINT8', NULL, 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('invalid', 'UINT8', NULL, 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL)
 -1
diff --git a/test/sql_stmt_tests/createcov_err4.testcase b/test/sql_stmt_tests/createcov_err4.testcase
index 9720a81..2304bca 100644
--- a/test/sql_stmt_tests/createcov_err4.testcase
+++ b/test/sql_stmt_tests/createcov_err4.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - NULL Bands
+RL2_CreateRasterCoverage - NULL Bands
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('invalid', 'UINT8', 'GRAYSCALE', NULL, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', NULL, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('invalid', 'UINT8', 'GRAYSCALE', NULL, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', NULL, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL)
 -1
diff --git a/test/sql_stmt_tests/createcov_err5.testcase b/test/sql_stmt_tests/createcov_err5.testcase
index a1f00c9..2875c5c 100644
--- a/test/sql_stmt_tests/createcov_err5.testcase
+++ b/test/sql_stmt_tests/createcov_err5.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - NULL compression
+RL2_CreateRasterCoverage - NULL compression
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, NULL, 100, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, NULL, 100, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, NULL, 100, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, NULL, 100, 512, 512, 3003, 1.0, 1.0, NULL)
 -1
diff --git a/test/sql_stmt_tests/createcov_err6.testcase b/test/sql_stmt_tests/createcov_err6.testcase
index 6d97ccc..f7f2e25 100644
--- a/test/sql_stmt_tests/createcov_err6.testcase
+++ b/test/sql_stmt_tests/createcov_err6.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - NULL quality
+RL2_CreateRasterCoverage - NULL quality
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', NULL, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', NULL, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', NULL, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', NULL, 512, 512, 3003, 1.0, 1.0, NULL)
 -1
diff --git a/test/sql_stmt_tests/createcov_err7.testcase b/test/sql_stmt_tests/createcov_err7.testcase
index b61ed91..8f928ad 100644
--- a/test/sql_stmt_tests/createcov_err7.testcase
+++ b/test/sql_stmt_tests/createcov_err7.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - NULL tile width
+RL2_CreateRasterCoverage - NULL tile width
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, NULL, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, NULL, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, NULL, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, NULL, 512, 3003, 1.0, 1.0, NULL)
 -1
diff --git a/test/sql_stmt_tests/createcov_err8.testcase b/test/sql_stmt_tests/createcov_err8.testcase
index 118288a..a8da45b 100644
--- a/test/sql_stmt_tests/createcov_err8.testcase
+++ b/test/sql_stmt_tests/createcov_err8.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - NULL tile height
+RL2_CreateRasterCoverage - NULL tile height
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, NULL, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, NULL, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, NULL, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, NULL, 3003, 1.0, 1.0, NULL)
 -1
diff --git a/test/sql_stmt_tests/createcov_err9.testcase b/test/sql_stmt_tests/createcov_err9.testcase
index 38acc7b..d98e44c 100644
--- a/test/sql_stmt_tests/createcov_err9.testcase
+++ b/test/sql_stmt_tests/createcov_err9.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - NULL SRID
+RL2_CreateRasterCoverage - NULL SRID
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, NULL, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, NULL, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, NULL, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('invalid', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, NULL, 1.0, 1.0, NULL)
 -1
diff --git a/test/sql_stmt_tests/createcov_float_grid.testcase b/test/sql_stmt_tests/createcov_float_grid.testcase
index 065db46..5a94a9e 100644
--- a/test/sql_stmt_tests/createcov_float_grid.testcase
+++ b/test/sql_stmt_tests/createcov_float_grid.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - FLOAT GRID
+RL2_CreateRasterCoverage - FLOAT GRID
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('float_grid', 'FLOAT', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('float_grid', 'FLOAT', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('float_grid', 'FLOAT', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('float_grid', 'FLOAT', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_float_grid1.testcase b/test/sql_stmt_tests/createcov_float_grid1.testcase
index 7bf1581..bbf1c11 100644
--- a/test/sql_stmt_tests/createcov_float_grid1.testcase
+++ b/test/sql_stmt_tests/createcov_float_grid1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - FLOAT GRID invalid Bands
+RL2_CreateRasterCoverage - FLOAT GRID invalid Bands
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('float_grid1', 'FLOAT', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('float_grid1', 'FLOAT', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('float_grid1', 'FLOAT', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('float_grid1', 'FLOAT', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_float_grid_deflate.testcase b/test/sql_stmt_tests/createcov_float_grid_deflate.testcase
index 0cffdfc..2fea567 100644
--- a/test/sql_stmt_tests/createcov_float_grid_deflate.testcase
+++ b/test/sql_stmt_tests/createcov_float_grid_deflate.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - FLOAT GRID DEFLATE
+RL2_CreateRasterCoverage - FLOAT GRID DEFLATE
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('float_grid_deflate', 'FLOAT', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('float_grid_deflate', 'FLOAT', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('float_grid_deflate', 'FLOAT', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('float_grid_deflate', 'FLOAT', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_float_grid_deflateno.testcase b/test/sql_stmt_tests/createcov_float_grid_deflateno.testcase
new file mode 100644
index 0000000..1da03cc
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_float_grid_deflateno.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - FLOAT GRID DEFLATE_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('float_grid_deflateno', 'FLOAT', 'DATAGRID', 1, 'DEFLATE_NO', 100, 512, 512, 3003, 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('float_grid_deflateno', 'FLOAT', 'DATAGRID', 1, 'DEFLATE_NO', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_float_grid_lzma.testcase b/test/sql_stmt_tests/createcov_float_grid_lzma.testcase
index 4231e76..a96a260 100644
--- a/test/sql_stmt_tests/createcov_float_grid_lzma.testcase
+++ b/test/sql_stmt_tests/createcov_float_grid_lzma.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - FLOAT GRID LZMA
+RL2_CreateRasterCoverage - FLOAT GRID LZMA
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('float_grid_lzma', 'FLOAT', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('float_grid_lzma', 'FLOAT', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('float_grid_lzma', 'FLOAT', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('float_grid_lzma', 'FLOAT', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_float_grid_lzmano.testcase b/test/sql_stmt_tests/createcov_float_grid_lzmano.testcase
new file mode 100644
index 0000000..239432b
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_float_grid_lzmano.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - FLOAT GRID LZMA_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('float_grid_lzmano', 'FLOAT', 'DATAGRID', 1, 'LZMA_NO', 100, 512, 512, 3003, 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('float_grid_lzmano', 'FLOAT', 'DATAGRID', 1, 'LZMA_NO', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_int16_grid.testcase b/test/sql_stmt_tests/createcov_int16_grid.testcase
index 3526cda..7fff3d8 100644
--- a/test/sql_stmt_tests/createcov_int16_grid.testcase
+++ b/test/sql_stmt_tests/createcov_int16_grid.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - INT16 GRID
+RL2_CreateRasterCoverage - INT16 GRID
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('int16_grid1', 'INT16', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('int16_grid1', 'INT16', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('int16_grid1', 'INT16', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('int16_grid1', 'INT16', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_int16_grid1.testcase b/test/sql_stmt_tests/createcov_int16_grid1.testcase
index 73a4161..39beb61 100644
--- a/test/sql_stmt_tests/createcov_int16_grid1.testcase
+++ b/test/sql_stmt_tests/createcov_int16_grid1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - INT16 GRID invalid Bands
+RL2_CreateRasterCoverage - INT16 GRID invalid Bands
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('int16_grid1', 'INT16', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('int16_grid1', 'INT16', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('int16_grid1', 'INT16', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('int16_grid1', 'INT16', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_int16_grid_deflate.testcase b/test/sql_stmt_tests/createcov_int16_grid_deflate.testcase
index a1c5b5f..e81fa13 100644
--- a/test/sql_stmt_tests/createcov_int16_grid_deflate.testcase
+++ b/test/sql_stmt_tests/createcov_int16_grid_deflate.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - INT16 GRID DEFLATE
+RL2_CreateRasterCoverage - INT16 GRID DEFLATE
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('int16_grid_deflate', 'INT16', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('int16_grid_deflate', 'INT16', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('int16_grid_deflate', 'INT16', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('int16_grid_deflate', 'INT16', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_int16_grid_deflateno.testcase b/test/sql_stmt_tests/createcov_int16_grid_deflateno.testcase
new file mode 100644
index 0000000..13b654f
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_int16_grid_deflateno.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - INT16 GRID DEFLATE_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('int16_grid_deflateno', 'INT16', 'DATAGRID', 1, 'DEFLATE_NO', 100, 512, 512, 3003, 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('int16_grid_deflateno', 'INT16', 'DATAGRID', 1, 'DEFLATE_NO', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_int16_grid_lzma.testcase b/test/sql_stmt_tests/createcov_int16_grid_lzma.testcase
index 9f23adf..230b7cc 100644
--- a/test/sql_stmt_tests/createcov_int16_grid_lzma.testcase
+++ b/test/sql_stmt_tests/createcov_int16_grid_lzma.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - INT16 GRID LZMA
+RL2_CreateRasterCoverage - INT16 GRID LZMA
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('int16_grid_lzma', 'INT16', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('int16_grid_lzma', 'INT16', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('int16_grid_lzma', 'INT16', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('int16_grid_lzma', 'INT16', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_int16_grid_lzmano.testcase b/test/sql_stmt_tests/createcov_int16_grid_lzmano.testcase
new file mode 100644
index 0000000..f59d6ab
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_int16_grid_lzmano.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - INT16 GRID LZMA_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('int16_grid_lzmano', 'INT16', 'DATAGRID', 1, 'LZMA_NO', 100, 512, 512, 3003, 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('int16_grid_lzmano', 'INT16', 'DATAGRID', 1, 'LZMA_NO', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_int32_grid.testcase b/test/sql_stmt_tests/createcov_int32_grid.testcase
index b48bde1..dcad4dc 100644
--- a/test/sql_stmt_tests/createcov_int32_grid.testcase
+++ b/test/sql_stmt_tests/createcov_int32_grid.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - INT32 GRID
+RL2_CreateRasterCoverage - INT32 GRID
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('int32_grid', 'INT32', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('int32_grid', 'INT32', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('int32_grid', 'INT32', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('int32_grid', 'INT32', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_int32_grid1.testcase b/test/sql_stmt_tests/createcov_int32_grid1.testcase
index 4a4c86c..4372b47 100644
--- a/test/sql_stmt_tests/createcov_int32_grid1.testcase
+++ b/test/sql_stmt_tests/createcov_int32_grid1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - INT32 GRID invalid Bands
+RL2_CreateRasterCoverage - INT32 GRID invalid Bands
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('int32_grid', 'INT32', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('int32_grid', 'INT32', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('int32_grid', 'INT32', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('int32_grid', 'INT32', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_int32_grid_deflate.testcase b/test/sql_stmt_tests/createcov_int32_grid_deflate.testcase
index b04ccf4..9febb0c 100644
--- a/test/sql_stmt_tests/createcov_int32_grid_deflate.testcase
+++ b/test/sql_stmt_tests/createcov_int32_grid_deflate.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - INT32 GRID DEFLATE
+RL2_CreateRasterCoverage - INT32 GRID DEFLATE
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('int32_grid_deflate', 'INT32', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('int32_grid_deflate', 'INT32', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('int32_grid_deflate', 'INT32', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('int32_grid_deflate', 'INT32', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_int32_grid_deflateno.testcase b/test/sql_stmt_tests/createcov_int32_grid_deflateno.testcase
new file mode 100644
index 0000000..6463f2e
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_int32_grid_deflateno.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - INT32 GRID DEFLATE_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('int32_grid_deflateno', 'INT32', 'DATAGRID', 1, 'DEFLATE_NO', 100, 512, 512, 3003, 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('int32_grid_deflateno', 'INT32', 'DATAGRID', 1, 'DEFLATE_NO', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_int32_grid_gif.testcase b/test/sql_stmt_tests/createcov_int32_grid_gif.testcase
index 69f6547..58a4a5b 100644
--- a/test/sql_stmt_tests/createcov_int32_grid_gif.testcase
+++ b/test/sql_stmt_tests/createcov_int32_grid_gif.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - INT32 GRID GIF
+RL2_CreateRasterCoverage - INT32 GRID GIF
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('int32_grid_gif', 'INT32', 'DATAGRID', 1, 'GIF', 100, 512, 512, 3003, 1);
+SELECT RL2_CreateRasterCoverage('int32_grid_gif', 'INT32', 'DATAGRID', 1, 'GIF', 100, 512, 512, 3003, 1);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('int32_grid_gif', 'INT32', 'DATAGRID', 1, 'GIF', 100, 512, 512, 3003, 1)
+RL2_CreateRasterCoverage('int32_grid_gif', 'INT32', 'DATAGRID', 1, 'GIF', 100, 512, 512, 3003, 1)
 0
diff --git a/test/sql_stmt_tests/createcov_int32_grid_jpeg.testcase b/test/sql_stmt_tests/createcov_int32_grid_jpeg.testcase
index 72c4f37..c8e8cad 100644
--- a/test/sql_stmt_tests/createcov_int32_grid_jpeg.testcase
+++ b/test/sql_stmt_tests/createcov_int32_grid_jpeg.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - INT32 GRID JPEG
+RL2_CreateRasterCoverage - INT32 GRID JPEG
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('int32_grid_jpeg', 'INT32', 'DATAGRID', 1, 'JPEG', 100, 512, 512, 3003, 1);
+SELECT RL2_CreateRasterCoverage('int32_grid_jpeg', 'INT32', 'DATAGRID', 1, 'JPEG', 100, 512, 512, 3003, 1);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('int32_grid_jpeg', 'INT32', 'DATAGRID', 1, 'JPEG', 100, 512, 512, 3003, 1)
+RL2_CreateRasterCoverage('int32_grid_jpeg', 'INT32', 'DATAGRID', 1, 'JPEG', 100, 512, 512, 3003, 1)
 0
diff --git a/test/sql_stmt_tests/createcov_int32_grid_lzma.testcase b/test/sql_stmt_tests/createcov_int32_grid_lzma.testcase
index f99861c..3a42448 100644
--- a/test/sql_stmt_tests/createcov_int32_grid_lzma.testcase
+++ b/test/sql_stmt_tests/createcov_int32_grid_lzma.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - INT32 GRID LZMA
+RL2_CreateRasterCoverage - INT32 GRID LZMA
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('int32_grid_lzma', 'INT32', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('int32_grid_lzma', 'INT32', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('int32_grid_lzma', 'INT32', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('int32_grid_lzma', 'INT32', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_int32_grid_lzmano.testcase b/test/sql_stmt_tests/createcov_int32_grid_lzmano.testcase
new file mode 100644
index 0000000..7a84b33
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_int32_grid_lzmano.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - INT32 GRID LZMA_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('int32_grid_lzmano', 'INT32', 'DATAGRID', 1, 'LZMA_NO', 100, 512, 512, 3003, 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('int32_grid_lzmano', 'INT32', 'DATAGRID', 1, 'LZMA_NO', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_int32_grid_png.testcase b/test/sql_stmt_tests/createcov_int32_grid_png.testcase
index b2ed85e..8e392c7 100644
--- a/test/sql_stmt_tests/createcov_int32_grid_png.testcase
+++ b/test/sql_stmt_tests/createcov_int32_grid_png.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - INT32 GRID PNG
+RL2_CreateRasterCoverage - INT32 GRID PNG
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('int32_grid_png', 'INT32', 'DATAGRID', 1, 'PNG', 100, 512, 512, 3003, 1.0, 1);
+SELECT RL2_CreateRasterCoverage('int32_grid_png', 'INT32', 'DATAGRID', 1, 'PNG', 100, 512, 512, 3003, 1.0, 1);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('int32_grid_png', 'INT32', 'DATAGRID', 1, 'PNG', 100, 512, 512, 3003, 1.0, 1)
+RL2_CreateRasterCoverage('int32_grid_png', 'INT32', 'DATAGRID', 1, 'PNG', 100, 512, 512, 3003, 1.0, 1)
 0
diff --git a/test/sql_stmt_tests/createcov_int32_grid_webp1.testcase b/test/sql_stmt_tests/createcov_int32_grid_webp1.testcase
index 3a46d85..2d052cd 100644
--- a/test/sql_stmt_tests/createcov_int32_grid_webp1.testcase
+++ b/test/sql_stmt_tests/createcov_int32_grid_webp1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - INT32 GRID LOSSY WEBP
+RL2_CreateRasterCoverage - INT32 GRID LOSSY WEBP
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('int32_grid_webp1', 'INT32', 'DATAGRID', 1, 'WEBP', 100, 512, 512, 3003, 1);
+SELECT RL2_CreateRasterCoverage('int32_grid_webp1', 'INT32', 'DATAGRID', 1, 'WEBP', 100, 512, 512, 3003, 1);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('int32_grid_webp1', 'INT32', 'DATAGRID', 1, 'WEBP', 100, 512, 512, 3003, 1)
+RL2_CreateRasterCoverage('int32_grid_webp1', 'INT32', 'DATAGRID', 1, 'WEBP', 100, 512, 512, 3003, 1)
 0
diff --git a/test/sql_stmt_tests/createcov_int32_grid_webp2.testcase b/test/sql_stmt_tests/createcov_int32_grid_webp2.testcase
index 08550c0..fc6ab7e 100644
--- a/test/sql_stmt_tests/createcov_int32_grid_webp2.testcase
+++ b/test/sql_stmt_tests/createcov_int32_grid_webp2.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - INT32 GRID LOSSLESS WEBP
+RL2_CreateRasterCoverage - INT32 GRID LOSSLESS WEBP
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('int32_grid_webp2', 'INT32', 'DATAGRID', 1, 'LL_WEBP', 100, 512, 512, 3003, 1);
+SELECT RL2_CreateRasterCoverage('int32_grid_webp2', 'INT32', 'DATAGRID', 1, 'LL_WEBP', 100, 512, 512, 3003, 1);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('int32_grid_webp2', 'INT32', 'DATAGRID', 1, 'LL_WEBP', 100, 512, 512, 3003, 1)
+RL2_CreateRasterCoverage('int32_grid_webp2', 'INT32', 'DATAGRID', 1, 'LL_WEBP', 100, 512, 512, 3003, 1)
 0
diff --git a/test/sql_stmt_tests/createcov_int8_grid.testcase b/test/sql_stmt_tests/createcov_int8_grid.testcase
index 14576c7..8ea3a04 100644
--- a/test/sql_stmt_tests/createcov_int8_grid.testcase
+++ b/test/sql_stmt_tests/createcov_int8_grid.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - INT8 GRID
+RL2_CreateRasterCoverage - INT8 GRID
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('int8_grid', 'INT8', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('int8_grid', 'INT8', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('int8_grid', 'INT8', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('int8_grid', 'INT8', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_int8_grid1.testcase b/test/sql_stmt_tests/createcov_int8_grid1.testcase
index 705fb95..74737ae 100644
--- a/test/sql_stmt_tests/createcov_int8_grid1.testcase
+++ b/test/sql_stmt_tests/createcov_int8_grid1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - INT8 GRID invalid Bands
+RL2_CreateRasterCoverage - INT8 GRID invalid Bands
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('int8_grid1', 'INT8', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('int8_grid1', 'INT8', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('int8_grid1', 'INT8', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('int8_grid1', 'INT8', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_int8_grid_deflate.testcase b/test/sql_stmt_tests/createcov_int8_grid_deflate.testcase
index 816dc43..5207dab 100644
--- a/test/sql_stmt_tests/createcov_int8_grid_deflate.testcase
+++ b/test/sql_stmt_tests/createcov_int8_grid_deflate.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - INT8 GRID DEFLATE
+RL2_CreateRasterCoverage - INT8 GRID DEFLATE
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('int8_grid_deflate', 'INT8', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('int8_grid_deflate', 'INT8', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('int8_grid_deflate', 'INT8', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('int8_grid_deflate', 'INT8', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_int8_grid_deflateno.testcase b/test/sql_stmt_tests/createcov_int8_grid_deflateno.testcase
new file mode 100644
index 0000000..eefc0cc
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_int8_grid_deflateno.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - INT8 GRID DEFLATE_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('int8_grid_deflateno', 'INT8', 'DATAGRID', 1, 'DEFLATE_NO', 100, 512, 512, 3003, 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('int8_grid_deflateno', 'INT8', 'DATAGRID', 1, 'DEFLATE_NO', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_int8_grid_lzma.testcase b/test/sql_stmt_tests/createcov_int8_grid_lzma.testcase
index ef04a01..aa07dc6 100644
--- a/test/sql_stmt_tests/createcov_int8_grid_lzma.testcase
+++ b/test/sql_stmt_tests/createcov_int8_grid_lzma.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - NIT8 GRID LZMA
+RL2_CreateRasterCoverage - NIT8 GRID LZMA
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('int8_grid_lzma', 'INT8', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('int8_grid_lzma', 'INT8', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('int8_grid_lzma', 'INT8', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('int8_grid_lzma', 'INT8', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_int8_grid_lzmano.testcase b/test/sql_stmt_tests/createcov_int8_grid_lzmano.testcase
new file mode 100644
index 0000000..d93f89b
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_int8_grid_lzmano.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - NIT8 GRID LZMA_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('int8_grid_lzmano', 'INT8', 'DATAGRID', 1, 'LZMA_NO', 100, 512, 512, 3003, 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('int8_grid_lzmano', 'INT8', 'DATAGRID', 1, 'LZMA_NO', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_uint16_grid.testcase b/test/sql_stmt_tests/createcov_uint16_grid.testcase
index 4a28427..87f475a 100644
--- a/test/sql_stmt_tests/createcov_uint16_grid.testcase
+++ b/test/sql_stmt_tests/createcov_uint16_grid.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT16 GRID
+RL2_CreateRasterCoverage - UINT16 GRID
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint16_grid', 'UINT16', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint16_grid', 'UINT16', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint16_grid', 'UINT16', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint16_grid', 'UINT16', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_uint16_grid1.testcase b/test/sql_stmt_tests/createcov_uint16_grid1.testcase
index 8a1d5ba..97fefb6 100644
--- a/test/sql_stmt_tests/createcov_uint16_grid1.testcase
+++ b/test/sql_stmt_tests/createcov_uint16_grid1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT16 GRID invalid Bands
+RL2_CreateRasterCoverage - UINT16 GRID invalid Bands
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint16_grid1', 'UINT16', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint16_grid1', 'UINT16', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint16_grid1', 'UINT16', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint16_grid1', 'UINT16', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_uint16_grid_deflate.testcase b/test/sql_stmt_tests/createcov_uint16_grid_deflate.testcase
index 17f1fdc..1810840 100644
--- a/test/sql_stmt_tests/createcov_uint16_grid_deflate.testcase
+++ b/test/sql_stmt_tests/createcov_uint16_grid_deflate.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT16 GRID DEFLATE
+RL2_CreateRasterCoverage - UINT16 GRID DEFLATE
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint16_grid_deflate', 'UINT16', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint16_grid_deflate', 'UINT16', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint16_grid_deflate', 'UINT16', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint16_grid_deflate', 'UINT16', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_uint16_grid_deflateno.testcase b/test/sql_stmt_tests/createcov_uint16_grid_deflateno.testcase
new file mode 100644
index 0000000..a44ae70
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_uint16_grid_deflateno.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - UINT16 GRID DEFLATE_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('uint16_grid_deflateno', 'UINT16', 'DATAGRID', 1, 'DEFLATE_NO', 100, 512, 512, 3003, 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('uint16_grid_deflateno', 'UINT16', 'DATAGRID', 1, 'DEFLATE_NO', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_uint16_grid_lzma.testcase b/test/sql_stmt_tests/createcov_uint16_grid_lzma.testcase
index 668d8f2..5d96e4b 100644
--- a/test/sql_stmt_tests/createcov_uint16_grid_lzma.testcase
+++ b/test/sql_stmt_tests/createcov_uint16_grid_lzma.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UNIT16 GRID LZMA
+RL2_CreateRasterCoverage - UNIT16 GRID LZMA
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint16_grid_lzma', 'UINT16', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint16_grid_lzma', 'UINT16', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint16_grid_lzma', 'UINT16', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint16_grid_lzma', 'UINT16', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_uint16_grid_lzmano.testcase b/test/sql_stmt_tests/createcov_uint16_grid_lzmano.testcase
new file mode 100644
index 0000000..c3d2b81
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_uint16_grid_lzmano.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - UNIT16 GRID LZMA_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('uint16_grid_lzmano', 'UINT16', 'DATAGRID', 1, 'LZMA_NO', 100, 512, 512, 3003, 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('uint16_grid_lzmano', 'UINT16', 'DATAGRID', 1, 'LZMA_NO', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_uint32_grid.testcase b/test/sql_stmt_tests/createcov_uint32_grid.testcase
index 4fcc4fe..048bb7c 100644
--- a/test/sql_stmt_tests/createcov_uint32_grid.testcase
+++ b/test/sql_stmt_tests/createcov_uint32_grid.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT32 GRID
+RL2_CreateRasterCoverage - UINT32 GRID
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint32_grid', 'UINT32', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint32_grid', 'UINT32', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint32_grid', 'UINT32', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint32_grid', 'UINT32', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_uint32_grid1.testcase b/test/sql_stmt_tests/createcov_uint32_grid1.testcase
index 29f79a7..32da695 100644
--- a/test/sql_stmt_tests/createcov_uint32_grid1.testcase
+++ b/test/sql_stmt_tests/createcov_uint32_grid1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT32 GRID invalid Bands
+RL2_CreateRasterCoverage - UINT32 GRID invalid Bands
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint32_grid1', 'UINT32', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint32_grid1', 'UINT32', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint32_grid1', 'UINT32', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint32_grid1', 'UINT32', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_uint32_grid_deflate.testcase b/test/sql_stmt_tests/createcov_uint32_grid_deflate.testcase
index 00634cd..a0a701f 100644
--- a/test/sql_stmt_tests/createcov_uint32_grid_deflate.testcase
+++ b/test/sql_stmt_tests/createcov_uint32_grid_deflate.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT32 GRID DEFLATE
+RL2_CreateRasterCoverage - UINT32 GRID DEFLATE
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint32_grid_deflate', 'UINT32', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint32_grid_deflate', 'UINT32', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint32_grid_deflate', 'UINT32', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint32_grid_deflate', 'UINT32', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_uint32_grid_deflateno.testcase b/test/sql_stmt_tests/createcov_uint32_grid_deflateno.testcase
new file mode 100644
index 0000000..b0c8d8d
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_uint32_grid_deflateno.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - UINT32 GRID DEFLATE_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('uint32_grid_deflateno', 'UINT32', 'DATAGRID', 1, 'DEFLATE_NO', 100, 512, 512, 3003, 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('uint32_grid_deflateno', 'UINT32', 'DATAGRID', 1, 'DEFLATE_NO', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_uint32_grid_lzma.testcase b/test/sql_stmt_tests/createcov_uint32_grid_lzma.testcase
index 692a7b4..54bae4f 100644
--- a/test/sql_stmt_tests/createcov_uint32_grid_lzma.testcase
+++ b/test/sql_stmt_tests/createcov_uint32_grid_lzma.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UNIT32 GRID LZMA
+RL2_CreateRasterCoverage - UNIT32 GRID LZMA
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint32_grid_lzma', 'UINT32', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint32_grid_lzma', 'UINT32', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint32_grid_lzma', 'UINT32', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint32_grid_lzma', 'UINT32', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_uint32_grid_lzmano.testcase b/test/sql_stmt_tests/createcov_uint32_grid_lzmano.testcase
new file mode 100644
index 0000000..7086515
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_uint32_grid_lzmano.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - UNIT32 GRID LZMA_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('uint32_grid_lzmano', 'UINT32', 'DATAGRID', 1, 'LZMA_NO', 100, 512, 512, 3003, 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('uint32_grid_lzmano', 'UINT32', 'DATAGRID', 1, 'LZMA_NO', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_uint8_gray.testcase b/test/sql_stmt_tests/createcov_uint8_gray.testcase
index ac5a026..cd3888d 100644
--- a/test/sql_stmt_tests/createcov_uint8_gray.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_gray.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 GRAYSCALE
+RL2_CreateRasterCoverage - UINT8 GRAYSCALE
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_gray', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('uint8_gray', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_gray', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('uint8_gray', 'UINT8', 'GRAYSCALE', 1, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL)
 1
diff --git a/test/sql_stmt_tests/createcov_uint8_gray_deflate.testcase b/test/sql_stmt_tests/createcov_uint8_gray_deflate.testcase
index 0a6cb5f..8c5304a 100644
--- a/test/sql_stmt_tests/createcov_uint8_gray_deflate.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_gray_deflate.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 GRAYSCALE DEFLATE
+RL2_CreateRasterCoverage - UINT8 GRAYSCALE DEFLATE
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_gray_deflate', 'UINT8', 'GRAYSCALE', 1, 'DEFLATE', 10, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('uint8_gray_deflate', 'UINT8', 'GRAYSCALE', 1, 'DEFLATE', 10, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_gray_deflate', 'UINT8', 'GRAYSCALE', 1, 'DEFLATE', 10, 512, 512, 3003, 1.0, 1.0, NULL)
-0
+RL2_CreateRasterCoverage('uint8_gray_deflate', 'UINT8', 'GRAYSCALE', 1, 'DEFLATE', 10, 512, 512, 3003, 1.0, 1.0, NULL)
+1
diff --git a/test/sql_stmt_tests/createcov_uint8_gray_deflateno.testcase b/test/sql_stmt_tests/createcov_uint8_gray_deflateno.testcase
new file mode 100644
index 0000000..129e282
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_uint8_gray_deflateno.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - UINT8 GRAYSCALE DEFLATE_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('uint8_gray_deflateno', 'UINT8', 'GRAYSCALE', 1, 'DEFLATE_NO', 10, 512, 512, 3003, 1.0, 1.0, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('uint8_gray_deflateno', 'UINT8', 'GRAYSCALE', 1, 'DEFLATE_NO', 10, 512, 512, 3003, 1.0, 1.0, NULL)
+1
diff --git a/test/sql_stmt_tests/createcov_uint8_gray_fax3.testcase b/test/sql_stmt_tests/createcov_uint8_gray_fax3.testcase
index fc2b656..47640b0 100644
--- a/test/sql_stmt_tests/createcov_uint8_gray_fax3.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_gray_fax3.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 GRAYSCALE FAX3
+RL2_CreateRasteroverage - UINT8 GRAYSCALE FAX3
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_gray_fax3', 'UINT8', 'GRAYSCALE', 1, 'FAX3', 10, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('uint8_gray_fax3', 'UINT8', 'GRAYSCALE', 1, 'FAX3', 10, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_gray_fax3', 'UINT8', 'GRAYSCALE', 1, 'FAX3', 10, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('uint8_gray_fax3', 'UINT8', 'GRAYSCALE', 1, 'FAX3', 10, 512, 512, 3003, 1.0, 1.0, NULL)
 0
diff --git a/test/sql_stmt_tests/createcov_uint8_gray_fax4.testcase b/test/sql_stmt_tests/createcov_uint8_gray_fax4.testcase
index b1e1993..667998c 100644
--- a/test/sql_stmt_tests/createcov_uint8_gray_fax4.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_gray_fax4.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 GRAYSCALE FAX4
+RL2_CreateRasterCoverage - UINT8 GRAYSCALE FAX4
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_gray_fax4', 'UINT8', 'GRAYSCALE', 1, 'FAX4', 10, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('uint8_gray_fax4', 'UINT8', 'GRAYSCALE', 1, 'FAX4', 10, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_gray_fax4', 'UINT8', 'GRAYSCALE', 1, 'FAX4', 10, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('uint8_gray_fax4', 'UINT8', 'GRAYSCALE', 1, 'FAX4', 10, 512, 512, 3003, 1.0, 1.0, NULL)
 0
diff --git a/test/sql_stmt_tests/createcov_uint8_gray_gif.testcase b/test/sql_stmt_tests/createcov_uint8_gray_gif.testcase
index 2620282..b94732b 100644
--- a/test/sql_stmt_tests/createcov_uint8_gray_gif.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_gray_gif.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 GRAYSCALE GIF
+RL2_CreateRasterCoverage - UINT8 GRAYSCALE GIF
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_gray_gif', 'UINT8', 'GRAYSCALE', 1, 'GIF', 10, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('uint8_gray_gif', 'UINT8', 'GRAYSCALE', 1, 'GIF', 10, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_gray_gif', 'UINT8', 'GRAYSCALE', 1, 'GIF', 10, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('uint8_gray_gif', 'UINT8', 'GRAYSCALE', 1, 'GIF', 10, 512, 512, 3003, 1.0, 1.0, NULL)
 0
diff --git a/test/sql_stmt_tests/createcov_uint8_gray_jpeg.testcase b/test/sql_stmt_tests/createcov_uint8_gray_jpeg.testcase
index 361a85f..3a0242c 100644
--- a/test/sql_stmt_tests/createcov_uint8_gray_jpeg.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_gray_jpeg.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 GRAYSCALE JPEG
+RL2_CreateRasterCoverage - UINT8 GRAYSCALE JPEG
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_gray_jpeg', 'UINT8', 'GRAYSCALE', 1, 'JPEG', 80, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('uint8_gray_jpeg', 'UINT8', 'GRAYSCALE', 1, 'JPEG', 80, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_gray_jpeg', 'UINT8', 'GRAYSCALE', 1, 'JPEG', 80, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('uint8_gray_jpeg', 'UINT8', 'GRAYSCALE', 1, 'JPEG', 80, 512, 512, 3003, 1.0, 1.0, NULL)
 1
diff --git a/test/sql_stmt_tests/createcov_uint8_gray_lzma.testcase b/test/sql_stmt_tests/createcov_uint8_gray_lzma.testcase
index a8724ad..c788e7d 100644
--- a/test/sql_stmt_tests/createcov_uint8_gray_lzma.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_gray_lzma.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 GRAYSCALE LZMA
+RL2_CreateRasterCoverage - UINT8 GRAYSCALE LZMA
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_gray_lzma', 'UINT8', 'GRAYSCALE', 1, 'LZMA', 10, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('uint8_gray_lzma', 'UINT8', 'GRAYSCALE', 1, 'LZMA', 10, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_gray_lzma', 'UINT8', 'GRAYSCALE', 1, 'LZMA', 10, 512, 512, 3003, 1.0, 1.0, NULL)
-0
+RL2_CreateRasterCoverage('uint8_gray_lzma', 'UINT8', 'GRAYSCALE', 1, 'LZMA', 10, 512, 512, 3003, 1.0, 1.0, NULL)
+1
diff --git a/test/sql_stmt_tests/createcov_uint8_gray_lzmano.testcase b/test/sql_stmt_tests/createcov_uint8_gray_lzmano.testcase
new file mode 100644
index 0000000..567d956
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_uint8_gray_lzmano.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - UINT8 GRAYSCALE LZMA_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('uint8_gray_lzmano', 'UINT8', 'GRAYSCALE', 1, 'LZMA_NO', 10, 512, 512, 3003, 1.0, 1.0, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('uint8_gray_lzmano', 'UINT8', 'GRAYSCALE', 1, 'LZMA_NO', 10, 512, 512, 3003, 1.0, 1.0, NULL)
+1
diff --git a/test/sql_stmt_tests/createcov_uint8_gray_png.testcase b/test/sql_stmt_tests/createcov_uint8_gray_png.testcase
index 82d5e4f..79af221 100644
--- a/test/sql_stmt_tests/createcov_uint8_gray_png.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_gray_png.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 GRAYSCALE PNG
+RL2_CreateRasterCoverage - UINT8 GRAYSCALE PNG
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_gray_png', 'UINT8', 'GRAYSCALE', 1, 'PNG', 80, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('uint8_gray_png', 'UINT8', 'GRAYSCALE', 1, 'PNG', 80, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_gray_png', 'UINT8', 'GRAYSCALE', 1, 'PNG', 80, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('uint8_gray_png', 'UINT8', 'GRAYSCALE', 1, 'PNG', 80, 512, 512, 3003, 1.0, 1.0, NULL)
 1
diff --git a/test/sql_stmt_tests/createcov_uint8_gray_webp1.testcase b/test/sql_stmt_tests/createcov_uint8_gray_webp1.testcase
index d22cc29..6de79cc 100644
--- a/test/sql_stmt_tests/createcov_uint8_gray_webp1.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_gray_webp1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 GRAYSCALE LOSSY WEBP
+RL2_CreateRasterCoverage - UINT8 GRAYSCALE LOSSY WEBP
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_gray_webp1', 'UINT8', 'GRAYSCALE', 1, 'WEBP', 10, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('uint8_gray_webp1', 'UINT8', 'GRAYSCALE', 1, 'WEBP', 10, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_gray_webp1', 'UINT8', 'GRAYSCALE', 1, 'WEBP', 10, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('uint8_gray_webp1', 'UINT8', 'GRAYSCALE', 1, 'WEBP', 10, 512, 512, 3003, 1.0, 1.0, NULL)
 1
diff --git a/test/sql_stmt_tests/createcov_uint8_gray_webp2.testcase b/test/sql_stmt_tests/createcov_uint8_gray_webp2.testcase
index dea1883..e308bef 100644
--- a/test/sql_stmt_tests/createcov_uint8_gray_webp2.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_gray_webp2.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 GRAYSCALE LOSSLESS WEBP
+RL2_CreateRasterCoverage - UINT8 GRAYSCALE LOSSLESS WEBP
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_gray_webp2', 'UINT8', 'GRAYSCALE', 1, 'LL_WEBP', 10, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('uint8_gray_webp2', 'UINT8', 'GRAYSCALE', 1, 'LL_WEBP', 10, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_gray_webp2', 'UINT8', 'GRAYSCALE', 1, 'LL_WEBP', 10, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('uint8_gray_webp2', 'UINT8', 'GRAYSCALE', 1, 'LL_WEBP', 10, 512, 512, 3003, 1.0, 1.0, NULL)
 1
diff --git a/test/sql_stmt_tests/createcov_uint8_grid.testcase b/test/sql_stmt_tests/createcov_uint8_grid.testcase
index ebbe6c4..7753f95 100644
--- a/test/sql_stmt_tests/createcov_uint8_grid.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_grid.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 GRID
+RL2_CreateRasterCoverage - UINT8 GRID
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_grid', 'UINT8', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint8_grid', 'UINT8', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_grid', 'UINT8', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint8_grid', 'UINT8', 'DATAGRID', 1, 'NONE', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_uint8_grid1.testcase b/test/sql_stmt_tests/createcov_uint8_grid1.testcase
index 2c11263..105316a 100644
--- a/test/sql_stmt_tests/createcov_uint8_grid1.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_grid1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 GRID invalid Bands
+RL2_CreateRasterCoverage - UINT8 GRID invalid Bands
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_grid1', 'UINT8', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint8_grid1', 'UINT8', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_grid1', 'UINT8', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint8_grid1', 'UINT8', 'DATAGRID', 2, 'NONE', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_uint8_grid_deflate.testcase b/test/sql_stmt_tests/createcov_uint8_grid_deflate.testcase
index 7cb28d9..f8ce62a 100644
--- a/test/sql_stmt_tests/createcov_uint8_grid_deflate.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_grid_deflate.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 GRID DEFLATE
+RL2_CreateRasterCoverage - UINT8 GRID DEFLATE
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_grid_deflate', 'UINT8', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint8_grid_deflate', 'UINT8', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_grid_deflate', 'UINT8', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint8_grid_deflate', 'UINT8', 'DATAGRID', 1, 'DEFLATE', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_uint8_grid_deflateno.testcase b/test/sql_stmt_tests/createcov_uint8_grid_deflateno.testcase
new file mode 100644
index 0000000..8d50e83
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_uint8_grid_deflateno.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - UINT8 GRID DEFLATE_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('uint8_grid_deflateno', 'UINT8', 'DATAGRID', 1, 'DEFLATE_NO', 100, 512, 512, 3003, 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('uint8_grid_deflateno', 'UINT8', 'DATAGRID', 1, 'DEFLATE_NO', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_uint8_grid_lzma.testcase b/test/sql_stmt_tests/createcov_uint8_grid_lzma.testcase
index fdd46cf..efe7d87 100644
--- a/test/sql_stmt_tests/createcov_uint8_grid_lzma.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_grid_lzma.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UNIT8 GRID LZMA
+RL2_CreateRasterCoverage - UNIT8 GRID LZMA
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_grid_lzma', 'UINT8', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint8_grid_lzma', 'UINT8', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_grid_lzma', 'UINT8', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint8_grid_lzma', 'UINT8', 'DATAGRID', 1, 'LZMA', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_uint8_grid_lzmano.testcase b/test/sql_stmt_tests/createcov_uint8_grid_lzmano.testcase
new file mode 100644
index 0000000..f2d6c5d
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_uint8_grid_lzmano.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - UNIT8 GRID LZMA_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('uint8_grid_lzmano', 'UINT8', 'DATAGRID', 1, 'LZMA_NO', 100, 512, 512, 3003, 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('uint8_grid_lzmano', 'UINT8', 'DATAGRID', 1, 'LZMA_NO', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_uint8_palette.testcase b/test/sql_stmt_tests/createcov_uint8_palette.testcase
index fba09d4..198ff25 100644
--- a/test/sql_stmt_tests/createcov_uint8_palette.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_palette.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 PALETTE
+RL2_CreateRasterCoverage - UINT8 PALETTE
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_palette', 'UINT8', 'PALETTE', 1, 'NONE', 10, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('uint8_palette', 'UINT8', 'PALETTE', 1, 'NONE', 10, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_palette', 'UINT8', 'PALETTE', 1, 'NONE', 10, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('uint8_palette', 'UINT8', 'PALETTE', 1, 'NONE', 10, 512, 512, 3003, 1.0, 1.0, NULL)
 1
diff --git a/test/sql_stmt_tests/createcov_uint8_palette_deflate.testcase b/test/sql_stmt_tests/createcov_uint8_palette_deflate.testcase
index d861cae..80a1934 100644
--- a/test/sql_stmt_tests/createcov_uint8_palette_deflate.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_palette_deflate.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 PALETTE DEFLATE
+RL2_CreateRasterCoverage - UINT8 PALETTE DEFLATE
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_palette_deflate', 'UINT8', 'PALETTE', 1, 'DEFLATE', 10, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('uint8_palette_deflate', 'UINT8', 'PALETTE', 1, 'DEFLATE', 10, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_palette_deflate', 'UINT8', 'PALETTE', 1, 'DEFLATE', 10, 512, 512, 3003, 1.0, 1.0, NULL)
-0
+RL2_CreateRasterCoverage('uint8_palette_deflate', 'UINT8', 'PALETTE', 1, 'DEFLATE', 10, 512, 512, 3003, 1.0, 1.0, NULL)
+1
diff --git a/test/sql_stmt_tests/createcov_uint8_palette_deflateno.testcase b/test/sql_stmt_tests/createcov_uint8_palette_deflateno.testcase
new file mode 100644
index 0000000..68f769d
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_uint8_palette_deflateno.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - UINT8 PALETTE DEFLATE_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('uint8_palette_deflateno', 'UINT8', 'PALETTE', 1, 'DEFLATE_NO', 10, 512, 512, 3003, 1.0, 1.0, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('uint8_palette_deflateno', 'UINT8', 'PALETTE', 1, 'DEFLATE_NO', 10, 512, 512, 3003, 1.0, 1.0, NULL)
+1
diff --git a/test/sql_stmt_tests/createcov_uint8_palette_fax3.testcase b/test/sql_stmt_tests/createcov_uint8_palette_fax3.testcase
index d79ec58..f831cee 100644
--- a/test/sql_stmt_tests/createcov_uint8_palette_fax3.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_palette_fax3.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 PALETTE FAX3
+RL2_CreateRasterCoverage - UINT8 PALETTE FAX3
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_palette_fax3', 'UINT8', 'PALETTE', 1, 'FAX3', 10, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('uint8_palette_fax3', 'UINT8', 'PALETTE', 1, 'FAX3', 10, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_palette_fax3', 'UINT8', 'PALETTE', 1, 'FAX3', 10, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('uint8_palette_fax3', 'UINT8', 'PALETTE', 1, 'FAX3', 10, 512, 512, 3003, 1.0, 1.0, NULL)
 0
diff --git a/test/sql_stmt_tests/createcov_uint8_palette_fax4.testcase b/test/sql_stmt_tests/createcov_uint8_palette_fax4.testcase
index 4584815..f01a200 100644
--- a/test/sql_stmt_tests/createcov_uint8_palette_fax4.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_palette_fax4.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 PALETTE FAX3
+RL2_CreateRasterCoverage - UINT8 PALETTE FAX3
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_palette_fax4', 'UINT8', 'PALETTE', 1, 'FAX4', 10, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('uint8_palette_fax4', 'UINT8', 'PALETTE', 1, 'FAX4', 10, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_palette_fax4', 'UINT8', 'PALETTE', 1, 'FAX4', 10, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('uint8_palette_fax4', 'UINT8', 'PALETTE', 1, 'FAX4', 10, 512, 512, 3003, 1.0, 1.0, NULL)
 0
diff --git a/test/sql_stmt_tests/createcov_uint8_palette_gif.testcase b/test/sql_stmt_tests/createcov_uint8_palette_gif.testcase
index 97f6d14..55d1e9a 100644
--- a/test/sql_stmt_tests/createcov_uint8_palette_gif.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_palette_gif.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 PALETTE GIF
+RL2_CreateRasterCoverage - UINT8 PALETTE GIF
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_palette_gif', 'UINT8', 'PALETTE', 1, 'GIF', 10, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('uint8_palette_gif', 'UINT8', 'PALETTE', 1, 'GIF', 10, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_palette_gif', 'UINT8', 'PALETTE', 1, 'GIF', 10, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('uint8_palette_gif', 'UINT8', 'PALETTE', 1, 'GIF', 10, 512, 512, 3003, 1.0, 1.0, NULL)
 0
diff --git a/test/sql_stmt_tests/createcov_uint8_palette_jpeg.testcase b/test/sql_stmt_tests/createcov_uint8_palette_jpeg.testcase
index 1392be2..dfb22ff 100644
--- a/test/sql_stmt_tests/createcov_uint8_palette_jpeg.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_palette_jpeg.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 PALETTE JPEG
+RL2_CreateRasterCoverage - UINT8 PALETTE JPEG
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_palette_jpeg', 'UINT8', 'PALETTE', 1, 'JPEG', 10, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('uint8_palette_jpeg', 'UINT8', 'PALETTE', 1, 'JPEG', 10, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_palette_jpeg', 'UINT8', 'PALETTE', 1, 'JPEG', 10, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('uint8_palette_jpeg', 'UINT8', 'PALETTE', 1, 'JPEG', 10, 512, 512, 3003, 1.0, 1.0, NULL)
 0
diff --git a/test/sql_stmt_tests/createcov_uint8_palette_lzma.testcase b/test/sql_stmt_tests/createcov_uint8_palette_lzma.testcase
index a0fbcf8..5df7987 100644
--- a/test/sql_stmt_tests/createcov_uint8_palette_lzma.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_palette_lzma.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 PALETTE LZMA
+RL2_CreateRasterCoverage - UINT8 PALETTE LZMA
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_palette_lzma', 'UINT8', 'PALETTE', 1, 'LZMA', 10, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('uint8_palette_lzma', 'UINT8', 'PALETTE', 1, 'LZMA', 10, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_palette_lzma', 'UINT8', 'PALETTE', 1, 'LZMA', 10, 512, 512, 3003, 1.0, 1.0, NULL)
-0
+RL2_CreateRasterCoverage('uint8_palette_lzma', 'UINT8', 'PALETTE', 1, 'LZMA', 10, 512, 512, 3003, 1.0, 1.0, NULL)
+1
diff --git a/test/sql_stmt_tests/createcov_uint8_palette_lzmano.testcase b/test/sql_stmt_tests/createcov_uint8_palette_lzmano.testcase
new file mode 100644
index 0000000..db71eed
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_uint8_palette_lzmano.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - UINT8 PALETTE LZMA_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('uint8_palette_lzmano', 'UINT8', 'PALETTE', 1, 'LZMA_NO', 10, 512, 512, 3003, 1.0, 1.0, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('uint8_palette_lzmano', 'UINT8', 'PALETTE', 1, 'LZMA_NO', 10, 512, 512, 3003, 1.0, 1.0, NULL)
+1
diff --git a/test/sql_stmt_tests/createcov_uint8_palette_png.testcase b/test/sql_stmt_tests/createcov_uint8_palette_png.testcase
index 644e315..c29427d 100644
--- a/test/sql_stmt_tests/createcov_uint8_palette_png.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_palette_png.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 PALETTE PNG
+RL2_CreateRasterCoverage - UINT8 PALETTE PNG
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_palette_png', 'UINT8', 'PALETTE', 1, 'PNG', 10, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('uint8_palette_png', 'UINT8', 'PALETTE', 1, 'PNG', 10, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_palette_png', 'UINT8', 'PALETTE', 1, 'PNG', 10, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('uint8_palette_png', 'UINT8', 'PALETTE', 1, 'PNG', 10, 512, 512, 3003, 1.0, 1.0, NULL)
 1
diff --git a/test/sql_stmt_tests/createcov_uint8_palette_webp1.testcase b/test/sql_stmt_tests/createcov_uint8_palette_webp1.testcase
index 4bbc603..cd0b11a 100644
--- a/test/sql_stmt_tests/createcov_uint8_palette_webp1.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_palette_webp1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 PALETTE LOSSY WEBP
+RL2_CreateRasterCoverage - UINT8 PALETTE LOSSY WEBP
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_palette_webp1', 'UINT8', 'PALETTE', 1, 'WEBP', 10, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('uint8_palette_webp1', 'UINT8', 'PALETTE', 1, 'WEBP', 10, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_palette_webp1', 'UINT8', 'PALETTE', 1, 'WEBP', 10, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('uint8_palette_webp1', 'UINT8', 'PALETTE', 1, 'WEBP', 10, 512, 512, 3003, 1.0, 1.0, NULL)
 0
diff --git a/test/sql_stmt_tests/createcov_uint8_palette_webp2.testcase b/test/sql_stmt_tests/createcov_uint8_palette_webp2.testcase
index a44f701..525d5cb 100644
--- a/test/sql_stmt_tests/createcov_uint8_palette_webp2.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_palette_webp2.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 PALETTE LOSSLESS WEBP
+RL2_CreateRasterCoverage - UINT8 PALETTE LOSSLESS WEBP
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_palette_webp2', 'UINT8', 'PALETTE', 1, 'LL_WEBP', 10, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('uint8_palette_webp2', 'UINT8', 'PALETTE', 1, 'LL_WEBP', 10, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_palette_webp2', 'UINT8', 'PALETTE', 1, 'LL_WEBP', 10, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('uint8_palette_webp2', 'UINT8', 'PALETTE', 1, 'LL_WEBP', 10, 512, 512, 3003, 1.0, 1.0, NULL)
 0
diff --git a/test/sql_stmt_tests/createcov_uint8_rgb.testcase b/test/sql_stmt_tests/createcov_uint8_rgb.testcase
index 65ca69e..84e64e1 100644
--- a/test/sql_stmt_tests/createcov_uint8_rgb.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_rgb.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 RGB
+RL2_CreateRasterCoverage - UINT8 RGB
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_rgb1', 'UINT8', 'RGB', 3, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('uint8_rgb1', 'UINT8', 'RGB', 3, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_rgb1', 'UINT8', 'RGB', 3, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('uint8_rgb1', 'UINT8', 'RGB', 3, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL)
 1
diff --git a/test/sql_stmt_tests/createcov_uint8_rgb1.testcase b/test/sql_stmt_tests/createcov_uint8_rgb1.testcase
index 343f14a..05a0151 100644
--- a/test/sql_stmt_tests/createcov_uint8_rgb1.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_rgb1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 RGB invalid Bands
+RL2_CreateRasterCoverage - UINT8 RGB invalid Bands
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_rgb1', 'UINT8', 'RGB', 2, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL);
+SELECT RL2_CreateRasterCoverage('uint8_rgb1', 'UINT8', 'RGB', 2, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_rgb1', 'UINT8', 'RGB', 2, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL)
+RL2_CreateRasterCoverage('uint8_rgb1', 'UINT8', 'RGB', 2, 'NONE', 100, 512, 512, 3003, 1.0, 1.0, NULL)
 0
diff --git a/test/sql_stmt_tests/createcov_uint8_rgb_deflate.testcase b/test/sql_stmt_tests/createcov_uint8_rgb_deflate.testcase
index c62d452..9dcbf7f 100644
--- a/test/sql_stmt_tests/createcov_uint8_rgb_deflate.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_rgb_deflate.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 RGB DEFLATE
+RL2_CreateRasterCoverage - UINT8 RGB DEFLATE
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_rgb_deflate', 'UINT8', 'RGB', 3, 'DEFLATE', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint8_rgb_deflate', 'UINT8', 'RGB', 3, 'DEFLATE', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_rgb_deflate', 'UINT8', 'RGB', 3, 'DEFLATE', 100, 512, 512, 3003, 1.0)
-0
+RL2_CreateRasterCoverage('uint8_rgb_deflate', 'UINT8', 'RGB', 3, 'DEFLATE', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_uint8_rgb_deflateno.testcase b/test/sql_stmt_tests/createcov_uint8_rgb_deflateno.testcase
new file mode 100644
index 0000000..70356bb
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_uint8_rgb_deflateno.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - UINT8 RGB DEFLATE_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('uint8_rgb_deflateno', 'UINT8', 'RGB', 3, 'DEFLATE_NO', 100, 512, 512, 3003, 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('uint8_rgb_deflateno', 'UINT8', 'RGB', 3, 'DEFLATE_NO', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_uint8_rgb_fax3.testcase b/test/sql_stmt_tests/createcov_uint8_rgb_fax3.testcase
index 930d88b..da9c02d 100644
--- a/test/sql_stmt_tests/createcov_uint8_rgb_fax3.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_rgb_fax3.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 RGB FAX3
+RL2_CreateRasterCoverage - UINT8 RGB FAX3
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_rgb_fax3', 'UINT8', 'RGB', 3, 'FAX3', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint8_rgb_fax3', 'UINT8', 'RGB', 3, 'FAX3', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_rgb_fax3', 'UINT8', 'RGB', 3, 'FAX3', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint8_rgb_fax3', 'UINT8', 'RGB', 3, 'FAX3', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_uint8_rgb_fax4.testcase b/test/sql_stmt_tests/createcov_uint8_rgb_fax4.testcase
index 8a65eb4..3c6858a 100644
--- a/test/sql_stmt_tests/createcov_uint8_rgb_fax4.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_rgb_fax4.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 RGB FAX4
+RL2_CreateRasterCoverage - UINT8 RGB FAX4
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_rgb_fax4', 'UINT8', 'RGB', 3, 'FAX4', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint8_rgb_fax4', 'UINT8', 'RGB', 3, 'FAX4', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_rgb_fax4', 'UINT8', 'RGB', 3, 'FAX4', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint8_rgb_fax4', 'UINT8', 'RGB', 3, 'FAX4', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_uint8_rgb_gif.testcase b/test/sql_stmt_tests/createcov_uint8_rgb_gif.testcase
index 8d5d44c..33f7038 100644
--- a/test/sql_stmt_tests/createcov_uint8_rgb_gif.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_rgb_gif.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 RGB GIF
+RL2_CreateRasterCoverage - UINT8 RGB GIF
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_rgb_gif', 'UINT8', 'RGB', 3, 'GIF', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint8_rgb_gif', 'UINT8', 'RGB', 3, 'GIF', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_rgb_gif', 'UINT8', 'RGB', 3, 'GIF', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint8_rgb_gif', 'UINT8', 'RGB', 3, 'GIF', 100, 512, 512, 3003, 1.0)
 0
diff --git a/test/sql_stmt_tests/createcov_uint8_rgb_jpeg.testcase b/test/sql_stmt_tests/createcov_uint8_rgb_jpeg.testcase
index 91554c2..774ad3c 100644
--- a/test/sql_stmt_tests/createcov_uint8_rgb_jpeg.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_rgb_jpeg.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 RGB JPEG
+RL2_CreateRasterCoverage - UINT8 RGB JPEG
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_rgb_jpeg', 'UINT8', 'RGB', 3, 'JPEG', 80, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint8_rgb_jpeg', 'UINT8', 'RGB', 3, 'JPEG', 80, 512, 512, 3003, 1.0, 1.0, NULL, 1, 1, 1, 1, 1);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_rgb_jpeg', 'UINT8', 'RGB', 3, 'JPEG', 80, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint8_rgb_jpeg', 'UINT8', 'RGB', 3, 'JPEG', 80, 512, 512, 3003, 1.0, 1.0, NULL, 1, 1, 1, 1, 1)
 1
diff --git a/test/sql_stmt_tests/createcov_uint8_rgb_lzma.testcase b/test/sql_stmt_tests/createcov_uint8_rgb_lzma.testcase
index 6bcc433..c2fa8f4 100644
--- a/test/sql_stmt_tests/createcov_uint8_rgb_lzma.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_rgb_lzma.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 RGB LZMA
+RL2_CreateRasterCoverage - UINT8 RGB LZMA
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_rgb_lzma', 'UINT8', 'RGB', 3, 'LZMA', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint8_rgb_lzma', 'UINT8', 'RGB', 3, 'LZMA', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_rgb_lzma', 'UINT8', 'RGB', 3, 'LZMA', 100, 512, 512, 3003, 1.0)
-0
+RL2_CreateRasterCoverage('uint8_rgb_lzma', 'UINT8', 'RGB', 3, 'LZMA', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_uint8_rgb_lzmano.testcase b/test/sql_stmt_tests/createcov_uint8_rgb_lzmano.testcase
new file mode 100644
index 0000000..bab6929
--- /dev/null
+++ b/test/sql_stmt_tests/createcov_uint8_rgb_lzmano.testcase
@@ -0,0 +1,7 @@
+RL2_CreateRasterCoverage - UINT8 RGB LZMA_NO
+:memory: #use in-memory database
+SELECT RL2_CreateRasterCoverage('uint8_rgb_lzmano', 'UINT8', 'RGB', 3, 'LZMA_NO', 100, 512, 512, 3003, 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_CreateRasterCoverage('uint8_rgb_lzmano', 'UINT8', 'RGB', 3, 'LZMA_NO', 100, 512, 512, 3003, 1.0)
+1
diff --git a/test/sql_stmt_tests/createcov_uint8_rgb_png.testcase b/test/sql_stmt_tests/createcov_uint8_rgb_png.testcase
index 7eb0efc..c31633a 100644
--- a/test/sql_stmt_tests/createcov_uint8_rgb_png.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_rgb_png.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 RGB PNG
+RL2_CreateRasterCoverage - UINT8 RGB PNG
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_rgb_png', 'UINT8', 'RGB', 3, 'PNG', 100, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint8_rgb_png', 'UINT8', 'RGB', 3, 'PNG', 100, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_rgb_png', 'UINT8', 'RGB', 3, 'PNG', 100, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint8_rgb_png', 'UINT8', 'RGB', 3, 'PNG', 100, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_uint8_rgb_webp1.testcase b/test/sql_stmt_tests/createcov_uint8_rgb_webp1.testcase
index 180da3e..f36cb1d 100644
--- a/test/sql_stmt_tests/createcov_uint8_rgb_webp1.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_rgb_webp1.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 RGB LOSSY WEBP
+RL2_CreateRasterCoverage - UINT8 RGB LOSSY WEBP
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_rgb_webp1', 'UINT8', 'RGB', 3, 'WEBP', 80, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint8_rgb_webp1', 'UINT8', 'RGB', 3, 'WEBP', 80, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_rgb_webp1', 'UINT8', 'RGB', 3, 'WEBP', 80, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint8_rgb_webp1', 'UINT8', 'RGB', 3, 'WEBP', 80, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/createcov_uint8_rgb_webp2.testcase b/test/sql_stmt_tests/createcov_uint8_rgb_webp2.testcase
index 22db3b1..e8eac9a 100644
--- a/test/sql_stmt_tests/createcov_uint8_rgb_webp2.testcase
+++ b/test/sql_stmt_tests/createcov_uint8_rgb_webp2.testcase
@@ -1,7 +1,7 @@
-RL2_CreateCoverage - UINT8 RGB LOSSLESS WEBP
+RL2_CreateRasterCoverage - UINT8 RGB LOSSLESS WEBP
 :memory: #use in-memory database
-SELECT RL2_CreateCoverage('uint8_rgb_webp2', 'UINT8', 'RGB', 3, 'LL_WEBP', 80, 512, 512, 3003, 1.0);
+SELECT RL2_CreateRasterCoverage('uint8_rgb_webp2', 'UINT8', 'RGB', 3, 'LL_WEBP', 80, 512, 512, 3003, 1.0);
 1 # rows (not including the header row)
 1 # columns
-RL2_CreateCoverage('uint8_rgb_webp2', 'UINT8', 'RGB', 3, 'LL_WEBP', 80, 512, 512, 3003, 1.0)
+RL2_CreateRasterCoverage('uint8_rgb_webp2', 'UINT8', 'RGB', 3, 'LL_WEBP', 80, 512, 512, 3003, 1.0)
 1
diff --git a/test/sql_stmt_tests/deletesection3.testcase b/test/sql_stmt_tests/deletesection3.testcase
index ee6d115..9c71cc9 100644
--- a/test/sql_stmt_tests/deletesection3.testcase
+++ b/test/sql_stmt_tests/deletesection3.testcase
@@ -1,7 +1,7 @@
 DeleteSection - NULL transaction
 :memory: #use in-memory database
-SELECT RL2_DeleteSection('alpha', 'beta', NULL);
+SELECT RL2_DeleteSection('alpha', 1, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_DeleteSection('alpha', 'beta', NULL)
+RL2_DeleteSection('alpha', 1, NULL)
 -1
diff --git a/test/sql_stmt_tests/deletesection4.testcase b/test/sql_stmt_tests/deletesection4.testcase
index 817e0ed..e4df6dc 100644
--- a/test/sql_stmt_tests/deletesection4.testcase
+++ b/test/sql_stmt_tests/deletesection4.testcase
@@ -1,7 +1,7 @@
 DeleteSection - not existing
 :memory: #use in-memory database
-SELECT RL2_DeleteSection('alpha', 'beta', 1);
+SELECT RL2_DeleteSection('alpha', 1, 1);
 1 # rows (not including the header row)
 1 # columns
-RL2_DeleteSection('alpha', 'beta', 1)
+RL2_DeleteSection('alpha', 1, 1)
 0
diff --git a/test/sql_stmt_tests/depyramidize10.testcase b/test/sql_stmt_tests/depyramidize10.testcase
index e05c9a1..3fe8f86 100644
--- a/test/sql_stmt_tests/depyramidize10.testcase
+++ b/test/sql_stmt_tests/depyramidize10.testcase
@@ -1,7 +1,7 @@
 rl2_depyramidize - BLOB Transaction
 :memory: #use in-memory database
-SELECT rl2_depyramidize('coverage', 'section', zeroblob(4));
+SELECT rl2_depyramidize('coverage', 1, zeroblob(4));
 1 # rows (not including the header row)
 1 # columns
-rl2_depyramidize('coverage', 'section', zeroblob(4))
+rl2_depyramidize('coverage', 1, zeroblob(4))
 -1
diff --git a/test/sql_stmt_tests/depyramidize11.testcase b/test/sql_stmt_tests/depyramidize11.testcase
index b550970..213b07e 100644
--- a/test/sql_stmt_tests/depyramidize11.testcase
+++ b/test/sql_stmt_tests/depyramidize11.testcase
@@ -1,7 +1,7 @@
 rl2_depyramidize - DOUBLE Transaction
 :memory: #use in-memory database
-SELECT rl2_depyramidize('coverage', 'section', 1.1);
+SELECT rl2_depyramidize('coverage', 1, 1.1);
 1 # rows (not including the header row)
 1 # columns
-rl2_depyramidize('coverage', 'section', 1.1)
+rl2_depyramidize('coverage', 1, 1.1)
 -1
diff --git a/test/sql_stmt_tests/depyramidize12.testcase b/test/sql_stmt_tests/depyramidize12.testcase
index 9971ed7..3082bbb 100644
--- a/test/sql_stmt_tests/depyramidize12.testcase
+++ b/test/sql_stmt_tests/depyramidize12.testcase
@@ -1,7 +1,7 @@
 rl2_depyramidize - TEXT Transaction
 :memory: #use in-memory database
-SELECT rl2_depyramidize('coverage', 'section', 'no');
+SELECT rl2_depyramidize('coverage', 1, 'no');
 1 # rows (not including the header row)
 1 # columns
-rl2_depyramidize('coverage', 'section', 'no')
+rl2_depyramidize('coverage', 1, 'no')
 -1
diff --git a/test/sql_stmt_tests/depyramidize6.testcase b/test/sql_stmt_tests/depyramidize6.testcase
index 9f14629..cbde5f5 100644
--- a/test/sql_stmt_tests/depyramidize6.testcase
+++ b/test/sql_stmt_tests/depyramidize6.testcase
@@ -1,7 +1,7 @@
-rl2_depyramidize - INT Section
+rl2_depyramidize - TEXT Section
 :memory: #use in-memory database
-SELECT rl2_depyramidize('coverage', 1);
+SELECT rl2_depyramidize('coverage', 'alpha');
 1 # rows (not including the header row)
 1 # columns
-rl2_depyramidize('coverage', 1)
+rl2_depyramidize('coverage', 'alpha')
 -1
diff --git a/test/sql_stmt_tests/depyramidize9.testcase b/test/sql_stmt_tests/depyramidize9.testcase
index 35e227a..40c7c46 100644
--- a/test/sql_stmt_tests/depyramidize9.testcase
+++ b/test/sql_stmt_tests/depyramidize9.testcase
@@ -1,7 +1,7 @@
 rl2_depyramidize - NULL Transaction
 :memory: #use in-memory database
-SELECT rl2_depyramidize('coverage', 'section', NULL);
+SELECT rl2_depyramidize('coverage', 1, NULL);
 1 # rows (not including the header row)
 1 # columns
-rl2_depyramidize('coverage', 'section', NULL)
+rl2_depyramidize('coverage', 1, NULL)
 -1
diff --git a/test/sql_stmt_tests/dropcoverage1.testcase b/test/sql_stmt_tests/dropcoverage1.testcase
index 8219ae5..99bf658 100644
--- a/test/sql_stmt_tests/dropcoverage1.testcase
+++ b/test/sql_stmt_tests/dropcoverage1.testcase
@@ -1,7 +1,7 @@
-DropCoverage - NULL coverage
+DropRasterCoverage - NULL coverage
 :memory: #use in-memory database
-SELECT RL2_DropCoverage(NULL);
+SELECT RL2_DropRasterCoverage(NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_DropCoverage(NULL)
+RL2_DropRasterCoverage(NULL)
 -1
diff --git a/test/sql_stmt_tests/dropcoverage2.testcase b/test/sql_stmt_tests/dropcoverage2.testcase
index 8a0f88d..fb3a29f 100644
--- a/test/sql_stmt_tests/dropcoverage2.testcase
+++ b/test/sql_stmt_tests/dropcoverage2.testcase
@@ -1,7 +1,7 @@
-DropCoverage - NULL transaction
+DropRasterCoverage - NULL transaction
 :memory: #use in-memory database
-SELECT RL2_DropCoverage('alpha', NULL);
+SELECT RL2_DropRasterCoverage('alpha', NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_DropCoverage('alpha', NULL)
+RL2_DropRasterCoverage('alpha', NULL)
 -1
diff --git a/test/sql_stmt_tests/dropcoverage3.testcase b/test/sql_stmt_tests/dropcoverage3.testcase
index 188e5a7..3f94f2f 100644
--- a/test/sql_stmt_tests/dropcoverage3.testcase
+++ b/test/sql_stmt_tests/dropcoverage3.testcase
@@ -1,7 +1,7 @@
-DropCoverage - not existing
+DropRasterCoverage - not existing
 :memory: #use in-memory database
-SELECT RL2_DropCoverage('alpha', 1);
+SELECT RL2_DropRasterCoverage('alpha', 1);
 1 # rows (not including the header row)
 1 # columns
-RL2_DropCoverage('alpha', 1)
+RL2_DropRasterCoverage('alpha', 1)
 0
diff --git a/test/sql_stmt_tests/enableautondvi1.testcase b/test/sql_stmt_tests/enableautondvi1.testcase
new file mode 100644
index 0000000..6a08ff2
--- /dev/null
+++ b/test/sql_stmt_tests/enableautondvi1.testcase
@@ -0,0 +1,7 @@
+RL2_EnableRasterCoverageAutoNDVI - NULL Coverage
+:memory: #use in-memory database
+SELECT RL2_EnableRasterCoverageAutoNDVI(NULL, 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_EnableRasterCoverageAutoNDVI(NULL, 1)
+-1
diff --git a/test/sql_stmt_tests/enableautondvi2.testcase b/test/sql_stmt_tests/enableautondvi2.testcase
new file mode 100644
index 0000000..075c65a
--- /dev/null
+++ b/test/sql_stmt_tests/enableautondvi2.testcase
@@ -0,0 +1,7 @@
+RL2_EnableRasterCoverageAutoNDVI - NULL OnOff
+:memory: #use in-memory database
+SELECT RL2_EnableRasterCoverageAutoNDVI('test', NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_EnableRasterCoverageAutoNDVI('test', NULL)
+-1
diff --git a/test/sql_stmt_tests/enableautondvi3.testcase b/test/sql_stmt_tests/enableautondvi3.testcase
new file mode 100644
index 0000000..b5b1e38
--- /dev/null
+++ b/test/sql_stmt_tests/enableautondvi3.testcase
@@ -0,0 +1,7 @@
+RL2_EnableRasterCoverageAutoNDVI - Not existing Coverage
+:memory: #use in-memory database
+SELECT RL2_EnableRasterCoverageAutoNDVI('test', 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_EnableRasterCoverageAutoNDVI('test', 1)
+0
diff --git a/test/sql_stmt_tests/exportraw1.testcase b/test/sql_stmt_tests/exportraw1.testcase
new file mode 100644
index 0000000..4acd197
--- /dev/null
+++ b/test/sql_stmt_tests/exportraw1.testcase
@@ -0,0 +1,7 @@
+RL2_ExportRawPixels - NULL coverage
+:memory: #use in-memory database
+SELECT RL2_ExportRawPixels(NULL, 1000, 1000, BuildMBR(1, 2, 3, 4), 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportRawPixels(NULL, 1000, 1000, BuildMBR(1, 2, 3, 4), 1.0)
+(NULL)
diff --git a/test/sql_stmt_tests/exportraw2.testcase b/test/sql_stmt_tests/exportraw2.testcase
new file mode 100644
index 0000000..bdfdbb1
--- /dev/null
+++ b/test/sql_stmt_tests/exportraw2.testcase
@@ -0,0 +1,7 @@
+RL2_ExportRawPixels - NULL width
+:memory: #use in-memory database
+SELECT RL2_ExportRawPixels('coverage', NULL, 1000, BuildMBR(1, 2, 3, 4), 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportRawPixels('coverage', NULL, 1000, BuildMBR(1, 2, 3, 4), 1.0)
+(NULL)
diff --git a/test/sql_stmt_tests/exportraw3.testcase b/test/sql_stmt_tests/exportraw3.testcase
new file mode 100644
index 0000000..a5aaef7
--- /dev/null
+++ b/test/sql_stmt_tests/exportraw3.testcase
@@ -0,0 +1,7 @@
+RL2_ExportRawPixels - NULL height
+:memory: #use in-memory database
+SELECT RL2_ExportRawPixels('coverage', 1000, NULL, BuildMBR(1, 2, 3, 4), 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportRawPixels('coverage', 1000, NULL, BuildMBR(1, 2, 3, 4), 1.0)
+(NULL)
diff --git a/test/sql_stmt_tests/exportraw4.testcase b/test/sql_stmt_tests/exportraw4.testcase
new file mode 100644
index 0000000..ec97acc
--- /dev/null
+++ b/test/sql_stmt_tests/exportraw4.testcase
@@ -0,0 +1,7 @@
+RL2_ExportRawPixels - NULL bbox
+:memory: #use in-memory database
+SELECT RL2_ExportRawPixels('coverage', 1000, 1000, NULL, 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportRawPixels('coverage', 1000, 1000, NULL, 1.0)
+(NULL)
diff --git a/test/sql_stmt_tests/exportraw5.testcase b/test/sql_stmt_tests/exportraw5.testcase
new file mode 100644
index 0000000..a1a9b85
--- /dev/null
+++ b/test/sql_stmt_tests/exportraw5.testcase
@@ -0,0 +1,7 @@
+RL2_ExportRawPixels - NULL resolution
+:memory: #use in-memory database
+SELECT RL2_ExportRawPixels('coverage', 1000, 1000, BuildMBR(1, 2, 3, 4), NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportRawPixels('coverage', 1000, 1000, BuildMBR(1, 2, 3, 4), NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/exportraw6.testcase b/test/sql_stmt_tests/exportraw6.testcase
new file mode 100644
index 0000000..78344f2
--- /dev/null
+++ b/test/sql_stmt_tests/exportraw6.testcase
@@ -0,0 +1,7 @@
+RL2_ExportRawPixels - NULL vertical resolution
+:memory: #use in-memory database
+SELECT RL2_ExportRawPixels('coverage', 1000, 1000, BuildMBR(1, 2, 3, 4), 1, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportRawPixels('coverage', 1000, 1000, BuildMBR(1, 2, 3, 4), 1, NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/exportraw7.testcase b/test/sql_stmt_tests/exportraw7.testcase
new file mode 100644
index 0000000..9a09d01
--- /dev/null
+++ b/test/sql_stmt_tests/exportraw7.testcase
@@ -0,0 +1,7 @@
+RL2_ExportRawPixels - NULL big-endian
+:memory: #use in-memory database
+SELECT RL2_ExportRawPixels('coverage', 1000, 1000, BuildMBR(1, 2, 3, 4), 1, 1.0, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportRawPixels('coverage', 1000, 1000, BuildMBR(1, 2, 3, 4), 1, 1.0, NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/exportraw8.testcase b/test/sql_stmt_tests/exportraw8.testcase
new file mode 100644
index 0000000..278064b
--- /dev/null
+++ b/test/sql_stmt_tests/exportraw8.testcase
@@ -0,0 +1,7 @@
+RL2_ExportRawPixels - not existing Coverage
+:memory: #use in-memory database
+SELECT RL2_ExportRawPixels('coverage', 1000, 1000, BuildMBR(1, 2, 3, 4), 1, 1, 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportRawPixels('coverage', 1000, 1000, BuildMBR(1, 2, 3, 4), 1, 1, 1)
+(NULL)
diff --git a/test/sql_stmt_tests/exportsectraw1.testcase b/test/sql_stmt_tests/exportsectraw1.testcase
new file mode 100644
index 0000000..0c2e002
--- /dev/null
+++ b/test/sql_stmt_tests/exportsectraw1.testcase
@@ -0,0 +1,7 @@
+RL2_ExportSectionRawPixels - NULL coverage
+:memory: #use in-memory database
+SELECT RL2_ExportSectionRawPixels(NULL, 1, 1000, 1000, BuildMBR(1, 2, 3, 4), 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportSectionRawPixels(NULL, 1, 1000, 1000, BuildMBR(1, 2, 3, 4), 1.0)
+(NULL)
diff --git a/test/sql_stmt_tests/exportsectraw2.testcase b/test/sql_stmt_tests/exportsectraw2.testcase
new file mode 100644
index 0000000..cb794f1
--- /dev/null
+++ b/test/sql_stmt_tests/exportsectraw2.testcase
@@ -0,0 +1,7 @@
+RL2_ExportSectionRawPixels - NULL section
+:memory: #use in-memory database
+SELECT RL2_ExportSectionRawPixels('coverage', NULL, 1000, 1000, BuildMBR(1, 2, 3, 4), 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportSectionRawPixels('coverage', NULL, 1000, 1000, BuildMBR(1, 2, 3, 4), 1.0)
+(NULL)
diff --git a/test/sql_stmt_tests/exportsectraw3.testcase b/test/sql_stmt_tests/exportsectraw3.testcase
new file mode 100644
index 0000000..159cffd
--- /dev/null
+++ b/test/sql_stmt_tests/exportsectraw3.testcase
@@ -0,0 +1,7 @@
+RL2_ExportSectionRawPixels - NULL width
+:memory: #use in-memory database
+SELECT RL2_ExportSectionRawPixels('coverage', 1, NULL, 1000, BuildMBR(1, 2, 3, 4), 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportSectionRawPixels('coverage', 1, NULL, 1000, BuildMBR(1, 2, 3, 4), 1.0)
+(NULL)
diff --git a/test/sql_stmt_tests/exportsectraw4.testcase b/test/sql_stmt_tests/exportsectraw4.testcase
new file mode 100644
index 0000000..d40f626
--- /dev/null
+++ b/test/sql_stmt_tests/exportsectraw4.testcase
@@ -0,0 +1,7 @@
+RL2_ExportSectionRawPixels - NULL height
+:memory: #use in-memory database
+SELECT RL2_ExportSectionRawPixels('coverage', 1, 1000, NULL, BuildMBR(1, 2, 3, 4), 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportSectionRawPixels('coverage', 1, 1000, NULL, BuildMBR(1, 2, 3, 4), 1.0)
+(NULL)
diff --git a/test/sql_stmt_tests/exportsectraw5.testcase b/test/sql_stmt_tests/exportsectraw5.testcase
new file mode 100644
index 0000000..a3e8ab9
--- /dev/null
+++ b/test/sql_stmt_tests/exportsectraw5.testcase
@@ -0,0 +1,7 @@
+RL2_ExportSectionRawPixels - NULL bbox
+:memory: #use in-memory database
+SELECT RL2_ExportSectionRawPixels('coverage', 1, 1000, 1000, NULL, 1.0);
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportSectionRawPixels('coverage', 1, 1000, 1000, NULL, 1.0)
+(NULL)
diff --git a/test/sql_stmt_tests/exportsectraw6.testcase b/test/sql_stmt_tests/exportsectraw6.testcase
new file mode 100644
index 0000000..d26f2f5
--- /dev/null
+++ b/test/sql_stmt_tests/exportsectraw6.testcase
@@ -0,0 +1,7 @@
+RL2_ExportSectionRawPixels - NULL resolution
+:memory: #use in-memory database
+SELECT RL2_ExportSectionRawPixels('coverage', 1, 1000, 1000, BuildMBR(1, 2, 3, 4), NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportSectionRawPixels('coverage', 1, 1000, 1000, BuildMBR(1, 2, 3, 4), NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/exportsectraw7.testcase b/test/sql_stmt_tests/exportsectraw7.testcase
new file mode 100644
index 0000000..8d6298e
--- /dev/null
+++ b/test/sql_stmt_tests/exportsectraw7.testcase
@@ -0,0 +1,7 @@
+RL2_ExportSectionRawPixels - NULL vertical resolution
+:memory: #use in-memory database
+SELECT RL2_ExportSectionRawPixels('coverage', 1, 1000, 1000, BuildMBR(1, 2, 3, 4), 1, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportSectionRawPixels('coverage', 1, 1000, 1000, BuildMBR(1, 2, 3, 4), 1, NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/exportsectraw8.testcase b/test/sql_stmt_tests/exportsectraw8.testcase
new file mode 100644
index 0000000..500eea1
--- /dev/null
+++ b/test/sql_stmt_tests/exportsectraw8.testcase
@@ -0,0 +1,7 @@
+RL2_ExportSectionRawPixels - NULL big-endian
+:memory: #use in-memory database
+SELECT RL2_ExportSectionRawPixels('coverage', 1, 1000, 1000, BuildMBR(1, 2, 3, 4), 1, 1.0, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportSectionRawPixels('coverage', 1, 1000, 1000, BuildMBR(1, 2, 3, 4), 1, 1.0, NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/exportsectraw9.testcase b/test/sql_stmt_tests/exportsectraw9.testcase
new file mode 100644
index 0000000..e4cab28
--- /dev/null
+++ b/test/sql_stmt_tests/exportsectraw9.testcase
@@ -0,0 +1,7 @@
+RL2_ExportSectionRawPixels - not existing Coverage
+:memory: #use in-memory database
+SELECT RL2_ExportSectionRawPixels('coverage', 1, 1000, 1000, BuildMBR(1, 2, 3, 4), 1, 1, 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_ExportSectionRawPixels('coverage', 1, 1000, 1000, BuildMBR(1, 2, 3, 4), 1, 1, 1)
+(NULL)
diff --git a/test/sql_stmt_tests/getfontfacename1.testcase b/test/sql_stmt_tests/getfontfacename1.testcase
new file mode 100644
index 0000000..4017bf1
--- /dev/null
+++ b/test/sql_stmt_tests/getfontfacename1.testcase
@@ -0,0 +1,7 @@
+GetFontFacename - NULL Font
+:memory: #use in-memory database
+SELECT RL2_GetFontFacename(NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetFontFacename(NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/getfontfacename2.testcase b/test/sql_stmt_tests/getfontfacename2.testcase
new file mode 100644
index 0000000..228e534
--- /dev/null
+++ b/test/sql_stmt_tests/getfontfacename2.testcase
@@ -0,0 +1,7 @@
+GetFontFacename - Text Font
+:memory: #use in-memory database
+SELECT RL2_GetFontFacename('myfont');
+1 # rows (not including the header row)
+1 # columns
+RL2_GetFontFacename('myfont')
+(NULL)
diff --git a/test/sql_stmt_tests/getfontfacename3.testcase b/test/sql_stmt_tests/getfontfacename3.testcase
new file mode 100644
index 0000000..0431d06
--- /dev/null
+++ b/test/sql_stmt_tests/getfontfacename3.testcase
@@ -0,0 +1,7 @@
+GetFontFacename - Integer Font
+:memory: #use in-memory database
+SELECT RL2_GetFontFacename(1);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetFontFacename(1)
+(NULL)
diff --git a/test/sql_stmt_tests/getfontfacename4.testcase b/test/sql_stmt_tests/getfontfacename4.testcase
new file mode 100644
index 0000000..e1a7e2e
--- /dev/null
+++ b/test/sql_stmt_tests/getfontfacename4.testcase
@@ -0,0 +1,7 @@
+GetFontFacename - Double Font
+:memory: #use in-memory database
+SELECT RL2_GetFontFacename(1.2);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetFontFacename(1.2)
+(NULL)
diff --git a/test/sql_stmt_tests/getfontfacename5.testcase b/test/sql_stmt_tests/getfontfacename5.testcase
new file mode 100644
index 0000000..3b5b2d0
--- /dev/null
+++ b/test/sql_stmt_tests/getfontfacename5.testcase
@@ -0,0 +1,7 @@
+GetFontFacename - invalid BLOB Font
+:memory: #use in-memory database
+SELECT RL2_GetFontFacename(zeroblob(10));
+1 # rows (not including the header row)
+1 # columns
+RL2_GetFontFacename(zeroblob(10))
+(NULL)
diff --git a/test/sql_stmt_tests/getfontfamily1.testcase b/test/sql_stmt_tests/getfontfamily1.testcase
new file mode 100644
index 0000000..d545d98
--- /dev/null
+++ b/test/sql_stmt_tests/getfontfamily1.testcase
@@ -0,0 +1,7 @@
+GetFontFamily - NULL Font
+:memory: #use in-memory database
+SELECT RL2_GetFontFamily(NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetFontFamily(NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/getfontfamily2.testcase b/test/sql_stmt_tests/getfontfamily2.testcase
new file mode 100644
index 0000000..8b2b0be
--- /dev/null
+++ b/test/sql_stmt_tests/getfontfamily2.testcase
@@ -0,0 +1,7 @@
+GetFontFamily - Text Font
+:memory: #use in-memory database
+SELECT RL2_GetFontFamily('myfont');
+1 # rows (not including the header row)
+1 # columns
+RL2_GetFontFamily('myfont')
+(NULL)
diff --git a/test/sql_stmt_tests/getfontfamily3.testcase b/test/sql_stmt_tests/getfontfamily3.testcase
new file mode 100644
index 0000000..7832827
--- /dev/null
+++ b/test/sql_stmt_tests/getfontfamily3.testcase
@@ -0,0 +1,7 @@
+GetFontFamily - Integer Font
+:memory: #use in-memory database
+SELECT RL2_GetFontFamily(1);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetFontFamily(1)
+(NULL)
diff --git a/test/sql_stmt_tests/getfontfamily4.testcase b/test/sql_stmt_tests/getfontfamily4.testcase
new file mode 100644
index 0000000..9549e49
--- /dev/null
+++ b/test/sql_stmt_tests/getfontfamily4.testcase
@@ -0,0 +1,7 @@
+GetFontFamily - Double Font
+:memory: #use in-memory database
+SELECT RL2_GetFontFamily(1.2);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetFontFamily(1.2)
+(NULL)
diff --git a/test/sql_stmt_tests/getfontfamily5.testcase b/test/sql_stmt_tests/getfontfamily5.testcase
new file mode 100644
index 0000000..d91b64f
--- /dev/null
+++ b/test/sql_stmt_tests/getfontfamily5.testcase
@@ -0,0 +1,7 @@
+GetFontFamily - invalid BLOB Font
+:memory: #use in-memory database
+SELECT RL2_GetFontFamily(zeroblob(10));
+1 # rows (not including the header row)
+1 # columns
+RL2_GetFontFamily(zeroblob(10))
+(NULL)
diff --git a/test/sql_stmt_tests/getmapimage1.testcase b/test/sql_stmt_tests/getmapimage1.testcase
index e74a87c..708f1a8 100644
--- a/test/sql_stmt_tests/getmapimage1.testcase
+++ b/test/sql_stmt_tests/getmapimage1.testcase
@@ -1,7 +1,7 @@
-RL2_GetMapImage - NULL coverage 
+RL2_GetMapImageFromRaster - NULL coverage 
 :memory: #use in-memory database
-SELECT RL2_GetMapImage(NULL, BuildMbr(1, 1, 10, 10), 640, 480);
+SELECT RL2_GetMapImageFromRaster(NULL, BuildMbr(1, 1, 10, 10), 640, 480);
 1 # rows (not including the header row)
 1 # columns
-RL2_GetMapImage(NULL, BuildMbr(1, 1, 10, 10), 640, 480)
+RL2_GetMapImageFromRaster(NULL, BuildMbr(1, 1, 10, 10), 640, 480)
 (NULL)
diff --git a/test/sql_stmt_tests/getmapimage10.testcase b/test/sql_stmt_tests/getmapimage10.testcase
index 06f769a..ad94a8d 100644
--- a/test/sql_stmt_tests/getmapimage10.testcase
+++ b/test/sql_stmt_tests/getmapimage10.testcase
@@ -1,7 +1,7 @@
-RL2_GetMapImage - Invalid BLOB geometry
+RL2_GetMapImageFromRaster - Invalid BLOB geometry
 :memory: #use in-memory database
-SELECT RL2_GetMapImage('landsat', zeroblob(100), 640, 480, 'default', 'image/png', '#ffffff', 1, 100, 0);
+SELECT RL2_GetMapImageFromRaster('landsat', zeroblob(100), 640, 480, 'default', 'image/png', '#ffffff', 1, 100, 0);
 1 # rows (not including the header row)
 1 # columns
-RL2_GetMapImage('landsat', zeroblob(100), 640, 480, 'default', 'image/png', '#ffffff', 1, 100, 0)
+RL2_GetMapImageFromRaster('landsat', zeroblob(100), 640, 480, 'default', 'image/png', '#ffffff', 1, 100, 0)
 (NULL)
diff --git a/test/sql_stmt_tests/getmapimage11.testcase b/test/sql_stmt_tests/getmapimage11.testcase
new file mode 100644
index 0000000..d704b15
--- /dev/null
+++ b/test/sql_stmt_tests/getmapimage11.testcase
@@ -0,0 +1,7 @@
+RL2_GetMapImageFromRaster - Invalid POINT geometry
+:memory: #use in-memory database
+SELECT RL2_GetMapImageFromRaster('landsat', MakePoint(1, 1), 640, 480, 'default', 'image/png', '#ffffff', 1, 100, 0);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetMapImageFromRaster('landsat', MakePoint(1, 1), 640, 480, 'default', 'image/png', '#ffffff', 1, 100, 0)
+(NULL)
diff --git a/test/sql_stmt_tests/getmapimage12.testcase b/test/sql_stmt_tests/getmapimage12.testcase
index 982f0ae..84d9b30 100644
--- a/test/sql_stmt_tests/getmapimage12.testcase
+++ b/test/sql_stmt_tests/getmapimage12.testcase
@@ -1,7 +1,7 @@
-RL2_GetMapImage - Invalid width (too small)
+RL2_GetMapImageFromRaster - Invalid width (too small)
 :memory: #use in-memory database
-SELECT RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 6, 480, 'default', 'image/png', '#ffffff', 1, 100, 0);
+SELECT RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 6, 480, 'default', 'image/png', '#ffffff', 1, 100, 0);
 1 # rows (not including the header row)
 1 # columns
-RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 6, 480, 'default', 'image/png', '#ffffff', 1, 100, 0)
+RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 6, 480, 'default', 'image/png', '#ffffff', 1, 100, 0)
 (NULL)
diff --git a/test/sql_stmt_tests/getmapimage13.testcase b/test/sql_stmt_tests/getmapimage13.testcase
index d423d97..6d53394 100644
--- a/test/sql_stmt_tests/getmapimage13.testcase
+++ b/test/sql_stmt_tests/getmapimage13.testcase
@@ -1,7 +1,7 @@
-RL2_GetMapImage - Invalid width (too big)
+RL2_GetMapImageFromRaster - Invalid width (too big)
 :memory: #use in-memory database
-SELECT RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 6666, 480, 'default', 'image/png', '#ffffff', 1, 100, 0);
+SELECT RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 6666, 480, 'default', 'image/png', '#ffffff', 1, 100, 0);
 1 # rows (not including the header row)
 1 # columns
-RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 6666, 480, 'default', 'image/png', '#ffffff', 1, 100, 0)
+RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 6666, 480, 'default', 'image/png', '#ffffff', 1, 100, 0)
 (NULL)
diff --git a/test/sql_stmt_tests/getmapimage14.testcase b/test/sql_stmt_tests/getmapimage14.testcase
index 3dc5b1f..2745290 100644
--- a/test/sql_stmt_tests/getmapimage14.testcase
+++ b/test/sql_stmt_tests/getmapimage14.testcase
@@ -1,7 +1,7 @@
-RL2_GetMapImage - Invalid height (too small)
+RL2_GetMapImageFromRaster - Invalid height (too small)
 :memory: #use in-memory database
-SELECT RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, 8, 'default', 'image/png', '#ffffff', 1, 100, 0);
+SELECT RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, 8, 'default', 'image/png', '#ffffff', 1, 100, 0);
 1 # rows (not including the header row)
 1 # columns
-RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, 8, 'default', 'image/png', '#ffffff', 1, 100, 0)
+RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, 8, 'default', 'image/png', '#ffffff', 1, 100, 0)
 (NULL)
diff --git a/test/sql_stmt_tests/getmapimage15.testcase b/test/sql_stmt_tests/getmapimage15.testcase
index 1849acb..1fb2c88 100644
--- a/test/sql_stmt_tests/getmapimage15.testcase
+++ b/test/sql_stmt_tests/getmapimage15.testcase
@@ -1,7 +1,7 @@
-RL2_GetMapImage - Invalid height (too big)
+RL2_GetMapImageFromRaster - Invalid height (too big)
 :memory: #use in-memory database
-SELECT RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, 8888, 'default', 'image/png', '#ffffff', 1, 100, 0);
+SELECT RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, 8888, 'default', 'image/png', '#ffffff', 1, 100, 0);
 1 # rows (not including the header row)
 1 # columns
-RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, 8888, 'default', 'image/png', '#ffffff', 1, 100, 0)
+RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, 8888, 'default', 'image/png', '#ffffff', 1, 100, 0)
 (NULL)
diff --git a/test/sql_stmt_tests/getmapimage16.testcase b/test/sql_stmt_tests/getmapimage16.testcase
index 9a5c4b6..20de003 100644
--- a/test/sql_stmt_tests/getmapimage16.testcase
+++ b/test/sql_stmt_tests/getmapimage16.testcase
@@ -1,7 +1,7 @@
-RL2_GetMapImage - Invalid style
+RL2_GetMapImageFromRaster - Invalid style
 :memory: #use in-memory database
-SELECT RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'gothic', 'image/png', '#ffffff', 1, 100, 0);
+SELECT RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'gothic', 'image/png', '#ffffff', 1, 100, 0);
 1 # rows (not including the header row)
 1 # columns
-RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'gothic', 'image/png', '#ffffff', 1, 100, 0)
+RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'gothic', 'image/png', '#ffffff', 1, 100, 0)
 (NULL)
diff --git a/test/sql_stmt_tests/getmapimage17.testcase b/test/sql_stmt_tests/getmapimage17.testcase
index 31040ea..dfdbf36 100644
--- a/test/sql_stmt_tests/getmapimage17.testcase
+++ b/test/sql_stmt_tests/getmapimage17.testcase
@@ -1,7 +1,7 @@
-RL2_GetMapImage - Invalid format
+RL2_GetMapImageFromRaster - Invalid format
 :memory: #use in-memory database
-SELECT RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'text/plain', '#ffffff', 1, 100, 0);
+SELECT RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'text/plain', '#ffffff', 1, 100, 0);
 1 # rows (not including the header row)
 1 # columns
-RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'text/plain', '#ffffff', 1, 100, 0)
+RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'text/plain', '#ffffff', 1, 100, 0)
 (NULL)
diff --git a/test/sql_stmt_tests/getmapimage18.testcase b/test/sql_stmt_tests/getmapimage18.testcase
index fccbad6..60e1768 100644
--- a/test/sql_stmt_tests/getmapimage18.testcase
+++ b/test/sql_stmt_tests/getmapimage18.testcase
@@ -1,7 +1,7 @@
-RL2_GetMapImage - not existing coverage
+RL2_GetMapImageFromRaster - not existing coverage
 :memory: #use in-memory database
-SELECT RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/jpeg', '#ffffff', 1, 80, 0);
+SELECT RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/jpeg', '#ffffff', 1, 80, 0);
 1 # rows (not including the header row)
 1 # columns
-RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/jpeg', '#ffffff', 1, 80, 0)
+RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/jpeg', '#ffffff', 1, 80, 0)
 (NULL)
diff --git a/test/sql_stmt_tests/getmapimage19.testcase b/test/sql_stmt_tests/getmapimage19.testcase
index e31b8d3..f7ff6c1 100644
--- a/test/sql_stmt_tests/getmapimage19.testcase
+++ b/test/sql_stmt_tests/getmapimage19.testcase
@@ -1,7 +1,7 @@
-RL2_GetMapImage - NULL background color
+RL2_GetMapImageFromRaster - NULL background color
 :memory: #use in-memory database
-SELECT RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/jpeg', NULL, 1, 80, 0);
+SELECT RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/jpeg', NULL, 1, 80, 0);
 1 # rows (not including the header row)
 1 # columns
-RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/jpeg', NULL, 1, 80, 0)
+RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/jpeg', NULL, 1, 80, 0)
 (NULL)
diff --git a/test/sql_stmt_tests/getmapimage2.testcase b/test/sql_stmt_tests/getmapimage2.testcase
index 657686c..b3800e2 100644
--- a/test/sql_stmt_tests/getmapimage2.testcase
+++ b/test/sql_stmt_tests/getmapimage2.testcase
@@ -1,7 +1,7 @@
-RL2_GetMapImage - NULL BBOX
+RL2_GetMapImageFromRaster - NULL BBOX
 :memory: #use in-memory database
-SELECT RL2_GetMapImage('landsat', NULL, 640, 480);
+SELECT RL2_GetMapImageFromRaster('landsat', NULL, 640, 480);
 1 # rows (not including the header row)
 1 # columns
-RL2_GetMapImage('landsat', NULL, 640, 480)
+RL2_GetMapImageFromRaster('landsat', NULL, 640, 480)
 (NULL)
diff --git a/test/sql_stmt_tests/getmapimage20.testcase b/test/sql_stmt_tests/getmapimage20.testcase
index e4633c3..a3f306c 100644
--- a/test/sql_stmt_tests/getmapimage20.testcase
+++ b/test/sql_stmt_tests/getmapimage20.testcase
@@ -1,7 +1,7 @@
-RL2_GetMapImage - invalid background color
+RL2_GetMapImageFromRaster - invalid background color
 :memory: #use in-memory database
-SELECT RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/jpeg', 'magenta', 1, 80, 0);
+SELECT RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/jpeg', 'magenta', 1, 80, 0);
 1 # rows (not including the header row)
 1 # columns
-RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/jpeg', 'magenta', 1, 80, 0)
+RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/jpeg', 'magenta', 1, 80, 0)
 (NULL)
diff --git a/test/sql_stmt_tests/getmapimage3.testcase b/test/sql_stmt_tests/getmapimage3.testcase
index 0041752..2f6f671 100644
--- a/test/sql_stmt_tests/getmapimage3.testcase
+++ b/test/sql_stmt_tests/getmapimage3.testcase
@@ -1,7 +1,7 @@
-RL2_GetMapImage - NULL width
+RL2_GetMapImageFromRaster - NULL width
 :memory: #use in-memory database
-SELECT RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), NULL, 480);
+SELECT RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), NULL, 480);
 1 # rows (not including the header row)
 1 # columns
-RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), NULL, 480)
+RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), NULL, 480)
 (NULL)
diff --git a/test/sql_stmt_tests/getmapimage4.testcase b/test/sql_stmt_tests/getmapimage4.testcase
index ca6cc9e..611ba87 100644
--- a/test/sql_stmt_tests/getmapimage4.testcase
+++ b/test/sql_stmt_tests/getmapimage4.testcase
@@ -1,7 +1,7 @@
-RL2_GetMapImage - NULL height
+RL2_GetMapImageFromRaster - NULL height
 :memory: #use in-memory database
-SELECT RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, NULL);
+SELECT RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, NULL)
+RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, NULL)
 (NULL)
diff --git a/test/sql_stmt_tests/getmapimage5.testcase b/test/sql_stmt_tests/getmapimage5.testcase
index 0b10899..8ad5c6a 100644
--- a/test/sql_stmt_tests/getmapimage5.testcase
+++ b/test/sql_stmt_tests/getmapimage5.testcase
@@ -1,7 +1,7 @@
-RL2_GetMapImage - NULL style
+RL2_GetMapImageFromRaster - NULL style
 :memory: #use in-memory database
-SELECT RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, 480, NULL);
+SELECT RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, 480, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, 480, NULL)
+RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, 480, NULL)
 (NULL)
diff --git a/test/sql_stmt_tests/getmapimage6.testcase b/test/sql_stmt_tests/getmapimage6.testcase
index ec4f55b..717bbd2 100644
--- a/test/sql_stmt_tests/getmapimage6.testcase
+++ b/test/sql_stmt_tests/getmapimage6.testcase
@@ -1,7 +1,7 @@
-RL2_GetMapImage - NULL format
+RL2_GetMapImageFromRaster - NULL format
 :memory: #use in-memory database
-SELECT RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', NULL);
+SELECT RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', NULL)
+RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', NULL)
 (NULL)
diff --git a/test/sql_stmt_tests/getmapimage7.testcase b/test/sql_stmt_tests/getmapimage7.testcase
index fd511b8..295948f 100644
--- a/test/sql_stmt_tests/getmapimage7.testcase
+++ b/test/sql_stmt_tests/getmapimage7.testcase
@@ -1,7 +1,7 @@
-RL2_GetMapImage - NULL transparent
+RL2_GetMapImageFromRaster - NULL transparent
 :memory: #use in-memory database
-SELECT RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/png', '#ffffff', NULL);
+SELECT RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/png', '#ffffff', NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/png', '#ffffff', NULL)
+RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/png', '#ffffff', NULL)
 (NULL)
diff --git a/test/sql_stmt_tests/getmapimage8.testcase b/test/sql_stmt_tests/getmapimage8.testcase
index 46e832b..b212b7b 100644
--- a/test/sql_stmt_tests/getmapimage8.testcase
+++ b/test/sql_stmt_tests/getmapimage8.testcase
@@ -1,7 +1,7 @@
-RL2_GetMapImage - NULL quality
+RL2_GetMapImageFromRaster - NULL quality
 :memory: #use in-memory database
-SELECT RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/png', '#ffffff', 1, NULL);
+SELECT RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/png', '#ffffff', 1, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/png', '#ffffff', 1, NULL)
+RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/png', '#ffffff', 1, NULL)
 (NULL)
diff --git a/test/sql_stmt_tests/getmapimage9.testcase b/test/sql_stmt_tests/getmapimage9.testcase
index 6461417..469b4c4 100644
--- a/test/sql_stmt_tests/getmapimage9.testcase
+++ b/test/sql_stmt_tests/getmapimage9.testcase
@@ -1,7 +1,7 @@
-RL2_GetMapImage - NULL reaspect
+RL2_GetMapImageFromRaster - NULL reaspect
 :memory: #use in-memory database
-SELECT RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/png', '#ffffff', 1, 100, NULL);
+SELECT RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/png', '#ffffff', 1, 100, NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_GetMapImage('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/png', '#ffffff', 1, 100, NULL)
+RL2_GetMapImageFromRaster('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/png', '#ffffff', 1, 100, NULL)
 (NULL)
diff --git a/test/sql_stmt_tests/getmaxthreads1.testcase b/test/sql_stmt_tests/getmaxthreads1.testcase
new file mode 100644
index 0000000..7996c40
--- /dev/null
+++ b/test/sql_stmt_tests/getmaxthreads1.testcase
@@ -0,0 +1,7 @@
+RL2_GetMaxThreads 
+:memory: #use in-memory database
+SELECT RL2_GetMaxThreads();
+1 # rows (not including the header row)
+1 # columns
+RL2_GetMaxThreads()
+1
diff --git a/test/sql_stmt_tests/getvectorimage1.testcase b/test/sql_stmt_tests/getvectorimage1.testcase
new file mode 100644
index 0000000..5330e04
--- /dev/null
+++ b/test/sql_stmt_tests/getvectorimage1.testcase
@@ -0,0 +1,7 @@
+RL2_GetMapImageFromVector - NULL coverage 
+:memory: #use in-memory database
+SELECT RL2_GetMapImageFromVector(NULL, BuildMbr(1, 1, 10, 10), 640, 480);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetMapImageFromVector(NULL, BuildMbr(1, 1, 10, 10), 640, 480)
+(NULL)
diff --git a/test/sql_stmt_tests/getvectorimage10.testcase b/test/sql_stmt_tests/getvectorimage10.testcase
new file mode 100644
index 0000000..cb8b0bd
--- /dev/null
+++ b/test/sql_stmt_tests/getvectorimage10.testcase
@@ -0,0 +1,7 @@
+RL2_GetMapImageFromVector - Invalid BLOB geometry
+:memory: #use in-memory database
+SELECT RL2_GetMapImageFromVector('landsat', zeroblob(100), 640, 480, 'default', 'image/png', '#ffffff', 1, 100, 0);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetMapImageFromVector('landsat', zeroblob(100), 640, 480, 'default', 'image/png', '#ffffff', 1, 100, 0)
+(NULL)
diff --git a/test/sql_stmt_tests/getvectorimage11.testcase b/test/sql_stmt_tests/getvectorimage11.testcase
new file mode 100644
index 0000000..2706254
--- /dev/null
+++ b/test/sql_stmt_tests/getvectorimage11.testcase
@@ -0,0 +1,7 @@
+RL2_GetMapImageFromVector - Invalid POINT geometry
+:memory: #use in-memory database
+SELECT RL2_GetMapImageFromVector('landsat', MakePoint(1, 1), 640, 480, 'default', 'image/png', '#ffffff', 1, 100, 0);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetMapImageFromVector('landsat', MakePoint(1, 1), 640, 480, 'default', 'image/png', '#ffffff', 1, 100, 0)
+(NULL)
diff --git a/test/sql_stmt_tests/getvectorimage12.testcase b/test/sql_stmt_tests/getvectorimage12.testcase
new file mode 100644
index 0000000..1e2694a
--- /dev/null
+++ b/test/sql_stmt_tests/getvectorimage12.testcase
@@ -0,0 +1,7 @@
+RL2_GetMapImageFromVector - Invalid width (too small)
+:memory: #use in-memory database
+SELECT RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 6, 480, 'default', 'image/png', '#ffffff', 1, 100, 0);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 6, 480, 'default', 'image/png', '#ffffff', 1, 100, 0)
+(NULL)
diff --git a/test/sql_stmt_tests/getvectorimage13.testcase b/test/sql_stmt_tests/getvectorimage13.testcase
new file mode 100644
index 0000000..095ad52
--- /dev/null
+++ b/test/sql_stmt_tests/getvectorimage13.testcase
@@ -0,0 +1,7 @@
+RL2_GetMapImageFromVector - Invalid width (too big)
+:memory: #use in-memory database
+SELECT RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 6666, 480, 'default', 'image/png', '#ffffff', 1, 100, 0);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 6666, 480, 'default', 'image/png', '#ffffff', 1, 100, 0)
+(NULL)
diff --git a/test/sql_stmt_tests/getvectorimage14.testcase b/test/sql_stmt_tests/getvectorimage14.testcase
new file mode 100644
index 0000000..6159919
--- /dev/null
+++ b/test/sql_stmt_tests/getvectorimage14.testcase
@@ -0,0 +1,7 @@
+RL2_GetMapImageFromVector - Invalid height (too small)
+:memory: #use in-memory database
+SELECT RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, 8, 'default', 'image/png', '#ffffff', 1, 100, 0);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, 8, 'default', 'image/png', '#ffffff', 1, 100, 0)
+(NULL)
diff --git a/test/sql_stmt_tests/getvectorimage15.testcase b/test/sql_stmt_tests/getvectorimage15.testcase
new file mode 100644
index 0000000..c5121ea
--- /dev/null
+++ b/test/sql_stmt_tests/getvectorimage15.testcase
@@ -0,0 +1,7 @@
+RL2_GetMapImageFromVector - Invalid height (too big)
+:memory: #use in-memory database
+SELECT RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, 8888, 'default', 'image/png', '#ffffff', 1, 100, 0);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, 8888, 'default', 'image/png', '#ffffff', 1, 100, 0)
+(NULL)
diff --git a/test/sql_stmt_tests/getvectorimage16.testcase b/test/sql_stmt_tests/getvectorimage16.testcase
new file mode 100644
index 0000000..2dd328a
--- /dev/null
+++ b/test/sql_stmt_tests/getvectorimage16.testcase
@@ -0,0 +1,7 @@
+RL2_GetMapImageFromVector - Invalid style
+:memory: #use in-memory database
+SELECT RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'gothic', 'image/png', '#ffffff', 1, 100, 0);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'gothic', 'image/png', '#ffffff', 1, 100, 0)
+(NULL)
diff --git a/test/sql_stmt_tests/getvectorimage17.testcase b/test/sql_stmt_tests/getvectorimage17.testcase
new file mode 100644
index 0000000..5ecb108
--- /dev/null
+++ b/test/sql_stmt_tests/getvectorimage17.testcase
@@ -0,0 +1,7 @@
+RL2_GetMapImageFromVector - Invalid format
+:memory: #use in-memory database
+SELECT RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'text/plain', '#ffffff', 1, 100, 0);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'text/plain', '#ffffff', 1, 100, 0)
+(NULL)
diff --git a/test/sql_stmt_tests/getvectorimage18.testcase b/test/sql_stmt_tests/getvectorimage18.testcase
new file mode 100644
index 0000000..2effba6
--- /dev/null
+++ b/test/sql_stmt_tests/getvectorimage18.testcase
@@ -0,0 +1,7 @@
+RL2_GetMapImageFromVector - not existing coverage
+:memory: #use in-memory database
+SELECT RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/jpeg', '#ffffff', 1, 80, 0);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/jpeg', '#ffffff', 1, 80, 0)
+(NULL)
diff --git a/test/sql_stmt_tests/getvectorimage19.testcase b/test/sql_stmt_tests/getvectorimage19.testcase
new file mode 100644
index 0000000..c906fb1
--- /dev/null
+++ b/test/sql_stmt_tests/getvectorimage19.testcase
@@ -0,0 +1,7 @@
+RL2_GetMapImageFromVector - NULL background color
+:memory: #use in-memory database
+SELECT RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/jpeg', NULL, 1, 80, 0);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/jpeg', NULL, 1, 80, 0)
+(NULL)
diff --git a/test/sql_stmt_tests/getvectorimage2.testcase b/test/sql_stmt_tests/getvectorimage2.testcase
new file mode 100644
index 0000000..ee9dada
--- /dev/null
+++ b/test/sql_stmt_tests/getvectorimage2.testcase
@@ -0,0 +1,7 @@
+RL2_GetMapImageFromVector - NULL BBOX
+:memory: #use in-memory database
+SELECT RL2_GetMapImageFromVector('landsat', NULL, 640, 480);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetMapImageFromVector('landsat', NULL, 640, 480)
+(NULL)
diff --git a/test/sql_stmt_tests/getvectorimage20.testcase b/test/sql_stmt_tests/getvectorimage20.testcase
new file mode 100644
index 0000000..9b44d51
--- /dev/null
+++ b/test/sql_stmt_tests/getvectorimage20.testcase
@@ -0,0 +1,7 @@
+RL2_GetMapImageFromVector - invalid background color
+:memory: #use in-memory database
+SELECT RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/jpeg', 'magenta', 1, 80, 0);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/jpeg', 'magenta', 1, 80, 0)
+(NULL)
diff --git a/test/sql_stmt_tests/getvectorimage3.testcase b/test/sql_stmt_tests/getvectorimage3.testcase
new file mode 100644
index 0000000..c1b6557
--- /dev/null
+++ b/test/sql_stmt_tests/getvectorimage3.testcase
@@ -0,0 +1,7 @@
+RL2_GetMapImageFromVector - NULL width
+:memory: #use in-memory database
+SELECT RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), NULL, 480);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), NULL, 480)
+(NULL)
diff --git a/test/sql_stmt_tests/getvectorimage4.testcase b/test/sql_stmt_tests/getvectorimage4.testcase
new file mode 100644
index 0000000..84821ab
--- /dev/null
+++ b/test/sql_stmt_tests/getvectorimage4.testcase
@@ -0,0 +1,7 @@
+RL2_GetMapImageFromVector - NULL height
+:memory: #use in-memory database
+SELECT RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/getvectorimage5.testcase b/test/sql_stmt_tests/getvectorimage5.testcase
new file mode 100644
index 0000000..cdf04e8
--- /dev/null
+++ b/test/sql_stmt_tests/getvectorimage5.testcase
@@ -0,0 +1,7 @@
+RL2_GetMapImageFromVector - NULL style
+:memory: #use in-memory database
+SELECT RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, 480, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, 480, NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/getvectorimage6.testcase b/test/sql_stmt_tests/getvectorimage6.testcase
new file mode 100644
index 0000000..e22a9e4
--- /dev/null
+++ b/test/sql_stmt_tests/getvectorimage6.testcase
@@ -0,0 +1,7 @@
+RL2_GetMapImageFromVector - NULL format
+:memory: #use in-memory database
+SELECT RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/getvectorimage7.testcase b/test/sql_stmt_tests/getvectorimage7.testcase
new file mode 100644
index 0000000..c586fdd
--- /dev/null
+++ b/test/sql_stmt_tests/getvectorimage7.testcase
@@ -0,0 +1,7 @@
+RL2_GetMapImageFromVector - NULL transparent
+:memory: #use in-memory database
+SELECT RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/png', '#ffffff', NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/png', '#ffffff', NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/getvectorimage8.testcase b/test/sql_stmt_tests/getvectorimage8.testcase
new file mode 100644
index 0000000..a7efcb3
--- /dev/null
+++ b/test/sql_stmt_tests/getvectorimage8.testcase
@@ -0,0 +1,7 @@
+RL2_GetMapImageFromVector - NULL quality
+:memory: #use in-memory database
+SELECT RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/png', '#ffffff', 1, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/png', '#ffffff', 1, NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/getvectorimage9.testcase b/test/sql_stmt_tests/getvectorimage9.testcase
new file mode 100644
index 0000000..c037ab6
--- /dev/null
+++ b/test/sql_stmt_tests/getvectorimage9.testcase
@@ -0,0 +1,7 @@
+RL2_GetMapImageFromVector - NULL reaspect
+:memory: #use in-memory database
+SELECT RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/png', '#ffffff', 1, 100, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_GetMapImageFromVector('landsat', BuildMbr(1, 1, 10, 10), 640, 480, 'default', 'image/png', '#ffffff', 1, 100, NULL)
+(NULL)
diff --git a/test/sql_stmt_tests/importraw1.testcase b/test/sql_stmt_tests/importraw1.testcase
new file mode 100644
index 0000000..f4fe904
--- /dev/null
+++ b/test/sql_stmt_tests/importraw1.testcase
@@ -0,0 +1,7 @@
+RL2_ImportSectionRawPixels - NULL coverage
+:memory: #use in-memory database
+SELECT RL2_ImportSectionRawPixels(NULL, 'section', 1000, 1000, zeroblob(1000000), BuildMBR(1, 2, 3, 4));
+1 # rows (not including the header row)
+1 # columns
+RL2_ImportSectionRawPixels(NULL, 'section', 1000, 1000, zeroblob(1000000), BuildMBR(1, 2, 3, 4))
+-1
diff --git a/test/sql_stmt_tests/importraw10.testcase b/test/sql_stmt_tests/importraw10.testcase
new file mode 100644
index 0000000..c83f319
--- /dev/null
+++ b/test/sql_stmt_tests/importraw10.testcase
@@ -0,0 +1,7 @@
+RL2_ImportSectionRawPixels - not existent Coverage
+:memory: #use in-memory database
+SELECT RL2_ImportSectionRawPixels('coverage', 'section', 1000, 1000, zeroblob(1000000), BuildMBR(1, 2, 3, 4), 1, 1, 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_ImportSectionRawPixels('coverage', 'section', 1000, 1000, zeroblob(1000000), BuildMBR(1, 2, 3, 4), 1, 1, 1)
+-1
diff --git a/test/sql_stmt_tests/importraw2.testcase b/test/sql_stmt_tests/importraw2.testcase
new file mode 100644
index 0000000..21b8afa
--- /dev/null
+++ b/test/sql_stmt_tests/importraw2.testcase
@@ -0,0 +1,7 @@
+RL2_ImportSectionRawPixels - NULL section
+:memory: #use in-memory database
+SELECT RL2_ImportSectionRawPixels('coverage', NULL, 1000, 1000, zeroblob(1000000), BuildMBR(1, 2, 3, 4));
+1 # rows (not including the header row)
+1 # columns
+RL2_ImportSectionRawPixels('coverage', NULL, 1000, 1000, zeroblob(1000000), BuildMBR(1, 2, 3, 4))
+-1
diff --git a/test/sql_stmt_tests/importraw3.testcase b/test/sql_stmt_tests/importraw3.testcase
new file mode 100644
index 0000000..e84c7c3
--- /dev/null
+++ b/test/sql_stmt_tests/importraw3.testcase
@@ -0,0 +1,7 @@
+RL2_ImportSectionRawPixels - NULL width
+:memory: #use in-memory database
+SELECT RL2_ImportSectionRawPixels('coverage', 'section', NULL, 1000, zeroblob(1000000), BuildMBR(1, 2, 3, 4));
+1 # rows (not including the header row)
+1 # columns
+RL2_ImportSectionRawPixels('coverage', 'section', NULL, 1000, zeroblob(1000000), BuildMBR(1, 2, 3, 4))
+-1
diff --git a/test/sql_stmt_tests/importraw4.testcase b/test/sql_stmt_tests/importraw4.testcase
new file mode 100644
index 0000000..c3d398f
--- /dev/null
+++ b/test/sql_stmt_tests/importraw4.testcase
@@ -0,0 +1,7 @@
+RL2_ImportSectionRawPixels - NULL height
+:memory: #use in-memory database
+SELECT RL2_ImportSectionRawPixels('coverage', 'section', 1000, NULL, zeroblob(1000000), BuildMBR(1, 2, 3, 4));
+1 # rows (not including the header row)
+1 # columns
+RL2_ImportSectionRawPixels('coverage', 'section', 1000, NULL, zeroblob(1000000), BuildMBR(1, 2, 3, 4))
+-1
diff --git a/test/sql_stmt_tests/importraw5.testcase b/test/sql_stmt_tests/importraw5.testcase
new file mode 100644
index 0000000..fe00eb2
--- /dev/null
+++ b/test/sql_stmt_tests/importraw5.testcase
@@ -0,0 +1,7 @@
+RL2_ImportSectionRawPixels - NULL pixels
+:memory: #use in-memory database
+SELECT RL2_ImportSectionRawPixels('coverage', 'section', 1000, 1000, NULL, BuildMBR(1, 2, 3, 4));
+1 # rows (not including the header row)
+1 # columns
+RL2_ImportSectionRawPixels('coverage', 'section', 1000, 1000, NULL, BuildMBR(1, 2, 3, 4))
+-1
diff --git a/test/sql_stmt_tests/importraw6.testcase b/test/sql_stmt_tests/importraw6.testcase
new file mode 100644
index 0000000..3cf2958
--- /dev/null
+++ b/test/sql_stmt_tests/importraw6.testcase
@@ -0,0 +1,7 @@
+RL2_ImportSectionRawPixels - NULL bbox
+:memory: #use in-memory database
+SELECT RL2_ImportSectionRawPixels('coverage', 'section', 1000, 1000, zeroblob(1000000), NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_ImportSectionRawPixels('coverage', 'section', 1000, 1000, zeroblob(1000000), NULL)
+-1
diff --git a/test/sql_stmt_tests/importraw7.testcase b/test/sql_stmt_tests/importraw7.testcase
new file mode 100644
index 0000000..f64a9fd
--- /dev/null
+++ b/test/sql_stmt_tests/importraw7.testcase
@@ -0,0 +1,7 @@
+RL2_ImportSectionRawPixels - NULL pyramidize
+:memory: #use in-memory database
+SELECT RL2_ImportSectionRawPixels('coverage', 'section', 1000, 1000, zeroblob(1000000), BuildMBR(1, 2, 3, 4), NULL, 1, 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_ImportSectionRawPixels('coverage', 'section', 1000, 1000, zeroblob(1000000), BuildMBR(1, 2, 3, 4), NULL, 1, 1)
+-1
diff --git a/test/sql_stmt_tests/importraw8.testcase b/test/sql_stmt_tests/importraw8.testcase
new file mode 100644
index 0000000..d4b5e49
--- /dev/null
+++ b/test/sql_stmt_tests/importraw8.testcase
@@ -0,0 +1,7 @@
+RL2_ImportSectionRawPixels - NULL transaction
+:memory: #use in-memory database
+SELECT RL2_ImportSectionRawPixels('coverage', 'section', 1000, 1000, zeroblob(1000000), BuildMBR(1, 2, 3, 4), 1, NULL, 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_ImportSectionRawPixels('coverage', 'section', 1000, 1000, zeroblob(1000000), BuildMBR(1, 2, 3, 4), 1, NULL, 1)
+-1
diff --git a/test/sql_stmt_tests/importraw9.testcase b/test/sql_stmt_tests/importraw9.testcase
new file mode 100644
index 0000000..6bb79c0
--- /dev/null
+++ b/test/sql_stmt_tests/importraw9.testcase
@@ -0,0 +1,7 @@
+RL2_ImportSectionRawPixels - NULL big_endian
+:memory: #use in-memory database
+SELECT RL2_ImportSectionRawPixels('coverage', 'section', 1000, 1000, zeroblob(1000000), BuildMBR(1, 2, 3, 4), 1, 1, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_ImportSectionRawPixels('coverage', 'section', 1000, 1000, zeroblob(1000000), BuildMBR(1, 2, 3, 4), 1, 1, NULL)
+-1
diff --git a/test/sql_stmt_tests/isautondvienabled1.testcase b/test/sql_stmt_tests/isautondvienabled1.testcase
new file mode 100644
index 0000000..323222e
--- /dev/null
+++ b/test/sql_stmt_tests/isautondvienabled1.testcase
@@ -0,0 +1,7 @@
+RL2_IsRasterCoverageAutoNdviEnabled - NULL Coverage
+:memory: #use in-memory database
+SELECT RL2_IsRasterCoverageAutoNdviEnabled (NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_IsRasterCoverageAutoNdviEnabled (NULL)
+-1
diff --git a/test/sql_stmt_tests/isautondvienabled2.testcase b/test/sql_stmt_tests/isautondvienabled2.testcase
new file mode 100644
index 0000000..4c2eef4
--- /dev/null
+++ b/test/sql_stmt_tests/isautondvienabled2.testcase
@@ -0,0 +1,7 @@
+RL2_IsRasterCoverageAutoNdviEnabled - Integer Coverage
+:memory: #use in-memory database
+SELECT RL2_IsRasterCoverageAutoNdviEnabled (1);
+1 # rows (not including the header row)
+1 # columns
+RL2_IsRasterCoverageAutoNdviEnabled (1)
+-1
diff --git a/test/sql_stmt_tests/isautondvienabled3.testcase b/test/sql_stmt_tests/isautondvienabled3.testcase
new file mode 100644
index 0000000..f67f013
--- /dev/null
+++ b/test/sql_stmt_tests/isautondvienabled3.testcase
@@ -0,0 +1,7 @@
+RL2_IsRasterCoverageAutoNdviEnabled - Double Coverage
+:memory: #use in-memory database
+SELECT RL2_IsRasterCoverageAutoNdviEnabled (1.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_IsRasterCoverageAutoNdviEnabled (1.5)
+-1
diff --git a/test/sql_stmt_tests/isautondvienabled4.testcase b/test/sql_stmt_tests/isautondvienabled4.testcase
new file mode 100644
index 0000000..e6e9ee9
--- /dev/null
+++ b/test/sql_stmt_tests/isautondvienabled4.testcase
@@ -0,0 +1,7 @@
+RL2_IsRasterCoverageAutoNdviEnabled - BLOB Coverage
+:memory: #use in-memory database
+SELECT RL2_IsRasterCoverageAutoNdviEnabled (zeroblob(4));
+1 # rows (not including the header row)
+1 # columns
+RL2_IsRasterCoverageAutoNdviEnabled (zeroblob(4))
+-1
diff --git a/test/sql_stmt_tests/isautondvienabled5.testcase b/test/sql_stmt_tests/isautondvienabled5.testcase
new file mode 100644
index 0000000..297a0e4
--- /dev/null
+++ b/test/sql_stmt_tests/isautondvienabled5.testcase
@@ -0,0 +1,7 @@
+RL2_IsRasterCoverageAutoNdviEnabled - Not existing Coverage
+:memory: #use in-memory database
+SELECT RL2_IsRasterCoverageAutoNdviEnabled ('test');
+1 # rows (not including the header row)
+1 # columns
+RL2_IsRasterCoverageAutoNdviEnabled ('test')
+-1
diff --git a/test/sql_stmt_tests/isfontbold1.testcase b/test/sql_stmt_tests/isfontbold1.testcase
new file mode 100644
index 0000000..48dacf0
--- /dev/null
+++ b/test/sql_stmt_tests/isfontbold1.testcase
@@ -0,0 +1,7 @@
+IsFontBold - NULL Font
+:memory: #use in-memory database
+SELECT RL2_IsFontBold(NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_IsFontBold(NULL)
+-1
diff --git a/test/sql_stmt_tests/isfontbold2.testcase b/test/sql_stmt_tests/isfontbold2.testcase
new file mode 100644
index 0000000..527a2f2
--- /dev/null
+++ b/test/sql_stmt_tests/isfontbold2.testcase
@@ -0,0 +1,7 @@
+IsFontBold - Text Font
+:memory: #use in-memory database
+SELECT RL2_IsFontBold('myfont');
+1 # rows (not including the header row)
+1 # columns
+RL2_IsFontBold('myfont')
+-1
diff --git a/test/sql_stmt_tests/isfontbold3.testcase b/test/sql_stmt_tests/isfontbold3.testcase
new file mode 100644
index 0000000..98a7de0
--- /dev/null
+++ b/test/sql_stmt_tests/isfontbold3.testcase
@@ -0,0 +1,7 @@
+IsFontBold - Integer Font
+:memory: #use in-memory database
+SELECT RL2_IsFontBold(1);
+1 # rows (not including the header row)
+1 # columns
+RL2_IsFontBold(1)
+-1
diff --git a/test/sql_stmt_tests/isfontbold4.testcase b/test/sql_stmt_tests/isfontbold4.testcase
new file mode 100644
index 0000000..4a46185
--- /dev/null
+++ b/test/sql_stmt_tests/isfontbold4.testcase
@@ -0,0 +1,7 @@
+IsFontBold - Double Font
+:memory: #use in-memory database
+SELECT RL2_IsFontBold(1.4);
+1 # rows (not including the header row)
+1 # columns
+RL2_IsFontBold(1.4)
+-1
diff --git a/test/sql_stmt_tests/isfontbold5.testcase b/test/sql_stmt_tests/isfontbold5.testcase
new file mode 100644
index 0000000..c0e46f1
--- /dev/null
+++ b/test/sql_stmt_tests/isfontbold5.testcase
@@ -0,0 +1,7 @@
+IsFontBold - invalid BLOB Font
+:memory: #use in-memory database
+SELECT RL2_IsFontBold(zeroblob(19));
+1 # rows (not including the header row)
+1 # columns
+RL2_IsFontBold(zeroblob(19))
+-1
diff --git a/test/sql_stmt_tests/isfontitalic1.testcase b/test/sql_stmt_tests/isfontitalic1.testcase
new file mode 100644
index 0000000..5ea19f4
--- /dev/null
+++ b/test/sql_stmt_tests/isfontitalic1.testcase
@@ -0,0 +1,7 @@
+IsFontItalic - NULL Font
+:memory: #use in-memory database
+SELECT RL2_IsFontItalic(NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_IsFontItalic(NULL)
+-1
diff --git a/test/sql_stmt_tests/isfontitalic2.testcase b/test/sql_stmt_tests/isfontitalic2.testcase
new file mode 100644
index 0000000..3008e59
--- /dev/null
+++ b/test/sql_stmt_tests/isfontitalic2.testcase
@@ -0,0 +1,7 @@
+IsFontItalic - Text Font
+:memory: #use in-memory database
+SELECT RL2_IsFontItalic('myfont');
+1 # rows (not including the header row)
+1 # columns
+RL2_IsFontItalic('myfont')
+-1
diff --git a/test/sql_stmt_tests/isfontitalic3.testcase b/test/sql_stmt_tests/isfontitalic3.testcase
new file mode 100644
index 0000000..6c9c664
--- /dev/null
+++ b/test/sql_stmt_tests/isfontitalic3.testcase
@@ -0,0 +1,7 @@
+IsFontItalic - Integer Font
+:memory: #use in-memory database
+SELECT RL2_IsFontItalic(1);
+1 # rows (not including the header row)
+1 # columns
+RL2_IsFontItalic(1)
+-1
diff --git a/test/sql_stmt_tests/isfontitalic4.testcase b/test/sql_stmt_tests/isfontitalic4.testcase
new file mode 100644
index 0000000..0463e5a
--- /dev/null
+++ b/test/sql_stmt_tests/isfontitalic4.testcase
@@ -0,0 +1,7 @@
+IsFontItalic - Double Font
+:memory: #use in-memory database
+SELECT RL2_IsFontItalic(1.4);
+1 # rows (not including the header row)
+1 # columns
+RL2_IsFontItalic(1.4)
+-1
diff --git a/test/sql_stmt_tests/isfontitalic5.testcase b/test/sql_stmt_tests/isfontitalic5.testcase
new file mode 100644
index 0000000..35c43e5
--- /dev/null
+++ b/test/sql_stmt_tests/isfontitalic5.testcase
@@ -0,0 +1,7 @@
+IsFontItalic - invalid BLOB Font
+:memory: #use in-memory database
+SELECT RL2_IsFontItalic(zeroblob(19));
+1 # rows (not including the header row)
+1 # columns
+RL2_IsFontItalic(zeroblob(19))
+-1
diff --git a/test/sql_stmt_tests/isvalidfont1.testcase b/test/sql_stmt_tests/isvalidfont1.testcase
new file mode 100644
index 0000000..ea110df
--- /dev/null
+++ b/test/sql_stmt_tests/isvalidfont1.testcase
@@ -0,0 +1,7 @@
+IsValidFont - NULL Font
+:memory: #use in-memory database
+SELECT RL2_IsValidFont(NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_IsValidFont(NULL)
+-1
diff --git a/test/sql_stmt_tests/isvalidfont2.testcase b/test/sql_stmt_tests/isvalidfont2.testcase
new file mode 100644
index 0000000..7fdb69a
--- /dev/null
+++ b/test/sql_stmt_tests/isvalidfont2.testcase
@@ -0,0 +1,7 @@
+IsValidFont - Text Font
+:memory: #use in-memory database
+SELECT RL2_IsValidFont('myfont');
+1 # rows (not including the header row)
+1 # columns
+RL2_IsValidFont('myfont')
+-1
diff --git a/test/sql_stmt_tests/isvalidfont3.testcase b/test/sql_stmt_tests/isvalidfont3.testcase
new file mode 100644
index 0000000..fbae7df
--- /dev/null
+++ b/test/sql_stmt_tests/isvalidfont3.testcase
@@ -0,0 +1,7 @@
+IsValidFont - Integer Font
+:memory: #use in-memory database
+SELECT RL2_IsValidFont(1);
+1 # rows (not including the header row)
+1 # columns
+RL2_IsValidFont(1)
+-1
diff --git a/test/sql_stmt_tests/isvalidfont4.testcase b/test/sql_stmt_tests/isvalidfont4.testcase
new file mode 100644
index 0000000..26bf499
--- /dev/null
+++ b/test/sql_stmt_tests/isvalidfont4.testcase
@@ -0,0 +1,7 @@
+IsValidFont - Double Font
+:memory: #use in-memory database
+SELECT RL2_IsValidFont(1.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_IsValidFont(1.5)
+-1
diff --git a/test/sql_stmt_tests/isvalidfont5.testcase b/test/sql_stmt_tests/isvalidfont5.testcase
new file mode 100644
index 0000000..9b4960c
--- /dev/null
+++ b/test/sql_stmt_tests/isvalidfont5.testcase
@@ -0,0 +1,7 @@
+IsValidFont - invalid BLOB Font
+:memory: #use in-memory database
+SELECT RL2_IsValidFont(zeroblob(4));
+1 # rows (not including the header row)
+1 # columns
+RL2_IsValidFont(zeroblob(4))
+0
diff --git a/test/sql_stmt_tests/pyramidize10.testcase b/test/sql_stmt_tests/pyramidize10.testcase
index 09e2733..6431c25 100644
--- a/test/sql_stmt_tests/pyramidize10.testcase
+++ b/test/sql_stmt_tests/pyramidize10.testcase
@@ -1,7 +1,7 @@
 rl2_pyramidize - BLOB forced-rebuild
 :memory: #use in-memory database
-SELECT rl2_pyramidize('coverage', 'section', zeroblob(4));
+SELECT rl2_pyramidize('coverage', 1, zeroblob(4));
 1 # rows (not including the header row)
 1 # columns
-rl2_pyramidize('coverage', 'section', zeroblob(4))
+rl2_pyramidize('coverage', 1, zeroblob(4))
 -1
diff --git a/test/sql_stmt_tests/pyramidize11.testcase b/test/sql_stmt_tests/pyramidize11.testcase
index d6563a6..462c387 100644
--- a/test/sql_stmt_tests/pyramidize11.testcase
+++ b/test/sql_stmt_tests/pyramidize11.testcase
@@ -1,7 +1,7 @@
 rl2_pyramidize - DOUBLE forced-rebuild
 :memory: #use in-memory database
-SELECT rl2_pyramidize('coverage', 'section', 1.1);
+SELECT rl2_pyramidize('coverage', 1, 1.1);
 1 # rows (not including the header row)
 1 # columns
-rl2_pyramidize('coverage', 'section', 1.1)
+rl2_pyramidize('coverage', 1, 1.1)
 -1
diff --git a/test/sql_stmt_tests/pyramidize12.testcase b/test/sql_stmt_tests/pyramidize12.testcase
index 5b11c0c..96d6923 100644
--- a/test/sql_stmt_tests/pyramidize12.testcase
+++ b/test/sql_stmt_tests/pyramidize12.testcase
@@ -1,7 +1,7 @@
 rl2_pyramidize - TEXT forced-rebuild
 :memory: #use in-memory database
-SELECT rl2_pyramidize('coverage', 'section', 'yes');
+SELECT rl2_pyramidize('coverage', 1, 'yes');
 1 # rows (not including the header row)
 1 # columns
-rl2_pyramidize('coverage', 'section', 'yes')
+rl2_pyramidize('coverage', 1, 'yes')
 -1
diff --git a/test/sql_stmt_tests/pyramidize13.testcase b/test/sql_stmt_tests/pyramidize13.testcase
index 4d238c9..1834795 100644
--- a/test/sql_stmt_tests/pyramidize13.testcase
+++ b/test/sql_stmt_tests/pyramidize13.testcase
@@ -1,7 +1,7 @@
 rl2_pyramidize - NULL Transaction
 :memory: #use in-memory database
-SELECT rl2_pyramidize('coverage', 'section', 0, NULL);
+SELECT rl2_pyramidize('coverage', 1, 0, NULL);
 1 # rows (not including the header row)
 1 # columns
-rl2_pyramidize('coverage', 'section', 0, NULL)
+rl2_pyramidize('coverage', 1, 0, NULL)
 -1
diff --git a/test/sql_stmt_tests/pyramidize14.testcase b/test/sql_stmt_tests/pyramidize14.testcase
index 05bcac2..ad2d1b1 100644
--- a/test/sql_stmt_tests/pyramidize14.testcase
+++ b/test/sql_stmt_tests/pyramidize14.testcase
@@ -1,7 +1,7 @@
 rl2_pyramidize - BLOB Transaction
 :memory: #use in-memory database
-SELECT rl2_pyramidize('coverage', 'section', 0, zeroblob(4));
+SELECT rl2_pyramidize('coverage', 1, 0, zeroblob(4));
 1 # rows (not including the header row)
 1 # columns
-rl2_pyramidize('coverage', 'section', 0, zeroblob(4))
+rl2_pyramidize('coverage', 1, 0, zeroblob(4))
 -1
diff --git a/test/sql_stmt_tests/pyramidize15.testcase b/test/sql_stmt_tests/pyramidize15.testcase
index 5783707..291c60a 100644
--- a/test/sql_stmt_tests/pyramidize15.testcase
+++ b/test/sql_stmt_tests/pyramidize15.testcase
@@ -1,7 +1,7 @@
 rl2_pyramidize - DOUBLE Transaction
 :memory: #use in-memory database
-SELECT rl2_pyramidize('coverage', 'section', 1, 1.1);
+SELECT rl2_pyramidize('coverage', 1, 1, 1.1);
 1 # rows (not including the header row)
 1 # columns
-rl2_pyramidize('coverage', 'section', 1, 1.1)
+rl2_pyramidize('coverage', 1, 1, 1.1)
 -1
diff --git a/test/sql_stmt_tests/pyramidize16.testcase b/test/sql_stmt_tests/pyramidize16.testcase
index 4382003..704dd63 100644
--- a/test/sql_stmt_tests/pyramidize16.testcase
+++ b/test/sql_stmt_tests/pyramidize16.testcase
@@ -1,7 +1,7 @@
 rl2_pyramidize - TEXT Transaction
 :memory: #use in-memory database
-SELECT rl2_pyramidize('coverage', 'section', 1, 'no');
+SELECT rl2_pyramidize('coverage', 1, 1, 'no');
 1 # rows (not including the header row)
 1 # columns
-rl2_pyramidize('coverage', 'section', 1, 'no')
+rl2_pyramidize('coverage', 1, 1, 'no')
 -1
diff --git a/test/sql_stmt_tests/pyramidize17.testcase b/test/sql_stmt_tests/pyramidize17.testcase
new file mode 100644
index 0000000..f16ec56
--- /dev/null
+++ b/test/sql_stmt_tests/pyramidize17.testcase
@@ -0,0 +1,7 @@
+rl2_PyramidizeMonolithic - NULL coverage
+:memory: #use in-memory database
+SELECT rl2_PyramidizeMonolithic(NULL, 1, 1);
+1 # rows (not including the header row)
+1 # columns
+rl2_PyramidizeMonolithic(NULL, 1, 1)
+-1
diff --git a/test/sql_stmt_tests/pyramidize18.testcase b/test/sql_stmt_tests/pyramidize18.testcase
new file mode 100644
index 0000000..024d9de
--- /dev/null
+++ b/test/sql_stmt_tests/pyramidize18.testcase
@@ -0,0 +1,7 @@
+rl2_PyramidizeMonolithic - NULL levels
+:memory: #use in-memory database
+SELECT rl2_PyramidizeMonolithic('coverage', NULL, 1);
+1 # rows (not including the header row)
+1 # columns
+rl2_PyramidizeMonolithic('coverage', NULL, 1)
+-1
diff --git a/test/sql_stmt_tests/pyramidize19.testcase b/test/sql_stmt_tests/pyramidize19.testcase
new file mode 100644
index 0000000..1234f43
--- /dev/null
+++ b/test/sql_stmt_tests/pyramidize19.testcase
@@ -0,0 +1,7 @@
+rl2_PyramidizeMonolithic - NULL transaction
+:memory: #use in-memory database
+SELECT rl2_PyramidizeMonolithic('coverage', 1, NULL);
+1 # rows (not including the header row)
+1 # columns
+rl2_PyramidizeMonolithic('coverage', 1, NULL)
+-1
diff --git a/test/sql_stmt_tests/pyramidize6.testcase b/test/sql_stmt_tests/pyramidize6.testcase
index e54c19f..0227cdf 100644
--- a/test/sql_stmt_tests/pyramidize6.testcase
+++ b/test/sql_stmt_tests/pyramidize6.testcase
@@ -1,7 +1,7 @@
-rl2_pyramidize - INT Section
+rl2_pyramidize - TEXT Section
 :memory: #use in-memory database
-SELECT rl2_pyramidize('coverage', 1);
+SELECT rl2_pyramidize('coverage', 'alpha');
 1 # rows (not including the header row)
 1 # columns
-rl2_pyramidize('coverage', 1)
+rl2_pyramidize('coverage', 'alpha')
 -1
diff --git a/test/sql_stmt_tests/pyramidize9.testcase b/test/sql_stmt_tests/pyramidize9.testcase
index 2b3d756..eb52797 100644
--- a/test/sql_stmt_tests/pyramidize9.testcase
+++ b/test/sql_stmt_tests/pyramidize9.testcase
@@ -1,7 +1,7 @@
 rl2_pyramidize - NULL forced-rebuild
 :memory: #use in-memory database
-SELECT rl2_pyramidize('coverage', 'section', NULL);
+SELECT rl2_pyramidize('coverage', 1, NULL);
 1 # rows (not including the header row)
 1 # columns
-rl2_pyramidize('coverage', 'section', NULL)
+rl2_pyramidize('coverage', 1, NULL)
 -1
diff --git a/test/sql_stmt_tests/setcoverageinfos1.testcase b/test/sql_stmt_tests/setcoverageinfos1.testcase
index 8177b70..d2b3481 100644
--- a/test/sql_stmt_tests/setcoverageinfos1.testcase
+++ b/test/sql_stmt_tests/setcoverageinfos1.testcase
@@ -1,7 +1,7 @@
-SetCoevrageInfos - NULL coverage name 
+SetRasterCoverageInfos - NULL coverage name 
 :memory: #use in-memory database
-SELECT RL2_SetCoverageInfos(NULL, 'title', 'abstract');
+SELECT RL2_SetRasterCoverageInfos(NULL, 'title', 'abstract');
 1 # rows (not including the header row)
 1 # columns
-RL2_SetCoverageInfos(NULL, 'title', 'abstract')
+RL2_SetRasterCoverageInfos(NULL, 'title', 'abstract')
 -1
diff --git a/test/sql_stmt_tests/setcoverageinfos2.testcase b/test/sql_stmt_tests/setcoverageinfos2.testcase
index 6f65bd0..931d235 100644
--- a/test/sql_stmt_tests/setcoverageinfos2.testcase
+++ b/test/sql_stmt_tests/setcoverageinfos2.testcase
@@ -1,7 +1,7 @@
-SetCoevrageInfos - NULL title
+SetRasterCoverageInfos - NULL title
 :memory: #use in-memory database
-SELECT RL2_SetCoverageInfos('coverage', NULL, 'abstract');
+SELECT RL2_SetRasterCoverageInfos('coverage', NULL, 'abstract');
 1 # rows (not including the header row)
 1 # columns
-RL2_SetCoverageInfos('coverage', NULL, 'abstract')
+RL2_SetRasterCoverageInfos('coverage', NULL, 'abstract')
 -1
diff --git a/test/sql_stmt_tests/setcoverageinfos3.testcase b/test/sql_stmt_tests/setcoverageinfos3.testcase
index 507eb1d..afe276f 100644
--- a/test/sql_stmt_tests/setcoverageinfos3.testcase
+++ b/test/sql_stmt_tests/setcoverageinfos3.testcase
@@ -1,7 +1,7 @@
-SetCoevrageInfos - NULL abstract
+SetRasterCoverageInfos - NULL abstract
 :memory: #use in-memory database
-SELECT RL2_SetCoverageInfos('coverage', 'title', NULL);
+SELECT RL2_SetRasterCoverageInfos('coverage', 'title', NULL);
 1 # rows (not including the header row)
 1 # columns
-RL2_SetCoverageInfos('coverage', 'title', NULL)
+RL2_SetRasterCoverageInfos('coverage', 'title', NULL)
 -1
diff --git a/test/sql_stmt_tests/setcoverageinfos4.testcase b/test/sql_stmt_tests/setcoverageinfos4.testcase
index f126d39..581e0b7 100644
--- a/test/sql_stmt_tests/setcoverageinfos4.testcase
+++ b/test/sql_stmt_tests/setcoverageinfos4.testcase
@@ -1,7 +1,7 @@
-SetCoevrageInfos - not existing coverage
+SetRasterCoverageInfos - not existing coverage
 :memory: #use in-memory database
-SELECT RL2_SetCoverageInfos('coverage', 'title', 'abstract');
+SELECT RL2_SetRasterCoverageInfos('coverage', 'title', 'abstract');
 1 # rows (not including the header row)
 1 # columns
-RL2_SetCoverageInfos('coverage', 'title', 'abstract')
+RL2_SetRasterCoverageInfos('coverage', 'title', 'abstract')
 0
diff --git a/test/sql_stmt_tests/setdefaultbands1.testcase b/test/sql_stmt_tests/setdefaultbands1.testcase
new file mode 100644
index 0000000..47fd084
--- /dev/null
+++ b/test/sql_stmt_tests/setdefaultbands1.testcase
@@ -0,0 +1,7 @@
+RL2_SetRasterCoverageDefaultBands - NULL Coverage
+:memory: #use in-memory database
+SELECT RL2_SetRasterCoverageDefaultBands(NULL, 0, 1, 2, 3);
+1 # rows (not including the header row)
+1 # columns
+RL2_SetRasterCoverageDefaultBands(NULL, 0, 1, 2, 3)
+-1
diff --git a/test/sql_stmt_tests/setdefaultbands10.testcase b/test/sql_stmt_tests/setdefaultbands10.testcase
new file mode 100644
index 0000000..394c29b
--- /dev/null
+++ b/test/sql_stmt_tests/setdefaultbands10.testcase
@@ -0,0 +1,7 @@
+RL2_SetRasterCoverageDefaultBands - exceeding Red
+:memory: #use in-memory database
+SELECT RL2_SetRasterCoverageDefaultBands('something', 1000, 1, 2, 3);
+1 # rows (not including the header row)
+1 # columns
+RL2_SetRasterCoverageDefaultBands('something', 1000, 1, 2, 3)
+-1
diff --git a/test/sql_stmt_tests/setdefaultbands11.testcase b/test/sql_stmt_tests/setdefaultbands11.testcase
new file mode 100644
index 0000000..4eb96df
--- /dev/null
+++ b/test/sql_stmt_tests/setdefaultbands11.testcase
@@ -0,0 +1,7 @@
+RL2_SetRasterCoverageDefaultBands - exceeding Green
+:memory: #use in-memory database
+SELECT RL2_SetRasterCoverageDefaultBands('something', 0, 1000, 2, 3);
+1 # rows (not including the header row)
+1 # columns
+RL2_SetRasterCoverageDefaultBands('something', 0, 1000, 2, 3)
+-1
diff --git a/test/sql_stmt_tests/setdefaultbands12.testcase b/test/sql_stmt_tests/setdefaultbands12.testcase
new file mode 100644
index 0000000..2c4c773
--- /dev/null
+++ b/test/sql_stmt_tests/setdefaultbands12.testcase
@@ -0,0 +1,7 @@
+RL2_SetRasterCoverageDefaultBands - exceeding Blue
+:memory: #use in-memory database
+SELECT RL2_SetRasterCoverageDefaultBands('something', 0, 1, 1000, 3);
+1 # rows (not including the header row)
+1 # columns
+RL2_SetRasterCoverageDefaultBands('something', 0, 1, 1000, 3)
+-1
diff --git a/test/sql_stmt_tests/setdefaultbands13.testcase b/test/sql_stmt_tests/setdefaultbands13.testcase
new file mode 100644
index 0000000..f71e723
--- /dev/null
+++ b/test/sql_stmt_tests/setdefaultbands13.testcase
@@ -0,0 +1,7 @@
+RL2_SetRasterCoverageDefaultBands - exceeding NIR
+:memory: #use in-memory database
+SELECT RL2_SetRasterCoverageDefaultBands('something', 0, 1, 2, 1000);
+1 # rows (not including the header row)
+1 # columns
+RL2_SetRasterCoverageDefaultBands('something', 0, 1, 2, 1000)
+-1
diff --git a/test/sql_stmt_tests/setdefaultbands14.testcase b/test/sql_stmt_tests/setdefaultbands14.testcase
new file mode 100644
index 0000000..5c89c09
--- /dev/null
+++ b/test/sql_stmt_tests/setdefaultbands14.testcase
@@ -0,0 +1,7 @@
+RL2_SetRasterCoverageDefaultBands - Red=Green
+:memory: #use in-memory database
+SELECT RL2_SetRasterCoverageDefaultBands('something', 0, 0, 2, 3);
+1 # rows (not including the header row)
+1 # columns
+RL2_SetRasterCoverageDefaultBands('something', 0, 0, 2, 3)
+-1
diff --git a/test/sql_stmt_tests/setdefaultbands15.testcase b/test/sql_stmt_tests/setdefaultbands15.testcase
new file mode 100644
index 0000000..9dea755
--- /dev/null
+++ b/test/sql_stmt_tests/setdefaultbands15.testcase
@@ -0,0 +1,7 @@
+RL2_SetRasterCoverageDefaultBands - Red=Blue
+:memory: #use in-memory database
+SELECT RL2_SetRasterCoverageDefaultBands('something', 0, 1, 0, 3);
+1 # rows (not including the header row)
+1 # columns
+RL2_SetRasterCoverageDefaultBands('something', 0, 1, 0, 3)
+-1
diff --git a/test/sql_stmt_tests/setdefaultbands16.testcase b/test/sql_stmt_tests/setdefaultbands16.testcase
new file mode 100644
index 0000000..f5df72e
--- /dev/null
+++ b/test/sql_stmt_tests/setdefaultbands16.testcase
@@ -0,0 +1,7 @@
+RL2_SetRasterCoverageDefaultBands - Red=NIR
+:memory: #use in-memory database
+SELECT RL2_SetRasterCoverageDefaultBands('something', 0, 1, 2, 0);
+1 # rows (not including the header row)
+1 # columns
+RL2_SetRasterCoverageDefaultBands('something', 0, 1, 2, 0)
+-1
diff --git a/test/sql_stmt_tests/setdefaultbands17.testcase b/test/sql_stmt_tests/setdefaultbands17.testcase
new file mode 100644
index 0000000..dce1ce3
--- /dev/null
+++ b/test/sql_stmt_tests/setdefaultbands17.testcase
@@ -0,0 +1,7 @@
+RL2_SetRasterCoverageDefaultBands - Green=Blue
+:memory: #use in-memory database
+SELECT RL2_SetRasterCoverageDefaultBands('something', 0, 1, 1, 3);
+1 # rows (not including the header row)
+1 # columns
+RL2_SetRasterCoverageDefaultBands('something', 0, 1, 1, 3)
+-1
diff --git a/test/sql_stmt_tests/setdefaultbands18.testcase b/test/sql_stmt_tests/setdefaultbands18.testcase
new file mode 100644
index 0000000..d57eb17
--- /dev/null
+++ b/test/sql_stmt_tests/setdefaultbands18.testcase
@@ -0,0 +1,7 @@
+RL2_SetRasterCoverageDefaultBands - Green=NIR
+:memory: #use in-memory database
+SELECT RL2_SetRasterCoverageDefaultBands('something', 0, 1, 2, 1);
+1 # rows (not including the header row)
+1 # columns
+RL2_SetRasterCoverageDefaultBands('something', 0, 1, 2, 1)
+-1
diff --git a/test/sql_stmt_tests/setdefaultbands19.testcase b/test/sql_stmt_tests/setdefaultbands19.testcase
new file mode 100644
index 0000000..bbc9961
--- /dev/null
+++ b/test/sql_stmt_tests/setdefaultbands19.testcase
@@ -0,0 +1,7 @@
+RL2_SetRasterCoverageDefaultBands - Blue=NIR
+:memory: #use in-memory database
+SELECT RL2_SetRasterCoverageDefaultBands('something', 0, 1, 2, 2);
+1 # rows (not including the header row)
+1 # columns
+RL2_SetRasterCoverageDefaultBands('something', 0, 1, 2, 2)
+-1
diff --git a/test/sql_stmt_tests/setdefaultbands2.testcase b/test/sql_stmt_tests/setdefaultbands2.testcase
new file mode 100644
index 0000000..680822c
--- /dev/null
+++ b/test/sql_stmt_tests/setdefaultbands2.testcase
@@ -0,0 +1,7 @@
+RL2_SetRasterCoverageDefaultBands - NULL Red
+:memory: #use in-memory database
+SELECT RL2_SetRasterCoverageDefaultBands('something', NULL, 1, 2, 3);
+1 # rows (not including the header row)
+1 # columns
+RL2_SetRasterCoverageDefaultBands('something', NULL, 1, 2, 3)
+-1
diff --git a/test/sql_stmt_tests/setdefaultbands20.testcase b/test/sql_stmt_tests/setdefaultbands20.testcase
new file mode 100644
index 0000000..06ff44f
--- /dev/null
+++ b/test/sql_stmt_tests/setdefaultbands20.testcase
@@ -0,0 +1,7 @@
+RL2_SetRasterCoverageDefaultBands - Not existing Coverage
+:memory: #use in-memory database
+SELECT RL2_SetRasterCoverageDefaultBands('something', 0, 1, 2, 3);
+1 # rows (not including the header row)
+1 # columns
+RL2_SetRasterCoverageDefaultBands('something', 0, 1, 2, 3)
+0
diff --git a/test/sql_stmt_tests/setdefaultbands3.testcase b/test/sql_stmt_tests/setdefaultbands3.testcase
new file mode 100644
index 0000000..7d179de
--- /dev/null
+++ b/test/sql_stmt_tests/setdefaultbands3.testcase
@@ -0,0 +1,7 @@
+RL2_SetRasterCoverageDefaultBands - NULL Green
+:memory: #use in-memory database
+SELECT RL2_SetRasterCoverageDefaultBands('something', 0, NULL, 2, 3);
+1 # rows (not including the header row)
+1 # columns
+RL2_SetRasterCoverageDefaultBands('something', 0, NULL, 2, 3)
+-1
diff --git a/test/sql_stmt_tests/setdefaultbands4.testcase b/test/sql_stmt_tests/setdefaultbands4.testcase
new file mode 100644
index 0000000..751ab59
--- /dev/null
+++ b/test/sql_stmt_tests/setdefaultbands4.testcase
@@ -0,0 +1,7 @@
+RL2_SetRasterCoverageDefaultBands - NULL Blue
+:memory: #use in-memory database
+SELECT RL2_SetRasterCoverageDefaultBands('something', 0, 1, NULL, 3);
+1 # rows (not including the header row)
+1 # columns
+RL2_SetRasterCoverageDefaultBands('something', 0, 1, NULL, 3)
+-1
diff --git a/test/sql_stmt_tests/setdefaultbands5.testcase b/test/sql_stmt_tests/setdefaultbands5.testcase
new file mode 100644
index 0000000..ec1317f
--- /dev/null
+++ b/test/sql_stmt_tests/setdefaultbands5.testcase
@@ -0,0 +1,7 @@
+RL2_SetRasterCoverageDefaultBands - NULL Blue
+:memory: #use in-memory database
+SELECT RL2_SetRasterCoverageDefaultBands('something', 0, 1, 2, NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_SetRasterCoverageDefaultBands('something', 0, 1, 2, NULL)
+-1
diff --git a/test/sql_stmt_tests/setdefaultbands6.testcase b/test/sql_stmt_tests/setdefaultbands6.testcase
new file mode 100644
index 0000000..1382f68
--- /dev/null
+++ b/test/sql_stmt_tests/setdefaultbands6.testcase
@@ -0,0 +1,7 @@
+RL2_SetRasterCoverageDefaultBands - negative Red
+:memory: #use in-memory database
+SELECT RL2_SetRasterCoverageDefaultBands('something', -1, 1, 2, 3);
+1 # rows (not including the header row)
+1 # columns
+RL2_SetRasterCoverageDefaultBands('something', -1, 1, 2, 3)
+-1
diff --git a/test/sql_stmt_tests/setdefaultbands7.testcase b/test/sql_stmt_tests/setdefaultbands7.testcase
new file mode 100644
index 0000000..641d504
--- /dev/null
+++ b/test/sql_stmt_tests/setdefaultbands7.testcase
@@ -0,0 +1,7 @@
+RL2_SetRasterCoverageDefaultBands - negative Green
+:memory: #use in-memory database
+SELECT RL2_SetRasterCoverageDefaultBands('something', 0, -1, 2, 3);
+1 # rows (not including the header row)
+1 # columns
+RL2_SetRasterCoverageDefaultBands('something', 0, -1, 2, 3)
+-1
diff --git a/test/sql_stmt_tests/setdefaultbands8.testcase b/test/sql_stmt_tests/setdefaultbands8.testcase
new file mode 100644
index 0000000..a5f1d05
--- /dev/null
+++ b/test/sql_stmt_tests/setdefaultbands8.testcase
@@ -0,0 +1,7 @@
+RL2_SetRasterCoverageDefaultBands - negative Blue
+:memory: #use in-memory database
+SELECT RL2_SetRasterCoverageDefaultBands('something', 0, 1, -1, 3);
+1 # rows (not including the header row)
+1 # columns
+RL2_SetRasterCoverageDefaultBands('something', 0, 1, -1, 3)
+-1
diff --git a/test/sql_stmt_tests/setdefaultbands9.testcase b/test/sql_stmt_tests/setdefaultbands9.testcase
new file mode 100644
index 0000000..48fc168
--- /dev/null
+++ b/test/sql_stmt_tests/setdefaultbands9.testcase
@@ -0,0 +1,7 @@
+RL2_SetRasterCoverageDefaultBands - negative NIR
+:memory: #use in-memory database
+SELECT RL2_SetRasterCoverageDefaultBands('something', 0, 1, 2, -1);
+1 # rows (not including the header row)
+1 # columns
+RL2_SetRasterCoverageDefaultBands('something', 0, 1, 2, -1)
+-1
diff --git a/test/sql_stmt_tests/setmaxthreads1.testcase b/test/sql_stmt_tests/setmaxthreads1.testcase
new file mode 100644
index 0000000..a3d4afc
--- /dev/null
+++ b/test/sql_stmt_tests/setmaxthreads1.testcase
@@ -0,0 +1,7 @@
+RL2_SetMaxThreads - NULL 
+:memory: #use in-memory database
+SELECT RL2_SetMaxThreads(NULL);
+1 # rows (not including the header row)
+1 # columns
+RL2_SetMaxThreads(NULL)
+-1
diff --git a/test/sql_stmt_tests/setmaxthreads2.testcase b/test/sql_stmt_tests/setmaxthreads2.testcase
new file mode 100644
index 0000000..8583b7b
--- /dev/null
+++ b/test/sql_stmt_tests/setmaxthreads2.testcase
@@ -0,0 +1,7 @@
+RL2_SetMaxThreads - Double
+:memory: #use in-memory database
+SELECT RL2_SetMaxThreads(1.5);
+1 # rows (not including the header row)
+1 # columns
+RL2_SetMaxThreads(1.5)
+-1
diff --git a/test/sql_stmt_tests/setmaxthreads3.testcase b/test/sql_stmt_tests/setmaxthreads3.testcase
new file mode 100644
index 0000000..10afe36
--- /dev/null
+++ b/test/sql_stmt_tests/setmaxthreads3.testcase
@@ -0,0 +1,7 @@
+RL2_SetMaxThreads - Text
+:memory: #use in-memory database
+SELECT RL2_SetMaxThreads('alpha');
+1 # rows (not including the header row)
+1 # columns
+RL2_SetMaxThreads('alpha')
+-1
diff --git a/test/sql_stmt_tests/setmaxthreads4.testcase b/test/sql_stmt_tests/setmaxthreads4.testcase
new file mode 100644
index 0000000..a6ba177
--- /dev/null
+++ b/test/sql_stmt_tests/setmaxthreads4.testcase
@@ -0,0 +1,7 @@
+RL2_SetMaxThreads - BLOB
+:memory: #use in-memory database
+SELECT RL2_SetMaxThreads(zeroblob(4));
+1 # rows (not including the header row)
+1 # columns
+RL2_SetMaxThreads(zeroblob(4))
+-1
diff --git a/test/sql_stmt_tests/setmaxthreads5.testcase b/test/sql_stmt_tests/setmaxthreads5.testcase
new file mode 100644
index 0000000..073e754
--- /dev/null
+++ b/test/sql_stmt_tests/setmaxthreads5.testcase
@@ -0,0 +1,7 @@
+RL2_SetMaxThreads - 8
+:memory: #use in-memory database
+SELECT RL2_SetMaxThreads(8);
+1 # rows (not including the header row)
+1 # columns
+RL2_SetMaxThreads(8)
+8
diff --git a/test/sql_stmt_tests/setmaxthreads6.testcase b/test/sql_stmt_tests/setmaxthreads6.testcase
new file mode 100644
index 0000000..2b7b261
--- /dev/null
+++ b/test/sql_stmt_tests/setmaxthreads6.testcase
@@ -0,0 +1,7 @@
+RL2_SetMaxThreads - -1
+:memory: #use in-memory database
+SELECT RL2_SetMaxThreads(-1);
+1 # rows (not including the header row)
+1 # columns
+RL2_SetMaxThreads(-1)
+1
diff --git a/test/sql_stmt_tests/setmaxthreads7.testcase b/test/sql_stmt_tests/setmaxthreads7.testcase
new file mode 100644
index 0000000..f070788
--- /dev/null
+++ b/test/sql_stmt_tests/setmaxthreads7.testcase
@@ -0,0 +1,7 @@
+RL2_SetMaxThreads - 256
+:memory: #use in-memory database
+SELECT RL2_SetMaxThreads(256);
+1 # rows (not including the header row)
+1 # columns
+RL2_SetMaxThreads(256)
+64
diff --git a/test/symbolizers.sqlite b/test/symbolizers.sqlite
new file mode 100644
index 0000000..eb43da9
Binary files /dev/null and b/test/symbolizers.sqlite differ
diff --git a/test/test1.c b/test/test1.c
index 1c53a17..6df0c4c 100644
--- a/test/test1.c
+++ b/test/test1.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -43,8 +43,12 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include <unistd.h>
 #include <stdio.h>
 
+#include "config.h"
+
 #include "rasterlite2/rasterlite2.h"
 
+#include "spatialite.h"
+
 static int
 test_rgb_jpeg (const char *path)
 {
@@ -641,6 +645,7 @@ test_rgb_jpeg (const char *path)
     rl2_destroy_pixel (pxl);
     unlink ("./from_rgb_jpeg.png");
 
+#ifndef OMIT_WEBP		/* only if WebP is enabled */
     if (rl2_section_to_lossy_webp (img, "./from_rgb_jpeg_10.webp", 10) !=
 	RL2_OK)
       {
@@ -655,6 +660,24 @@ test_rgb_jpeg (const char *path)
 	  return 0;
       }
     unlink ("./from_rgb_jpeg.webp");
+#endif /* end WebP conditional */
+
+#ifndef OMIT_OPENJPEG		/* only if OpenJpeg is enabled */
+    if (rl2_section_to_lossy_jpeg2000 (img, "./from_rgb_jpeg_10.jp2", 10) !=
+	RL2_OK)
+      {
+	  fprintf (stderr, "Unable to write: from_rgb_jpeg_10.jp2\n");
+	  return 0;
+      }
+    unlink ("./from_rgb_jpeg_10.jp2");
+
+    if (rl2_section_to_lossless_jpeg2000 (img, "./from_rgb_jpeg.jp2") != RL2_OK)
+      {
+	  fprintf (stderr, "Unable to write: from_rgb_jpeg.jp2\n");
+	  return 0;
+      }
+    unlink ("./from_rgb_jpeg.jp2");
+#endif /* end OpenJpeg conditional */
 
     rl2_destroy_section (img);
     return 1;
@@ -909,6 +932,7 @@ test_gray_jpeg (const char *path)
     rl2_destroy_pixel (pxl);
     unlink ("./from_gray_jpeg.png");
 
+#ifndef OMIT_WEBP		/* only if WebP is enabled */
     if (rl2_section_to_lossy_webp (img, "./from_gray_jpeg_10.webp", 10) !=
 	RL2_OK)
       {
@@ -923,6 +947,7 @@ test_gray_jpeg (const char *path)
 	  return 0;
       }
     unlink ("./from_gray_jpeg.webp");
+#endif /* end WebP conditional */
 
     rl2_destroy_section (img);
     return 1;
@@ -951,7 +976,6 @@ test_palette_png (const char *path)
     double minY;
     double maxX;
     double maxY;
-    gaiaGeomCollPtr geom;
     rl2PixelPtr pxl;
     rl2RasterPtr rst;
     rl2SectionPtr img = rl2_section_from_png (path);
@@ -1098,13 +1122,6 @@ test_palette_png (const char *path)
 	  return 0;
       }
 
-    geom = rl2_get_raster_bbox (rst);
-    if (geom != NULL)
-      {
-	  fprintf (stderr, "\"%s\" unexpected image BBOX\n", path);
-	  return 0;
-      }
-
     if (rl2_get_raster_palette (rst) == NULL)
       {
 	  fprintf (stderr, "\"%s\" invalid palette\n", path);
@@ -1314,6 +1331,7 @@ test_palette_png (const char *path)
       }
     unlink ("./from_palette_png.gif");
 
+#ifndef OMIT_WEBP		/* only if WebP is enabled */
     if (rl2_section_to_lossy_webp (img, "./from_palette_png_10.webp", 10) !=
 	RL2_OK)
       {
@@ -1328,6 +1346,7 @@ test_palette_png (const char *path)
 	  return 0;
       }
     unlink ("./from_palette_png.webp");
+#endif /* end WebP conditional */
 
     rl2_destroy_section (img);
     return 1;
diff --git a/test/test10.c b/test/test10.c
index 1eff3c5..3cb1212 100644
--- a/test/test10.c
+++ b/test/test10.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
diff --git a/test/test11.c b/test/test11.c
index f9906a3..b0041a8 100644
--- a/test/test11.c
+++ b/test/test11.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
diff --git a/test/test12.c b/test/test12.c
index 13c71e0..3bc9e06 100644
--- a/test/test12.c
+++ b/test/test12.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
diff --git a/test/test13.c b/test/test13.c
index 0303646..d948b4a 100644
--- a/test/test13.c
+++ b/test/test13.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
diff --git a/test/test14.c b/test/test14.c
index 4911b33..e2b6f5c 100644
--- a/test/test14.c
+++ b/test/test14.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
diff --git a/test/test15.c b/test/test15.c
index 7597404..85fa98f 100644
--- a/test/test15.c
+++ b/test/test15.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
diff --git a/test/test16.c b/test/test16.c
index d8daaf5..dfb36f6 100644
--- a/test/test16.c
+++ b/test/test16.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
diff --git a/test/test17.c b/test/test17.c
index acb37c1..bc58d3b 100644
--- a/test/test17.c
+++ b/test/test17.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
diff --git a/test/test18.c b/test/test18.c
index 698dec3..37d56fb 100644
--- a/test/test18.c
+++ b/test/test18.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
diff --git a/test/test19.c b/test/test19.c
index b463fb7..2836acb 100644
--- a/test/test19.c
+++ b/test/test19.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
diff --git a/test/test2.c b/test/test2.c
index f8f3d75..ac15694 100644
--- a/test/test2.c
+++ b/test/test2.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -43,6 +43,8 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include <unistd.h>
 #include <stdio.h>
 
+#include "config.h"
+
 #include "rasterlite2/rasterlite2.h"
 
 static int
@@ -255,22 +257,10 @@ main (int argc, char *argv[])
     int blob_odd_sz_zip;
     unsigned char *blob_even_zip;
     int blob_even_sz_zip;
-    unsigned char *blob_odd_lzma;
-    int blob_odd_sz_lzma;
-    unsigned char *blob_even_lzma;
-    int blob_even_sz_lzma;
     unsigned char *blob_odd_jpeg;
     int blob_odd_sz_jpeg;
     unsigned char *blob_even_jpeg;
     int blob_even_sz_jpeg;
-    unsigned char *blob_odd_lossy_webp;
-    int blob_odd_sz_lossy_webp;
-    unsigned char *blob_even_lossy_webp;
-    int blob_even_sz_lossy_webp;
-    unsigned char *blob_odd_lossless_webp;
-    int blob_odd_sz_lossless_webp;
-    unsigned char *blob_even_lossless_webp;
-    int blob_even_sz_lossless_webp;
     unsigned char *blob_odd_png;
     int blob_odd_sz_png;
     unsigned char *blob_even_png;
@@ -281,6 +271,25 @@ main (int argc, char *argv[])
     int blob_even_sz_gif;
     unsigned char *blob_stat;
     int blob_stat_size;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
+    unsigned char *blob_odd_lzma;
+    int blob_odd_sz_lzma;
+    unsigned char *blob_even_lzma;
+    int blob_even_sz_lzma;
+#endif /* end LZMA conditional */
+
+#ifndef OMIT_WEBP		/* only if WebP is enabled */
+    unsigned char *blob_odd_lossy_webp;
+    int blob_odd_sz_lossy_webp;
+    unsigned char *blob_even_lossy_webp;
+    int blob_even_sz_lossy_webp;
+    unsigned char *blob_odd_lossless_webp;
+    int blob_odd_sz_lossless_webp;
+    unsigned char *blob_even_lossless_webp;
+    int blob_even_sz_lossless_webp;
+#endif /* end WebP conditional */
+
     int anti_endian = antiEndian ();
 
     if (argc > 1 || argv[0] == NULL)
@@ -343,26 +352,44 @@ main (int argc, char *argv[])
 
     if (rl2_raster_encode
 	(raster, RL2_COMPRESSION_DEFLATE, &blob_odd_zip, &blob_odd_sz_zip,
-	 &blob_even_zip, &blob_even_sz_zip, 0, anti_endian) == RL2_OK)
+	 &blob_even_zip, &blob_even_sz_zip, 0, anti_endian) != RL2_OK)
       {
 	  fprintf (stderr, "Unexpected result - DEFLATE compressed\n");
 	  return -8;
       }
 
     if (rl2_raster_encode
+	(raster, RL2_COMPRESSION_DEFLATE_NO, &blob_odd_zip, &blob_odd_sz_zip,
+	 &blob_even_zip, &blob_even_sz_zip, 0, anti_endian) != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected result - DEFLATE_NO compressed\n");
+	  return -9;
+      }
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
+    if (rl2_raster_encode
 	(raster, RL2_COMPRESSION_LZMA, &blob_odd_lzma, &blob_odd_sz_lzma,
-	 &blob_even_lzma, &blob_even_sz_lzma, 0, anti_endian) == RL2_OK)
+	 &blob_even_lzma, &blob_even_sz_lzma, 0, anti_endian) != RL2_OK)
       {
 	  fprintf (stderr, "Unexpected result - LZMA compressed\n");
-	  return -9;
+	  return -10;
+      }
+
+    if (rl2_raster_encode
+	(raster, RL2_COMPRESSION_LZMA_NO, &blob_odd_lzma, &blob_odd_sz_lzma,
+	 &blob_even_lzma, &blob_even_sz_lzma, 0, anti_endian) != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected result - LZMA_NO compressed\n");
+	  return -11;
       }
+#endif /* end LZMA conditional */
 
     if (rl2_raster_encode
 	(raster, RL2_COMPRESSION_JPEG, &blob_odd_jpeg, &blob_odd_sz_jpeg,
 	 &blob_even_jpeg, &blob_even_sz_jpeg, 70, anti_endian) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to Encode - JPEG compressed\n");
-	  return -10;
+	  return -12;
       }
 
     stats =
@@ -390,6 +417,7 @@ main (int argc, char *argv[])
     free (blob_stat);
     rl2_destroy_raster_statistics (stats);
 
+#ifndef OMIT_WEBP		/* only if WebP is defined */
     if (rl2_raster_encode
 	(raster, RL2_COMPRESSION_LOSSY_WEBP, &blob_odd_lossy_webp,
 	 &blob_odd_sz_lossy_webp, &blob_even_lossy_webp,
@@ -407,6 +435,7 @@ main (int argc, char *argv[])
 	  fprintf (stderr, "Unable to Encode - lossless WEBP compressed\n");
 	  return -12;
       }
+#endif /* end of WebP conditional */
 
     if (rl2_raster_encode
 	(raster, RL2_COMPRESSION_PNG, &blob_odd_png, &blob_odd_sz_png,
@@ -646,6 +675,7 @@ main (int argc, char *argv[])
 
     unlink ("./rainbow_1_8_jpeg.png");
 
+#ifndef OMIT_WEBP		/* only if WebP is enabled */
     raster =
 	rl2_raster_decode (RL2_SCALE_1, blob_odd_lossy_webp,
 			   blob_odd_sz_lossy_webp, blob_even_lossy_webp,
@@ -873,6 +903,7 @@ main (int argc, char *argv[])
     free (blob_even_lossless_webp);
 
     unlink ("./rainbow_1_8_lossless_webp.png");
+#endif /* end WebP conditional */
 
     raster =
 	rl2_raster_decode (RL2_SCALE_1, blob_odd_png, blob_odd_sz_png,
diff --git a/test/test20.c b/test/test20.c
index b463fb7..2836acb 100644
--- a/test/test20.c
+++ b/test/test20.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
diff --git a/test/test3.c b/test/test3.c
index 0d1406d..6bf63dc 100644
--- a/test/test3.c
+++ b/test/test3.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -43,6 +43,8 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include <unistd.h>
 #include <stdio.h>
 
+#include "config.h"
+
 #include "rasterlite2/rasterlite2.h"
 
 static int
@@ -139,14 +141,6 @@ main (int argc, char *argv[])
     int blob_odd_sz_jpeg;
     unsigned char *blob_even_jpeg;
     int blob_even_sz_jpeg;
-    unsigned char *blob_odd_lossy_webp;
-    int blob_odd_sz_lossy_webp;
-    unsigned char *blob_even_lossy_webp;
-    int blob_even_sz_lossy_webp;
-    unsigned char *blob_odd_lossless_webp;
-    int blob_odd_sz_lossless_webp;
-    unsigned char *blob_even_lossless_webp;
-    int blob_even_sz_lossless_webp;
     unsigned char *blob_odd_png;
     int blob_odd_sz_png;
     unsigned char *blob_even_png;
@@ -157,6 +151,18 @@ main (int argc, char *argv[])
     int blob_even_sz_gif;
     unsigned char *blob_stat;
     int blob_stat_size;
+
+#ifndef OMIT_WEBP		/* only if WebP is enabled */
+    unsigned char *blob_odd_lossy_webp;
+    int blob_odd_sz_lossy_webp;
+    unsigned char *blob_even_lossy_webp;
+    int blob_even_sz_lossy_webp;
+    unsigned char *blob_odd_lossless_webp;
+    int blob_odd_sz_lossless_webp;
+    unsigned char *blob_even_lossless_webp;
+    int blob_even_sz_lossless_webp;
+#endif /* end WebP conditional */
+
     int anti_endian = antiEndian ();
 
     if (argc > 1 || argv[0] == NULL)
@@ -250,6 +256,7 @@ main (int argc, char *argv[])
     free (blob_stat);
     rl2_destroy_raster_statistics (stats);
 
+#ifndef OMIT_WEBP		/* only if WebP is defined */
     if (rl2_raster_encode
 	(raster, RL2_COMPRESSION_LOSSY_WEBP, &blob_odd_lossy_webp,
 	 &blob_odd_sz_lossy_webp, &blob_even_lossy_webp,
@@ -275,6 +282,7 @@ main (int argc, char *argv[])
 	free (blob_odd_lossless_webp);
     if (blob_even_lossless_webp != NULL)
 	free (blob_even_lossless_webp);
+#endif /* end WebP conditional */
 
     if (rl2_raster_encode
 	(raster, RL2_COMPRESSION_PNG, &blob_odd_png, &blob_odd_sz_png,
diff --git a/test/test4.c b/test/test4.c
index c99787b..1f039b4 100644
--- a/test/test4.c
+++ b/test/test4.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -43,6 +43,8 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include <unistd.h>
 #include <stdio.h>
 
+#include "config.h"
+
 #include "rasterlite2/rasterlite2.h"
 
 static int
@@ -631,10 +633,6 @@ main (int argc, char *argv[])
     int blob_odd_sz_zip;
     unsigned char *blob_even_zip;
     int blob_even_sz_zip;
-    unsigned char *blob_odd_lzma;
-    int blob_odd_sz_lzma;
-    unsigned char *blob_even_lzma;
-    int blob_even_sz_lzma;
     unsigned char *blob_odd_jpeg;
     int blob_odd_sz_jpeg;
     unsigned char *blob_even_jpeg;
@@ -651,6 +649,14 @@ main (int argc, char *argv[])
     int blob_odd_sz_fax;
     unsigned char *blob_even_fax;
     int blob_even_sz_fax;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
+    unsigned char *blob_odd_lzma;
+    int blob_odd_sz_lzma;
+    unsigned char *blob_even_lzma;
+    int blob_even_sz_lzma;
+#endif /* end LZMA conditional */
+
     unsigned char *blob_stat;
     int blob_stat_size;
     int endian = naturalEndian ();
@@ -749,19 +755,41 @@ main (int argc, char *argv[])
 
     if (rl2_raster_encode
 	(raster, RL2_COMPRESSION_DEFLATE, &blob_odd_zip, &blob_odd_sz_zip,
-	 &blob_even_zip, &blob_even_sz_zip, 0, endian) != RL2_ERROR)
+	 &blob_even_zip, &blob_even_sz_zip, 0, endian) != RL2_OK)
       {
 	  fprintf (stderr, "Unexpected result - DEFLATE compressed\n");
 	  return -103;
       }
+    free (blob_odd_zip);
 
     if (rl2_raster_encode
+	(raster, RL2_COMPRESSION_DEFLATE_NO, &blob_odd_zip, &blob_odd_sz_zip,
+	 &blob_even_zip, &blob_even_sz_zip, 0, endian) != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected result - DEFLATE_NO compressed\n");
+	  return -104;
+      }
+    free (blob_odd_zip);
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
+    if (rl2_raster_encode
 	(raster, RL2_COMPRESSION_LZMA, &blob_odd_lzma, &blob_odd_sz_lzma,
-	 &blob_even_lzma, &blob_even_sz_lzma, 0, endian) != RL2_ERROR)
+	 &blob_even_lzma, &blob_even_sz_lzma, 0, endian) != RL2_OK)
       {
 	  fprintf (stderr, "Unexpected result - LZMA compressed\n");
 	  return -10;
       }
+    free (blob_odd_lzma);
+
+    if (rl2_raster_encode
+	(raster, RL2_COMPRESSION_LZMA_NO, &blob_odd_lzma, &blob_odd_sz_lzma,
+	 &blob_even_lzma, &blob_even_sz_lzma, 0, endian) != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected result - LZMA_NO compressed\n");
+	  return -105;
+      }
+    free (blob_odd_lzma);
+#endif /* end LZMA conditional */
 
     if (rl2_raster_encode
 	(raster, RL2_COMPRESSION_JPEG, &blob_odd_jpeg, &blob_odd_sz_jpeg,
@@ -851,7 +879,6 @@ main (int argc, char *argv[])
 	  fprintf (stderr, "Unexpected result: Decode 1:2 - fax\n");
 	  return -24;
       }
-    free (blob_odd_lzma);
 
     unlink ("./monochrome_1_1_fax.png");
 
@@ -889,6 +916,7 @@ main (int argc, char *argv[])
 	  return -28;
       }
     free (blob_odd_png);
+    free (blob_odd_fax);
 
     unlink ("./monochrome_1_1_png.png");
 
diff --git a/test/test5.c b/test/test5.c
index 19ba613..1883b82 100644
--- a/test/test5.c
+++ b/test/test5.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -43,6 +43,8 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include <unistd.h>
 #include <stdio.h>
 
+#include "config.h"
+
 #include "rasterlite2/rasterlite2.h"
 
 static int
@@ -651,10 +653,6 @@ main (int argc, char *argv[])
     int blob_odd_sz_zip;
     unsigned char *blob_even_zip;
     int blob_even_sz_zip;
-    unsigned char *blob_odd_lzma;
-    int blob_odd_sz_lzma;
-    unsigned char *blob_even_lzma;
-    int blob_even_sz_lzma;
     unsigned char *blob_odd_png;
     int blob_odd_sz_png;
     unsigned char *blob_even_png;
@@ -663,6 +661,14 @@ main (int argc, char *argv[])
     int blob_odd_sz_gif;
     unsigned char *blob_even_gif;
     int blob_even_sz_gif;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
+    unsigned char *blob_odd_lzma;
+    int blob_odd_sz_lzma;
+    unsigned char *blob_even_lzma;
+    int blob_even_sz_lzma;
+#endif /* end LZMA conditional */
+
     int endian = naturalEndian ();
     rl2PalettePtr palette;
     rl2PalettePtr plt2;
@@ -732,19 +738,41 @@ main (int argc, char *argv[])
 
     if (rl2_raster_encode
 	(raster, RL2_COMPRESSION_DEFLATE, &blob_odd_zip, &blob_odd_sz_zip,
-	 &blob_even_zip, &blob_even_sz_zip, 0, endian) == RL2_OK)
+	 &blob_even_zip, &blob_even_sz_zip, 0, endian) != RL2_OK)
       {
 	  fprintf (stderr, "Unexpected result - compressed DEFLATE\n");
 	  return -9;
       }
+    free (blob_odd_zip);
+
+    if (rl2_raster_encode
+	(raster, RL2_COMPRESSION_DEFLATE_NO, &blob_odd_zip, &blob_odd_sz_zip,
+	 &blob_even_zip, &blob_even_sz_zip, 0, endian) != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected result - compressed DEFLATE_NO\n");
+	  return -109;
+      }
+    free (blob_odd_zip);
 
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
     if (rl2_raster_encode
 	(raster, RL2_COMPRESSION_LZMA, &blob_odd_lzma, &blob_odd_sz_lzma,
-	 &blob_even_lzma, &blob_even_sz_lzma, 0, endian) == RL2_OK)
+	 &blob_even_lzma, &blob_even_sz_lzma, 0, endian) != RL2_OK)
       {
 	  fprintf (stderr, "Unexpected result - compressed LZMA\n");
 	  return -10;
       }
+    free (blob_odd_lzma);
+
+    if (rl2_raster_encode
+	(raster, RL2_COMPRESSION_LZMA_NO, &blob_odd_lzma, &blob_odd_sz_lzma,
+	 &blob_even_lzma, &blob_even_sz_lzma, 0, endian) != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected result - compressed LZMA_NO\n");
+	  return -110;
+      }
+    free (blob_odd_lzma);
+#endif /* end LZMA conditional */
 
     if (rl2_raster_encode
 	(raster, RL2_COMPRESSION_PNG, &blob_odd_png, &blob_odd_sz_png,
diff --git a/test/test6.c b/test/test6.c
index 20f9e6f..5e0a1bc 100644
--- a/test/test6.c
+++ b/test/test6.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
diff --git a/test/test7.c b/test/test7.c
index c1d272e..f54c492 100644
--- a/test/test7.c
+++ b/test/test7.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
diff --git a/test/test8.c b/test/test8.c
index 9a8349c..e90daba 100644
--- a/test/test8.c
+++ b/test/test8.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
diff --git a/test/test9.c b/test/test9.c
index 3029f16..25f7d77 100644
--- a/test/test9.c
+++ b/test/test9.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
diff --git a/test/test_copy_rastercov.c b/test/test_copy_rastercov.c
new file mode 100644
index 0000000..c02bdd4
--- /dev/null
+++ b/test/test_copy_rastercov.c
@@ -0,0 +1,309 @@
+/*
+
+ test_copy_rastercov.c -- RasterLite-2 Test Case
+
+ Author: Sandro Furieri <a.furieri at lqt.it>
+
+ ------------------------------------------------------------------------------
+ 
+ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ 
+ The contents of this file are subject to the Mozilla Public License Version
+ 1.1 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+ 
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the
+License.
+
+The Original Code is the RasterLite2 library
+
+The Initial Developer of the Original Code is Alessandro Furieri
+ 
+Portions created by the Initial Developer are Copyright (C) 2013
+the Initial Developer. All Rights Reserved.
+
+Contributor(s):
+
+Alternatively, the contents of this file may be used under the terms of
+either the GNU General Public License Version 2 or later (the "GPL"), or
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+in which case the provisions of the GPL or the LGPL are applicable instead
+of those above. If you wish to allow use of your version of this file only
+under the terms of either the GPL or the LGPL, and not to allow others to
+use your version of this file under the terms of the MPL, indicate your
+decision by deleting the provisions above and replace them with the notice
+and other provisions required by the GPL or the LGPL. If you do not delete
+the provisions above, a recipient may use your version of this file under
+the terms of any one of the MPL, the GPL or the LGPL.
+ 
+*/
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "config.h"
+
+#include "sqlite3.h"
+#include "spatialite.h"
+#include "spatialite/gaiaaux.h"
+
+#include "rasterlite2/rasterlite2.h"
+
+static int
+execute_check (sqlite3 * sqlite, const char *sql)
+{
+/* executing an SQL statement returning True/False */
+    sqlite3_stmt *stmt;
+    int ret;
+    int retcode = 0;
+
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return SQLITE_ERROR;
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+      {
+	  if (sqlite3_column_int (stmt, 0) == 1)
+	      retcode = 1;
+      }
+    sqlite3_finalize (stmt);
+    if (retcode == 1)
+	return SQLITE_OK;
+    return SQLITE_ERROR;
+}
+
+int
+main (int argc, char *argv[])
+{
+    int result = 0;
+    int ret;
+    char *err_msg = NULL;
+    char *sql;
+    sqlite3 *db_handle;
+    void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
+    char *old_SPATIALITE_SECURITY_ENV = NULL;
+
+    if (argc > 1 || argv[0] == NULL)
+	argc = 1;		/* silencing stupid compiler warnings */
+
+/*=====================================================================
+/
+/ step I - we'll start by creating and populating the Origin DB
+/
+/====================================================================*/
+
+    old_SPATIALITE_SECURITY_ENV = getenv ("SPATIALITE_SECURITY");
+#ifdef _WIN32
+    putenv ("SPATIALITE_SECURITY=relaxed");
+#else /* not WIN32 */
+    setenv ("SPATIALITE_SECURITY", "relaxed", 1);
+#endif
+
+/* opening and initializing the "copy_origin" test DB */
+    ret = sqlite3_open_v2 ("copy_origin.sqlite", &db_handle,
+			   SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "sqlite3_open_v2() error: %s\n",
+		   sqlite3_errmsg (db_handle));
+	  return -1;
+      }
+    spatialite_init_ex (db_handle, cache, 0);
+    rl2_init (db_handle, priv_data, 0);
+    ret =
+	sqlite3_exec (db_handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
+		      &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "InitSpatialMetadata() error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -2;
+      }
+    ret =
+	sqlite3_exec (db_handle, "SELECT CreateRasterCoveragesTable()", NULL,
+		      NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "CreateRasterCoveragesTable() error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -3;
+      }
+
+/* creating the DBMS Coverage */
+    sql = sqlite3_mprintf ("SELECT RL2_CreateRasterCoverage("
+			   "%Q, %Q, %Q, %d, %Q, %d, %d, %d, %d, %1.4f, %1.4f, "
+			   "RL2_SetPixelValue(RL2_CreatePixel(%Q, %Q, 1), 0, 0))",
+			   "test_coverage", "4-BIT", "PALETTE", 1,
+			   "PNG", 100, 512, 512, 26716,
+			   2.4384, 2.4384, "4-BIT", "PALETTE");
+    ret = execute_check (db_handle, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "CreateRasterCoverage \"%s\" error: %s\n",
+		   "test_coverage", err_msg);
+	  sqlite3_free (err_msg);
+	  return -4;
+      }
+
+/* loading from directory */
+    sql =
+	sqlite3_mprintf
+	("SELECT RL2_LoadRastersFromDir(%Q, %Q, %Q, 0, 26716, 0, 1)",
+	 "test_coverage", "map_samples/usgs-indiana", ".tif");
+    ret = execute_check (db_handle, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "LoadRastersFromDir \"%s\" error: %s\n",
+		   "test_coverage", err_msg);
+	  sqlite3_free (err_msg);
+	  return -5;
+      }
+
+/* building the Pyramid Levels */
+    sql =
+	sqlite3_mprintf ("SELECT RL2_Pyramidize(%Q, NULL, 0, 1)",
+			 "test_coverage");
+    ret = execute_check (db_handle, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Pyramidize \"%s\" error: %s\n", "test_coverage",
+		   err_msg);
+	  sqlite3_free (err_msg);
+	  return -6;
+      }
+
+/* closing the origin DB */
+    sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
+    if (old_SPATIALITE_SECURITY_ENV)
+      {
+#ifdef _WIN32
+	  char *env = sqlite3_mprintf ("SPATIALITE_SECURITY=%s",
+				       old_SPATIALITE_SECURITY_ENV);
+	  putenv (env);
+	  sqlite3_free (env);
+#else /* not WIN32 */
+	  setenv ("SPATIALITE_SECURITY", old_SPATIALITE_SECURITY_ENV, 1);
+#endif
+      }
+    else
+      {
+#ifdef _WIN32
+	  putenv ("SPATIALITE_SECURITY=");
+#else /* not WIN32 */
+	  unsetenv ("SPATIALITE_SECURITY");
+#endif
+      }
+
+
+/*=====================================================================
+/
+/ step II - we'll now create the Destination DB
+/
+/====================================================================*/
+    cache = spatialite_alloc_connection ();
+    priv_data = rl2_alloc_private ();
+/* opening and initializing the "memory" test DB */
+    ret = sqlite3_open_v2 (":memory:", &db_handle,
+			   SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "sqlite3_open_v2() error: %s\n",
+		   sqlite3_errmsg (db_handle));
+	  return -7;
+      }
+    spatialite_init_ex (db_handle, cache, 0);
+    rl2_init (db_handle, priv_data, 0);
+    ret =
+	sqlite3_exec (db_handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
+		      &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "InitSpatialMetadata() error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -8;
+      }
+
+/* Attaching the Origin DB */
+    ret =
+	sqlite3_exec (db_handle,
+		      "ATTACH DATABASE './copy_origin.sqlite' AS 'origin'",
+		      NULL, NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "ATTACH DATABASE error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -9;
+      }
+
+/* copying a Raster Coverage */
+    sql =
+	sqlite3_mprintf ("SELECT RL2_CopyRasterCoverage(%Q, %Q, 1)", "origin",
+			 "test_coverage");
+    ret = execute_check (db_handle, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "CopyRasterCoverage error\n");
+	  sqlite3_free (err_msg);
+	  return -10;
+      }
+
+/* error: not existing origin (bad prefix) */
+    sql =
+	sqlite3_mprintf ("SELECT RL2_CopyRasterCoverage(%Q, %Q, 1)", "wrong",
+			 "test_coverage");
+    ret = execute_check (db_handle, sql);
+    sqlite3_free (sql);
+    if (ret == SQLITE_OK)
+      {
+	  fprintf (stderr, "CopyRasterCoverage unexpected success #1\n");
+	  sqlite3_free (err_msg);
+	  return -11;
+      }
+
+/* error: not existing origin (bad coverage) */
+    sql =
+	sqlite3_mprintf ("SELECT RL2_CopyRasterCoverage(%Q, %Q, 1)", "origin",
+			 "wrong");
+    ret = execute_check (db_handle, sql);
+    sqlite3_free (sql);
+    if (ret == SQLITE_OK)
+      {
+	  fprintf (stderr, "CopyRasterCoverage unexpected success #2\n");
+	  sqlite3_free (err_msg);
+	  return -12;
+      }
+
+/* error: already existing destination */
+    sql =
+	sqlite3_mprintf ("SELECT RL2_CopyRasterCoverage(%Q, %Q, 1)", "origin",
+			 "test_coverage");
+    ret = execute_check (db_handle, sql);
+    sqlite3_free (sql);
+    if (ret == SQLITE_OK)
+      {
+	  fprintf (stderr, "CopyRasterCoverage unexpected success #3\n");
+	  sqlite3_free (err_msg);
+	  return -13;
+      }
+
+/* closing the destination DB */
+    sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
+    spatialite_shutdown ();
+    
+    unlink ("copy_origin.sqlite");
+    return result;
+}
diff --git a/test/test_coverage.c b/test/test_coverage.c
index 85055c3..b2420d9 100644
--- a/test/test_coverage.c
+++ b/test/test_coverage.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -200,12 +200,15 @@ main (int argc, char *argv[])
 	  return -18;
       }
 
-    if (rl2_create_coverage ("alpha", RL2_SAMPLE_UINT16, RL2_PIXEL_RGB, 3,
-			     RL2_COMPRESSION_NONE, 0, 1024, 1024, NULL) == NULL)
+    coverage =
+	rl2_create_coverage ("alpha", RL2_SAMPLE_UINT16, RL2_PIXEL_RGB, 3,
+			     RL2_COMPRESSION_NONE, 0, 1024, 1024, NULL);
+    if (coverage == NULL)
       {
 	  fprintf (stderr, "Invalid coverage - rgb 16\n");
 	  return -19;
       }
+    rl2_destroy_coverage (coverage);
 
     if (rl2_create_coverage ("alpha", RL2_SAMPLE_UINT8, RL2_PIXEL_RGB, 3,
 			     RL2_COMPRESSION_GIF, 0, 1024, 1024, NULL) != NULL)
diff --git a/test/test_font.c b/test/test_font.c
new file mode 100644
index 0000000..7db62b6
--- /dev/null
+++ b/test/test_font.c
@@ -0,0 +1,325 @@
+/*
+
+ test_font.c -- RasterLite-2 Test Case
+
+ Author: Sandro Furieri <a.furieri at lqt.it>
+
+ ------------------------------------------------------------------------------
+ 
+ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ 
+ The contents of this file are subject to the Mozilla Public License Version
+ 1.1 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+ 
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the
+License.
+
+The Original Code is the RasterLite2 library
+
+The Initial Developer of the Original Code is Alessandro Furieri
+ 
+Portions created by the Initial Developer are Copyright (C) 2015
+the Initial Developer. All Rights Reserved.
+
+Contributor(s):
+
+Alternatively, the contents of this file may be used under the terms of
+either the GNU General Public License Version 2 or later (the "GPL"), or
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+in which case the provisions of the GPL or the LGPL are applicable instead
+of those above. If you wish to allow use of your version of this file only
+under the terms of either the GPL or the LGPL, and not to allow others to
+use your version of this file under the terms of the MPL, indicate your
+decision by deleting the provisions above and replace them with the notice
+and other provisions required by the GPL or the LGPL. If you do not delete
+the provisions above, a recipient may use your version of this file under
+the terms of any one of the MPL, the GPL or the LGPL.
+ 
+*/
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "sqlite3.h"
+#include "spatialite.h"
+
+#include "rasterlite2/rasterlite2.h"
+
+static int
+execute_check (sqlite3 * sqlite, const char *sql)
+{
+/* executing an SQL statement returning True/False */
+    sqlite3_stmt *stmt;
+    int ret;
+    int retcode = 0;
+
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return SQLITE_ERROR;
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+      {
+	  if (sqlite3_column_int (stmt, 0) == 1)
+	      retcode = 1;
+      }
+    sqlite3_finalize (stmt);
+    if (retcode == 1)
+	return SQLITE_OK;
+    return SQLITE_ERROR;
+}
+
+static int
+execute_test_string (sqlite3 * sqlite, const char *sql, const char *expected)
+{
+/* executing an SQL statement returning a TEXT resultset */
+    sqlite3_stmt *stmt;
+    int ret;
+    int err = 0;
+    int match = 0;
+    int count = 0;
+
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return SQLITE_ERROR;
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	    {
+		count++;
+		if (sqlite3_column_type (stmt, 0) == SQLITE_TEXT)
+		  {
+		      const char *value =
+			  (const char *) sqlite3_column_text (stmt, 0);
+		      if (strcmp (value, expected) == 0)
+			  match++;
+		  }
+	    }
+	  else
+	    {
+		err = 1;
+		break;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    if (count == 1 && match == 1 && err == 0)
+	return SQLITE_OK;
+    return SQLITE_ERROR;
+}
+
+static int
+execute_test_boolean (sqlite3 * sqlite, const char *sql, int expected)
+{
+/* executing an SQL statement returning a BOOLEAN resultset */
+    sqlite3_stmt *stmt;
+    int ret;
+    int err = 0;
+    int match = 0;
+    int count = 0;
+
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return SQLITE_ERROR;
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	    {
+		count++;
+		if (sqlite3_column_type (stmt, 0) == SQLITE_INTEGER)
+		  {
+		      int value = sqlite3_column_int (stmt, 0);
+		      if (value == expected)
+			  match++;
+		  }
+	    }
+	  else
+	    {
+		err = 1;
+		break;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    if (count == 1 && match == 1 && err == 0)
+	return SQLITE_OK;
+    return SQLITE_ERROR;
+}
+
+static int
+test_font (sqlite3 * sqlite, int *retcode)
+{
+/* testing SE Font functions */
+    int ret;
+    const char *sql;
+
+/* testing LoadFontFromFile() */
+    sql = "SELECT LoadFontFromFile('./Karla-BoldItalic.ttf')";
+    ret = execute_check (sqlite, sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "ERROR: Unable to import a Font #1\n");
+	  *retcode -= 1;
+	  return 0;
+      }
+
+/* testing LoadFontFromFile() - second time */
+    sql = "SELECT LoadFontFromFile('./Karla-BoldItalic.ttf')";
+    ret = execute_check (sqlite, sql);
+    if (ret == SQLITE_OK)
+      {
+	  fprintf (stderr, "ERROR: Unexpected success import Font #2\n");
+	  *retcode -= 2;
+	  return 0;
+      }
+
+/* testing ExportFontToFile() */
+    sql =
+	"SELECT ExportFontToFile('Karla-BoldItalic', 'out-karla-bold-italic.ttf')";
+    ret = execute_check (sqlite, sql);
+    unlink ("out-karla-bold-italic.ttf");
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "ERROR: Unable to export a Font\n");
+	  *retcode -= 3;
+	  return 0;
+      }
+
+/* testing GetFontFamily() */
+    sql = "SELECT GetFontFamily(font) FROM SE_fonts "
+	"WHERE font_facename = 'Karla-BoldItalic'";
+    ret = execute_test_string (sqlite, sql, "Karla");
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "ERROR: Unable to get the Font Family name\n");
+	  *retcode -= 4;
+	  return 0;
+      }
+
+/* testing GetFontFacename() */
+    sql = "SELECT GetFontFacename(font) FROM SE_fonts "
+	"WHERE font_facename = 'Karla-BoldItalic'";
+    ret = execute_test_string (sqlite, sql, "Karla-BoldItalic");
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "ERROR: Unable to get the Font Facename\n");
+	  *retcode -= 5;
+	  return 0;
+      }
+
+/* testing IsFontBold() */
+    sql = "SELECT IsFontBold(font) FROM SE_fonts "
+	"WHERE font_facename = 'Karla-BoldItalic'";
+    ret = execute_test_boolean (sqlite, sql, 1);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "ERROR: Unable to get the Font IsBold\n");
+	  *retcode -= 6;
+	  return 0;
+      }
+
+/* testing IsFontItalic() */
+    sql = "SELECT IsFontItalic(font) FROM SE_fonts "
+	"WHERE font_facename = 'Karla-BoldItalic'";
+    ret = execute_test_boolean (sqlite, sql, 1);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "ERROR: Unable to get the Font IsItalic\n");
+	  *retcode -= 7;
+	  return 0;
+      }
+
+    return 1;
+}
+
+int
+main (int argc, char *argv[])
+{
+    int result = 0;
+    int ret;
+    sqlite3 *db_handle;
+    char *err_msg = NULL;
+    void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
+    char *old_SPATIALITE_SECURITY_ENV = NULL;
+
+    if (argc > 1 || argv[0] == NULL)
+	argc = 1;		/* silencing stupid compiler warnings */
+
+    old_SPATIALITE_SECURITY_ENV = getenv ("SPATIALITE_SECURITY");
+#ifdef _WIN32
+    putenv ("SPATIALITE_SECURITY=relaxed");
+#else /* not WIN32 */
+    setenv ("SPATIALITE_SECURITY", "relaxed", 1);
+#endif
+
+/* opening and initializing the "memory" test DB */
+    ret = sqlite3_open_v2 (":memory:", &db_handle,
+			   SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "sqlite3_open_v2() error: %s\n",
+		   sqlite3_errmsg (db_handle));
+	  return -1;
+      }
+    spatialite_init_ex (db_handle, cache, 0);
+    rl2_init (db_handle, priv_data, 0);
+    ret =
+	sqlite3_exec (db_handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
+		      &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "InitSpatialMetadata() error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -2;
+      }
+    ret =
+	sqlite3_exec (db_handle, "SELECT CreateStylingTables()", NULL,
+		      NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "CreateStylingTables() error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -3;
+      }
+
+/* tests */
+    ret = -100;
+    if (!test_font (db_handle, &ret))
+	return ret;
+
+/* closing the DB */
+    sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
+    spatialite_shutdown ();
+    if (old_SPATIALITE_SECURITY_ENV)
+      {
+#ifdef _WIN32
+	  char *env = sqlite3_mprintf ("SPATIALITE_SECURITY=%s",
+				       old_SPATIALITE_SECURITY_ENV);
+	  putenv (env);
+	  sqlite3_free (env);
+#else /* not WIN32 */
+	  setenv ("SPATIALITE_SECURITY", old_SPATIALITE_SECURITY_ENV, 1);
+#endif
+      }
+    else
+      {
+#ifdef _WIN32
+	  putenv ("SPATIALITE_SECURITY=");
+#else /* not WIN32 */
+	  unsetenv ("SPATIALITE_SECURITY");
+#endif
+      }
+    return result;
+}
diff --git a/test/test_gif.c b/test/test_gif.c
index ad14019..fd92bd8 100644
--- a/test/test_gif.c
+++ b/test/test_gif.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
diff --git a/test/test_line_symbolizer.c b/test/test_line_symbolizer.c
new file mode 100644
index 0000000..bda539c
--- /dev/null
+++ b/test/test_line_symbolizer.c
@@ -0,0 +1,1551 @@
+/*
+
+ test_line_symbolizer.c -- RasterLite-2 Test Case
+
+ Author: Sandro Furieri <a.furieri at lqt.it>
+
+ ------------------------------------------------------------------------------
+ 
+ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ 
+ The contents of this file are subject to the Mozilla Public License Version
+ 1.1 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+ 
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the
+License.
+
+The Original Code is the RasterLite2 library
+
+The Initial Developer of the Original Code is Alessandro Furieri
+ 
+Portions created by the Initial Developer are Copyright (C) 2015
+the Initial Developer. All Rights Reserved.
+
+Contributor(s):
+
+Alternatively, the contents of this file may be used under the terms of
+either the GNU General Public License Version 2 or later (the "GPL"), or
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+in which case the provisions of the GPL or the LGPL are applicable instead
+of those above. If you wish to allow use of your version of this file only
+under the terms of either the GPL or the LGPL, and not to allow others to
+use your version of this file under the terms of the MPL, indicate your
+decision by deleting the provisions above and replace them with the notice
+and other provisions required by the GPL or the LGPL. If you do not delete
+the provisions above, a recipient may use your version of this file under
+the terms of any one of the MPL, the GPL or the LGPL.
+ 
+*/
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "sqlite3.h"
+#include "spatialite.h"
+
+#include "rasterlite2/rasterlite2.h"
+
+static int
+test_symbolizer (sqlite3 * db_handle, const char *coverage,
+		 const char *style_name, int *retcode)
+{
+/* testing a LineSymbolizer */
+    rl2FeatureTypeStylePtr style;
+    rl2VectorSymbolizerPtr symbolizer;
+    rl2LineSymbolizerPtr line;
+    int intval;
+    int index;
+    double dblval;
+    const char *string;
+    unsigned char red;
+    unsigned char green;
+    unsigned char blue;
+    int scale_forbidden;
+    style =
+	rl2_create_feature_type_style_from_dbms (db_handle, coverage,
+						 style_name);
+    if (style == NULL)
+      {
+	  fprintf (stderr, "Unable to retrieve style '%s'\n", style_name);
+	  *retcode += 1;
+	  return 0;
+      }
+
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 1.0, NULL,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s)\n",
+		   style_name);
+	  *retcode += 2;
+	  return 0;
+      }
+
+    if (rl2_is_valid_vector_symbolizer (symbolizer, &intval) != RL2_OK)
+      {
+	  fprintf (stderr, "%s: Unable to get Vector Symbolizer Validity #1\n",
+		   style_name);
+	  *retcode += 3;
+	  return 0;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr, "%s: Unexpected Vector Symbolizer Validity #1: %d\n",
+		   style_name, intval);
+	  *retcode += 4;
+	  return 0;
+      }
+
+    if (rl2_get_vector_symbolizer_count (symbolizer, &intval) != RL2_OK)
+      {
+	  fprintf (stderr, "%s: Unable to get Vector Symbolizer Count #1\n",
+		   style_name);
+	  *retcode += 5;
+	  return 0;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr, "%s: Unexpected Vector Symbolizer Count #1: %d\n",
+		   style_name, intval);
+	  *retcode += 6;
+	  return 0;
+      }
+
+    if (rl2_get_vector_symbolizer_item_type (symbolizer, 0, &intval) != RL2_OK)
+      {
+	  fprintf (stderr, "%s: Unable to get Vector Symbolizer Item Type #1\n",
+		   style_name);
+	  *retcode += 7;
+	  return 0;
+      }
+    if (intval != RL2_LINE_SYMBOLIZER)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Vector Symbolizer Item Type #1: %d\n",
+		   style_name, intval);
+	  *retcode += 8;
+	  return 0;
+      }
+
+    line = rl2_get_line_symbolizer (symbolizer, 0);
+    if (line == NULL)
+      {
+	  fprintf (stderr, "%s: Unable to get a Line Symbolizer #1\n",
+		   style_name);
+	  *retcode += 9;
+	  return 0;
+      }
+
+    if (rl2_line_symbolizer_has_stroke (line, &intval) != RL2_OK)
+      {
+	  fprintf (stderr, "%s: Unable to get Line Symbolizer HasStroke #1\n",
+		   style_name);
+	  *retcode += 10;
+	  return 0;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr, "%s: Unexpected Line Symbolizer HasStroke #1: %d\n",
+		   style_name, intval);
+	  *retcode += 11;
+	  return 0;
+      }
+
+    if (rl2_line_symbolizer_get_stroke_color (line, &red, &green, &blue) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Line Symbolizer GetStrokeColor #1\n",
+		   style_name);
+	  *retcode += 12;
+	  return 0;
+      }
+    intval = 0;
+    if (strcmp (style_name, "line_1") == 0)
+      {
+	  if (red == 0xff && green == 0xff && blue == 0x00)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "line_2") == 0)
+      {
+	  if (red == 0x00 && green == 0x00 && blue == 0x00)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "line_3") == 0)
+	intval = 1;
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Line Symbolizer GetStrokeColor #1: #%02x%02x%02x\n",
+		   style_name, red, green, blue);
+	  *retcode += 13;
+	  return 0;
+      }
+
+    if (rl2_line_symbolizer_get_stroke_opacity (line, &dblval) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Line Symbolizer GetStrokeOpacity #1\n",
+		   style_name);
+	  *retcode += 14;
+	  return 0;
+      }
+    intval = 0;
+    if (strcmp (style_name, "line_1") == 0)
+      {
+	  if (dblval == 1.0)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "line_2") == 0)
+      {
+	  if (dblval == 0.5)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "line_3") == 0)
+      {
+	  if (dblval == 0.75)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Line Symbolizer GetStrokeOpacity #1: %1.4f\n",
+		   style_name, dblval);
+	  *retcode += 15;
+	  return 0;
+      }
+
+    if (rl2_line_symbolizer_get_stroke_width (line, &dblval) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Line Symbolizer GetStrokeWidth #1\n",
+		   style_name);
+	  *retcode += 16;
+	  return 0;
+      }
+    intval = 0;
+    if (strcmp (style_name, "line_1") == 0)
+      {
+	  if (dblval == 4.0)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "line_2") == 0)
+      {
+	  if (dblval == 1.0)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "line_3") == 0)
+      {
+	  if (dblval == 2.0)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Line Symbolizer GetStrokeWidth #1: %1.4f\n",
+		   style_name, dblval);
+	  *retcode += 17;
+	  return 0;
+      }
+
+    if (rl2_line_symbolizer_get_stroke_linejoin (line, &red) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Line Symbolizer GetStrokeLinejoin #1\n",
+		   style_name);
+	  *retcode += 18;
+	  return 0;
+      }
+    intval = 0;
+    if (strcmp (style_name, "line_1") == 0)
+      {
+	  if (red == RL2_STROKE_LINEJOIN_UNKNOWN)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "line_2") == 0)
+      {
+	  if (red == RL2_STROKE_LINEJOIN_ROUND)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "line_3") == 0)
+      {
+	  if (red == RL2_STROKE_LINEJOIN_MITRE)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Line Symbolizer GetStrokeLinejoin #1: %02x\n",
+		   style_name, red);
+	  *retcode += 19;
+	  return 0;
+      }
+
+    if (rl2_line_symbolizer_get_stroke_linecap (line, &red) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Line Symbolizer GetStrokeLinecap #1\n",
+		   style_name);
+	  *retcode += 20;
+	  return 0;
+      }
+    intval = 0;
+    if (strcmp (style_name, "line_1") == 0)
+      {
+	  if (red == RL2_STROKE_LINECAP_UNKNOWN)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "line_2") == 0)
+      {
+	  if (red == RL2_STROKE_LINECAP_SQUARE)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "line_3") == 0)
+      {
+	  if (red == RL2_STROKE_LINECAP_ROUND)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Line Symbolizer GetStrokeLinecap #1: %02x\n",
+		   style_name, red);
+	  *retcode += 21;
+	  return 0;
+      }
+
+    if (rl2_line_symbolizer_get_stroke_dash_count (line, &intval) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Line Symbolizer GetStrokeDashCount #1\n",
+		   style_name);
+	  *retcode += 22;
+	  return 0;
+      }
+    red = 0;
+    if (strcmp (style_name, "line_1") == 0)
+      {
+	  if (intval == 0)
+	      red = 1;
+      }
+    if (strcmp (style_name, "line_2") == 0)
+      {
+	  if (intval == 6)
+	      red = 1;
+      }
+    if (strcmp (style_name, "line_3") == 0)
+      {
+	  if (intval == 0)
+	      red = 1;
+      }
+    if (red != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Line Symbolizer GetStrokeDashCount #1: %d\n",
+		   style_name, intval);
+	  *retcode += 23;
+	  return 0;
+      }
+
+    if (strcmp (style_name, "line_1") == 0
+	|| strcmp (style_name, "line_3") == 0)
+      {
+	  if (rl2_line_symbolizer_get_stroke_dash_item (line, 0, &dblval) ==
+	      RL2_OK)
+	    {
+		fprintf (stderr,
+			 "Expected failure, got success: Line Symbolizer GetStrokeDashItem #1\n");
+		*retcode += 24;
+		return 0;
+	    }
+      }
+    if (strcmp (style_name, "line_2") == 0)
+      {
+	  if (rl2_line_symbolizer_get_stroke_dash_item (line, 0, &dblval) !=
+	      RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Line Symbolizer GetStrokeDashItem #1\n",
+			 style_name);
+		*retcode += 25;
+		return 0;
+	    }
+	  if (dblval != 20.0)
+	    {
+		fprintf (stderr,
+			 "Unexpected Line Symbolizer GetStrokDashItem #1: %1.4f\n",
+			 dblval);
+		*retcode += 26;
+		return 0;
+	    }
+	  if (rl2_line_symbolizer_get_stroke_dash_item (line, 1, &dblval) !=
+	      RL2_OK)
+	    {
+		fprintf (stderr,
+			 "Unable to get Line Symbolizer GetStrokeDashItem #2\n");
+		*retcode += 27;
+		return 0;
+	    }
+	  if (dblval != 10.1)
+	    {
+		fprintf (stderr,
+			 "Unexpected Line Symbolizer GetStrokDashItem #2: %1.4f\n",
+			 dblval);
+		*retcode += 28;
+		return 0;
+	    }
+	  if (rl2_line_symbolizer_get_stroke_dash_item (line, 2, &dblval) !=
+	      RL2_OK)
+	    {
+		fprintf (stderr,
+			 "Unable to get Line Symbolizer GetStrokeDashItem #3\n");
+		*retcode += 29;
+		return 0;
+	    }
+	  if (dblval != 5.5)
+	    {
+		fprintf (stderr,
+			 "Unexpected Line Symbolizer GetStrokDashItem #3: %1.4f\n",
+			 dblval);
+		*retcode += 30;
+		return 0;
+	    }
+	  if (rl2_line_symbolizer_get_stroke_dash_item (line, 3, &dblval) !=
+	      RL2_OK)
+	    {
+		fprintf (stderr,
+			 "Unable to get Line Symbolizer GetStrokeDashItem #4\n");
+		*retcode += 31;
+		return 0;
+	    }
+	  if (dblval != 4.0)
+	    {
+		fprintf (stderr,
+			 "Unexpected Line Symbolizer GetStrokDashItem #4: %1.4f\n",
+			 dblval);
+		*retcode += 32;
+		return 0;
+	    }
+	  if (rl2_line_symbolizer_get_stroke_dash_item (line, 4, &dblval) !=
+	      RL2_OK)
+	    {
+		fprintf (stderr,
+			 "Unable to get Line Symbolizer GetStrokeDashItem #5\n");
+		*retcode += 33;
+		return 0;
+	    }
+	  if (dblval != 6.0)
+	    {
+		fprintf (stderr,
+			 "Unexpected Line Symbolizer GetStrokDashItem #4: %1.4f\n",
+			 dblval);
+		*retcode += 34;
+		return 0;
+	    }
+	  if (rl2_line_symbolizer_get_stroke_dash_item (line, 5, &dblval) !=
+	      RL2_OK)
+	    {
+		fprintf (stderr,
+			 "Unable to get Line Symbolizer GetStrokeDashItem #5\n");
+		*retcode += 35;
+		return 0;
+	    }
+	  if (dblval != 12.0)
+	    {
+		fprintf (stderr,
+			 "Unexpected Line Symbolizer GetStrokDashItem #5: %1.4f\n",
+			 dblval);
+		*retcode += 36;
+		return 0;
+	    }
+      }
+
+    if (rl2_line_symbolizer_get_stroke_dash_offset (line, &dblval) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Line Symbolizer GetStrokeDashOffset #1\n",
+		   style_name);
+	  *retcode += 37;
+	  return 0;
+      }
+    intval = 0;
+    if (strcmp (style_name, "line_1") == 0
+	|| strcmp (style_name, "line_3") == 0)
+      {
+	  if (dblval == 0.0)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "line_2") == 0)
+      {
+	  if (dblval == 10.0)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Line Symbolizer GetStrokeDashOffset #1: %1.4f\n",
+		   style_name, dblval);
+	  *retcode += 38;
+	  return 0;
+      }
+
+    if (rl2_line_symbolizer_get_perpendicular_offset (line, &dblval) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Line Symbolizer GetPerpendicularOffset #1\n",
+		   style_name);
+	  *retcode += 39;
+	  return 0;
+      }
+    intval = 0;
+    if (strcmp (style_name, "line_1") == 0
+	|| strcmp (style_name, "line_3") == 0)
+      {
+	  if (dblval == 0.0)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "line_2") == 0)
+      {
+	  if (dblval == 5.0)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s; Unexpected Line Symbolizer GetPerpendicularOffset #1: %1.4f\n",
+		   style_name, dblval);
+	  *retcode += 40;
+	  return 0;
+      }
+
+    if (rl2_line_symbolizer_has_graphic_stroke (line, &intval) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Line Symbolizer HasGraphicStroke #1\n",
+		   style_name);
+	  *retcode += 41;
+	  return 0;
+      }
+    red = 0;
+    if (strcmp (style_name, "line_1") == 0
+	|| strcmp (style_name, "line_2") == 0)
+      {
+	  if (intval == 0)
+	      red = 1;
+      }
+    if (strcmp (style_name, "line_3") == 0)
+      {
+	  if (intval == 1)
+	      red = 1;
+      }
+    if (red != 1)
+      {
+	  fprintf (stderr,
+		   "%s; Unexpected Line Symbolizer HasGraphicStroke #1: %d\n",
+		   style_name, intval);
+	  *retcode += 42;
+	  return 0;
+      }
+
+    string = rl2_line_symbolizer_get_graphic_stroke_href (line);
+    intval = 0;
+    if (strcmp (style_name, "line_1") == 0
+	|| strcmp (style_name, "line_2") == 0)
+      {
+	  if (string == NULL)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "line_3") == 0)
+      {
+	  if (string != NULL)
+	    {
+		if (strcmp (string, "http:/www.acme.com/sample.png") == 0)
+		    intval = 1;
+	    }
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s; Unexpected Line Symbolizer GetGraphicStrokeHref #1: %s\n",
+		   style_name, string);
+	  *retcode += 43;
+	  return 0;
+      }
+
+    if (rl2_line_symbolizer_get_graphic_stroke_recode_count (line, &intval) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Line Symbolizer GetGraphicStrokeRecodeCount #1\n",
+		   style_name);
+	  *retcode += 44;
+	  return 0;
+      }
+    red = 0;
+    if (strcmp (style_name, "line_1") == 0
+	|| strcmp (style_name, "line_2") == 0)
+      {
+	  if (intval == 0)
+	      red = 1;
+      }
+    if (strcmp (style_name, "line_3") == 0)
+      {
+	  if (intval == 2)
+	      red = 1;
+      }
+    if (red != 1)
+      {
+	  fprintf (stderr,
+		   "%s; Unexpected Line Symbolizer GetGraphicStrokeRecodeCount #1: %d\n",
+		   style_name, intval);
+	  *retcode += 45;
+	  return 0;
+      }
+
+    intval =
+	rl2_line_symbolizer_get_graphic_stroke_recode_color (line, 0, &index,
+							     &red, &green,
+							     &blue);
+    if (strcmp (style_name, "line_1") == 0
+	|| strcmp (style_name, "line_2") == 0)
+      {
+	  if (intval == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Line Symbolizer GetGraphicStrokeRecodeColor #1\n",
+			 style_name);
+		*retcode += 46;
+		return 0;
+	    }
+	  intval = 1;
+      }
+    if (strcmp (style_name, "line_3") == 0)
+      {
+	  if (intval != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Line Symbolizer GetGraphicStrokeRecodeColor #1\n",
+			 style_name);
+		*retcode += 47;
+		return 0;
+	    }
+	  intval = 0;
+	  if (index == 0 && red == 0xff && green == 0x00 && blue == 0x80)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Line Symbolizer GetGraphicStrokeRecodeColor #1: #%02x%02x%02x\n",
+		   style_name, red, green, blue);
+	  *retcode += 48;
+	  return 0;
+      }
+
+    rl2_destroy_feature_type_style (style);
+    return 1;
+}
+
+static int
+test_style (sqlite3 * db_handle, const char *coverage,
+	    const char *style_name, int *retcode)
+{
+/* testing a FeatureType Style (LineSymbolizers) */
+    rl2FeatureTypeStylePtr style;
+    rl2VectorSymbolizerPtr symbolizer;
+    rl2LineSymbolizerPtr line;
+    int intval;
+    int index;
+    double dblval;
+    const char *string;
+    unsigned char red;
+    unsigned char green;
+    unsigned char blue;
+    int scale_forbidden;
+    style =
+	rl2_create_feature_type_style_from_dbms (db_handle, coverage,
+						 style_name);
+    if (style == NULL)
+      {
+	  fprintf (stderr, "Unable to retrieve style '%s'\n", style_name);
+	  *retcode += 1;
+	  return 0;
+      }
+
+    string = rl2_get_feature_type_style_name (style);
+    if (string == NULL)
+      {
+	  fprintf (stderr, "Unable to retrieve style name '%s'\n", style_name);
+	  *retcode += 2;
+	  return 0;
+      }
+    if (strcmp (string, "line_style") != 0)
+      {
+	  fprintf (stderr, "%s: Unexpected style name '%s'\n", style_name,
+		   string);
+	  *retcode += 3;
+	  return 0;
+      }
+
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 1.0, NULL,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s)\n",
+		   style_name);
+	  *retcode += 4;
+	  return 0;
+      }
+
+    if (rl2_get_vector_symbolizer_count (symbolizer, &intval) != RL2_OK)
+      {
+	  fprintf (stderr, "%s: Unable to get Vector Symbolizer Count #2\n",
+		   style_name);
+	  *retcode += 5;
+	  return 0;
+      }
+    if (intval != 2)
+      {
+	  fprintf (stderr, "%s: Unexpected Vector Symbolizer Count #2: %d\n",
+		   style_name, intval);
+	  *retcode += 6;
+	  return 0;
+      }
+
+    if (rl2_get_vector_symbolizer_item_type (symbolizer, 1, &intval) != RL2_OK)
+      {
+	  fprintf (stderr, "%s: Unable to get Vector Symbolizer Item Type #2\n",
+		   style_name);
+	  *retcode += 7;
+	  return 0;
+      }
+    if (intval != RL2_LINE_SYMBOLIZER)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Vector Symbolizer Item Type #2: %d\n",
+		   style_name, intval);
+	  *retcode += 8;
+	  return 0;
+      }
+
+    line = rl2_get_line_symbolizer (symbolizer, 1);
+    if (line == NULL)
+      {
+	  fprintf (stderr, "%s: Unable to get a Line Symbolizer #2\n",
+		   style_name);
+	  *retcode += 9;
+	  return 0;
+      }
+
+    if (rl2_get_text_symbolizer (symbolizer, 0) != NULL)
+      {
+	  fprintf (stderr, "Unexpected success: Text Symbolizer #1\n");
+	  *retcode += 10;
+	  return 0;
+      }
+
+    if (rl2_get_point_symbolizer (symbolizer, 0) != NULL)
+      {
+	  fprintf (stderr, "Unexpected success: Point Symbolizer #1\n");
+	  *retcode += 11;
+	  return 0;
+      }
+
+    if (rl2_get_text_symbolizer (NULL, 0) != NULL)
+      {
+	  fprintf (stderr, "Unexpected success: Text Symbolizer #2\n");
+	  *retcode += 12;
+	  return 0;
+      }
+
+    if (rl2_get_point_symbolizer (NULL, 0) != NULL)
+      {
+	  fprintf (stderr, "Unexpected success: Point Symbolizer #2\n");
+	  *retcode += 13;
+	  return 0;
+      }
+
+    if (rl2_get_vector_symbolizer_count (NULL, &intval) == RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected success: Vector Symbolizer Count #2\n");
+	  *retcode += 14;
+	  return 0;
+      }
+
+    if (rl2_get_vector_symbolizer_item_type (symbolizer, 10, &intval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Vector Symbolizer GetItemType #2\n");
+	  *retcode += 15;
+	  return 0;
+      }
+
+    if (rl2_get_vector_symbolizer_item_type (NULL, 0, &intval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Vector Symbolizer GetItemType #3\n");
+	  *retcode += 16;
+	  return 0;
+      }
+
+    if (rl2_line_symbolizer_has_stroke (NULL, &intval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Line Symbolizer HasStroke #2\n");
+	  *retcode += 17;
+	  return 0;
+      }
+
+    if (rl2_line_symbolizer_has_graphic_stroke (NULL, &intval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Line Symbolizer HasGraphicStroke #2\n");
+	  *retcode += 18;
+	  return 0;
+      }
+
+    if (rl2_line_symbolizer_get_graphic_stroke_href (NULL) != NULL)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Line Symbolizer GetGraphicStrokeHref #2\n");
+	  *retcode += 19;
+	  return 0;
+      }
+
+    if (rl2_line_symbolizer_get_graphic_stroke_recode_count (NULL, &intval) ==
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Line Symbolizer GetGraphicStrokeRecodeCount #2\n");
+	  *retcode += 20;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_get_graphic_stroke_recode_color (NULL, 0,
+								&index, &red,
+								&green,
+								&blue) ==
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Line Symbolizer GetGraphicStrokeRecodeColor #2\n");
+	  *retcode += 21;
+	  return 0;
+      }
+
+    if (rl2_line_symbolizer_get_stroke_color (NULL, &red, &green, &blue) ==
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Line Symbolizer GetStrokeColor #2\n");
+	  *retcode += 22;
+	  return 0;
+      }
+
+    if (rl2_line_symbolizer_get_stroke_opacity (NULL, &dblval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Line Symbolizer GetStrokeOpacity #2\n");
+	  *retcode += 23;
+	  return 0;
+      }
+
+    if (rl2_line_symbolizer_get_stroke_width (NULL, &dblval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Line Symbolizer GetStrokeWidth #2\n");
+	  *retcode += 24;
+	  return 0;
+      }
+
+    if (rl2_line_symbolizer_get_stroke_linejoin (NULL, &red) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Line Symbolizer GetStrokeLinejoin #2\n");
+	  *retcode += 25;
+	  return 0;
+      }
+
+    if (rl2_line_symbolizer_get_stroke_linecap (NULL, &red) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Line Symbolizer GetStrokeLinecap #2\n");
+	  *retcode += 26;
+	  return 0;
+      }
+
+    if (rl2_line_symbolizer_get_stroke_dash_count (NULL, &intval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Line Symbolizer GetStrokeDashCount #2\n");
+	  *retcode += 27;
+	  return 0;
+      }
+
+    if (rl2_line_symbolizer_get_stroke_dash_item (NULL, 0, &dblval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Line Symbolizer GetStrokeDashItem #2\n");
+	  *retcode += 28;
+	  return 0;
+      }
+
+    if (rl2_line_symbolizer_get_stroke_dash_offset (NULL, &dblval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Line Symbolizer GetStrokeDashOffset #2\n");
+	  *retcode += 29;
+	  return 0;
+      }
+
+    if (rl2_line_symbolizer_get_perpendicular_offset (NULL, &dblval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Line Symbolizer GetPerpendicularOffset #2\n");
+	  *retcode += 30;
+	  return 0;
+      }
+
+    rl2_destroy_feature_type_style (style);
+    return 1;
+}
+
+static int
+test_filter (sqlite3 * db_handle, const char *coverage,
+	     const char *style_name, int *retcode)
+{
+/* testing Filter from a FeatureType Style (LineSymbolizers) */
+    rl2FeatureTypeStylePtr style;
+    rl2VectorSymbolizerPtr symbolizer;
+    rl2LineSymbolizerPtr line;
+    rl2VariantArrayPtr value;
+    int intval;
+    const char *string;
+    unsigned char red;
+    unsigned char green;
+    unsigned char blue;
+    int scale_forbidden;
+    unsigned char blob[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
+    style =
+	rl2_create_feature_type_style_from_dbms (db_handle, coverage,
+						 style_name);
+    if (style == NULL)
+      {
+	  fprintf (stderr, "Unable to retrieve style '%s'\n", style_name);
+	  *retcode += 1;
+	  return 0;
+      }
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #1\n");
+	  *retcode += 2;
+	  return 0;
+      }
+    if (rl2_set_variant_double (value, 0, "some_column", 6000000000.4) !=
+	RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #1\n");
+	  *retcode += 3;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #3\n",
+		   style_name);
+	  *retcode += 4;
+	  return 0;
+      }
+    line = rl2_get_line_symbolizer (symbolizer, 0);
+    if (line == NULL)
+      {
+	  fprintf (stderr, "Unable to get Line Symbolizer #2\n");
+	  *retcode += 5;
+	  return 0;
+      }
+    if (rl2_line_symbolizer_get_stroke_color (line, &red, &green, &blue) !=
+	RL2_OK)
+      {
+	  fprintf (stderr, "Unable to get Line Symbolizer GetStrokeColor #2\n");
+	  *retcode += 6;
+	  return 0;
+      }
+    if (red != 0x01 || green != 0xff || blue != 0x02)
+      {
+	  fprintf (stderr,
+		   "Unexpected Line Symbolizer GetStrokeColor #2: %02x%02x%02x\n",
+		   red, green, blue);
+	  *retcode += 7;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #2\n");
+	  *retcode += 8;
+	  return 0;
+      }
+    if (rl2_set_variant_double (value, 0, "some_column", 4.4) != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #2\n");
+	  *retcode += 9;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #4\n",
+		   style_name);
+	  *retcode += 10;
+	  return 0;
+      }
+    line = rl2_get_line_symbolizer (symbolizer, 0);
+    if (line == NULL)
+      {
+	  fprintf (stderr, "Unable to get Line Symbolizer #3\n");
+	  *retcode += 11;
+	  return 0;
+      }
+    if (rl2_line_symbolizer_get_stroke_color (line, &red, &green, &blue) !=
+	RL2_OK)
+      {
+	  fprintf (stderr, "Unable to get Line Symbolizer GetStrokeColor #3\n");
+	  *retcode += 12;
+	  return 0;
+      }
+    if (red != 0xff || green != 0x01 || blue != 0x20)
+      {
+	  fprintf (stderr,
+		   "Unexpected Line Symbolizer GetStrokeColor #3: %02x%02x%02x\n",
+		   red, green, blue);
+	  *retcode += 13;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #3\n");
+	  *retcode += 14;
+	  return 0;
+      }
+    if (rl2_set_variant_blob (value, 0, "some_column", blob, 8) != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #3\n");
+	  *retcode += 15;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #5\n",
+		   style_name);
+	  *retcode += 16;
+	  return 0;
+      }
+    line = rl2_get_line_symbolizer (symbolizer, 0);
+    if (line == NULL)
+      {
+	  fprintf (stderr, "Unable to get Line Symbolizer #4\n");
+	  *retcode += 17;
+	  return 0;
+      }
+    if (rl2_line_symbolizer_get_stroke_color (line, &red, &green, &blue) !=
+	RL2_OK)
+      {
+	  fprintf (stderr, "Unable to get Line Symbolizer GetStrokeColor #4\n");
+	  *retcode += 18;
+	  return 0;
+      }
+    if (red != 0x80 || green != 0x80 || blue != 0x80)
+      {
+	  fprintf (stderr,
+		   "Unexpected Line Symbolizer GetStrokeColor #4: %02x%02x%02x\n",
+		   red, green, blue);
+	  *retcode += 19;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #4\n");
+	  *retcode += 20;
+	  return 0;
+      }
+    if (rl2_set_variant_int (value, 0, "some_column", 6000000000) != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #4\n");
+	  *retcode += 21;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #6\n",
+		   style_name);
+	  *retcode += 22;
+	  return 0;
+      }
+    line = rl2_get_line_symbolizer (symbolizer, 0);
+    if (line == NULL)
+      {
+	  fprintf (stderr, "Unable to get Line Symbolizer #5\n");
+	  *retcode += 23;
+	  return 0;
+      }
+    if (rl2_line_symbolizer_get_stroke_color (line, &red, &green, &blue) !=
+	RL2_OK)
+      {
+	  fprintf (stderr, "Unable to get Line Symbolizer GetStrokeColor #5\n");
+	  *retcode += 24;
+	  return 0;
+      }
+    if (red != 0x01 || green != 0xff || blue != 0x02)
+      {
+	  fprintf (stderr,
+		   "Unexpected Line Symbolizer GetStrokeColor #5: %02x%02x%02x\n",
+		   red, green, blue);
+	  *retcode += 25;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #5\n");
+	  *retcode += 26;
+	  return 0;
+      }
+    if (rl2_set_variant_int (value, 0, "some_column", 2) != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #5\n");
+	  *retcode += 27;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #7\n",
+		   style_name);
+	  *retcode += 28;
+	  return 0;
+      }
+    line = rl2_get_line_symbolizer (symbolizer, 0);
+    if (line == NULL)
+      {
+	  fprintf (stderr, "Unable to get Line Symbolizer #6\n");
+	  *retcode += 29;
+	  return 0;
+      }
+    if (rl2_line_symbolizer_get_stroke_color (line, &red, &green, &blue) !=
+	RL2_OK)
+      {
+	  fprintf (stderr, "Unable to get Line Symbolizer GetStrokeColor #6\n");
+	  *retcode += 30;
+	  return 0;
+      }
+    if (red != 0x12 || green != 0x34 || blue != 0x56)
+      {
+	  fprintf (stderr,
+		   "Unexpected Line Symbolizer GetStrokeColor #6: %02x%02x%02x\n",
+		   red, green, blue);
+	  *retcode += 31;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #6\n");
+	  *retcode += 32;
+	  return 0;
+      }
+    if (rl2_set_variant_double (value, 0, "some_column", 2.5) != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #6\n");
+	  *retcode += 33;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #8\n",
+		   style_name);
+	  *retcode += 34;
+	  return 0;
+      }
+    line = rl2_get_line_symbolizer (symbolizer, 0);
+    if (line == NULL)
+      {
+	  fprintf (stderr, "Unable to get Line Symbolizer #7\n");
+	  *retcode += 35;
+	  return 0;
+      }
+    if (rl2_line_symbolizer_get_stroke_color (line, &red, &green, &blue) !=
+	RL2_OK)
+      {
+	  fprintf (stderr, "Unable to get Line Symbolizer GetStrokeColor #7\n");
+	  *retcode += 37;
+	  return 0;
+      }
+    if (red != 0x12 || green != 0x34 || blue != 0x56)
+      {
+	  fprintf (stderr,
+		   "Unexpected Line Symbolizer GetStrokeColor #7: %02x%02x%02x\n",
+		   red, green, blue);
+	  *retcode += 38;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #6\n");
+	  *retcode += 38;
+	  return 0;
+      }
+    string = "0 walhalla";
+    if (rl2_set_variant_text (value, 0, "some_column", string, strlen (string))
+	!= RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #6\n");
+	  *retcode += 39;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #9\n",
+		   style_name);
+	  *retcode += 40;
+	  return 0;
+      }
+    line = rl2_get_line_symbolizer (symbolizer, 0);
+    if (line == NULL)
+      {
+	  fprintf (stderr, "Unable to get Line Symbolizer #8\n");
+	  *retcode += 41;
+	  return 0;
+      }
+    if (rl2_line_symbolizer_get_stroke_color (line, &red, &green, &blue) !=
+	RL2_OK)
+      {
+	  fprintf (stderr, "Unable to get Line Symbolizer GetStrokeColor #8\n");
+	  *retcode += 42;
+	  return 0;
+      }
+    if (red != 0x12 || green != 0x34 || blue != 0x56)
+      {
+	  fprintf (stderr,
+		   "Unexpected Line Symbolizer GetStrokeColor #8: %02x%02x%02x\n",
+		   red, green, blue);
+	  *retcode += 43;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #7\n");
+	  *retcode += 44;
+	  return 0;
+      }
+    string = "100200300";
+    if (rl2_set_variant_text (value, 0, "some_column", string, strlen (string))
+	!= RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #7\n");
+	  *retcode += 45;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #10\n",
+		   style_name);
+	  *retcode += 46;
+	  return 0;
+      }
+    line = rl2_get_line_symbolizer (symbolizer, 0);
+    if (line == NULL)
+      {
+	  fprintf (stderr, "Unable to get Line Symbolizer #9\n");
+	  *retcode += 47;
+	  return 0;
+      }
+    if (rl2_line_symbolizer_get_stroke_color (line, &red, &green, &blue) !=
+	RL2_OK)
+      {
+	  fprintf (stderr, "Unable to get Line Symbolizer GetStrokeColor #9\n");
+	  *retcode += 48;
+	  return 0;
+      }
+    if (red != 0x80 || green != 0x80 || blue != 0x80)
+      {
+	  fprintf (stderr,
+		   "Unexpected Line Symbolizer GetStrokeColor #9: %02x%02x%02x\n",
+		   red, green, blue);
+	  *retcode += 49;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #8\n");
+	  *retcode += 50;
+	  return 0;
+      }
+    if (rl2_set_variant_int (value, 0, "some_column", 100200300) != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #8\n");
+	  *retcode += 51;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #11\n",
+		   style_name);
+	  *retcode += 52;
+	  return 0;
+      }
+    line = rl2_get_line_symbolizer (symbolizer, 0);
+    if (line == NULL)
+      {
+	  fprintf (stderr, "Unable to get Line Symbolizer #10\n");
+	  *retcode += 53;
+	  return 0;
+      }
+    if (rl2_line_symbolizer_get_stroke_color (line, &red, &green, &blue) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unable to get Line Symbolizer GetStrokeColor #10\n");
+	  *retcode += 54;
+	  return 0;
+      }
+    if (red != 0x80 || green != 0x80 || blue != 0x80)
+      {
+	  fprintf (stderr,
+		   "Unexpected Line Symbolizer GetStrokeColor #10: %02x%02x%02x\n",
+		   red, green, blue);
+	  *retcode += 55;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #9\n");
+	  *retcode += 56;
+	  return 0;
+      }
+    if (rl2_set_variant_double (value, 0, "some_column", 100200300.0) != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #9\n");
+	  *retcode += 57;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #12\n",
+		   style_name);
+	  *retcode += 58;
+	  return 0;
+      }
+    line = rl2_get_line_symbolizer (symbolizer, 0);
+    if (line == NULL)
+      {
+	  fprintf (stderr, "Unable to get Line Symbolizer #11\n");
+	  *retcode += 59;
+	  return 0;
+      }
+    if (rl2_line_symbolizer_get_stroke_color (line, &red, &green, &blue) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unable to get Line Symbolizer GetStrokeColor #11\n");
+	  *retcode += 60;
+	  return 0;
+      }
+    if (red != 0x80 || green != 0x80 || blue != 0x80)
+      {
+	  fprintf (stderr,
+		   "Unexpected Line Symbolizer GetStrokeColor #11: %02x%02x%02x\n",
+		   red, green, blue);
+	  *retcode += 61;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #10\n");
+	  *retcode += 62;
+	  return 0;
+      }
+    string = "TOSCANA";
+    if (rl2_set_variant_text (value, 0, "name", string, strlen (string)) !=
+	RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #10\n");
+	  *retcode += 63;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #13\n",
+		   style_name);
+	  *retcode += 64;
+	  return 0;
+      }
+    line = rl2_get_line_symbolizer (symbolizer, 0);
+    if (line == NULL)
+      {
+	  fprintf (stderr, "Unable to get Line Symbolizer #12\n");
+	  *retcode += 65;
+	  return 0;
+      }
+    if (rl2_line_symbolizer_get_stroke_color (line, &red, &green, &blue) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unable to get Line Symbolizer GetStrokeColor #12\n");
+	  *retcode += 66;
+	  return 0;
+      }
+    if (red != 0xff || green != 0xa0 || blue != 0x80)
+      {
+	  fprintf (stderr,
+		   "Unexpected Line Symbolizer GetStrokeColor #12: %02x%02x%02x\n",
+		   red, green, blue);
+	  *retcode += 67;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    intval = rl2_get_feature_type_style_columns_count (style);
+    if (intval != 2)
+      {
+	  fprintf (stderr,
+		   "Unexpected GetFeatureTypeStyleColumnsCount #1: %d\n",
+		   intval);
+	  *retcode += 68;
+	  return 0;
+      }
+
+    string = rl2_get_feature_type_style_column_name (style, 0);
+    if (strcasecmp (string, "name") != 0)
+      {
+	  fprintf (stderr,
+		   "Unexpected GetFeatureTypeStyleColumnName #1: \"%s\"\n",
+		   string);
+	  *retcode += 69;
+	  return 0;
+      }
+
+    string = rl2_get_feature_type_style_column_name (style, 1);
+    if (strcasecmp (string, "some_column") != 0)
+      {
+	  fprintf (stderr,
+		   "Unexpected GetFeatureTypeStyleColumnName #2: \"%s\"\n",
+		   string);
+	  *retcode += 70;
+	  return 0;
+      }
+
+    rl2_destroy_feature_type_style (style);
+    return 1;
+}
+
+int
+main (int argc, char *argv[])
+{
+    int result = 0;
+    int ret;
+    sqlite3 *db_handle;
+    void *cache = spatialite_alloc_connection ();
+
+    if (argc > 1 || argv[0] == NULL)
+	argc = 1;		/* silencing stupid compiler warnings */
+
+/* opening and initializing the "memory" test DB */
+    ret = sqlite3_open_v2 ("symbolizers.sqlite", &db_handle,
+			   SQLITE_OPEN_READONLY, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "sqlite3_open_v2() error: %s\n",
+		   sqlite3_errmsg (db_handle));
+	  return -1;
+      }
+    spatialite_init_ex (db_handle, cache, 0);
+
+/* tests */
+    ret = -100;
+    if (!test_symbolizer (db_handle, "line1", "line_1", &ret))
+	return ret;
+    ret = -200;
+    if (!test_symbolizer (db_handle, "line2", "line_2", &ret))
+	return ret;
+    ret = -300;
+    if (!test_symbolizer (db_handle, "line2", "line_3", &ret))
+	return ret;
+    ret = -400;
+    if (!test_style (db_handle, "line1", "line_style", &ret))
+	return ret;
+    ret = -500;
+    if (!test_filter (db_handle, "line1", "line_style", &ret))
+	return ret;
+
+/* closing the DB */
+    sqlite3_close (db_handle);
+    spatialite_shutdown ();
+    return result;
+}
diff --git a/test/test_load_wms.c b/test/test_load_wms.c
index c727278..9a45b8b 100644
--- a/test/test_load_wms.c
+++ b/test/test_load_wms.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -212,11 +212,20 @@ main (int argc, char *argv[])
     char *sql;
     gaiaGeomCollPtr geom;
     void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
     char *old_SPATIALITE_SECURITY_ENV = NULL;
 
     if (argc > 1 || argv[0] == NULL)
 	argc = 1;		/* silencing stupid compiler warnings */
 
+    if (getenv ("ENABLE_RL2_WEB_TESTS") == NULL)
+      {
+	  fprintf (stderr, "this testcase has been skipped !!!\n\n"
+		   "you can enable all testcases requiring an Internet connection\n"
+		   "by setting the environment variable \"ENABLE_RL2_WEB_TESTS=1\"\n");
+	  return 0;
+      }
+
     old_SPATIALITE_SECURITY_ENV = getenv ("SPATIALITE_SECURITY");
 #ifdef _WIN32
     putenv ("SPATIALITE_SECURITY=relaxed");
@@ -234,7 +243,7 @@ main (int argc, char *argv[])
 	  return -1;
       }
     spatialite_init_ex (db_handle, cache, 0);
-    rl2_init (db_handle, 0);
+    rl2_init (db_handle, priv_data, 0);
     ret =
 	sqlite3_exec (db_handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
 		      &err_msg);
@@ -255,7 +264,7 @@ main (int argc, char *argv[])
       }
 
 /* creating an RGB DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_CreateCoverage("
+    sql = sqlite3_mprintf ("SELECT RL2_CreateRasterCoverage("
 			   "%Q, %Q, %Q, %d, %Q, %d, %d, %d, %d, %1.2f)",
 			   "rgb10k", "UINT8", "RGB", 3, "JPEG", 80,
 			   512, 512, 3003, 0.5);
@@ -263,14 +272,14 @@ main (int argc, char *argv[])
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "CreateCoverage \"%s\" error: %s\n", "rgb10k",
+	  fprintf (stderr, "CreateRasterCoverage \"%s\" error: %s\n", "rgb10k",
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  return -4;
       }
 
 /* creating a Grayscale DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_CreateCoverage("
+    sql = sqlite3_mprintf ("SELECT RL2_CreateRasterCoverage("
 			   "%Q, %Q, %Q, %d, %Q, %d, %d, %d, %d, %1.2f)",
 			   "gray10k", "UINT8", "GRAYSCALE", 1, "JPEG", 80,
 			   512, 512, 3003, 1.0);
@@ -278,14 +287,14 @@ main (int argc, char *argv[])
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "CreateCoverage \"%s\" error: %s\n", "gray10k",
+	  fprintf (stderr, "CreateRasterCoverage \"%s\" error: %s\n", "gray10k",
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  return -5;
       }
 
 /* creating a Monochrome DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_CreateCoverage("
+    sql = sqlite3_mprintf ("SELECT RL2_CreateRasterCoverage("
 			   "%Q, %Q, %Q, %d, %Q, %d, %d, %d, %d, %1.2f, %1.2f, "
 			   "RL2_SetPixelValue(RL2_CreatePixel(%Q, %Q, 1), 0, 0))",
 			   "ctrt10k", "1-BIT", "MONOCHROME", 1, "FAX4", 100,
@@ -294,7 +303,7 @@ main (int argc, char *argv[])
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "CreateCoverage \"%s\" error: %s\n", "ctrt10k",
+	  fprintf (stderr, "CreateRasterCoverage \"%s\" error: %s\n", "ctrt10k",
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  return -6;
@@ -353,9 +362,7 @@ main (int argc, char *argv[])
 	  sqlite3_free (err_msg);
 	  return -9;
       }
-    sql =
-	sqlite3_mprintf
-	("SELECT RL2_Pyramidize(%Q, %Q, 1, 1)", "ctrt10k", "firenze");
+    sql = sqlite3_mprintf ("SELECT RL2_Pyramidize(%Q, 1, 1, 1)", "ctrt10k");
     ret = execute_check (db_handle, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -405,6 +412,8 @@ main (int argc, char *argv[])
 
 /* closing the DB */
     sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
     spatialite_shutdown ();
     if (old_SPATIALITE_SECURITY_ENV)
       {
diff --git a/test/test_map_ascii.c b/test/test_map_ascii.c
index 8198234..29bc3b1 100644
--- a/test/test_map_ascii.c
+++ b/test/test_map_ascii.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -46,6 +46,8 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include <stdio.h>
 #include <string.h>
 
+#include "config.h"
+
 #include "sqlite3.h"
 #include "spatialite.h"
 
@@ -54,6 +56,9 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #define TILE_256	256
 #define TILE_1024	1024
 
+/* global variable used to alternatively enable/disable multithreading */
+int multithreading = 1;
+
 static int
 execute_check (sqlite3 * sqlite, const char *sql)
 {
@@ -122,6 +127,52 @@ do_export_ascii (sqlite3 * sqlite, const char *coverage, gaiaGeomCollPtr geom,
     return retcode;
 }
 
+static int
+do_export_section_ascii (sqlite3 * sqlite, const char *coverage,
+			 gaiaGeomCollPtr geom, int scale)
+{
+/* exporting an ASCII Grid */
+    char *sql;
+    char *path;
+    sqlite3_stmt *stmt;
+    int ret;
+    unsigned char *blob;
+    int blob_size;
+    int retcode = 0;
+    double res = 1.0 * (double) scale;
+
+    path = sqlite3_mprintf ("./%s_sect1_%d.asc", coverage, scale);
+
+    sql = "SELECT RL2_WriteSectionAsciiGrid(?, ?, ?, ?, ?, ?, ?, ?, ?)";
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return 0;
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
+    sqlite3_bind_int (stmt, 2, 1);
+    sqlite3_bind_text (stmt, 3, path, strlen (path), SQLITE_STATIC);
+    sqlite3_bind_int (stmt, 4, 1024);
+    sqlite3_bind_int (stmt, 5, 1024);
+    gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
+    sqlite3_bind_blob (stmt, 6, blob, blob_size, free);
+    sqlite3_bind_double (stmt, 7, res);
+    sqlite3_bind_int (stmt, 8, 1);
+    sqlite3_bind_int (stmt, 9, 2);
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+      {
+	  if (sqlite3_column_int (stmt, 0) == 1)
+	      retcode = 1;
+      }
+    sqlite3_finalize (stmt);
+    unlink (path);
+    if (!retcode)
+	fprintf (stderr, "ERROR: unable to export \"%s\"\n", path);
+    sqlite3_free (path);
+    return retcode;
+}
+
 static gaiaGeomCollPtr
 get_center_point (sqlite3 * sqlite, const char *coverage)
 {
@@ -353,14 +404,14 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 /* testing some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
-    const char *sample_name;
-    const char *pixel_name;
-    unsigned char num_bands;
-    const char *compression_name;
+    const char *coverage = NULL;
+    const char *sample_name = NULL;
+    const char *pixel_name = NULL;
+    unsigned char num_bands = 1;
+    const char *compression_name = NULL;
     int qlty;
     char *sql;
-    int tile_size;
+    int tile_size = 256;
     gaiaGeomCollPtr geom;
 
 /* setting the coverage name */
@@ -380,7 +431,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_DEFLATE:
+	    case RL2_COMPRESSION_DEFLATE_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -391,7 +442,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_LZMA:
+	    case RL2_COMPRESSION_LZMA_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -418,7 +469,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_DEFLATE:
+	    case RL2_COMPRESSION_DEFLATE_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -429,7 +480,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_LZMA:
+	    case RL2_COMPRESSION_LZMA_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -456,7 +507,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_DEFLATE:
+	    case RL2_COMPRESSION_DEFLATE_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -467,7 +518,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_LZMA:
+	    case RL2_COMPRESSION_LZMA_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -494,7 +545,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_DEFLATE:
+	    case RL2_COMPRESSION_DEFLATE_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -505,7 +556,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_LZMA:
+	    case RL2_COMPRESSION_LZMA_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -532,7 +583,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_DEFLATE:
+	    case RL2_COMPRESSION_DEFLATE_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -543,7 +594,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_LZMA:
+	    case RL2_COMPRESSION_LZMA_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -570,7 +621,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_DEFLATE:
+	    case RL2_COMPRESSION_DEFLATE_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -581,7 +632,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_LZMA:
+	    case RL2_COMPRESSION_LZMA_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -608,7 +659,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_DEFLATE:
+	    case RL2_COMPRESSION_DEFLATE_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -619,7 +670,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_LZMA:
+	    case RL2_COMPRESSION_LZMA_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -646,7 +697,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_DEFLATE:
+	    case RL2_COMPRESSION_DEFLATE_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -657,7 +708,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_LZMA:
+	    case RL2_COMPRESSION_LZMA_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -708,12 +759,12 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 	  compression_name = "NONE";
 	  qlty = 100;
 	  break;
-      case RL2_COMPRESSION_DEFLATE:
-	  compression_name = "DEFLATE";
+      case RL2_COMPRESSION_DEFLATE_NO:
+	  compression_name = "DEFLATE_NO";
 	  qlty = 100;
 	  break;
-      case RL2_COMPRESSION_LZMA:
-	  compression_name = "LZMA";
+      case RL2_COMPRESSION_LZMA_NO:
+	  compression_name = "LZMA_NO";
 	  qlty = 100;
 	  break;
       };
@@ -727,8 +778,21 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 	  break;
       };
 
+/* setting the MultiThreading mode alternatively on/off */
+    if (multithreading)
+      {
+	  sql = "SELECT RL2_SetMaxThreads(2)";
+	  multithreading = 0;
+      }
+    else
+      {
+	  sql = "SELECT RL2_SetMaxThreads(1)";
+	  multithreading = 1;
+      }
+    execute_check (sqlite, sql);
+
 /* creating the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_CreateCoverage("
+    sql = sqlite3_mprintf ("SELECT RL2_CreateRasterCoverage("
 			   "%Q, %Q, %Q, %d, %Q, %d, %d, %d, %d, %1.8f, %1.8f)",
 			   coverage, sample_name, pixel_name, num_bands,
 			   compression_name, qlty, tile_size, tile_size, 3003,
@@ -737,7 +801,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "CreateCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "CreateRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -761,8 +825,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
       }
 
 /* deleting the first section */
-    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, %Q, 1)",
-			   coverage, "ascii1");
+    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, 1, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -814,13 +877,33 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 	  *retcode += -9;
 	  return 0;
       }
+    if (!do_export_section_ascii (sqlite, coverage, geom, 1))
+      {
+	  *retcode += -10;
+	  return 0;
+      }
+    if (!do_export_section_ascii (sqlite, coverage, geom, 2))
+      {
+	  *retcode += -11;
+	  return 0;
+      }
+    if (!do_export_section_ascii (sqlite, coverage, geom, 4))
+      {
+	  *retcode += -12;
+	  return 0;
+      }
+    if (!do_export_section_ascii (sqlite, coverage, geom, 8))
+      {
+	  *retcode += -13;
+	  return 0;
+      }
     gaiaFreeGeomColl (geom);
 
-    *retcode += -10;
+    *retcode += -14;
     if (!test_statistics (sqlite, coverage, retcode))
 	return 0;
 
-    if (compression == RL2_COMPRESSION_DEFLATE)
+    if (compression == RL2_COMPRESSION_DEFLATE_NO)
       {
 	  /* testing a Monolithic Pyramid */
 	  sql =
@@ -833,7 +916,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 		fprintf (stderr, "PyramidizeMonolithic \"%s\" error: %s\n",
 			 coverage, err_msg);
 		sqlite3_free (err_msg);
-		*retcode += -11;
+		*retcode += -15;
 		return 0;
 	    }
       }
@@ -868,7 +951,7 @@ drop_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_DEFLATE:
+	    case RL2_COMPRESSION_DEFLATE_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -879,7 +962,7 @@ drop_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_LZMA:
+	    case RL2_COMPRESSION_LZMA_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -906,7 +989,7 @@ drop_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_DEFLATE:
+	    case RL2_COMPRESSION_DEFLATE_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -917,7 +1000,7 @@ drop_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_LZMA:
+	    case RL2_COMPRESSION_LZMA_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -944,7 +1027,7 @@ drop_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_DEFLATE:
+	    case RL2_COMPRESSION_DEFLATE_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -955,7 +1038,7 @@ drop_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_LZMA:
+	    case RL2_COMPRESSION_LZMA_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -982,7 +1065,7 @@ drop_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_DEFLATE:
+	    case RL2_COMPRESSION_DEFLATE_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -993,7 +1076,7 @@ drop_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_LZMA:
+	    case RL2_COMPRESSION_LZMA_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -1020,7 +1103,7 @@ drop_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_DEFLATE:
+	    case RL2_COMPRESSION_DEFLATE_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -1031,7 +1114,7 @@ drop_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_LZMA:
+	    case RL2_COMPRESSION_LZMA_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -1058,7 +1141,7 @@ drop_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_DEFLATE:
+	    case RL2_COMPRESSION_DEFLATE_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -1069,7 +1152,7 @@ drop_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_LZMA:
+	    case RL2_COMPRESSION_LZMA_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -1096,7 +1179,7 @@ drop_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_DEFLATE:
+	    case RL2_COMPRESSION_DEFLATE_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -1107,7 +1190,7 @@ drop_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_LZMA:
+	    case RL2_COMPRESSION_LZMA_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -1134,7 +1217,7 @@ drop_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_DEFLATE:
+	    case RL2_COMPRESSION_DEFLATE_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -1145,7 +1228,7 @@ drop_coverage (sqlite3 * sqlite, unsigned char sample,
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_LZMA:
+	    case RL2_COMPRESSION_LZMA_NO:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
@@ -1161,12 +1244,12 @@ drop_coverage (sqlite3 * sqlite, unsigned char sample,
       };
 
 /* dropping the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_DropCoverage(%Q, 1)", coverage);
+    sql = sqlite3_mprintf ("SELECT RL2_DropRasterCoverage(%Q, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "DropCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "DropRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -1192,6 +1275,7 @@ main (int argc, char *argv[])
     char *err_msg = NULL;
     sqlite3 *db_handle;
     void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
     char *old_SPATIALITE_SECURITY_ENV = NULL;
 
     if (argc > 1 || argv[0] == NULL)
@@ -1214,7 +1298,7 @@ main (int argc, char *argv[])
 	  return -1;
       }
     spatialite_init_ex (db_handle, cache, 0);
-    rl2_init (db_handle, 0);
+    rl2_init (db_handle, priv_data, 0);
     ret =
 	sqlite3_exec (db_handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
 		      &err_msg);
@@ -1241,7 +1325,8 @@ main (int argc, char *argv[])
 	return ret;
     ret = -120;
     if (!test_coverage
-	(db_handle, RL2_SAMPLE_INT8, RL2_COMPRESSION_DEFLATE, TILE_1024, &ret))
+	(db_handle, RL2_SAMPLE_INT8, RL2_COMPRESSION_DEFLATE_NO, TILE_1024,
+	 &ret))
 	return ret;
     ret = -150;
     if (!test_coverage
@@ -1249,11 +1334,13 @@ main (int argc, char *argv[])
 	return ret;
     ret = -170;
     if (!test_coverage
-	(db_handle, RL2_SAMPLE_UINT8, RL2_COMPRESSION_DEFLATE, TILE_1024, &ret))
+	(db_handle, RL2_SAMPLE_UINT8, RL2_COMPRESSION_DEFLATE_NO, TILE_1024,
+	 &ret))
 	return ret;
     ret = -200;
     if (!test_coverage
-	(db_handle, RL2_SAMPLE_INT16, RL2_COMPRESSION_DEFLATE, TILE_256, &ret))
+	(db_handle, RL2_SAMPLE_INT16, RL2_COMPRESSION_DEFLATE_NO, TILE_256,
+	 &ret))
 	return ret;
     ret = -220;
     if (!test_coverage
@@ -1261,23 +1348,31 @@ main (int argc, char *argv[])
 	return ret;
     ret = -250;
     if (!test_coverage
-	(db_handle, RL2_SAMPLE_UINT16, RL2_COMPRESSION_DEFLATE, TILE_256, &ret))
+	(db_handle, RL2_SAMPLE_UINT16, RL2_COMPRESSION_DEFLATE_NO, TILE_256,
+	 &ret))
 	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
     ret = -270;
     if (!test_coverage
-	(db_handle, RL2_SAMPLE_UINT16, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
+	(db_handle, RL2_SAMPLE_UINT16, RL2_COMPRESSION_LZMA_NO, TILE_1024,
+	 &ret))
 	return ret;
+#endif
+
     ret = -300;
     if (!test_coverage
 	(db_handle, RL2_SAMPLE_INT32, RL2_COMPRESSION_NONE, TILE_256, &ret))
 	return ret;
     ret = -320;
     if (!test_coverage
-	(db_handle, RL2_SAMPLE_INT32, RL2_COMPRESSION_DEFLATE, TILE_1024, &ret))
+	(db_handle, RL2_SAMPLE_INT32, RL2_COMPRESSION_DEFLATE_NO, TILE_1024,
+	 &ret))
 	return ret;
     ret = -350;
     if (!test_coverage
-	(db_handle, RL2_SAMPLE_UINT32, RL2_COMPRESSION_DEFLATE, TILE_256, &ret))
+	(db_handle, RL2_SAMPLE_UINT32, RL2_COMPRESSION_DEFLATE_NO, TILE_256,
+	 &ret))
 	return ret;
     ret = -370;
     if (!test_coverage
@@ -1285,15 +1380,21 @@ main (int argc, char *argv[])
 	return ret;
     ret = -400;
     if (!test_coverage
-	(db_handle, RL2_SAMPLE_FLOAT, RL2_COMPRESSION_DEFLATE, TILE_256, &ret))
+	(db_handle, RL2_SAMPLE_FLOAT, RL2_COMPRESSION_DEFLATE_NO, TILE_256,
+	 &ret))
 	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
     ret = -420;
     if (!test_coverage
-	(db_handle, RL2_SAMPLE_FLOAT, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
+	(db_handle, RL2_SAMPLE_FLOAT, RL2_COMPRESSION_LZMA_NO, TILE_1024, &ret))
 	return ret;
+#endif
+
     ret = -450;
     if (!test_coverage
-	(db_handle, RL2_SAMPLE_DOUBLE, RL2_COMPRESSION_DEFLATE, TILE_256, &ret))
+	(db_handle, RL2_SAMPLE_DOUBLE, RL2_COMPRESSION_DEFLATE_NO, TILE_256,
+	 &ret))
 	return ret;
     ret = -470;
     if (!test_coverage
@@ -1307,7 +1408,8 @@ main (int argc, char *argv[])
 	return ret;
     ret = -130;
     if (!drop_coverage
-	(db_handle, RL2_SAMPLE_INT8, RL2_COMPRESSION_DEFLATE, TILE_1024, &ret))
+	(db_handle, RL2_SAMPLE_INT8, RL2_COMPRESSION_DEFLATE_NO, TILE_1024,
+	 &ret))
 	return ret;
     ret = -160;
     if (!drop_coverage
@@ -1315,11 +1417,13 @@ main (int argc, char *argv[])
 	return ret;
     ret = -180;
     if (!drop_coverage
-	(db_handle, RL2_SAMPLE_UINT8, RL2_COMPRESSION_DEFLATE, TILE_1024, &ret))
+	(db_handle, RL2_SAMPLE_UINT8, RL2_COMPRESSION_DEFLATE_NO, TILE_1024,
+	 &ret))
 	return ret;
     ret = -210;
     if (!drop_coverage
-	(db_handle, RL2_SAMPLE_INT16, RL2_COMPRESSION_DEFLATE, TILE_256, &ret))
+	(db_handle, RL2_SAMPLE_INT16, RL2_COMPRESSION_DEFLATE_NO, TILE_256,
+	 &ret))
 	return ret;
     ret = -230;
     if (!drop_coverage
@@ -1327,23 +1431,31 @@ main (int argc, char *argv[])
 	return ret;
     ret = -260;
     if (!drop_coverage
-	(db_handle, RL2_SAMPLE_UINT16, RL2_COMPRESSION_DEFLATE, TILE_256, &ret))
+	(db_handle, RL2_SAMPLE_UINT16, RL2_COMPRESSION_DEFLATE_NO, TILE_256,
+	 &ret))
 	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
     ret = -280;
     if (!drop_coverage
-	(db_handle, RL2_SAMPLE_UINT16, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
+	(db_handle, RL2_SAMPLE_UINT16, RL2_COMPRESSION_LZMA_NO, TILE_1024,
+	 &ret))
 	return ret;
+#endif
+
     ret = -310;
     if (!drop_coverage
 	(db_handle, RL2_SAMPLE_INT32, RL2_COMPRESSION_NONE, TILE_256, &ret))
 	return ret;
     ret = -330;
     if (!drop_coverage
-	(db_handle, RL2_SAMPLE_INT32, RL2_COMPRESSION_DEFLATE, TILE_1024, &ret))
+	(db_handle, RL2_SAMPLE_INT32, RL2_COMPRESSION_DEFLATE_NO, TILE_1024,
+	 &ret))
 	return ret;
     ret = -360;
     if (!drop_coverage
-	(db_handle, RL2_SAMPLE_UINT32, RL2_COMPRESSION_DEFLATE, TILE_256, &ret))
+	(db_handle, RL2_SAMPLE_UINT32, RL2_COMPRESSION_DEFLATE_NO, TILE_256,
+	 &ret))
 	return ret;
     ret = -380;
     if (!drop_coverage
@@ -1351,15 +1463,21 @@ main (int argc, char *argv[])
 	return ret;
     ret = -410;
     if (!drop_coverage
-	(db_handle, RL2_SAMPLE_FLOAT, RL2_COMPRESSION_DEFLATE, TILE_256, &ret))
+	(db_handle, RL2_SAMPLE_FLOAT, RL2_COMPRESSION_DEFLATE_NO, TILE_256,
+	 &ret))
 	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
     ret = -430;
     if (!drop_coverage
-	(db_handle, RL2_SAMPLE_FLOAT, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
+	(db_handle, RL2_SAMPLE_FLOAT, RL2_COMPRESSION_LZMA_NO, TILE_1024, &ret))
 	return ret;
+#endif
+
     ret = -460;
     if (!drop_coverage
-	(db_handle, RL2_SAMPLE_DOUBLE, RL2_COMPRESSION_DEFLATE, TILE_256, &ret))
+	(db_handle, RL2_SAMPLE_DOUBLE, RL2_COMPRESSION_DEFLATE_NO, TILE_256,
+	 &ret))
 	return ret;
     ret = -480;
     if (!drop_coverage
@@ -1434,9 +1552,12 @@ main (int argc, char *argv[])
 	  return 510;
       }
     rl2_destroy_ascii_grid_destination (ascii);
+    unlink ("test_ascii.asc");
 
 /* closing the DB */
     sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
     spatialite_shutdown ();
     if (old_SPATIALITE_SECURITY_ENV)
       {
diff --git a/test/test_map_gray.c b/test/test_map_gray.c
index 67c81dc..cb6d6dd 100644
--- a/test/test_map_gray.c
+++ b/test/test_map_gray.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -46,6 +46,8 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include <stdio.h>
 #include <string.h>
 
+#include "config.h"
+
 #include "sqlite3.h"
 #include "spatialite.h"
 
@@ -171,6 +173,175 @@ do_export_geotiff (sqlite3 * sqlite, const char *coverage, const char *type,
 }
 
 static int
+do_export_section_geotiff (sqlite3 * sqlite, const char *coverage,
+			   gaiaGeomCollPtr geom, int scale)
+{
+/* exporting a GeoTiff + Worldfile - Section */
+    char *sql;
+    char *path;
+    sqlite3_stmt *stmt;
+    int ret;
+    double x_res;
+    double y_res;
+    double xx_res;
+    double yy_res;
+    unsigned char *blob;
+    int blob_size;
+    int retcode = 0;
+
+    path = sqlite3_mprintf ("./%s_sect_gt_%d.tif", coverage, scale);
+
+    if (!get_base_resolution (sqlite, coverage, &x_res, &y_res))
+	return 0;
+    xx_res = x_res * (double) scale;
+    yy_res = y_res * (double) scale;
+
+    sql = "SELECT RL2_WriteSectionGeoTiff(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return 0;
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
+    sqlite3_bind_int64 (stmt, 2, 1);
+    sqlite3_bind_text (stmt, 3, path, strlen (path), SQLITE_STATIC);
+    sqlite3_bind_int (stmt, 4, 1024);
+    sqlite3_bind_int (stmt, 5, 1024);
+    gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
+    sqlite3_bind_blob (stmt, 6, blob, blob_size, free);
+    sqlite3_bind_double (stmt, 7, xx_res);
+    sqlite3_bind_double (stmt, 8, yy_res);
+    sqlite3_bind_int (stmt, 9, 1);
+    sqlite3_bind_text (stmt, 10, "NONE", 4, SQLITE_TRANSIENT);
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+      {
+	  if (sqlite3_column_int (stmt, 0) == 1)
+	      retcode = 1;
+      }
+    sqlite3_finalize (stmt);
+    unlink (path);
+    if (!retcode)
+	fprintf (stderr, "ERROR: unable to export \"%s\"\n", path);
+    sqlite3_free (path);
+    path = sqlite3_mprintf ("./%s_sect_gt_%d.tfw", coverage, scale);
+    unlink (path);
+    sqlite3_free (path);
+    return retcode;
+}
+
+static int
+do_export_section_tiff (sqlite3 * sqlite, const char *coverage,
+			gaiaGeomCollPtr geom, int scale)
+{
+/* exporting a plain Tiff - Section */
+    char *sql;
+    char *path;
+    sqlite3_stmt *stmt;
+    int ret;
+    double x_res;
+    double y_res;
+    double xx_res;
+    double yy_res;
+    unsigned char *blob;
+    int blob_size;
+    int retcode = 0;
+
+    path = sqlite3_mprintf ("./%s_sect_tif_%d.tif", coverage, scale);
+
+    if (!get_base_resolution (sqlite, coverage, &x_res, &y_res))
+	return 0;
+    xx_res = x_res * (double) scale;
+    yy_res = y_res * (double) scale;
+
+    sql = "SELECT RL2_WriteSectionTiff(?, ?, ?, ?, ?, ?, ?, ?, ?)";
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return 0;
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
+    sqlite3_bind_int64 (stmt, 2, 1);
+    sqlite3_bind_text (stmt, 3, path, strlen (path), SQLITE_STATIC);
+    sqlite3_bind_int (stmt, 4, 1024);
+    sqlite3_bind_int (stmt, 5, 1024);
+    gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
+    sqlite3_bind_blob (stmt, 6, blob, blob_size, free);
+    sqlite3_bind_double (stmt, 7, xx_res);
+    sqlite3_bind_double (stmt, 8, yy_res);
+    sqlite3_bind_text (stmt, 9, "NONE", 4, SQLITE_TRANSIENT);
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+      {
+	  if (sqlite3_column_int (stmt, 0) == 1)
+	      retcode = 1;
+      }
+    sqlite3_finalize (stmt);
+    unlink (path);
+    if (!retcode)
+	fprintf (stderr, "ERROR: unable to export \"%s\"\n", path);
+    sqlite3_free (path);
+    return retcode;
+}
+
+static int
+do_export_section_tiff_tfw (sqlite3 * sqlite, const char *coverage,
+			    gaiaGeomCollPtr geom, int scale)
+{
+/* exporting a Tiff + Worldfile - Section */
+    char *sql;
+    char *path;
+    sqlite3_stmt *stmt;
+    int ret;
+    double x_res;
+    double y_res;
+    double xx_res;
+    double yy_res;
+    unsigned char *blob;
+    int blob_size;
+    int retcode = 0;
+
+    path = sqlite3_mprintf ("./%s_sect_tfw_%d.tif", coverage, scale);
+
+    if (!get_base_resolution (sqlite, coverage, &x_res, &y_res))
+	return 0;
+    xx_res = x_res * (double) scale;
+    yy_res = y_res * (double) scale;
+
+    sql = "SELECT RL2_WriteSectionTiffTfw(?, ?, ?, ?, ?, ?, ?, ?, ?)";
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return 0;
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
+    sqlite3_bind_int64 (stmt, 2, 1);
+    sqlite3_bind_text (stmt, 3, path, strlen (path), SQLITE_STATIC);
+    sqlite3_bind_int (stmt, 4, 1024);
+    sqlite3_bind_int (stmt, 5, 1024);
+    gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
+    sqlite3_bind_blob (stmt, 6, blob, blob_size, free);
+    sqlite3_bind_double (stmt, 7, xx_res);
+    sqlite3_bind_double (stmt, 8, yy_res);
+    sqlite3_bind_text (stmt, 9, "NONE", 4, SQLITE_TRANSIENT);
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+      {
+	  if (sqlite3_column_int (stmt, 0) == 1)
+	      retcode = 1;
+      }
+    sqlite3_finalize (stmt);
+    unlink (path);
+    if (!retcode)
+	fprintf (stderr, "ERROR: unable to export \"%s\"\n", path);
+    sqlite3_free (path);
+    path = sqlite3_mprintf ("./%s_sect_tfw_%d.tfw", coverage, scale);
+    unlink (path);
+    sqlite3_free (path);
+    return retcode;
+}
+
+static int
 do_export_tiff (sqlite3 * sqlite, const char *coverage, gaiaGeomCollPtr geom,
 		int scale)
 {
@@ -276,7 +447,7 @@ do_export_image (sqlite3 * sqlite, const char *coverage, gaiaGeomCollPtr geom,
     path = sqlite3_mprintf ("./%s_%1.0f%s", coverage, radius, suffix);
 
     sql =
-	"SELECT RL2_GetMapImage(?, ST_Buffer(?, ?), 512, 512, 'default', ?, '#ffffff', 0, 80)";
+	"SELECT RL2_GetMapImageFromRaster(?, ST_Buffer(?, ?), 512, 512, 'default', ?, '#ffffff', 0, 80)";
     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
 	return 0;
@@ -329,14 +500,14 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
 /* testing some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
-    const char *sample_name;
-    const char *pixel_name;
-    unsigned char num_bands;
-    const char *compression_name;
-    int qlty;
+    const char *coverage = NULL;
+    const char *sample_name = NULL;
+    const char *pixel_name = NULL;
+    unsigned char num_bands = 1;
+    const char *compression_name = NULL;
+    int qlty = 100;
     char *sql;
-    int tile_size;
+    int tile_size = 256;
     gaiaGeomCollPtr geom;
 
 /* setting the coverage name */
@@ -501,7 +672,7 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
       };
 
 /* creating the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_CreateCoverage("
+    sql = sqlite3_mprintf ("SELECT RL2_CreateRasterCoverage("
 			   "%Q, %Q, %Q, %d, %Q, %d, %d, %d, %d, %d, %d)",
 			   coverage, sample_name, pixel_name, num_bands,
 			   compression_name, qlty, tile_size, tile_size, 26914,
@@ -510,7 +681,7 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "CreateCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "CreateRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -552,8 +723,7 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
       }
 
 /* deleting the first section */
-    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, %Q, 1)",
-			   coverage, "gray1");
+    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, 1, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -582,8 +752,7 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
       {
 /* building the Pyramid Levels */
 	  sql =
-	      sqlite3_mprintf ("SELECT RL2_Pyramidize(%Q, %Q, 1, 1)", coverage,
-			       "gray2");
+	      sqlite3_mprintf ("SELECT RL2_Pyramidize(%Q, 2, 1, 1)", coverage);
 	  ret = execute_check (sqlite, sql);
 	  sqlite3_free (sql);
 	  if (ret != SQLITE_OK)
@@ -612,8 +781,7 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
 
 /* building yet again the Pyramid Levels */
 	  sql =
-	      sqlite3_mprintf ("SELECT RL2_Pyramidize(%Q, %Q, 1, 1)", coverage,
-			       "gray2");
+	      sqlite3_mprintf ("SELECT RL2_Pyramidize(%Q, 2, 1, 1)", coverage);
 	  ret = execute_check (sqlite, sql);
 	  sqlite3_free (sql);
 	  if (ret != SQLITE_OK)
@@ -673,6 +841,7 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
 	  *retcode += -17;
 	  return 0;
       }
+    fprintf (stderr, "*************************************** 3\n");
     if (!do_export_image (sqlite, coverage, geom, 256.0, ".jpg"))
       {
 	  *retcode += -18;
@@ -713,6 +882,7 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
 	  *retcode += -25;
 	  return 0;
       }
+    fprintf (stderr, "*************************************** 4\n");
 
 
     if (strcmp (coverage, "gray_jpeg_512") == 0)
@@ -759,6 +929,66 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
 		return 0;
 	    }
       }
+    if (!do_export_section_geotiff (sqlite, coverage, geom, 1))
+      {
+	  *retcode += -32;
+	  return 0;
+      }
+    if (!do_export_section_geotiff (sqlite, coverage, geom, 2))
+      {
+	  *retcode += -33;
+	  return 0;
+      }
+    if (!do_export_section_geotiff (sqlite, coverage, geom, 4))
+      {
+	  *retcode += -34;
+	  return 0;
+      }
+    if (!do_export_section_geotiff (sqlite, coverage, geom, 8))
+      {
+	  *retcode += -35;
+	  return 0;
+      }
+    if (!do_export_section_tiff (sqlite, coverage, geom, 1))
+      {
+	  *retcode += -36;
+	  return 0;
+      }
+    if (!do_export_section_tiff (sqlite, coverage, geom, 2))
+      {
+	  *retcode += -37;
+	  return 0;
+      }
+    if (!do_export_section_tiff (sqlite, coverage, geom, 4))
+      {
+	  *retcode += -38;
+	  return 0;
+      }
+    if (!do_export_section_tiff (sqlite, coverage, geom, 8))
+      {
+	  *retcode += -39;
+	  return 0;
+      }
+    if (!do_export_section_tiff_tfw (sqlite, coverage, geom, 1))
+      {
+	  *retcode += -40;
+	  return 0;
+      }
+    if (!do_export_section_tiff_tfw (sqlite, coverage, geom, 2))
+      {
+	  *retcode += -41;
+	  return 0;
+      }
+    if (!do_export_section_tiff_tfw (sqlite, coverage, geom, 4))
+      {
+	  *retcode += -42;
+	  return 0;
+      }
+    if (!do_export_section_tiff_tfw (sqlite, coverage, geom, 8))
+      {
+	  *retcode += -43;
+	  return 0;
+      }
 
     gaiaFreeGeomColl (geom);
 
@@ -772,7 +1002,7 @@ drop_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
 /* dropping some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
+    const char *coverage = NULL;
     char *sql;
 
 /* setting the coverage name */
@@ -889,12 +1119,12 @@ drop_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
       };
 
 /* dropping the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_DropCoverage(%Q, 1)", coverage);
+    sql = sqlite3_mprintf ("SELECT RL2_DropRasterCoverage(%Q, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "DropCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "DropRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -912,6 +1142,7 @@ main (int argc, char *argv[])
     char *err_msg = NULL;
     sqlite3 *db_handle;
     void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
     char *old_SPATIALITE_SECURITY_ENV = NULL;
 
     if (argc > 1 || argv[0] == NULL)
@@ -934,7 +1165,7 @@ main (int argc, char *argv[])
 	  return -1;
       }
     spatialite_init_ex (db_handle, cache, 0);
-    rl2_init (db_handle, 0);
+    rl2_init (db_handle, priv_data, 0);
     ret =
 	sqlite3_exec (db_handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
 		      &err_msg);
@@ -991,6 +1222,8 @@ main (int argc, char *argv[])
     if (!test_coverage
 	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_JPEG, TILE_1024, &ret))
 	return ret;
+
+#ifndef OMIT_WEBP		/* only if WebP is enabled */
     ret = -400;
     if (!test_coverage
 	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_LOSSY_WEBP, TILE_256,
@@ -1021,6 +1254,7 @@ main (int argc, char *argv[])
 	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_LOSSLESS_WEBP,
 	 TILE_1024, &ret))
 	return ret;
+#endif /* end WebP conditional */
 
 /* PALETTE tests */
     ret = -600;
@@ -1085,6 +1319,8 @@ main (int argc, char *argv[])
     if (!drop_coverage
 	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_JPEG, TILE_1024, &ret))
 	return ret;
+
+#ifndef OMIT_WEBP		/* only if WebP is enabled */
     ret = -470;
     if (!drop_coverage
 	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_LOSSY_WEBP, TILE_256,
@@ -1115,6 +1351,7 @@ main (int argc, char *argv[])
 	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_LOSSLESS_WEBP,
 	 TILE_1024, &ret))
 	return ret;
+#endif /* end WebP conditional */
 
 /* dropping all PALETTE Coverages */
     ret = -670;
@@ -1144,6 +1381,8 @@ main (int argc, char *argv[])
 
 /* closing the DB */
     sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
     spatialite_shutdown ();
     if (old_SPATIALITE_SECURITY_ENV)
       {
diff --git a/test/test_map_indiana.c b/test/test_map_indiana.c
index ee915eb..54dcd2a 100644
--- a/test/test_map_indiana.c
+++ b/test/test_map_indiana.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -46,6 +46,8 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include <stdio.h>
 #include <string.h>
 
+#include "config.h"
+
 #include "sqlite3.h"
 #include "spatialite.h"
 #include "spatialite/gaiaaux.h"
@@ -399,7 +401,7 @@ do_export_image (sqlite3 * sqlite, const char *coverage, gaiaGeomCollPtr geom,
     path = sqlite3_mprintf ("./%s_%1.0f%s", coverage, radius, suffix);
 
     sql =
-	"SELECT RL2_GetMapImage(?, ST_Buffer(?, ?), 512, 512, 'default', ?, '#ffffff', 1, 80)";
+	"SELECT RL2_GetMapImageFromRaster(?, ST_Buffer(?, ?), 512, 512, 'default', ?, '#ffffff', 1, 80)";
     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
 	return 0;
@@ -452,15 +454,25 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
 /* testing some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
-    const char *sample_name;
-    const char *pixel_name;
-    unsigned char num_bands;
-    const char *compression_name;
-    int qlty;
+    const char *coverage = NULL;
+    const char *sample_name = NULL;
+    const char *pixel_name = NULL;
+    unsigned char num_bands = 1;
+    const char *compression_name = NULL;
+    int qlty = 100;
     char *sql;
-    int tile_size;
+    int tile_size = 256;
     gaiaGeomCollPtr geom;
+    sqlite3_int64 section_id;
+    int duplicate;
+    double x_res;
+    double y_res;
+    double minx;
+    double miny;
+    double maxx;
+    double maxy;
+    unsigned int width;
+    unsigned int height;
 
 /* setting the coverage name */
     switch (pixel)
@@ -496,6 +508,34 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
 		      break;
 		  };
 		break;
+	    case RL2_COMPRESSION_DEFLATE:
+		switch (tile_sz)
+		  {
+		  case TILE_256:
+		      coverage = "plt_deflate_256";
+		      break;
+		  case TILE_512:
+		      coverage = "plt_deflate_512";
+		      break;
+		  case TILE_1024:
+		      coverage = "plt_deflate_1024";
+		      break;
+		  };
+		break;
+	    case RL2_COMPRESSION_LZMA:
+		switch (tile_sz)
+		  {
+		  case TILE_256:
+		      coverage = "plt_lzma_256";
+		      break;
+		  case TILE_512:
+		      coverage = "plt_lzma_512";
+		      break;
+		  case TILE_1024:
+		      coverage = "plt_lzma_1024";
+		      break;
+		  };
+		break;
 	    };
 	  break;
       };
@@ -514,6 +554,14 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
 	  compression_name = "PNG";
 	  qlty = 100;
 	  break;
+      case RL2_COMPRESSION_DEFLATE:
+	  compression_name = "DEFLATE";
+	  qlty = 100;
+	  break;
+      case RL2_COMPRESSION_LZMA:
+	  compression_name = "LZMA";
+	  qlty = 100;
+	  break;
       };
     switch (tile_sz)
       {
@@ -529,7 +577,7 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
       };
 
 /* creating the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_CreateCoverage("
+    sql = sqlite3_mprintf ("SELECT RL2_CreateRasterCoverage("
 			   "%Q, %Q, %Q, %d, %Q, %d, %d, %d, %d, %1.4f, %1.4f, "
 			   "RL2_SetPixelValue(RL2_CreatePixel(%Q, %Q, 1), 0, 0))",
 			   coverage, sample_name, pixel_name, num_bands,
@@ -539,7 +587,7 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "CreateCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "CreateRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -562,33 +610,6 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
 	  return 0;
       }
 
-/* deleting the first section */
-    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, %Q, 1)",
-			   coverage, "indiana1");
-    ret = execute_check (sqlite, sql);
-    sqlite3_free (sql);
-    if (ret != SQLITE_OK)
-      {
-	  fprintf (stderr, "DeleteSection \"%s\" error: %s\n", coverage,
-		   err_msg);
-	  sqlite3_free (err_msg);
-	  *retcode += -3;
-	  return 0;
-      }
-
-/* re-loading yet again the first section */
-    sql = sqlite3_mprintf ("SELECT RL2_LoadRaster(%Q, %Q, 0, 26716, 0, 1)",
-			   coverage, "map_samples/usgs-indiana/indiana1.tif");
-    ret = execute_check (sqlite, sql);
-    sqlite3_free (sql);
-    if (ret != SQLITE_OK)
-      {
-	  fprintf (stderr, "LoadRaster \"%s\" error: %s\n", coverage, err_msg);
-	  sqlite3_free (err_msg);
-	  *retcode += -4;
-	  return 0;
-      }
-
 /* building the Pyramid Levels */
     sql = sqlite3_mprintf ("SELECT RL2_Pyramidize(%Q, NULL, 0, 1)", coverage);
     ret = execute_check (sqlite, sql);
@@ -602,9 +623,7 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
       }
 
 /* destroying Pyramid Levels on the second section */
-    sql =
-	sqlite3_mprintf ("SELECT RL2_DePyramidize(%Q, 'indiana2', 1)",
-			 coverage);
+    sql = sqlite3_mprintf ("SELECT RL2_DePyramidize(%Q, 2, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -728,6 +747,34 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
 	  *retcode += -26;
 	  return 0;
       }
+    if (rl2_get_dbms_section_id
+	(sqlite, coverage, "indiana2", &section_id, &duplicate) != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected error: GetDbmsSectionID\n");
+	  *retcode += -27;
+	  return 0;
+      }
+    if (!get_base_resolution (sqlite, coverage, &x_res, &y_res))
+      {
+	  *retcode += -28;
+	  return 0;
+      }
+    if (rl2_resolve_full_section_from_dbms
+	(sqlite, coverage, section_id, x_res, y_res, &minx, &miny, &maxx, &maxy,
+	 &width, &height) != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected error: ResolveDbmsFullSection\n");
+	  *retcode += -29;
+	  return 0;
+      }
+    if (rl2_resolve_full_section_from_dbms
+	(sqlite, coverage, section_id, x_res * 4, y_res * 4, &minx, &miny,
+	 &maxx, &maxy, &width, &height) != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected error: ResolveDbmsFullSection\n");
+	  *retcode += -29;
+	  return 0;
+      }
 
     return 1;
 }
@@ -739,7 +786,7 @@ drop_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
 /* dropping some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
+    const char *coverage = NULL;
     char *sql;
 
 /* setting the coverage name */
@@ -776,17 +823,45 @@ drop_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
 		      break;
 		  };
 		break;
+	    case RL2_COMPRESSION_DEFLATE:
+		switch (tile_sz)
+		  {
+		  case TILE_256:
+		      coverage = "plt_deflate_256";
+		      break;
+		  case TILE_512:
+		      coverage = "plt_deflate_512";
+		      break;
+		  case TILE_1024:
+		      coverage = "plt_deflate_1024";
+		      break;
+		  };
+		break;
+	    case RL2_COMPRESSION_LZMA:
+		switch (tile_sz)
+		  {
+		  case TILE_256:
+		      coverage = "plt_lzma_256";
+		      break;
+		  case TILE_512:
+		      coverage = "plt_lzma_512";
+		      break;
+		  case TILE_1024:
+		      coverage = "plt_lzma_1024";
+		      break;
+		  };
+		break;
 	    };
 	  break;
       };
 
 /* dropping the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_DropCoverage(%Q, 1)", coverage);
+    sql = sqlite3_mprintf ("SELECT RL2_DropRasterCoverage(%Q, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "DropCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "DropRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -804,6 +879,7 @@ main (int argc, char *argv[])
     char *err_msg = NULL;
     sqlite3 *db_handle;
     void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
     char *old_SPATIALITE_SECURITY_ENV = NULL;
 
     if (argc > 1 || argv[0] == NULL)
@@ -826,7 +902,7 @@ main (int argc, char *argv[])
 	  return -1;
       }
     spatialite_init_ex (db_handle, cache, 0);
-    rl2_init (db_handle, 0);
+    rl2_init (db_handle, priv_data, 0);
     ret =
 	sqlite3_exec (db_handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
 		      &err_msg);
@@ -871,6 +947,34 @@ main (int argc, char *argv[])
     if (!test_coverage
 	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_PNG, TILE_1024, &ret))
 	return ret;
+    ret = -260;
+    if (!test_coverage
+	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_DEFLATE, TILE_256, &ret))
+	return ret;
+    ret = -280;
+    if (!test_coverage
+	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_DEFLATE, TILE_512, &ret))
+	return ret;
+    ret = -300;
+    if (!test_coverage
+	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_DEFLATE, TILE_1024,
+	 &ret))
+	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
+    ret = -320;
+    if (!test_coverage
+	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_LZMA, TILE_256, &ret))
+	return ret;
+    ret = -340;
+    if (!test_coverage
+	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_LZMA, TILE_512, &ret))
+	return ret;
+    ret = -360;
+    if (!test_coverage
+	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
+	return ret;
+#endif /* end LZMA conditional */
 
 /* dropping all PALETTE Coverages */
     ret = -170;
@@ -897,9 +1001,39 @@ main (int argc, char *argv[])
     if (!drop_coverage
 	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_PNG, TILE_1024, &ret))
 	return ret;
+    ret = -300;
+    if (!drop_coverage
+	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_DEFLATE, TILE_256, &ret))
+	return ret;
+    ret = -310;
+    if (!drop_coverage
+	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_DEFLATE, TILE_512, &ret))
+	return ret;
+    ret = -320;
+    if (!drop_coverage
+	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_DEFLATE, TILE_1024,
+	 &ret))
+	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
+    ret = -330;
+    if (!drop_coverage
+	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_LZMA, TILE_256, &ret))
+	return ret;
+    ret = -340;
+    if (!drop_coverage
+	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_LZMA, TILE_512, &ret))
+	return ret;
+    ret = -350;
+    if (!drop_coverage
+	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
+	return ret;
+#endif /* end LZMA conditional */
 
 /* closing the DB */
     sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
     spatialite_shutdown ();
     if (old_SPATIALITE_SECURITY_ENV)
       {
diff --git a/test/test_map_infrared.c b/test/test_map_infrared.c
index 3d6171e..984ff44 100644
--- a/test/test_map_infrared.c
+++ b/test/test_map_infrared.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -46,6 +46,8 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include <stdio.h>
 #include <string.h>
 
+#include "config.h"
+
 #include "sqlite3.h"
 #include "spatialite.h"
 #include "spatialite/gaiaaux.h"
@@ -80,6 +82,37 @@ execute_check (sqlite3 * sqlite, const char *sql)
 }
 
 static int
+execute_check_boolean (sqlite3 * sqlite, const char *sql)
+{
+/* executing an SQL statement returning True/False */
+    sqlite3_stmt *stmt;
+    int ret;
+    int retcode = -1;
+
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return -1;
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+      {
+	  if (sqlite3_column_type (stmt, 0) == SQLITE_INTEGER)
+	    {
+		int value = sqlite3_column_int (stmt, 0);
+		if (value < 0)
+		    retcode = -1;
+		else if (value == 0)
+		    retcode = 0;
+		else
+		    retcode = 1;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    if (retcode >= 0)
+	return retcode;
+    return -1;
+}
+
+static int
 get_max_tile_id (sqlite3 * sqlite, const char *coverage)
 {
 /* retriving the Max tile_id for a given Coverage */
@@ -113,10 +146,42 @@ get_max_tile_id (sqlite3 * sqlite, const char *coverage)
 }
 
 static int
-do_export_tile_image (sqlite3 * sqlite, const char *coverage, int tile_id,
-		      int band_mix)
+do_export_tile_image (sqlite3 * sqlite, const char *coverage, int tile_id)
+{
+/* attempting to export a visible Tile - basic */
+    char *sql;
+    char *path;
+    int ret;
+    int transparent = 1;
+
+    if (tile_id > 1)
+	transparent = 0;
+    if (tile_id < 0)
+	tile_id = get_max_tile_id (sqlite, coverage);
+    path = sqlite3_mprintf ("./%s_tile_%d.png", coverage, tile_id);
+    sql =
+	sqlite3_mprintf
+	("SELECT BlobToFile(RL2_GetTileImage(%Q, %d, '#e0ffe0', %d), %Q)",
+	 coverage, tile_id, transparent, path);
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    unlink (path);
+    sqlite3_free (path);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr,
+		   "ERROR: Unable to export an Image from \"%s\" tile_id=%d\n",
+		   coverage, tile_id);
+	  return 0;
+      }
+    return 1;
+}
+
+static int
+do_export_tile_image3 (sqlite3 * sqlite, const char *coverage, int tile_id,
+		       int band_mix)
 {
-/* attempting to export a visible Tile */
+/* attempting to export a visible Tile - triple band */
     char *sql;
     char *path;
     int ret;
@@ -707,114 +772,838 @@ do_export_mono_band_tiff_tfw (sqlite3 * sqlite, const char *coverage,
 }
 
 static int
-do_export_map_image (sqlite3 * sqlite, const char *coverage,
-		     gaiaGeomCollPtr geom, const char *style,
-		     const char *suffix, int monolithic)
+do_export_section_triple_geotiff (sqlite3 * sqlite, const char *coverage,
+				  gaiaGeomCollPtr geom, int scale)
 {
-/* exporting a Map Image (full rendered) */
+/* exporting a Section TripleBand GeoTiff */
     char *sql;
     char *path;
     sqlite3_stmt *stmt;
     int ret;
+    double x_res;
+    double y_res;
+    double xx_res;
+    double yy_res;
     unsigned char *blob;
     int blob_size;
     int retcode = 0;
-    const char *format = "text/plain";
+    unsigned char red_band = 0;
+    unsigned char green_band = 1;
+    unsigned char blue_band = 2;
 
-    if (strcmp (suffix, "png") == 0)
-	format = "image/png";
-    if (strcmp (suffix, "jpg") == 0)
-	format = "image/jpeg";
-    if (strcmp (suffix, "tif") == 0)
-	format = "image/tiff";
-    if (strcmp (suffix, "pdf") == 0)
-	format = "application/x-pdf";
+    path = sqlite3_mprintf ("./%s_sect1_triple_gt_%d.tif", coverage, scale);
 
-    path =
-	sqlite3_mprintf ("./%s_%s_map_%s.%s", coverage,
-			 monolithic ? "mono" : "sect", style, suffix);
+    if (!get_base_resolution (sqlite, coverage, &x_res, &y_res))
+	return 0;
+    xx_res = x_res * (double) scale;
+    yy_res = y_res * (double) scale;
 
     sql =
-	"SELECT BlobToFile(RL2_GetMapImage(?, ST_Buffer(?, 100), ?, ?, ?, ?, ?, ?), ?)";
+	"SELECT RL2_WriteSectionTripleBandGeoTiff(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
 	return 0;
     sqlite3_reset (stmt);
     sqlite3_clear_bindings (stmt);
     sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
+    sqlite3_bind_int64 (stmt, 2, 1);
+    sqlite3_bind_text (stmt, 3, path, strlen (path), SQLITE_STATIC);
+    sqlite3_bind_int (stmt, 4, 1024);
+    sqlite3_bind_int (stmt, 5, 1024);
+    sqlite3_bind_int (stmt, 6, red_band);
+    sqlite3_bind_int (stmt, 7, green_band);
+    sqlite3_bind_int (stmt, 8, blue_band);
     gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
-    sqlite3_bind_blob (stmt, 2, blob, blob_size, free);
-    sqlite3_bind_int (stmt, 3, 1024);
+    sqlite3_bind_blob (stmt, 9, blob, blob_size, free);
+    sqlite3_bind_double (stmt, 10, xx_res);
+    sqlite3_bind_double (stmt, 11, yy_res);
+    sqlite3_bind_int (stmt, 12, 0);
+    sqlite3_bind_text (stmt, 13, "NONE", 4, SQLITE_TRANSIENT);
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+      {
+	  if (sqlite3_column_int (stmt, 0) == 1)
+	      retcode = 1;
+      }
+    sqlite3_finalize (stmt);
+    unlink (path);
+    if (!retcode)
+	fprintf (stderr, "ERROR: unable to export \"%s\"\n", path);
+    sqlite3_free (path);
+    return retcode;
+}
+
+static int
+do_export_section_triple_tiff (sqlite3 * sqlite, const char *coverage,
+			       gaiaGeomCollPtr geom, int scale)
+{
+/* exporting a Section TripleBand Tiff */
+    char *sql;
+    char *path;
+    sqlite3_stmt *stmt;
+    int ret;
+    double x_res;
+    double y_res;
+    double xx_res;
+    double yy_res;
+    unsigned char *blob;
+    int blob_size;
+    int retcode = 0;
+    unsigned char red_band = 0;
+    unsigned char green_band = 1;
+    unsigned char blue_band = 2;
+
+    path = sqlite3_mprintf ("./%s_sect1_triple_tif_%d.tif", coverage, scale);
+
+    if (!get_base_resolution (sqlite, coverage, &x_res, &y_res))
+	return 0;
+    xx_res = x_res * (double) scale;
+    yy_res = y_res * (double) scale;
+
+    sql =
+	"SELECT RL2_WriteSectionTripleBandTiff(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return 0;
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
+    sqlite3_bind_int64 (stmt, 2, 1);
+    sqlite3_bind_text (stmt, 3, path, strlen (path), SQLITE_STATIC);
     sqlite3_bind_int (stmt, 4, 1024);
-    sqlite3_bind_text (stmt, 5, style, strlen (style), SQLITE_STATIC);
-    sqlite3_bind_text (stmt, 6, format, strlen (format), SQLITE_STATIC);
-    sqlite3_bind_text (stmt, 7, "#ffe0e0", 7, SQLITE_STATIC);
-    sqlite3_bind_int (stmt, 8, 1);
-    sqlite3_bind_text (stmt, 9, path, strlen (path), SQLITE_STATIC);
+    sqlite3_bind_int (stmt, 5, 1024);
+    sqlite3_bind_int (stmt, 6, red_band);
+    sqlite3_bind_int (stmt, 7, green_band);
+    sqlite3_bind_int (stmt, 8, blue_band);
+    gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
+    sqlite3_bind_blob (stmt, 9, blob, blob_size, free);
+    sqlite3_bind_double (stmt, 10, xx_res);
+    sqlite3_bind_double (stmt, 11, yy_res);
+    sqlite3_bind_text (stmt, 12, "NONE", 4, SQLITE_TRANSIENT);
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+      {
+	  if (sqlite3_column_int (stmt, 0) == 1)
+	      retcode = 1;
+      }
+    sqlite3_finalize (stmt);
+    unlink (path);
+    if (!retcode)
+	fprintf (stderr, "ERROR: unable to export \"%s\"\n", path);
+    sqlite3_free (path);
+    return retcode;
+}
+
+static int
+do_export_section_triple_tiff_tfw (sqlite3 * sqlite, const char *coverage,
+				   gaiaGeomCollPtr geom, int scale)
+{
+/* exporting a Section TripleBand TiffTfw */
+    char *sql;
+    char *path;
+    sqlite3_stmt *stmt;
+    int ret;
+    double x_res;
+    double y_res;
+    double xx_res;
+    double yy_res;
+    unsigned char *blob;
+    int blob_size;
+    int retcode = 0;
+    unsigned char red_band = 0;
+    unsigned char green_band = 1;
+    unsigned char blue_band = 2;
+
+    path = sqlite3_mprintf ("./%s_sect1_triple_tfw_%d.tif", coverage, scale);
+
+    if (!get_base_resolution (sqlite, coverage, &x_res, &y_res))
+	return 0;
+    xx_res = x_res * (double) scale;
+    yy_res = y_res * (double) scale;
+
+    sql =
+	"SELECT RL2_WriteSectionTripleBandTiffTfw(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return 0;
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
+    sqlite3_bind_int64 (stmt, 2, 1);
+    sqlite3_bind_text (stmt, 3, path, strlen (path), SQLITE_STATIC);
+    sqlite3_bind_int (stmt, 4, 1024);
+    sqlite3_bind_int (stmt, 5, 1024);
+    sqlite3_bind_int (stmt, 6, red_band);
+    sqlite3_bind_int (stmt, 7, green_band);
+    sqlite3_bind_int (stmt, 8, blue_band);
+    gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
+    sqlite3_bind_blob (stmt, 9, blob, blob_size, free);
+    sqlite3_bind_double (stmt, 10, xx_res);
+    sqlite3_bind_double (stmt, 11, yy_res);
+    sqlite3_bind_text (stmt, 12, "NONE", 4, SQLITE_TRANSIENT);
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+      {
+	  if (sqlite3_column_int (stmt, 0) == 1)
+	      retcode = 1;
+      }
+    sqlite3_finalize (stmt);
+    unlink (path);
+    if (!retcode)
+	fprintf (stderr, "ERROR: unable to export \"%s\"\n", path);
+    sqlite3_free (path);
+    path = sqlite3_mprintf ("./%s_sect1_triple_tfw_%d.tfw", coverage, scale);
+    unlink (path);
+    sqlite3_free (path);
+    return retcode;
+}
+
+static int
+do_export_section_mono_geotiff (sqlite3 * sqlite, const char *coverage,
+				gaiaGeomCollPtr geom, int scale)
+{
+/* exporting a Section MonoBand GeoTiff */
+    char *sql;
+    char *path;
+    sqlite3_stmt *stmt;
+    int ret;
+    double x_res;
+    double y_res;
+    double xx_res;
+    double yy_res;
+    unsigned char *blob;
+    int blob_size;
+    int retcode = 0;
+
+    path = sqlite3_mprintf ("./%s_sect1_mono_gt_%d.tif", coverage, scale);
+
+    if (!get_base_resolution (sqlite, coverage, &x_res, &y_res))
+	return 0;
+    xx_res = x_res * (double) scale;
+    yy_res = y_res * (double) scale;
+
+    sql =
+	"SELECT RL2_WriteSectionMonoBandGeoTiff(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return 0;
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
+    sqlite3_bind_int64 (stmt, 2, 1);
+    sqlite3_bind_text (stmt, 3, path, strlen (path), SQLITE_STATIC);
+    sqlite3_bind_int (stmt, 4, 1024);
+    sqlite3_bind_int (stmt, 5, 1024);
+    sqlite3_bind_int (stmt, 6, 0);
+    gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
+    sqlite3_bind_blob (stmt, 7, blob, blob_size, free);
+    sqlite3_bind_double (stmt, 8, xx_res);
+    sqlite3_bind_double (stmt, 9, yy_res);
+    sqlite3_bind_int (stmt, 10, 0);
+    sqlite3_bind_text (stmt, 11, "NONE", 4, SQLITE_TRANSIENT);
     ret = sqlite3_step (stmt);
     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
       {
-	  if (sqlite3_column_int (stmt, 0) == 1)
-	      retcode = 1;
+	  if (sqlite3_column_int (stmt, 0) == 1)
+	      retcode = 1;
+      }
+    sqlite3_finalize (stmt);
+    unlink (path);
+    if (!retcode)
+	fprintf (stderr, "ERROR: unable to export \"%s\"\n", path);
+    sqlite3_free (path);
+    return retcode;
+}
+
+static int
+do_export_section_mono_tiff (sqlite3 * sqlite, const char *coverage,
+			     gaiaGeomCollPtr geom, int scale)
+{
+/* exporting a Section MonoBand Tiff */
+    char *sql;
+    char *path;
+    sqlite3_stmt *stmt;
+    int ret;
+    double x_res;
+    double y_res;
+    double xx_res;
+    double yy_res;
+    unsigned char *blob;
+    int blob_size;
+    int retcode = 0;
+
+    path = sqlite3_mprintf ("./%s_sect1_mono_tif_%d.tif", coverage, scale);
+
+    if (!get_base_resolution (sqlite, coverage, &x_res, &y_res))
+	return 0;
+    xx_res = x_res * (double) scale;
+    yy_res = y_res * (double) scale;
+
+    sql = "SELECT RL2_WriteSectionMonoBandTiff(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return 0;
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
+    sqlite3_bind_int64 (stmt, 2, 1);
+    sqlite3_bind_text (stmt, 3, path, strlen (path), SQLITE_STATIC);
+    sqlite3_bind_int (stmt, 4, 1024);
+    sqlite3_bind_int (stmt, 5, 1024);
+    sqlite3_bind_int (stmt, 6, 0);
+    gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
+    sqlite3_bind_blob (stmt, 7, blob, blob_size, free);
+    sqlite3_bind_double (stmt, 8, xx_res);
+    sqlite3_bind_double (stmt, 9, yy_res);
+    sqlite3_bind_text (stmt, 10, "NONE", 4, SQLITE_TRANSIENT);
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+      {
+	  if (sqlite3_column_int (stmt, 0) == 1)
+	      retcode = 1;
+      }
+    sqlite3_finalize (stmt);
+    unlink (path);
+    if (!retcode)
+	fprintf (stderr, "ERROR: unable to export \"%s\"\n", path);
+    sqlite3_free (path);
+    return retcode;
+}
+
+static int
+do_export_section_mono_tiff_tfw (sqlite3 * sqlite, const char *coverage,
+				 gaiaGeomCollPtr geom, int scale)
+{
+/* exporting a Section MonoBand Tiff */
+    char *sql;
+    char *path;
+    sqlite3_stmt *stmt;
+    int ret;
+    double x_res;
+    double y_res;
+    double xx_res;
+    double yy_res;
+    unsigned char *blob;
+    int blob_size;
+    int retcode = 0;
+
+    path = sqlite3_mprintf ("./%s_sect1_mono_tfw_%d.tif", coverage, scale);
+
+    if (!get_base_resolution (sqlite, coverage, &x_res, &y_res))
+	return 0;
+    xx_res = x_res * (double) scale;
+    yy_res = y_res * (double) scale;
+
+    sql =
+	"SELECT RL2_WriteSectionMonoBandTiffTfw(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return 0;
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
+    sqlite3_bind_int64 (stmt, 2, 1);
+    sqlite3_bind_text (stmt, 3, path, strlen (path), SQLITE_STATIC);
+    sqlite3_bind_int (stmt, 4, 1024);
+    sqlite3_bind_int (stmt, 5, 1024);
+    sqlite3_bind_int (stmt, 6, 0);
+    gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
+    sqlite3_bind_blob (stmt, 7, blob, blob_size, free);
+    sqlite3_bind_double (stmt, 8, xx_res);
+    sqlite3_bind_double (stmt, 9, yy_res);
+    sqlite3_bind_text (stmt, 10, "NONE", 4, SQLITE_TRANSIENT);
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+      {
+	  if (sqlite3_column_int (stmt, 0) == 1)
+	      retcode = 1;
+      }
+    sqlite3_finalize (stmt);
+    unlink (path);
+    if (!retcode)
+	fprintf (stderr, "ERROR: unable to export \"%s\"\n", path);
+    sqlite3_free (path);
+    path = sqlite3_mprintf ("./%s_sect1_mono_tfw_%d.tfw", coverage, scale);
+    unlink (path);
+    sqlite3_free (path);
+    return retcode;
+}
+
+static int
+do_export_map_image (sqlite3 * sqlite, const char *coverage,
+		     gaiaGeomCollPtr geom, const char *style,
+		     const char *suffix, int monolithic)
+{
+/* exporting a Map Image (full rendered) */
+    char *sql;
+    char *path;
+    sqlite3_stmt *stmt;
+    int ret;
+    unsigned char *blob;
+    int blob_size;
+    int retcode = 0;
+    const char *format = "text/plain";
+
+    if (strcmp (suffix, "png") == 0)
+	format = "image/png";
+    if (strcmp (suffix, "jpg") == 0)
+	format = "image/jpeg";
+    if (strcmp (suffix, "tif") == 0)
+	format = "image/tiff";
+    if (strcmp (suffix, "pdf") == 0)
+	format = "application/x-pdf";
+
+    path =
+	sqlite3_mprintf ("./%s_%s_map_%s.%s", coverage,
+			 monolithic ? "mono" : "sect", style, suffix);
+
+    sql =
+	"SELECT BlobToFile(RL2_GetMapImageFromRaster(?, ST_Buffer(?, 100), ?, ?, ?, ?, ?, ?), ?)";
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return 0;
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
+    gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
+    sqlite3_bind_blob (stmt, 2, blob, blob_size, free);
+    sqlite3_bind_int (stmt, 3, 1024);
+    sqlite3_bind_int (stmt, 4, 1024);
+    sqlite3_bind_text (stmt, 5, style, strlen (style), SQLITE_STATIC);
+    sqlite3_bind_text (stmt, 6, format, strlen (format), SQLITE_STATIC);
+    sqlite3_bind_text (stmt, 7, "#ffe0e0", 7, SQLITE_STATIC);
+    sqlite3_bind_int (stmt, 8, 1);
+    sqlite3_bind_text (stmt, 9, path, strlen (path), SQLITE_STATIC);
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+      {
+	  if (sqlite3_column_int (stmt, 0) == 1)
+	      retcode = 1;
+      }
+    sqlite3_finalize (stmt);
+    unlink (path);
+    if (!retcode)
+	fprintf (stderr, "ERROR: unable to export \"%s\"\n", path);
+    sqlite3_free (path);
+    return retcode;
+}
+
+static int
+do_export_ndvi (sqlite3 * sqlite, const char *coverage, gaiaGeomCollPtr geom)
+{
+/* exporting an NDVI Ascii Grid */
+    char *sql;
+    const char *path = "./ndvi_ascii_grid.asc";
+    sqlite3_stmt *stmt;
+    int ret;
+    double x_res;
+    double y_res;
+    double xx_res;
+    double yy_res;
+    unsigned char *blob;
+    int blob_size;
+    int retcode = 0;
+    double scale = 1.0;
+
+    if (!get_base_resolution (sqlite, coverage, &x_res, &y_res))
+	return 0;
+    xx_res = x_res * (double) scale;
+    yy_res = y_res * (double) scale;
+    if (xx_res != yy_res)
+	xx_res = (xx_res + yy_res) / 2.0;
+
+    sql = "SELECT RL2_WriteNdviAsciiGrid(?, ?, ?, ?, ?, ?, ?, ?)";
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return 0;
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
+    sqlite3_bind_text (stmt, 2, path, strlen (path), SQLITE_STATIC);
+    sqlite3_bind_int (stmt, 3, 1024);
+    sqlite3_bind_int (stmt, 4, 1024);
+    sqlite3_bind_int (stmt, 5, 0);	/* red band */
+    sqlite3_bind_int (stmt, 6, 3);	/* NIR band */
+    gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
+    sqlite3_bind_blob (stmt, 7, blob, blob_size, free);
+    sqlite3_bind_double (stmt, 8, xx_res);
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+      {
+	  if (sqlite3_column_int (stmt, 0) == 1)
+	      retcode = 1;
+      }
+    sqlite3_finalize (stmt);
+    unlink (path);
+    if (!retcode)
+	fprintf (stderr, "ERROR: unable to export \"%s\"\n", path);
+    return retcode;
+}
+
+static int
+do_export_section_ndvi (sqlite3 * sqlite, const char *coverage,
+			gaiaGeomCollPtr geom)
+{
+/* exporting a Section NDVI Ascii Grid */
+    char *sql;
+    const char *path = "./ndvi_ascii_grid_section.asc";
+    sqlite3_stmt *stmt;
+    int ret;
+    double x_res;
+    double y_res;
+    double xx_res;
+    double yy_res;
+    unsigned char *blob;
+    int blob_size;
+    int retcode = 0;
+    double scale = 1.0;
+
+    if (!get_base_resolution (sqlite, coverage, &x_res, &y_res))
+	return 0;
+    xx_res = x_res * (double) scale;
+    yy_res = y_res * (double) scale;
+    if (xx_res != yy_res)
+	xx_res = (xx_res + yy_res) / 2.0;
+
+    sql = "SELECT RL2_WriteSectionNdviAsciiGrid(?, ?, ?, ?, ?, ?, ?, ?, ?)";
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return 0;
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
+    sqlite3_bind_int64 (stmt, 2, 1);
+    sqlite3_bind_text (stmt, 3, path, strlen (path), SQLITE_STATIC);
+    sqlite3_bind_int (stmt, 4, 1024);
+    sqlite3_bind_int (stmt, 5, 1024);
+    sqlite3_bind_int (stmt, 6, 0);	/* red band */
+    sqlite3_bind_int (stmt, 7, 3);	/* NIR band */
+    gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
+    sqlite3_bind_blob (stmt, 8, blob, blob_size, free);
+    sqlite3_bind_double (stmt, 9, xx_res);
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+      {
+	  if (sqlite3_column_int (stmt, 0) == 1)
+	      retcode = 1;
+      }
+    sqlite3_finalize (stmt);
+    unlink (path);
+    if (!retcode)
+	fprintf (stderr, "ERROR: unable to export \"%s\"\n", path);
+    return retcode;
+}
+
+static gaiaGeomCollPtr
+get_center_point (sqlite3 * sqlite, const char *coverage)
+{
+/* attempting to retrieve the Coverage's Center Point */
+    char *sql;
+    sqlite3_stmt *stmt;
+    gaiaGeomCollPtr geom = NULL;
+    int ret;
+
+    sql = sqlite3_mprintf ("SELECT MakePoint("
+			   "extent_minx + ((extent_maxx - extent_minx) / 2.0), "
+			   "extent_miny + ((extent_maxy - extent_miny) / 2.0)) "
+			   "FROM raster_coverages WHERE coverage_name = %Q",
+			   coverage);
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+	return NULL;
+
+    while (1)
+      {
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		const unsigned char *blob = sqlite3_column_blob (stmt, 0);
+		int blob_sz = sqlite3_column_bytes (stmt, 0);
+		geom = gaiaFromSpatiaLiteBlobWkb (blob, blob_sz);
+	    }
+      }
+    sqlite3_finalize (stmt);
+    return geom;
+}
+
+static int
+test_default_bands (sqlite3 * sqlite, const char *coverage)
+{
+/* testing default bands SQL functions */
+    int ret;
+    char *sql;
+    char *err_msg = NULL;
+
+    sql =
+	sqlite3_mprintf
+	("SELECT RL2_SetRasterCoverageDefaultBands(%Q, 4, 1, 2, 3)", coverage);
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret == SQLITE_OK)
+      {
+	  fprintf (stderr,
+		   "SetRasterCoverageDefaultBands #1 \"%s\" error: %s\n",
+		   coverage, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+    sql =
+	sqlite3_mprintf
+	("SELECT RL2_SetRasterCoverageDefaultBands(%Q, 0, 4, 2, 3)", coverage);
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret == SQLITE_OK)
+      {
+	  fprintf (stderr,
+		   "SetRasterCoverageDefaultBands #2 \"%s\" error: %s\n",
+		   coverage, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+    sql =
+	sqlite3_mprintf
+	("SELECT RL2_SetRasterCoverageDefaultBands(%Q, 0, 1, 4, 3)", coverage);
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret == SQLITE_OK)
+      {
+	  fprintf (stderr,
+		   "SetRasterCoverageDefaultBands #3 \"%s\" error: %s\n",
+		   coverage, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+    sql =
+	sqlite3_mprintf
+	("SELECT RL2_SetRasterCoverageDefaultBands(%Q, 0, 1, 4, 3)", coverage);
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret == SQLITE_OK)
+      {
+	  fprintf (stderr,
+		   "SetRasterCoverageDefaultBands #4 \"%s\" error: %s\n",
+		   coverage, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+    sql =
+	sqlite3_mprintf
+	("SELECT RL2_SetRasterCoverageDefaultBands(%Q, 0, 1, 2, 4)", coverage);
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret == SQLITE_OK)
+      {
+	  fprintf (stderr,
+		   "SetRasterCoverageDefaultBands #5 \"%s\" error: %s\n",
+		   coverage, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+    sql =
+	sqlite3_mprintf
+	("SELECT RL2_SetRasterCoverageDefaultBands(%Q, 0, 0, 2, 3)", coverage);
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret == SQLITE_OK)
+      {
+	  fprintf (stderr,
+		   "SetRasterCoverageDefaultBands #6 \"%s\" error: %s\n",
+		   coverage, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+    sql =
+	sqlite3_mprintf
+	("SELECT RL2_SetRasterCoverageDefaultBands(%Q, 0, 1, 0, 3)", coverage);
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret == SQLITE_OK)
+      {
+	  fprintf (stderr,
+		   "SetRasterCoverageDefaultBands #7 \"%s\" error: %s\n",
+		   coverage, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+    sql =
+	sqlite3_mprintf
+	("SELECT RL2_SetRasterCoverageDefaultBands(%Q, 0, 1, 2, 0)", coverage);
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret == SQLITE_OK)
+      {
+	  fprintf (stderr,
+		   "SetRasterCoverageDefaultBands #8 \"%s\" error: %s\n",
+		   coverage, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+    sql =
+	sqlite3_mprintf
+	("SELECT RL2_SetRasterCoverageDefaultBands(%Q, 0, 1, 1, 3)", coverage);
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret == SQLITE_OK)
+      {
+	  fprintf (stderr,
+		   "SetRasterCoverageDefaultBands #9 \"%s\" error: %s\n",
+		   coverage, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+    sql =
+	sqlite3_mprintf
+	("SELECT RL2_SetRasterCoverageDefaultBands(%Q, 0, 1, 2, 1)", coverage);
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret == SQLITE_OK)
+      {
+	  fprintf (stderr,
+		   "SetRasterCoverageDefaultBands #10 \"%s\" error: %s\n",
+		   coverage, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+    sql =
+	sqlite3_mprintf
+	("SELECT RL2_SetRasterCoverageDefaultBands(%Q, 0, 1, 2, 2)", coverage);
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret == SQLITE_OK)
+      {
+	  fprintf (stderr,
+		   "SetRasterCoverageDefaultBands #11 \"%s\" error: %s\n",
+		   coverage, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+    sql =
+	sqlite3_mprintf ("SELECT RL2_EnableRasterCoverageAutoNDVI(%Q, 1)",
+			 coverage);
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret == SQLITE_OK)
+      {
+	  fprintf (stderr, "EnableRasterCoverageAutoNDVI #1 \"%s\" error: %s\n",
+		   coverage, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+    sql =
+	sqlite3_mprintf ("SELECT RL2_IsRasterCoverageAutoNdviEnabled(%Q)",
+			 coverage);
+    ret = execute_check_boolean (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret >= 0)
+      {
+	  fprintf (stderr,
+		   "IsRasterCoverageAutoNdviEnabled #1 \"%s\" error: %s\n",
+		   coverage, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+    sql =
+	sqlite3_mprintf
+	("SELECT RL2_SetRasterCoverageDefaultBands(%Q, 0, 1, 2, 3)", coverage);
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr,
+		   "SetRasterCoverageDefaultBands #12 \"%s\" error: %s\n",
+		   coverage, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+    sql =
+	sqlite3_mprintf ("SELECT RL2_EnableRasterCoverageAutoNDVI(%Q, 0)",
+			 coverage);
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "EnableRasterCoverageAutoNDVI #2 \"%s\" error: %s\n",
+		   coverage, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
       }
-    sqlite3_finalize (stmt);
-    unlink (path);
-    if (!retcode)
-	fprintf (stderr, "ERROR: unable to export \"%s\"\n", path);
-    sqlite3_free (path);
-    return retcode;
-}
 
-static gaiaGeomCollPtr
-get_center_point (sqlite3 * sqlite, const char *coverage)
-{
-/* attempting to retrieve the Coverage's Center Point */
-    char *sql;
-    sqlite3_stmt *stmt;
-    gaiaGeomCollPtr geom = NULL;
-    int ret;
+    sql =
+	sqlite3_mprintf ("SELECT RL2_IsRasterCoverageAutoNdviEnabled(%Q)",
+			 coverage);
+    ret = execute_check_boolean (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != 0)
+      {
+	  fprintf (stderr,
+		   "IsRasterCoverageAutoNdviEnabled #2 \"%s\" error: %s\n",
+		   coverage, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
 
-    sql = sqlite3_mprintf ("SELECT MakePoint("
-			   "extent_minx + ((extent_maxx - extent_minx) / 2.0), "
-			   "extent_miny + ((extent_maxy - extent_miny) / 2.0)) "
-			   "FROM raster_coverages WHERE coverage_name = %Q",
-			   coverage);
-    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    sql =
+	sqlite3_mprintf ("SELECT RL2_EnableRasterCoverageAutoNDVI(%Q, 1)",
+			 coverage);
+    ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
-	return NULL;
+      {
+	  fprintf (stderr, "EnableRasterCoverageAutoNDVI #3 \"%s\" error: %s\n",
+		   coverage, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
 
-    while (1)
+    sql =
+	sqlite3_mprintf ("SELECT RL2_IsRasterCoverageAutoNdviEnabled(%Q)",
+			 coverage);
+    ret = execute_check_boolean (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != 1)
       {
-	  /* scrolling the result set rows */
-	  ret = sqlite3_step (stmt);
-	  if (ret == SQLITE_DONE)
-	      break;		/* end of result set */
-	  if (ret == SQLITE_ROW)
-	    {
-		const unsigned char *blob = sqlite3_column_blob (stmt, 0);
-		int blob_sz = sqlite3_column_bytes (stmt, 0);
-		geom = gaiaFromSpatiaLiteBlobWkb (blob, blob_sz);
-	    }
+	  fprintf (stderr,
+		   "IsRasterCoverageAutoNdviEnabled #3 \"%s\" error: %s\n",
+		   coverage, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
       }
-    sqlite3_finalize (stmt);
-    return geom;
+
+    return 1;
 }
 
 static int
 test_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
-	       int *retcode)
+	       int ndvi, int *retcode)
 {
 /* testing some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
-    const char *sample_name;
-    const char *pixel_name;
-    unsigned char num_bands;
-    const char *compression_name;
-    int qlty;
-    int tile_size;
+    const char *coverage = NULL;
+    const char *sample_name = NULL;
+    const char *pixel_name = NULL;
+    unsigned char num_bands = 1;
+    const char *compression_name = NULL;
+    int qlty = 100;
+    int tile_size = 256;
     char *sql;
     gaiaGeomCollPtr geom;
     int test_map_image = 0;
@@ -822,46 +1611,46 @@ test_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
 /* setting the coverage name */
     switch (compression)
       {
-      case RL2_COMPRESSION_NONE:
+      case RL2_COMPRESSION_CHARLS:
 	  switch (tile_sz)
 	    {
 	    case TILE_256:
-		coverage = "infrared_none_256";
+		coverage = "infrared_charls_256";
 		break;
 	    case TILE_512:
-		coverage = "infrared_none_512";
+		coverage = "infrared_charls_512";
 		break;
 	    case TILE_1024:
-		coverage = "infrared_none_1024";
+		coverage = "infrared_charls_1024";
 		test_map_image = 1;
 		break;
 	    };
 	  break;
-      case RL2_COMPRESSION_DEFLATE:
+      case RL2_COMPRESSION_LOSSY_JP2:
 	  switch (tile_sz)
 	    {
 	    case TILE_256:
-		coverage = "infrared_zip_256";
+		coverage = "infrared_jp2_256";
 		break;
 	    case TILE_512:
-		coverage = "infrared_zip_512";
+		coverage = "infrared_jp2_512";
 		break;
 	    case TILE_1024:
-		coverage = "infrared_zip_1024";
+		coverage = "infrared_jp2_1024";
 		break;
 	    };
 	  break;
-      case RL2_COMPRESSION_LZMA:
+      case RL2_COMPRESSION_PNG:
 	  switch (tile_sz)
 	    {
 	    case TILE_256:
-		coverage = "infrared_lzma_256";
+		coverage = "infrared_png_256";
 		break;
 	    case TILE_512:
-		coverage = "infrared_lzma_512";
+		coverage = "infrared_png_512";
 		break;
 	    case TILE_1024:
-		coverage = "infrared_lzma_1024";
+		coverage = "infrared_png_1024";
 		break;
 	    };
 	  break;
@@ -873,16 +1662,16 @@ test_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
     num_bands = 4;
     switch (compression)
       {
-      case RL2_COMPRESSION_NONE:
-	  compression_name = "NONE";
+      case RL2_COMPRESSION_CHARLS:
+	  compression_name = "CHARLS";
 	  qlty = 100;
 	  break;
-      case RL2_COMPRESSION_DEFLATE:
-	  compression_name = "DEFLATE";
+      case RL2_COMPRESSION_LOSSY_JP2:
+	  compression_name = "JP2";
 	  qlty = 100;
 	  break;
-      case RL2_COMPRESSION_LZMA:
-	  compression_name = "LZMA";
+      case RL2_COMPRESSION_PNG:
+	  compression_name = "PNG";
 	  qlty = 100;
 	  break;
       };
@@ -900,7 +1689,7 @@ test_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
       };
 
 /* creating the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_CreateCoverage("
+    sql = sqlite3_mprintf ("SELECT RL2_CreateRasterCoverage("
 			   "%Q, %Q, %Q, %d, %Q, %d, %d, %d, %d, %1.2f, %1.2f)",
 			   coverage, sample_name, pixel_name, num_bands,
 			   compression_name, qlty, tile_size, tile_size, 32632,
@@ -909,7 +1698,7 @@ test_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "CreateCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "CreateRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -948,9 +1737,7 @@ test_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
       }
 
 /* re-building the Pyramid Levels */
-    sql =
-	sqlite3_mprintf ("SELECT RL2_Pyramidize(%Q, %Q, 1, 1)", coverage,
-			 "infrared2");
+    sql = sqlite3_mprintf ("SELECT RL2_Pyramidize(%Q, 2, 1, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -975,9 +1762,7 @@ test_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
       }
 
 /* building yet again the Pyramid Levels */
-    sql =
-	sqlite3_mprintf ("SELECT RL2_Pyramidize(%Q, %Q, 1, 1)", coverage,
-			 "infrared2");
+    sql = sqlite3_mprintf ("SELECT RL2_Pyramidize(%Q, 2, 1, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -1173,13 +1958,22 @@ test_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
 	  *retcode += -41;
 	  return 0;
       }
+    if (ndvi)
+      {
+	  /* NDVI Ascii Grid */
+	  if (!do_export_ndvi (sqlite, coverage, geom))
+	    {
+		*retcode += -101;
+		return 0;
+	    }
+      }
     if (!test_map_image)
 	goto skip;
 
 /* loading the RasterSymbolizers */
-    sql = sqlite3_mprintf ("SELECT RegisterRasterStyledLayer(%Q, "
-			   "XB_Create(XB_LoadXML(%Q), 1, 1))", coverage,
-			   "ir_false_color1.xml");
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 1)",
+			 coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -1190,45 +1984,70 @@ test_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
 	  *retcode += -42;
 	  return 0;
       }
-    sql = sqlite3_mprintf ("SELECT RegisterRasterStyledLayer(%Q, "
-			   "XB_Create(XB_LoadXML(%Q), 1, 1))", coverage,
-			   "ir_false_color1_gamma.xml");
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 2)",
+			 coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "RegisterRasterStyledLayer #1 \"%s\" error: %s\n",
+	  fprintf (stderr, "RegisterRasterStyledLayer #2 \"%s\" error: %s\n",
 		   coverage, err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -43;
 	  return 0;
       }
-    sql = sqlite3_mprintf ("SELECT RegisterRasterStyledLayer(%Q, "
-			   "XB_Create(XB_LoadXML(%Q), 1, 1))", coverage,
-			   "ir_gray.xml");
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 3)",
+			 coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "RegisterRasterStyledLayer #2 \"%s\" error: %s\n",
+	  fprintf (stderr, "RegisterRasterStyledLayer #3 \"%s\" error: %s\n",
 		   coverage, err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -44;
 	  return 0;
       }
-    sql = sqlite3_mprintf ("SELECT RegisterRasterStyledLayer(%Q, "
-			   "XB_Create(XB_LoadXML(%Q), 1, 1))", coverage,
-			   "ir_gray_gamma.xml");
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 4)",
+			 coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "RegisterRasterStyledLayer #3 \"%s\" error: %s\n",
+	  fprintf (stderr, "RegisterRasterStyledLayer #4 \"%s\" error: %s\n",
 		   coverage, err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -45;
 	  return 0;
       }
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 5)",
+			 coverage);
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyledLayer #5 \"%s\" error: %s\n",
+		   coverage, err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -103;
+	  return 0;
+      }
+
+/* testing GetMapImage - NDVI */
+    if (!test_default_bands (sqlite, coverage))
+      {
+	  *retcode += -102;
+	  return 0;
+      }
+    if (!do_export_map_image (sqlite, coverage, geom, "ndvi", "jpg", 0))
+      {
+	  *retcode += 104;
+	  return 0;
+      }
 
 /* testing GetMapImage - IR false color */
     if (!do_export_map_image
@@ -1332,23 +2151,35 @@ test_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
   skip:
     gaiaFreeGeomColl (geom);
 
-/* testing GetTileImage() */
-    if (!do_export_tile_image (sqlite, coverage, 1, 0))
+/* testing GetTileImage() - basic */
+    if (!do_export_tile_image (sqlite, coverage, 1))
+      {
+	  *retcode += -162;
+	  return 0;
+      }
+    if (!do_export_tile_image (sqlite, coverage, -1))
+      {
+	  *retcode += -163;
+	  return 0;
+      }
+
+/* testing GetTileImage() - triple band */
+    if (!do_export_tile_image3 (sqlite, coverage, 1, 0))
       {
 	  *retcode += -62;
 	  return 0;
       }
-    if (!do_export_tile_image (sqlite, coverage, 1, 1))
+    if (!do_export_tile_image3 (sqlite, coverage, 1, 1))
       {
 	  *retcode += -63;
 	  return 0;
       }
-    if (!do_export_tile_image (sqlite, coverage, 1, 2))
+    if (!do_export_tile_image3 (sqlite, coverage, 1, 2))
       {
 	  *retcode += -64;
 	  return 0;
       }
-    if (!do_export_tile_image (sqlite, coverage, -1, 0))
+    if (!do_export_tile_image3 (sqlite, coverage, -1, 0))
       {
 	  *retcode += -65;
 	  return 0;
@@ -1376,7 +2207,7 @@ test_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
 	  return 0;
       }
 
-    if (compression == RL2_COMPRESSION_NONE && tile_sz == TILE_1024)
+    if (compression == RL2_COMPRESSION_CHARLS && tile_sz == TILE_1024)
       {
 	  /* testing a Monolithic Pyramid */
 	  geom = get_center_point (sqlite, coverage);
@@ -1425,6 +2256,261 @@ test_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
 	  gaiaFreeGeomColl (geom);
       }
 
+    if (strcmp (coverage, "infrared_png_512") == 0)
+      {
+	  /* testing Band Composed Section */
+	  geom = get_center_point (sqlite, coverage);
+	  if (geom == NULL)
+	    {
+		*retcode += -75;
+		return 0;
+	    }
+	  /* GeoTiff TripleBand */
+	  if (!do_export_section_triple_geotiff (sqlite, coverage, geom, 1))
+	    {
+		*retcode += -76;
+		return 0;
+	    }
+	  if (!do_export_section_triple_geotiff (sqlite, coverage, geom, 2))
+	    {
+		*retcode += -77;
+		return 0;
+	    }
+	  if (!do_export_section_triple_geotiff (sqlite, coverage, geom, 4))
+	    {
+		*retcode += -78;
+		return 0;
+	    }
+	  if (!do_export_section_triple_geotiff (sqlite, coverage, geom, 8))
+	    {
+		*retcode += -79;
+		return 0;
+	    }
+	  /* Tiff TripleBand */
+	  if (!do_export_section_triple_tiff (sqlite, coverage, geom, 1))
+	    {
+		*retcode += -80;
+		return 0;
+	    }
+	  if (!do_export_section_triple_tiff (sqlite, coverage, geom, 2))
+	    {
+		*retcode += -81;
+		return 0;
+	    }
+	  if (!do_export_section_triple_tiff (sqlite, coverage, geom, 4))
+	    {
+		*retcode += -82;
+		return 0;
+	    }
+	  if (!do_export_section_triple_tiff (sqlite, coverage, geom, 8))
+	    {
+		*retcode += -83;
+		return 0;
+	    }
+	  /* TiffTfw TripleBand */
+	  if (!do_export_section_triple_tiff_tfw (sqlite, coverage, geom, 1))
+	    {
+		*retcode += -84;
+		return 0;
+	    }
+	  if (!do_export_section_triple_tiff_tfw (sqlite, coverage, geom, 2))
+	    {
+		*retcode += -85;
+		return 0;
+	    }
+	  if (!do_export_section_triple_tiff_tfw (sqlite, coverage, geom, 4))
+	    {
+		*retcode += -86;
+		return 0;
+	    }
+	  if (!do_export_section_triple_tiff_tfw (sqlite, coverage, geom, 8))
+	    {
+		*retcode += -87;
+		return 0;
+	    }
+	  /* GeoTiff MonoBand */
+	  if (!do_export_section_mono_geotiff (sqlite, coverage, geom, 1))
+	    {
+		*retcode += -88;
+		return 0;
+	    }
+	  if (!do_export_section_mono_geotiff (sqlite, coverage, geom, 2))
+	    {
+		*retcode += -89;
+		return 0;
+	    }
+	  if (!do_export_section_mono_geotiff (sqlite, coverage, geom, 4))
+	    {
+		*retcode += -90;
+		return 0;
+	    }
+	  if (!do_export_section_mono_geotiff (sqlite, coverage, geom, 8))
+	    {
+		*retcode += -91;
+		return 0;
+	    }
+	  /* Tiff MonoBand */
+	  if (!do_export_section_mono_tiff (sqlite, coverage, geom, 1))
+	    {
+		*retcode += -92;
+		return 0;
+	    }
+	  if (!do_export_section_mono_tiff (sqlite, coverage, geom, 2))
+	    {
+		*retcode += -93;
+		return 0;
+	    }
+	  if (!do_export_section_mono_tiff (sqlite, coverage, geom, 4))
+	    {
+		*retcode += -94;
+		return 0;
+	    }
+	  if (!do_export_section_mono_tiff (sqlite, coverage, geom, 8))
+	    {
+		*retcode += -95;
+		return 0;
+	    }
+	  /* TiffTfw MonoBand */
+	  if (!do_export_section_mono_tiff_tfw (sqlite, coverage, geom, 1))
+	    {
+		*retcode += -97;
+		return 0;
+	    }
+	  if (!do_export_section_mono_tiff_tfw (sqlite, coverage, geom, 2))
+	    {
+		*retcode += -98;
+		return 0;
+	    }
+	  if (!do_export_section_mono_tiff_tfw (sqlite, coverage, geom, 4))
+	    {
+		*retcode += -99;
+		return 0;
+	    }
+	  if (!do_export_section_mono_tiff_tfw (sqlite, coverage, geom, 8))
+	    {
+		*retcode += -100;
+		return 0;
+	    }
+	  if (ndvi)
+	    {
+		/* Section NDVI Ascii Grid */
+		if (!do_export_section_ndvi (sqlite, coverage, geom))
+		  {
+		      *retcode += -102;
+		      return 0;
+		  }
+	    }
+	  gaiaFreeGeomColl (geom);
+      }
+
+    return 1;
+}
+
+static int
+register_raster_symbolizers (sqlite3 * sqlite, int no_web_connection,
+			     int *retcode)
+{
+/* loading the RasterSymbolizers */
+    int ret;
+    char *err_msg = NULL;
+    char *sql;
+
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "ir_false_color1.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "ir_false_color1.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #1 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -1;
+	  return 0;
+      }
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "ir_false_color1_gamma.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "ir_false_color1_gamma.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #2 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -2;
+	  return 0;
+      }
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "ir_gray.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "ir_gray.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #3 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -3;
+	  return 0;
+      }
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "ir_gray_gamma.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "ir_gray_gamma.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyledLayer #4 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -4;
+	  return 0;
+      }
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "ndvi.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "ndvi.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #5 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -5;
+	  return 0;
+      }
+
     return 1;
 }
 
@@ -1435,63 +2521,63 @@ drop_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
 /* dropping some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
+    const char *coverage = NULL;
     char *sql;
 
 /* setting the coverage name */
     switch (compression)
       {
-      case RL2_COMPRESSION_NONE:
+      case RL2_COMPRESSION_CHARLS:
 	  switch (tile_sz)
 	    {
 	    case TILE_256:
-		coverage = "infrared_none_256";
+		coverage = "infrared_charls_256";
 		break;
 	    case TILE_512:
-		coverage = "infrared_none_512";
+		coverage = "infrared_charls_512";
 		break;
 	    case TILE_1024:
-		coverage = "infrared_none_1024";
+		coverage = "infrared_charls_1024";
 		break;
 	    };
 	  break;
-      case RL2_COMPRESSION_DEFLATE:
+      case RL2_COMPRESSION_LOSSY_JP2:
 	  switch (tile_sz)
 	    {
 	    case TILE_256:
-		coverage = "infrared_zip_256";
+		coverage = "infrared_jp2_256";
 		break;
 	    case TILE_512:
-		coverage = "infrared_zip_512";
+		coverage = "infrared_jp2_512";
 		break;
 	    case TILE_1024:
-		coverage = "infrared_zip_1024";
+		coverage = "infrared_jp2_1024";
 		break;
 	    };
 	  break;
-      case RL2_COMPRESSION_LZMA:
+      case RL2_COMPRESSION_PNG:
 	  switch (tile_sz)
 	    {
 	    case TILE_256:
-		coverage = "infrared_lzma_256";
+		coverage = "infrared_png_256";
 		break;
 	    case TILE_512:
-		coverage = "infrared_lzma_512";
+		coverage = "infrared_png_512";
 		break;
 	    case TILE_1024:
-		coverage = "infrared_lzma_1024";
+		coverage = "infrared_png_1024";
 		break;
 	    };
 	  break;
       };
 
 /* dropping the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_DropCoverage(%Q, 1)", coverage);
+    sql = sqlite3_mprintf ("SELECT RL2_DropRasterCoverage(%Q, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "DropCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "DropRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -1504,16 +2590,28 @@ drop_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
 int
 main (int argc, char *argv[])
 {
+    int no_web_connection = 0;
     int result = 0;
     int ret;
     char *err_msg = NULL;
     sqlite3 *db_handle;
     void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
     char *old_SPATIALITE_SECURITY_ENV = NULL;
 
     if (argc > 1 || argv[0] == NULL)
 	argc = 1;		/* silencing stupid compiler warnings */
 
+    if (getenv ("ENABLE_RL2_WEB_TESTS") == NULL)
+      {
+	  fprintf (stderr,
+		   "this testcase has been executed with several limitations\n"
+		   "because it was not enabled to access the Web.\n\n"
+		   "you can enable all testcases requiring an Internet connection\n"
+		   "by setting the environment variable \"ENABLE_RL2_WEB_TESTS=1\"\n\n");
+	  no_web_connection = 1;
+      }
+
     old_SPATIALITE_SECURITY_ENV = getenv ("SPATIALITE_SECURITY");
 #ifdef _WIN32
     putenv ("SPATIALITE_SECURITY=relaxed");
@@ -1531,7 +2629,7 @@ main (int argc, char *argv[])
 	  return -1;
       }
     spatialite_init_ex (db_handle, cache, 0);
-    rl2_init (db_handle, 0);
+    rl2_init (db_handle, priv_data, 0);
     ret =
 	sqlite3_exec (db_handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
 		      &err_msg);
@@ -1550,76 +2648,103 @@ main (int argc, char *argv[])
 	  sqlite3_free (err_msg);
 	  return -3;
       }
-    ret =
-	sqlite3_exec (db_handle, "SELECT CreateStylingTables()", NULL,
-		      NULL, &err_msg);
+    if (no_web_connection)
+	ret =
+	    sqlite3_exec (db_handle, "SELECT CreateStylingTables(1)", NULL,
+			  NULL, &err_msg);
+    else
+	ret =
+	    sqlite3_exec (db_handle, "SELECT CreateStylingTables()", NULL,
+			  NULL, &err_msg);
     if (ret != SQLITE_OK)
       {
 	  fprintf (stderr, "CreateStylingTables() error: %s\n", err_msg);
 	  sqlite3_free (err_msg);
-	  return 4;
+	  return -4;
+      }
+    if (!register_raster_symbolizers (db_handle, no_web_connection, &ret))
+      {
+	  fprintf (stderr, "Register Raster Symbolizers error\n");
+	  return -5;
       }
 
 /* tests */
+#ifndef OMIT_CHARLS		/* only if CharLS is enabled */
     ret = -100;
-    if (!test_coverage (db_handle, RL2_COMPRESSION_NONE, TILE_256, &ret))
+    if (!test_coverage (db_handle, RL2_COMPRESSION_CHARLS, TILE_256, 0, &ret))
 	return ret;
     ret = -120;
-    if (!test_coverage (db_handle, RL2_COMPRESSION_NONE, TILE_512, &ret))
+    if (!test_coverage (db_handle, RL2_COMPRESSION_CHARLS, TILE_512, 0, &ret))
 	return ret;
     ret = -140;
-    if (!test_coverage (db_handle, RL2_COMPRESSION_NONE, TILE_1024, &ret))
+    if (!test_coverage (db_handle, RL2_COMPRESSION_CHARLS, TILE_1024, 0, &ret))
 	return ret;
+#endif /* end CharLS conditional */
+
+#ifndef OMIT_OPENJPEG		/* only if OpenJpeg is enabled */
     ret = -200;
-    if (!test_coverage (db_handle, RL2_COMPRESSION_DEFLATE, TILE_256, &ret))
+    if (!test_coverage
+	(db_handle, RL2_COMPRESSION_LOSSY_JP2, TILE_256, 0, &ret))
 	return ret;
     ret = -220;
-    if (!test_coverage (db_handle, RL2_COMPRESSION_DEFLATE, TILE_512, &ret))
+    if (!test_coverage
+	(db_handle, RL2_COMPRESSION_LOSSY_JP2, TILE_512, 0, &ret))
 	return ret;
     ret = -240;
-    if (!test_coverage (db_handle, RL2_COMPRESSION_DEFLATE, TILE_1024, &ret))
+    if (!test_coverage
+	(db_handle, RL2_COMPRESSION_LOSSY_JP2, TILE_1024, 0, &ret))
 	return ret;
+#endif /* end OpenJpeg conditional */
+
     ret = -300;
-    if (!test_coverage (db_handle, RL2_COMPRESSION_LZMA, TILE_256, &ret))
+    if (!test_coverage (db_handle, RL2_COMPRESSION_PNG, TILE_256, 0, &ret))
 	return ret;
     ret = -320;
-    if (!test_coverage (db_handle, RL2_COMPRESSION_LZMA, TILE_512, &ret))
+    if (!test_coverage (db_handle, RL2_COMPRESSION_PNG, TILE_512, 1, &ret))
 	return ret;
     ret = -340;
-    if (!test_coverage (db_handle, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
+    if (!test_coverage (db_handle, RL2_COMPRESSION_PNG, TILE_1024, 0, &ret))
 	return ret;
 
 /* dropping all Coverages */
+#ifndef OMIT_CHARLS		/* only if CharLS is enabled */
     ret = -170;
-    if (!drop_coverage (db_handle, RL2_COMPRESSION_NONE, TILE_256, &ret))
+    if (!drop_coverage (db_handle, RL2_COMPRESSION_CHARLS, TILE_256, &ret))
 	return ret;
     ret = -180;
-    if (!drop_coverage (db_handle, RL2_COMPRESSION_NONE, TILE_512, &ret))
+    if (!drop_coverage (db_handle, RL2_COMPRESSION_CHARLS, TILE_512, &ret))
 	return ret;
     ret = -190;
-    if (!drop_coverage (db_handle, RL2_COMPRESSION_NONE, TILE_1024, &ret))
+    if (!drop_coverage (db_handle, RL2_COMPRESSION_CHARLS, TILE_1024, &ret))
 	return ret;
+#endif /* end CharLS conditional */
+
+#ifndef OMIT_OPENJPEG		/* only if OpenJpeg is enabled */
     ret = -270;
-    if (!drop_coverage (db_handle, RL2_COMPRESSION_DEFLATE, TILE_256, &ret))
+    if (!drop_coverage (db_handle, RL2_COMPRESSION_LOSSY_JP2, TILE_256, &ret))
 	return ret;
     ret = -280;
-    if (!drop_coverage (db_handle, RL2_COMPRESSION_DEFLATE, TILE_512, &ret))
+    if (!drop_coverage (db_handle, RL2_COMPRESSION_LOSSY_JP2, TILE_512, &ret))
 	return ret;
     ret = -290;
-    if (!drop_coverage (db_handle, RL2_COMPRESSION_DEFLATE, TILE_1024, &ret))
+    if (!drop_coverage (db_handle, RL2_COMPRESSION_LOSSY_JP2, TILE_1024, &ret))
 	return ret;
+#endif /* end OpenJpeg conditional */
+
     ret = -370;
-    if (!drop_coverage (db_handle, RL2_COMPRESSION_LZMA, TILE_256, &ret))
+    if (!drop_coverage (db_handle, RL2_COMPRESSION_PNG, TILE_256, &ret))
 	return ret;
     ret = -380;
-    if (!drop_coverage (db_handle, RL2_COMPRESSION_LZMA, TILE_512, &ret))
+    if (!drop_coverage (db_handle, RL2_COMPRESSION_PNG, TILE_512, &ret))
 	return ret;
     ret = -390;
-    if (!drop_coverage (db_handle, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
+    if (!drop_coverage (db_handle, RL2_COMPRESSION_PNG, TILE_1024, &ret))
 	return ret;
 
 /* closing the DB */
     sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
     spatialite_shutdown ();
     if (old_SPATIALITE_SECURITY_ENV)
       {
diff --git a/test/test_map_mono.c b/test/test_map_mono.c
index 0e09ed0..556e8d4 100644
--- a/test/test_map_mono.c
+++ b/test/test_map_mono.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -46,6 +46,8 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include <stdio.h>
 #include <string.h>
 
+#include "config.h"
+
 #include "sqlite3.h"
 #include "spatialite.h"
 #include "spatialite/gaiaaux.h"
@@ -402,7 +404,7 @@ do_export_image (sqlite3 * sqlite, const char *coverage, gaiaGeomCollPtr geom,
     path = sqlite3_mprintf ("./%s_%1.0f%s", coverage, radius, suffix);
 
     sql =
-	"SELECT RL2_GetMapImage(?, ST_Buffer(?, ?), 512, 512, 'default', ?, '#ffffff', ?, 80)";
+	"SELECT RL2_GetMapImageFromRaster(?, ST_Buffer(?, ?), 512, 512, 'default', ?, '#ffffff', ?, 80)";
     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
 	return 0;
@@ -456,15 +458,15 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel,
 /* testing some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
-    const char *sample_name;
-    const char *pixel_name;
-    unsigned char num_bands;
-    const char *compression_name;
+    const char *coverage = NULL;
+    const char *sample_name = NULL;
+    const char *pixel_name = NULL;
+    unsigned char num_bands = 1;
+    const char *compression_name = NULL;
     const char *alt_compression_name = "NONE";
-    int qlty;
+    int qlty = 100;
     char *sql;
-    int tile_size;
+    int tile_size = 256;
     gaiaGeomCollPtr geom;
 
 /* setting the coverage name */
@@ -515,6 +517,34 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel,
 		      break;
 		  };
 		break;
+	    case RL2_COMPRESSION_DEFLATE:
+		switch (tile_sz)
+		  {
+		  case TILE_256:
+		      coverage = "mono_deflate_256";
+		      break;
+		  case TILE_512:
+		      coverage = "mono_deflate_256_512";
+		      break;
+		  case TILE_1024:
+		      coverage = "mono_deflate_256_1024";
+		      break;
+		  };
+		break;
+	    case RL2_COMPRESSION_LZMA:
+		switch (tile_sz)
+		  {
+		  case TILE_256:
+		      coverage = "mono_lzma_256";
+		      break;
+		  case TILE_512:
+		      coverage = "mono_lzma_256_512";
+		      break;
+		  case TILE_1024:
+		      coverage = "mono_lzma_256_1024";
+		      break;
+		  };
+		break;
 	    };
 	  break;
       case RL2_PIXEL_PALETTE:
@@ -548,6 +578,34 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel,
 		      break;
 		  };
 		break;
+	    case RL2_COMPRESSION_DEFLATE:
+		switch (tile_sz)
+		  {
+		  case TILE_256:
+		      coverage = "plt1_deflate_256";
+		      break;
+		  case TILE_512:
+		      coverage = "plt1_deflate_512";
+		      break;
+		  case TILE_1024:
+		      coverage = "plt1_deflate_1024";
+		      break;
+		  };
+		break;
+	    case RL2_COMPRESSION_LZMA:
+		switch (tile_sz)
+		  {
+		  case TILE_256:
+		      coverage = "plt1_lzma_256";
+		      break;
+		  case TILE_512:
+		      coverage = "plt1_lzma_512";
+		      break;
+		  case TILE_1024:
+		      coverage = "plt1_lzma_1024";
+		      break;
+		  };
+		break;
 	    };
 	  break;
       };
@@ -570,6 +628,22 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel,
 	  compression_name = "NONE";
 	  qlty = 100;
 	  break;
+      case RL2_COMPRESSION_DEFLATE:
+	  compression_name = "DEFLATE";
+	  qlty = 100;
+	  break;
+      case RL2_COMPRESSION_DEFLATE_NO:
+	  compression_name = "DEFLATE_NO";
+	  qlty = 100;
+	  break;
+      case RL2_COMPRESSION_LZMA:
+	  compression_name = "LZMA";
+	  qlty = 100;
+	  break;
+      case RL2_COMPRESSION_LZMA_NO:
+	  compression_name = "LZMA_NO";
+	  qlty = 100;
+	  break;
       case RL2_COMPRESSION_PNG:
 	  compression_name = "PNG";
 	  qlty = 100;
@@ -593,7 +667,7 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel,
       };
 
 /* creating the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_CreateCoverage("
+    sql = sqlite3_mprintf ("SELECT RL2_CreateRasterCoverage("
 			   "%Q, %Q, %Q, %d, %Q, %d, %d, %d, %d, %1.2f, %1.2f, "
 			   "RL2_SetPixelValue(RL2_CreatePixel(%Q, %Q, 1), 0, 0))",
 			   coverage, sample_name, pixel_name, num_bands,
@@ -603,7 +677,7 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel,
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "CreateCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "CreateRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -627,8 +701,7 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel,
       }
 
 /* deleting the first section */
-    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, %Q, 1)",
-			   coverage, "cap1");
+    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, 1, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -861,7 +934,7 @@ drop_coverage (sqlite3 * sqlite, unsigned char pixel,
 /* dropping some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
+    const char *coverage = NULL;
     char *sql;
 
 /* setting the coverage name */
@@ -912,6 +985,34 @@ drop_coverage (sqlite3 * sqlite, unsigned char pixel,
 		      break;
 		  };
 		break;
+	    case RL2_COMPRESSION_DEFLATE:
+		switch (tile_sz)
+		  {
+		  case TILE_256:
+		      coverage = "mono_deflate_256";
+		      break;
+		  case TILE_512:
+		      coverage = "mono_deflate_256_512";
+		      break;
+		  case TILE_1024:
+		      coverage = "mono_deflate_256_1024";
+		      break;
+		  };
+		break;
+	    case RL2_COMPRESSION_LZMA:
+		switch (tile_sz)
+		  {
+		  case TILE_256:
+		      coverage = "mono_lzma_256";
+		      break;
+		  case TILE_512:
+		      coverage = "mono_lzma_256_512";
+		      break;
+		  case TILE_1024:
+		      coverage = "mono_lzma_256_1024";
+		      break;
+		  };
+		break;
 	    };
 	  break;
       case RL2_PIXEL_PALETTE:
@@ -945,17 +1046,45 @@ drop_coverage (sqlite3 * sqlite, unsigned char pixel,
 		      break;
 		  };
 		break;
+	    case RL2_COMPRESSION_DEFLATE:
+		switch (tile_sz)
+		  {
+		  case TILE_256:
+		      coverage = "plt1_deflate_256";
+		      break;
+		  case TILE_512:
+		      coverage = "plt1_deflate_512";
+		      break;
+		  case TILE_1024:
+		      coverage = "plt1_deflate_1024";
+		      break;
+		  };
+		break;
+	    case RL2_COMPRESSION_LZMA:
+		switch (tile_sz)
+		  {
+		  case TILE_256:
+		      coverage = "plt1_lzma_256";
+		      break;
+		  case TILE_512:
+		      coverage = "plt1_lzma_512";
+		      break;
+		  case TILE_1024:
+		      coverage = "plt1_lzma_1024";
+		      break;
+		  };
+		break;
 	    };
 	  break;
       };
 
 /* dropping the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_DropCoverage(%Q, 1)", coverage);
+    sql = sqlite3_mprintf ("SELECT RL2_DropRasterCoverage(%Q, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "DropCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "DropRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -973,6 +1102,7 @@ main (int argc, char *argv[])
     char *err_msg = NULL;
     sqlite3 *db_handle;
     void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
     char *old_SPATIALITE_SECURITY_ENV = NULL;
 
     if (argc > 1 || argv[0] == NULL)
@@ -995,7 +1125,7 @@ main (int argc, char *argv[])
 	  return -1;
       }
     spatialite_init_ex (db_handle, cache, 0);
-    rl2_init (db_handle, 0);
+    rl2_init (db_handle, priv_data, 0);
     ret =
 	sqlite3_exec (db_handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
 		      &err_msg);
@@ -1056,6 +1186,37 @@ main (int argc, char *argv[])
 	(db_handle, RL2_PIXEL_MONOCHROME, RL2_COMPRESSION_CCITTFAX4, TILE_1024,
 	 &ret))
 	return ret;
+    ret = -360;
+    if (!test_coverage
+	(db_handle, RL2_PIXEL_MONOCHROME, RL2_COMPRESSION_DEFLATE, TILE_256,
+	 &ret))
+	return ret;
+    ret = -380;
+    if (!test_coverage
+	(db_handle, RL2_PIXEL_MONOCHROME, RL2_COMPRESSION_DEFLATE, TILE_512,
+	 &ret))
+	return ret;
+    ret = -390;
+    if (!test_coverage
+	(db_handle, RL2_PIXEL_MONOCHROME, RL2_COMPRESSION_DEFLATE, TILE_1024,
+	 &ret))
+	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
+    ret = -410;
+    if (!test_coverage
+	(db_handle, RL2_PIXEL_MONOCHROME, RL2_COMPRESSION_LZMA, TILE_256, &ret))
+	return ret;
+    ret = -420;
+    if (!test_coverage
+	(db_handle, RL2_PIXEL_MONOCHROME, RL2_COMPRESSION_LZMA, TILE_512, &ret))
+	return ret;
+    ret = -420;
+    if (!test_coverage
+	(db_handle, RL2_PIXEL_MONOCHROME, RL2_COMPRESSION_LZMA, TILE_1024,
+	 &ret))
+	return ret;
+#endif /* end LZMA conditional */
 
 /* PALETTE tests */
     ret = -400;
@@ -1082,6 +1243,34 @@ main (int argc, char *argv[])
     if (!test_coverage
 	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_PNG, TILE_1024, &ret))
 	return ret;
+    ret = -560;
+    if (!test_coverage
+	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_DEFLATE, TILE_256, &ret))
+	return ret;
+    ret = -580;
+    if (!test_coverage
+	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_DEFLATE, TILE_512, &ret))
+	return ret;
+    ret = -600;
+    if (!test_coverage
+	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_DEFLATE, TILE_1024,
+	 &ret))
+	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
+    ret = -620;
+    if (!test_coverage
+	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_LZMA, TILE_256, &ret))
+	return ret;
+    ret = -640;
+    if (!test_coverage
+	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_LZMA, TILE_512, &ret))
+	return ret;
+    ret = -660;
+    if (!test_coverage
+	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
+	return ret;
+#endif /* end LZMA conditional */
 
 /* dropping all MONOCHROME Coverages */
     ret = -170;
@@ -1124,6 +1313,37 @@ main (int argc, char *argv[])
 	(db_handle, RL2_PIXEL_MONOCHROME, RL2_COMPRESSION_CCITTFAX4, TILE_1024,
 	 &ret))
 	return ret;
+    ret = -400;
+    if (!drop_coverage
+	(db_handle, RL2_PIXEL_MONOCHROME, RL2_COMPRESSION_DEFLATE, TILE_256,
+	 &ret))
+	return ret;
+    ret = -410;
+    if (!drop_coverage
+	(db_handle, RL2_PIXEL_MONOCHROME, RL2_COMPRESSION_DEFLATE, TILE_512,
+	 &ret))
+	return ret;
+    ret = -420;
+    if (!drop_coverage
+	(db_handle, RL2_PIXEL_MONOCHROME, RL2_COMPRESSION_DEFLATE, TILE_1024,
+	 &ret))
+	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
+    ret = -430;
+    if (!drop_coverage
+	(db_handle, RL2_PIXEL_MONOCHROME, RL2_COMPRESSION_LZMA, TILE_256, &ret))
+	return ret;
+    ret = -440;
+    if (!drop_coverage
+	(db_handle, RL2_PIXEL_MONOCHROME, RL2_COMPRESSION_LZMA, TILE_512, &ret))
+	return ret;
+    ret = -450;
+    if (!drop_coverage
+	(db_handle, RL2_PIXEL_MONOCHROME, RL2_COMPRESSION_LZMA, TILE_1024,
+	 &ret))
+	return ret;
+#endif /* end LZMA conditional */
 
 /* dropping all PALETTE Coverages */
     ret = -470;
@@ -1150,9 +1370,39 @@ main (int argc, char *argv[])
     if (!drop_coverage
 	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_PNG, TILE_1024, &ret))
 	return ret;
+    ret = -600;
+    if (!drop_coverage
+	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_DEFLATE, TILE_256, &ret))
+	return ret;
+    ret = -610;
+    if (!drop_coverage
+	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_DEFLATE, TILE_512, &ret))
+	return ret;
+    ret = -620;
+    if (!drop_coverage
+	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_DEFLATE, TILE_1024,
+	 &ret))
+	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
+    ret = -630;
+    if (!drop_coverage
+	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_LZMA, TILE_256, &ret))
+	return ret;
+    ret = -640;
+    if (!drop_coverage
+	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_LZMA, TILE_512, &ret))
+	return ret;
+    ret = -650;
+    if (!drop_coverage
+	(db_handle, RL2_PIXEL_PALETTE, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
+	return ret;
+#endif /* end LZMA conditional */
 
 /* closing the DB */
     sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
     spatialite_shutdown ();
     if (old_SPATIALITE_SECURITY_ENV)
       {
diff --git a/test/test_map_nile_32.c b/test/test_map_nile_32.c
index 064e40f..7ca5800 100644
--- a/test/test_map_nile_32.c
+++ b/test/test_map_nile_32.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -84,14 +84,14 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
 /* testing some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
-    const char *sample_name;
-    const char *pixel_name;
-    unsigned char num_bands;
-    const char *compression_name;
+    const char *coverage = NULL;
+    const char *sample_name = NULL;
+    const char *pixel_name = NULL;
+    unsigned char num_bands = NULL;
+    const char *compression_name = NULL;
     int qlty = 100;
     char *sql;
-    int tile_size;
+    int tile_size = 256;
 
 /* setting the coverage name */
     switch (sample)
@@ -228,7 +228,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
       };
 
 /* creating the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_CreateCoverage("
+    sql = sqlite3_mprintf ("SELECT RL2_CreateRasterCoverage("
 			   "%Q, %Q, %Q, %d, %Q, %d, %d, %d, %d, %1.8f, %1.8f)",
 			   coverage, sample_name, pixel_name, num_bands,
 			   compression_name, qlty, tile_size, tile_size, 4326,
@@ -237,7 +237,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "CreateCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "CreateRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -261,8 +261,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
       }
 
 /* deleting the first section */
-    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, %Q, 1)",
-			   coverage, "nile1-int32");
+    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, 1, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -299,6 +298,7 @@ main (int argc, char *argv[])
     char *err_msg = NULL;
     sqlite3 *db_handle;
     void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
     char *old_SPATIALITE_SECURITY_ENV = NULL;
 
     if (argc > 1 || argv[0] == NULL)
@@ -321,7 +321,7 @@ main (int argc, char *argv[])
 	  return -1;
       }
     spatialite_init_ex (db_handle, cache, 0);
-    rl2_init (db_handle, 0);
+    rl2_init (db_handle, priv_data, 0);
     ret =
 	sqlite3_exec (db_handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
 		      &err_msg);
@@ -393,6 +393,8 @@ main (int argc, char *argv[])
 
 /* closing the DB */
     sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
     spatialite_shutdown ();
     if (old_SPATIALITE_SECURITY_ENV)
       {
diff --git a/test/test_map_nile_8.c b/test/test_map_nile_8.c
index 9899b8c..bbad2f2 100644
--- a/test/test_map_nile_8.c
+++ b/test/test_map_nile_8.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -84,14 +84,14 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
 /* testing some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
-    const char *sample_name;
-    const char *pixel_name;
-    unsigned char num_bands;
-    const char *compression_name;
+    const char *coverage = NULL;
+    const char *sample_name = NULL;
+    const char *pixel_name = NULL;
+    unsigned char num_bands = 1;
+    const char *compression_name = NULL;
     int qlty = 100;
     char *sql;
-    int tile_size;
+    int tile_size = 256;
 
 /* setting the coverage name */
     switch (sample)
@@ -228,7 +228,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
       };
 
 /* creating the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_CreateCoverage("
+    sql = sqlite3_mprintf ("SELECT RL2_CreateRasterCoverage("
 			   "%Q, %Q, %Q, %d, %Q, %d, %d, %d, %d, %1.8f, %1.8f)",
 			   coverage, sample_name, pixel_name, num_bands,
 			   compression_name, qlty, tile_size, tile_size, 4326,
@@ -237,7 +237,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "CreateCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "CreateRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -261,8 +261,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
       }
 
 /* deleting the first section */
-    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, %Q, 1)",
-			   coverage, "nile1-int8");
+    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, 1, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -298,6 +297,7 @@ main (int argc, char *argv[])
     char *err_msg = NULL;
     sqlite3 *db_handle;
     void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
     char *old_SPATIALITE_SECURITY_ENV = NULL;
 
     if (argc > 1 || argv[0] == NULL)
@@ -320,7 +320,7 @@ main (int argc, char *argv[])
 	  return -1;
       }
     spatialite_init_ex (db_handle, cache, 0);
-    rl2_init (db_handle, 0);
+    rl2_init (db_handle, priv_data, 0);
     ret =
 	sqlite3_exec (db_handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
 		      &err_msg);
@@ -392,6 +392,8 @@ main (int argc, char *argv[])
 
 /* closing the DB */
     sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
     spatialite_shutdown ();
     if (old_SPATIALITE_SECURITY_ENV)
       {
diff --git a/test/test_map_nile_dbl.c b/test/test_map_nile_dbl.c
index d200473..ed72464 100644
--- a/test/test_map_nile_dbl.c
+++ b/test/test_map_nile_dbl.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -84,14 +84,14 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
 /* testing some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
-    const char *sample_name;
-    const char *pixel_name;
-    unsigned char num_bands;
-    const char *compression_name;
+    const char *coverage = NULL;
+    const char *sample_name = NULL;
+    const char *pixel_name = NULL;
+    unsigned char num_bands = 1;
+    const char *compression_name = NULL;
     int qlty = 100;
     char *sql;
-    int tile_size;
+    int tile_size = 256;
 
 /* setting the coverage name */
     switch (sample)
@@ -228,7 +228,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
       };
 
 /* creating the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_CreateCoverage("
+    sql = sqlite3_mprintf ("SELECT RL2_CreateRasterCoverage("
 			   "%Q, %Q, %Q, %d, %Q, %d, %d, %d, %d, %1.8f, %1.8f)",
 			   coverage, sample_name, pixel_name, num_bands,
 			   compression_name, qlty, tile_size, tile_size, 4326,
@@ -237,7 +237,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "CreateCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "CreateRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -261,8 +261,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
       }
 
 /* deleting the first section */
-    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, %Q, 1)",
-			   coverage, "nile1-dbl");
+    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, 1, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -298,6 +297,7 @@ main (int argc, char *argv[])
     char *err_msg = NULL;
     sqlite3 *db_handle;
     void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
     char *old_SPATIALITE_SECURITY_ENV = NULL;
 
     if (argc > 1 || argv[0] == NULL)
@@ -320,7 +320,7 @@ main (int argc, char *argv[])
 	  return -1;
       }
     spatialite_init_ex (db_handle, cache, 0);
-    rl2_init (db_handle, 0);
+    rl2_init (db_handle, priv_data, 0);
     ret =
 	sqlite3_exec (db_handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
 		      &err_msg);
@@ -392,6 +392,8 @@ main (int argc, char *argv[])
 
 /* closing the DB */
     sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
     spatialite_shutdown ();
     if (old_SPATIALITE_SECURITY_ENV)
       {
diff --git a/test/test_map_nile_flt.c b/test/test_map_nile_flt.c
index 8c87787..a0dc702 100644
--- a/test/test_map_nile_flt.c
+++ b/test/test_map_nile_flt.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -84,14 +84,14 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
 /* testing some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
-    const char *sample_name;
-    const char *pixel_name;
-    unsigned char num_bands;
-    const char *compression_name;
+    const char *coverage = NULL;
+    const char *sample_name = NULL;
+    const char *pixel_name = NULL;
+    unsigned char num_bands = 1;
+    const char *compression_name = NULL;
     int qlty = 100;
     char *sql;
-    int tile_size;
+    int tile_size = 256;
 
 /* setting the coverage name */
     switch (sample)
@@ -228,7 +228,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
       };
 
 /* creating the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_CreateCoverage("
+    sql = sqlite3_mprintf ("SELECT RL2_CreateRasterCoverage("
 			   "%Q, %Q, %Q, %d, %Q, %d, %d, %d, %d, %1.8f, %1.8f)",
 			   coverage, sample_name, pixel_name, num_bands,
 			   compression_name, qlty, tile_size, tile_size, 4326,
@@ -237,7 +237,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "CreateCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "CreateRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -261,8 +261,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
       }
 
 /* deleting the first section */
-    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, %Q, 1)",
-			   coverage, "nile1-flt");
+    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q,1, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -298,6 +297,7 @@ main (int argc, char *argv[])
     char *err_msg = NULL;
     sqlite3 *db_handle;
     void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
     char *old_SPATIALITE_SECURITY_ENV = NULL;
 
     if (argc > 1 || argv[0] == NULL)
@@ -320,7 +320,7 @@ main (int argc, char *argv[])
 	  return -1;
       }
     spatialite_init_ex (db_handle, cache, 0);
-    rl2_init (db_handle, 0);
+    rl2_init (db_handle, priv_data, 0);
     ret =
 	sqlite3_exec (db_handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
 		      &err_msg);
@@ -392,6 +392,8 @@ main (int argc, char *argv[])
 
 /* closing the DB */
     sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
     spatialite_shutdown ();
     if (old_SPATIALITE_SECURITY_ENV)
       {
diff --git a/test/test_map_nile_u16.c b/test/test_map_nile_u16.c
index d19520c..da44723 100644
--- a/test/test_map_nile_u16.c
+++ b/test/test_map_nile_u16.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -84,14 +84,14 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
 /* testing some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
-    const char *sample_name;
-    const char *pixel_name;
-    unsigned char num_bands;
-    const char *compression_name;
+    const char *coverage = NULL;
+    const char *sample_name = NULL;
+    const char *pixel_name = NULL;
+    unsigned char num_bands = 1;
+    const char *compression_name = NULL;
     int qlty = 100;
     char *sql;
-    int tile_size;
+    int tile_size = 256;
 
 /* setting the coverage name */
     switch (sample)
@@ -228,7 +228,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
       };
 
 /* creating the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_CreateCoverage("
+    sql = sqlite3_mprintf ("SELECT RL2_CreateRasterCoverage("
 			   "%Q, %Q, %Q, %d, %Q, %d, %d, %d, %d, %1.8f, %1.8f)",
 			   coverage, sample_name, pixel_name, num_bands,
 			   compression_name, qlty, tile_size, tile_size, 4326,
@@ -237,7 +237,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "CreateCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "CreateRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -261,8 +261,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
       }
 
 /* deleting the first section */
-    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, %Q, 1)",
-			   coverage, "nile1-uint16");
+    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, 1, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -299,6 +298,7 @@ main (int argc, char *argv[])
     char *err_msg = NULL;
     sqlite3 *db_handle;
     void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
     char *old_SPATIALITE_SECURITY_ENV = NULL;
 
     if (argc > 1 || argv[0] == NULL)
@@ -321,7 +321,7 @@ main (int argc, char *argv[])
 	  return -1;
       }
     spatialite_init_ex (db_handle, cache, 0);
-    rl2_init (db_handle, 0);
+    rl2_init (db_handle, priv_data, 0);
     ret =
 	sqlite3_exec (db_handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
 		      &err_msg);
@@ -393,6 +393,8 @@ main (int argc, char *argv[])
 
 /* closing the DB */
     sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
     spatialite_shutdown ();
     if (old_SPATIALITE_SECURITY_ENV)
       {
diff --git a/test/test_map_nile_u32.c b/test/test_map_nile_u32.c
index 6990e47..3bb13be 100644
--- a/test/test_map_nile_u32.c
+++ b/test/test_map_nile_u32.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -84,14 +84,14 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
 /* testing some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
-    const char *sample_name;
-    const char *pixel_name;
-    unsigned char num_bands;
-    const char *compression_name;
+    const char *coverage = NULL;
+    const char *sample_name = NULL;
+    const char *pixel_name = NULL;
+    unsigned char num_bands = 0;
+    const char *compression_name = NULL;
     int qlty = 100;
     char *sql;
-    int tile_size;
+    int tile_size = 256;
 
 /* setting the coverage name */
     switch (sample)
@@ -228,7 +228,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
       };
 
 /* creating the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_CreateCoverage("
+    sql = sqlite3_mprintf ("SELECT RL2_CreateRasterCoverage("
 			   "%Q, %Q, %Q, %d, %Q, %d, %d, %d, %d, %1.8f, %1.8f)",
 			   coverage, sample_name, pixel_name, num_bands,
 			   compression_name, qlty, tile_size, tile_size, 4326,
@@ -237,7 +237,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "CreateCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "CreateRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -261,8 +261,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
       }
 
 /* deleting the first section */
-    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, %Q, 1)",
-			   coverage, "nile1-uint32");
+    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, 1, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -299,6 +298,7 @@ main (int argc, char *argv[])
     char *err_msg = NULL;
     sqlite3 *db_handle;
     void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
     char *old_SPATIALITE_SECURITY_ENV = NULL;
 
     if (argc > 1 || argv[0] == NULL)
@@ -321,7 +321,7 @@ main (int argc, char *argv[])
 	  return -1;
       }
     spatialite_init_ex (db_handle, cache, 0);
-    rl2_init (db_handle, 0);
+    rl2_init (db_handle, priv_data, 0);
     ret =
 	sqlite3_exec (db_handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
 		      &err_msg);
@@ -393,6 +393,8 @@ main (int argc, char *argv[])
 
 /* closing the DB */
     sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
     spatialite_shutdown ();
     if (old_SPATIALITE_SECURITY_ENV)
       {
diff --git a/test/test_map_nile_u8.c b/test/test_map_nile_u8.c
index d219a29..e90caf7 100644
--- a/test/test_map_nile_u8.c
+++ b/test/test_map_nile_u8.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -84,14 +84,14 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
 /* testing some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
-    const char *sample_name;
-    const char *pixel_name;
-    unsigned char num_bands;
-    const char *compression_name;
+    const char *coverage = NULL;
+    const char *sample_name = NULL;
+    const char *pixel_name = NULL;
+    unsigned char num_bands = 1;
+    const char *compression_name = NULL;
     int qlty = 100;
     char *sql;
-    int tile_size;
+    int tile_size = 256;
 
 /* setting the coverage name */
     switch (sample)
@@ -228,7 +228,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
       };
 
 /* creating the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_CreateCoverage("
+    sql = sqlite3_mprintf ("SELECT RL2_CreateRasterCoverage("
 			   "%Q, %Q, %Q, %d, %Q, %d, %d, %d, %d, %1.8f, %1.8f)",
 			   coverage, sample_name, pixel_name, num_bands,
 			   compression_name, qlty, tile_size, tile_size, 4326,
@@ -237,7 +237,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "CreateCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "CreateRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -261,8 +261,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample, int tile_sz,
       }
 
 /* deleting the first section */
-    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, %Q, 1)",
-			   coverage, "nile1-uint8");
+    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, 1, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -299,6 +298,7 @@ main (int argc, char *argv[])
     char *err_msg = NULL;
     sqlite3 *db_handle;
     void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
     char *old_SPATIALITE_SECURITY_ENV = NULL;
 
     if (argc > 1 || argv[0] == NULL)
@@ -321,7 +321,7 @@ main (int argc, char *argv[])
 	  return -1;
       }
     spatialite_init_ex (db_handle, cache, 0);
-    rl2_init (db_handle, 0);
+    rl2_init (db_handle, priv_data, 0);
     ret =
 	sqlite3_exec (db_handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
 		      &err_msg);
@@ -393,6 +393,8 @@ main (int argc, char *argv[])
 
 /* closing the DB */
     sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
     spatialite_shutdown ();
     if (old_SPATIALITE_SECURITY_ENV)
       {
diff --git a/test/test_map_noref.c b/test/test_map_noref.c
index 1e82fd9..24a4482 100644
--- a/test/test_map_noref.c
+++ b/test/test_map_noref.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -46,6 +46,8 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include <stdio.h>
 #include <string.h>
 
+#include "config.h"
+
 #include "sqlite3.h"
 #include "spatialite.h"
 
@@ -215,7 +217,7 @@ do_export_image (sqlite3 * sqlite, const char *coverage, gaiaGeomCollPtr geom,
     path = sqlite3_mprintf ("./%s_%1.0f%s", coverage, radius, suffix);
 
     sql =
-	"SELECT RL2_GetMapImage(?, ST_Buffer(?, ?), 512, 512, 'default', ?, '#ffffff', 1, 80)";
+	"SELECT RL2_GetMapImageFromRaster(?, ST_Buffer(?, ?), 512, 512, 'default', ?, '#ffffff', 1, 80)";
     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
 	return 0;
@@ -268,14 +270,14 @@ test_coverage (sqlite3 * sqlite, const char *prefix, unsigned char pixel,
 /* testing some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
-    const char *sample_name;
-    const char *pixel_name;
-    unsigned char num_bands;
-    const char *compression_name;
-    int qlty;
+    const char *coverage = NULL;
+    const char *sample_name = NULL;
+    const char *pixel_name = NULL;
+    unsigned char num_bands = 1;
+    const char *compression_name = NULL;
+    int qlty = 100;
     char *sql;
-    int tile_size;
+    int tile_size = 256;
     gaiaGeomCollPtr geom;
     char *cov_name;
     const char *file_path;
@@ -413,7 +415,7 @@ test_coverage (sqlite3 * sqlite, const char *prefix, unsigned char pixel,
 
 /* creating the DBMS Coverage */
     cov_name = sqlite3_mprintf ("%s_%s", prefix, coverage);
-    sql = sqlite3_mprintf ("SELECT RL2_CreateCoverage("
+    sql = sqlite3_mprintf ("SELECT RL2_CreateRasterCoverage("
 			   "%Q, %Q, %Q, %d, %Q, %d, %d, %d, %d, %1.16f, %1.16f)",
 			   cov_name, sample_name, pixel_name, num_bands,
 			   compression_name, qlty, tile_size, tile_size, -1,
@@ -422,7 +424,7 @@ test_coverage (sqlite3 * sqlite, const char *prefix, unsigned char pixel,
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "CreateCoverage \"%s\" error: %s\n", cov_name,
+	  fprintf (stderr, "CreateRasterCoverage \"%s\" error: %s\n", cov_name,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -534,7 +536,7 @@ drop_coverage (sqlite3 * sqlite, const char *prefix, unsigned char pixel,
 /* dropping some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
+    const char *coverage = NULL;
     char *cov_name;
     char *sql;
 
@@ -610,12 +612,12 @@ drop_coverage (sqlite3 * sqlite, const char *prefix, unsigned char pixel,
 
 /* dropping the DBMS Coverage */
     cov_name = sqlite3_mprintf ("%s_%s", prefix, coverage);
-    sql = sqlite3_mprintf ("SELECT RL2_DropCoverage(%Q, 1)", cov_name);
+    sql = sqlite3_mprintf ("SELECT RL2_DropRasterCoverage(%Q, 1)", cov_name);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "DropCoverage \"%s\" error: %s\n", cov_name,
+	  fprintf (stderr, "DropRasterCoverage \"%s\" error: %s\n", cov_name,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -635,6 +637,7 @@ main (int argc, char *argv[])
     char *err_msg = NULL;
     sqlite3 *db_handle;
     void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
     char *old_SPATIALITE_SECURITY_ENV = NULL;
 
     if (argc > 1 || argv[0] == NULL)
@@ -657,7 +660,7 @@ main (int argc, char *argv[])
 	  return -1;
       }
     spatialite_init_ex (db_handle, cache, 0);
-    rl2_init (db_handle, 0);
+    rl2_init (db_handle, priv_data, 0);
     ret =
 	sqlite3_exec (db_handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
 		      &err_msg);
@@ -690,6 +693,8 @@ main (int argc, char *argv[])
     if (!test_coverage
 	(db_handle, "noref-rgb", RL2_PIXEL_RGB, RL2_COMPRESSION_JPEG, &ret))
 	return ret;
+
+#ifndef OMIT_WEBP		/* only if WebP is enabled */
     ret = -160;
     if (!test_coverage
 	(db_handle, "noref-rgb", RL2_PIXEL_RGB, RL2_COMPRESSION_LOSSY_WEBP,
@@ -700,6 +705,7 @@ main (int argc, char *argv[])
 	(db_handle, "noref-rgb", RL2_PIXEL_RGB, RL2_COMPRESSION_LOSSLESS_WEBP,
 	 &ret))
 	return ret;
+#endif /* end WebP conditional */
 
 /* GRAYSCALE tests */
     ret = -300;
@@ -717,6 +723,8 @@ main (int argc, char *argv[])
 	(db_handle, "noref-gray", RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_JPEG,
 	 &ret))
 	return ret;
+
+#ifndef OMIT_WEBP		/* only if WebP is enabled */
     ret = -360;
     if (!test_coverage
 	(db_handle, "noref-gray", RL2_PIXEL_GRAYSCALE,
@@ -727,6 +735,7 @@ main (int argc, char *argv[])
 	(db_handle, "noref-gray", RL2_PIXEL_GRAYSCALE,
 	 RL2_COMPRESSION_LOSSLESS_WEBP, &ret))
 	return ret;
+#endif /* end WebP conditional */
 
 /* MONOCHROME tests */
     ret = -500;
@@ -768,6 +777,8 @@ main (int argc, char *argv[])
     if (!drop_coverage
 	(db_handle, "noref-rgb", RL2_PIXEL_RGB, RL2_COMPRESSION_JPEG, &ret))
 	return ret;
+
+#ifndef OMIT_WEBP		/* only if WebP is enabled */
     ret = -230;
     if (!drop_coverage
 	(db_handle, "noref-rgb", RL2_PIXEL_RGB, RL2_COMPRESSION_LOSSY_WEBP,
@@ -778,6 +789,7 @@ main (int argc, char *argv[])
 	(db_handle, "noref-rgb", RL2_PIXEL_RGB, RL2_COMPRESSION_LOSSLESS_WEBP,
 	 &ret))
 	return ret;
+#endif /* end WebP conditional */
 
 /* dropping all GRAYSCALE Coverages */
     ret = -400;
@@ -795,6 +807,8 @@ main (int argc, char *argv[])
 	(db_handle, "noref-gray", RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_JPEG,
 	 &ret))
 	return ret;
+
+#ifndef OMIT_WEBP		/* only if WebP is enabled */
     ret = -430;
     if (!drop_coverage
 	(db_handle, "noref-gray", RL2_PIXEL_GRAYSCALE,
@@ -805,6 +819,7 @@ main (int argc, char *argv[])
 	(db_handle, "noref-gray", RL2_PIXEL_GRAYSCALE,
 	 RL2_COMPRESSION_LOSSLESS_WEBP, &ret))
 	return ret;
+#endif /* end WebP conditional */
 
 /* dropping all MONOCHROME Coverages */
     ret = -600;
@@ -835,6 +850,8 @@ main (int argc, char *argv[])
 
 /* closing the DB */
     sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
     spatialite_shutdown ();
     if (old_SPATIALITE_SECURITY_ENV)
       {
diff --git a/test/test_map_orbetello.c b/test/test_map_orbetello.c
index e01f0fc..47f75fc 100644
--- a/test/test_map_orbetello.c
+++ b/test/test_map_orbetello.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -46,6 +46,8 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include <stdio.h>
 #include <string.h>
 
+#include "config.h"
+
 #include "sqlite3.h"
 #include "spatialite.h"
 #include "spatialite/gaiaaux.h"
@@ -57,6 +59,24 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #define TILE_1024	1024
 
 static int
+execute_with_retval (sqlite3 * sqlite, const char *sql)
+{
+/* executing an SQL statement then returning an INT result */
+    sqlite3_stmt *stmt;
+    int ret;
+    int retcode = -1;
+
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return SQLITE_ERROR;
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+	retcode = sqlite3_column_int (stmt, 0);
+    sqlite3_finalize (stmt);
+    return retcode;
+}
+
+static int
 execute_check (sqlite3 * sqlite, const char *sql)
 {
 /* executing an SQL statement returning True/False */
@@ -136,10 +156,42 @@ get_max_tile_id (sqlite3 * sqlite, const char *coverage)
 }
 
 static int
-do_export_tile_image (sqlite3 * sqlite, const char *coverage, int tile_id,
-		      int band_mix)
+do_export_tile_image (sqlite3 * sqlite, const char *coverage, int tile_id)
+{
+/* attempting to export a visible Tile - basic */
+    char *sql;
+    char *path;
+    int ret;
+    int transparent = 1;
+
+    if (tile_id > 10)
+	transparent = 0;
+    if (tile_id < 0)
+	tile_id = get_max_tile_id (sqlite, coverage);
+    path = sqlite3_mprintf ("./%s_tile_%d.png", coverage, tile_id);
+    sql =
+	sqlite3_mprintf
+	("SELECT BlobToFile(RL2_GetTileImage(%Q, %d, '#e0ffe0', %d), %Q)",
+	 coverage, tile_id, transparent, path);
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    unlink (path);
+    sqlite3_free (path);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr,
+		   "ERROR: Unable to export an Image from \"%s\" tile_id=%d\n",
+		   coverage, tile_id);
+	  return 0;
+      }
+    return 1;
+}
+
+static int
+do_export_tile_image3 (sqlite3 * sqlite, const char *coverage, int tile_id,
+		       int band_mix)
 {
-/* attempting to export a visible Tile */
+/* attempting to export a visible Tile - triple band */
     char *sql;
     char *path;
     int ret;
@@ -773,7 +825,7 @@ do_export_map_image (sqlite3 * sqlite, const char *coverage,
 			 monolithic ? "mono" : "sect", style, suffix);
 
     sql =
-	"SELECT BlobToFile(RL2_GetMapImage(?, ST_Buffer(?, 2000), ?, ?, ?, ?, ?, ?), ?)";
+	"SELECT BlobToFile(RL2_GetMapImageFromRaster(?, ST_Buffer(?, 2000), ?, ?, ?, ?, ?, ?), ?)";
     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
 	return 0;
@@ -803,6 +855,58 @@ do_export_map_image (sqlite3 * sqlite, const char *coverage,
     return retcode;
 }
 
+static int
+do_export_ndvi (sqlite3 * sqlite, const char *coverage, gaiaGeomCollPtr geom)
+{
+/* exporting an NDVI Ascii Grid */
+    char *sql;
+    const char *path = "./ndvi16_ascii_grid.asc";
+    sqlite3_stmt *stmt;
+    int ret;
+    double x_res;
+    double y_res;
+    double xx_res;
+    double yy_res;
+    unsigned char *blob;
+    int blob_size;
+    int retcode = 0;
+    double scale = 1.0;
+
+    if (!get_base_resolution (sqlite, coverage, &x_res, &y_res))
+	return 0;
+    xx_res = x_res * (double) scale;
+    yy_res = y_res * (double) scale;
+    if (xx_res != yy_res)
+	xx_res = (xx_res + yy_res) / 2.0;
+
+    sql = "SELECT RL2_WriteNdviAsciiGrid(?, ?, ?, ?, ?, ?, ?, ?)";
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return 0;
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
+    sqlite3_bind_text (stmt, 2, path, strlen (path), SQLITE_STATIC);
+    sqlite3_bind_int (stmt, 3, 1024);
+    sqlite3_bind_int (stmt, 4, 1024);
+    sqlite3_bind_int (stmt, 5, 2);	/* red band */
+    sqlite3_bind_int (stmt, 6, 3);	/* NIR band */
+    gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
+    sqlite3_bind_blob (stmt, 7, blob, blob_size, free);
+    sqlite3_bind_double (stmt, 8, xx_res);
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+      {
+	  if (sqlite3_column_int (stmt, 0) == 1)
+	      retcode = 1;
+      }
+    sqlite3_finalize (stmt);
+    unlink (path);
+    if (!retcode)
+	fprintf (stderr, "ERROR: unable to export \"%s\"\n", path);
+    return retcode;
+}
+
 static gaiaGeomCollPtr
 get_center_point (sqlite3 * sqlite, const char *coverage)
 {
@@ -840,19 +944,57 @@ get_center_point (sqlite3 * sqlite, const char *coverage)
 }
 
 static int
+set_default_bands (sqlite3 * sqlite, const char *coverage)
+{
+/* enabling default bands and Auto NDVI */
+    int ret;
+    char *sql;
+    char *err_msg = NULL;
+
+    sql =
+	sqlite3_mprintf
+	("SELECT RL2_SetRasterCoverageDefaultBands(%Q, 2, 1, 0, 3)", coverage);
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr,
+		   "SetRasterCoverageDefaultBands #1 \"%s\" error: %s\n",
+		   coverage, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+    sql =
+	sqlite3_mprintf ("SELECT RL2_EnableRasterCoverageAutoNDVI(%Q, 1)",
+			 coverage);
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "EnableRasterCoverageAutoNDVI #3 \"%s\" error: %s\n",
+		   coverage, err_msg);
+	  sqlite3_free (err_msg);
+	  return 0;
+      }
+
+    return 1;
+}
+
+static int
 test_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
 	       int *retcode)
 {
 /* testing some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
-    const char *sample_name;
-    const char *pixel_name;
-    unsigned char num_bands;
-    const char *compression_name;
-    int qlty;
-    int tile_size;
+    const char *coverage = NULL;
+    const char *sample_name = NULL;
+    const char *pixel_name = NULL;
+    unsigned char num_bands = 1;
+    const char *compression_name = NULL;
+    int qlty = 100;
+    int tile_size = 256;
     char *sql;
     gaiaGeomCollPtr geom;
     int test_map_image = 0;
@@ -860,46 +1002,46 @@ test_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
 /* setting the coverage name */
     switch (compression)
       {
-      case RL2_COMPRESSION_NONE:
+      case RL2_COMPRESSION_CHARLS:
 	  switch (tile_sz)
 	    {
 	    case TILE_256:
-		coverage = "orbetello_none_256";
+		coverage = "orbetello_charls_256";
 		test_map_image = 1;
 		break;
 	    case TILE_512:
-		coverage = "orbetello_none_512";
+		coverage = "orbetello_charls_512";
 		break;
 	    case TILE_1024:
-		coverage = "orbetello_none_1024";
+		coverage = "orbetello_charls_1024";
 		break;
 	    };
 	  break;
-      case RL2_COMPRESSION_DEFLATE:
+      case RL2_COMPRESSION_LOSSY_JP2:
 	  switch (tile_sz)
 	    {
 	    case TILE_256:
-		coverage = "orbetello_zip_256";
+		coverage = "orbetello_jp2_256";
 		break;
 	    case TILE_512:
-		coverage = "orbetello_zip_512";
+		coverage = "orbetello_jp2_512";
 		break;
 	    case TILE_1024:
-		coverage = "orbetello_zip_1024";
+		coverage = "orbetello_jp2_1024";
 		break;
 	    };
 	  break;
-      case RL2_COMPRESSION_LZMA:
+      case RL2_COMPRESSION_PNG:
 	  switch (tile_sz)
 	    {
 	    case TILE_256:
-		coverage = "orbetello_lzma_256";
+		coverage = "orbetello_png_256";
 		break;
 	    case TILE_512:
-		coverage = "orbetello_lzma_512";
+		coverage = "orbetello_png_512";
 		break;
 	    case TILE_1024:
-		coverage = "orbetello_lzma_1024";
+		coverage = "orbetello_png_1024";
 		break;
 	    };
 	  break;
@@ -911,16 +1053,16 @@ test_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
     num_bands = 4;
     switch (compression)
       {
-      case RL2_COMPRESSION_NONE:
-	  compression_name = "NONE";
+      case RL2_COMPRESSION_CHARLS:
+	  compression_name = "CHARLS";
 	  qlty = 100;
 	  break;
-      case RL2_COMPRESSION_DEFLATE:
-	  compression_name = "DEFLATE";
+      case RL2_COMPRESSION_LOSSY_JP2:
+	  compression_name = "JP2";
 	  qlty = 100;
 	  break;
-      case RL2_COMPRESSION_LZMA:
-	  compression_name = "LZMA";
+      case RL2_COMPRESSION_PNG:
+	  compression_name = "PNG";
 	  qlty = 100;
 	  break;
       };
@@ -938,7 +1080,7 @@ test_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
       };
 
 /* creating the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_CreateCoverage("
+    sql = sqlite3_mprintf ("SELECT RL2_CreateRasterCoverage("
 			   "%Q, %Q, %Q, %d, %Q, %d, %d, %d, %d, %1.2f, %1.2f)",
 			   coverage, sample_name, pixel_name, num_bands,
 			   compression_name, qlty, tile_size, tile_size, 32632,
@@ -947,7 +1089,7 @@ test_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "CreateCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "CreateRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -986,9 +1128,7 @@ test_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
       }
 
 /* re-building the Pyramid Levels */
-    sql =
-	sqlite3_mprintf ("SELECT RL2_Pyramidize(%Q, %Q, 1, 1)", coverage,
-			 "orbetello1");
+    sql = sqlite3_mprintf ("SELECT RL2_Pyramidize(%Q, 1, 1, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -1013,9 +1153,7 @@ test_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
       }
 
 /* building yet again the Pyramid Levels */
-    sql =
-	sqlite3_mprintf ("SELECT RL2_Pyramidize(%Q, %Q, 1, 1)", coverage,
-			 "orbetello1");
+    sql = sqlite3_mprintf ("SELECT RL2_Pyramidize(%Q, 1, 1, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -1215,9 +1353,9 @@ test_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
 	goto skip;
 
 /* loading the RasterSymbolizers */
-    sql = sqlite3_mprintf ("SELECT RegisterRasterStyledLayer(%Q, "
-			   "XB_Create(XB_LoadXML(%Q), 1, 1))", coverage,
-			   "ir_false_color2.xml");
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 1)",
+			 coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -1228,149 +1366,181 @@ test_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
 	  *retcode += -42;
 	  return 0;
       }
-    sql = sqlite3_mprintf ("SELECT RegisterRasterStyledLayer(%Q, "
-			   "XB_Create(XB_LoadXML(%Q), 1, 1))", coverage,
-			   "ir_false_color2_gamma.xml");
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 2)",
+			 coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "RegisterRasterStyledLayer #1 \"%s\" error: %s\n",
+	  fprintf (stderr, "RegisterRasterStyledLayer #2 \"%s\" error: %s\n",
 		   coverage, err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -43;
 	  return 0;
       }
-    sql = sqlite3_mprintf ("SELECT RegisterRasterStyledLayer(%Q, "
-			   "XB_Create(XB_LoadXML(%Q), 1, 1))", coverage,
-			   "ir_gray.xml");
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 3)",
+			 coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "RegisterRasterStyledLayer #2 \"%s\" error: %s\n",
+	  fprintf (stderr, "RegisterRasterStyledLayer #3 \"%s\" error: %s\n",
 		   coverage, err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -44;
 	  return 0;
       }
-    sql = sqlite3_mprintf ("SELECT RegisterRasterStyledLayer(%Q, "
-			   "XB_Create(XB_LoadXML(%Q), 1, 1))", coverage,
-			   "ir_gray_gamma.xml");
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 4)",
+			 coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "RegisterRasterStyledLayer #3 \"%s\" error: %s\n",
+	  fprintf (stderr, "RegisterRasterStyledLayer #4 \"%s\" error: %s\n",
 		   coverage, err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -45;
 	  return 0;
       }
-    sql = sqlite3_mprintf ("SELECT RegisterRasterStyledLayer(%Q, "
-			   "XB_Create(XB_LoadXML(%Q), 1, 1))", coverage,
-			   "rgb_histogram.xml");
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 5)",
+			 coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "RegisterRasterStyledLayer #4 \"%s\" error: %s\n",
+	  fprintf (stderr, "RegisterRasterStyledLayer #5 \"%s\" error: %s\n",
 		   coverage, err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -46;
 	  return 0;
       }
-    sql = sqlite3_mprintf ("SELECT RegisterRasterStyledLayer(%Q, "
-			   "XB_Create(XB_LoadXML(%Q), 1, 1))", coverage,
-			   "rgb_normalize.xml");
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 6)",
+			 coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "RegisterRasterStyledLayer #5 \"%s\" error: %s\n",
+	  fprintf (stderr, "RegisterRasterStyledLayer #6 \"%s\" error: %s\n",
 		   coverage, err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -47;
 	  return 0;
       }
-    sql = sqlite3_mprintf ("SELECT RegisterRasterStyledLayer(%Q, "
-			   "XB_Create(XB_LoadXML(%Q), 1, 1))", coverage,
-			   "rgb_normalize2.xml");
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 7)",
+			 coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "RegisterRasterStyledLayer #6 \"%s\" error: %s\n",
+	  fprintf (stderr, "RegisterRasterStyledLayer #7 \"%s\" error: %s\n",
 		   coverage, err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -48;
 	  return 0;
       }
-    sql = sqlite3_mprintf ("SELECT RegisterRasterStyledLayer(%Q, "
-			   "XB_Create(XB_LoadXML(%Q), 1, 1))", coverage,
-			   "rgb_histogram2.xml");
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 8)",
+			 coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "RegisterRasterStyledLayer #7 \"%s\" error: %s\n",
+	  fprintf (stderr, "RegisterRasterStyledLayer #8 \"%s\" error: %s\n",
 		   coverage, err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -50;
 	  return 0;
       }
-    sql = sqlite3_mprintf ("SELECT RegisterRasterStyledLayer(%Q, "
-			   "XB_Create(XB_LoadXML(%Q), 1, 1))", coverage,
-			   "rgb_gamma.xml");
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 9)",
+			 coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "RegisterRasterStyledLayer #8 \"%s\" error: %s\n",
+	  fprintf (stderr, "RegisterRasterStyledLayer #9 \"%s\" error: %s\n",
 		   coverage, err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -51;
 	  return 0;
       }
-    sql = sqlite3_mprintf ("SELECT RegisterRasterStyledLayer(%Q, "
-			   "XB_Create(XB_LoadXML(%Q), 1, 1))", coverage,
-			   "gray_normalize2.xml");
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 10)",
+			 coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "RegisterRasterStyledLayer #9 \"%s\" error: %s\n",
+	  fprintf (stderr, "RegisterRasterStyledLayer #10 \"%s\" error: %s\n",
 		   coverage, err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -52;
 	  return 0;
       }
-    sql = sqlite3_mprintf ("SELECT RegisterRasterStyledLayer(%Q, "
-			   "XB_Create(XB_LoadXML(%Q), 1, 1))", coverage,
-			   "gray_histogram2.xml");
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 11)",
+			 coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "RegisterRasterStyledLayer #10 \"%s\" error: %s\n",
+	  fprintf (stderr, "RegisterRasterStyledLayer #11 \"%s\" error: %s\n",
 		   coverage, err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -53;
 	  return 0;
       }
-    sql = sqlite3_mprintf ("SELECT RegisterRasterStyledLayer(%Q, "
-			   "XB_Create(XB_LoadXML(%Q), 1, 1))", coverage,
-			   "gray_gamma2.xml");
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 12)",
+			 coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "RegisterRasterStyledLayer #11 \"%s\" error: %s\n",
+	  fprintf (stderr, "RegisterRasterStyledLayer #12 \"%s\" error: %s\n",
 		   coverage, err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -54;
 	  return 0;
       }
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 13)",
+			 coverage);
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyledLayer #13 \"%s\" error: %s\n",
+		   coverage, err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -167;
+	  return 0;
+      }
+
+/* testing NDVI Ascii Grid */
+    if (!do_export_ndvi (sqlite, coverage, geom))
+      {
+	  *retcode += -165;
+	  return 0;
+      }
+/* enabling auto NDVI */
+    if (!set_default_bands (sqlite, coverage))
+      {
+	  *retcode += -166;
+	  return 0;
+      }
+/* testing GetMapImage - NDVI */
+    if (!do_export_map_image (sqlite, coverage, geom, "ndvi", "png", 0))
+      {
+	  *retcode += 168;
+	  return 0;
+      }
 
 /* testing GetMapImage - IR false color */
     if (!do_export_map_image
@@ -1674,23 +1844,35 @@ test_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
   skip:
     gaiaFreeGeomColl (geom);
 
-/* testing GetTileImage() */
-    if (!do_export_tile_image (sqlite, coverage, 1, 0))
+/* testing GetTileImage() - basic */
+    if (!do_export_tile_image (sqlite, coverage, 1))
+      {
+	  *retcode += -162;
+	  return 0;
+      }
+    if (!do_export_tile_image (sqlite, coverage, -1))
+      {
+	  *retcode += -163;
+	  return 0;
+      }
+
+/* testing GetTileImage() - triple band */
+    if (!do_export_tile_image3 (sqlite, coverage, 1, 0))
       {
 	  *retcode += -62;
 	  return 0;
       }
-    if (!do_export_tile_image (sqlite, coverage, 1, 1))
+    if (!do_export_tile_image3 (sqlite, coverage, 1, 1))
       {
 	  *retcode += -63;
 	  return 0;
       }
-    if (!do_export_tile_image (sqlite, coverage, 1, 2))
+    if (!do_export_tile_image3 (sqlite, coverage, 1, 2))
       {
 	  *retcode += -64;
 	  return 0;
       }
-    if (!do_export_tile_image (sqlite, coverage, -1, 0))
+    if (!do_export_tile_image3 (sqlite, coverage, -1, 0))
       {
 	  *retcode += -65;
 	  return 0;
@@ -1718,7 +1900,7 @@ test_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
 	  return 0;
       }
 
-    if (compression == RL2_COMPRESSION_NONE && tile_sz == TILE_256)
+    if (compression == RL2_COMPRESSION_CHARLS && tile_sz == TILE_256)
       {
 	  /* testing a Monolithic Pyramid */
 	  geom = get_center_point (sqlite, coverage);
@@ -1759,57 +1941,318 @@ test_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
 }
 
 static int
+register_raster_symbolizers (sqlite3 * sqlite, int no_web_connection,
+			     int *retcode)
+{
+/* loading the RasterSymbolizers */
+    int ret;
+    char *err_msg = NULL;
+    char *sql;
+
+
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "ir_false_color2.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "ir_false_color2.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #1 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -1;
+	  return 0;
+      }
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "ir_false_color2_gamma.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "ir_false_color2_gamma.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #2 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -2;
+	  return 0;
+      }
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "ir_gray.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "ir_gray.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #3 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -3;
+	  return 0;
+      }
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "ir_gray_gamma.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "ir_gray_gamma.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #4 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -4;
+	  return 0;
+      }
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "rgb_histogram.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "rgb_histogram.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #5 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -5;
+	  return 0;
+      }
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "rgb_normalize.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "rgb_normalize.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #6 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -6;
+	  return 0;
+      }
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "rgb_normalize2.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "rgb_normalize2.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #7 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -7;
+	  return 0;
+      }
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "rgb_histogram2.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "rgb_histogram2.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #8 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -8;
+	  return 0;
+      }
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "rgb_gamma.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "rgb_gamma.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #9 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -9;
+	  return 0;
+      }
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "gray_normalize2.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "gray_normalize2.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #10 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -10;
+	  return 0;
+      }
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "gray_histogram2.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "gray_histogram2.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #11 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -11;
+	  return 0;
+      }
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "gray_gamma2.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "gray_gamma2.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #12 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -12;
+	  return 0;
+      }
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "ndvi.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "ndvi.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #13 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -13;
+	  return 0;
+      }
+
+    return 1;
+}
+
+static int
 drop_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
 	       int *retcode)
 {
 /* dropping some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
+    const char *coverage = NULL;
     char *sql;
 
 /* setting the coverage name */
     switch (compression)
       {
-      case RL2_COMPRESSION_NONE:
+      case RL2_COMPRESSION_CHARLS:
 	  switch (tile_sz)
 	    {
 	    case TILE_256:
-		coverage = "orbetello_none_256";
+		coverage = "orbetello_charls_256";
 		break;
 	    case TILE_512:
-		coverage = "orbetello_none_512";
+		coverage = "orbetello_charls_512";
 		break;
 	    case TILE_1024:
-		coverage = "orbetello_none_1024";
+		coverage = "orbetello_charls_1024";
 		break;
 	    };
 	  break;
-      case RL2_COMPRESSION_DEFLATE:
+      case RL2_COMPRESSION_LOSSY_JP2:
 	  switch (tile_sz)
 	    {
 	    case TILE_256:
-		coverage = "orbetello_zip_256";
+		coverage = "orbetello_jp2_256";
 		break;
 	    case TILE_512:
-		coverage = "orbetello_zip_512";
+		coverage = "orbetello_jp2_512";
 		break;
 	    case TILE_1024:
-		coverage = "orbetello_zip_1024";
+		coverage = "orbetello_jp2_1024";
 		break;
 	    };
 	  break;
-      case RL2_COMPRESSION_LZMA:
+      case RL2_COMPRESSION_PNG:
 	  switch (tile_sz)
 	    {
 	    case TILE_256:
-		coverage = "orbetello_lzma_256";
+		coverage = "orbetello_png_256";
 		break;
 	    case TILE_512:
-		coverage = "orbetello_lzma_512";
+		coverage = "orbetello_png_512";
 		break;
 	    case TILE_1024:
-		coverage = "orbetello_lzma_1024";
+		coverage = "orbetello_png_1024";
 		break;
 	    };
 	  break;
@@ -1817,26 +2260,26 @@ drop_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
 
 /* setting a Title and Abstract for this DBMS Coverage */
     sql =
-	sqlite3_mprintf ("SELECT RL2_SetCoverageInfos(%Q, %Q, %Q)", coverage,
-			 "this is a tile", "this is an abstact");
+	sqlite3_mprintf ("SELECT RL2_SetRasterCoverageInfos(%Q, %Q, %Q)",
+			 coverage, "this is a tile", "this is an abstact");
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "SetCoverageInfos \"%s\" error: %s\n", coverage,
-		   err_msg);
+	  fprintf (stderr, "SetRasterCoverageInfos \"%s\" error: %s\n",
+		   coverage, err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
 	  return 0;
       }
 
 /* dropping the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_DropCoverage(%Q, 1)", coverage);
+    sql = sqlite3_mprintf ("SELECT RL2_DropRasterCoverage(%Q, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "DropCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "DropRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -1849,16 +2292,28 @@ drop_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
 int
 main (int argc, char *argv[])
 {
+    int no_web_connection = 0;
     int result = 0;
     int ret;
     char *err_msg = NULL;
     sqlite3 *db_handle;
     void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
     char *old_SPATIALITE_SECURITY_ENV = NULL;
 
     if (argc > 1 || argv[0] == NULL)
 	argc = 1;		/* silencing stupid compiler warnings */
 
+    if (getenv ("ENABLE_RL2_WEB_TESTS") == NULL)
+      {
+	  fprintf (stderr,
+		   "this testcase has been executed with several limitations\n"
+		   "because it was not enabled to access the Web.\n\n"
+		   "you can enable all testcases requiring an Internet connection\n"
+		   "by setting the environment variable \"ENABLE_RL2_WEB_TESTS=1\"\n\n");
+	  no_web_connection = 1;
+      }
+
     old_SPATIALITE_SECURITY_ENV = getenv ("SPATIALITE_SECURITY");
 #ifdef _WIN32
     putenv ("SPATIALITE_SECURITY=relaxed");
@@ -1876,7 +2331,7 @@ main (int argc, char *argv[])
 	  return -1;
       }
     spatialite_init_ex (db_handle, cache, 0);
-    rl2_init (db_handle, 0);
+    rl2_init (db_handle, priv_data, 0);
     ret =
 	sqlite3_exec (db_handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
 		      &err_msg);
@@ -1895,76 +2350,211 @@ main (int argc, char *argv[])
 	  sqlite3_free (err_msg);
 	  return -3;
       }
-    ret =
-	sqlite3_exec (db_handle, "SELECT CreateStylingTables()", NULL,
-		      NULL, &err_msg);
+    if (no_web_connection)
+	ret =
+	    sqlite3_exec (db_handle, "SELECT CreateStylingTables(1)", NULL,
+			  NULL, &err_msg);
+    else
+	ret =
+	    sqlite3_exec (db_handle, "SELECT CreateStylingTables()", NULL,
+			  NULL, &err_msg);
     if (ret != SQLITE_OK)
       {
 	  fprintf (stderr, "CreateStylingTables() error: %s\n", err_msg);
 	  sqlite3_free (err_msg);
-	  return 4;
+	  return -4;
+      }
+    if (!register_raster_symbolizers (db_handle, no_web_connection, &ret))
+      {
+	  fprintf (stderr, "Register Raster Symbolizers error\n");
+	  return -5;
       }
 
 /* tests */
+#ifndef OMIT_CHARLS		/* only if CharLS is enabled */
     ret = -100;
-    if (!test_coverage (db_handle, RL2_COMPRESSION_NONE, TILE_256, &ret))
+    if (!test_coverage (db_handle, RL2_COMPRESSION_CHARLS, TILE_256, &ret))
 	return ret;
     ret = -120;
-    if (!test_coverage (db_handle, RL2_COMPRESSION_NONE, TILE_512, &ret))
+    if (!test_coverage (db_handle, RL2_COMPRESSION_CHARLS, TILE_512, &ret))
 	return ret;
     ret = -140;
-    if (!test_coverage (db_handle, RL2_COMPRESSION_NONE, TILE_1024, &ret))
+    if (!test_coverage (db_handle, RL2_COMPRESSION_CHARLS, TILE_1024, &ret))
 	return ret;
+#endif /* end CharLS conditional */
+
+#ifndef OMIT_OPENJPEG		/* only if OpenJpeg is enabled */
     ret = -200;
-    if (!test_coverage (db_handle, RL2_COMPRESSION_DEFLATE, TILE_256, &ret))
+    if (!test_coverage (db_handle, RL2_COMPRESSION_LOSSY_JP2, TILE_256, &ret))
 	return ret;
     ret = -220;
-    if (!test_coverage (db_handle, RL2_COMPRESSION_DEFLATE, TILE_512, &ret))
+    if (!test_coverage (db_handle, RL2_COMPRESSION_LOSSY_JP2, TILE_512, &ret))
 	return ret;
     ret = -240;
-    if (!test_coverage (db_handle, RL2_COMPRESSION_DEFLATE, TILE_1024, &ret))
+    if (!test_coverage (db_handle, RL2_COMPRESSION_LOSSY_JP2, TILE_1024, &ret))
 	return ret;
+#endif /* end OpenJpeg conditional */
+
     ret = -300;
-    if (!test_coverage (db_handle, RL2_COMPRESSION_LZMA, TILE_256, &ret))
+    if (!test_coverage (db_handle, RL2_COMPRESSION_PNG, TILE_256, &ret))
 	return ret;
     ret = -320;
-    if (!test_coverage (db_handle, RL2_COMPRESSION_LZMA, TILE_512, &ret))
+    if (!test_coverage (db_handle, RL2_COMPRESSION_PNG, TILE_512, &ret))
 	return ret;
     ret = -340;
-    if (!test_coverage (db_handle, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
+    if (!test_coverage (db_handle, RL2_COMPRESSION_PNG, TILE_1024, &ret))
 	return ret;
 
 /* dropping all Coverages */
+#ifndef OMIT_CHARLS		/* only if CharLS is enabled */
     ret = -170;
-    if (!drop_coverage (db_handle, RL2_COMPRESSION_NONE, TILE_256, &ret))
+    if (!drop_coverage (db_handle, RL2_COMPRESSION_CHARLS, TILE_256, &ret))
 	return ret;
     ret = -180;
-    if (!drop_coverage (db_handle, RL2_COMPRESSION_NONE, TILE_512, &ret))
+    if (!drop_coverage (db_handle, RL2_COMPRESSION_CHARLS, TILE_512, &ret))
 	return ret;
     ret = -190;
-    if (!drop_coverage (db_handle, RL2_COMPRESSION_NONE, TILE_1024, &ret))
+    if (!drop_coverage (db_handle, RL2_COMPRESSION_CHARLS, TILE_1024, &ret))
 	return ret;
+#endif /* end CharLS conditional */
+
+#ifndef OMIT_OPENJPEG		/* only if OpenJpeg is enabled */
     ret = -270;
-    if (!drop_coverage (db_handle, RL2_COMPRESSION_DEFLATE, TILE_256, &ret))
+    if (!drop_coverage (db_handle, RL2_COMPRESSION_LOSSY_JP2, TILE_256, &ret))
 	return ret;
     ret = -280;
-    if (!drop_coverage (db_handle, RL2_COMPRESSION_DEFLATE, TILE_512, &ret))
+    if (!drop_coverage (db_handle, RL2_COMPRESSION_LOSSY_JP2, TILE_512, &ret))
 	return ret;
     ret = -290;
-    if (!drop_coverage (db_handle, RL2_COMPRESSION_DEFLATE, TILE_1024, &ret))
+    if (!drop_coverage (db_handle, RL2_COMPRESSION_LOSSY_JP2, TILE_1024, &ret))
 	return ret;
+#endif /* end OpenJpeg conditional */
+
     ret = -370;
-    if (!drop_coverage (db_handle, RL2_COMPRESSION_LZMA, TILE_256, &ret))
+    if (!drop_coverage (db_handle, RL2_COMPRESSION_PNG, TILE_256, &ret))
 	return ret;
     ret = -380;
-    if (!drop_coverage (db_handle, RL2_COMPRESSION_LZMA, TILE_512, &ret))
+    if (!drop_coverage (db_handle, RL2_COMPRESSION_PNG, TILE_512, &ret))
 	return ret;
     ret = -390;
-    if (!drop_coverage (db_handle, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
+    if (!drop_coverage (db_handle, RL2_COMPRESSION_PNG, TILE_1024, &ret))
 	return ret;
 
+/* testing HasCodec functions */
+    ret = execute_with_retval (db_handle, "SELECT rl2_has_codec_none()");
+    if (ret != 1)
+      {
+	  fprintf (stderr, "rl2_has_codec_none() unexpected result: %d\n", ret);
+	  return -1;
+      }
+    ret = execute_with_retval (db_handle, "SELECT rl2_has_codec_deflate()");
+    if (ret != 1)
+      {
+	  fprintf (stderr, "rl2_has_codec_deflate() unexpected result: %d\n",
+		   ret);
+	  return -1;
+      }
+    ret = execute_with_retval (db_handle, "SELECT rl2_has_codec_deflate_no()");
+    if (ret != 1)
+      {
+	  fprintf (stderr, "rl2_has_codec_deflate_no() unexpected result: %d\n",
+		   ret);
+	  return -1;
+      }
+    ret = execute_with_retval (db_handle, "SELECT rl2_has_codec_png()");
+    if (ret != 1)
+      {
+	  fprintf (stderr, "rl2_has_codec_png() unexpected result: %d\n", ret);
+	  return -1;
+      }
+    ret = execute_with_retval (db_handle, "SELECT rl2_has_codec_jpeg()");
+    if (ret != 1)
+      {
+	  fprintf (stderr, "rl2_has_codec_jpeg() unexpected result: %d\n", ret);
+	  return -1;
+      }
+    ret = execute_with_retval (db_handle, "SELECT rl2_has_codec_fax4()");
+    if (ret != 1)
+      {
+	  fprintf (stderr, "rl2_has_codec_fax4() unexpected result: %d\n", ret);
+	  return -1;
+      }
+
+#ifndef OMIT_LZMA
+    result = 1;
+#else
+    result = 0;
+#endif /* ; */
+    ret = execute_with_retval (db_handle, "SELECT rl2_has_codec_lzma()");
+    if (ret != result)
+      {
+	  fprintf (stderr, "rl2_has_codec_lzma() unexpected result: %d\n", ret);
+	  return -1;
+      }
+    ret = execute_with_retval (db_handle, "SELECT rl2_has_codec_lzma_no()");
+    if (ret != result)
+      {
+	  fprintf (stderr, "rl2_has_codec_lzma_no() unexpected result: %d\n",
+		   ret);
+	  return -1;
+      }
+
+#ifndef OMIT_CHARLS
+    result = 1;
+#else
+    result = 0;
+#endif /* ; */
+    ret = execute_with_retval (db_handle, "SELECT rl2_has_codec_charls()");
+    if (ret != result)
+      {
+	  fprintf (stderr, "rl2_has_codec_charls() unexpected result: %d\n",
+		   ret);
+	  return -1;
+      }
+
+#ifndef OMIT_WEBP
+    result = 1;
+#else
+    result = 0;
+#endif /* ; */
+    ret = execute_with_retval (db_handle, "SELECT rl2_has_codec_webp()");
+    if (ret != result)
+      {
+	  fprintf (stderr, "rl2_has_codec_webp() unexpected result: %d\n", ret);
+	  return -1;
+      }
+    ret = execute_with_retval (db_handle, "SELECT rl2_has_codec_ll_webp()");
+    if (ret != result)
+      {
+	  fprintf (stderr, "rl2_has_codec_ll_webp() unexpected result: %d\n",
+		   ret);
+	  return -1;
+      }
+
+#ifndef OMIT_OPENJPEG
+    result = 1;
+#else
+    result = 0;
+#endif /* ; */
+    ret = execute_with_retval (db_handle, "SELECT rl2_has_codec_jp2()");
+    if (ret != result)
+      {
+	  fprintf (stderr, "rl2_has_codec_jp2() unexpected result: %d\n", ret);
+	  return -1;
+      }
+    ret = execute_with_retval (db_handle, "SELECT rl2_has_codec_ll_jp2()");
+    if (ret != result)
+      {
+	  fprintf (stderr, "rl2_has_codec_ll_jp2() unexpected result: %d\n",
+		   ret);
+	  return -1;
+      }
+
+    result = 0;
 /* closing the DB */
     sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
     spatialite_shutdown ();
     if (old_SPATIALITE_SECURITY_ENV)
       {
diff --git a/test/test_map_rgb.c b/test/test_map_rgb.c
index 6449305..4188b5c 100644
--- a/test/test_map_rgb.c
+++ b/test/test_map_rgb.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -46,6 +46,8 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include <stdio.h>
 #include <string.h>
 
+#include "config.h"
+
 #include "sqlite3.h"
 #include "spatialite.h"
 #include "spatialite/gaiaaux.h"
@@ -342,7 +344,7 @@ do_export_image (sqlite3 * sqlite, const char *coverage, gaiaGeomCollPtr geom,
     path = sqlite3_mprintf ("./%s_%1.0f%s", coverage, radius, suffix);
 
     sql =
-	"SELECT RL2_GetMapImage(?, ST_Buffer(?, ?), 512, 512, 'default', ?, '#ffffff', 1, 80)";
+	"SELECT RL2_GetMapImageFromRaster(?, ST_Buffer(?, ?), 512, 512, 'default', ?, '#ffffff', 1, 80)";
     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
 	return 0;
@@ -395,14 +397,14 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel,
 /* testing some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
-    const char *sample_name;
-    const char *pixel_name;
-    unsigned char num_bands;
-    const char *compression_name;
-    int qlty;
+    const char *coverage = NULL;
+    const char *sample_name = NULL;
+    const char *pixel_name = NULL;
+    unsigned char num_bands = 1;
+    const char *compression_name = NULL;
+    int qlty = 100;
     char *sql;
-    int tile_size;
+    int tile_size = 256;
     gaiaGeomCollPtr geom;
 
 /* setting the coverage name */
@@ -610,7 +612,7 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel,
       };
 
 /* creating the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_CreateCoverage("
+    sql = sqlite3_mprintf ("SELECT RL2_CreateRasterCoverage("
 			   "%Q, %Q, %Q, %d, %Q, %d, %d, %d, %d, %1.16f, %1.16f)",
 			   coverage, sample_name, pixel_name, num_bands,
 			   compression_name, qlty, tile_size, tile_size, 26914,
@@ -619,7 +621,7 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel,
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "CreateCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "CreateRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -643,8 +645,7 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel,
       }
 
 /* deleting the first section */
-    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, %Q, 1)",
-			   coverage, "rgb1");
+    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, 1, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -1003,12 +1004,12 @@ drop_coverage (sqlite3 * sqlite, unsigned char pixel,
       };
 
 /* dropping the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_DropCoverage(%Q, 1)", coverage);
+    sql = sqlite3_mprintf ("SELECT RL2_DropRasterCoverage(%Q, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "DropCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "DropRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -1026,6 +1027,7 @@ main (int argc, char *argv[])
     char *err_msg = NULL;
     sqlite3 *db_handle;
     void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
     char *old_SPATIALITE_SECURITY_ENV = NULL;
 
     if (argc > 1 || argv[0] == NULL)
@@ -1048,7 +1050,7 @@ main (int argc, char *argv[])
 	  return -1;
       }
     spatialite_init_ex (db_handle, cache, 0);
-    rl2_init (db_handle, 0);
+    rl2_init (db_handle, priv_data, 0);
     ret =
 	sqlite3_exec (db_handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
 		      &err_msg);
@@ -1105,6 +1107,8 @@ main (int argc, char *argv[])
     if (!test_coverage
 	(db_handle, RL2_PIXEL_RGB, RL2_COMPRESSION_JPEG, TILE_1024, &ret))
 	return ret;
+
+#ifndef OMIT_WEBP		/* only if WebP is enabled */
     ret = -400;
     if (!test_coverage
 	(db_handle, RL2_PIXEL_RGB, RL2_COMPRESSION_LOSSY_WEBP, TILE_256, &ret))
@@ -1132,6 +1136,7 @@ main (int argc, char *argv[])
 	(db_handle, RL2_PIXEL_RGB, RL2_COMPRESSION_LOSSLESS_WEBP, TILE_1024,
 	 &ret))
 	return ret;
+#endif /* end WebP conditional */
 
 /* GRAYSCALE tests */
     ret = -600;
@@ -1170,6 +1175,8 @@ main (int argc, char *argv[])
     if (!test_coverage
 	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_JPEG, TILE_1024, &ret))
 	return ret;
+
+#ifndef OMIT_WEBP		/* only if WebP is enabled */
     ret = -900;
     if (!test_coverage
 	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_LOSSY_WEBP, TILE_256,
@@ -1200,6 +1207,7 @@ main (int argc, char *argv[])
 	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_LOSSLESS_WEBP,
 	 TILE_1024, &ret))
 	return ret;
+#endif /* end WebP conditional */
 
 /* dropping all RGB Coverages */
     ret = -170;
@@ -1238,6 +1246,8 @@ main (int argc, char *argv[])
     if (!drop_coverage
 	(db_handle, RL2_PIXEL_RGB, RL2_COMPRESSION_JPEG, TILE_1024, &ret))
 	return ret;
+
+#ifndef OMIT_WEBP		/* only if WebP is enabled */
     ret = -470;
     if (!drop_coverage
 	(db_handle, RL2_PIXEL_RGB, RL2_COMPRESSION_LOSSY_WEBP, TILE_256, &ret))
@@ -1265,6 +1275,7 @@ main (int argc, char *argv[])
 	(db_handle, RL2_PIXEL_RGB, RL2_COMPRESSION_LOSSLESS_WEBP, TILE_1024,
 	 &ret))
 	return ret;
+#endif /* end WebP conditional */
 
 /* dropping all GRAYSCALE Coverages */
     ret = -670;
@@ -1303,6 +1314,8 @@ main (int argc, char *argv[])
     if (!drop_coverage
 	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_JPEG, TILE_1024, &ret))
 	return ret;
+
+#ifndef OMIT_WEBP		/* only if WebP is enabled */
     ret = -970;
     if (!drop_coverage
 	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_LOSSY_WEBP, TILE_256,
@@ -1333,9 +1346,12 @@ main (int argc, char *argv[])
 	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_LOSSLESS_WEBP,
 	 TILE_1024, &ret))
 	return ret;
+#endif /* end WebP conditional */
 
 /* closing the DB */
     sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
     spatialite_shutdown ();
     if (old_SPATIALITE_SECURITY_ENV)
       {
diff --git a/test/test_map_srtm.c b/test/test_map_srtm.c
index 518e3ee..89b8eba 100644
--- a/test/test_map_srtm.c
+++ b/test/test_map_srtm.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -46,6 +46,8 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include <stdio.h>
 #include <string.h>
 
+#include "config.h"
+
 #include "sqlite3.h"
 #include "spatialite.h"
 #include "spatialite/gaiaaux.h"
@@ -55,6 +57,9 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #define TILE_256	256
 #define TILE_1024	1024
 
+/* global variable used to alternatively enable/disable multithreading */
+int multithreading = 1;
+
 static int
 execute_check (sqlite3 * sqlite, const char *sql)
 {
@@ -315,7 +320,7 @@ do_export_map_image (sqlite3 * sqlite, const char *coverage,
     path = sqlite3_mprintf ("./%s_map_%s.%s", coverage, style, suffix);
 
     sql =
-	"SELECT BlobToFile(RL2_GetMapImage(?, ST_Buffer(?, 0.65), ?, ?, ?, ?, ?, ?), ?)";
+	"SELECT BlobToFile(RL2_GetMapImageFromRaster(?, ST_Buffer(?, 0.65), ?, ?, ?, ?, ?, ?), ?)";
     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
 	return 0;
@@ -388,14 +393,14 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 /* testing some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
-    const char *sample_name;
-    const char *pixel_name;
-    unsigned char num_bands;
-    const char *compression_name;
-    int qlty;
+    const char *coverage = NULL;
+    const char *sample_name = NULL;
+    const char *pixel_name = NULL;
+    unsigned char num_bands = 1;
+    const char *compression_name = NULL;
+    int qlty = 100;
     char *sql;
-    int tile_size;
+    int tile_size = 256;
     gaiaGeomCollPtr geom;
     int test_map_image = 0;
 
@@ -771,8 +776,21 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 	  break;
       };
 
+/* setting the MultiThreading mode alternatively on/off */
+    if (multithreading)
+      {
+	  sql = "SELECT RL2_SetMaxThreads(2)";
+	  multithreading = 0;
+      }
+    else
+      {
+	  sql = "SELECT RL2_SetMaxThreads(1)";
+	  multithreading = 1;
+      }
+    execute_check (sqlite, sql);
+
 /* creating the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_CreateCoverage("
+    sql = sqlite3_mprintf ("SELECT RL2_CreateRasterCoverage("
 			   "%Q, %Q, %Q, %d, %Q, %d, %d, %d, %d, %1.8f, %1.8f, "
 			   "RL2_SetPixelValue(RL2_CreatePixel(%Q, %Q, 1), 0, 0))",
 			   coverage, sample_name, pixel_name, num_bands,
@@ -783,7 +801,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "CreateCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "CreateRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -807,8 +825,7 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
       }
 
 /* deleting the first section */
-    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, %Q, 1)",
-			   coverage, "srtm1");
+    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, 1, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -906,9 +923,9 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
       }
 
 /* loading the RasterSymbolizers */
-    sql = sqlite3_mprintf ("SELECT RegisterRasterStyledLayer(%Q, "
-			   "XB_Create(XB_LoadXML(%Q), 1, 1))", coverage,
-			   "srtm_categ.xml");
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 1)",
+			 coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -916,12 +933,12 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 	  fprintf (stderr, "RegisterRasterStyledLayer #1 \"%s\" error: %s\n",
 		   coverage, err_msg);
 	  sqlite3_free (err_msg);
-	  *retcode += -19;
+	  *retcode += -18;
 	  return 0;
       }
-    sql = sqlite3_mprintf ("SELECT RegisterRasterStyledLayer(%Q, "
-			   "XB_Create(XB_LoadXML(%Q), 1, 1))", coverage,
-			   "srtm_interp.xml");
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 2)",
+			 coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -929,12 +946,12 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 	  fprintf (stderr, "RegisterRasterStyledLayer #2 \"%s\" error: %s\n",
 		   coverage, err_msg);
 	  sqlite3_free (err_msg);
-	  *retcode += -20;
+	  *retcode += -19;
 	  return 0;
       }
-    sql = sqlite3_mprintf ("SELECT RegisterRasterStyledLayer(%Q, "
-			   "XB_Create(XB_LoadXML(%Q), 1, 1))", coverage,
-			   "gray_gamma.xml");
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 3)",
+			 coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -942,12 +959,12 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 	  fprintf (stderr, "RegisterRasterStyledLayer #3 \"%s\" error: %s\n",
 		   coverage, err_msg);
 	  sqlite3_free (err_msg);
-	  *retcode += -21;
+	  *retcode += -20;
 	  return 0;
       }
-    sql = sqlite3_mprintf ("SELECT RegisterRasterStyledLayer(%Q, "
-			   "XB_Create(XB_LoadXML(%Q), 1, 1))", coverage,
-			   "gray_histogram.xml");
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 4)",
+			 coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -955,12 +972,12 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 	  fprintf (stderr, "RegisterRasterStyledLayer #4 \"%s\" error: %s\n",
 		   coverage, err_msg);
 	  sqlite3_free (err_msg);
-	  *retcode += -22;
+	  *retcode += -21;
 	  return 0;
       }
-    sql = sqlite3_mprintf ("SELECT RegisterRasterStyledLayer(%Q, "
-			   "XB_Create(XB_LoadXML(%Q), 1, 1))", coverage,
-			   "gray_normalize.xml");
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 5)",
+			 coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -968,12 +985,12 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 	  fprintf (stderr, "RegisterRasterStyledLayer #5 \"%s\" error: %s\n",
 		   coverage, err_msg);
 	  sqlite3_free (err_msg);
-	  *retcode += -23;
+	  *retcode += -22;
 	  return 0;
       }
-    sql = sqlite3_mprintf ("SELECT RegisterRasterStyledLayer(%Q, "
-			   "XB_Create(XB_LoadXML(%Q), 1, 1))", coverage,
-			   "srtm_relief_25.xml");
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 6)",
+			 coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -981,12 +998,12 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 	  fprintf (stderr, "RegisterRasterStyledLayer #6 \"%s\" error: %s\n",
 		   coverage, err_msg);
 	  sqlite3_free (err_msg);
-	  *retcode += -24;
+	  *retcode += -23;
 	  return 0;
       }
-    sql = sqlite3_mprintf ("SELECT RegisterRasterStyledLayer(%Q, "
-			   "XB_Create(XB_LoadXML(%Q), 1, 1))", coverage,
-			   "srtm_relief_75.xml");
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 7)",
+			 coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -994,19 +1011,31 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 	  fprintf (stderr, "RegisterRasterStyledLayer #7 \"%s\" error: %s\n",
 		   coverage, err_msg);
 	  sqlite3_free (err_msg);
-	  *retcode += -25;
+	  *retcode += -24;
 	  return 0;
       }
-    sql = sqlite3_mprintf ("SELECT RegisterRasterStyledLayer(%Q, "
-			   "XB_Create(XB_LoadXML(%Q), 1, 1))", coverage,
-			   "srtm_brightness.xml");
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 8)",
+			 coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "RegisterRasterStyledLayer #7 \"%s\" error: %s\n",
+	  fprintf (stderr, "RegisterRasterStyledLayer #8 \"%s\" error: %s\n",
 		   coverage, err_msg);
 	  sqlite3_free (err_msg);
+	  *retcode += -25;
+	  return 0;
+      }
+    sql =
+	sqlite3_mprintf ("SELECT SE_RegisterRasterStyledLayer(%Q, 9)",
+			 coverage);
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret == SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyledLayer #9 error: %s\n",
+		   "expected failure");
 	  *retcode += -26;
 	  return 0;
       }
@@ -1215,6 +1244,191 @@ test_coverage (sqlite3 * sqlite, unsigned char sample,
 }
 
 static int
+register_raster_symbolizers (sqlite3 * sqlite, int no_web_connection,
+			     int *retcode)
+{
+
+/* loading the RasterSymbolizers */
+    int ret;
+    char *err_msg = NULL;
+    char *sql;
+
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "srtm_categ.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "srtm_categ.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #1 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -1;
+	  return 0;
+      }
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "srtm_interp.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "srtm_interp.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #2 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -2;
+	  return 0;
+      }
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "gray_gamma.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "gray_gamma.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #3 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -3;
+	  return 0;
+      }
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "gray_histogram.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "gray_histogram.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #4 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -4;
+	  return 0;
+      }
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "gray_normalize.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "gray_normalize.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #5 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -5;
+	  return 0;
+      }
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "gray_histogram.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "gray_histogram.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret == SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #6 error: %s\n",
+		   "expected failure");
+	  *retcode += -6;
+	  return 0;
+      }
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "srtm_relief_25.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "srtm_relief_25.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #7 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -7;
+	  return 0;
+      }
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "srtm_relief_75.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "srtm_relief_75.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #8 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -8;
+	  return 0;
+      }
+    if (no_web_connection)
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1))",
+	     "srtm_brightness.xml");
+    else
+	sql =
+	    sqlite3_mprintf
+	    ("SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(%Q), 1, 1))",
+	     "srtm_brightness.xml");
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "RegisterRasterStyle #9 error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -9;
+	  return 0;
+      }
+
+    return 1;
+}
+
+static int
 drop_coverage (sqlite3 * sqlite, unsigned char sample,
 	       unsigned char compression, int tile_sz, int *retcode)
 {
@@ -1534,12 +1748,12 @@ drop_coverage (sqlite3 * sqlite, unsigned char sample,
       };
 
 /* dropping the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_DropCoverage(%Q, 1)", coverage);
+    sql = sqlite3_mprintf ("SELECT RL2_DropRasterCoverage(%Q, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "DropCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "DropRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -1552,16 +1766,28 @@ drop_coverage (sqlite3 * sqlite, unsigned char sample,
 int
 main (int argc, char *argv[])
 {
+    int no_web_connection = 0;
     int result = 0;
     int ret;
     char *err_msg = NULL;
     sqlite3 *db_handle;
     void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
     char *old_SPATIALITE_SECURITY_ENV = NULL;
 
     if (argc > 1 || argv[0] == NULL)
 	argc = 1;		/* silencing stupid compiler warnings */
 
+    if (getenv ("ENABLE_RL2_WEB_TESTS") == NULL)
+      {
+	  fprintf (stderr,
+		   "this testcase has been executed with several limitations\n"
+		   "because it was not enabled to access the Web.\n\n"
+		   "you can enable all testcases requiring an Internet connection\n"
+		   "by setting the environment variable \"ENABLE_RL2_WEB_TESTS=1\"\n\n");
+	  no_web_connection = 1;
+      }
+
     old_SPATIALITE_SECURITY_ENV = getenv ("SPATIALITE_SECURITY");
 #ifdef _WIN32
     putenv ("SPATIALITE_SECURITY=relaxed");
@@ -1579,7 +1805,7 @@ main (int argc, char *argv[])
 	  return -1;
       }
     spatialite_init_ex (db_handle, cache, 0);
-    rl2_init (db_handle, 0);
+    rl2_init (db_handle, priv_data, 0);
     ret =
 	sqlite3_exec (db_handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
 		      &err_msg);
@@ -1598,14 +1824,25 @@ main (int argc, char *argv[])
 	  sqlite3_free (err_msg);
 	  return -3;
       }
-    ret =
-	sqlite3_exec (db_handle, "SELECT CreateStylingTables()", NULL,
-		      NULL, &err_msg);
+    if (no_web_connection)
+	ret =
+	    sqlite3_exec (db_handle, "SELECT CreateStylingTables(1)", NULL,
+			  NULL, &err_msg);
+    else
+	ret =
+	    sqlite3_exec (db_handle, "SELECT CreateStylingTables()", NULL,
+			  NULL, &err_msg);
     if (ret != SQLITE_OK)
       {
 	  fprintf (stderr, "CreateStylingTables() error: %s\n", err_msg);
 	  sqlite3_free (err_msg);
-	  return 4;
+	  return -4;
+      }
+
+    if (!register_raster_symbolizers (db_handle, no_web_connection, &ret))
+      {
+	  fprintf (stderr, "Register Raster Symbolizers error\n");
+	  return -5;
       }
 
 /* SRTM (GRID) tests */
@@ -1625,6 +1862,8 @@ main (int argc, char *argv[])
     if (!test_coverage
 	(db_handle, RL2_SAMPLE_INT16, RL2_COMPRESSION_DEFLATE, TILE_1024, &ret))
 	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
     ret = -300;
     if (!test_coverage
 	(db_handle, RL2_SAMPLE_INT16, RL2_COMPRESSION_LZMA, TILE_256, &ret))
@@ -1633,6 +1872,7 @@ main (int argc, char *argv[])
     if (!test_coverage
 	(db_handle, RL2_SAMPLE_INT16, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
 	return ret;
+#endif /* end LZMA conditional */
 
 /* UINT16 tests */
     ret = -150;
@@ -1652,6 +1892,8 @@ main (int argc, char *argv[])
 	(db_handle, RL2_SAMPLE_UINT16, RL2_COMPRESSION_DEFLATE, TILE_1024,
 	 &ret))
 	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
     ret = -350;
     if (!test_coverage
 	(db_handle, RL2_SAMPLE_UINT16, RL2_COMPRESSION_LZMA, TILE_256, &ret))
@@ -1660,6 +1902,7 @@ main (int argc, char *argv[])
     if (!test_coverage
 	(db_handle, RL2_SAMPLE_UINT16, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
 	return ret;
+#endif /* end LZMA conditional */
 
 /* INT32 tests */
     ret = -400;
@@ -1678,6 +1921,8 @@ main (int argc, char *argv[])
     if (!test_coverage
 	(db_handle, RL2_SAMPLE_INT32, RL2_COMPRESSION_DEFLATE, TILE_1024, &ret))
 	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
     ret = -600;
     if (!test_coverage
 	(db_handle, RL2_SAMPLE_INT32, RL2_COMPRESSION_LZMA, TILE_256, &ret))
@@ -1686,6 +1931,7 @@ main (int argc, char *argv[])
     if (!test_coverage
 	(db_handle, RL2_SAMPLE_INT32, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
 	return ret;
+#endif /* end LZMA conditional */
 
 /* UINT32 tests */
     ret = -450;
@@ -1705,6 +1951,8 @@ main (int argc, char *argv[])
 	(db_handle, RL2_SAMPLE_UINT32, RL2_COMPRESSION_DEFLATE, TILE_1024,
 	 &ret))
 	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
     ret = -650;
     if (!test_coverage
 	(db_handle, RL2_SAMPLE_UINT32, RL2_COMPRESSION_LZMA, TILE_256, &ret))
@@ -1713,6 +1961,7 @@ main (int argc, char *argv[])
     if (!test_coverage
 	(db_handle, RL2_SAMPLE_UINT32, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
 	return ret;
+#endif /* end LZMA conditional */
 
 /* FLOAT tests */
     ret = -700;
@@ -1731,6 +1980,8 @@ main (int argc, char *argv[])
     if (!test_coverage
 	(db_handle, RL2_SAMPLE_FLOAT, RL2_COMPRESSION_DEFLATE, TILE_1024, &ret))
 	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
     ret = -900;
     if (!test_coverage
 	(db_handle, RL2_SAMPLE_FLOAT, RL2_COMPRESSION_LZMA, TILE_256, &ret))
@@ -1739,6 +1990,7 @@ main (int argc, char *argv[])
     if (!test_coverage
 	(db_handle, RL2_SAMPLE_FLOAT, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
 	return ret;
+#endif /* end LZMA conditional */
 
 /* INT8 tests */
     ret = -750;
@@ -1757,6 +2009,8 @@ main (int argc, char *argv[])
     if (!test_coverage
 	(db_handle, RL2_SAMPLE_INT8, RL2_COMPRESSION_DEFLATE, TILE_1024, &ret))
 	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
     ret = -950;
     if (!test_coverage
 	(db_handle, RL2_SAMPLE_INT8, RL2_COMPRESSION_LZMA, TILE_256, &ret))
@@ -1765,6 +2019,7 @@ main (int argc, char *argv[])
     if (!test_coverage
 	(db_handle, RL2_SAMPLE_INT8, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
 	return ret;
+#endif /* end LZMA conditional */
 
 /* DOUBLE tests */
     ret = -1000;
@@ -1784,6 +2039,8 @@ main (int argc, char *argv[])
 	(db_handle, RL2_SAMPLE_DOUBLE, RL2_COMPRESSION_DEFLATE, TILE_1024,
 	 &ret))
 	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
     ret = -1200;
     if (!test_coverage
 	(db_handle, RL2_SAMPLE_DOUBLE, RL2_COMPRESSION_LZMA, TILE_256, &ret))
@@ -1792,6 +2049,7 @@ main (int argc, char *argv[])
     if (!test_coverage
 	(db_handle, RL2_SAMPLE_DOUBLE, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
 	return ret;
+#endif /* end LZMA conditional */
 
 /* UINT8 tests */
     ret = -1050;
@@ -1810,6 +2068,8 @@ main (int argc, char *argv[])
     if (!test_coverage
 	(db_handle, RL2_SAMPLE_UINT8, RL2_COMPRESSION_DEFLATE, TILE_1024, &ret))
 	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
     ret = -1250;
     if (!test_coverage
 	(db_handle, RL2_SAMPLE_UINT8, RL2_COMPRESSION_LZMA, TILE_256, &ret))
@@ -1818,6 +2078,7 @@ main (int argc, char *argv[])
     if (!test_coverage
 	(db_handle, RL2_SAMPLE_UINT8, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
 	return ret;
+#endif /* end LZMA conditional */
 
 /* dropping all SRTM INT16 Coverages */
     ret = -130;
@@ -1836,6 +2097,8 @@ main (int argc, char *argv[])
     if (!drop_coverage
 	(db_handle, RL2_SAMPLE_INT16, RL2_COMPRESSION_DEFLATE, TILE_1024, &ret))
 	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
     ret = -330;
     if (!drop_coverage
 	(db_handle, RL2_SAMPLE_INT16, RL2_COMPRESSION_LZMA, TILE_256, &ret))
@@ -1844,6 +2107,7 @@ main (int argc, char *argv[])
     if (!drop_coverage
 	(db_handle, RL2_SAMPLE_INT16, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
 	return ret;
+#endif /* end LZMA conditional */
 
 /* dropping all SRTM UINT16 Coverages */
     ret = -180;
@@ -1863,6 +2127,8 @@ main (int argc, char *argv[])
 	(db_handle, RL2_SAMPLE_UINT16, RL2_COMPRESSION_DEFLATE, TILE_1024,
 	 &ret))
 	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
     ret = -380;
     if (!drop_coverage
 	(db_handle, RL2_SAMPLE_UINT16, RL2_COMPRESSION_LZMA, TILE_256, &ret))
@@ -1871,6 +2137,7 @@ main (int argc, char *argv[])
     if (!drop_coverage
 	(db_handle, RL2_SAMPLE_UINT16, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
 	return ret;
+#endif /* end LZMA conditional */
 
 /* dropping all INT32 Coverages */
     ret = -430;
@@ -1889,6 +2156,8 @@ main (int argc, char *argv[])
     if (!drop_coverage
 	(db_handle, RL2_SAMPLE_INT32, RL2_COMPRESSION_DEFLATE, TILE_1024, &ret))
 	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
     ret = -630;
     if (!drop_coverage
 	(db_handle, RL2_SAMPLE_INT32, RL2_COMPRESSION_LZMA, TILE_256, &ret))
@@ -1897,6 +2166,7 @@ main (int argc, char *argv[])
     if (!drop_coverage
 	(db_handle, RL2_SAMPLE_INT32, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
 	return ret;
+#endif /* end LZMA conditional */
 
 /* dropping all UINT32 Coverages */
     ret = -480;
@@ -1916,6 +2186,8 @@ main (int argc, char *argv[])
 	(db_handle, RL2_SAMPLE_UINT32, RL2_COMPRESSION_DEFLATE, TILE_1024,
 	 &ret))
 	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
     ret = -680;
     if (!drop_coverage
 	(db_handle, RL2_SAMPLE_UINT32, RL2_COMPRESSION_LZMA, TILE_256, &ret))
@@ -1924,6 +2196,7 @@ main (int argc, char *argv[])
     if (!drop_coverage
 	(db_handle, RL2_SAMPLE_UINT32, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
 	return ret;
+#endif /* end LZMA conditional */
 
 /* dropping all FLOAT Coverages */
     ret = -740;
@@ -1942,6 +2215,8 @@ main (int argc, char *argv[])
     if (!drop_coverage
 	(db_handle, RL2_SAMPLE_FLOAT, RL2_COMPRESSION_DEFLATE, TILE_1024, &ret))
 	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
     ret = -940;
     if (!drop_coverage
 	(db_handle, RL2_SAMPLE_FLOAT, RL2_COMPRESSION_LZMA, TILE_256, &ret))
@@ -1950,6 +2225,7 @@ main (int argc, char *argv[])
     if (!drop_coverage
 	(db_handle, RL2_SAMPLE_FLOAT, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
 	return ret;
+#endif /* end LZMA conditional */
 
 /* dropping all INT8 Coverages */
     ret = -780;
@@ -1968,6 +2244,8 @@ main (int argc, char *argv[])
     if (!drop_coverage
 	(db_handle, RL2_SAMPLE_INT8, RL2_COMPRESSION_DEFLATE, TILE_1024, &ret))
 	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
     ret = -980;
     if (!drop_coverage
 	(db_handle, RL2_SAMPLE_INT8, RL2_COMPRESSION_LZMA, TILE_256, &ret))
@@ -1976,6 +2254,7 @@ main (int argc, char *argv[])
     if (!drop_coverage
 	(db_handle, RL2_SAMPLE_INT8, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
 	return ret;
+#endif /* end LZMA conditional */
 
 /* dropping all DOUBLE Coverages */
     ret = -1030;
@@ -1995,6 +2274,8 @@ main (int argc, char *argv[])
 	(db_handle, RL2_SAMPLE_DOUBLE, RL2_COMPRESSION_DEFLATE, TILE_1024,
 	 &ret))
 	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
     ret = -1230;
     if (!drop_coverage
 	(db_handle, RL2_SAMPLE_DOUBLE, RL2_COMPRESSION_LZMA, TILE_256, &ret))
@@ -2003,6 +2284,7 @@ main (int argc, char *argv[])
     if (!drop_coverage
 	(db_handle, RL2_SAMPLE_DOUBLE, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
 	return ret;
+#endif /* end LZMA conditional */
 
 /* dropping all UINT8 Coverages */
     ret = -1030;
@@ -2021,6 +2303,8 @@ main (int argc, char *argv[])
     if (!drop_coverage
 	(db_handle, RL2_SAMPLE_UINT8, RL2_COMPRESSION_DEFLATE, TILE_1024, &ret))
 	return ret;
+
+#ifndef OMIT_LZMA		/* only if LZMA is enabled */
     ret = -1230;
     if (!drop_coverage
 	(db_handle, RL2_SAMPLE_UINT8, RL2_COMPRESSION_LZMA, TILE_256, &ret))
@@ -2029,9 +2313,12 @@ main (int argc, char *argv[])
     if (!drop_coverage
 	(db_handle, RL2_SAMPLE_UINT8, RL2_COMPRESSION_LZMA, TILE_1024, &ret))
 	return ret;
+#endif /* end LZMA conditional */
 
 /* closing the DB */
     sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
     spatialite_shutdown ();
     if (old_SPATIALITE_SECURITY_ENV)
       {
diff --git a/test/test_map_trento.c b/test/test_map_trento.c
index b6a17c5..d275052 100644
--- a/test/test_map_trento.c
+++ b/test/test_map_trento.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -56,6 +56,10 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #define TILE_512	512
 #define TILE_1024	1024
 
+/* global variable used to alternatively enable/disable multithreading */
+int multithreading = 1;
+
+
 static int
 execute_check (sqlite3 * sqlite, const char *sql)
 {
@@ -342,6 +346,117 @@ do_export_jpeg_jgw (sqlite3 * sqlite, const char *coverage,
     return retcode;
 }
 
+static int
+do_export_section_jpeg (sqlite3 * sqlite, const char *coverage,
+			gaiaGeomCollPtr geom, int scale)
+{
+/* exporting a JPEG [no Worldfile] - Section */
+    char *sql;
+    char *path;
+    sqlite3_stmt *stmt;
+    int ret;
+    double x_res;
+    double y_res;
+    double xx_res;
+    double yy_res;
+    unsigned char *blob;
+    int blob_size;
+    int retcode = 0;
+
+    path = sqlite3_mprintf ("./%s_sect1_%d.jpg", coverage, scale);
+
+    if (!get_base_resolution (sqlite, coverage, &x_res, &y_res))
+	return 0;
+    xx_res = x_res * (double) scale;
+    yy_res = y_res * (double) scale;
+
+    sql = "SELECT RL2_WriteSectionJpeg(?, ?, ?, ?, ?, ?, ?, ?, ?)";
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return 0;
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
+    sqlite3_bind_int (stmt, 2, 1);
+    sqlite3_bind_text (stmt, 3, path, strlen (path), SQLITE_STATIC);
+    sqlite3_bind_int (stmt, 4, 1024);
+    sqlite3_bind_int (stmt, 5, 1024);
+    gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
+    sqlite3_bind_blob (stmt, 6, blob, blob_size, free);
+    sqlite3_bind_double (stmt, 7, xx_res);
+    sqlite3_bind_double (stmt, 8, yy_res);
+    sqlite3_bind_int (stmt, 9, 90);
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+      {
+	  if (sqlite3_column_int (stmt, 0) == 1)
+	      retcode = 1;
+      }
+    sqlite3_finalize (stmt);
+    unlink (path);
+    if (!retcode)
+	fprintf (stderr, "ERROR: unable to export \"%s\"\n", path);
+    sqlite3_free (path);
+    return retcode;
+}
+
+static int
+do_export_section_jpeg_jgw (sqlite3 * sqlite, const char *coverage,
+			    gaiaGeomCollPtr geom, int scale)
+{
+/* exporting a JPEG + Worldfile - Section */
+    char *sql;
+    char *path;
+    sqlite3_stmt *stmt;
+    int ret;
+    double x_res;
+    double y_res;
+    double xx_res;
+    double yy_res;
+    unsigned char *blob;
+    int blob_size;
+    int retcode = 0;
+
+    path = sqlite3_mprintf ("./%s_sect1_jgw_%d.jpg", coverage, scale);
+
+    if (!get_base_resolution (sqlite, coverage, &x_res, &y_res))
+	return 0;
+    xx_res = x_res * (double) scale;
+    yy_res = y_res * (double) scale;
+
+    sql = "SELECT RL2_WriteSectionJpegJgw(?, ?, ?, ?, ?, ?, ?, ?, ?)";
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return 0;
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
+    sqlite3_bind_int (stmt, 2, 1);
+    sqlite3_bind_text (stmt, 3, path, strlen (path), SQLITE_STATIC);
+    sqlite3_bind_int (stmt, 4, 1024);
+    sqlite3_bind_int (stmt, 5, 1024);
+    gaiaToSpatiaLiteBlobWkb (geom, &blob, &blob_size);
+    sqlite3_bind_blob (stmt, 6, blob, blob_size, free);
+    sqlite3_bind_double (stmt, 7, xx_res);
+    sqlite3_bind_double (stmt, 8, yy_res);
+    sqlite3_bind_int (stmt, 9, 40);
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+      {
+	  if (sqlite3_column_int (stmt, 0) == 1)
+	      retcode = 1;
+      }
+    sqlite3_finalize (stmt);
+    unlink (path);
+    if (!retcode)
+	fprintf (stderr, "ERROR: unable to export \"%s\"\n", path);
+    sqlite3_free (path);
+    path = sqlite3_mprintf ("./%s_sect1_jgw_%d.jgw", coverage, scale);
+    unlink (path);
+    sqlite3_free (path);
+    return retcode;
+}
+
 static gaiaGeomCollPtr
 get_center_point (sqlite3 * sqlite, const char *coverage)
 {
@@ -395,7 +510,7 @@ do_export_image (sqlite3 * sqlite, const char *coverage, gaiaGeomCollPtr geom,
     path = sqlite3_mprintf ("./%s_%1.0f%s", coverage, radius, suffix);
 
     sql =
-	"SELECT RL2_GetMapImage(?, ST_Buffer(?, ?), 512, 512, 'default', ?, '#ffffff', 1, 80)";
+	"SELECT RL2_GetMapImageFromRaster(?, ST_Buffer(?, ?), 512, 512, 'default', ?, '#ffffff', 1, 80)";
     ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
 	return 0;
@@ -448,29 +563,30 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
 /* testing some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
-    const char *sample_name;
-    const char *pixel_name;
-    unsigned char num_bands;
-    const char *compression_name;
+    const char *coverage = NULL;
+    const char *sample_name = NULL;
+    const char *pixel_name = NULL;
+    unsigned char num_bands = 1;
+    const char *compression_name = NULL;
     const char *indir;
-    const char *delsect;
     const char *reload;
-    int qlty;
+    int qlty = 100;
     char *sql;
-    int tile_size;
+    int tile_size = 256;
     gaiaGeomCollPtr geom;
+    unsigned int width;
+    unsigned int height;
+    unsigned char pixel_type;
+    char *md5;
 
     if (!type)
       {
 	  indir = "map_samples/trento-gray";
-	  delsect = "trento-gray1";
 	  reload = "map_samples/trento-gray/trento-gray1.jpg";
       }
     else
       {
 	  indir = "map_samples/trento-rgb";
-	  delsect = "trento-rgb1";
 	  reload = "map_samples/trento-rgb/trento-rgb1.jpg";
       }
 
@@ -575,8 +691,21 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
       };
     tile_size = 512;
 
+/* setting the MultiThreading mode alternatively on/off */
+    if (multithreading)
+      {
+	  sql = "SELECT RL2_SetMaxThreads(2)";
+	  multithreading = 0;
+      }
+    else
+      {
+	  sql = "SELECT RL2_SetMaxThreads(1)";
+	  multithreading = 1;
+      }
+    execute_check (sqlite, sql);
+
 /* creating the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_CreateCoverage("
+    sql = sqlite3_mprintf ("SELECT RL2_CreateRasterCoverage("
 			   "%Q, %Q, %Q, %d, %Q, %d, %d, %d, %d, %1.16f, %1.16f)",
 			   coverage, sample_name, pixel_name, num_bands,
 			   compression_name, qlty, tile_size, tile_size, 32632,
@@ -585,7 +714,7 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "CreateCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "CreateRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -609,8 +738,7 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
       }
 
 /* deleting the first section */
-    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, %Q, 1)",
-			   coverage, delsect);
+    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, 1, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -744,24 +872,160 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
 	  *retcode += -24;
 	  return 0;
       }
+    if (!do_export_section_jpeg (sqlite, coverage, geom, 1))
+      {
+	  *retcode += -25;
+	  return 0;
+      }
+    if (!do_export_section_jpeg (sqlite, coverage, geom, 2))
+      {
+	  *retcode += -26;
+	  return 0;
+      }
+    if (!do_export_section_jpeg (sqlite, coverage, geom, 4))
+      {
+	  *retcode += -27;
+	  return 0;
+      }
+    if (!do_export_section_jpeg (sqlite, coverage, geom, 8))
+      {
+	  *retcode += -28;
+	  return 0;
+      }
+    if (!do_export_section_jpeg_jgw (sqlite, coverage, geom, 1))
+      {
+	  *retcode += -29;
+	  return 0;
+      }
+    if (!do_export_section_jpeg_jgw (sqlite, coverage, geom, 2))
+      {
+	  *retcode += -30;
+	  return 0;
+      }
+    if (!do_export_section_jpeg_jgw (sqlite, coverage, geom, 4))
+      {
+	  *retcode += -31;
+	  return 0;
+      }
+    if (!do_export_section_jpeg_jgw (sqlite, coverage, geom, 8))
+      {
+	  *retcode += -32;
+	  return 0;
+      }
     gaiaFreeGeomColl (geom);
 
 /* testing GetTileImage() */
     if (!do_export_tile_image (sqlite, coverage, 1))
       {
-	  *retcode += -23;
+	  *retcode += -33;
 	  return 0;
       }
     if (!do_export_tile_image (sqlite, coverage, 2))
       {
-	  *retcode += -24;
+	  *retcode += -34;
 	  return 0;
       }
     if (!do_export_tile_image (sqlite, coverage, -1))
       {
-	  *retcode += -25;
+	  *retcode += -35;
+	  return 0;
+      }
+
+/* testing GetJpegInfos */
+    if (rl2_get_jpeg_infos
+	("./map_samples/trento-gray/trento-gray1.jpg", &width, &height,
+	 &pixel_type) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unable to GetJpegInfos from \"trento-gray1.jpg\"\n");
+	  *retcode += -36;
+	  return 0;
+      }
+    if (width != 600)
+      {
+	  fprintf (stderr, "Unexpected Width from \"trento-gray1.jpg\" %u\n",
+		   width);
+	  *retcode += -37;
+	  return 0;
+      }
+    if (height != 600)
+      {
+	  fprintf (stderr, "Unexpected Height from \"trento-gray1.jpg\" %u\n",
+		   height);
+	  *retcode += -38;
+	  return 0;
+      }
+    if (pixel_type != RL2_PIXEL_GRAYSCALE)
+      {
+	  fprintf (stderr,
+		   "Unexpected PixelType from \"trento-gray1.jpg\" %02x\n",
+		   pixel_type);
+	  *retcode += -39;
+	  return 0;
+      }
+    if (rl2_get_jpeg_infos
+	("./map_samples/trento-rgb/trento-rgb1.jpg", &width, &height,
+	 &pixel_type) != RL2_OK)
+      {
+	  fprintf (stderr, "Unable to GetJpegInfos from \"trento-rgb1.jpg\"\n");
+	  *retcode += -40;
+	  return 0;
+      }
+    if (width != 600)
+      {
+	  fprintf (stderr, "Unexpected Width from \"trento-rgb1.jpg\" %u\n",
+		   width);
+	  *retcode += -41;
+	  return 0;
+      }
+    if (height != 600)
+      {
+	  fprintf (stderr, "Unexpected Height from \"trento-rgb1.jpg\" %u\n",
+		   height);
+	  *retcode += -42;
+	  return 0;
+      }
+    if (pixel_type != RL2_PIXEL_RGB)
+      {
+	  fprintf (stderr,
+		   "Unexpected PixelType from \"trento-rgb1.jpg\" %02x\n",
+		   pixel_type);
+	  *retcode += -43;
+	  return 0;
+      }
+/* testing MD5 Checksum */
+    md5 =
+	rl2_compute_file_md5_checksum
+	("./map_samples/trento-gray/trento-gray1.jpg");
+    if (md5 == NULL)
+      {
+	  fprintf (stderr, "Unable to GetMD5 from \"trento-gray1.jpg\"\n");
+	  *retcode += -44;
+	  return 0;
+      }
+    if (strcmp (md5, "6750bf6f168200dab2c741017af82f1d") != 0)
+      {
+	  fprintf (stderr, "Unexpected MD5 for \"trento-gray1.jpg\" %s\n", md5);
+	  *retcode += -45;
+	  return 0;
+      }
+    free (md5);
+    md5 =
+	rl2_compute_file_md5_checksum
+	("./map_samples/trento-rgb/trento-rgb1.jpg");
+    if (md5 == NULL)
+      {
+	  fprintf (stderr, "Unable to GetMD5 from \"trento-rgb1.jpg\"\n");
+	  *retcode += -46;
+	  return 0;
+      }
+    if (strcmp (md5, "8f0903be04e7ff3a2cb6188d52034502") != 0)
+      {
+	  fprintf (stderr, "Unexpected MD5 for \"trento-rgb1.jpg\" %s\n", md5);
+	  *retcode += -47;
 	  return 0;
       }
+    free (md5);
 
     return 1;
 }
@@ -773,7 +1037,7 @@ drop_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
 /* dropping some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
+    const char *coverage = NULL;
     char *sql;
 
 /* setting the coverage name */
@@ -848,12 +1112,12 @@ drop_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
       }
 
 /* dropping the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_DropCoverage(%Q, 1)", coverage);
+    sql = sqlite3_mprintf ("SELECT RL2_DropRasterCoverage(%Q, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "DropCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "DropRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -871,6 +1135,7 @@ main (int argc, char *argv[])
     char *err_msg = NULL;
     sqlite3 *db_handle;
     void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
     char *old_SPATIALITE_SECURITY_ENV = NULL;
 
     if (argc > 1 || argv[0] == NULL)
@@ -893,7 +1158,7 @@ main (int argc, char *argv[])
 	  return -1;
       }
     spatialite_init_ex (db_handle, cache, 0);
-    rl2_init (db_handle, 0);
+    rl2_init (db_handle, priv_data, 0);
     ret =
 	sqlite3_exec (db_handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
 		      &err_msg);
@@ -1015,6 +1280,8 @@ main (int argc, char *argv[])
 
 /* closing the DB */
     sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
     spatialite_shutdown ();
     if (old_SPATIALITE_SECURITY_ENV)
       {
diff --git a/test/test_map_trieste.c b/test/test_map_trieste.c
index f7ede7e..296e3a4 100644
--- a/test/test_map_trieste.c
+++ b/test/test_map_trieste.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -46,6 +46,8 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include <stdio.h>
 #include <string.h>
 
+#include "config.h"
+
 #include "sqlite3.h"
 #include "spatialite.h"
 #include "spatialite/gaiaaux.h"
@@ -471,13 +473,13 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
 /* testing some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
-    const char *sample_name;
-    const char *pixel_name;
-    unsigned char num_bands;
-    const char *compression_name;
-    int qlty;
-    int tile_size;
+    const char *coverage = NULL;
+    const char *sample_name = NULL;
+    const char *pixel_name = NULL;
+    unsigned char num_bands = 1;
+    const char *compression_name = NULL;
+    int qlty = 100;
+    int tile_size = 256;
     char *sql;
     gaiaGeomCollPtr geom;
 
@@ -487,31 +489,45 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
       case RL2_PIXEL_GRAYSCALE:
 	  switch (compression)
 	    {
-	    case RL2_COMPRESSION_NONE:
+	    case RL2_COMPRESSION_CHARLS:
+		switch (tile_sz)
+		  {
+		  case TILE_256:
+		      coverage = "gray_charls_256";
+		      break;
+		  case TILE_512:
+		      coverage = "gray_charls_512";
+		      break;
+		  case TILE_1024:
+		      coverage = "gray_charls_1024";
+		      break;
+		  };
+		break;
+	    case RL2_COMPRESSION_PNG:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
-		      coverage = "gray_none_256";
+		      coverage = "gray_png_256";
 		      break;
 		  case TILE_512:
-		      coverage = "gray_none_512";
+		      coverage = "gray_png_512";
 		      break;
 		  case TILE_1024:
-		      coverage = "gray_none_1024";
+		      coverage = "gray_png_1024";
 		      break;
 		  };
 		break;
-	    case RL2_COMPRESSION_DEFLATE:
+	    case RL2_COMPRESSION_LOSSLESS_JP2:
 		switch (tile_sz)
 		  {
 		  case TILE_256:
-		      coverage = "gray_zip_256";
+		      coverage = "gray_jp2_256";
 		      break;
 		  case TILE_512:
-		      coverage = "gray_zip_512";
+		      coverage = "gray_jp2_512";
 		      break;
 		  case TILE_1024:
-		      coverage = "gray_zip_1024";
+		      coverage = "gray_jp2_1024";
 		      break;
 		  };
 		break;
@@ -525,14 +541,18 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
     num_bands = 1;
     switch (compression)
       {
-      case RL2_COMPRESSION_NONE:
-	  compression_name = "NONE";
+      case RL2_COMPRESSION_CHARLS:
+	  compression_name = "CHARLS";
 	  qlty = 100;
 	  break;
-      case RL2_COMPRESSION_DEFLATE:
-	  compression_name = "DEFLATE";
+      case RL2_COMPRESSION_PNG:
+	  compression_name = "PNG";
 	  qlty = 100;
 	  break;
+      case RL2_COMPRESSION_LOSSLESS_JP2:
+	  compression_name = "LL_JP2";
+	  qlty = 10;
+	  break;
       };
     switch (tile_sz)
       {
@@ -548,7 +568,7 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
       };
 
 /* creating the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_CreateCoverage("
+    sql = sqlite3_mprintf ("SELECT RL2_CreateRasterCoverage("
 			   "%Q, %Q, %Q, %d, %Q, %d, %d, %d, %d, %1.2f, %1.2f)",
 			   coverage, sample_name, pixel_name, num_bands,
 			   compression_name, qlty, tile_size, tile_size, 32633,
@@ -557,7 +577,7 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "CreateCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "CreateRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -592,48 +612,6 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
 	  return 0;
       }
 
-/* deleting the first section */
-    sql = sqlite3_mprintf ("SELECT RL2_DeleteSection(%Q, %Q, 1)",
-			   coverage, "trieste1");
-    ret = execute_check (sqlite, sql);
-    sqlite3_free (sql);
-    if (ret != SQLITE_OK)
-      {
-	  fprintf (stderr, "DeleteSection \"%s\" error: %s\n", coverage,
-		   err_msg);
-	  sqlite3_free (err_msg);
-	  *retcode += -4;
-	  return 0;
-      }
-
-/* re-loading yet again the first section */
-    sql = sqlite3_mprintf ("SELECT RL2_LoadRaster(%Q, %Q, 0, 32633, 0, 1)",
-			   coverage,
-			   "map_samples/orbview3-trieste/trieste1.tif");
-    ret = execute_check (sqlite, sql);
-    sqlite3_free (sql);
-    if (ret != SQLITE_OK)
-      {
-	  fprintf (stderr, "LoadRaster \"%s\" error: %s\n", coverage, err_msg);
-	  sqlite3_free (err_msg);
-	  *retcode += -5;
-	  return 0;
-      }
-
-/* building the Pyramid Levels */
-    sql =
-	sqlite3_mprintf ("SELECT RL2_Pyramidize(%Q, %Q, 1, 1)", coverage,
-			 "trieste2");
-    ret = execute_check (sqlite, sql);
-    sqlite3_free (sql);
-    if (ret != SQLITE_OK)
-      {
-	  fprintf (stderr, "Pyramidize \"%s\" error: %s\n", coverage, err_msg);
-	  sqlite3_free (err_msg);
-	  *retcode += -6;
-	  return 0;
-      }
-
 /* destroying the Pyramid Levels */
     sql = sqlite3_mprintf ("SELECT RL2_DePyramidize(%Q, NULL, 1)", coverage);
     ret = execute_check (sqlite, sql);
@@ -648,9 +626,7 @@ test_coverage (sqlite3 * sqlite, unsigned char pixel, unsigned char compression,
       }
 
 /* building yet again the Pyramid Levels */
-    sql =
-	sqlite3_mprintf ("SELECT RL2_Pyramidize(%Q, %Q, 1, 1)", coverage,
-			 "trieste2");
+    sql = sqlite3_mprintf ("SELECT RL2_Pyramidize(%Q, 2, 1, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
@@ -721,49 +697,63 @@ drop_coverage (sqlite3 * sqlite, unsigned char compression, int tile_sz,
 /* dropping some DBMS Coverage */
     int ret;
     char *err_msg = NULL;
-    const char *coverage;
+    const char *coverage = NULL;
     char *sql;
 
 /* setting the coverage name */
     switch (compression)
       {
-      case RL2_COMPRESSION_NONE:
+      case RL2_COMPRESSION_CHARLS:
+	  switch (tile_sz)
+	    {
+	    case TILE_256:
+		coverage = "gray_charls_256";
+		break;
+	    case TILE_512:
+		coverage = "gray_charls_512";
+		break;
+	    case TILE_1024:
+		coverage = "gray_charls_1024";
+		break;
+	    };
+	  break;
+      case RL2_COMPRESSION_PNG:
 	  switch (tile_sz)
 	    {
 	    case TILE_256:
-		coverage = "gray_none_256";
+		coverage = "gray_png_256";
 		break;
 	    case TILE_512:
-		coverage = "gray_none_512";
+		coverage = "gray_png_512";
 		break;
 	    case TILE_1024:
-		coverage = "gray_none_1024";
+		coverage = "gray_png_1024";
 		break;
 	    };
 	  break;
-      case RL2_COMPRESSION_DEFLATE:
+      case RL2_COMPRESSION_LOSSLESS_JP2:
 	  switch (tile_sz)
 	    {
 	    case TILE_256:
-		coverage = "gray_zip_256";
+		coverage = "gray_jp2_256";
 		break;
 	    case TILE_512:
-		coverage = "gray_zip_512";
+		coverage = "gray_jp2_512";
 		break;
 	    case TILE_1024:
-		coverage = "gray_zip_1024";
+		coverage = "gray_jp2_1024";
 		break;
 	    };
 	  break;
       };
 
 /* dropping the DBMS Coverage */
-    sql = sqlite3_mprintf ("SELECT RL2_DropCoverage(%Q, 1)", coverage);
+    sql = sqlite3_mprintf ("SELECT RL2_DropRasterCoverage(%Q, 1)", coverage);
     ret = execute_check (sqlite, sql);
     sqlite3_free (sql);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "DropCoverage \"%s\" error: %s\n", coverage,
+	  fprintf (stderr, "DropRasterCoverage \"%s\" error: %s\n", coverage,
 		   err_msg);
 	  sqlite3_free (err_msg);
 	  *retcode += -1;
@@ -781,6 +771,7 @@ main (int argc, char *argv[])
     char *err_msg = NULL;
     sqlite3 *db_handle;
     void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
     char *old_SPATIALITE_SECURITY_ENV = NULL;
 
     if (argc > 1 || argv[0] == NULL)
@@ -803,7 +794,7 @@ main (int argc, char *argv[])
 	  return -1;
       }
     spatialite_init_ex (db_handle, cache, 0);
-    rl2_init (db_handle, 0);
+    rl2_init (db_handle, priv_data, 0);
     ret =
 	sqlite3_exec (db_handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
 		      &err_msg);
@@ -824,56 +815,97 @@ main (int argc, char *argv[])
       }
 
 /* GRAYSCALE tests */
+#ifndef OMIT_CHARLS		/* only if CharLS is enabled */
     ret = -100;
     if (!test_coverage
-	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_NONE, TILE_256, &ret))
+	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_CHARLS, TILE_256,
+	 &ret))
 	return ret;
     ret = -120;
     if (!test_coverage
-	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_NONE, TILE_512, &ret))
+	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_CHARLS, TILE_512,
+	 &ret))
 	return ret;
     ret = -140;
     if (!test_coverage
-	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_NONE, TILE_1024, &ret))
+	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_CHARLS, TILE_1024,
+	 &ret))
 	return ret;
+#endif /* end CharLS conditional */
+
     ret = -200;
     if (!test_coverage
-	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_DEFLATE, TILE_256,
-	 &ret))
+	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_PNG, TILE_256, &ret))
 	return ret;
     ret = -220;
     if (!test_coverage
-	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_DEFLATE, TILE_512,
-	 &ret))
+	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_PNG, TILE_512, &ret))
 	return ret;
     ret = -240;
     if (!test_coverage
-	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_DEFLATE, TILE_1024,
+	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_PNG, TILE_1024, &ret))
+	return ret;
+
+#ifndef OMIT_OPENJPEG		/* only if OpenJpeg is enabled */
+    ret = -300;
+    if (!test_coverage
+	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_LOSSLESS_JP2, TILE_256,
+	 &ret))
+	return ret;
+    ret = -320;
+    if (!test_coverage
+	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_LOSSLESS_JP2, TILE_512,
 	 &ret))
 	return ret;
+    ret = -340;
+    if (!test_coverage
+	(db_handle, RL2_PIXEL_GRAYSCALE, RL2_COMPRESSION_LOSSLESS_JP2,
+	 TILE_1024, &ret))
+	return ret;
+#endif /* end OpenJpeg conditional */
 
 /* dropping all GRAYSCALE Coverages */
+#ifndef OMIT_CHARLS		/* only if CharLS is enabled */
     ret = -170;
-    if (!drop_coverage (db_handle, RL2_COMPRESSION_NONE, TILE_256, &ret))
+    if (!drop_coverage (db_handle, RL2_COMPRESSION_CHARLS, TILE_256, &ret))
 	return ret;
     ret = -180;
-    if (!drop_coverage (db_handle, RL2_COMPRESSION_NONE, TILE_512, &ret))
+    if (!drop_coverage (db_handle, RL2_COMPRESSION_CHARLS, TILE_512, &ret))
 	return ret;
     ret = -190;
-    if (!drop_coverage (db_handle, RL2_COMPRESSION_NONE, TILE_1024, &ret))
+    if (!drop_coverage (db_handle, RL2_COMPRESSION_CHARLS, TILE_1024, &ret))
 	return ret;
+#endif /* end CharLS conditional */
+
     ret = -270;
-    if (!drop_coverage (db_handle, RL2_COMPRESSION_DEFLATE, TILE_256, &ret))
+    if (!drop_coverage (db_handle, RL2_COMPRESSION_PNG, TILE_256, &ret))
 	return ret;
     ret = -280;
-    if (!drop_coverage (db_handle, RL2_COMPRESSION_DEFLATE, TILE_512, &ret))
+    if (!drop_coverage (db_handle, RL2_COMPRESSION_PNG, TILE_512, &ret))
 	return ret;
     ret = -290;
-    if (!drop_coverage (db_handle, RL2_COMPRESSION_DEFLATE, TILE_1024, &ret))
+    if (!drop_coverage (db_handle, RL2_COMPRESSION_PNG, TILE_1024, &ret))
+	return ret;
+
+#ifndef OMIT_OPENJPEG		/* only if OpenJpeg is enabled */
+    ret = -370;
+    if (!drop_coverage
+	(db_handle, RL2_COMPRESSION_LOSSLESS_JP2, TILE_256, &ret))
+	return ret;
+    ret = -380;
+    if (!drop_coverage
+	(db_handle, RL2_COMPRESSION_LOSSLESS_JP2, TILE_512, &ret))
+	return ret;
+    ret = -390;
+    if (!drop_coverage
+	(db_handle, RL2_COMPRESSION_LOSSLESS_JP2, TILE_1024, &ret))
 	return ret;
+#endif /* end OpenJpeg conditional */
 
 /* closing the DB */
     sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
     spatialite_shutdown ();
     if (old_SPATIALITE_SECURITY_ENV)
       {
diff --git a/test/test_mask.c b/test/test_mask.c
index 7364624..e984873 100644
--- a/test/test_mask.c
+++ b/test/test_mask.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -43,6 +43,8 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include <unistd.h>
 #include <stdio.h>
 
+#include "config.h"
+
 #include "rasterlite2/rasterlite2.h"
 
 static int
@@ -317,6 +319,7 @@ test_rgb_jpeg (const char *path, const char *mask_path)
       }
     unlink ("./masked_rgb_20.jpg");
 
+#ifndef OMIT_WEBP		/* only if WebP is enabled */
     if (rl2_section_to_lossy_webp (img, "./masked_rgb_20.webp", 20) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to write: masked_rgb_20.webp\n");
@@ -330,6 +333,7 @@ test_rgb_jpeg (const char *path, const char *mask_path)
 	  return 0;
       }
     unlink ("./masked_rgb.webp");
+#endif /* end WebP conditional */
     unlink ("./masked_rgb.jpg");
 
     rl2_destroy_section (img);
@@ -442,6 +446,7 @@ test_gray_jpeg (const char *path, const char *mask_path)
       }
     unlink ("./masked_gray.jpg");
 
+#ifndef OMIT_WEBP		/* only if WebP is enabled */
     if (rl2_section_to_lossy_webp (img, "./masked_gray_20.webp", 20) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to write: masked_gray_20.webp\n");
@@ -455,6 +460,7 @@ test_gray_jpeg (const char *path, const char *mask_path)
 	  return 0;
       }
     unlink ("./masked_gray.webp");
+#endif /* end WebP conditional */
 
     rl2_destroy_section (img);
     return 1;
diff --git a/test/test_openjpeg.c b/test/test_openjpeg.c
new file mode 100644
index 0000000..f7ffad5
--- /dev/null
+++ b/test/test_openjpeg.c
@@ -0,0 +1,783 @@
+/*
+
+ test_openjpeg.c -- RasterLite2 Test Case
+
+ Author: Alessandro Furieri <a.furieri at lqt.it>
+
+ ------------------------------------------------------------------------------
+ 
+ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ 
+ The contents of this file are subject to the Mozilla Public License Version
+ 1.1 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+ 
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the
+License.
+
+The Original Code is the RasterLite2 library
+
+The Initial Developer of the Original Code is Alessandro Furieri
+ 
+Portions created by the Initial Developer are Copyright (C) 2013
+the Initial Developer. All Rights Reserved.
+
+Contributor(s):
+
+Alternatively, the contents of this file may be used under the terms of
+either the GNU General Public License Version 2 or later (the "GPL"), or
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+in which case the provisions of the GPL or the LGPL are applicable instead
+of those above. If you wish to allow use of your version of this file only
+under the terms of either the GPL or the LGPL, and not to allow others to
+use your version of this file under the terms of the MPL, indicate your
+decision by deleting the provisions above and replace them with the notice
+and other provisions required by the GPL or the LGPL. If you do not delete
+the provisions above, a recipient may use your version of this file under
+the terms of any one of the MPL, the GPL or the LGPL.
+*/
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <memory.h>
+
+#include "config.h"
+
+#include "rasterlite2/rasterlite2.h"
+
+#ifndef OMIT_OPENJPEG		/* only if OpenJpeg is enabled */
+
+static int
+test_no_alpha_openjpeg (const char *path)
+{
+    rl2RasterPtr rst;
+    unsigned int width;
+    unsigned int height;
+    unsigned int row;
+    unsigned int col;
+    unsigned char *rgbbuf;
+    int rgbbuf_sz;
+    unsigned char *mskbuf;
+    int mskbuf_sz;
+    unsigned char *p_mask;
+    rl2RasterPtr raster;
+    rl2PixelPtr no_data;
+    unsigned char *bufpix;
+
+    rl2SectionPtr img =
+	rl2_section_from_jpeg2000 (path, RL2_SAMPLE_UINT8, RL2_PIXEL_RGB, 3);
+    if (img == NULL)
+      {
+	  fprintf (stderr, "Unable to read: %s\n", path);
+	  return 0;
+      }
+
+    if (rl2_section_to_png (img, "./from_jp2_no_alpha.png") != RL2_OK)
+      {
+	  fprintf (stderr, "Unable to write: from_jp2_no_alpha.png\n");
+	  return 0;
+      }
+    unlink ("./from_jp2_no_alpha.png");
+
+    rst = rl2_get_section_raster (img);
+    if (rst == NULL)
+      {
+	  fprintf (stderr, "Unable to get the raster: %s\n", path);
+	  return 0;
+      }
+
+    if (rl2_get_raster_size (rst, &width, &height) != RL2_OK)
+      {
+	  fprintf (stderr, "Invalid width/height: %s\n", path);
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_RGB (rst, &rgbbuf, &rgbbuf_sz) != RL2_OK)
+      {
+	  fprintf (stderr, "Unable to get raw buffer: %s\n", path);
+	  return 0;
+      }
+    rl2_destroy_section (img);
+
+    mskbuf_sz = width * height;
+    mskbuf = malloc (mskbuf_sz);
+    if (mskbuf == NULL)
+      {
+	  fprintf (stderr, "Unable to create a mask for: %s\n", path);
+	  return 0;
+      }
+    p_mask = mskbuf;
+
+    for (row = 0; row < height; row++)
+      {
+	  for (col = 0; col < width; col++)
+	    {
+		if (row >= 64 && row <= 96 && col >= 32 && col <= 64)
+		    *p_mask++ = 0;
+		else
+		    *p_mask++ = 1;
+	    }
+      }
+
+    rst = rl2_create_raster (width, height, RL2_SAMPLE_UINT8, RL2_PIXEL_RGB, 3,
+			     rgbbuf, rgbbuf_sz, NULL, mskbuf, mskbuf_sz, NULL);
+    if (rst == NULL)
+      {
+	  fprintf (stderr, "Unable to create the output raster+mask\n");
+	  return 0;
+      }
+
+    img =
+	rl2_create_section ("beta", RL2_COMPRESSION_JPEG,
+			    RL2_TILESIZE_UNDEFINED, RL2_TILESIZE_UNDEFINED,
+			    rst);
+    if (img == NULL)
+      {
+	  fprintf (stderr, "Unable to create the output section+mask\n");
+	  return 0;
+      }
+
+    if (rl2_section_to_lossless_jpeg2000 (img, "./jp2_alpha.jp2") != RL2_OK)
+      {
+	  fprintf (stderr, "Unable to write: jp2_alpha.jp2\n");
+	  return 0;
+      }
+
+    rl2_destroy_section (img);
+
+    img =
+	rl2_section_from_jpeg2000 ("./jp2_alpha.jp2", RL2_SAMPLE_UINT8,
+				   RL2_PIXEL_RGB, 3);
+    if (img == NULL)
+      {
+	  fprintf (stderr, "Unable to read: %s\n", "./jp2_alpha.jp2");
+	  return 0;
+      }
+
+    if (rl2_section_to_png (img, "./from_jp2_alpha.png") != RL2_OK)
+      {
+	  fprintf (stderr, "Unable to write: from_jp2_alpha.png\n");
+	  return 0;
+      }
+    unlink ("./from_jp2_alpha.png");
+    unlink ("./jp2_alpha.jp2");
+
+    rl2_destroy_section (img);
+
+    if (rl2_raster_data_to_RGB (NULL, &rgbbuf, &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw RGB buffer: (NULL raster)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_RGBA (NULL, &rgbbuf, &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw RGBA buffer: (NULL raster)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_ARGB (NULL, &rgbbuf, &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw ARGB buffer: (NULL raster)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_BGR (NULL, &rgbbuf, &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw BGR buffer: (NULL raster)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_BGRA (NULL, &rgbbuf, &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw BGRA buffer: (NULL raster)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_int8 (NULL, (char **) (&rgbbuf), &rgbbuf_sz) !=
+	RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw INT8 buffer: (NULL raster)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_uint8 (NULL, &rgbbuf, &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw UINT8 buffer: (NULL raster)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_int16 (NULL, (short **) (&rgbbuf), &rgbbuf_sz) !=
+	RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw INT16 buffer: (NULL raster)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_uint16
+	(NULL, (unsigned short **) (&rgbbuf), &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw UINT16 buffer: (NULL raster)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_int32 (NULL, (int **) (&rgbbuf), &rgbbuf_sz) !=
+	RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw INT32 buffer: (NULL raster)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_uint32
+	(NULL, (unsigned int **) (&rgbbuf), &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw UINT32 buffer: (NULL raster)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_float (NULL, (float **) (&rgbbuf), &rgbbuf_sz) !=
+	RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw FLOAT buffer: (NULL raster)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_double (NULL, (double **) (&rgbbuf), &rgbbuf_sz) !=
+	RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw DOUBLE buffer: (NULL raster)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_1bit (NULL, &rgbbuf, &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw 1-BIT buffer: (NULL raster)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_2bit (NULL, &rgbbuf, &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw 2-BIT buffer: (NULL raster)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_4bit (NULL, &rgbbuf, &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw 4-BIT buffer: (NULL raster)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_band_to_uint8 (NULL, 0, &rgbbuf, &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw band UINT8 buffer: (NULL raster)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_band_to_uint16
+	(NULL, 0, (unsigned short **) (&rgbbuf), &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw band UINT16 buffer: (NULL raster)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_bands_to_RGB (NULL, 0, 1, 2, &rgbbuf, &rgbbuf_sz) !=
+	RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw BandsAsRGB buffer: (NULL raster)\n");
+	  return 0;
+      }
+
+    bufpix = malloc (256 * 256);
+    raster =
+	rl2_create_raster (256, 256, RL2_SAMPLE_UINT8, RL2_PIXEL_DATAGRID, 1,
+			   bufpix, 256 * 256, NULL, NULL, 0, NULL);
+
+    if (raster == NULL)
+      {
+	  fprintf (stderr, "Unable to create raster (UINT8 Grid)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_int8 (raster, (char **) (&rgbbuf), &rgbbuf_sz) !=
+	RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw INT8 buffer: (UINT8 Grid)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_int16 (raster, (short **) (&rgbbuf), &rgbbuf_sz) !=
+	RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw INT16 buffer: (UINT8 Grid)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_uint16
+	(raster, (unsigned short **) (&rgbbuf), &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw INT16 buffer: (UINT8 Grid)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_int32 (raster, (int **) (&rgbbuf), &rgbbuf_sz) !=
+	RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw INT32 buffer: (UINT8 Grid)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_uint32
+	(raster, (unsigned int **) (&rgbbuf), &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw INT32 buffer: (UINT8 Grid)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_float (raster, (float **) (&rgbbuf), &rgbbuf_sz) !=
+	RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw FLOAT buffer: (UINT8 Grid)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_double (raster, (double **) (&rgbbuf), &rgbbuf_sz) !=
+	RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw DOUBLE buffer: (UINT8 Grid)\n");
+	  return 0;
+      }
+
+    rl2_destroy_raster (raster);
+
+    bufpix = malloc (256 * 256);
+    raster =
+	rl2_create_raster (256, 256, RL2_SAMPLE_INT8, RL2_PIXEL_DATAGRID, 1,
+			   bufpix, 256 * 256, NULL, NULL, 0, NULL);
+
+    if (raster == NULL)
+      {
+	  fprintf (stderr, "Unable to create raster (INT8 Grid)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_uint8 (raster, &rgbbuf, &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw UINT8 buffer: (INT8 Grid)\n");
+	  return 0;
+      }
+
+    rl2_destroy_raster (raster);
+
+    bufpix = malloc (256 * 256 * 3);
+    raster =
+	rl2_create_raster (256, 256, RL2_SAMPLE_UINT8, RL2_PIXEL_MULTIBAND, 3,
+			   bufpix, 256 * 256 * 3, NULL, NULL, 0, NULL);
+
+    if (raster == NULL)
+      {
+	  fprintf (stderr, "Unable to create raster (MultiBand)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_band_to_uint16
+	(raster, 0, (unsigned short **) (&rgbbuf), &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw UINT16 buffer: (MultiBand)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_band_to_uint8 (raster, -1, &rgbbuf, &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw UINT8 buffer: (invalid Band #1)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_band_to_uint8 (raster, 3, &rgbbuf, &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw UINT8 buffer: (invalid Band #2)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_band_to_uint8 (raster, -1, &rgbbuf, &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw UINT8 buffer: (invalid Band #1)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_band_to_uint8 (raster, 3, &rgbbuf, &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw UINT8 buffer: (invalid Band #2)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_bands_to_RGB (raster, 0, -1, 2, &rgbbuf, &rgbbuf_sz) !=
+	RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw BandsAsRGB buffer: (invalid GREEN Band #1)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_bands_to_RGB (raster, 0, 3, 2, &rgbbuf, &rgbbuf_sz) !=
+	RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw BandsAsRGB buffer: (invalid GREEN Band #2)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_bands_to_RGB (raster, 0, 1, -1, &rgbbuf, &rgbbuf_sz) !=
+	RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw BandsAsRGB buffer: (invalid BLUE Band #1)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_bands_to_RGB (raster, 0, 1, 3, &rgbbuf, &rgbbuf_sz) !=
+	RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw BandsAsRGB buffer: (invalid BLUE Band #2)\n");
+	  return 0;
+      }
+
+    rl2_destroy_raster (raster);
+
+    bufpix = malloc (256 * 256 * 6);
+    raster =
+	rl2_create_raster (256, 256, RL2_SAMPLE_UINT16, RL2_PIXEL_MULTIBAND, 3,
+			   bufpix, 256 * 256 * 6, NULL, NULL, 0, NULL);
+
+    if (raster == NULL)
+      {
+	  fprintf (stderr, "Unable to create raster (MultiBand16)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_band_to_uint8 (raster, 0, &rgbbuf, &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr,
+		   "Unexpected resut: get raw UINT8 buffer: (MultiBand16)\n");
+	  return 0;
+      }
+
+    rl2_destroy_raster (raster);
+
+    no_data = rl2_create_pixel (RL2_SAMPLE_UINT8, RL2_PIXEL_RGB, 3);
+    if (no_data == NULL)
+      {
+	  fprintf (stderr, "Unable to create a NoData pixel (RGB)\n");
+	  return 0;
+      }
+
+    if (rl2_set_pixel_sample_uint8 (no_data, RL2_RED_BAND, 0) != RL2_OK)
+      {
+	  fprintf (stderr, "Unable to set Red NoData (RGB)\n");
+	  return 0;
+      }
+
+    if (rl2_set_pixel_sample_uint8 (no_data, RL2_GREEN_BAND, 0) != RL2_OK)
+      {
+	  fprintf (stderr, "Unable to set Green NoData (RGB)\n");
+	  return 0;
+      }
+
+    if (rl2_set_pixel_sample_uint8 (no_data, RL2_BLUE_BAND, 255) != RL2_OK)
+      {
+	  fprintf (stderr, "Unable to set Blue NoData (RGB)\n");
+	  return 0;
+      }
+
+    bufpix = malloc (256 * 256 * 3);
+    memset (bufpix, 0, 256 * 256 * 3);
+    raster =
+	rl2_create_raster (256, 256, RL2_SAMPLE_UINT8, RL2_PIXEL_RGB, 3,
+			   bufpix, 256 * 256 * 3, NULL, NULL, 0, no_data);
+
+    if (raster == NULL)
+      {
+	  fprintf (stderr, "Unable to create raster (RGB)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_band_to_uint16
+	(raster, 0, (unsigned short **) (&rgbbuf), &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr, "Unexpected resut: get raw UINT16 buffer: (RGB)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_RGBA (raster, &rgbbuf, &rgbbuf_sz) != RL2_OK)
+      {
+	  fprintf (stderr, "Unable to get raw RGBA buffer (RGB)\n");
+	  return 0;
+      }
+    free (rgbbuf);
+
+    if (rl2_raster_data_to_ARGB (raster, &rgbbuf, &rgbbuf_sz) != RL2_OK)
+      {
+	  fprintf (stderr, "Unable to get raw ARGB buffer (RGB)\n");
+	  return 0;
+      }
+    free (rgbbuf);
+
+    if (rl2_raster_data_to_BGRA (raster, &rgbbuf, &rgbbuf_sz) != RL2_OK)
+      {
+	  fprintf (stderr, "Unable to get raw BGRA buffer (RGB)\n");
+	  return 0;
+      }
+    free (rgbbuf);
+
+    if (rl2_raster_data_to_1bit (raster, &rgbbuf, &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr, "Unexpected resut: get raw 1-BIT buffer: (RGB)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_2bit (raster, &rgbbuf, &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr, "Unexpected resut: get raw 2-BIT buffer: (RGB)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_4bit (raster, &rgbbuf, &rgbbuf_sz) != RL2_ERROR)
+      {
+	  fprintf (stderr, "Unexpected resut: get raw 4-BIT buffer: (RGB)\n");
+	  return 0;
+      }
+
+    rl2_destroy_raster (raster);
+
+    no_data = rl2_create_pixel (RL2_SAMPLE_1_BIT, RL2_PIXEL_MONOCHROME, 1);
+    if (no_data == NULL)
+      {
+	  fprintf (stderr, "Unable to create a NoData pixel (MONOCHROME)\n");
+	  return 0;
+      }
+
+    if (rl2_set_pixel_sample_1bit (no_data, 1) != RL2_OK)
+      {
+	  fprintf (stderr, "Unable to set NoData (MONOCHROME)\n");
+	  return 0;
+      }
+
+    bufpix = malloc (256 * 256);
+    memset (bufpix, 0, 256 * 256);
+    raster =
+	rl2_create_raster (256, 256, RL2_SAMPLE_1_BIT, RL2_PIXEL_MONOCHROME, 1,
+			   bufpix, 256 * 256, NULL, NULL, 0, no_data);
+
+    if (raster == NULL)
+      {
+	  fprintf (stderr, "Unable to create raster (MONOCHROME)\n");
+	  return 0;
+      }
+
+    if (rl2_raster_data_to_RGBA (raster, &rgbbuf, &rgbbuf_sz) != RL2_OK)
+      {
+	  fprintf (stderr, "Unable to get raw RGBA buffer (MONOCHROME)\n");
+	  return 0;
+      }
+    free (rgbbuf);
+
+    if (rl2_raster_data_to_ARGB (raster, &rgbbuf, &rgbbuf_sz) != RL2_OK)
+      {
+	  fprintf (stderr, "Unable to get raw ARGB buffer (MONOCHROME)\n");
+	  return 0;
+      }
+    free (rgbbuf);
+
+    if (rl2_raster_data_to_BGRA (raster, &rgbbuf, &rgbbuf_sz) != RL2_OK)
+      {
+	  fprintf (stderr, "Unable to get raw BGRA buffer (MONOCHROME)\n");
+	  return 0;
+      }
+    free (rgbbuf);
+
+    rl2_destroy_raster (raster);
+
+    return 1;
+}
+
+static int
+test_infos_openjpeg (const char *path)
+{
+    unsigned int width;
+    unsigned int height;
+    unsigned char sample_type;
+    unsigned char pixel_type;
+    unsigned char num_bands;
+    unsigned int tile_width;
+    unsigned int tile_height;
+    unsigned char num_levels;
+
+    if (rl2_get_jpeg2000_infos
+	(path, &width, &height, &sample_type, &pixel_type, &num_bands,
+	 &tile_width, &tile_height, &num_levels) != RL2_OK)
+      {
+	  fprintf (stderr, "Unable to read: %s\n", path);
+	  return 0;
+      }
+    if (width != 640)
+      {
+	  fprintf (stderr, "Unexpected Width: %u\n", width);
+	  return 0;
+      }
+    if (height != 480)
+      {
+	  fprintf (stderr, "Unexpected Height: %u\n", height);
+	  return 0;
+      }
+    if (sample_type != RL2_SAMPLE_UINT8)
+      {
+	  fprintf (stderr, "Unexpected SampleType: %02x\n", sample_type);
+	  return 0;
+      }
+    if (pixel_type != RL2_PIXEL_RGB)
+      {
+	  fprintf (stderr, "Unexpected PixelType: %02x\n", pixel_type);
+	  return 0;
+      }
+    if (num_bands != 3)
+      {
+	  fprintf (stderr, "Unexpected Bands: %u\n", num_bands);
+	  return 0;
+      }
+    if (tile_width != 640)
+      {
+	  fprintf (stderr, "Unexpected TileWidth: %u\n", tile_width);
+	  return 0;
+      }
+    if (tile_height != 480)
+      {
+	  fprintf (stderr, "Unexpected TileHeight: %u\n", tile_height);
+	  return 0;
+      }
+    if (num_levels != 6)
+      {
+	  fprintf (stderr, "Unexpected Levels: %u\n", num_levels);
+	  return 0;
+      }
+
+    return 1;
+}
+
+static int
+test_blob_infos_openjpeg (const char *path)
+{
+    unsigned char *p_blob = NULL;
+    int n_bytes;
+    int rd;
+    FILE *in = NULL;
+    char *msg;
+    unsigned char sample_type;
+    unsigned char pixel_type;
+    unsigned char num_bands;
+
+/* loading the image in-memory */
+    msg = sqlite3_mprintf ("Unable to load \"%s\" in-memory\n", path);
+    in = fopen (path, "rb");
+    if (in == NULL)
+	goto error;
+    if (fseek (in, 0, SEEK_END) < 0)
+	goto error;
+    n_bytes = ftell (in);
+    rewind (in);
+    p_blob = malloc (n_bytes);
+    rd = fread (p_blob, 1, n_bytes, in);
+    fclose (in);
+    in = NULL;
+    if (rd != n_bytes)
+	goto error;
+
+    if (rl2_get_jpeg2000_blob_type
+	(p_blob, n_bytes, &sample_type, &pixel_type, &num_bands) != RL2_OK)
+      {
+	  fprintf (stderr, "Unable to read: %s\n", path);
+	  goto error;
+      }
+    if (sample_type != RL2_SAMPLE_UINT8)
+      {
+	  fprintf (stderr, "Unexpected SampleType: %02x\n", sample_type);
+	  goto error;
+      }
+    if (pixel_type != RL2_PIXEL_RGB)
+      {
+	  fprintf (stderr, "Unexpected PixelType: %02x\n", pixel_type);
+	  goto error;
+      }
+    if (num_bands != 3)
+      {
+	  fprintf (stderr, "Unexpected Bands: %u\n", num_bands);
+	  goto error;
+      }
+
+    free (p_blob);
+    sqlite3_free (msg);
+    return 1;
+
+  error:
+    if (p_blob != NULL)
+	free (p_blob);
+    if (in != NULL)
+	fclose (in);
+    fprintf (stderr, "%s", msg);
+    sqlite3_free (msg);
+    return 0;
+}
+
+#endif /* end OpenJpeg conditional */
+
+int
+main (int argc, char *argv[])
+{
+    if (argc > 1 || argv[0] == NULL)
+	argc = 1;		/* silencing stupid compiler warnings */
+
+#ifndef OMIT_OPENJPEG
+    if (!test_no_alpha_openjpeg ("./Cevennes2.jp2"))
+	return -1;
+    if (!test_infos_openjpeg ("./Cevennes2.jp2"))
+	return -1;
+    if (!test_blob_infos_openjpeg ("./Cevennes2.jp2"))
+	return -1;
+#endif
+
+    return 0;
+}
diff --git a/test/test_paint.c b/test/test_paint.c
index 71eb1f5..41e555c 100644
--- a/test/test_paint.c
+++ b/test/test_paint.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -72,6 +72,7 @@ do_paint_test (rl2GraphicsContextPtr ctx)
     double h;
     double post_x;
     double post_y;
+    double dash_list[4];
 
 /* loading a sample Image (RGB) */
     img = rl2_section_from_jpeg ("./jpeg1.jpg");
@@ -178,7 +179,11 @@ do_paint_test (rl2GraphicsContextPtr ctx)
     rl2_graph_destroy_bitmap (bmp);
 
 /* setting up a RED dotted pen */
-    if (!rl2_graph_set_pen (ctx, 255, 0, 0, 255, 8.0, RL2_PENSTYLE_DOT))
+    dash_list[0] = 25.0;
+    dash_list[1] = 25.0;
+    if (!rl2_graph_set_dashed_pen
+	(ctx, 255, 0, 0, 255, 8.0, RL2_PEN_CAP_BUTT, RL2_PEN_JOIN_MITER, 2,
+	 dash_list, 0.0))
       {
 	  fprintf (stderr, "Unable to set a Red Dotted Pen\n");
 	  return -24;
@@ -206,7 +211,8 @@ do_paint_test (rl2GraphicsContextPtr ctx)
       }
 
 /* setting up a Black solid pen */
-    if (!rl2_graph_set_pen (ctx, 0, 0, 0, 255, 2.0, RL2_PENSTYLE_SOLID))
+    if (!rl2_graph_set_solid_pen
+	(ctx, 0, 0, 0, 255, 2.0, RL2_PEN_CAP_BUTT, RL2_PEN_JOIN_MITER))
       {
 	  fprintf (stderr, "Unable to set a Black solid Pen\n");
 	  return -28;
@@ -245,7 +251,8 @@ do_paint_test (rl2GraphicsContextPtr ctx)
       }
 
 /* setting up a Red solid pen */
-    if (!rl2_graph_set_pen (ctx, 255, 0, 0, 255, 16.0, RL2_PENSTYLE_SOLID))
+    if (!rl2_graph_set_solid_pen
+	(ctx, 255, 0, 0, 255, 16.0, RL2_PEN_CAP_BUTT, RL2_PEN_JOIN_MITER))
       {
 	  fprintf (stderr, "Unable to set a Red solid Pen\n");
 	  return -33;
@@ -300,7 +307,7 @@ do_paint_test (rl2GraphicsContextPtr ctx)
       }
 
 /* creating and setting up a pattern brush */
-    pattern = rl2_graph_create_pattern (rgba, 64, 64);
+    pattern = rl2_graph_create_pattern (rgba, 64, 64, 1);
     if (pattern == NULL)
       {
 	  fprintf (stderr, "Unable to create a Pattern Brush\n");
@@ -369,11 +376,13 @@ do_paint_test (rl2GraphicsContextPtr ctx)
 	  return -46;
       }
 
+    rl2_graph_release_pattern_brush (ctx);
     rl2_graph_destroy_pattern (pattern);
 
 /* creating and setting up a Green bold italic font */
     font =
-	rl2_graph_create_font (32, RL2_FONTSTYLE_ITALIC, RL2_FONTWEIGHT_BOLD);
+	rl2_graph_create_toy_font ("serif", 32, RL2_FONTSTYLE_ITALIC,
+				   RL2_FONTWEIGHT_BOLD);
     if (pattern == NULL)
       {
 	  fprintf (stderr, "Unable to create a Font\n");
@@ -389,7 +398,7 @@ do_paint_test (rl2GraphicsContextPtr ctx)
 	  fprintf (stderr, "Unable to set up a font\n");
 	  return -49;
       }
-    if (!rl2_graph_draw_text (ctx, "Armageddon", 1000, 100, 120))
+    if (!rl2_graph_draw_text (ctx, "Armageddon", 1000, 100, 120, 0.0, 0.0))
       {
 	  fprintf (stderr, "Unable to print text #1\n");
 	  return -50;
@@ -398,7 +407,8 @@ do_paint_test (rl2GraphicsContextPtr ctx)
 
 /* creating and setting up a Black outlined font */
     font =
-	rl2_graph_create_font (32, RL2_FONTSTYLE_NORMAL, RL2_FONTWEIGHT_BOLD);
+	rl2_graph_create_toy_font ("sans-serif", 32, RL2_FONTSTYLE_NORMAL,
+				   RL2_FONTWEIGHT_BOLD);
     if (pattern == NULL)
       {
 	  fprintf (stderr, "Unable to create a Font #2\n");
@@ -409,7 +419,7 @@ do_paint_test (rl2GraphicsContextPtr ctx)
 	  fprintf (stderr, "Unable to set the font color #2\n");
 	  return -52;
       }
-    if (!rl2_graph_font_set_outline (font, 1.5))
+    if (!rl2_graph_font_set_halo (font, 1.5, 255, 255, 255, 255))
       {
 	  fprintf (stderr, "Unable to set the font outline\n");
 	  return -53;
@@ -419,7 +429,7 @@ do_paint_test (rl2GraphicsContextPtr ctx)
 	  fprintf (stderr, "Unable to set up a font #2\n");
 	  return -54;
       }
-    if (!rl2_graph_draw_text (ctx, "Walhalla", 300, 400, 0))
+    if (!rl2_graph_draw_text (ctx, "Walhalla", 300, 400, 0, 0.0, 0.0))
       {
 	  fprintf (stderr, "Unable to print text #2\n");
 	  return -55;
@@ -433,6 +443,759 @@ do_paint_test (rl2GraphicsContextPtr ctx)
 
     rl2_graph_destroy_font (font);
 
+/* testing a blue dotted pen #1 */
+    dash_list[0] = 10.0;
+    dash_list[1] = 10.0;
+    if (!rl2_graph_set_dashed_pen
+	(ctx, 0, 0, 255, 255, 32.0, RL2_PEN_CAP_BUTT, RL2_PEN_JOIN_MITER, 2,
+	 dash_list, 0.0))
+      {
+	  fprintf (stderr, "Unable to set a Blue thick Dotted Pen #1\n");
+	  return -57;
+      }
+    if (!rl2_graph_move_to_point (ctx, 1700, 100))
+      {
+	  fprintf (stderr, "Unable to move to point #1-1\n");
+	  return -58;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1800, 150))
+      {
+	  fprintf (stderr, "Unable to move to point #1-2\n");
+	  return -59;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1900, 100))
+      {
+	  fprintf (stderr, "Unable to move to point #1-3\n");
+	  return -60;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 2000, 150))
+      {
+	  fprintf (stderr, "Unable to move to point #1-3\n");
+	  return -61;
+      }
+    if (!rl2_graph_stroke_path (ctx, 0))
+      {
+	  fprintf (stderr, "Unable to stroke a path #1\n");
+	  return -62;
+      }
+
+/* testing a green dotted pen #2 */
+    dash_list[0] = 10.0;
+    dash_list[1] = 40.0;
+    if (!rl2_graph_set_dashed_pen
+	(ctx, 0, 0, 255, 255, 32.0, RL2_PEN_CAP_ROUND, RL2_PEN_JOIN_ROUND, 2,
+	 dash_list, 0.0))
+      {
+	  fprintf (stderr, "Unable to set a Blue thick Dotted Pen #2\n");
+	  return -63;
+      }
+    if (!rl2_graph_move_to_point (ctx, 1700, 150))
+      {
+	  fprintf (stderr, "Unable to move to point #2-1\n");
+	  return -64;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1800, 200))
+      {
+	  fprintf (stderr, "Unable to move to point #2-2\n");
+	  return -65;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1900, 150))
+      {
+	  fprintf (stderr, "Unable to move to point #2-3\n");
+	  return -66;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 2000, 200))
+      {
+	  fprintf (stderr, "Unable to move to point #2-3\n");
+	  return -67;
+      }
+    if (!rl2_graph_stroke_path (ctx, 0))
+      {
+	  fprintf (stderr, "Unable to stroke a path #2\n");
+	  return -68;
+      }
+
+/* testing a blue dotted pen #3 */
+    dash_list[0] = 50.0;
+    dash_list[1] = 50.0;
+    if (!rl2_graph_set_dashed_pen
+	(ctx, 0, 0, 255, 255, 32.0, RL2_PEN_CAP_SQUARE, RL2_PEN_JOIN_BEVEL, 2,
+	 dash_list, 0.0))
+      {
+	  fprintf (stderr, "Unable to set a Blue thick Dotted Pen #3\n");
+	  return -63;
+      }
+    if (!rl2_graph_move_to_point (ctx, 1700, 200))
+      {
+	  fprintf (stderr, "Unable to move to point #3-1\n");
+	  return -64;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1800, 250))
+      {
+	  fprintf (stderr, "Unable to move to point #3-2\n");
+	  return -65;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1900, 200))
+      {
+	  fprintf (stderr, "Unable to move to point #3-3\n");
+	  return -66;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 2000, 250))
+      {
+	  fprintf (stderr, "Unable to move to point #3-3\n");
+	  return -67;
+      }
+    if (!rl2_graph_stroke_path (ctx, 0))
+      {
+	  fprintf (stderr, "Unable to stroke a path #3\n");
+	  return -68;
+      }
+
+/* testing a gren solid pen #1 */
+    if (!rl2_graph_set_solid_pen
+	(ctx, 0, 255, 0, 255, 32.0, RL2_PEN_CAP_BUTT, RL2_PEN_JOIN_MITER))
+      {
+	  fprintf (stderr, "Unable to set a Green thick Solid Pen #1\n");
+	  return -69;
+      }
+    if (!rl2_graph_move_to_point (ctx, 1700, 300))
+      {
+	  fprintf (stderr, "Unable to move to point #4-1\n");
+	  return -70;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1800, 350))
+      {
+	  fprintf (stderr, "Unable to move to point #4-2\n");
+	  return -71;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1900, 300))
+      {
+	  fprintf (stderr, "Unable to move to point #4-3\n");
+	  return -72;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 2000, 350))
+      {
+	  fprintf (stderr, "Unable to move to point #4-3\n");
+	  return -72;
+      }
+    if (!rl2_graph_stroke_path (ctx, 0))
+      {
+	  fprintf (stderr, "Unable to stroke a path #4\n");
+	  return -74;
+      }
+
+/* testing a green solid pen #2 */
+    if (!rl2_graph_set_solid_pen
+	(ctx, 0, 255, 0, 255, 32.0, RL2_PEN_CAP_ROUND, RL2_PEN_JOIN_ROUND))
+      {
+	  fprintf (stderr, "Unable to set a Green thick Solid Pen #2\n");
+	  return -75;
+      }
+    if (!rl2_graph_move_to_point (ctx, 1700, 350))
+      {
+	  fprintf (stderr, "Unable to move to point #5-1\n");
+	  return -76;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1800, 400))
+      {
+	  fprintf (stderr, "Unable to move to point #5-2\n");
+	  return -77;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1900, 350))
+      {
+	  fprintf (stderr, "Unable to move to point #5-3\n");
+	  return -78;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 2000, 400))
+      {
+	  fprintf (stderr, "Unable to move to point #5-3\n");
+	  return -79;
+      }
+    if (!rl2_graph_stroke_path (ctx, 0))
+      {
+	  fprintf (stderr, "Unable to stroke a path #5\n");
+	  return -80;
+      }
+
+/* testing a green solid pen #3 */
+    if (!rl2_graph_set_solid_pen
+	(ctx, 0, 255, 0, 255, 32.0, RL2_PEN_CAP_SQUARE, RL2_PEN_JOIN_BEVEL))
+      {
+	  fprintf (stderr, "Unable to set a Green thick Solid Pen #3\n");
+	  return -81;
+      }
+    if (!rl2_graph_move_to_point (ctx, 1700, 400))
+      {
+	  fprintf (stderr, "Unable to move to point #6-1\n");
+	  return -82;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1800, 450))
+      {
+	  fprintf (stderr, "Unable to move to point #6-2\n");
+	  return -83;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1900, 400))
+      {
+	  fprintf (stderr, "Unable to move to point #6-3\n");
+	  return -84;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 2000, 450))
+      {
+	  fprintf (stderr, "Unable to move to point #6-3\n");
+	  return -85;
+      }
+    if (!rl2_graph_stroke_path (ctx, 0))
+      {
+	  fprintf (stderr, "Unable to stroke a path #6\n");
+	  return -86;
+      }
+
+/* testing a linear gradient dotted pen #1 */
+    dash_list[0] = 10.0;
+    dash_list[1] = 10.0;
+    if (!rl2_graph_set_linear_gradient_dashed_pen
+	(ctx, 1700, 700, 300, 50, 255, 255, 0, 255, 0, 0, 255, 255, 32.0,
+	 RL2_PEN_CAP_BUTT, RL2_PEN_JOIN_MITER, 2, dash_list, 0.0))
+      {
+	  fprintf (stderr,
+		   "Unable to set a Linear Gradient thick Dotted Pen #1\n");
+	  return -57;
+      }
+    if (!rl2_graph_move_to_point (ctx, 1700, 500))
+      {
+	  fprintf (stderr, "Unable to move to point #7-1\n");
+	  return -87;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1800, 550))
+      {
+	  fprintf (stderr, "Unable to move to point #7-2\n");
+	  return -88;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1900, 500))
+      {
+	  fprintf (stderr, "Unable to move to point #7-3\n");
+	  return -89;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 2000, 550))
+      {
+	  fprintf (stderr, "Unable to move to point #7-3\n");
+	  return -90;
+      }
+    if (!rl2_graph_stroke_path (ctx, 0))
+      {
+	  fprintf (stderr, "Unable to stroke a path #7\n");
+	  return -91;
+      }
+
+/* testing a linear gradient dotted pen #2 */
+    dash_list[0] = 10.0;
+    dash_list[1] = 40.0;
+    if (!rl2_graph_set_linear_gradient_dashed_pen
+	(ctx, 1700, 800, 300, 50, 255, 255, 0, 255, 0, 0, 255, 255, 32.0,
+	 RL2_PEN_CAP_ROUND, RL2_PEN_JOIN_ROUND, 2, dash_list, 0.0))
+      {
+	  fprintf (stderr,
+		   "Unable to set a Linear Gradient thick Dotted Pen #2\n");
+	  return -92;
+      }
+    if (!rl2_graph_move_to_point (ctx, 1700, 550))
+      {
+	  fprintf (stderr, "Unable to move to point #8-1\n");
+	  return -93;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1800, 600))
+      {
+	  fprintf (stderr, "Unable to move to point #8-2\n");
+	  return -94;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1900, 550))
+      {
+	  fprintf (stderr, "Unable to move to point #8-3\n");
+	  return -95;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 2000, 600))
+      {
+	  fprintf (stderr, "Unable to move to point #8-3\n");
+	  return -96;
+      }
+    if (!rl2_graph_stroke_path (ctx, 0))
+      {
+	  fprintf (stderr, "Unable to stroke a path #8\n");
+	  return -97;
+      }
+
+/* testing a linear gradient dotted pen #3 */
+    dash_list[0] = 50.0;
+    dash_list[1] = 50.0;
+    if (!rl2_graph_set_linear_gradient_dashed_pen
+	(ctx, 1700, 900, 300, 50, 255, 255, 0, 255, 0, 0, 255, 255, 32.0,
+	 RL2_PEN_CAP_SQUARE, RL2_PEN_JOIN_BEVEL, 2, dash_list, 0.0))
+      {
+	  fprintf (stderr,
+		   "Unable to set a Linear Gradient thick Dotted Pen #3\n");
+	  return -98;
+      }
+    if (!rl2_graph_move_to_point (ctx, 1700, 600))
+      {
+	  fprintf (stderr, "Unable to move to point #9-1\n");
+	  return -99;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1800, 650))
+      {
+	  fprintf (stderr, "Unable to move to point #9-2\n");
+	  return -100;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1900, 600))
+      {
+	  fprintf (stderr, "Unable to move to point #9-3\n");
+	  return -101;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 2000, 650))
+      {
+	  fprintf (stderr, "Unable to move to point #9-3\n");
+	  return -102;
+      }
+    if (!rl2_graph_stroke_path (ctx, 0))
+      {
+	  fprintf (stderr, "Unable to stroke a path #9\n");
+	  return -103;
+      }
+
+/* testing a linear gradient solid pen #1 */
+    if (!rl2_graph_set_linear_gradient_solid_pen
+	(ctx, 1700, 1000, 300, 50, 255, 0, 0, 255, 0, 255, 255, 255, 32.0,
+	 RL2_PEN_CAP_BUTT, RL2_PEN_JOIN_MITER))
+      {
+	  fprintf (stderr,
+		   "Unable to set a Linear Gradient thick Solid Pen #1\n");
+	  return -104;
+      }
+    if (!rl2_graph_move_to_point (ctx, 1700, 700))
+      {
+	  fprintf (stderr, "Unable to move to point #10-1\n");
+	  return -105;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1800, 750))
+      {
+	  fprintf (stderr, "Unable to move to point #10-2\n");
+	  return -106;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1900, 700))
+      {
+	  fprintf (stderr, "Unable to move to point #10-3\n");
+	  return -107;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 2000, 750))
+      {
+	  fprintf (stderr, "Unable to move to point #10-3\n");
+	  return -108;
+      }
+    if (!rl2_graph_stroke_path (ctx, 0))
+      {
+	  fprintf (stderr, "Unable to stroke a path #10\n");
+	  return -109;
+      }
+
+/* testing a linear gradient solid pen #2 */
+    if (!rl2_graph_set_linear_gradient_solid_pen
+	(ctx, 1700, 1100, 300, 50, 255, 0, 0, 255, 0, 255, 255, 255, 32.0,
+	 RL2_PEN_CAP_ROUND, RL2_PEN_JOIN_ROUND))
+      {
+	  fprintf (stderr,
+		   "Unable to set a Linear Gradient thick Solid Pen #2\n");
+	  return -110;
+      }
+    if (!rl2_graph_move_to_point (ctx, 1700, 750))
+      {
+	  fprintf (stderr, "Unable to move to point #11-1\n");
+	  return -111;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1800, 800))
+      {
+	  fprintf (stderr, "Unable to move to point #11-2\n");
+	  return -112;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1900, 750))
+      {
+	  fprintf (stderr, "Unable to move to point #11-3\n");
+	  return -113;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 2000, 800))
+      {
+	  fprintf (stderr, "Unable to move to point #11-3\n");
+	  return -114;
+      }
+    if (!rl2_graph_stroke_path (ctx, 0))
+      {
+	  fprintf (stderr, "Unable to stroke a path #11\n");
+	  return -115;
+      }
+
+/* testing a linear gradient solid pen #3 */
+    if (!rl2_graph_set_linear_gradient_solid_pen
+	(ctx, 1700, 1200, 300, 50, 255, 0, 0, 255, 0, 255, 255, 255, 32.0,
+	 RL2_PEN_CAP_SQUARE, RL2_PEN_JOIN_BEVEL))
+      {
+	  fprintf (stderr,
+		   "Unable to set a Linear Gradient thick Solid Pen #3\n");
+	  return -116;
+      }
+    if (!rl2_graph_move_to_point (ctx, 1700, 800))
+      {
+	  fprintf (stderr, "Unable to move to point #12-1\n");
+	  return -117;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1800, 850))
+      {
+	  fprintf (stderr, "Unable to move to point #12-2\n");
+	  return -118;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1900, 800))
+      {
+	  fprintf (stderr, "Unable to move to point #12-3\n");
+	  return -119;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 2000, 850))
+      {
+	  fprintf (stderr, "Unable to move to point #12-3\n");
+	  return -120;
+      }
+    if (!rl2_graph_stroke_path (ctx, 0))
+      {
+	  fprintf (stderr, "Unable to stroke a path #12\n");
+	  return -121;
+      }
+
+/* creating an RGBA buffer */
+    rgba = malloc (64 * 64 * 4);
+    p_rgba = rgba;
+    for (row = 0; row < 64; row++)
+      {
+	  for (col = 0; col < 64; col++)
+	    {
+		if (row >= 32)
+		  {
+		      if (col >= 32)
+			{
+			    red = 255;
+			    green = 255;
+			    blue = 0;
+			    alpha = 255;
+			}
+		      else
+			{
+			    red = 0;
+			    green = 255;
+			    blue = 255;
+			    alpha = 255;
+			}
+		  }
+		else
+		  {
+		      if (col >= 32)
+			{
+			    red = 0;
+			    green = 255;
+			    blue = 255;
+			    alpha = 255;
+			}
+		      else
+			{
+			    red = 255;
+			    green = 255;
+			    blue = 0;
+			    alpha = 255;
+			}
+		  }
+		*p_rgba++ = red;
+		*p_rgba++ = green;
+		*p_rgba++ = blue;
+		*p_rgba++ = alpha;
+	    }
+      }
+
+/* creating and setting up a pattern brush */
+    pattern = rl2_graph_create_pattern (rgba, 64, 64, 1);
+    if (pattern == NULL)
+      {
+	  fprintf (stderr, "Unable to create a Pattern Pen\n");
+	  return -122;
+      }
+
+/* testing a pattern dotted pen #1 */
+    dash_list[0] = 10.0;
+    dash_list[1] = 10.0;
+    if (!rl2_graph_set_pattern_dashed_pen
+	(ctx, pattern, 32.0, RL2_PEN_CAP_BUTT, RL2_PEN_JOIN_MITER, 2, dash_list,
+	 0.0))
+      {
+	  fprintf (stderr, "Unable to set a Pattern thick Dotted Pen #1\n");
+	  return -123;
+      }
+    if (!rl2_graph_move_to_point (ctx, 1700, 900))
+      {
+	  fprintf (stderr, "Unable to move to point #13-1\n");
+	  return -124;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1800, 950))
+      {
+	  fprintf (stderr, "Unable to move to point #13-2\n");
+	  return -125;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1900, 900))
+      {
+	  fprintf (stderr, "Unable to move to point #13-3\n");
+	  return -126;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 2000, 950))
+      {
+	  fprintf (stderr, "Unable to move to point #13-3\n");
+	  return -127;
+      }
+    if (!rl2_graph_stroke_path (ctx, 0))
+      {
+	  fprintf (stderr, "Unable to stroke a path #13\n");
+	  return -128;
+      }
+
+/* testing a pattern dotted pen #2 */
+    dash_list[0] = 10.0;
+    dash_list[1] = 40.0;
+    if (!rl2_graph_set_pattern_dashed_pen
+	(ctx, pattern, 32.0, RL2_PEN_CAP_ROUND, RL2_PEN_JOIN_ROUND, 2,
+	 dash_list, 0.0))
+      {
+	  fprintf (stderr, "Unable to set a Pattern thick Dotted Pen #2\n");
+	  return -129;
+      }
+    if (!rl2_graph_move_to_point (ctx, 1700, 950))
+      {
+	  fprintf (stderr, "Unable to move to point #14-1\n");
+	  return -130;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1800, 1000))
+      {
+	  fprintf (stderr, "Unable to move to point #14-2\n");
+	  return -131;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1900, 950))
+      {
+	  fprintf (stderr, "Unable to move to point #14-3\n");
+	  return -132;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 2000, 1000))
+      {
+	  fprintf (stderr, "Unable to move to point #14-3\n");
+	  return -133;
+      }
+    if (!rl2_graph_stroke_path (ctx, 0))
+      {
+	  fprintf (stderr, "Unable to stroke a path #14\n");
+	  return -134;
+      }
+
+/* testing a pattern dotted pen #3 */
+    dash_list[0] = 50.0;
+    dash_list[1] = 50.0;
+    if (!rl2_graph_set_pattern_dashed_pen
+	(ctx, pattern, 32.0, RL2_PEN_CAP_SQUARE, RL2_PEN_JOIN_BEVEL, 2,
+	 dash_list, 0.0))
+      {
+	  fprintf (stderr, "Unable to set a Pattern thick Dotted Pen #3\n");
+	  return -98;
+      }
+    if (!rl2_graph_move_to_point (ctx, 1700, 1000))
+      {
+	  fprintf (stderr, "Unable to move to point #15-1\n");
+	  return -135;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1800, 1050))
+      {
+	  fprintf (stderr, "Unable to move to point #15-2\n");
+	  return -136;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1900, 1000))
+      {
+	  fprintf (stderr, "Unable to move to point #15-3\n");
+	  return -137;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 2000, 1050))
+      {
+	  fprintf (stderr, "Unable to move to point #15-3\n");
+	  return -138;
+      }
+    if (!rl2_graph_stroke_path (ctx, 0))
+      {
+	  fprintf (stderr, "Unable to stroke a path #15\n");
+	  return -139;
+      }
+
+    rl2_graph_release_pattern_pen (ctx);
+    rl2_graph_destroy_pattern (pattern);
+
+/* creating an RGBA buffer */
+    rgba = malloc (64 * 64 * 4);
+    p_rgba = rgba;
+    for (row = 0; row < 64; row++)
+      {
+	  for (col = 0; col < 64; col++)
+	    {
+		if (row >= 32)
+		  {
+		      if (col >= 32)
+			{
+			    red = 255;
+			    green = 255;
+			    blue = 0;
+			    alpha = 255;
+			}
+		      else
+			{
+			    red = 255;
+			    green = 0;
+			    blue = 0;
+			    alpha = 255;
+			}
+		  }
+		else
+		  {
+		      if (col >= 32)
+			{
+			    red = 255;
+			    green = 0;
+			    blue = 0;
+			    alpha = 255;
+			}
+		      else
+			{
+			    red = 255;
+			    green = 255;
+			    blue = 0;
+			    alpha = 255;
+			}
+		  }
+		*p_rgba++ = red;
+		*p_rgba++ = green;
+		*p_rgba++ = blue;
+		*p_rgba++ = alpha;
+	    }
+      }
+
+/* creating and setting up a pattern brush */
+    pattern = rl2_graph_create_pattern (rgba, 64, 64, 1);
+    if (pattern == NULL)
+      {
+	  fprintf (stderr, "Unable to create a Pattern Pen\n");
+	  return -140;
+      }
+
+/* testing a pattern solid pen #1 */
+    dash_list[0] = 10.0;
+    dash_list[1] = 10.0;
+    if (!rl2_graph_set_pattern_solid_pen
+	(ctx, pattern, 32.0, RL2_PEN_CAP_BUTT, RL2_PEN_JOIN_MITER))
+      {
+	  fprintf (stderr, "Unable to set a Pattern thick Solid Pen #1\n");
+	  return -141;
+      }
+    if (!rl2_graph_move_to_point (ctx, 1700, 1100))
+      {
+	  fprintf (stderr, "Unable to move to point #16-1\n");
+	  return -142;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1800, 1150))
+      {
+	  fprintf (stderr, "Unable to move to point #16-2\n");
+	  return -143;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1900, 1100))
+      {
+	  fprintf (stderr, "Unable to move to point #16-3\n");
+	  return -144;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 2000, 1150))
+      {
+	  fprintf (stderr, "Unable to move to point #16-3\n");
+	  return -145;
+      }
+    if (!rl2_graph_stroke_path (ctx, 0))
+      {
+	  fprintf (stderr, "Unable to stroke a path #16\n");
+	  return -146;
+      }
+
+/* testing a pattern solid pen #2 */
+    dash_list[0] = 10.0;
+    dash_list[1] = 40.0;
+    if (!rl2_graph_set_pattern_solid_pen
+	(ctx, pattern, 32.0, RL2_PEN_CAP_ROUND, RL2_PEN_JOIN_ROUND))
+      {
+	  fprintf (stderr, "Unable to set a Pattern thick Solid Pen #2\n");
+	  return -147;
+      }
+    if (!rl2_graph_move_to_point (ctx, 1700, 1150))
+      {
+	  fprintf (stderr, "Unable to move to point #17-1\n");
+	  return -148;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1800, 1200))
+      {
+	  fprintf (stderr, "Unable to move to point #17-2\n");
+	  return -131;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1900, 1150))
+      {
+	  fprintf (stderr, "Unable to move to point #17-3\n");
+	  return -149;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 2000, 1200))
+      {
+	  fprintf (stderr, "Unable to move to point #17-3\n");
+	  return -150;
+      }
+    if (!rl2_graph_stroke_path (ctx, 0))
+      {
+	  fprintf (stderr, "Unable to stroke a path #17\n");
+	  return -151;
+      }
+
+/* testing a pattern solid pen #3 */
+    dash_list[0] = 50.0;
+    dash_list[1] = 50.0;
+    if (!rl2_graph_set_pattern_solid_pen
+	(ctx, pattern, 32.0, RL2_PEN_CAP_SQUARE, RL2_PEN_JOIN_BEVEL))
+      {
+	  fprintf (stderr, "Unable to set a Pattern thick Solid Pen #3\n");
+	  return -152;
+      }
+    if (!rl2_graph_move_to_point (ctx, 1700, 1200))
+      {
+	  fprintf (stderr, "Unable to move to point #18-1\n");
+	  return -153;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1800, 1250))
+      {
+	  fprintf (stderr, "Unable to move to point #18-2\n");
+	  return -154;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 1900, 1200))
+      {
+	  fprintf (stderr, "Unable to move to point #18-3\n");
+	  return -155;
+      }
+    if (!rl2_graph_add_line_to_path (ctx, 2000, 1250))
+      {
+	  fprintf (stderr, "Unable to move to point #18-3\n");
+	  return -156;
+      }
+    if (!rl2_graph_stroke_path (ctx, 0))
+      {
+	  fprintf (stderr, "Unable to stroke a path #18\n");
+	  return -157;
+      }
+
+    rl2_graph_release_pattern_pen (ctx);
+    rl2_graph_destroy_pattern (pattern);
 
     return 0;
 }
@@ -446,6 +1209,7 @@ main (int argc, char *argv[])
     rl2RasterPtr rst;
     rl2SectionPtr img;
     int ret;
+    int half_transparent;
     unsigned char *rgb;
     unsigned char *alpha;
 
@@ -467,8 +1231,8 @@ main (int argc, char *argv[])
 
 /* testing the PDF backend */
     pdf =
-	rl2_graph_create_pdf_context ("./test_paint.pdf", 300, 11.7, 8.3, 1.0,
-				      1.0);
+	rl2_graph_create_pdf_context ("./test_paint.pdf", 300, 11.7, 8.3, 0.5,
+				      0.5);
     if (pdf == NULL)
       {
 	  fprintf (stderr, "Unable to create a PDF backend\n");
@@ -496,7 +1260,7 @@ main (int argc, char *argv[])
 	  fprintf (stderr, "invalid RGB buffer from Graphics Context\n");
 	  return -4;
       }
-    alpha = rl2_graph_get_context_alpha_array (ctx);
+    alpha = rl2_graph_get_context_alpha_array (ctx, &half_transparent);
     if (alpha == NULL)
       {
 	  fprintf (stderr, "invalid Alpha buffer from Graphics Context\n");
diff --git a/test/test_palette.c b/test/test_palette.c
index 8e33459..f50f58f 100644
--- a/test/test_palette.c
+++ b/test/test_palette.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -171,8 +171,9 @@ test_sql_palette (unsigned char *blob, int blob_size, unsigned char *blob2,
     const char *sql;
     sqlite3_stmt *stmt;
     unsigned char *blob3 = NULL;
-    int blob_size3;
+    int blob_size3 = 0;
     void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
 
 /* opening and initializing the "memory" test DB */
     ret = sqlite3_open_v2 (":memory:", &db_handle,
@@ -184,7 +185,7 @@ test_sql_palette (unsigned char *blob, int blob_size, unsigned char *blob2,
 	  return 0;
       }
     spatialite_init_ex (db_handle, cache, 0);
-    rl2_init (db_handle, 0);
+    rl2_init (db_handle, priv_data, 0);
 
     sql = "SELECT RL2_GetPaletteNumEntries(?), RL2_GetPaletteNumEntries(?), "
 	"RL2_GetPaletteColorEntry(?, 0), RL2_GetPaletteColorEntry(?, 0), "
@@ -373,6 +374,8 @@ test_sql_palette (unsigned char *blob, int blob_size, unsigned char *blob2,
 
 /* closing the DB */
     sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
     spatialite_shutdown ();
     free (blob);
     free (blob2);
@@ -383,6 +386,10 @@ test_sql_palette (unsigned char *blob, int blob_size, unsigned char *blob2,
   error:
     sqlite3_finalize (stmt);
     sqlite3_close (db_handle);
+    if (cache != NULL)
+	spatialite_cleanup_ex (cache);
+    if (priv_data != NULL)
+	rl2_cleanup_private (priv_data);
     spatialite_shutdown ();
     free (blob);
     free (blob2);
@@ -759,6 +766,7 @@ main (int argc, char *argv[])
 	  fprintf (stderr, "ERROR: unable to clone a palette\n");
 	  return 51;
       }
+    rl2_destroy_palette (plt2);
     if (rl2_serialize_dbms_palette (NULL, &blob, &blob_size) == RL2_OK)
       {
 	  fprintf (stderr, "ERROR: unexpected NULL palette serialization\n");
diff --git a/test/test_point_symbolizer.c b/test/test_point_symbolizer.c
new file mode 100644
index 0000000..2e455b7
--- /dev/null
+++ b/test/test_point_symbolizer.c
@@ -0,0 +1,2137 @@
+/*
+
+ test_point_symbolizer.c -- RasterLite-2 Test Case
+
+ Author: Sandro Furieri <a.furieri at lqt.it>
+
+ ------------------------------------------------------------------------------
+ 
+ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ 
+ The contents of this file are subject to the Mozilla Public License Version
+ 1.1 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+ 
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the
+License.
+
+The Original Code is the RasterLite2 library
+
+The Initial Developer of the Original Code is Alessandro Furieri
+ 
+Portions created by the Initial Developer are Copyright (C) 2015
+the Initial Developer. All Rights Reserved.
+
+Contributor(s):
+
+Alternatively, the contents of this file may be used under the terms of
+either the GNU General Public License Version 2 or later (the "GPL"), or
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+in which case the provisions of the GPL or the LGPL are applicable instead
+of those above. If you wish to allow use of your version of this file only
+under the terms of either the GPL or the LGPL, and not to allow others to
+use your version of this file under the terms of the MPL, indicate your
+decision by deleting the provisions above and replace them with the notice
+and other provisions required by the GPL or the LGPL. If you do not delete
+the provisions above, a recipient may use your version of this file under
+the terms of any one of the MPL, the GPL or the LGPL.
+ 
+*/
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "sqlite3.h"
+#include "spatialite.h"
+
+#include "rasterlite2/rasterlite2.h"
+
+static int
+test_symbolizer (sqlite3 * db_handle, const char *coverage,
+		 const char *style_name, int *retcode)
+{
+/* testing a PointSymbolizer */
+    rl2FeatureTypeStylePtr style;
+    rl2VectorSymbolizerPtr symbolizer;
+    rl2PointSymbolizerPtr point;
+    int intval;
+    int index;
+    int ret;
+    double dblval;
+    double dblval2;
+    const char *string;
+    unsigned char red;
+    unsigned char green;
+    unsigned char blue;
+    int scale_forbidden;
+    style =
+	rl2_create_feature_type_style_from_dbms (db_handle, coverage,
+						 style_name);
+    if (style == NULL)
+      {
+	  fprintf (stderr, "Unable to retrieve style '%s'\n", style_name);
+	  *retcode += 1;
+	  return 0;
+      }
+
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 1.0, NULL,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s)\n",
+		   style_name);
+	  *retcode += 2;
+	  return 0;
+      }
+
+    if (rl2_is_valid_vector_symbolizer (symbolizer, &intval) != RL2_OK)
+      {
+	  fprintf (stderr, "%s: Unable to get Vector Symbolizer Validity #1\n",
+		   style_name);
+	  *retcode += 3;
+	  return 0;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr, "%s: Unexpected Vector Symbolizer Validity #1: %d\n",
+		   style_name, intval);
+	  *retcode += 4;
+	  return 0;
+      }
+
+    if (rl2_get_vector_symbolizer_count (symbolizer, &intval) != RL2_OK)
+      {
+	  fprintf (stderr, "%s: Unable to get Vector Symbolizer Count #1\n",
+		   style_name);
+	  *retcode += 5;
+	  return 0;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr, "%s: Unexpected Vector Symbolizer Count #1: %d\n",
+		   style_name, intval);
+	  *retcode += 6;
+	  return 0;
+      }
+
+    if (rl2_get_vector_symbolizer_item_type (symbolizer, 0, &intval) != RL2_OK)
+      {
+	  fprintf (stderr, "%s: Unable to get Vector Symbolizer Item Type #1\n",
+		   style_name);
+	  *retcode += 7;
+	  return 0;
+      }
+    if (intval != RL2_POINT_SYMBOLIZER)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Vector Symbolizer Item Type #1: %d\n",
+		   style_name, intval);
+	  *retcode += 8;
+	  return 0;
+      }
+
+    point = rl2_get_point_symbolizer (symbolizer, 0);
+    if (point == NULL)
+      {
+	  fprintf (stderr, "%s: Unable to get a Point Symbolizer #1\n",
+		   style_name);
+	  *retcode += 9;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_get_count (point, &intval) != RL2_OK)
+      {
+	  fprintf (stderr, "%s: Unable to get Point Symbolizer Count #1\n",
+		   style_name);
+	  *retcode += 10;
+	  return 0;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr, "%s: Unexpected Point Symbolizer Count #1: %d\n",
+		   style_name, intval);
+	  *retcode += 11;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_is_graphic (point, 0, &intval) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Point Symbolizer IsGraphic #1\n",
+		   style_name);
+	  *retcode += 12;
+	  return 0;
+      }
+    red = 0;
+    if (strcmp (style_name, "point_1") == 0
+	|| strcmp (style_name, "point_2") == 0)
+      {
+	  if (intval == 0)
+	      red = 1;
+      }
+    if (strcmp (style_name, "point_3") == 0)
+      {
+	  if (intval == 1)
+	      red = 1;
+      }
+    if (red != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer IsGraphic #1: %d\n",
+		   style_name, intval);
+	  *retcode += 13;
+	  return 0;
+      }
+
+    string = rl2_point_symbolizer_get_graphic_href (point, 0);
+    intval = 0;
+    if (strcmp (style_name, "point_1") == 0
+	|| strcmp (style_name, "point_2") == 0)
+      {
+	  if (string == NULL)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "point_3") == 0)
+      {
+	  if (string != NULL)
+	    {
+		if (strcmp (string, "http:/www.acme.com/sample.png") == 0)
+		    intval = 1;
+	    }
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s; Unexpected Point Symbolizer GetGraphicHref #1: %s\n",
+		   style_name, string);
+	  *retcode += 14;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_is_mark (point, 0, &intval) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Point Symbolizer IsMark #1\n",
+		   style_name);
+	  *retcode += 15;
+	  return 0;
+      }
+    red = 0;
+    if (strcmp (style_name, "point_1") == 0
+	|| strcmp (style_name, "point_2") == 0)
+      {
+	  if (intval == 1)
+	      red = 1;
+      }
+    if (strcmp (style_name, "point_3") == 0)
+      {
+	  if (intval == 0)
+	      red = 1;
+      }
+    if (red != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer IsMark #1: %d\n",
+		   style_name, intval);
+	  *retcode += 16;
+	  return 0;
+      }
+
+    ret = rl2_point_symbolizer_mark_has_stroke (point, 0, &intval);
+    if (strcmp (style_name, "point_3") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Point Symbolizer Mark HasStroke #1\n",
+			 style_name);
+		*retcode += 17;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Point Symbolizer Mark HasStroke #1\n",
+			 style_name);
+		*retcode += 18;
+		return 0;
+	    }
+      }
+    red = 0;
+    if (strcmp (style_name, "point_1") == 0)
+      {
+	  if (intval == 1)
+	      red = 1;
+      }
+    if (strcmp (style_name, "point_2") == 0
+	|| strcmp (style_name, "point_3") == 0)
+      {
+	  if (intval == 0)
+	      red = 1;
+      }
+    if (red != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer Mark HasStroke #1: %d\n",
+		   style_name, intval);
+	  *retcode += 19;
+	  return 0;
+      }
+
+    ret =
+	rl2_point_symbolizer_mark_get_stroke_color (point, 0, &red, &green,
+						    &blue);
+    if (strcmp (style_name, "point_2") == 0
+	|| strcmp (style_name, "point_3") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Point Symbolizer Mark GetStrokeColor #1\n",
+			 style_name);
+		*retcode += 20;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Point Symbolizer Mark GetStrokeColor #1\n",
+			 style_name);
+		*retcode += 21;
+		return 0;
+	    }
+      }
+    intval = 0;
+    if (strcmp (style_name, "point_1") == 0)
+      {
+	  if (red == 0xff && green == 0xff && blue == 0x80)
+	      intval = 1;
+      }
+    else
+	intval = 1;
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer Mark GetStrokeColor #1: #%02x%02x%02x\n",
+		   style_name, red, green, blue);
+	  *retcode += 22;
+	  return 0;
+      }
+
+    ret = rl2_point_symbolizer_mark_get_stroke_width (point, 0, &dblval);
+    if (strcmp (style_name, "point_2") == 0
+	|| strcmp (style_name, "point_3") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Point Symbolizer Mark GetStrokeWidth #1\n",
+			 style_name);
+		*retcode += 23;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Point Symbolizer Mark GetStrokeWidth #1\n",
+			 style_name);
+		*retcode += 24;
+		return 0;
+	    }
+      }
+    intval = 0;
+    if (strcmp (style_name, "point_1") == 0)
+      {
+	  if (dblval == 2.0)
+	      intval = 1;
+      }
+    else
+	intval = 1;
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer Mark GetStrokeWidth #1: %1.4f\n",
+		   style_name, dblval);
+	  *retcode += 25;
+	  return 0;
+      }
+
+    ret = rl2_point_symbolizer_mark_get_stroke_linejoin (point, 0, &red);
+    if (strcmp (style_name, "point_2") == 0
+	|| strcmp (style_name, "point_3") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Point Symbolizer Mark GetStrokeLinejoin #1\n",
+			 style_name);
+		*retcode += 26;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Point Symbolizer Mark GetStrokeLinejoin #1\n",
+			 style_name);
+		*retcode += 27;
+		return 0;
+	    }
+      }
+    intval = 0;
+    if (strcmp (style_name, "point_1") == 0)
+      {
+	  if (red == RL2_STROKE_LINEJOIN_UNKNOWN)
+	      intval = 1;
+      }
+    else
+	intval = 1;
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer Mark GetStrokeLinejoin #1: %02x\n",
+		   style_name, red);
+	  *retcode += 28;
+	  return 0;
+      }
+
+    ret = rl2_point_symbolizer_mark_get_stroke_linecap (point, 0, &red);
+    if (strcmp (style_name, "point_2") == 0
+	|| strcmp (style_name, "point_3") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Point Symbolizer Mark GetStrokeLinecap #1\n",
+			 style_name);
+		*retcode += 29;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Point Symbolizer Mark GetStrokeLinecap #1\n",
+			 style_name);
+		*retcode += 30;
+		return 0;
+	    }
+      }
+    intval = 0;
+    if (strcmp (style_name, "point_1") == 0)
+      {
+	  if (red == RL2_STROKE_LINECAP_UNKNOWN)
+	      intval = 1;
+      }
+    else
+	intval = 1;
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer Mark GetStrokeLinecap #1: %02x\n",
+		   style_name, red);
+	  *retcode += 31;
+	  return 0;
+      }
+
+    ret = rl2_point_symbolizer_mark_get_stroke_dash_count (point, 0, &intval);
+    if (strcmp (style_name, "point_2") == 0
+	|| strcmp (style_name, "point_3") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Point Symbolizer Mark GetStrokeDashCount #1\n",
+			 style_name);
+		*retcode += 32;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Point Symbolizer GetStrokeDashCount #1\n",
+			 style_name);
+		*retcode += 33;
+		return 0;
+	    }
+      }
+    red = 0;
+    if (strcmp (style_name, "point_1") == 0)
+      {
+	  if (intval == 2)
+	      red = 1;
+      }
+    else
+	red = 1;
+    if (red != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer Mark GetStrokeDashCount #1: %d\n",
+		   style_name, intval);
+	  *retcode += 34;
+	  return 0;
+      }
+
+
+    if (strcmp (style_name, "point_2") == 0
+	|| strcmp (style_name, "point_3") == 0)
+      {
+	  if (rl2_point_symbolizer_mark_get_stroke_dash_item
+	      (point, 0, 0, &dblval) == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "Expected failure, got success: Point Symbolizer Mark GetStrokeDashItem #1\n");
+		*retcode += 35;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (rl2_point_symbolizer_mark_get_stroke_dash_item
+	      (point, 0, 0, &dblval) != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Point Symbolizer Mark GetStrokeDashItem #1\n",
+			 style_name);
+		*retcode += 36;
+		return 0;
+	    }
+	  if (dblval != 20.0)
+	    {
+		fprintf (stderr,
+			 "Unexpected Point Symbolizer Mark GetStrokDashItem #1: %1.4f\n",
+			 dblval);
+		*retcode += 37;
+		return 0;
+	    }
+	  if (rl2_point_symbolizer_mark_get_stroke_dash_item
+	      (point, 0, 1, &dblval) != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "Unable to get Point Symbolizer Mark GetStrokeDashItem #2\n");
+		*retcode += 38;
+		return 0;
+	    }
+	  if (dblval != 10)
+	    {
+		fprintf (stderr,
+			 "Unexpected Point Symbolizer Mark GetStrokDashItem #2: %1.4f\n",
+			 dblval);
+		*retcode += 39;
+		return 0;
+	    }
+      }
+
+    ret = rl2_point_symbolizer_mark_get_stroke_dash_offset (point, 0, &dblval);
+    if (strcmp (style_name, "point_2") == 0
+	|| strcmp (style_name, "point_3") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Point Symbolizer Mark GetStrokeDashOffset #1\n",
+			 style_name);
+		*retcode += 40;
+		return 0;
+	    }
+	  dblval = 0.0;
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Point Symbolizer Mark GetStrokeDashOffset #1\n",
+			 style_name);
+		*retcode += 41;
+		return 0;
+	    }
+      }
+    intval = 0;
+    if (strcmp (style_name, "point_1") == 0)
+      {
+	  if (dblval == 0.0)
+	      intval = 1;
+      }
+    else
+	intval = 1;
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer Mark GetStrokeDashOffset #1: %1.4f\n",
+		   style_name, dblval);
+	  *retcode += 42;
+	  return 0;
+      }
+
+    ret = rl2_point_symbolizer_mark_has_fill (point, 0, &intval);
+    if (strcmp (style_name, "point_3") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Point Symbolizer Mark HasFill #1\n",
+			 style_name);
+		*retcode += 43;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Point Symbolizer Mark HasFill #1\n",
+			 style_name);
+		*retcode += 44;
+		return 0;
+	    }
+      }
+    red = 0;
+    if (strcmp (style_name, "point_1") == 0
+	|| strcmp (style_name, "point_2") == 0)
+      {
+	  if (intval == 1)
+	      red = 1;
+      }
+    else
+	red = 1;
+    if (red != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer Mark HasFill #1: %d\n",
+		   style_name, intval);
+	  *retcode += 45;
+	  return 0;
+      }
+
+    ret =
+	rl2_point_symbolizer_mark_get_fill_color (point, 0, &red, &green,
+						  &blue);
+    if (strcmp (style_name, "point_3") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Point Symbolizer Mark GetFillColor #1\n",
+			 style_name);
+		*retcode += 46;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Point Symbolizer Mark GetFillColor #1\n",
+			 style_name);
+		*retcode += 47;
+		return 0;
+	    }
+      }
+    intval = 0;
+    if (strcmp (style_name, "point_1") == 0)
+      {
+	  if (red == 0x78 && green == 0x90 && blue == 0xcd)
+	      intval = 1;
+      }
+    else if (strcmp (style_name, "point_2") == 0)
+      {
+	  if (red == 0x62 && green == 0x14 && blue == 0x93)
+	      intval = 1;
+      }
+    else
+	intval = 1;
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer Mark GetFillColor #1: #%02x%02x%02x\n",
+		   style_name, red, green, blue);
+	  *retcode += 48;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_get_opacity (point, &dblval) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Point Symbolizer GetOpacity #1\n",
+		   style_name);
+	  *retcode += 49;
+	  return 0;
+      }
+    intval = 0;
+    if (strcmp (style_name, "point_1") == 0)
+      {
+	  if (dblval == 1.0)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "point_2") == 0)
+      {
+	  if (dblval == 0.5)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "point_3") == 0)
+      {
+	  if (dblval == 0.25)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer GetOpacity #1: %1.4f\n",
+		   style_name, dblval);
+	  *retcode += 50;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_get_size (point, &dblval) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Point Symbolizer GetSize #1\n",
+		   style_name);
+	  *retcode += 51;
+	  return 0;
+      }
+    intval = 0;
+    if (strcmp (style_name, "point_1") == 0)
+      {
+	  if (dblval == 48.0)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "point_2") == 0)
+      {
+	  if (dblval == 36.0)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "point_3") == 0)
+      {
+	  if (dblval == 16.0)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer GetSize #1: %1.4f\n",
+		   style_name, dblval);
+	  *retcode += 52;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_get_rotation (point, &dblval) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Point Symbolizer GetRotation #1\n",
+		   style_name);
+	  *retcode += 53;
+	  return 0;
+      }
+    intval = 0;
+    if (strcmp (style_name, "point_1") == 0)
+      {
+	  if (dblval == 0.0)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "point_2") == 0)
+      {
+	  if (dblval == 45.0)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "point_3") == 0)
+      {
+	  if (dblval == 60.0)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer GetRotation #1: %1.4f\n",
+		   style_name, dblval);
+	  *retcode += 54;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_get_anchor_point (point, &dblval, &dblval2) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Point Symbolizer GetAnchorPoint #1\n",
+		   style_name);
+	  *retcode += 55;
+	  return 0;
+      }
+    intval = 0;
+    if (strcmp (style_name, "point_3") == 0)
+      {
+	  if (dblval == 3.0 && dblval2 == 2.0)
+	      intval = 1;
+      }
+    else
+      {
+	  if (dblval == 0.5 && dblval2 == 0.5)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer GetAnchorPoint #1: %1.4f %1.4f\n",
+		   style_name, dblval, dblval2);
+	  *retcode += 56;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_get_displacement (point, &dblval, &dblval2) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Point Symbolizer GetDisplacement #1\n",
+		   style_name);
+	  *retcode += 57;
+	  return 0;
+      }
+    intval = 0;
+    if (strcmp (style_name, "point_2") == 0)
+      {
+	  if (dblval == 2.0 && dblval2 == -6.0)
+	      intval = 1;
+      }
+    else if (strcmp (style_name, "point_3") == 0)
+      {
+	  if (dblval == -2.5 && dblval2 == 6.5)
+	      intval = 1;
+      }
+    else
+      {
+	  if (dblval == 0.0 && dblval2 == 0.0)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer GetDisplacement #1: %1.4f %1.4f\n",
+		   style_name, dblval, dblval2);
+	  *retcode += 58;
+	  return 0;
+      }
+
+    ret = rl2_point_symbolizer_get_graphic_recode_color (point, 0, 0, &index,
+							 &red, &green, &blue);
+    if (strcmp (style_name, "point_1") == 0
+	|| strcmp (style_name, "point_2") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Point Symbolizer GetGraphicRecodeColor #1\n",
+			 style_name);
+		*retcode += 59;
+		return 0;
+	    }
+	  intval = 1;
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Point Symbolizer GetGraphicRecodeColor #1\n",
+			 style_name);
+		*retcode += 60;
+		return 0;
+	    }
+	  intval = 0;
+	  if (index == 0 && red == 0x98 && green == 0x76 && blue == 0x54)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer GetGraphicRecodeColor #1: #%02x%02x%02x\n",
+		   style_name, red, green, blue);
+	  *retcode += 61;
+	  return 0;
+      }
+
+    rl2_destroy_feature_type_style (style);
+    return 1;
+}
+
+static int
+test_style (sqlite3 * db_handle, const char *coverage,
+	    const char *style_name, int *retcode)
+{
+/* testing a FeatureType Style (PointSymbolizers) */
+    rl2FeatureTypeStylePtr style;
+    rl2VectorSymbolizerPtr symbolizer;
+    rl2PointSymbolizerPtr point;
+    int intval;
+    double dblval;
+    double dblval2;
+    const char *string;
+    unsigned char red;
+    unsigned char green;
+    unsigned char blue;
+    int scale_forbidden;
+    style =
+	rl2_create_feature_type_style_from_dbms (db_handle, coverage,
+						 style_name);
+    if (style == NULL)
+      {
+	  fprintf (stderr, "Unable to retrieve style '%s'\n", style_name);
+	  *retcode += 1;
+	  return 0;
+      }
+
+    string = rl2_get_feature_type_style_name (style);
+    if (string == NULL)
+      {
+	  fprintf (stderr, "Unable to retrieve style name '%s'\n", style_name);
+	  *retcode += 2;
+	  return 0;
+      }
+    if (strcmp (string, "point_style") != 0)
+      {
+	  fprintf (stderr, "%s: Unexpected style name '%s'\n", style_name,
+		   string);
+	  *retcode += 3;
+	  return 0;
+      }
+
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 1.0, NULL,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s)\n",
+		   style_name);
+	  *retcode += 4;
+	  return 0;
+      }
+
+    if (rl2_get_vector_symbolizer_count (symbolizer, &intval) != RL2_OK)
+      {
+	  fprintf (stderr, "%s: Unable to get Vector Symbolizer Count #2\n",
+		   style_name);
+	  *retcode += 5;
+	  return 0;
+      }
+    if (intval != 2)
+      {
+	  fprintf (stderr, "%s: Unexpected Vector Symbolizer Count #2: %d\n",
+		   style_name, intval);
+	  *retcode += 6;
+	  return 0;
+      }
+
+    if (rl2_get_vector_symbolizer_item_type (symbolizer, 1, &intval) != RL2_OK)
+      {
+	  fprintf (stderr, "%s: Unable to get Vector Symbolizer Item Type #2\n",
+		   style_name);
+	  *retcode += 7;
+	  return 0;
+      }
+    if (intval != RL2_POINT_SYMBOLIZER)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Vector Symbolizer Item Type #2: %d\n",
+		   style_name, intval);
+	  *retcode += 8;
+	  return 0;
+      }
+
+    point = rl2_get_point_symbolizer (symbolizer, 1);
+    if (point == NULL)
+      {
+	  fprintf (stderr, "%s: Unable to get a Point Symbolizer #2\n",
+		   style_name);
+	  *retcode += 9;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_is_mark (point, 1, &intval) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Point Symbolizer IsMark #2\n",
+		   style_name);
+	  *retcode += 10;
+	  return 0;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer IsMark #2: %d\n",
+		   style_name, intval);
+	  *retcode += 11;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_mark_has_stroke (point, 1, &intval) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Point Symbolizer Mark HasStroke #21\n",
+		   style_name);
+	  *retcode += 12;
+	  return 0;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer Mark HasStroke #2: %d\n",
+		   style_name, intval);
+	  *retcode += 13;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_mark_get_stroke_color (point, 1, &red, &green,
+						    &blue) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Point Symbolizer Mark GetStrokeColor #2\n",
+		   style_name);
+	  *retcode += 14;
+	  return 0;
+      }
+    if (red != 0xff || green != 0xff || blue != 0x80)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer Mark GetStrokeColor #2: #%02x%02x%02x\n",
+		   style_name, red, green, blue);
+	  *retcode += 15;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_mark_get_stroke_width (point, 1, &dblval) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Point Symbolizer Mark GetStrokeWidth #2\n",
+		   style_name);
+	  *retcode += 16;
+	  return 0;
+      }
+    if (dblval != 1.0)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer Mark GetStrokeWidth #2: %1.4f\n",
+		   style_name, dblval);
+	  *retcode += 17;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_mark_get_stroke_linejoin (point, 1, &red) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Point Symbolizer Mark GetStrokeLinejoin #2\n",
+		   style_name);
+	  *retcode += 18;
+	  return 0;
+      }
+    if (red != RL2_STROKE_LINEJOIN_MITRE)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer Mark GetStrokeLinejoin #2: %02x\n",
+		   style_name, red);
+	  *retcode += 19;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_mark_get_stroke_linecap (point, 1, &red) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Point Symbolizer Mark GetStrokeLinecap #2\n",
+		   style_name);
+	  *retcode += 20;
+	  return 0;
+      }
+    if (red != RL2_STROKE_LINECAP_ROUND)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer Mark GetStrokeLinecap #2: %02x\n",
+		   style_name, red);
+	  *retcode += 21;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_mark_get_stroke_dash_count (point, 1, &intval) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Point Symbolizer GetStrokeDashCount #2\n",
+		   style_name);
+	  *retcode += 22;
+	  return 0;
+      }
+    if (intval != 2)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer Mark GetStrokeDashCount #2: %d\n",
+		   style_name, intval);
+	  *retcode += 23;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_mark_get_stroke_dash_item
+	(point, 1, 1, &dblval) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Point Symbolizer Mark GetStrokeDashItem #2\n",
+		   style_name);
+	  *retcode += 24;
+	  return 0;
+      }
+    if (dblval != 6.0)
+      {
+	  fprintf (stderr,
+		   "Unexpected Point Symbolizer Mark GetStrokDashItem #2: %1.4f\n",
+		   dblval);
+	  *retcode += 25;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_mark_get_stroke_dash_offset (point, 1, &dblval) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Point Symbolizer Mark GetStrokeDashOffset #2\n",
+		   style_name);
+	  *retcode += 26;
+	  return 0;
+      }
+    if (dblval != 2.5)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer Mark GetStrokeDashOffset #2: %1.4f\n",
+		   style_name, dblval);
+	  *retcode += 27;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_mark_has_fill (point, 1, &intval) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Point Symbolizer Mark HasFill #2\n",
+		   style_name);
+	  *retcode += 28;
+	  return 0;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer Mark HasFill #2: %d\n",
+		   style_name, intval);
+	  *retcode += 29;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_mark_get_fill_color (point, 1, &red, &green,
+						  &blue) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Point Symbolizer Mark GetFillColor #2\n",
+		   style_name);
+	  *retcode += 30;
+	  return 0;
+      }
+    if (red != 0x78 || green != 0x90 || blue != 0xcd)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Point Symbolizer Mark GetFillColor #2: #%02x%02x%02x\n",
+		   style_name, red, green, blue);
+	  *retcode += 31;
+	  return 0;
+      }
+
+    if (rl2_get_line_symbolizer (symbolizer, 1) != NULL)
+      {
+	  fprintf (stderr, "Unexpected success: Line Symbolizer #2\n");
+	  *retcode += 32;
+	  return 0;
+      }
+
+    if (rl2_get_polygon_symbolizer (symbolizer, 1) != NULL)
+      {
+	  fprintf (stderr, "Unexpected success: Polygon Symbolizer #2\n");
+	  *retcode += 33;
+	  return 0;
+      }
+
+    if (rl2_get_text_symbolizer (symbolizer, 1) != NULL)
+      {
+	  fprintf (stderr, "Unexpected success: Text Symbolizer #2\n");
+	  *retcode += 34;
+	  return 0;
+      }
+
+    if (rl2_get_point_symbolizer (symbolizer, 10) != NULL)
+      {
+	  fprintf (stderr, "Unexpected success: Point Symbolizer #2\n");
+	  *retcode += 35;
+	  return 0;
+      }
+
+    if (rl2_get_line_symbolizer (symbolizer, 10) != NULL)
+      {
+	  fprintf (stderr, "Unexpected success: Line Symbolizer #3\n");
+	  *retcode += 36;
+	  return 0;
+      }
+
+    if (rl2_get_polygon_symbolizer (symbolizer, 10) != NULL)
+      {
+	  fprintf (stderr, "Unexpected success: Polygon Symbolizer #3\n");
+	  *retcode += 37;
+	  return 0;
+      }
+
+    if (rl2_get_text_symbolizer (symbolizer, 10) != NULL)
+      {
+	  fprintf (stderr, "Unexpected success: Text Symbolizer #3\n");
+	  *retcode += 38;
+	  return 0;
+      }
+
+    if (rl2_get_point_symbolizer (NULL, 0) != NULL)
+      {
+	  fprintf (stderr, "Unexpected success: Point Symbolizer #3\n");
+	  *retcode += 39;
+	  return 0;
+      }
+
+    if (rl2_get_line_symbolizer (NULL, 0) != NULL)
+      {
+	  fprintf (stderr, "Unexpected success: Line Symbolizer #4\n");
+	  *retcode += 40;
+	  return 0;
+      }
+
+    if (rl2_get_polygon_symbolizer (NULL, 0) != NULL)
+      {
+	  fprintf (stderr, "Unexpected success: Polygon Symbolizer #4\n");
+	  *retcode += 41;
+	  return 0;
+      }
+
+    if (rl2_get_text_symbolizer (NULL, 0) != NULL)
+      {
+	  fprintf (stderr, "Unexpected success: Text Symbolizer #4\n");
+	  *retcode += 42;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_get_count (NULL, &intval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Point Symbolizer GetCount #2\n");
+	  *retcode += 43;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_is_graphic (point, 10, &intval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Point Symbolizer IsGraphic #2\n");
+	  *retcode += 44;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_is_graphic (NULL, 0, &intval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Point Symbolizer IsGraphic #3\n");
+	  *retcode += 45;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_get_graphic_href (NULL, 0) != NULL)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Point Symbolizer GetGraphicHref #2\n");
+	  *retcode += 46;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_get_graphic_recode_color
+	(NULL, 0, 0, &intval, &red, &green, &blue) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Point Symbolizer GetGraphicRecodeColor #2\n");
+	  *retcode += 47;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_is_mark (point, 10, &intval) == RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected success: Point Symbolizer IsMark #2\n");
+	  *retcode += 48;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_is_mark (NULL, 0, &intval) == RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected success: Point Symbolizer IsMark #3\n");
+	  *retcode += 49;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_mark_has_stroke (NULL, 0, &intval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Point Symbolizer MarkHasStroke #2\n");
+	  *retcode += 40;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_mark_get_stroke_color
+	(NULL, 0, &red, &green, &blue) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Point Symbolizer MarkGetStrokeColor #2\n");
+	  *retcode += 41;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_mark_get_stroke_width (NULL, 0, &dblval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Point Symbolizer MarkGetStrokeWidth #2\n");
+	  *retcode += 42;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_mark_get_stroke_linejoin (NULL, 0, &red) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Point Symbolizer MarkGetStrokeLinejoin #2\n");
+	  *retcode += 43;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_mark_get_stroke_linecap (NULL, 0, &red) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Point Symbolizer MarkGetStrokeLinecap #2\n");
+	  *retcode += 44;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_mark_get_stroke_dash_count (NULL, 0, &intval) ==
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Point Symbolizer MarkGetStrokeDashCount #2\n");
+	  *retcode += 45;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_mark_get_stroke_dash_item (NULL, 0, 0, &dblval) ==
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Point Symbolizer MarkGetStrokeDashItem #2\n");
+	  *retcode += 46;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_mark_get_stroke_dash_offset (NULL, 0, &dblval) ==
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Point Symbolizer MarkGetStrokeDashOffset #2\n");
+	  *retcode += 47;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_mark_has_fill (NULL, 0, &intval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Point Symbolizer MarkHasFill #2\n");
+	  *retcode += 48;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_mark_get_fill_color (NULL, 0, &red, &green, &blue)
+	== RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Point Symbolizer MarkGetFillColor #2\n");
+	  *retcode += 49;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_get_opacity (NULL, &dblval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Point Symbolizer GetOpacity #2\n");
+	  *retcode += 50;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_get_size (NULL, &dblval) == RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected success: Point Symbolizer GetSize #2\n");
+	  *retcode += 51;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_get_rotation (NULL, &dblval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Point Symbolizer GetRotation #2\n");
+	  *retcode += 52;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_get_anchor_point (NULL, &dblval, &dblval2) ==
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Point Symbolizer GetAnchorPoint #2\n");
+	  *retcode += 53;
+	  return 0;
+      }
+
+    if (rl2_point_symbolizer_get_displacement (NULL, &dblval, &dblval2) ==
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Point Symbolizer GetDisplacement #2\n");
+	  *retcode += 54;
+	  return 0;
+      }
+
+    if (rl2_get_feature_type_style_name (NULL) != NULL)
+      {
+	  fprintf (stderr, "Unexpected success: GetFeatureTypeStyleName #2\n");
+	  *retcode += 55;
+	  return 0;
+      }
+
+    rl2_destroy_feature_type_style (style);
+    return 1;
+}
+
+static int
+test_filter (sqlite3 * db_handle, const char *coverage,
+	     const char *style_name, int *retcode)
+{
+/* testing Filter from a FeatureType Style (PointSymbolizers) */
+    rl2FeatureTypeStylePtr style;
+    rl2VectorSymbolizerPtr symbolizer;
+    rl2PointSymbolizerPtr point;
+    rl2VariantArrayPtr value;
+    int intval;
+    int scale_forbidden;
+    const char *string;
+    unsigned char type;
+    unsigned char blob[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
+    style =
+	rl2_create_feature_type_style_from_dbms (db_handle, coverage,
+						 style_name);
+    if (style == NULL)
+      {
+	  fprintf (stderr, "Unable to retrieve style '%s'\n", style_name);
+	  *retcode += 1;
+	  return 0;
+      }
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #1\n");
+	  *retcode += 2;
+	  return 0;
+      }
+    if (rl2_set_variant_int (value, 0, "some_column", 4) != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #1\n");
+	  *retcode += 3;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #3\n",
+		   style_name);
+	  *retcode += 4;
+	  return 0;
+      }
+    point = rl2_get_point_symbolizer (symbolizer, 0);
+    if (point == NULL)
+      {
+	  fprintf (stderr, "Unable to get Point Symbolizer #2\n");
+	  *retcode += 5;
+	  return 0;
+      }
+    if (rl2_point_symbolizer_mark_get_well_known_type (point, 0, &type) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unable to get Point Symbolizer Mark GetWellKnownType #1\n");
+	  *retcode += 6;
+	  return 0;
+      }
+    if (type != RL2_GRAPHIC_MARK_TRIANGLE)
+      {
+	  fprintf (stderr,
+		   "Unexpected Point Symbolizer Mark GetWellKnownType #1: %02x\n",
+		   type);
+	  *retcode += 7;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #2\n");
+	  *retcode += 8;
+	  return 0;
+      }
+    if (rl2_set_variant_double (value, 0, "some_column", 14.6) != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #2\n");
+	  *retcode += 9;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #4\n",
+		   style_name);
+	  *retcode += 10;
+	  return 0;
+      }
+    point = rl2_get_point_symbolizer (symbolizer, 0);
+    if (point == NULL)
+      {
+	  fprintf (stderr, "Unable to get Point Symbolizer #3\n");
+	  *retcode += 11;
+	  return 0;
+      }
+    if (rl2_point_symbolizer_mark_get_well_known_type (point, 0, &type) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unable to get Point Symbolizer Mark GetWellKnownType #2\n");
+	  *retcode += 12;
+	  return 0;
+      }
+    if (type != RL2_GRAPHIC_MARK_TRIANGLE)
+      {
+	  fprintf (stderr,
+		   "Unexpected Point Symbolizer Mark GetWellKnownType #2: %02x\n",
+		   type);
+	  *retcode += 13;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #3\n");
+	  *retcode += 14;
+	  return 0;
+      }
+    if (rl2_set_variant_null (value, 0, "some_column") != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #3\n");
+	  *retcode += 15;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #5\n",
+		   style_name);
+	  *retcode += 16;
+	  return 0;
+      }
+    point = rl2_get_point_symbolizer (symbolizer, 0);
+    if (point == NULL)
+      {
+	  fprintf (stderr, "Unable to get Point Symbolizer #4\n");
+	  *retcode += 17;
+	  return 0;
+      }
+    if (rl2_point_symbolizer_mark_get_well_known_type (point, 0, &type) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unable to get Point Symbolizer Mark GetWellKnownType #3\n");
+	  *retcode += 18;
+	  return 0;
+      }
+    if (type != RL2_GRAPHIC_MARK_SQUARE)
+      {
+	  fprintf (stderr,
+		   "Unexpected Point Symbolizer Mark GetWellKnownType #3: %02x\n",
+		   type);
+	  *retcode += 19;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #4\n");
+	  *retcode += 20;
+	  return 0;
+      }
+    if (rl2_set_variant_blob (value, 0, "some_column", blob, 8) != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #4\n");
+	  *retcode += 21;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #6\n",
+		   style_name);
+	  *retcode += 22;
+	  return 0;
+      }
+    point = rl2_get_point_symbolizer (symbolizer, 0);
+    if (point == NULL)
+      {
+	  fprintf (stderr, "Unable to get Point Symbolizer #5\n");
+	  *retcode += 23;
+	  return 0;
+      }
+    if (rl2_point_symbolizer_mark_get_well_known_type (point, 0, &type) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unable to get Point Symbolizer Mark GetWellKnownType #4\n");
+	  *retcode += 24;
+	  return 0;
+      }
+    if (type != RL2_GRAPHIC_MARK_X)
+      {
+	  fprintf (stderr,
+		   "Unexpected Point Symbolizer Mark GetWellKnownType #4: %02x\n",
+		   type);
+	  *retcode += 25;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #5\n");
+	  *retcode += 26;
+	  return 0;
+      }
+    if (rl2_set_variant_int (value, 0, "some_column", 5) != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #5\n");
+	  *retcode += 27;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #7\n",
+		   style_name);
+	  *retcode += 28;
+	  return 0;
+      }
+    point = rl2_get_point_symbolizer (symbolizer, 0);
+    if (point == NULL)
+      {
+	  fprintf (stderr, "Unable to get Point Symbolizer #6\n");
+	  *retcode += 29;
+	  return 0;
+      }
+    if (rl2_point_symbolizer_mark_get_well_known_type (point, 0, &type) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unable to get Point Symbolizer Mark GetWellKnownType #5\n");
+	  *retcode += 30;
+	  return 0;
+      }
+    if (type != RL2_GRAPHIC_MARK_TRIANGLE)
+      {
+	  fprintf (stderr,
+		   "Unexpected Point Symbolizer Mark GetWellKnownType #5: %02x\n",
+		   type);
+	  *retcode += 31;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #6\n");
+	  *retcode += 32;
+	  return 0;
+      }
+    if (rl2_set_variant_int (value, 0, "some_column", 54321) != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #6\n");
+	  *retcode += 33;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #8\n",
+		   style_name);
+	  *retcode += 34;
+	  return 0;
+      }
+    point = rl2_get_point_symbolizer (symbolizer, 0);
+    if (point == NULL)
+      {
+	  fprintf (stderr, "Unable to get Point Symbolizer #7\n");
+	  *retcode += 35;
+	  return 0;
+      }
+    if (rl2_point_symbolizer_mark_get_well_known_type (point, 0, &type) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unable to get Point Symbolizer Mark GetWellKnownType #6\n");
+	  *retcode += 36;
+	  return 0;
+      }
+    if (type != RL2_GRAPHIC_MARK_CIRCLE)
+      {
+	  fprintf (stderr,
+		   "Unexpected Point Symbolizer Mark GetWellKnownType #6: %02x\n",
+		   type);
+	  *retcode += 37;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #7\n");
+	  *retcode += 38;
+	  return 0;
+      }
+    if (rl2_set_variant_double (value, 0, "some_column", 54321.0) != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #7\n");
+	  *retcode += 39;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #9\n",
+		   style_name);
+	  *retcode += 40;
+	  return 0;
+      }
+    point = rl2_get_point_symbolizer (symbolizer, 0);
+    if (point == NULL)
+      {
+	  fprintf (stderr, "Unable to get Point Symbolizer #8\n");
+	  *retcode += 41;
+	  return 0;
+      }
+    if (rl2_point_symbolizer_mark_get_well_known_type (point, 0, &type) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unable to get Point Symbolizer Mark GetWellKnownType #7\n");
+	  *retcode += 42;
+	  return 0;
+      }
+    if (type != RL2_GRAPHIC_MARK_CIRCLE)
+      {
+	  fprintf (stderr,
+		   "Unexpected Point Symbolizer Mark GetWellKnownType #7: %02x\n",
+		   type);
+	  *retcode += 43;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #8\n");
+	  *retcode += 44;
+	  return 0;
+      }
+    if (rl2_set_variant_int (value, 0, "some_column", 14) != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #8\n");
+	  *retcode += 45;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #10\n",
+		   style_name);
+	  *retcode += 46;
+	  return 0;
+      }
+    point = rl2_get_point_symbolizer (symbolizer, 0);
+    if (point == NULL)
+      {
+	  fprintf (stderr, "Unable to get Point Symbolizer #9\n");
+	  *retcode += 47;
+	  return 0;
+      }
+    if (rl2_point_symbolizer_mark_get_well_known_type (point, 0, &type) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unable to get Point Symbolizer Mark GetWellKnownType #8\n");
+	  *retcode += 48;
+	  return 0;
+      }
+    if (type != RL2_GRAPHIC_MARK_TRIANGLE)
+      {
+	  fprintf (stderr,
+		   "Unexpected Point Symbolizer Mark GetWellKnownType #8: %02x\n",
+		   type);
+	  *retcode += 49;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #9\n");
+	  *retcode += 50;
+	  return 0;
+      }
+    if (rl2_set_variant_int (value, 0, "some_column", 500) != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #9\n");
+	  *retcode += 51;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #11\n",
+		   style_name);
+	  *retcode += 52;
+	  return 0;
+      }
+    point = rl2_get_point_symbolizer (symbolizer, 0);
+    if (point == NULL)
+      {
+	  fprintf (stderr, "Unable to get Point Symbolizer #10\n");
+	  *retcode += 53;
+	  return 0;
+      }
+    if (rl2_point_symbolizer_mark_get_well_known_type (point, 0, &type) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unable to get Point Symbolizer Mark GetWellKnownType #9\n");
+	  *retcode += 54;
+	  return 0;
+      }
+    if (type != RL2_GRAPHIC_MARK_TRIANGLE)
+      {
+	  fprintf (stderr,
+		   "Unexpected Point Symbolizer Mark GetWellKnownType #9: %02x\n",
+		   type);
+	  *retcode += 55;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #10\n");
+	  *retcode += 56;
+	  return 0;
+      }
+    if (rl2_set_variant_double (value, 0, "some_column", 500.1) != RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #10\n");
+	  *retcode += 57;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #12\n",
+		   style_name);
+	  *retcode += 58;
+	  return 0;
+      }
+    point = rl2_get_point_symbolizer (symbolizer, 0);
+    if (point == NULL)
+      {
+	  fprintf (stderr, "Unable to get Point Symbolizer #11\n");
+	  *retcode += 59;
+	  return 0;
+      }
+    if (rl2_point_symbolizer_mark_get_well_known_type (point, 0, &type) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unable to get Point Symbolizer Mark GetWellKnownType #10\n");
+	  *retcode += 60;
+	  return 0;
+      }
+    if (type != RL2_GRAPHIC_MARK_TRIANGLE)
+      {
+	  fprintf (stderr,
+		   "Unexpected Point Symbolizer Mark GetWellKnownType #10: %02x\n",
+		   type);
+	  *retcode += 61;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #11\n");
+	  *retcode += 62;
+	  return 0;
+      }
+    string = "TOSCANA";
+    if (rl2_set_variant_text (value, 0, "name", string, strlen (string)) !=
+	RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #11\n");
+	  *retcode += 63;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #13\n",
+		   style_name);
+	  *retcode += 64;
+	  return 0;
+      }
+    point = rl2_get_point_symbolizer (symbolizer, 0);
+    if (point == NULL)
+      {
+	  fprintf (stderr, "Unable to get Point Symbolizer #12\n");
+	  *retcode += 65;
+	  return 0;
+      }
+    if (rl2_point_symbolizer_mark_get_well_known_type (point, 0, &type) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unable to get Point Symbolizer Mark GetWellKnownType #11\n");
+	  *retcode += 66;
+	  return 0;
+      }
+    if (type != RL2_GRAPHIC_MARK_CIRCLE)
+      {
+	  fprintf (stderr,
+		   "Unexpected Point Symbolizer Mark GetWellKnownType #11: %02x\n",
+		   type);
+	  *retcode += 67;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #12\n");
+	  *retcode += 68;
+	  return 0;
+      }
+    string = "Lazio";
+    if (rl2_set_variant_text (value, 0, "name", string, strlen (string)) !=
+	RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #12\n");
+	  *retcode += 69;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #14\n",
+		   style_name);
+	  *retcode += 70;
+	  return 0;
+      }
+    point = rl2_get_point_symbolizer (symbolizer, 0);
+    if (point == NULL)
+      {
+	  fprintf (stderr, "Unable to get Point Symbolizer #13\n");
+	  *retcode += 71;
+	  return 0;
+      }
+    if (rl2_point_symbolizer_mark_get_well_known_type (point, 0, &type) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unable to get Point Symbolizer Mark GetWellKnownType #12\n");
+	  *retcode += 72;
+	  return 0;
+      }
+    if (type != RL2_GRAPHIC_MARK_X)
+      {
+	  fprintf (stderr,
+		   "Unexpected Point Symbolizer Mark GetWellKnownType #12: %02x\n",
+		   type);
+	  *retcode += 73;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    intval = rl2_get_feature_type_style_columns_count (style);
+    if (intval != 2)
+      {
+	  fprintf (stderr,
+		   "Unexpected GetFeatureTypeStyleColumnsCount #1: %d\n",
+		   intval);
+	  *retcode += 74;
+	  return 0;
+      }
+
+    string = rl2_get_feature_type_style_column_name (style, 0);
+    if (strcasecmp (string, "name") != 0)
+      {
+	  fprintf (stderr,
+		   "Unexpected GetFeatureTypeStyleColumnName #1: \"%s\"\n",
+		   string);
+	  *retcode += 75;
+	  return 0;
+      }
+
+    string = rl2_get_feature_type_style_column_name (style, 1);
+    if (strcasecmp (string, "some_column") != 0)
+      {
+	  fprintf (stderr,
+		   "Unexpected GetFeatureTypeStyleColumnName #2: \"%s\"\n",
+		   string);
+	  *retcode += 76;
+	  return 0;
+      }
+
+    string = rl2_get_feature_type_style_column_name (style, 2);
+    if (string != NULL)
+      {
+	  fprintf (stderr,
+		   "Unexpected GetFeatureTypeStyleColumnName #3: \"%s\"\n",
+		   string);
+	  *retcode += 77;
+	  return 0;
+      }
+
+    string = rl2_get_feature_type_style_column_name (NULL, 0);
+    if (string != NULL)
+      {
+	  fprintf (stderr,
+		   "Unexpected GetFeatureTypeStyleColumnName #4: \"%s\"\n",
+		   string);
+	  *retcode += 78;
+	  return 0;
+      }
+
+    rl2_destroy_feature_type_style (style);
+    return 1;
+}
+
+int
+main (int argc, char *argv[])
+{
+    int result = 0;
+    int ret;
+    sqlite3 *db_handle;
+    void *cache = spatialite_alloc_connection ();
+
+    if (argc > 1 || argv[0] == NULL)
+	argc = 1;		/* silencing stupid compiler warnings */
+
+/* opening and initializing the "memory" test DB */
+    ret = sqlite3_open_v2 ("symbolizers.sqlite", &db_handle,
+			   SQLITE_OPEN_READONLY, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "sqlite3_open_v2() error: %s\n",
+		   sqlite3_errmsg (db_handle));
+	  return -1;
+      }
+    spatialite_init_ex (db_handle, cache, 0);
+
+/* tests */
+    ret = -100;
+    if (!test_symbolizer (db_handle, "point1", "point_1", &ret))
+	return ret;
+    ret = -200;
+    if (!test_symbolizer (db_handle, "point2", "point_2", &ret))
+	return ret;
+    ret = -300;
+    if (!test_symbolizer (db_handle, "point2", "point_3", &ret))
+	return ret;
+    ret = -400;
+    if (!test_style (db_handle, "point1", "point_style", &ret))
+	return ret;
+    ret = -500;
+    if (!test_filter (db_handle, "point1", "point_style", &ret))
+	return ret;
+
+/* closing the DB */
+    sqlite3_close (db_handle);
+    spatialite_shutdown ();
+    return result;
+}
diff --git a/test/test_polygon_symbolizer.c b/test/test_polygon_symbolizer.c
new file mode 100644
index 0000000..3776814
--- /dev/null
+++ b/test/test_polygon_symbolizer.c
@@ -0,0 +1,1765 @@
+/*
+
+ test_polygon_symbolizer.c -- RasterLite-2 Test Case
+
+ Author: Sandro Furieri <a.furieri at lqt.it>
+
+ ------------------------------------------------------------------------------
+ 
+ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ 
+ The contents of this file are subject to the Mozilla Public License Version
+ 1.1 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+ 
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the
+License.
+
+The Original Code is the RasterLite2 library
+
+The Initial Developer of the Original Code is Alessandro Furieri
+ 
+Portions created by the Initial Developer are Copyright (C) 2015
+the Initial Developer. All Rights Reserved.
+
+Contributor(s):
+
+Alternatively, the contents of this file may be used under the terms of
+either the GNU General Public License Version 2 or later (the "GPL"), or
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+in which case the provisions of the GPL or the LGPL are applicable instead
+of those above. If you wish to allow use of your version of this file only
+under the terms of either the GPL or the LGPL, and not to allow others to
+use your version of this file under the terms of the MPL, indicate your
+decision by deleting the provisions above and replace them with the notice
+and other provisions required by the GPL or the LGPL. If you do not delete
+the provisions above, a recipient may use your version of this file under
+the terms of any one of the MPL, the GPL or the LGPL.
+ 
+*/
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "sqlite3.h"
+#include "spatialite.h"
+
+#include "rasterlite2/rasterlite2.h"
+
+static int
+test_symbolizer (sqlite3 * db_handle, const char *coverage,
+		 const char *style_name, int *retcode)
+{
+/* testing a PolygonSymbolizer */
+    rl2FeatureTypeStylePtr style;
+    rl2VectorSymbolizerPtr symbolizer;
+    rl2PolygonSymbolizerPtr polyg;
+    int intval;
+    int index;
+    int ret;
+    double dblval;
+    double dblval2;
+    const char *string;
+    unsigned char red;
+    unsigned char green;
+    unsigned char blue;
+    int scale_forbidden;
+    style =
+	rl2_create_feature_type_style_from_dbms (db_handle, coverage,
+						 style_name);
+    if (style == NULL)
+      {
+	  fprintf (stderr, "Unable to retrieve style '%s'\n", style_name);
+	  *retcode += 1;
+	  return 0;
+      }
+
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 1.0, NULL,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s)\n",
+		   style_name);
+	  *retcode += 2;
+	  return 0;
+      }
+
+    if (rl2_is_valid_vector_symbolizer (symbolizer, &intval) != RL2_OK)
+      {
+	  fprintf (stderr, "%s: Unable to get Vector Symbolizer Validity #1\n",
+		   style_name);
+	  *retcode += 3;
+	  return 0;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr, "%s: Unexpected Vector Symbolizer Validity #1: %d\n",
+		   style_name, intval);
+	  *retcode += 4;
+	  return 0;
+      }
+
+    if (rl2_get_vector_symbolizer_count (symbolizer, &intval) != RL2_OK)
+      {
+	  fprintf (stderr, "%s: Unable to get Vector Symbolizer Count #1\n",
+		   style_name);
+	  *retcode += 5;
+	  return 0;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr, "%s: Unexpected Vector Symbolizer Count #1: %d\n",
+		   style_name, intval);
+	  *retcode += 6;
+	  return 0;
+      }
+
+    if (rl2_get_vector_symbolizer_item_type (symbolizer, 0, &intval) != RL2_OK)
+      {
+	  fprintf (stderr, "%s: Unable to get Vector Symbolizer Item Type #1\n",
+		   style_name);
+	  *retcode += 7;
+	  return 0;
+      }
+    if (intval != RL2_POLYGON_SYMBOLIZER)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Vector Symbolizer Item Type #1: %d\n",
+		   style_name, intval);
+	  *retcode += 8;
+	  return 0;
+      }
+
+    polyg = rl2_get_polygon_symbolizer (symbolizer, 0);
+    if (polyg == NULL)
+      {
+	  fprintf (stderr, "%s: Unable to get a Polygon Symbolizer #1\n",
+		   style_name);
+	  *retcode += 9;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_has_stroke (polyg, &intval) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Polygon Symbolizer HasStroke #1\n",
+		   style_name);
+	  *retcode += 10;
+	  return 0;
+      }
+    red = 0;
+    if (strcmp (style_name, "polygon_1") == 0)
+      {
+	  if (intval == 0)
+	      red = 1;
+      }
+    if (strcmp (style_name, "polygon_2") == 0
+	|| strcmp (style_name, "polygon_3") == 0)
+      {
+	  if (intval == 1)
+	      red = 1;
+      }
+    if (red != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Polygon Symbolizer HasStroke #1: %d\n",
+		   style_name, intval);
+	  *retcode += 11;
+	  return 0;
+      }
+
+    ret = rl2_polygon_symbolizer_get_stroke_color (polyg, &red, &green, &blue);
+    if (strcmp (style_name, "polygon_1") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Polygon Symbolizer GetStrokeColor #1\n",
+			 style_name);
+		*retcode += 12;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Polygon Symbolizer GetStrokeColor #1\n",
+			 style_name);
+		*retcode += 13;
+		return 0;
+	    }
+      }
+    intval = 0;
+    if (strcmp (style_name, "polygon_1") == 0)
+	intval = 1;
+    if (strcmp (style_name, "polygon_2") == 0)
+      {
+	  if (red == 0x00 && green == 0x00 && blue == 0x00)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "polygon_3") == 0)
+	intval = 1;
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Polygon Symbolizer GetStrokeColor #1: #%02x%02x%02x\n",
+		   style_name, red, green, blue);
+	  *retcode += 14;
+	  return 0;
+      }
+
+    ret = rl2_polygon_symbolizer_get_stroke_opacity (polyg, &dblval);
+    if (strcmp (style_name, "polygon_1") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Polygon Symbolizer GetStrokeOpacity #1\n",
+			 style_name);
+		*retcode += 15;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Polygon Symbolizer GetStrokeOpacity #1\n",
+			 style_name);
+		*retcode += 16;
+		return 0;
+	    }
+      }
+    intval = 0;
+    if (strcmp (style_name, "polygon_1") == 0)
+	intval = 1;
+    if (strcmp (style_name, "polygon_2") == 0)
+      {
+	  if (dblval == 1.0)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "polygon_3") == 0)
+      {
+	  if (dblval == 0.75)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Polygon Symbolizer GetStrokeOpacity #1: %1.4f\n",
+		   style_name, dblval);
+	  *retcode += 17;
+	  return 0;
+      }
+
+    ret = rl2_polygon_symbolizer_get_stroke_width (polyg, &dblval);
+    if (strcmp (style_name, "polygon_1") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Polygon Symbolizer GetStrokeWidth #1\n",
+			 style_name);
+		*retcode += 15;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Polygon Symbolizer GetStrokeWidth #1\n",
+			 style_name);
+		*retcode += 16;
+		return 0;
+	    }
+      }
+    intval = 0;
+    if (strcmp (style_name, "polygon_1") == 0)
+	intval = 1;
+    if (strcmp (style_name, "polygon_2") == 0)
+      {
+	  if (dblval == 2.0)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "polygon_3") == 0)
+      {
+	  if (dblval == 2.25)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Polygon Symbolizer GetStrokeWidth #1: %1.4f\n",
+		   style_name, dblval);
+	  *retcode += 17;
+	  return 0;
+      }
+
+    ret = rl2_polygon_symbolizer_get_stroke_linejoin (polyg, &red);
+    if (strcmp (style_name, "polygon_1") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Polygon Symbolizer GetStrokeLinejoin #1\n",
+			 style_name);
+		*retcode += 16;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Polygon Symbolizer GetStrokeLinejoin #1\n",
+			 style_name);
+		*retcode += 17;
+		return 0;
+	    }
+      }
+    intval = 0;
+    if (strcmp (style_name, "polygon_1") == 0)
+	intval = 1;
+    if (strcmp (style_name, "polygon_2") == 0)
+      {
+	  if (red == RL2_STROKE_LINEJOIN_UNKNOWN)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "polygon_3") == 0)
+      {
+	  if (red == RL2_STROKE_LINEJOIN_BEVEL)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Polygon Symbolizer GetStrokeLinejoin #1: %02x\n",
+		   style_name, red);
+	  *retcode += 18;
+	  return 0;
+      }
+
+    ret = rl2_polygon_symbolizer_get_stroke_linecap (polyg, &red);
+    if (strcmp (style_name, "polygon_1") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Polygon Symbolizer GetStrokeLinecap #1\n",
+			 style_name);
+		*retcode += 19;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Polygon Symbolizer GetStrokeLinecap #1\n",
+			 style_name);
+		*retcode += 20;
+		return 0;
+	    }
+      }
+    intval = 0;
+    if (strcmp (style_name, "polygon_1") == 0)
+	intval = 1;
+    if (strcmp (style_name, "polygon_2") == 0)
+      {
+	  if (red == RL2_STROKE_LINECAP_UNKNOWN)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "polygon_3") == 0)
+      {
+	  if (red == RL2_STROKE_LINECAP_BUTT)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Polygon Symbolizer GetStrokeLinecap #1: %02x\n",
+		   style_name, red);
+	  *retcode += 21;
+	  return 0;
+      }
+
+    ret = rl2_polygon_symbolizer_get_stroke_dash_count (polyg, &intval);
+    if (strcmp (style_name, "polygon_1") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Polygon Symbolizer GetStrokeDashCount #1\n",
+			 style_name);
+		*retcode += 22;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Polygon Symbolizer GetStrokeDashCount #1\n",
+			 style_name);
+		*retcode += 23;
+		return 0;
+	    }
+      }
+    red = 0;
+    if (strcmp (style_name, "polygon_1") == 0)
+	red = 1;
+    if (strcmp (style_name, "polygon_2") == 0)
+      {
+	  if (intval == 6)
+	      red = 1;
+      }
+    if (strcmp (style_name, "polygon_3") == 0)
+      {
+	  if (intval == 0)
+	      red = 1;
+      }
+    if (red != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Polygon Symbolizer GetStrokeDashCount #1: %d\n",
+		   style_name, intval);
+	  *retcode += 24;
+	  return 0;
+      }
+
+    if (strcmp (style_name, "polygon_1") == 0
+	|| strcmp (style_name, "polygon_3") == 0)
+      {
+	  if (rl2_polygon_symbolizer_get_stroke_dash_item (polyg, 0, &dblval) ==
+	      RL2_OK)
+	    {
+		fprintf (stderr,
+			 "Expected failure, got success: Polygon Symbolizer GetStrokeDashItem #1\n");
+		*retcode += 25;
+		return 0;
+	    }
+      }
+    if (strcmp (style_name, "polygon_2") == 0)
+      {
+	  if (rl2_polygon_symbolizer_get_stroke_dash_item (polyg, 0, &dblval) !=
+	      RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Polygon Symbolizer GetStrokeDashItem #1\n",
+			 style_name);
+		*retcode += 26;
+		return 0;
+	    }
+	  if (dblval != 20.0)
+	    {
+		fprintf (stderr,
+			 "Unexpected Polygon Symbolizer GetStrokDashItem #1: %1.4f\n",
+			 dblval);
+		*retcode += 27;
+		return 0;
+	    }
+	  if (rl2_polygon_symbolizer_get_stroke_dash_item (polyg, 1, &dblval) !=
+	      RL2_OK)
+	    {
+		fprintf (stderr,
+			 "Unable to get Polygon Symbolizer GetStrokeDashItem #2\n");
+		*retcode += 28;
+		return 0;
+	    }
+	  if (dblval != 10.1)
+	    {
+		fprintf (stderr,
+			 "Unexpected Polygon Symbolizer GetStrokDashItem #2: %1.4f\n",
+			 dblval);
+		*retcode += 29;
+		return 0;
+	    }
+	  if (rl2_polygon_symbolizer_get_stroke_dash_item (polyg, 2, &dblval) !=
+	      RL2_OK)
+	    {
+		fprintf (stderr,
+			 "Unable to get Polygon Symbolizer GetStrokeDashItem #3\n");
+		*retcode += 30;
+		return 0;
+	    }
+	  if (dblval != 5.5)
+	    {
+		fprintf (stderr,
+			 "Unexpected Polygon Symbolizer GetStrokDashItem #3: %1.4f\n",
+			 dblval);
+		*retcode += 31;
+		return 0;
+	    }
+	  if (rl2_polygon_symbolizer_get_stroke_dash_item (polyg, 3, &dblval) !=
+	      RL2_OK)
+	    {
+		fprintf (stderr,
+			 "Unable to get Polygon Symbolizer GetStrokeDashItem #4\n");
+		*retcode += 32;
+		return 0;
+	    }
+	  if (dblval != 4.0)
+	    {
+		fprintf (stderr,
+			 "Unexpected Polygon Symbolizer GetStrokDashItem #4: %1.4f\n",
+			 dblval);
+		*retcode += 33;
+		return 0;
+	    }
+	  if (rl2_polygon_symbolizer_get_stroke_dash_item (polyg, 4, &dblval) !=
+	      RL2_OK)
+	    {
+		fprintf (stderr,
+			 "Unable to get Polygon Symbolizer GetStrokeDashItem #5\n");
+		*retcode += 34;
+		return 0;
+	    }
+	  if (dblval != 6.0)
+	    {
+		fprintf (stderr,
+			 "Unexpected Polygon Symbolizer GetStrokDashItem #4: %1.4f\n",
+			 dblval);
+		*retcode += 35;
+		return 0;
+	    }
+	  if (rl2_polygon_symbolizer_get_stroke_dash_item (polyg, 5, &dblval) !=
+	      RL2_OK)
+	    {
+		fprintf (stderr,
+			 "Unable to get Polygon Symbolizer GetStrokeDashItem #5\n");
+		*retcode += 36;
+		return 0;
+	    }
+	  if (dblval != 12.0)
+	    {
+		fprintf (stderr,
+			 "Unexpected Polygon Symbolizer GetStrokDashItem #5: %1.4f\n",
+			 dblval);
+		*retcode += 37;
+		return 0;
+	    }
+      }
+
+    ret = rl2_polygon_symbolizer_get_stroke_dash_offset (polyg, &dblval);
+    if (strcmp (style_name, "polygon_1") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Polygon Symbolizer GetStrokeDashOffset #1\n",
+			 style_name);
+		*retcode += 38;
+		return 0;
+	    }
+	  dblval = 0.0;
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Polygon Symbolizer GetStrokeDashOffset #1\n",
+			 style_name);
+		*retcode += 39;
+		return 0;
+	    }
+      }
+    intval = 0;
+    if (strcmp (style_name, "polygon_1") == 0
+	|| strcmp (style_name, "polygon_3") == 0)
+      {
+	  if (dblval == 0.0)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "polygon_2") == 0)
+      {
+	  if (dblval == 10.0)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Polygon Symbolizer GetStrokeDashOffset #1: %1.4f\n",
+		   style_name, dblval);
+	  *retcode += 40;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_has_fill (polyg, &intval) != RL2_OK)
+      {
+	  fprintf (stderr, "%s: Unable to get Polygon Symbolizer HasFill #1\n",
+		   style_name);
+	  *retcode += 41;
+	  return 0;
+      }
+    red = 0;
+    if (strcmp (style_name, "polygon_2") == 0)
+      {
+	  if (intval == 0)
+	      red = 1;
+      }
+    if (strcmp (style_name, "polygon_1") == 0
+	|| strcmp (style_name, "polygon_3") == 0)
+      {
+	  if (intval == 1)
+	      red = 1;
+      }
+    if (red != 1)
+      {
+	  fprintf (stderr, "%s: Unexpected Polygon Symbolizer HasFill #1: %d\n",
+		   style_name, intval);
+	  *retcode += 42;
+	  return 0;
+      }
+
+    ret = rl2_polygon_symbolizer_get_fill_color (polyg, &red, &green, &blue);
+    if (strcmp (style_name, "polygon_2") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Polygon Symbolizer GetFillColor #1\n",
+			 style_name);
+		*retcode += 43;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Polygon Symbolizer GetFillColor #1\n",
+			 style_name);
+		*retcode += 44;
+		return 0;
+	    }
+      }
+    intval = 0;
+    if (strcmp (style_name, "polygon_1") == 0)
+      {
+	  if (red == 0x37 && green == 0x81 && blue == 0xf2)
+	      intval = 1;
+      }
+    else
+	intval = 1;
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Polygon Symbolizer GetFillColor #1: #%02x%02x%02x\n",
+		   style_name, red, green, blue);
+	  *retcode += 45;
+	  return 0;
+      }
+
+    ret = rl2_polygon_symbolizer_get_fill_opacity (polyg, &dblval);
+    if (strcmp (style_name, "polygon_2") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Polygon Symbolizer GetFillOpacity #1\n",
+			 style_name);
+		*retcode += 46;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Polygon Symbolizer GetFillOpacity #1\n",
+			 style_name);
+		*retcode += 47;
+		return 0;
+	    }
+      }
+    intval = 0;
+    if (strcmp (style_name, "polygon_1") == 0)
+      {
+	  if (dblval == 0.5)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "polygon_2") == 0)
+	intval = 1;
+    if (strcmp (style_name, "polygon_3") == 0)
+      {
+	  if (dblval == 0.25)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Polygon Symbolizer GetFillOpacity #1: %1.4f\n",
+		   style_name, dblval);
+	  *retcode += 48;
+	  return 0;
+      }
+
+    ret = rl2_polygon_symbolizer_get_displacement (polyg, &dblval, &dblval2);
+    if (ret != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Polygon Symbolizer GetDisplacement #1\n",
+		   style_name);
+	  *retcode += 49;
+	  return 0;
+      }
+    intval = 0;
+    if (strcmp (style_name, "polygon_1") == 0
+	|| strcmp (style_name, "polygon_3") == 0)
+      {
+	  if (dblval == 0.0 && dblval2 == 0.0)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "polygon_2") == 0)
+      {
+	  if (dblval == 10.0 && dblval2 == 15.0)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s; Unexpected polygon Symbolizer GetDisplacement #1: x=%1.4f y=%1.4f\n",
+		   style_name, dblval, dblval2);
+	  *retcode += 50;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_get_perpendicular_offset (polyg, &dblval) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Polygon Symbolizer GetPerpendicularOffset #1\n",
+		   style_name);
+	  *retcode += 51;
+	  return 0;
+      }
+    intval = 0;
+    if (strcmp (style_name, "polygon_1") == 0
+	|| strcmp (style_name, "polygon_3") == 0)
+      {
+	  if (dblval == 0.0)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "polygon_2") == 0)
+      {
+	  if (dblval == 5.0)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s; Unexpected polygon Symbolizer GetPerpendicularOffset #1: %1.4f\n",
+		   style_name, dblval);
+	  *retcode += 52;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_has_graphic_stroke (polyg, &intval) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Polygon Symbolizer HasGraphicStroke #1\n",
+		   style_name);
+	  *retcode += 53;
+	  return 0;
+      }
+    red = 0;
+    if (strcmp (style_name, "polygon_1") == 0
+	|| strcmp (style_name, "polygon_3") == 0)
+      {
+	  if (intval == 0)
+	      red = 1;
+      }
+    if (strcmp (style_name, "polygon_2") == 0)
+      {
+	  if (intval == 1)
+	      red = 1;
+      }
+    if (red != 1)
+      {
+	  fprintf (stderr,
+		   "%s; Unexpected Polygon Symbolizer HasGraphicStroke #1: %d\n",
+		   style_name, intval);
+	  *retcode += 54;
+	  return 0;
+      }
+
+    string = rl2_polygon_symbolizer_get_graphic_stroke_href (polyg);
+    intval = 0;
+    if (strcmp (style_name, "polygon_1") == 0
+	|| strcmp (style_name, "polygon_3") == 0)
+      {
+	  if (string == NULL)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "polygon_2") == 0)
+      {
+	  if (string != NULL)
+	    {
+		if (strcmp (string, "http:/www.acme.com/sample.png") == 0)
+		    intval = 1;
+	    }
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s; Unexpected Polygon Symbolizer GetGraphicStrokeHref #1: %s\n",
+		   style_name, string);
+	  *retcode += 55;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_get_graphic_stroke_recode_count (polyg, &intval)
+	!= RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Polygon Symbolizer GetGraphicStrokeRecodeCount #1\n",
+		   style_name);
+	  *retcode += 56;
+	  return 0;
+      }
+    red = 0;
+    if (strcmp (style_name, "polygon_1") == 0
+	|| strcmp (style_name, "polygon_3") == 0)
+      {
+	  if (intval == 0)
+	      red = 1;
+      }
+    if (strcmp (style_name, "polygon_2") == 0)
+      {
+	  if (intval == 2)
+	      red = 1;
+      }
+    if (red != 1)
+      {
+	  fprintf (stderr,
+		   "%s; Unexpected Polygon Symbolizer GetGraphicStrokeRecodeCount #1: %d\n",
+		   style_name, intval);
+	  *retcode += 57;
+	  return 0;
+      }
+
+    intval =
+	rl2_polygon_symbolizer_get_graphic_stroke_recode_color (polyg, 0,
+								&index, &red,
+								&green, &blue);
+    if (strcmp (style_name, "polygon_1") == 0
+	|| strcmp (style_name, "polygon_3") == 0)
+      {
+	  if (intval == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Polygon Symbolizer GetGraphicStrokeRecodeColor #1\n",
+			 style_name);
+		*retcode += 58;
+		return 0;
+	    }
+	  intval = 1;
+      }
+    if (strcmp (style_name, "polygon_2") == 0)
+      {
+	  if (intval != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Polygon Symbolizer GetGraphicStrokeRecodeColor #1\n",
+			 style_name);
+		*retcode += 59;
+		return 0;
+	    }
+	  intval = 0;
+	  if (index == 0 && red == 0x12 && green == 0x34 && blue == 0x56)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Polygon Symbolizer GetGraphicStrokeRecodeColor #1: #%02x%02x%02x\n",
+		   style_name, red, green, blue);
+	  *retcode += 60;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_has_graphic_fill (polyg, &intval) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Polygon Symbolizer HasGraphicFill #1\n",
+		   style_name);
+	  *retcode += 61;
+	  return 0;
+      }
+    red = 0;
+    if (strcmp (style_name, "polygon_1") == 0
+	|| strcmp (style_name, "polygon_2") == 0)
+      {
+	  if (intval == 0)
+	      red = 1;
+      }
+    if (strcmp (style_name, "polygon_3") == 0)
+      {
+	  if (intval == 1)
+	      red = 1;
+      }
+    if (red != 1)
+      {
+	  fprintf (stderr,
+		   "%s; Unexpected Polygon Symbolizer HasGraphicFill #1: %d\n",
+		   style_name, intval);
+	  *retcode += 62;
+	  return 0;
+      }
+
+    string = rl2_polygon_symbolizer_get_graphic_fill_href (polyg);
+    intval = 0;
+    if (strcmp (style_name, "polygon_1") == 0
+	|| strcmp (style_name, "polygon_2") == 0)
+      {
+	  if (string == NULL)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "polygon_3") == 0)
+      {
+	  if (string != NULL)
+	    {
+		if (strcmp (string, "http:/www.acme.com/sample.png") == 0)
+		    intval = 1;
+	    }
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s; Unexpected Polygon Symbolizer GetGraphicFillHref #1: %s\n",
+		   style_name, string);
+	  *retcode += 63;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_get_graphic_fill_recode_count (polyg, &intval) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Polygon Symbolizer GetGraphicFillRecodeCount #1\n",
+		   style_name);
+	  *retcode += 64;
+	  return 0;
+      }
+    red = 0;
+    if (strcmp (style_name, "polygon_1") == 0
+	|| strcmp (style_name, "polygon_2") == 0)
+      {
+	  if (intval == 0)
+	      red = 1;
+      }
+    if (strcmp (style_name, "polygon_3") == 0)
+      {
+	  if (intval == 2)
+	      red = 1;
+      }
+    if (red != 1)
+      {
+	  fprintf (stderr,
+		   "%s; Unexpected Polygon Symbolizer GetGraphicFillRecodeCount #1: %d\n",
+		   style_name, intval);
+	  *retcode += 65;
+	  return 0;
+      }
+
+    intval =
+	rl2_polygon_symbolizer_get_graphic_fill_recode_color (polyg, 0, &index,
+							      &red, &green,
+							      &blue);
+    if (strcmp (style_name, "polygon_1") == 0
+	|| strcmp (style_name, "polygon_2") == 0)
+      {
+	  if (intval == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Polygon Symbolizer GetGraphicFillRecodeColor #1\n",
+			 style_name);
+		*retcode += 66;
+		return 0;
+	    }
+	  intval = 1;
+      }
+    if (strcmp (style_name, "polygon_3") == 0)
+      {
+	  if (intval != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Polygon Symbolizer GetGraphicFillRecodeColor #1\n",
+			 style_name);
+		*retcode += 67;
+		return 0;
+	    }
+	  intval = 0;
+	  if (index == 0 && red == 0x12 && green == 0x34 && blue == 0x56)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Polygon Symbolizer GetGraphicFillRecodeColor #1: #%02x%02x%02x\n",
+		   style_name, red, green, blue);
+	  *retcode += 68;
+	  return 0;
+      }
+
+    rl2_destroy_feature_type_style (style);
+    return 1;
+}
+
+static int
+test_style (sqlite3 * db_handle, const char *coverage,
+	    const char *style_name, int *retcode)
+{
+/* testing a FeatureType Style (PolygonSymbolizers) */
+    rl2FeatureTypeStylePtr style;
+    rl2VectorSymbolizerPtr symbolizer;
+    rl2PolygonSymbolizerPtr polyg;
+    int intval;
+    int index;
+    double dblval;
+    double dblval2;
+    const char *string;
+    unsigned char red;
+    unsigned char green;
+    unsigned char blue;
+    int scale_forbidden;
+    style =
+	rl2_create_feature_type_style_from_dbms (db_handle, coverage,
+						 style_name);
+    if (style == NULL)
+      {
+	  fprintf (stderr, "Unable to retrieve style '%s'\n", style_name);
+	  *retcode += 1;
+	  return 0;
+      }
+
+    string = rl2_get_feature_type_style_name (style);
+    if (string == NULL)
+      {
+	  fprintf (stderr, "Unable to retrieve style name '%s'\n", style_name);
+	  *retcode += 2;
+	  return 0;
+      }
+    if (strcmp (string, "polygon_style") != 0)
+      {
+	  fprintf (stderr, "%s: Unexpected style name '%s'\n", style_name,
+		   string);
+	  *retcode += 3;
+	  return 0;
+      }
+
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 1.0, NULL,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s)\n",
+		   style_name);
+	  *retcode += 4;
+	  return 0;
+      }
+
+    if (rl2_get_vector_symbolizer_count (symbolizer, &intval) != RL2_OK)
+      {
+	  fprintf (stderr, "%s: Unable to get Vector Symbolizer Count #2\n",
+		   style_name);
+	  *retcode += 5;
+	  return 0;
+      }
+    if (intval != 2)
+      {
+	  fprintf (stderr, "%s: Unexpected Vector Symbolizer Count #2: %d\n",
+		   style_name, intval);
+	  *retcode += 6;
+	  return 0;
+      }
+
+    if (rl2_get_vector_symbolizer_item_type (symbolizer, 1, &intval) != RL2_OK)
+      {
+	  fprintf (stderr, "%s: Unable to get Vector Symbolizer Item Type #2\n",
+		   style_name);
+	  *retcode += 7;
+	  return 0;
+      }
+    if (intval != RL2_POLYGON_SYMBOLIZER)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Vector Symbolizer Item Type #2: %d\n",
+		   style_name, intval);
+	  *retcode += 8;
+	  return 0;
+      }
+
+    polyg = rl2_get_polygon_symbolizer (symbolizer, 1);
+    if (polyg == NULL)
+      {
+	  fprintf (stderr, "%s: Unable to get a Polygon Symbolizer #2\n",
+		   style_name);
+	  *retcode += 9;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_has_stroke (NULL, &intval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Polygon Symbolizer HasStroke #2\n");
+	  *retcode += 10;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_has_graphic_stroke (NULL, &intval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Polygon Symbolizer HasGraphicStroke #2\n");
+	  *retcode += 11;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_get_graphic_stroke_href (NULL) != NULL)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Polygon Symbolizer GetGraphicStrokeHref #2\n");
+	  *retcode += 12;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_get_graphic_stroke_recode_count (NULL, &intval)
+	== RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Polygon Symbolizer GetGraphicStrokeRecodeCount #2\n");
+	  *retcode += 13;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_get_graphic_stroke_recode_color (NULL, 0,
+								&index, &red,
+								&green,
+								&blue) ==
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Polygon Symbolizer GetGraphicStrokeRecodeColor #2\n");
+	  *retcode += 14;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_get_stroke_color (NULL, &red, &green, &blue) ==
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Polygon Symbolizer GetStrokeColor #2\n");
+	  *retcode += 15;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_get_stroke_opacity (NULL, &dblval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Polygon Symbolizer GetStrokeOpacity #2\n");
+	  *retcode += 16;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_get_stroke_width (NULL, &dblval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Polygon Symbolizer GetStrokeWidth #2\n");
+	  *retcode += 17;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_get_stroke_linejoin (NULL, &red) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Polygon Symbolizer GetStrokePolygonjoin #2\n");
+	  *retcode += 18;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_get_stroke_linecap (NULL, &red) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Polygon Symbolizer GetStrokePolygoncap #2\n");
+	  *retcode += 19;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_get_stroke_dash_count (NULL, &intval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Polygon Symbolizer GetStrokeDashCount #2\n");
+	  *retcode += 20;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_get_stroke_dash_item (NULL, 0, &dblval) ==
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Polygon Symbolizer GetStrokeDashItem #2\n");
+	  *retcode += 21;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_get_stroke_dash_offset (NULL, &dblval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Polygon Symbolizer GetStrokeDashOffset #2\n");
+	  *retcode += 22;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_get_perpendicular_offset (NULL, &dblval) ==
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Polygon Symbolizer GetPerpendicularOffset #2\n");
+	  *retcode += 23;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_has_fill (NULL, &intval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Polygon Symbolizer HasFill #2\n");
+	  *retcode += 24;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_has_graphic_fill (NULL, &intval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Polygon Symbolizer HasGraphicFill #2\n");
+	  *retcode += 25;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_get_graphic_fill_href (NULL) != NULL)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Polygon Symbolizer GetGraphicFillHref #2\n");
+	  *retcode += 26;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_get_graphic_fill_recode_count (NULL, &intval) ==
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Polygon Symbolizer GetGraphicFillRecodeCount #2\n");
+	  *retcode += 27;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_get_graphic_fill_recode_color (NULL, 0,
+							      &index, &red,
+							      &green,
+							      &blue) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Polygon Symbolizer GetGraphicFillRecodeColor #2\n");
+	  *retcode += 28;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_get_fill_color (NULL, &red, &green, &blue) ==
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Polygon Symbolizer GetFillColor #2\n");
+	  *retcode += 29;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_get_fill_opacity (NULL, &dblval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Polygon Symbolizer GetFillOpacity #2\n");
+	  *retcode += 30;
+	  return 0;
+      }
+
+    if (rl2_polygon_symbolizer_get_displacement (NULL, &dblval, &dblval2) ==
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Polygon Symbolizer GetDisplacement #2\n");
+	  *retcode += 31;
+	  return 0;
+      }
+
+    rl2_destroy_feature_type_style (style);
+    return 1;
+}
+
+static int
+test_filter (sqlite3 * db_handle, const char *coverage,
+	     const char *style_name, int *retcode)
+{
+/* testing Filter from a FeatureType Style (PolygonSymbolizers) */
+    rl2FeatureTypeStylePtr style;
+    rl2VectorSymbolizerPtr symbolizer;
+    rl2PolygonSymbolizerPtr polyg;
+    rl2VariantArrayPtr value;
+    unsigned char red;
+    unsigned char green;
+    unsigned char blue;
+    int scale_forbidden;
+    int intval;
+    const char *string;
+    style =
+	rl2_create_feature_type_style_from_dbms (db_handle, coverage,
+						 style_name);
+    if (style == NULL)
+      {
+	  fprintf (stderr, "Unable to retrieve style '%s'\n", style_name);
+	  *retcode += 1;
+	  return 0;
+      }
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #1\n");
+	  *retcode += 2;
+	  return 0;
+      }
+    string = "Emilia Romagna";
+    if (rl2_set_variant_text (value, 0, "some_column", string, strlen (string))
+	!= RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #1\n");
+	  *retcode += 3;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #3\n",
+		   style_name);
+	  *retcode += 4;
+	  return 0;
+      }
+    polyg = rl2_get_polygon_symbolizer (symbolizer, 0);
+    if (polyg == NULL)
+      {
+	  fprintf (stderr, "Unable to get Polygon Symbolizer #2\n");
+	  *retcode += 5;
+	  return 0;
+      }
+    if (rl2_polygon_symbolizer_get_stroke_color (polyg, &red, &green, &blue) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unable to get Polygon Symbolizer GetStrokeColor #2\n");
+	  *retcode += 6;
+	  return 0;
+      }
+    if (red != 0x10 || green != 0xff || blue != 0x20)
+      {
+	  fprintf (stderr,
+		   "Unexpected Polygon Symbolizer GetStrokeColor #2: %02x%02x%02x\n",
+		   red, green, blue);
+	  *retcode += 7;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #2\n");
+	  *retcode += 8;
+	  return 0;
+      }
+    string = "Lazio";
+    if (rl2_set_variant_text (value, 0, "some_column", string, strlen (string))
+	!= RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #2\n");
+	  *retcode += 9;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #4\n",
+		   style_name);
+	  *retcode += 10;
+	  return 0;
+      }
+    polyg = rl2_get_polygon_symbolizer (symbolizer, 0);
+    if (polyg == NULL)
+      {
+	  fprintf (stderr, "Unable to get Polygon Symbolizer #3\n");
+	  *retcode += 11;
+	  return 0;
+      }
+    if (rl2_polygon_symbolizer_get_fill_color (polyg, &red, &green, &blue) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unable to get Polygon Symbolizer GetFillColor #2\n");
+	  *retcode += 12;
+	  return 0;
+      }
+    if (red != 0xff || green != 0xdd || blue != 0xaa)
+      {
+	  fprintf (stderr,
+		   "Unexpected Polygon Symbolizer GetStrokeColor #3: %02x%02x%02x\n",
+		   red, green, blue);
+	  *retcode += 13;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #3\n");
+	  *retcode += 14;
+	  return 0;
+      }
+    string = "Abruzzo";
+    if (rl2_set_variant_text (value, 0, "some_column", string, strlen (string))
+	!= RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #3\n");
+	  *retcode += 15;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #5\n",
+		   style_name);
+	  *retcode += 16;
+	  return 0;
+      }
+    polyg = rl2_get_polygon_symbolizer (symbolizer, 0);
+    if (polyg == NULL)
+      {
+	  fprintf (stderr, "Unable to get Polygon Symbolizer #4\n");
+	  *retcode += 17;
+	  return 0;
+      }
+    if (rl2_polygon_symbolizer_get_fill_color (polyg, &red, &green, &blue) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unable to get Polygon Symbolizer GetFillColor #3\n");
+	  *retcode += 18;
+	  return 0;
+      }
+    if (red != 0x81 || green != 0xfa || blue != 0x91)
+      {
+	  fprintf (stderr,
+		   "Unexpected Polygon Symbolizer GetStrokeColor #4: %02x%02x%02x\n",
+		   red, green, blue);
+	  *retcode += 19;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #4\n");
+	  *retcode += 20;
+	  return 0;
+      }
+    string = "Campania";
+    if (rl2_set_variant_text (value, 0, "some_column", string, strlen (string))
+	!= RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #4\n");
+	  *retcode += 21;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #6\n",
+		   style_name);
+	  *retcode += 22;
+	  return 0;
+      }
+    polyg = rl2_get_polygon_symbolizer (symbolizer, 1);
+    if (polyg == NULL)
+      {
+	  fprintf (stderr, "Unable to get Polygon Symbolizer #5\n");
+	  *retcode += 23;
+	  return 0;
+      }
+    if (rl2_polygon_symbolizer_get_fill_color (polyg, &red, &green, &blue) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unable to get Polygon Symbolizer GetFillColor #4\n");
+	  *retcode += 24;
+	  return 0;
+      }
+    if (red != 0x37 || green != 0x81 || blue != 0xf2)
+      {
+	  fprintf (stderr,
+		   "Unexpected Polygon Symbolizer GetStrokeColor #5: %02x%02x%02x\n",
+		   red, green, blue);
+	  *retcode += 25;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #5\n");
+	  *retcode += 26;
+	  return 0;
+      }
+    string = "Trentino Alto Adige";
+    if (rl2_set_variant_text (value, 0, "some_column", string, strlen (string))
+	!= RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #5\n");
+	  *retcode += 27;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #7\n",
+		   style_name);
+	  *retcode += 29;
+	  return 0;
+      }
+    polyg = rl2_get_polygon_symbolizer (symbolizer, 0);
+    if (polyg == NULL)
+      {
+	  fprintf (stderr, "Unable to get Polygon Symbolizer #6\n");
+	  *retcode += 30;
+	  return 0;
+      }
+    if (rl2_polygon_symbolizer_get_fill_color (polyg, &red, &green, &blue) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unable to get Polygon Symbolizer GetFillColor #5\n");
+	  *retcode += 31;
+	  return 0;
+      }
+    if (red != 0x83 || green != 0xfc || blue != 0x93)
+      {
+	  fprintf (stderr,
+		   "Unexpected Polygon Symbolizer GetStrokeColor #6: %02x%02x%02x\n",
+		   red, green, blue);
+	  *retcode += 32;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #6\n");
+	  *retcode += 26;
+	  return 0;
+      }
+    string = "pseudo-Toscanella";
+    if (rl2_set_variant_text (value, 0, "name", string, strlen (string)) !=
+	RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #6\n");
+	  *retcode += 27;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #8\n",
+		   style_name);
+	  *retcode += 28;
+	  return 0;
+      }
+    polyg = rl2_get_polygon_symbolizer (symbolizer, 0);
+    if (polyg == NULL)
+      {
+	  fprintf (stderr, "Unable to get Polygon Symbolizer #7\n");
+	  *retcode += 29;
+	  return 0;
+      }
+    if (rl2_polygon_symbolizer_get_fill_color (polyg, &red, &green, &blue) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unable to get Polygon Symbolizer GetFillColor #6\n");
+	  *retcode += 30;
+	  return 0;
+      }
+    if (red != 0xab || green != 0xcd || blue != 0xef)
+      {
+	  fprintf (stderr,
+		   "Unexpected Polygon Symbolizer GetStrokeColor #7: %02x%02x%02x\n",
+		   red, green, blue);
+	  *retcode += 32;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #7\n");
+	  *retcode += 33;
+	  return 0;
+      }
+    string = "Toscanona";
+    if (rl2_set_variant_text (value, 0, "name", string, strlen (string)) !=
+	RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #7\n");
+	  *retcode += 34;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #9\n",
+		   style_name);
+	  *retcode += 35;
+	  return 0;
+      }
+    polyg = rl2_get_polygon_symbolizer (symbolizer, 0);
+    if (polyg == NULL)
+      {
+	  fprintf (stderr, "Unable to get Polygon Symbolizer #8\n");
+	  *retcode += 36;
+	  return 0;
+      }
+    if (rl2_polygon_symbolizer_get_fill_color (polyg, &red, &green, &blue) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unable to get Polygon Symbolizer GetFillColor #7\n");
+	  *retcode += 37;
+	  return 0;
+      }
+    if (red != 0xab || green != 0xcd || blue != 0xef)
+      {
+	  fprintf (stderr,
+		   "Unexpected Polygon Symbolizer GetStrokeColor #8: %02x%02x%02x\n",
+		   red, green, blue);
+	  *retcode += 38;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    intval = rl2_get_feature_type_style_columns_count (style);
+    if (intval != 2)
+      {
+	  fprintf (stderr,
+		   "Unexpected GetFeatureTypeStyleColumnsCount #1: %d\n",
+		   intval);
+	  *retcode += 39;
+	  return 0;
+      }
+
+    string = rl2_get_feature_type_style_column_name (style, 0);
+    if (strcasecmp (string, "name") != 0)
+      {
+	  fprintf (stderr,
+		   "Unexpected GetFeatureTypeStyleColumnName #1: \"%s\"\n",
+		   string);
+	  *retcode += 40;
+	  return 0;
+      }
+
+    string = rl2_get_feature_type_style_column_name (style, 1);
+    if (strcasecmp (string, "some_column") != 0)
+      {
+	  fprintf (stderr,
+		   "Unexpected GetFeatureTypeStyleColumnName #2: \"%s\"\n",
+		   string);
+	  *retcode += 41;
+	  return 0;
+      }
+
+    rl2_destroy_feature_type_style (style);
+    return 1;
+}
+
+int
+main (int argc, char *argv[])
+{
+    int result = 0;
+    int ret;
+    sqlite3 *db_handle;
+    void *cache = spatialite_alloc_connection ();
+
+    if (argc > 1 || argv[0] == NULL)
+	argc = 1;		/* silencing stupid compiler warnings */
+
+/* opening and initializing the "memory" test DB */
+    ret = sqlite3_open_v2 ("symbolizers.sqlite", &db_handle,
+			   SQLITE_OPEN_READONLY, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "sqlite3_open_v2() error: %s\n",
+		   sqlite3_errmsg (db_handle));
+	  return -1;
+      }
+    spatialite_init_ex (db_handle, cache, 0);
+
+/* tests */
+    ret = -100;
+    if (!test_symbolizer (db_handle, "polyg1", "polygon_1", &ret))
+	return ret;
+    ret = -200;
+    if (!test_symbolizer (db_handle, "polyg2", "polygon_2", &ret))
+	return ret;
+    ret = -300;
+    if (!test_symbolizer (db_handle, "polyg2", "polygon_3", &ret))
+	return ret;
+    ret = -400;
+    if (!test_style (db_handle, "polyg1", "polygon_style", &ret))
+	return ret;
+    ret = -500;
+    if (!test_filter (db_handle, "polyg1", "polygon_style", &ret))
+	return ret;
+
+/* closing the DB */
+    sqlite3_close (db_handle);
+    spatialite_shutdown ();
+    return result;
+}
diff --git a/test/test_raster.c b/test/test_raster.c
index 849191e..0f137de 100644
--- a/test/test_raster.c
+++ b/test/test_raster.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -47,6 +47,8 @@ the terms of any one of the MPL, the GPL or the LGPL.
 
 #include "rasterlite2/rasterlite2.h"
 
+#include "spatialite.h"
+
 static rl2PalettePtr
 build_palette (int num)
 {
@@ -79,7 +81,6 @@ main (int argc, char *argv[])
     double vResolution;
     unsigned char sample;
     unsigned char *mask;
-    gaiaGeomCollPtr geom = NULL;
     unsigned char *bufpix = malloc (256 * 256);
     memset (bufpix, 255, 256 * 256);
 
@@ -229,14 +230,6 @@ main (int argc, char *argv[])
 	  fprintf (stderr, "Unexpected raster MaxY (Center point)\n");
 	  return -22;
       }
-
-    geom = rl2_get_raster_bbox (raster);
-    if (geom == NULL)
-      {
-	  fprintf (stderr, "Unable to get raster BBOX (Center point)\n");
-	  return -250;
-      }
-    gaiaFreeGeomColl (geom);
     rl2_destroy_raster (raster);
 
     bufpix = malloc (256 * 256);
@@ -1729,12 +1722,6 @@ main (int argc, char *argv[])
 	  return -221;
       }
 
-    if (rl2_get_raster_bbox (NULL) != NULL)
-      {
-	  fprintf (stderr, "Unexpected result: Raster BBOX (NULL)\n");
-	  return -222;
-      }
-
     rl2_destroy_raster (NULL);
 
     bufpix = malloc (256 * 256);
diff --git a/test/test_raster_symbolizer.c b/test/test_raster_symbolizer.c
index 825becf..a23984b 100644
--- a/test/test_raster_symbolizer.c
+++ b/test/test_raster_symbolizer.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -68,13 +68,15 @@ test_group_renderer (sqlite3 * sqlite, rl2GroupStylePtr style, int ind,
 }
 
 static int
-test_group_style (sqlite3 * db_handle, int *retcode)
+test_group_style (sqlite3 * db_handle, int no_web_connection, int *retcode)
 {
 /* loading and testing Group Styles */
     char *sql;
     int ret;
     int xret = 0;
-    sqlite3_stmt *stmt;
+    sqlite3_stmt *stmt1;
+    sqlite3_stmt *stmt2;
+    sqlite3_int64 last_id;
     const char *group = "my_group";
     const char *path1 = "group_style_1.xml";
     const char *path2 = "group_style_2.xml";
@@ -84,93 +86,118 @@ test_group_style (sqlite3 * db_handle, int *retcode)
     int count;
 
 /* loading the Group Stles */
-    sql = "SELECT RegisterGroupStyle(?, XB_Create(XB_LoadXML(?), 1, 1))";
-    ret = sqlite3_prepare_v2 (db_handle, sql, strlen (sql), &stmt, NULL);
+    if (no_web_connection)
+	sql = "SELECT SE_RegisterGroupStyle(XB_Create(XB_LoadXML(?), 1))";
+    else
+	sql = "SELECT SE_RegisterGroupStyle(XB_Create(XB_LoadXML(?), 1, 1))";
+    ret = sqlite3_prepare_v2 (db_handle, sql, strlen (sql), &stmt1, NULL);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "Unable to create the SQL statement\n");
+	  fprintf (stderr, "Unable to create the SQL statement (GroupStyle)\n");
 	  *retcode += 1;
 	  return 0;
       }
-    sqlite3_reset (stmt);
-    sqlite3_clear_bindings (stmt);
-    sqlite3_bind_text (stmt, 1, group, strlen (group), SQLITE_STATIC);
-    sqlite3_bind_text (stmt, 2, path1, strlen (path1), SQLITE_STATIC);
-    ret = sqlite3_step (stmt);
+
+    sql = "SELECT SE_RegisterStyledGroupStyle(?, ?)";
+    ret = sqlite3_prepare_v2 (db_handle, sql, strlen (sql), &stmt2, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr,
+		   "Unable to create the SQL statement (StyledGroupStyle)\n");
+	  *retcode += 2;
+	  return 0;
+      }
+
+    sqlite3_reset (stmt1);
+    sqlite3_clear_bindings (stmt1);
+    sqlite3_bind_text (stmt1, 1, path1, strlen (path1), SQLITE_STATIC);
+    ret = sqlite3_step (stmt1);
     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
       {
-	  if (sqlite3_column_int (stmt, 0) == 1)
+	  if (sqlite3_column_int (stmt1, 0) == 1)
 	      xret = 1;
       }
     if (xret != 1)
       {
 	  fprintf (stderr, "Unable to load \"%s\"\n", path2);
-	  *retcode += 1;
+	  *retcode += 3;
 	  return 0;
       }
-    sqlite3_reset (stmt);
-    sqlite3_clear_bindings (stmt);
-    sqlite3_bind_text (stmt, 1, group, strlen (group), SQLITE_STATIC);
-    sqlite3_bind_text (stmt, 2, path2, strlen (path2), SQLITE_STATIC);
-    ret = sqlite3_step (stmt);
+    last_id = sqlite3_last_insert_rowid (db_handle);
+
+    sqlite3_reset (stmt2);
+    sqlite3_clear_bindings (stmt2);
+    sqlite3_bind_text (stmt2, 1, group, strlen (group), SQLITE_STATIC);
+    sqlite3_bind_int64 (stmt2, 2, last_id);
+    ret = sqlite3_step (stmt2);
     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
       {
-	  if (sqlite3_column_int (stmt, 0) == 1)
+	  if (sqlite3_column_int (stmt2, 0) == 1)
 	      xret = 1;
       }
     if (xret != 1)
       {
-	  fprintf (stderr, "Unable to load \"%s\"\n", path2);
-	  *retcode += 2;
+	  fprintf (stderr, "Unable to register \"%s\"\n", path2);
+	  *retcode += 4;
 	  return 0;
       }
 
-/* testing Group Style #1 */
-    style =
-	rl2_create_group_style_from_dbms (db_handle, "my_group",
-					  "group_style_1");
-    if (style == NULL)
+    sqlite3_reset (stmt1);
+    sqlite3_clear_bindings (stmt1);
+    sqlite3_bind_text (stmt1, 1, path2, strlen (path2), SQLITE_STATIC);
+    ret = sqlite3_step (stmt1);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
       {
-	  fprintf (stderr, "Unable to create Group Style #1\n");
-	  *retcode += 3;
-	  return 0;
+	  if (sqlite3_column_int (stmt1, 0) == 1)
+	      xret = 1;
       }
-    str = rl2_get_group_style_name (style);
-    if (str == NULL)
+    if (xret != 1)
       {
-	  fprintf (stderr, "Unable to get Group Style Name #1\n");
-	  *retcode += 4;
+	  fprintf (stderr, "Unable to load \"%s\"\n", path2);
+	  *retcode += 5;
 	  return 0;
       }
-    if (strcmp (str, "group_style_1") != 0)
+    last_id = sqlite3_last_insert_rowid (db_handle);
+
+    sqlite3_reset (stmt2);
+    sqlite3_clear_bindings (stmt2);
+    sqlite3_bind_text (stmt2, 1, group, strlen (group), SQLITE_STATIC);
+    sqlite3_bind_int64 (stmt2, 2, last_id);
+    ret = sqlite3_step (stmt2);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
       {
-	  fprintf (stderr, "Unexpected Group Style Name #1: %s\n", str);
-	  *retcode += 5;
-	  return 0;
+	  if (sqlite3_column_int (stmt2, 0) == 1)
+	      xret = 1;
       }
-    str = rl2_get_group_style_title (style);
-    if (str == NULL)
+    if (xret != 1)
       {
-	  fprintf (stderr, "Unable to get Group Style Title #1\n");
+	  fprintf (stderr, "Unable to register \"%s\"\n", path2);
 	  *retcode += 6;
 	  return 0;
       }
-    if (strcmp (str, "style-1 title") != 0)
+    sqlite3_finalize (stmt1);
+    sqlite3_finalize (stmt2);
+
+/* testing Group Style #1 */
+    style =
+	rl2_create_group_style_from_dbms (db_handle, "my_group",
+					  "group_style_1");
+    if (style == NULL)
       {
-	  fprintf (stderr, "Unexpected Group Style Title #1: %s\n", str);
+	  fprintf (stderr, "Unable to create Group Style #1\n");
 	  *retcode += 7;
 	  return 0;
       }
-    str = rl2_get_group_style_abstract (style);
+    str = rl2_get_group_style_name (style);
     if (str == NULL)
       {
-	  fprintf (stderr, "Unable to get Group Style Abstract #1\n");
+	  fprintf (stderr, "Unable to get Group Style Name #1\n");
 	  *retcode += 8;
 	  return 0;
       }
-    if (strcmp (str, "style-1 abstract") != 0)
+    if (strcmp (str, "group_style_1") != 0)
       {
-	  fprintf (stderr, "Unexpected Group Style Abstract #1: %s\n", str);
+	  fprintf (stderr, "Unexpected Group Style Name #1: %s\n", str);
 	  *retcode += 9;
 	  return 0;
       }
@@ -277,100 +304,80 @@ test_group_style (sqlite3 * db_handle, int *retcode)
 	  *retcode += 24;
 	  return 0;
       }
-    str = rl2_get_group_style_title (style);
-    if (str == NULL)
-      {
-	  fprintf (stderr, "Unable to get Group Style Title #2\n");
-	  *retcode += 25;
-	  return 0;
-      }
-    if (strcmp (str, "style-2 title") != 0)
-      {
-	  fprintf (stderr, "Unexpected Group Style Title #2: %s\n", str);
-	  *retcode += 26;
-	  return 0;
-      }
-    str = rl2_get_group_style_abstract (style);
-    if (str != NULL)
-      {
-	  fprintf (stderr, "Unexpected Group Style Abstract #2: %s\n", str);
-	  *retcode += 27;
-	  return 0;
-      }
     if (rl2_is_valid_group_style (style, &valid) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to get Group Style Validity #2\n");
-	  *retcode += 28;
+	  *retcode += 25;
 	  return 0;
       }
     if (valid != 0)
       {
 	  fprintf (stderr, "Unexpected Group Style Validity #2: %d\n", valid);
-	  *retcode += 29;
+	  *retcode += 26;
 	  return 0;
       }
     if (rl2_get_group_style_count (style, &count) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to get Group Style Count #2\n");
-	  *retcode += 30;
+	  *retcode += 27;
 	  return 0;
       }
     if (count != 2)
       {
 	  fprintf (stderr, "Unexpected Group Style Count #2: %d\n", count);
-	  *retcode += 31;
+	  *retcode += 28;
 	  return 0;
       }
     str = rl2_get_group_named_layer (style, 1);
     if (str == NULL)
       {
 	  fprintf (stderr, "Unable to get Group Style NamedLayer #2\n");
-	  *retcode += 32;
+	  *retcode += 29;
 	  return 0;
       }
     if (strcmp (str, "dumb0") != 0)
       {
 	  fprintf (stderr, "Unexpected Group Style NamedLayer #2: %s\n", str);
-	  *retcode += 33;
+	  *retcode += 30;
 	  return 0;
       }
     str = rl2_get_group_named_style (style, 1);
     if (str == NULL)
       {
 	  fprintf (stderr, "Unable to get Group Style NamedLayer #2\n");
-	  *retcode += 34;
+	  *retcode += 31;
 	  return 0;
       }
     if (strcmp (str, "style1") != 0)
       {
 	  fprintf (stderr, "Unexpected Group Style NamedStyle #2: %s\n", str);
-	  *retcode += 35;
+	  *retcode += 32;
 	  return 0;
       }
     if (rl2_is_valid_group_named_layer (style, 0, &valid) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to get Group NamedLayer Validity #2\n");
-	  *retcode += 36;
+	  *retcode += 33;
 	  return 0;
       }
     if (valid != 1)
       {
 	  fprintf (stderr, "Unexpected Group NamedLayer Validity #2: %d\n",
 		   valid);
-	  *retcode += 37;
+	  *retcode += 34;
 	  return 0;
       }
     if (rl2_is_valid_group_named_style (style, 1, &valid) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to get Group NamedStyle Validity #2\n");
-	  *retcode += 38;
+	  *retcode += 35;
 	  return 0;
       }
     if (valid != 0)
       {
 	  fprintf (stderr, "Unexpected Group NamedStyle Validity #2: %d\n",
 		   valid);
-	  *retcode += 39;
+	  *retcode += 36;
 	  return 0;
       }
     if (!test_group_renderer (db_handle, style, 2, retcode))
@@ -382,12 +389,10 @@ test_group_style (sqlite3 * db_handle, int *retcode)
     if (style != NULL)
       {
 	  fprintf (stderr, "Unexpected success create Group Style\n");
-	  *retcode += 40;
+	  *retcode += 37;
 	  return 0;
       }
     rl2_get_group_style_name (NULL);
-    rl2_get_group_style_title (NULL);
-    rl2_get_group_style_abstract (NULL);
     rl2_is_valid_group_style (NULL, &valid);
     rl2_get_group_style_count (NULL, &count);
     rl2_get_group_named_layer (NULL, 1);
@@ -400,26 +405,58 @@ test_group_style (sqlite3 * db_handle, int *retcode)
 
 static int
 load_symbolizer (sqlite3 * db_handle, const char *coverage, const char *path,
-		 int *retcode)
+		 int no_web_connection, int *retcode)
 {
 /* loading a RasterSymbolizer as a RasterStyle */
     char *sql;
     int ret;
     int xret = 0;
     sqlite3_stmt *stmt;
+    sqlite3_int64 last_id;
 
-    sql = "SELECT RegisterRasterStyledLayer(?, XB_Create(XB_LoadXML(?), 1, 1))";
+    if (no_web_connection)
+	sql = "SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(?), 1))";
+    else
+	sql = "SELECT SE_RegisterRasterStyle(XB_Create(XB_LoadXML(?), 1, 1))";
     ret = sqlite3_prepare_v2 (db_handle, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "Unable to create the SQL statement\n");
+	  fprintf (stderr, "Unable to create the SQL statement (Style)\n");
 	  *retcode += 1;
 	  return 0;
       }
     sqlite3_reset (stmt);
     sqlite3_clear_bindings (stmt);
+    sqlite3_bind_text (stmt, 1, path, strlen (path), SQLITE_STATIC);
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+      {
+	  if (sqlite3_column_int (stmt, 0) == 1)
+	      xret = 1;
+      }
+    last_id = sqlite3_last_insert_rowid (db_handle);
+    sqlite3_finalize (stmt);
+    if (xret != 1)
+      {
+	  fprintf (stderr, "unable to register a Raster Style \"%s\")\n", path);
+	  *retcode += 2;
+	  return 0;
+      }
+    xret = 0;
+
+    sql = "SELECT SE_RegisterRasterStyledLayer(?, ?)";
+    ret = sqlite3_prepare_v2 (db_handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr,
+		   "Unable to create the SQL statement (RasterStyledLayer)\n");
+	  *retcode += 3;
+	  return 0;
+      }
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
     sqlite3_bind_text (stmt, 1, coverage, strlen (coverage), SQLITE_STATIC);
-    sqlite3_bind_text (stmt, 2, path, strlen (path), SQLITE_STATIC);
+    sqlite3_bind_int64 (stmt, 2, last_id);
     ret = sqlite3_step (stmt);
     if (ret == SQLITE_DONE || ret == SQLITE_ROW)
       {
@@ -428,7 +465,7 @@ load_symbolizer (sqlite3 * db_handle, const char *coverage, const char *path,
       }
     if (xret == 1)
 	return 1;
-    *retcode += 1;
+    *retcode += 4;
     return 0;
 }
 
@@ -437,15 +474,18 @@ test_symbolizer_1 (sqlite3 * db_handle, const char *coverage,
 		   const char *style_name, int *retcode)
 {
 /* testing a RasterSymbolizer */
-    rl2RasterStylePtr style;
-    const char *string;
+    rl2CoverageStylePtr style;
+    rl2RasterSymbolizerPtr symbolizer;
     double value;
     int intval;
+    int categorize;
+    int interpolate;
     unsigned char enhancement;
     unsigned char red;
     unsigned char green;
     unsigned char blue;
-    style = rl2_create_raster_style_from_dbms (db_handle, coverage, style_name);
+    style =
+	rl2_create_coverage_style_from_dbms (db_handle, coverage, style_name);
     if (style == NULL)
       {
 	  fprintf (stderr, "Unable to retrieve style '%s'\n", style_name);
@@ -453,125 +493,89 @@ test_symbolizer_1 (sqlite3 * db_handle, const char *coverage,
 	  return 0;
       }
 
-    if (strcmp (coverage, "dumb1") == 0)
+    symbolizer = rl2_get_symbolizer_from_coverage_style (style, 1.0);
+    if (symbolizer == NULL)
       {
-	  string = rl2_get_raster_style_name (style);
-	  if (string == NULL)
-	    {
-		fprintf (stderr, "Unexpected NULL style name (%s)\n",
-			 style_name);
-		*retcode += 1;
-		return 0;
-	    }
-	  if (strcmp (string, "style1") != 0)
-	    {
-		fprintf (stderr, "Unexpected style name \"%s\"\n", string);
-		*retcode += 2;
-		return 0;
-	    }
-
-	  string = rl2_get_raster_style_title (style);
-	  if (string == NULL)
-	    {
-		fprintf (stderr, "Unexpected NULL style title (%s)\n",
-			 style_name);
-		*retcode += 3;
-		return 0;
-	    }
-	  if (strcmp (string, "title: first style") != 0)
-	    {
-		fprintf (stderr, "Unexpected style title \"%s\"\n", string);
-		*retcode += 4;
-		return 0;
-	    }
-
-	  string = rl2_get_raster_style_abstract (style);
-	  if (string == NULL)
-	    {
-		fprintf (stderr, "Unexpected NULL style abstract (%s)\n",
-			 style_name);
-		*retcode += 5;
-		return 0;
-	    }
-	  if (strcmp (string, "abstract: first style") != 0)
-	    {
-		fprintf (stderr, "Unexpected style abstract \"%s\"\n", string);
-		*retcode += 6;
-		return 0;
-	    }
+	  fprintf (stderr, "Unexpected NULL RasterSymbolizer (%s)\n",
+		   style_name);
+	  *retcode += 2;
+	  return 0;
       }
 
-    if (rl2_get_raster_style_opacity (style, &value) != RL2_OK)
+    if (rl2_get_raster_symbolizer_opacity (symbolizer, &value) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to get Opacity\n");
-	  *retcode += 7;
+	  *retcode += 3;
 	  return 0;
       }
     if (value != 1.0)
       {
 	  fprintf (stderr, "Unexpected Opacity %1.2f\n", value);
-	  *retcode += 8;
+	  *retcode += 4;
 	  return 0;
       }
 
-    if (rl2_is_raster_style_mono_band_selected (style, &intval) != RL2_OK)
+    if (rl2_is_raster_symbolizer_mono_band_selected
+	(symbolizer, &intval, &categorize, &interpolate) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to get IsMonoBandSelected\n");
-	  *retcode += 9;
+	  *retcode += 5;
 	  return 0;
       }
     if (intval != 1)
       {
 	  fprintf (stderr, "Unexpected IsMonoBandSelected %d\n", intval);
-	  *retcode += 10;
+	  *retcode += 6;
 	  return 0;
       }
 
-    if (rl2_is_raster_style_triple_band_selected (style, &intval) != RL2_OK)
+    if (rl2_is_raster_symbolizer_triple_band_selected (symbolizer, &intval) !=
+	RL2_OK)
       {
 	  fprintf (stderr, "Unable to get IsTripleBandSelected\n");
-	  *retcode += 11;
+	  *retcode += 7;
 	  return 0;
       }
     if (intval != 0)
       {
 	  fprintf (stderr, "Unexpected IsTripleBandSelected %d\n", intval);
-	  *retcode += 12;
+	  *retcode += 8;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_overall_contrast_enhancement
-	(style, &enhancement, &value) != RL2_OK)
+    if (rl2_get_raster_symbolizer_overall_contrast_enhancement
+	(symbolizer, &enhancement, &value) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to get OverallContrastEnhancement\n");
-	  *retcode += 13;
+	  *retcode += 9;
 	  return 0;
       }
     if (enhancement != RL2_CONTRAST_ENHANCEMENT_NONE)
       {
 	  fprintf (stderr, "Unexpected OverallContrastEnhancement %02x\n",
 		   enhancement);
-	  *retcode += 14;
+	  *retcode += 10;
 	  return 0;
       }
 
-    if (rl2_has_raster_style_shaded_relief (style, &intval) != RL2_OK)
+    if (rl2_has_raster_symbolizer_shaded_relief (symbolizer, &intval) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to get HasShadedRelief\n");
-	  *retcode += 15;
+	  *retcode += 11;
 	  return 0;
       }
     if (intval != 1)
       {
 	  fprintf (stderr, "Unexpected HasShadedRelief %d\n", intval);
-	  *retcode += 16;
+	  *retcode += 12;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_shaded_relief (style, &intval, &value) != RL2_OK)
+    if (rl2_get_raster_symbolizer_shaded_relief (symbolizer, &intval, &value) !=
+	RL2_OK)
       {
 	  fprintf (stderr, "Unable to get ShadedRelief BrightnessOnly\n");
-	  *retcode += 17;
+	  *retcode += 13;
 	  return 0;
       }
     if (strcmp (coverage, "dumb1") == 0)
@@ -580,14 +584,14 @@ test_symbolizer_1 (sqlite3 * db_handle, const char *coverage,
 	    {
 		fprintf (stderr, "Unexpected ShadedRelief BrightnessOnly %d\n",
 			 intval);
-		*retcode += 18;
+		*retcode += 14;
 		return 0;
 	    }
 	  if (value != 55.0)
 	    {
 		fprintf (stderr, "Unexpected ShadedRelief ReliefFactor %1.2f\n",
 			 value);
-		*retcode += 18;
+		*retcode += 15;
 		return 0;
 	    }
       }
@@ -597,98 +601,101 @@ test_symbolizer_1 (sqlite3 * db_handle, const char *coverage,
 	    {
 		fprintf (stderr, "Unexpected ShadedRelief BrightnessOnly %d\n",
 			 intval);
-		*retcode += 18;
+		*retcode += 16;
 		return 0;
 	    }
 	  if (value != 33.5)
 	    {
 		fprintf (stderr, "Unexpected ShadedRelief ReliefFactor %1.2f\n",
 			 value);
-		*retcode += 18;
+		*retcode += 17;
 		return 0;
 	    }
       }
 
-    if (rl2_has_raster_style_color_map_interpolated (style, &intval) != RL2_OK)
+    if (rl2_has_raster_symbolizer_color_map_interpolated (symbolizer, &intval)
+	!= RL2_OK)
       {
 	  fprintf (stderr, "Unable to get HasColorMapInterpolated\n");
-	  *retcode += 19;
+	  *retcode += 18;
 	  return 0;
       }
     if (intval != 0)
       {
 	  fprintf (stderr, "Unexpected HasColorMapInterpolated %d\n", intval);
-	  *retcode += 20;
+	  *retcode += 19;
 	  return 0;
       }
 
-    if (rl2_has_raster_style_color_map_categorized (style, &intval) != RL2_OK)
+    if (rl2_has_raster_symbolizer_color_map_categorized (symbolizer, &intval) !=
+	RL2_OK)
       {
 	  fprintf (stderr, "Unable to get HasColorMapCategorized\n");
-	  *retcode += 21;
+	  *retcode += 20;
 	  return 0;
       }
     if (intval != 1)
       {
 	  fprintf (stderr, "Unexpected HasColorMapCategorized %d\n", intval);
-	  *retcode += 22;
+	  *retcode += 21;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_color_map_default (style, &red, &green, &blue) !=
-	RL2_OK)
+    if (rl2_get_raster_symbolizer_color_map_default
+	(symbolizer, &red, &green, &blue) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to get ColorMapDefault\n");
-	  *retcode += 23;
+	  *retcode += 22;
 	  return 0;
       }
     if (red != 0x78 || green != 0xc8 || blue != 0x18)
       {
 	  fprintf (stderr, "Unexpected ColorMapDefault #%02x%02x%02x\n", red,
 		   green, blue);
-	  *retcode += 24;
+	  *retcode += 23;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_color_map_category_base
-	(style, &red, &green, &blue) != RL2_OK)
+    if (rl2_get_raster_symbolizer_color_map_category_base
+	(symbolizer, &red, &green, &blue) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to get ColorMapCategoryBase\n");
-	  *retcode += 25;
+	  *retcode += 24;
 	  return 0;
       }
     if (red != 0x00 || green != 0xff || blue != 0x00)
       {
 	  fprintf (stderr, "Unexpected ColorMapCategoryBase #%02x%02x%02x\n",
 		   red, green, blue);
-	  *retcode += 26;
+	  *retcode += 25;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_color_map_count (style, &intval) != RL2_OK)
+    if (rl2_get_raster_symbolizer_color_map_count (symbolizer, &intval) !=
+	RL2_OK)
       {
 	  fprintf (stderr, "Unable to get ColorMapCount\n");
-	  *retcode += 27;
+	  *retcode += 26;
 	  return 0;
       }
     if (intval != 19)
       {
 	  fprintf (stderr, "Unexpected ColorMapCount %d\n", intval);
-	  *retcode += 28;
+	  *retcode += 27;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_color_map_entry
-	(style, 3, &value, &red, &green, &blue) != RL2_OK)
+    if (rl2_get_raster_symbolizer_color_map_entry
+	(symbolizer, 3, &value, &red, &green, &blue) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to get ColorMapEntry (3)\n");
-	  *retcode += 29;
+	  *retcode += 28;
 	  return 0;
       }
     if (value != -167)
       {
 	  fprintf (stderr, "Unexpected ColorMapEntry (3) %1.2f\n", value);
-	  *retcode += 30;
+	  *retcode += 29;
 	  return 0;
       }
     if (red != 0x3c || green != 0xf5 || blue != 0x05)
@@ -699,8 +706,8 @@ test_symbolizer_1 (sqlite3 * db_handle, const char *coverage,
 	  return 0;
       }
 
-    if (rl2_get_raster_style_color_map_entry
-	(style, 13, &value, &red, &green, &blue) != RL2_OK)
+    if (rl2_get_raster_symbolizer_color_map_entry
+	(symbolizer, 13, &value, &red, &green, &blue) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to get ColorMapEntry (13)\n");
 	  *retcode += 31;
@@ -720,23 +727,24 @@ test_symbolizer_1 (sqlite3 * db_handle, const char *coverage,
 	  return 0;
       }
 
-    if (rl2_get_raster_style_color_map_entry
-	(style, 30, &value, &red, &green, &blue) == RL2_OK)
+    if (rl2_get_raster_symbolizer_color_map_entry
+	(symbolizer, 30, &value, &red, &green, &blue) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected success: ColorMapEntry (30)\n");
 	  *retcode += 34;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_triple_band_selection (style, &red, &green, &blue)
-	== RL2_OK)
+    if (rl2_get_raster_symbolizer_triple_band_selection
+	(symbolizer, &red, &green, &blue) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected success: TripleBand selection\n");
 	  *retcode += 35;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_mono_band_selection (style, &red) != RL2_OK)
+    if (rl2_get_raster_symbolizer_mono_band_selection (symbolizer, &red) !=
+	RL2_OK)
       {
 	  fprintf (stderr, "Unable to get MonoBand selection\n");
 	  *retcode += 36;
@@ -745,58 +753,58 @@ test_symbolizer_1 (sqlite3 * db_handle, const char *coverage,
     if (red != 0)
       {
 	  fprintf (stderr, "Unexpected MonoBand selection: %d\n", intval);
-	  *retcode += 36;
+	  *retcode += 37;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_color_map_count (NULL, &intval) == RL2_OK)
+    if (rl2_get_raster_symbolizer_color_map_count (NULL, &intval) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected ColorMapCount\n");
 	  *retcode += 38;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_color_map_default (NULL, &red, &green, &blue) ==
-	RL2_OK)
+    if (rl2_get_raster_symbolizer_color_map_default (NULL, &red, &green, &blue)
+	== RL2_OK)
       {
 	  fprintf (stderr, "Unexpected ColorMapDefault\n");
 	  *retcode += 39;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_gray_band_contrast_enhancement
-	(style, &enhancement, &value) == RL2_OK)
+    if (rl2_get_raster_symbolizer_gray_band_contrast_enhancement
+	(symbolizer, &enhancement, &value) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected GrayBandContrastEnhancement\n");
 	  *retcode += 40;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_red_band_contrast_enhancement
-	(style, &enhancement, &value) == RL2_OK)
+    if (rl2_get_raster_symbolizer_red_band_contrast_enhancement
+	(symbolizer, &enhancement, &value) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected RedBandContrastEnhancement\n");
 	  *retcode += 41;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_green_band_contrast_enhancement
-	(style, &enhancement, &value) == RL2_OK)
+    if (rl2_get_raster_symbolizer_green_band_contrast_enhancement
+	(symbolizer, &enhancement, &value) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected GreenBandContrastEnhancement\n");
 	  *retcode += 42;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_blue_band_contrast_enhancement
-	(style, &enhancement, &value) == RL2_OK)
+    if (rl2_get_raster_symbolizer_blue_band_contrast_enhancement
+	(symbolizer, &enhancement, &value) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected BlueBandContrastEnhancement\n");
 	  *retcode += 43;
 	  return 0;
       }
 
-    rl2_destroy_raster_style (style);
+    rl2_destroy_coverage_style (style);
     return 1;
 }
 
@@ -805,15 +813,18 @@ test_symbolizer_2 (sqlite3 * db_handle, const char *coverage,
 		   const char *style_name, int *retcode)
 {
 /* testing a RasterSymbolizer */
-    rl2RasterStylePtr style;
-    const char *string;
+    rl2CoverageStylePtr style;
+    rl2RasterSymbolizerPtr symbolizer;
     double value;
     int intval;
+    int categorize;
+    int interpolate;
     unsigned char enhancement;
     unsigned char red;
     unsigned char green;
     unsigned char blue;
-    style = rl2_create_raster_style_from_dbms (db_handle, coverage, style_name);
+    style =
+	rl2_create_coverage_style_from_dbms (db_handle, coverage, style_name);
     if (style == NULL)
       {
 	  fprintf (stderr, "Unable to retrieve style '%s'\n", style_name);
@@ -821,285 +832,257 @@ test_symbolizer_2 (sqlite3 * db_handle, const char *coverage,
 	  return 0;
       }
 
-    if (strcmp (coverage, "dumb1") == 0)
+    symbolizer = rl2_get_symbolizer_from_coverage_style (style, 1.0);
+    if (symbolizer == NULL)
       {
-	  string = rl2_get_raster_style_name (style);
-	  if (string == NULL)
-	    {
-		fprintf (stderr, "Unexpected NULL style name (%s)\n",
-			 style_name);
-		*retcode += 1;
-		return 0;
-	    }
-	  if (strcmp (string, "style2") != 0)
-	    {
-		fprintf (stderr, "Unexpected style name \"%s\"\n", string);
-		*retcode += 2;
-		return 0;
-	    }
-
-	  string = rl2_get_raster_style_title (style);
-	  if (string == NULL)
-	    {
-		fprintf (stderr, "Unexpected NULL style title (%s)\n",
-			 style_name);
-		*retcode += 3;
-		return 0;
-	    }
-	  if (strcmp (string, "title: second style") != 0)
-	    {
-		fprintf (stderr, "Unexpected style title \"%s\"\n", string);
-		*retcode += 4;
-		return 0;
-	    }
-
-	  string = rl2_get_raster_style_abstract (style);
-	  if (string != NULL)
-	    {
-		fprintf (stderr, "Unexpected NOT NULL style abstract (%s)\n",
-			 style_name);
-		*retcode += 5;
-		return 0;
-	    }
+	  fprintf (stderr, "Unexpected NULL RasterSymbolizer (%s)\n",
+		   style_name);
+	  *retcode += 2;
+	  return 0;
       }
 
-    if (rl2_get_raster_style_opacity (style, &value) != RL2_OK)
+    if (rl2_get_raster_symbolizer_opacity (symbolizer, &value) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to get Opacity\n");
-	  *retcode += 6;
+	  *retcode += 3;
 	  return 0;
       }
     if (value != 0.8)
       {
 	  fprintf (stderr, "Unexpected Opacity %1.2f\n", value);
-	  *retcode += 7;
+	  *retcode += 4;
 	  return 0;
       }
 
-    if (rl2_is_raster_style_triple_band_selected (style, &intval) != RL2_OK)
+    if (rl2_is_raster_symbolizer_triple_band_selected (symbolizer, &intval) !=
+	RL2_OK)
       {
 	  fprintf (stderr, "Unable to get IsTripleBandSelected\n");
-	  *retcode += 8;
+	  *retcode += 5;
 	  return 0;
       }
     if (intval != 1)
       {
 	  fprintf (stderr, "Unexpected IsTripleBandSelected %d\n", intval);
-	  *retcode += 9;
+	  *retcode += 6;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_red_band_contrast_enhancement
-	(style, &enhancement, &value) != RL2_OK)
+    if (rl2_get_raster_symbolizer_red_band_contrast_enhancement
+	(symbolizer, &enhancement, &value) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to get RedBandContrastEnhancement\n");
-	  *retcode += 10;
+	  *retcode += 7;
 	  return 0;
       }
     if (enhancement != RL2_CONTRAST_ENHANCEMENT_HISTOGRAM)
       {
 	  fprintf (stderr, "Unexpected RedBandContrastEnhancement %02x\n",
 		   enhancement);
-	  *retcode += 11;
+	  *retcode += 8;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_green_band_contrast_enhancement
-	(style, &enhancement, &value) != RL2_OK)
+    if (rl2_get_raster_symbolizer_green_band_contrast_enhancement
+	(symbolizer, &enhancement, &value) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to get GreenBandContrastEnhancement\n");
-	  *retcode += 12;
+	  *retcode += 9;
 	  return 0;
       }
     if (enhancement != RL2_CONTRAST_ENHANCEMENT_GAMMA)
       {
 	  fprintf (stderr, "Unexpected GreenBandContrastEnhancement %02x\n",
 		   enhancement);
-	  *retcode += 13;
+	  *retcode += 10;
 	  return 0;
       }
     if (value != 2.5)
       {
 	  fprintf (stderr, "Unexpected GreenBandContrastEnhancement %1.2f\n",
 		   value);
-	  *retcode += 14;
+	  *retcode += 11;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_blue_band_contrast_enhancement
-	(style, &enhancement, &value) != RL2_OK)
+    if (rl2_get_raster_symbolizer_blue_band_contrast_enhancement
+	(symbolizer, &enhancement, &value) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to get BlueBandContrastEnhancement\n");
-	  *retcode += 15;
+	  *retcode += 12;
 	  return 0;
       }
     if (enhancement != RL2_CONTRAST_ENHANCEMENT_NORMALIZE)
       {
 	  fprintf (stderr, "Unexpected BlueBandContrastEnhancement %02x\n",
 		   enhancement);
-	  *retcode += 16;
+	  *retcode += 13;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_overall_contrast_enhancement
-	(style, &enhancement, &value) != RL2_OK)
+    if (rl2_get_raster_symbolizer_overall_contrast_enhancement
+	(symbolizer, &enhancement, &value) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to get OverallContrastEnhancement\n");
-	  *retcode += 17;
+	  *retcode += 14;
 	  return 0;
       }
     if (enhancement != RL2_CONTRAST_ENHANCEMENT_GAMMA)
       {
 	  fprintf (stderr, "Unexpected OverallContrastEnhancement %02x\n",
 		   enhancement);
-	  *retcode += 18;
+	  *retcode += 15;
 	  return 0;
       }
     if (value != 1.2)
       {
 	  fprintf (stderr, "Unexpected OverallContrastEnhancement %1.2f\n",
 		   value);
-	  *retcode += 19;
+	  *retcode += 16;
 	  return 0;
       }
 
-    if (rl2_has_raster_style_shaded_relief (style, &intval) != RL2_OK)
+    if (rl2_has_raster_symbolizer_shaded_relief (symbolizer, &intval) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to get HasShadedRelief\n");
-	  *retcode += 20;
+	  *retcode += 17;
 	  return 0;
       }
     if (intval != 0)
       {
 	  fprintf (stderr, "Unexpected HasShadedRelief %d\n", intval);
-	  *retcode += 21;
+	  *retcode += 18;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_shaded_relief (style, &intval, &value) == RL2_OK)
+    if (rl2_get_raster_symbolizer_shaded_relief (symbolizer, &intval, &value) ==
+	RL2_OK)
       {
 	  fprintf (stderr, "Unexpected success: ShadedRelief\n");
-	  *retcode += 22;
+	  *retcode += 19;
 	  return 0;
       }
 
-    if (rl2_has_raster_style_color_map_interpolated (style, &intval) != RL2_OK)
+    if (rl2_has_raster_symbolizer_color_map_interpolated (symbolizer, &intval)
+	!= RL2_OK)
       {
 	  fprintf (stderr, "Unable to get HasColorMapInterpolated\n");
-	  *retcode += 23;
+	  *retcode += 20;
 	  return 0;
       }
     if (intval != 1)
       {
 	  fprintf (stderr, "Unexpected HasColorMapInterpolated %d\n", intval);
-	  *retcode += 24;
+	  *retcode += 21;
 	  return 0;
       }
 
-    if (rl2_has_raster_style_color_map_categorized (style, &intval) != RL2_OK)
+    if (rl2_has_raster_symbolizer_color_map_categorized (symbolizer, &intval) !=
+	RL2_OK)
       {
 	  fprintf (stderr, "Unable to get HasColorMapCategorized\n");
-	  *retcode += 25;
+	  *retcode += 22;
 	  return 0;
       }
     if (intval != 0)
       {
 	  fprintf (stderr, "Unexpected HasColorMapCategorized %d\n", intval);
-	  *retcode += 26;
+	  *retcode += 23;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_color_map_default (style, &red, &green, &blue) !=
-	RL2_OK)
+    if (rl2_get_raster_symbolizer_color_map_default
+	(symbolizer, &red, &green, &blue) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to get ColorMapDefault\n");
-	  *retcode += 27;
+	  *retcode += 24;
 	  return 0;
       }
     if (red != 0xdd || green != 0xdd || blue != 0xdd)
       {
 	  fprintf (stderr, "Unexpected ColorMapDefault #%02x%02x%02x\n", red,
 		   green, blue);
-	  *retcode += 28;
+	  *retcode += 25;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_color_map_category_base
-	(style, &red, &green, &blue) == RL2_OK)
+    if (rl2_get_raster_symbolizer_color_map_category_base
+	(symbolizer, &red, &green, &blue) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected success: get ColorMapCategoryBase\n");
-	  *retcode += 29;
+	  *retcode += 26;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_color_map_count (style, &intval) != RL2_OK)
+    if (rl2_get_raster_symbolizer_color_map_count (symbolizer, &intval) !=
+	RL2_OK)
       {
 	  fprintf (stderr, "Unable to get ColorMapCount\n");
-	  *retcode += 30;
+	  *retcode += 27;
 	  return 0;
       }
     if (intval != 2)
       {
 	  fprintf (stderr, "Unexpected ColorMapCount %d\n", intval);
-	  *retcode += 31;
+	  *retcode += 28;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_color_map_entry
-	(style, 0, &value, &red, &green, &blue) != RL2_OK)
+    if (rl2_get_raster_symbolizer_color_map_entry
+	(symbolizer, 0, &value, &red, &green, &blue) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to get ColorMapEntry (0)\n");
-	  *retcode += 32;
+	  *retcode += 29;
 	  return 0;
       }
     if (value != 0)
       {
 	  fprintf (stderr, "Unexpected ColorMapEntry (0) %1.2f\n", value);
-	  *retcode += 33;
+	  *retcode += 30;
 	  return 0;
       }
     if (red != 0x00 || green != 0x00 || blue != 0x00)
       {
 	  fprintf (stderr, "Unexpected ColorMapEntry (0) #%02x%02x%02x\n", red,
 		   green, blue);
-	  *retcode += 34;
+	  *retcode += 31;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_color_map_entry
-	(style, 1, &value, &red, &green, &blue) != RL2_OK)
+    if (rl2_get_raster_symbolizer_color_map_entry
+	(symbolizer, 1, &value, &red, &green, &blue) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to get ColorMapEntry (1)\n");
-	  *retcode += 35;
+	  *retcode += 32;
 	  return 0;
       }
     if (value != 255)
       {
 	  fprintf (stderr, "Unexpected ColorMapEntry (1) %1.2f\n", value);
-	  *retcode += 36;
+	  *retcode += 33;
 	  return 0;
       }
     if (red != 0xff || green != 0xff || blue != 0xff)
       {
 	  fprintf (stderr, "Unexpected ColorMapEntry (1) #%02x%02x%02x\n", red,
 		   green, blue);
-	  *retcode += 37;
+	  *retcode += 34;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_color_map_entry
-	(style, 2, &value, &red, &green, &blue) == RL2_OK)
+    if (rl2_get_raster_symbolizer_color_map_entry
+	(symbolizer, 2, &value, &red, &green, &blue) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected success: ColorMapEntry (2)\n");
-	  *retcode += 38;
+	  *retcode += 35;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_triple_band_selection (style, &red, &green, &blue)
-	!= RL2_OK)
+    if (rl2_get_raster_symbolizer_triple_band_selection
+	(symbolizer, &red, &green, &blue) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to get TripleBand selection\n");
-	  *retcode += 35;
+	  *retcode += 36;
 	  return 0;
       }
     if (red == 0 && green == 1 && blue == 2)
@@ -1108,39 +1091,41 @@ test_symbolizer_2 (sqlite3 * db_handle, const char *coverage,
       {
 	  fprintf (stderr, "Unexpected TripleBand %d,%d,%d\n", red, green,
 		   blue);
-	  *retcode += 36;
+	  *retcode += 37;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_mono_band_selection (style, &red) == RL2_OK)
+    if (rl2_get_raster_symbolizer_mono_band_selection (symbolizer, &red) ==
+	RL2_OK)
       {
 	  fprintf (stderr, "Unexpected success: MonoBand selection\n");
-	  *retcode += 36;
+	  *retcode += 38;
 	  return 0;
       }
 
-    if (rl2_is_raster_style_mono_band_selected (style, &intval) != RL2_OK)
+    if (rl2_is_raster_symbolizer_mono_band_selected
+	(symbolizer, &intval, &categorize, &interpolate) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to get IsMonoBandSelected\n");
-	  *retcode += 37;
+	  *retcode += 39;
 	  return 0;
       }
     if (intval != 0)
       {
 	  fprintf (stderr, "Unexpected IsMonoBandSelected %d\n", intval);
-	  *retcode += 38;
+	  *retcode += 40;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_gray_band_contrast_enhancement
-	(style, &enhancement, &value) == RL2_OK)
+    if (rl2_get_raster_symbolizer_gray_band_contrast_enhancement
+	(symbolizer, &enhancement, &value) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected GrayBandContrastEnhancement\n");
-	  *retcode += 39;
+	  *retcode += 41;
 	  return 0;
       }
 
-    rl2_destroy_raster_style (style);
+    rl2_destroy_coverage_style (style);
     return 1;
 }
 
@@ -1149,14 +1134,18 @@ test_symbolizer_3 (sqlite3 * db_handle, const char *coverage,
 		   const char *style_name, int *retcode)
 {
 /* testing a RasterSymbolizer */
-    rl2RasterStylePtr style;
+    rl2CoverageStylePtr style;
+    rl2RasterSymbolizerPtr symbolizer;
     unsigned char enhancement;
     unsigned char red;
     unsigned char green;
     unsigned char blue;
     int intval;
+    int categorize;
+    int interpolate;
     double value;
-    style = rl2_create_raster_style_from_dbms (db_handle, coverage, style_name);
+    style =
+	rl2_create_coverage_style_from_dbms (db_handle, coverage, style_name);
     if (style == NULL)
       {
 	  fprintf (stderr, "Unable to retrieve style '%s'\n", style_name);
@@ -1164,315 +1153,385 @@ test_symbolizer_3 (sqlite3 * db_handle, const char *coverage,
 	  return 0;
       }
 
-    if (rl2_get_raster_style_triple_band_selection (style, &red, &green, &blue)
-	== RL2_OK)
+    symbolizer = rl2_get_symbolizer_from_coverage_style (style, 1.0);
+    if (symbolizer == NULL)
       {
-	  fprintf (stderr, "Unexpected success: TripleBand selection\n");
+	  fprintf (stderr, "Unexpected NULL RasterSymbolizer (%s)\n",
+		   style_name);
 	  *retcode += 2;
 	  return 0;
       }
 
-    if (rl2_is_raster_style_mono_band_selected (style, &intval) != RL2_OK)
+    if (rl2_get_raster_symbolizer_triple_band_selection
+	(symbolizer, &red, &green, &blue) == RL2_OK)
       {
-	  fprintf (stderr, "Unable to get IsMonoBandSelected\n");
+	  fprintf (stderr, "Unexpected success: TripleBand selection\n");
 	  *retcode += 3;
 	  return 0;
       }
+
+    if (rl2_is_raster_symbolizer_mono_band_selected
+	(symbolizer, &intval, &categorize, &interpolate) != RL2_OK)
+      {
+	  fprintf (stderr, "Unable to get IsMonoBandSelected\n");
+	  *retcode += 4;
+	  return 0;
+      }
     if (intval != 1)
       {
 	  fprintf (stderr, "Unexpected IsMonoBandSelected %d\n", intval);
-	  *retcode += 4;
+	  *retcode += 5;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_mono_band_selection (style, &red) != RL2_OK)
+    if (rl2_get_raster_symbolizer_mono_band_selection (symbolizer, &red) !=
+	RL2_OK)
       {
 	  fprintf (stderr, "Unable to get MonoBand selection\n");
-	  *retcode += 5;
+	  *retcode += 6;
 	  return 0;
       }
     if (red != 0)
       {
 	  fprintf (stderr, "Unexpected MonoBand %d\n", red);
-	  *retcode += 4;
+	  *retcode += 7;
 	  return 0;
       }
 
-    if (rl2_is_raster_style_triple_band_selected (style, &intval) != RL2_OK)
+    if (rl2_is_raster_symbolizer_triple_band_selected (symbolizer, &intval) !=
+	RL2_OK)
       {
 	  fprintf (stderr, "Unable to get IsTripleBandSelected\n");
-	  *retcode += 5;
+	  *retcode += 8;
 	  return 0;
       }
     if (intval != 0)
       {
 	  fprintf (stderr, "Unexpected IsMonoBandSelected %d\n", intval);
-	  *retcode += 6;
+	  *retcode += 9;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_gray_band_contrast_enhancement
-	(style, &enhancement, &value) != RL2_OK)
+    if (rl2_get_raster_symbolizer_gray_band_contrast_enhancement
+	(symbolizer, &enhancement, &value) != RL2_OK)
       {
 	  fprintf (stderr, "Unable to get GrayBandContrastEnhancement\n");
-	  *retcode += 7;
+	  *retcode += 10;
 	  return 0;
       }
     if (enhancement != RL2_CONTRAST_ENHANCEMENT_NONE)
       {
 	  fprintf (stderr, "Unexpected GrayBandContrastEnhancement %02x\n",
 		   enhancement);
-	  *retcode += 8;
+	  *retcode += 11;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_green_band_contrast_enhancement
-	(style, &enhancement, &value) == RL2_OK)
+    if (rl2_get_raster_symbolizer_green_band_contrast_enhancement
+	(symbolizer, &enhancement, &value) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected GreenBandContrastEnhancement\n");
-	  *retcode += 9;
+	  *retcode += 12;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_blue_band_contrast_enhancement
-	(style, &enhancement, &value) == RL2_OK)
+    if (rl2_get_raster_symbolizer_blue_band_contrast_enhancement
+	(symbolizer, &enhancement, &value) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected BlueBandContrastEnhancement\n");
-	  *retcode += 10;
+	  *retcode += 13;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_red_band_contrast_enhancement
-	(style, &enhancement, &value) == RL2_OK)
+    if (rl2_get_raster_symbolizer_red_band_contrast_enhancement
+	(symbolizer, &enhancement, &value) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected RedBandContrastEnhancement\n");
-	  *retcode += 11;
+	  *retcode += 14;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_green_band_contrast_enhancement
-	(style, &enhancement, &value) == RL2_OK)
+    if (rl2_get_raster_symbolizer_green_band_contrast_enhancement
+	(symbolizer, &enhancement, &value) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected GreenBandContrastEnhancement\n");
-	  *retcode += 12;
+	  *retcode += 15;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_blue_band_contrast_enhancement
-	(style, &enhancement, &value) == RL2_OK)
+    if (rl2_get_raster_symbolizer_blue_band_contrast_enhancement
+	(symbolizer, &enhancement, &value) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected BlueBandContrastEnhancement\n");
-	  *retcode += 13;
+	  *retcode += 16;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_color_map_count (style, &intval) == RL2_OK)
+    if (rl2_get_raster_symbolizer_color_map_count (symbolizer, &intval) ==
+	RL2_OK)
       {
 	  fprintf (stderr, "Unexpected ColorMapCount\n");
-	  *retcode += 14;
+	  *retcode += 17;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_color_map_default (style, &red, &green, &blue) ==
-	RL2_OK)
+    if (rl2_get_raster_symbolizer_color_map_default
+	(symbolizer, &red, &green, &blue) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected ColorMapDefault\n");
-	  *retcode += 15;
+	  *retcode += 18;
 	  return 0;
       }
 
-    rl2_destroy_raster_style (style);
+    rl2_destroy_coverage_style (style);
     return 1;
 }
 
 static int
-test_symbolizer_null (int *retcode)
+test_coverage_style (sqlite3 * db_handle, const char *coverage,
+		     const char *style_name, int *retcode)
 {
-/* testing a NULL RasterSymbolizer */
-    const char *string;
-    double value;
-    int intval;
-    unsigned char enhancement;
-    unsigned char red;
-    unsigned char green;
-    unsigned char blue;
-
-    string = rl2_get_raster_style_name (NULL);
-    if (string != NULL)
+/* testing a complex Coverage Style */
+    rl2CoverageStylePtr style;
+    rl2RasterSymbolizerPtr symbolizer;
+    const char *name;
+    style =
+	rl2_create_coverage_style_from_dbms (db_handle, coverage, style_name);
+    if (style == NULL)
       {
-	  fprintf (stderr, "Unexpected style name\n");
+	  fprintf (stderr, "Unable to retrieve style '%s'\n", style_name);
 	  *retcode += 1;
 	  return 0;
       }
 
-    string = rl2_get_raster_style_title (NULL);
-    if (string != NULL)
+    name = rl2_get_coverage_style_name (style);
+    if (name == NULL)
       {
-	  fprintf (stderr, "Unexpected style title\n");
+	  fprintf (stderr, "Unexpected NULL Coverage Style name (%s)\n",
+		   style_name);
 	  *retcode += 2;
 	  return 0;
       }
+    if (strcmp (name, style_name) != 0)
+	if (name == NULL)
+	  {
+	      fprintf (stderr, "Unexpected Coverage Style name (%s): %s\n",
+		       style_name, name);
+	      *retcode += 3;
+	      return 0;
+	  }
 
-    string = rl2_get_raster_style_abstract (NULL);
-    if (string != NULL)
+    symbolizer = rl2_get_symbolizer_from_coverage_style (style, 100000.0);
+    if (symbolizer == NULL)
       {
-	  fprintf (stderr, "Unexpected style abstract\n");
-	  *retcode += 3;
+	  fprintf (stderr, "Unexpected NULL RasterSymbolizer (%s 100K)\n",
+		   style_name);
+	  *retcode += 4;
+	  return 0;
+      }
+
+    symbolizer = rl2_get_symbolizer_from_coverage_style (style, 5000000.0);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL RasterSymbolizer (%s 5M)\n",
+		   style_name);
+	  *retcode += 5;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_opacity (NULL, &value) == RL2_OK)
+    symbolizer = rl2_get_symbolizer_from_coverage_style (style, 15000000.0);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL RasterSymbolizer (%s 15M)\n",
+		   style_name);
+	  *retcode += 6;
+	  return 0;
+      }
+
+    return 1;
+}
+
+static int
+test_symbolizer_null (int *retcode)
+{
+/* testing a NULL RasterSymbolizer */
+    double value;
+    int intval;
+    int categorize;
+    int interpolate;
+    unsigned char enhancement;
+    unsigned char red;
+    unsigned char green;
+    unsigned char blue;
+
+    if (rl2_get_raster_symbolizer_opacity (NULL, &value) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected Opacity\n");
-	  *retcode += 4;
+	  *retcode += 1;
 	  return 0;
       }
 
-    if (rl2_is_raster_style_mono_band_selected (NULL, &intval) == RL2_OK)
+    if (rl2_is_raster_symbolizer_mono_band_selected
+	(NULL, &intval, &categorize, &interpolate) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected IsMonoBandSelected\n");
-	  *retcode += 5;
+	  *retcode += 2;
 	  return 0;
       }
 
-    if (rl2_is_raster_style_triple_band_selected (NULL, &intval) == RL2_OK)
+    if (rl2_is_raster_symbolizer_triple_band_selected (NULL, &intval) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected IsTripleBandSelected\n");
-	  *retcode += 6;
+	  *retcode += 3;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_overall_contrast_enhancement
+    if (rl2_get_raster_symbolizer_overall_contrast_enhancement
 	(NULL, &enhancement, &value) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected OverallContrastEnhancement\n");
-	  *retcode += 7;
+	  *retcode += 4;
 	  return 0;
       }
 
-    if (rl2_has_raster_style_shaded_relief (NULL, &intval) == RL2_OK)
+    if (rl2_has_raster_symbolizer_shaded_relief (NULL, &intval) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected HasShadedRelief\n");
-	  *retcode += 8;
+	  *retcode += 5;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_shaded_relief (NULL, &intval, &value) == RL2_OK)
+    if (rl2_get_raster_symbolizer_shaded_relief (NULL, &intval, &value) ==
+	RL2_OK)
       {
 	  fprintf (stderr, "Unexpected ShadedRelief BrightnessOnly\n");
-	  *retcode += 9;
+	  *retcode += 6;
 	  return 0;
       }
 
-    if (rl2_has_raster_style_color_map_interpolated (NULL, &intval) == RL2_OK)
+    if (rl2_has_raster_symbolizer_color_map_interpolated (NULL, &intval) ==
+	RL2_OK)
       {
 	  fprintf (stderr, "Unexpected HasColorMapInterpolated\n");
-	  *retcode += 10;
+	  *retcode += 7;
 	  return 0;
       }
 
-    if (rl2_has_raster_style_color_map_categorized (NULL, &intval) == RL2_OK)
+    if (rl2_has_raster_symbolizer_color_map_categorized (NULL, &intval) ==
+	RL2_OK)
       {
 	  fprintf (stderr, "Unexpected HasColorMapCategorized\n");
-	  *retcode += 11;
+	  *retcode += 8;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_color_map_default (NULL, &red, &green, &blue) ==
-	RL2_OK)
+    if (rl2_get_raster_symbolizer_color_map_default (NULL, &red, &green, &blue)
+	== RL2_OK)
       {
 	  fprintf (stderr, "Unexpected ColorMapDefault\n");
-	  *retcode += 12;
+	  *retcode += 9;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_color_map_category_base
+    if (rl2_get_raster_symbolizer_color_map_category_base
 	(NULL, &red, &green, &blue) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected ColorMapCategoryBase\n");
-	  *retcode += 13;
+	  *retcode += 10;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_color_map_count (NULL, &intval) == RL2_OK)
+    if (rl2_get_raster_symbolizer_color_map_count (NULL, &intval) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected ColorMapCount\n");
-	  *retcode += 14;
+	  *retcode += 11;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_color_map_entry
+    if (rl2_get_raster_symbolizer_color_map_entry
 	(NULL, 3, &value, &red, &green, &blue) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected ColorMapEntry\n");
-	  *retcode += 15;
+	  *retcode += 12;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_triple_band_selection (NULL, &red, &green, &blue)
-	== RL2_OK)
+    if (rl2_get_raster_symbolizer_triple_band_selection
+	(NULL, &red, &green, &blue) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected success: TripleBand selection\n");
-	  *retcode += 16;
+	  *retcode += 13;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_mono_band_selection (NULL, &red) == RL2_OK)
+    if (rl2_get_raster_symbolizer_mono_band_selection (NULL, &red) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected success: MonoBand selection\n");
-	  *retcode += 17;
+	  *retcode += 14;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_red_band_contrast_enhancement
+    if (rl2_get_raster_symbolizer_red_band_contrast_enhancement
 	(NULL, &enhancement, &value) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected RedBandContrastEnhancement\n");
-	  *retcode += 18;
+	  *retcode += 15;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_green_band_contrast_enhancement
+    if (rl2_get_raster_symbolizer_green_band_contrast_enhancement
 	(NULL, &enhancement, &value) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected GreenBandContrastEnhancement\n");
-	  *retcode += 19;
+	  *retcode += 16;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_blue_band_contrast_enhancement
+    if (rl2_get_raster_symbolizer_blue_band_contrast_enhancement
 	(NULL, &enhancement, &value) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected BlueBandContrastEnhancement\n");
-	  *retcode += 20;
+	  *retcode += 17;
 	  return 0;
       }
 
-    if (rl2_get_raster_style_gray_band_contrast_enhancement
+    if (rl2_get_raster_symbolizer_gray_band_contrast_enhancement
 	(NULL, &enhancement, &value) == RL2_OK)
       {
 	  fprintf (stderr, "Unexpected GrayBandContrastEnhancement\n");
-	  *retcode += 21;
+	  *retcode += 18;
 	  return 0;
       }
 
-    rl2_destroy_raster_style (NULL);
+    rl2_destroy_coverage_style (NULL);
     return 1;
 }
 
 int
 main (int argc, char *argv[])
 {
+    int no_web_connection = 0;
     int result = 0;
     int ret;
     char *err_msg = NULL;
     sqlite3 *db_handle;
     void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
     char *old_SPATIALITE_SECURITY_ENV = NULL;
 
     if (argc > 1 || argv[0] == NULL)
 	argc = 1;		/* silencing stupid compiler warnings */
 
+    if (getenv ("ENABLE_RL2_WEB_TESTS") == NULL)
+      {
+	  fprintf (stderr,
+		   "this testcase has been executed with several limitations\n"
+		   "because it was not enabled to access the Web.\n\n"
+		   "you can enable all testcases requiring an Internet connection\n"
+		   "by setting the environment variable \"ENABLE_RL2_WEB_TESTS=1\"\n\n");
+	  no_web_connection = 1;
+      }
+
     old_SPATIALITE_SECURITY_ENV = getenv ("SPATIALITE_SECURITY");
 #ifdef _WIN32
     putenv ("SPATIALITE_SECURITY=relaxed");
@@ -1490,7 +1549,7 @@ main (int argc, char *argv[])
 	  return -1;
       }
     spatialite_init_ex (db_handle, cache, 0);
-    rl2_init (db_handle, 0);
+    rl2_init (db_handle, priv_data, 0);
     ret =
 	sqlite3_exec (db_handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
 		      &err_msg);
@@ -1510,39 +1569,46 @@ main (int argc, char *argv[])
 	  return -3;
       }
     ret =
-	sqlite3_exec (db_handle, "SELECT RL2_CreateCoverage('dumb1', 'UINT8', "
+	sqlite3_exec (db_handle,
+		      "SELECT RL2_CreateRasterCoverage('dumb1', 'UINT8', "
 		      "'GRAYSCALE', 1, 'NONE', 100, 256, 256, 4326, 1.0)", NULL,
 		      NULL, &err_msg);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "CreateCoverage() error: %s\n", err_msg);
+	  fprintf (stderr, "CreateRasterCoverage() error: %s\n", err_msg);
 	  sqlite3_free (err_msg);
 	  return -4;
       }
     ret =
-	sqlite3_exec (db_handle, "SELECT RL2_CreateCoverage('dumb2', 'UINT8', "
+	sqlite3_exec (db_handle,
+		      "SELECT RL2_CreateRasterCoverage('dumb2', 'UINT8', "
 		      "'GRAYSCALE', 1, 'NONE', 100, 256, 256, 4326, 1.0)", NULL,
 		      NULL, &err_msg);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "CreateCoverage() error: %s\n", err_msg);
+	  fprintf (stderr, "CreateRasterCoverage() error: %s\n", err_msg);
 	  sqlite3_free (err_msg);
 	  return -5;
       }
     ret =
 	sqlite3_exec (db_handle,
-		      "SELECT RL2_CreateCoverage('dumb_dem', 'INT16', "
+		      "SELECT RL2_CreateRasterCoverage('dumb_dem', 'INT16', "
 		      "'DATAGRID', 1, 'NONE', 100, 256, 256, 4326, 1.0)", NULL,
 		      NULL, &err_msg);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "CreateCoverage() error: %s\n", err_msg);
+	  fprintf (stderr, "CreateRasterCoverage() error: %s\n", err_msg);
 	  sqlite3_free (err_msg);
 	  return -6;
       }
-    ret =
-	sqlite3_exec (db_handle, "SELECT CreateStylingTables()", NULL,
-		      NULL, &err_msg);
+    if (no_web_connection)
+	ret =
+	    sqlite3_exec (db_handle, "SELECT CreateStylingTables(1)", NULL,
+			  NULL, &err_msg);
+    else
+	ret =
+	    sqlite3_exec (db_handle, "SELECT CreateStylingTables()", NULL,
+			  NULL, &err_msg);
     if (ret != SQLITE_OK)
       {
 	  fprintf (stderr, "CreateStylingTables() error: %s\n", err_msg);
@@ -1551,46 +1617,65 @@ main (int argc, char *argv[])
       }
     ret =
 	sqlite3_exec (db_handle,
-		      "SELECT RegisterStyledGroup('my_group', 'dumb1')", NULL,
-		      NULL, &err_msg);
+		      "SELECT SE_RegisterStyledGroupRaster('my_group', 'dumb1')",
+		      NULL, NULL, &err_msg);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "RegisterStyledGroup() #1 error: %s\n", err_msg);
+	  fprintf (stderr, "RegisterStyledGroupRaster() #1 error: %s\n",
+		   err_msg);
 	  sqlite3_free (err_msg);
 	  return -8;
       }
     ret =
 	sqlite3_exec (db_handle,
-		      "SELECT RegisterStyledGroup('my_group', 'dumb_dem')",
+		      "SELECT SE_RegisterStyledGroupRaster('my_group', 'dumb_dem')",
 		      NULL, NULL, &err_msg);
     if (ret != SQLITE_OK)
       {
-	  fprintf (stderr, "RegisterStyledGroup() #2 error: %s\n", err_msg);
+	  fprintf (stderr, "RegisterStyledGroupRaster() #2 error: %s\n",
+		   err_msg);
 	  sqlite3_free (err_msg);
 	  return -9;
       }
 
 /* tests */
     ret = -100;
-    if (!load_symbolizer (db_handle, "dumb1", "raster_symbolizer_1.xml", &ret))
+    if (!load_symbolizer
+	(db_handle, "dumb1", "raster_symbolizer_1.xml", no_web_connection,
+	 &ret))
 	return ret;
     ret = -200;
-    if (!load_symbolizer (db_handle, "dumb1", "raster_symbolizer_2.xml", &ret))
+    if (!load_symbolizer
+	(db_handle, "dumb1", "raster_symbolizer_2.xml", no_web_connection,
+	 &ret))
 	return ret;
     ret = -300;
-    if (!load_symbolizer (db_handle, "dumb1", "raster_symbolizer_3.xml", &ret))
+    if (!load_symbolizer
+	(db_handle, "dumb1", "raster_symbolizer_3.xml", no_web_connection,
+	 &ret))
 	return ret;
     ret = -400;
-    if (!load_symbolizer (db_handle, "dumb2", "raster_symbolizer_4.xml", &ret))
+    if (!load_symbolizer
+	(db_handle, "dumb2", "raster_symbolizer_4.xml", no_web_connection,
+	 &ret))
 	return ret;
     ret = -500;
-    if (!load_symbolizer (db_handle, "dumb2", "raster_symbolizer_5.xml", &ret))
+    if (!load_symbolizer
+	(db_handle, "dumb2", "raster_symbolizer_5.xml", no_web_connection,
+	 &ret))
 	return ret;
     ret = -600;
-    if (!load_symbolizer (db_handle, "dumb2", "raster_symbolizer_6.xml", &ret))
+    if (!load_symbolizer
+	(db_handle, "dumb2", "raster_symbolizer_6.xml", no_web_connection,
+	 &ret))
 	return ret;
     ret = -800;
-    if (!load_symbolizer (db_handle, "dumb_dem", "srtm_brightness.xml", &ret))
+    if (!load_symbolizer
+	(db_handle, "dumb_dem", "srtm_brightness.xml", no_web_connection, &ret))
+	return ret;
+    ret = -900;
+    if (!load_symbolizer
+	(db_handle, "dumb2", "coverage_style.xml", no_web_connection, &ret))
 	return ret;
     ret = -110;
     if (!test_symbolizer_1 (db_handle, "dumb1", "style1", &ret))
@@ -1602,23 +1687,28 @@ main (int argc, char *argv[])
     if (!test_symbolizer_3 (db_handle, "dumb1", "style3", &ret))
 	return ret;
     ret = -410;
-    if (!test_symbolizer_1 (db_handle, "dumb2", "style1", &ret))
+    if (!test_symbolizer_1 (db_handle, "dumb2", "style4", &ret))
 	return ret;
     ret = -510;
-    if (!test_symbolizer_2 (db_handle, "dumb2", "style2", &ret))
+    if (!test_symbolizer_2 (db_handle, "dumb2", "style5", &ret))
 	return ret;
     ret = -610;
-    if (!test_symbolizer_3 (db_handle, "dumb2", "style3", &ret))
+    if (!test_symbolizer_3 (db_handle, "dumb2", "style6", &ret))
 	return ret;
-    ret = -710;
-    if (!test_symbolizer_null (&ret))
+    ret = -610;
+    if (!test_coverage_style (db_handle, "dumb2", "coverage_style", &ret))
 	return ret;
     ret = -810;
-    if (!test_group_style (db_handle, &ret))
+    if (!test_symbolizer_null (&ret))
+	return ret;
+    ret = -910;
+    if (!test_group_style (db_handle, no_web_connection, &ret))
 	return -ret;
 
 /* closing the DB */
     sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
     spatialite_shutdown ();
     if (old_SPATIALITE_SECURITY_ENV)
       {
diff --git a/test/test_raw.c b/test/test_raw.c
new file mode 100644
index 0000000..a108c3e
--- /dev/null
+++ b/test/test_raw.c
@@ -0,0 +1,1526 @@
+/*
+
+ test_raw.c -- RasterLite-2 Test Case
+
+ Author: Sandro Furieri <a.furieri at lqt.it>
+
+ ------------------------------------------------------------------------------
+ 
+ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ 
+ The contents of this file are subject to the Mozilla Public License Version
+ 1.1 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+ 
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the
+License.
+
+The Original Code is the RasterLite2 library
+
+The Initial Developer of the Original Code is Alessandro Furieri
+ 
+Portions created by the Initial Developer are Copyright (C) 2013
+the Initial Developer. All Rights Reserved.
+
+Contributor(s):
+
+Alternatively, the contents of this file may be used under the terms of
+either the GNU General Public License Version 2 or later (the "GPL"), or
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+in which case the provisions of the GPL or the LGPL are applicable instead
+of those above. If you wish to allow use of your version of this file only
+under the terms of either the GPL or the LGPL, and not to allow others to
+use your version of this file under the terms of the MPL, indicate your
+decision by deleting the provisions above and replace them with the notice
+and other provisions required by the GPL or the LGPL. If you do not delete
+the provisions above, a recipient may use your version of this file under
+the terms of any one of the MPL, the GPL or the LGPL.
+ 
+*/
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "sqlite3.h"
+#include "spatialite.h"
+
+#include "rasterlite2/rasterlite2.h"
+
+static int
+is_big_endian_cpu ()
+{
+/* checking if the target CPU is big-endian */
+    union cvt
+    {
+	unsigned char byte[4];
+	int int_value;
+    } convert;
+    convert.int_value = 1;
+    if (convert.byte[0] == 0)
+	return 1;
+    return 0;
+}
+
+static void
+build_grid_i8 (unsigned int width, unsigned int height, unsigned char **blob,
+	       int *blob_sz)
+{
+/* building an INT8 RAW buffer */
+    int buf_sz = width * height * sizeof (char);
+    char *buf = malloc (buf_sz);
+    char *p = buf;
+    unsigned int x;
+    unsigned int y;
+
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		if ((y % 2) == 1)
+		  {
+		      if ((x % 2) == 1)
+			  *p++ = 123;
+		      else
+			  *p++ = -98;
+		  }
+		else
+		  {
+		      if ((x % 2) == 1)
+			  *p++ = -98;
+		      else
+			  *p++ = 123;
+		  }
+	    }
+      }
+    *blob = (unsigned char *) buf;
+    *blob_sz = buf_sz;
+}
+
+static void
+build_grid_u8 (unsigned int width, unsigned int height, unsigned char **blob,
+	       int *blob_sz)
+{
+/* building an UINT8 RAW buffer */
+    int buf_sz = width * height * sizeof (unsigned char);
+    unsigned char *buf = malloc (buf_sz);
+    unsigned char *p = buf;
+    unsigned int x;
+    unsigned int y;
+
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		if ((y % 2) == 1)
+		  {
+		      if ((x % 2) == 1)
+			  *p++ = 125;
+		      else
+			  *p++ = 97;
+		  }
+		else
+		  {
+		      if ((x % 2) == 1)
+			  *p++ = 97;
+		      else
+			  *p++ = 125;
+		  }
+	    }
+      }
+    *blob = buf;
+    *blob_sz = buf_sz;
+}
+
+static void
+build_grid_i16 (unsigned int width, unsigned int height, unsigned char **blob,
+		int *blob_sz)
+{
+/* building an INT16 RAW buffer */
+    int buf_sz = width * height * sizeof (short);
+    short *buf = malloc (buf_sz);
+    short *p = buf;
+    unsigned int x;
+    unsigned int y;
+
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		if ((y % 2) == 1)
+		  {
+		      if ((x % 2) == 1)
+			  *p++ = 12345;
+		      else
+			  *p++ = -9876;
+		  }
+		else
+		  {
+		      if ((x % 2) == 1)
+			  *p++ = -9876;
+		      else
+			  *p++ = 12345;
+		  }
+	    }
+      }
+    *blob = (unsigned char *) buf;
+    *blob_sz = buf_sz;
+}
+
+static void
+build_grid_u16 (unsigned int width, unsigned int height, unsigned char **blob,
+		int *blob_sz)
+{
+/* building an UINT16 RAW buffer */
+    int buf_sz = width * height * sizeof (unsigned short);
+    unsigned short *buf = malloc (buf_sz);
+    unsigned short *p = buf;
+    unsigned int x;
+    unsigned int y;
+
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		if ((y % 2) == 1)
+		  {
+		      if ((x % 2) == 1)
+			  *p++ = 18345;
+		      else
+			  *p++ = 9746;
+		  }
+		else
+		  {
+		      if ((x % 2) == 1)
+			  *p++ = 9746;
+		      else
+			  *p++ = 18345;
+		  }
+	    }
+      }
+    *blob = (unsigned char *) buf;
+    *blob_sz = buf_sz;
+}
+
+static void
+build_grid_i32 (unsigned int width, unsigned int height, unsigned char **blob,
+		int *blob_sz)
+{
+/* building an INT32 RAW buffer */
+    int buf_sz = width * height * sizeof (int);
+    int *buf = malloc (buf_sz);
+    int *p = buf;
+    unsigned int x;
+    unsigned int y;
+
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		if ((y % 2) == 1)
+		  {
+		      if ((x % 2) == 1)
+			  *p++ = 123456789;
+		      else
+			  *p++ = -987654321;
+		  }
+		else
+		  {
+		      if ((x % 2) == 1)
+			  *p++ = -987654321;
+		      else
+			  *p++ = 123456789;
+		  }
+	    }
+      }
+    *blob = (unsigned char *) buf;
+    *blob_sz = buf_sz;
+}
+
+static void
+build_grid_u32 (unsigned int width, unsigned int height, unsigned char **blob,
+		int *blob_sz)
+{
+/* building an UINT32 RAW buffer */
+    int buf_sz = width * height * sizeof (unsigned int);
+    unsigned int *buf = malloc (buf_sz);
+    unsigned int *p = buf;
+    unsigned int x;
+    unsigned int y;
+
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		if ((y % 2) == 1)
+		  {
+		      if ((x % 2) == 1)
+			  *p++ = 123457896;
+		      else
+			  *p++ = 986543217;
+		  }
+		else
+		  {
+		      if ((x % 2) == 1)
+			  *p++ = 985432167;
+		      else
+			  *p++ = 123456789;
+		  }
+	    }
+      }
+    *blob = (unsigned char *) buf;
+    *blob_sz = buf_sz;
+}
+
+static void
+build_grid_flt (unsigned int width, unsigned int height, unsigned char **blob,
+		int *blob_sz)
+{
+/* building a FLOAT RAW buffer */
+    int buf_sz = width * height * sizeof (float);
+    float *buf = malloc (buf_sz);
+    float *p = buf;
+    unsigned int x;
+    unsigned int y;
+
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		if ((y % 2) == 1)
+		  {
+		      if ((x % 2) == 1)
+			  *p++ = 1234.5600;
+		      else
+			  *p++ = -987.6500;
+		  }
+		else
+		  {
+		      if ((x % 2) == 1)
+			  *p++ = -987.6500;
+		      else
+			  *p++ = 1234.5600;
+		  }
+	    }
+      }
+    *blob = (unsigned char *) buf;
+    *blob_sz = buf_sz;
+}
+
+static void
+build_grid_dbl (unsigned int width, unsigned int height, unsigned char **blob,
+		int *blob_sz)
+{
+/* building a DOUBLE RAW buffer */
+    int buf_sz = width * height * sizeof (double);
+    double *buf = malloc (buf_sz);
+    double *p = buf;
+    unsigned int x;
+    unsigned int y;
+
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		if ((y % 2) == 1)
+		  {
+		      if ((x % 2) == 1)
+			  *p++ = 123456.7800;
+		      else
+			  *p++ = -98765.4300;
+		  }
+		else
+		  {
+		      if ((x % 2) == 1)
+			  *p++ = -98765.4300;
+		      else
+			  *p++ = 123456.7800;
+		  }
+	    }
+      }
+    *blob = (unsigned char *) buf;
+    *blob_sz = buf_sz;
+}
+
+static void
+reverse_i16 (unsigned int width, unsigned int height, const short *in,
+	     short *out)
+{
+/* reversing the endianness - INT16 */
+    union cvt
+    {
+	unsigned char byte[2];
+	short value;
+    };
+    union cvt cin;
+    union cvt cout;
+    unsigned int x;
+    unsigned int y;
+    const short *p_in = in;
+    short *p_out = out;
+
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		cin.value = *p_in++;
+		cout.byte[0] = cin.byte[1];
+		cout.byte[1] = cin.byte[0];
+		*p_out++ = cout.value;
+	    }
+      }
+}
+
+static void
+reverse_u16 (unsigned int width, unsigned int height, const unsigned short *in,
+	     unsigned short *out)
+{
+/* reversing the endianness - UINT16 */
+    union cvt
+    {
+	unsigned char byte[2];
+	unsigned short value;
+    };
+    union cvt cin;
+    union cvt cout;
+    unsigned int x;
+    unsigned int y;
+    const unsigned short *p_in = in;
+    unsigned short *p_out = out;
+
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		cin.value = *p_in++;
+		cout.byte[0] = cin.byte[1];
+		cout.byte[1] = cin.byte[0];
+		*p_out++ = cout.value;
+	    }
+      }
+}
+
+static void
+reverse_i32 (unsigned int width, unsigned int height, const int *in, int *out)
+{
+/* reversing the endianness - INT32 */
+    union cvt
+    {
+	unsigned char byte[4];
+	int value;
+    };
+    union cvt cin;
+    union cvt cout;
+    unsigned int x;
+    unsigned int y;
+    const int *p_in = in;
+    int *p_out = out;
+
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		cin.value = *p_in++;
+		cout.byte[0] = cin.byte[3];
+		cout.byte[1] = cin.byte[2];
+		cout.byte[2] = cin.byte[1];
+		cout.byte[3] = cin.byte[0];
+		*p_out++ = cout.value;
+	    }
+      }
+}
+
+static void
+reverse_u32 (unsigned int width, unsigned int height, const unsigned int *in,
+	     unsigned int *out)
+{
+/* reversing the endianness - UINT32 */
+    union cvt
+    {
+	unsigned char byte[4];
+	unsigned int value;
+    };
+    union cvt cin;
+    union cvt cout;
+    unsigned int x;
+    unsigned int y;
+    const unsigned int *p_in = in;
+    unsigned int *p_out = out;
+
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		cin.value = *p_in++;
+		cout.byte[0] = cin.byte[3];
+		cout.byte[1] = cin.byte[2];
+		cout.byte[2] = cin.byte[1];
+		cout.byte[3] = cin.byte[0];
+		*p_out++ = cout.value;
+	    }
+      }
+}
+
+static void
+reverse_flt (unsigned int width, unsigned int height, const float *in,
+	     float *out)
+{
+/* reversing the endianness - FLOAT */
+    union cvt
+    {
+	unsigned char byte[4];
+	float value;
+    };
+    union cvt cin;
+    union cvt cout;
+    unsigned int x;
+    unsigned int y;
+    const float *p_in = in;
+    float *p_out = out;
+
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		cin.value = *p_in++;
+		cout.byte[0] = cin.byte[3];
+		cout.byte[1] = cin.byte[2];
+		cout.byte[2] = cin.byte[1];
+		cout.byte[3] = cin.byte[0];
+		*p_out++ = cout.value;
+	    }
+      }
+}
+
+static void
+reverse_dbl (unsigned int width, unsigned int height, const double *in,
+	     double *out)
+{
+/* reversing the endianness - DOUBLE */
+    union cvt
+    {
+	unsigned char byte[8];
+	double value;
+    };
+    union cvt cin;
+    union cvt cout;
+    unsigned int x;
+    unsigned int y;
+    const double *p_in = in;
+    double *p_out = out;
+
+    for (y = 0; y < height; y++)
+      {
+	  for (x = 0; x < width; x++)
+	    {
+		cin.value = *p_in++;
+		cout.byte[0] = cin.byte[7];
+		cout.byte[1] = cin.byte[6];
+		cout.byte[2] = cin.byte[5];
+		cout.byte[3] = cin.byte[4];
+		cout.byte[4] = cin.byte[3];
+		cout.byte[5] = cin.byte[2];
+		cout.byte[6] = cin.byte[1];
+		cout.byte[7] = cin.byte[0];
+		*p_out++ = cout.value;
+	    }
+      }
+}
+
+static void
+reverse_endian (unsigned int width, unsigned int height,
+		const unsigned char *blob, int blob_sz, unsigned char sample,
+		unsigned char **rev_blob)
+{
+/* reversing the endianness */
+    unsigned char *buf = malloc (blob_sz);
+    switch (sample)
+      {
+      case RL2_SAMPLE_INT8:
+	  memcpy (buf, blob, blob_sz);
+	  break;
+      case RL2_SAMPLE_UINT8:
+	  memcpy (buf, blob, blob_sz);
+	  break;
+      case RL2_SAMPLE_INT16:
+	  reverse_i16 (width, height, (const short *) blob, (short *) buf);
+	  break;
+      case RL2_SAMPLE_UINT16:
+	  reverse_u16 (width, height, (const unsigned short *) blob,
+		       (unsigned short *) buf);
+	  break;
+      case RL2_SAMPLE_INT32:
+	  reverse_i32 (width, height, (const int *) blob, (int *) buf);
+	  break;
+      case RL2_SAMPLE_UINT32:
+	  reverse_u32 (width, height, (const unsigned int *) blob,
+		       (unsigned int *) buf);
+	  break;
+      case RL2_SAMPLE_FLOAT:
+	  reverse_flt (width, height, (const float *) blob, (float *) buf);
+	  break;
+      case RL2_SAMPLE_DOUBLE:
+	  reverse_dbl (width, height, (const double *) blob, (double *) buf);
+	  break;
+      };
+    *rev_blob = buf;
+}
+
+static int
+execute_check (sqlite3 * sqlite, const char *sql)
+{
+/* executing an SQL statement returning True/False */
+    sqlite3_stmt *stmt;
+    int ret;
+    int retcode = 0;
+
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return SQLITE_ERROR;
+    ret = sqlite3_step (stmt);
+    if (ret == SQLITE_DONE || ret == SQLITE_ROW)
+      {
+	  if (sqlite3_column_int (stmt, 0) == 1)
+	      retcode = 1;
+      }
+    sqlite3_finalize (stmt);
+    if (retcode == 1)
+	return SQLITE_OK;
+    return SQLITE_ERROR;
+}
+
+static int
+check_grid_i8 (unsigned int width, unsigned int x, unsigned int y,
+	       const char *blob, const char *msg, char value)
+{
+/* testing an INT8 value */
+    const char *p = blob + (y * width) + x;
+    if (*p != value)
+      {
+	  fprintf (stderr, "%s: Unexpected value %d (expected %d)\n", msg, *p,
+		   value);
+	  return 0;
+      }
+    return 1;
+}
+
+static int
+check_grid_u8 (unsigned int width, unsigned int x, unsigned int y,
+	       const unsigned char *blob, const char *msg, unsigned char value)
+{
+/* testing an UINT8 value */
+    const unsigned char *p = blob + (y * width) + x;
+    if (*p != value)
+      {
+	  fprintf (stderr, "%s: Unexpected value %d (expected %d)\n", msg, *p,
+		   value);
+	  return 0;
+      }
+    return 1;
+}
+
+static int
+check_grid_i16 (unsigned int width, unsigned int x, unsigned int y,
+		const short *blob, int big_endian, const char *msg, short value)
+{
+/* testing an INT16 value */
+    union cvt
+    {
+	unsigned char byte[2];
+	short value;
+    };
+    union cvt cin;
+    union cvt cout;
+    const short *p = blob + (y * width) + x;
+    short v = *p;
+    if (is_big_endian_cpu () && big_endian)
+	;
+    else if (!is_big_endian_cpu () && !big_endian)
+	;
+    else
+      {
+	  /* inverting the endianness */
+	  cin.value = *p;
+	  cout.byte[0] = cin.byte[1];
+	  cout.byte[1] = cin.byte[0];
+	  v = cout.value;
+      }
+    if (v != value)
+      {
+	  fprintf (stderr, "%s: Unexpected value %d (expected %d)\n", msg, v,
+		   value);
+	  return 0;
+      }
+    return 1;
+}
+
+static int
+check_grid_u16 (unsigned int width, unsigned int x, unsigned int y,
+		const unsigned short *blob, int big_endian, const char *msg,
+		unsigned short value)
+{
+/* testing an UINT16 value */
+    union cvt
+    {
+	unsigned char byte[2];
+	unsigned short value;
+    };
+    union cvt cin;
+    union cvt cout;
+    const unsigned short *p = blob + (y * width) + x;
+    unsigned short v = *p;
+    if (is_big_endian_cpu () && big_endian)
+	;
+    else if (!is_big_endian_cpu () && !big_endian)
+	;
+    else
+      {
+	  /* inverting the endianness */
+	  cin.value = *p;
+	  cout.byte[0] = cin.byte[1];
+	  cout.byte[1] = cin.byte[0];
+	  v = cout.value;
+      }
+    if (v != value)
+      {
+	  fprintf (stderr, "%s: Unexpected value %u (expected %u)\n", msg, v,
+		   value);
+	  return 0;
+      }
+    return 1;
+}
+
+static int
+check_grid_i32 (unsigned int width, unsigned int x, unsigned int y,
+		const int *blob, int big_endian, const char *msg, int value)
+{
+/* testing an INT32 value */
+    union cvt
+    {
+	unsigned char byte[4];
+	int value;
+    };
+    union cvt cin;
+    union cvt cout;
+    const int *p = blob + (y * width) + x;
+    int v = *p;
+    if (is_big_endian_cpu () && big_endian)
+	;
+    else if (!is_big_endian_cpu () && !big_endian)
+	;
+    else
+      {
+	  /* inverting the endianness */
+	  cin.value = *p;
+	  cout.byte[0] = cin.byte[3];
+	  cout.byte[1] = cin.byte[2];
+	  cout.byte[2] = cin.byte[1];
+	  cout.byte[3] = cin.byte[0];
+	  v = cout.value;
+      }
+    if (v != value)
+      {
+	  fprintf (stderr, "%s: Unexpected value %d (expected %d)\n", msg, v,
+		   value);
+	  return 0;
+      }
+    return 1;
+}
+
+static int
+check_grid_u32 (unsigned int width, unsigned int x, unsigned int y,
+		const unsigned int *blob, int big_endian, const char *msg,
+		unsigned int value)
+{
+/* testing an UINT32 value */
+    union cvt
+    {
+	unsigned char byte[4];
+	unsigned int value;
+    };
+    union cvt cin;
+    union cvt cout;
+    const unsigned int *p = blob + (y * width) + x;
+    unsigned int v = *p;
+    if (is_big_endian_cpu () && big_endian)
+	;
+    else if (!is_big_endian_cpu () && !big_endian)
+	;
+    else
+      {
+	  /* inverting the endianness */
+	  cin.value = *p;
+	  cout.byte[0] = cin.byte[3];
+	  cout.byte[1] = cin.byte[2];
+	  cout.byte[2] = cin.byte[1];
+	  cout.byte[3] = cin.byte[0];
+	  v = cout.value;
+      }
+    if (v != value)
+      {
+	  fprintf (stderr, "%s: Unexpected value %u (expected %u)\n", msg, v,
+		   value);
+	  return 0;
+      }
+    return 1;
+}
+
+static int
+check_grid_flt (unsigned int width, unsigned int x, unsigned int y,
+		const float *blob, int big_endian, const char *msg, float value)
+{
+/* testing a FLOAT value */
+    union cvt
+    {
+	unsigned char byte[4];
+	float value;
+    };
+    union cvt cin;
+    union cvt cout;
+    const float *p = blob + (y * width) + x;
+    float v = *p;
+    if (is_big_endian_cpu () && big_endian)
+	;
+    else if (!is_big_endian_cpu () && !big_endian)
+	;
+    else
+      {
+	  /* inverting the endianness */
+	  cin.value = *p;
+	  cout.byte[0] = cin.byte[3];
+	  cout.byte[1] = cin.byte[2];
+	  cout.byte[2] = cin.byte[1];
+	  cout.byte[3] = cin.byte[0];
+	  v = cout.value;
+      }
+    if (v != value)
+      {
+	  fprintf (stderr, "%s: Unexpected value %1.6f (expected %1.6f)\n", msg,
+		   v, value);
+	  return 0;
+      }
+    return 1;
+}
+
+static int
+check_grid_dbl (unsigned int width, unsigned int x, unsigned int y,
+		const double *blob, int big_endian, const char *msg,
+		double value)
+{
+/* testing a DOUBLE value */
+    union cvt
+    {
+	unsigned char byte[8];
+	double value;
+    };
+    union cvt cin;
+    union cvt cout;
+    const double *p = blob + (y * width) + x;
+    double v = *p;
+    if (is_big_endian_cpu () && big_endian)
+	;
+    else if (!is_big_endian_cpu () && !big_endian)
+	;
+    else
+      {
+	  /* inverting the endianness */
+	  cin.value = *p;
+	  cout.byte[0] = cin.byte[7];
+	  cout.byte[1] = cin.byte[6];
+	  cout.byte[2] = cin.byte[5];
+	  cout.byte[3] = cin.byte[4];
+	  cout.byte[4] = cin.byte[3];
+	  cout.byte[5] = cin.byte[2];
+	  cout.byte[6] = cin.byte[1];
+	  cout.byte[7] = cin.byte[0];
+	  v = cout.value;
+      }
+    if (v != value)
+      {
+	  fprintf (stderr, "%s: Unexpected value %1.6f (expected %1.6f)\n", msg,
+		   v, value);
+	  return 0;
+      }
+    return 1;
+}
+
+static int
+check_grid_odd (unsigned int width, unsigned int x, unsigned int y,
+		const unsigned char *blob, unsigned char sample, int big_endian,
+		const char *msg)
+{
+/* checking a RAW sample (odd) */
+    switch (sample)
+      {
+      case RL2_SAMPLE_INT8:
+	  return check_grid_i8 (width, x, y, (const char *) blob, msg, 123);
+      case RL2_SAMPLE_UINT8:
+	  return check_grid_u8 (width, x, y, blob, msg, 125);
+      case RL2_SAMPLE_INT16:
+	  return check_grid_i16 (width, x, y, (const short *) blob, big_endian,
+				 msg, 12345);
+      case RL2_SAMPLE_UINT16:
+	  return check_grid_u16 (width, x, y, (const unsigned short *) blob,
+				 big_endian, msg, 18345);
+      case RL2_SAMPLE_INT32:
+	  return check_grid_i32 (width, x, y, (const int *) blob, big_endian,
+				 msg, 123456789);
+      case RL2_SAMPLE_UINT32:
+	  return check_grid_u32 (width, x, y, (const unsigned int *) blob,
+				 big_endian, msg, 123457896);
+      case RL2_SAMPLE_FLOAT:
+	  return check_grid_flt (width, x, y, (const float *) blob, big_endian,
+				 msg, 1234.5600);
+      case RL2_SAMPLE_DOUBLE:
+	  return check_grid_dbl (width, x, y, (const double *) blob, big_endian,
+				 msg, 123456.7800);
+      };
+    return 0;
+}
+
+static int
+check_grid_even (unsigned int width, unsigned int x, unsigned int y,
+		 const unsigned char *blob, unsigned char sample,
+		 int big_endian, const char *msg)
+{
+/* checking a RAW sample (even) */
+    switch (sample)
+      {
+      case RL2_SAMPLE_INT8:
+	  return check_grid_i8 (width, x, y, (const char *) blob, msg, -98);
+      case RL2_SAMPLE_UINT8:
+	  return check_grid_u8 (width, x, y, blob, msg, 97);
+      case RL2_SAMPLE_INT16:
+	  return check_grid_i16 (width, x, y, (const short *) blob, big_endian,
+				 msg, -9876);
+      case RL2_SAMPLE_UINT16:
+	  return check_grid_u16 (width, x, y, (const unsigned short *) blob,
+				 big_endian, msg, 9746);
+      case RL2_SAMPLE_INT32:
+	  return check_grid_i32 (width, x, y, (const int *) blob, big_endian,
+				 msg, -987654321);
+      case RL2_SAMPLE_UINT32:
+	  return check_grid_u32 (width, x, y, (const unsigned int *) blob,
+				 big_endian, msg, 985432167);
+      case RL2_SAMPLE_FLOAT:
+	  return check_grid_flt (width, x, y, (const float *) blob, big_endian,
+				 msg, -987.6500);
+      case RL2_SAMPLE_DOUBLE:
+	  return check_grid_dbl (width, x, y, (const double *) blob, big_endian,
+				 msg, -98765.4300);
+      };
+    return 0;
+}
+
+static int
+check_grid_size (unsigned int width, unsigned int height, unsigned char sample)
+{
+/* computing the expected RAW buffer size */
+    int sample_sz = 1;
+    int buf_sz = width * height;
+    switch (sample)
+      {
+      case RL2_SAMPLE_INT16:
+      case RL2_SAMPLE_UINT16:
+	  sample_sz = 2;
+	  break;
+      case RL2_SAMPLE_INT32:
+      case RL2_SAMPLE_UINT32:
+      case RL2_SAMPLE_FLOAT:
+	  sample_sz = 4;
+	  break;
+      case RL2_SAMPLE_DOUBLE:
+	  sample_sz = 8;
+	  break;
+      };
+    return buf_sz * sample_sz;
+}
+
+static int
+test_grid (sqlite3 * sqlite, unsigned char sample, int *retcode)
+{
+/* testing some DBMS Coverage */
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+    char *err_msg = NULL;
+    const char *coverage = NULL;
+    const char *sample_name = NULL;
+    const char *pixel_name = NULL;
+    unsigned char num_bands = 1;
+    const char *compression_name = NULL;
+    int qlty = 100;
+    char *sql;
+    int tile_size = 512;
+    unsigned int width = 2045;
+    unsigned int height = 2543;
+    unsigned char *blob;
+    unsigned char *little_blob;
+    unsigned char *big_blob;
+    int blob_sz;
+    int ok = -1;
+    double x_res;
+    double y_res;
+
+/* setting the coverage name */
+    switch (sample)
+      {
+      case RL2_SAMPLE_INT8:
+	  coverage = "grid_8";
+	  break;
+      case RL2_SAMPLE_UINT8:
+	  coverage = "grid_u8";
+	  break;
+      case RL2_SAMPLE_INT16:
+	  coverage = "grid_16";
+	  break;
+      case RL2_SAMPLE_UINT16:
+	  coverage = "grid_u16";
+	  break;
+      case RL2_SAMPLE_INT32:
+	  coverage = "grid_32";
+	  break;
+      case RL2_SAMPLE_UINT32:
+	  coverage = "grid_u32";
+	  break;
+      case RL2_SAMPLE_FLOAT:
+	  coverage = "grid_flt";
+	  break;
+      case RL2_SAMPLE_DOUBLE:
+	  coverage = "grid_dbl";
+	  break;
+      };
+
+/* preparing misc Coverage's parameters */
+    pixel_name = "DATAGRID";
+    switch (sample)
+      {
+      case RL2_SAMPLE_INT8:
+	  sample_name = "INT8";
+	  break;
+      case RL2_SAMPLE_UINT8:
+	  sample_name = "UINT8";
+	  break;
+      case RL2_SAMPLE_INT16:
+	  sample_name = "INT16";
+	  break;
+      case RL2_SAMPLE_UINT16:
+	  sample_name = "UINT16";
+	  break;
+      case RL2_SAMPLE_INT32:
+	  sample_name = "INT32";
+	  break;
+      case RL2_SAMPLE_UINT32:
+	  sample_name = "UINT32";
+	  break;
+      case RL2_SAMPLE_FLOAT:
+	  sample_name = "FLOAT";
+	  break;
+      case RL2_SAMPLE_DOUBLE:
+	  sample_name = "DOUBLE";
+	  break;
+      };
+    num_bands = 1;
+    compression_name = "NONE";
+    tile_size = 512;
+
+/* creating the DBMS Coverage */
+    sql = sqlite3_mprintf ("SELECT RL2_CreateRasterCoverage("
+			   "%Q, %Q, %Q, %d, %Q, %d, %d, %d, %d, %1.8f, %1.8f)",
+			   coverage, sample_name, pixel_name, num_bands,
+			   compression_name, qlty, tile_size, tile_size, 4326,
+			   0.01, 0.01);
+    ret = execute_check (sqlite, sql);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "CreateRasterCoverage \"%s\" error: %s\n", coverage,
+		   err_msg);
+	  sqlite3_free (err_msg);
+	  *retcode += -1;
+	  return 0;
+      }
+
+/* preparing the RAW pixel buffer */
+    switch (sample)
+      {
+      case RL2_SAMPLE_INT8:
+	  build_grid_i8 (width, height, &blob, &blob_sz);
+	  break;
+      case RL2_SAMPLE_UINT8:
+	  build_grid_u8 (width, height, &blob, &blob_sz);
+	  break;
+      case RL2_SAMPLE_INT16:
+	  build_grid_i16 (width, height, &blob, &blob_sz);
+	  break;
+      case RL2_SAMPLE_UINT16:
+	  build_grid_u16 (width, height, &blob, &blob_sz);
+	  break;
+      case RL2_SAMPLE_INT32:
+	  build_grid_i32 (width, height, &blob, &blob_sz);
+	  break;
+      case RL2_SAMPLE_UINT32:
+	  build_grid_u32 (width, height, &blob, &blob_sz);
+	  break;
+      case RL2_SAMPLE_FLOAT:
+	  build_grid_flt (width, height, &blob, &blob_sz);
+	  break;
+      case RL2_SAMPLE_DOUBLE:
+	  build_grid_dbl (width, height, &blob, &blob_sz);
+	  break;
+      };
+    if (is_big_endian_cpu ())
+      {
+	  big_blob = blob;
+	  reverse_endian (width, height, blob, blob_sz, sample, &little_blob);
+      }
+    else
+      {
+	  little_blob = blob;
+	  reverse_endian (width, height, blob, blob_sz, sample, &big_blob);
+      }
+
+/* Inserting RAW pixels - little endian buffer */
+    sql = sqlite3_mprintf ("SELECT RL2_ImportSectionRawPixels("
+			   "%Q, %Q, %d, %d, ?, BuildMbr(0, 0, ?, ?, %d), 1, 1, 0)",
+			   coverage, "test little endian", width, height, 4326);
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Import RAW \"%s\" (little) error: %s\n", coverage,
+		   sqlite3_errmsg (sqlite));
+	  *retcode += -2;
+	  goto error;
+      }
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_blob (stmt, 1, little_blob, blob_sz, SQLITE_STATIC);
+    sqlite3_bind_double (stmt, 2, (double) width / 100.0);
+    sqlite3_bind_double (stmt, 3, (double) height / 100.0);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	      ok = sqlite3_column_int (stmt, 0);
+	  else
+	    {
+		fprintf (stderr,
+			 "Insert RAW (little); sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (sqlite));
+		*retcode += -3;
+		goto error;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    stmt = NULL;
+    if (ok <= 0)
+      {
+	  *retcode += -4;
+	  goto error;
+      }
+    free (little_blob);
+    little_blob = NULL;
+
+    ok = -1;
+/* Inserting RAW pixels - big endian buffer */
+    sql = sqlite3_mprintf ("SELECT RL2_ImportSectionRawPixels("
+			   "%Q, %Q, %d, %d, ?, BuildMbr(0, 0, ?, ?, %d), 1, 1, 1)",
+			   coverage, "test little endian", width, height, 4326);
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Import RAW \"%s\" (big) error: %s\n", coverage,
+		   sqlite3_errmsg (sqlite));
+	  *retcode += -5;
+	  goto error;
+      }
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_blob (stmt, 1, big_blob, blob_sz, SQLITE_STATIC);
+    sqlite3_bind_double (stmt, 2, -1.0 * (double) width / 100.0);
+    sqlite3_bind_double (stmt, 3, -1.0 * (double) height / 100.0);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	      ok = sqlite3_column_int (stmt, 0);
+	  else
+	    {
+		fprintf (stderr,
+			 "Insert RAW (big); sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (sqlite));
+		*retcode += -6;
+		goto error;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    stmt = NULL;
+    if (ok <= 0)
+      {
+	  *retcode += -7;
+	  goto error;
+      }
+    free (big_blob);
+    big_blob = NULL;
+
+    blob = NULL;
+    blob_sz = 0;
+/* Checking RAW pixels - little endian buffer / Section */
+    sql = sqlite3_mprintf ("SELECT RL2_ExportSectionRawPixels("
+			   "%Q, 1, %d, %d, BuildMbr(0, 0, ?, ?, %d), 0.01, 0.01, 0)",
+			   coverage, width, height, 4326);
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "ExportSection RAW \"%s\" (little) error: %s\n",
+		   coverage, sqlite3_errmsg (sqlite));
+	  *retcode += -8;
+	  goto error;
+      }
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_double (stmt, 1, (double) width / 100.0);
+    sqlite3_bind_double (stmt, 2, (double) height / 100.0);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	    {
+		if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
+		  {
+		      blob = (unsigned char *) sqlite3_column_blob (stmt, 0);
+		      blob_sz = sqlite3_column_bytes (stmt, 0);
+		      if (blob_sz != check_grid_size (width, height, sample))
+			{
+			    fprintf (stderr,
+				     "Unexpected ExportSection RAW (little) size: %d\n",
+				     blob_sz);
+			    *retcode += -9;
+			    goto error;
+			}
+		      if (!check_grid_odd
+			  (width, 101, 101, blob, sample, 0,
+			   "ExportSection RAW (little)"))
+			{
+			    *retcode += -10;
+			    goto error;
+			}
+		      if (!check_grid_even
+			  (width, 101, 102, blob, sample, 0,
+			   "ExportSection RAW (little)"))
+			{
+			    *retcode += -11;
+			    goto error;
+			}
+		  }
+	    }
+	  else
+	    {
+		fprintf (stderr,
+			 "ExportSection RAW (little); sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (sqlite));
+		*retcode += -12;
+		goto error;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    stmt = NULL;
+    if (ok <= 0)
+      {
+	  fprintf (stderr, "ERROR: ExportSection RAW (little) \"%s\"\n",
+		   coverage);
+	  *retcode += -13;
+	  goto error;
+      }
+
+    blob = NULL;
+    blob_sz = 0;
+/* Checking RAW pixels - big endian buffer / Coverage */
+    sql = sqlite3_mprintf ("SELECT RL2_ExportRawPixels("
+			   "%Q, %d, %d, MakePoint(?, ?, %d), 0.01, 0.01, 1)",
+			   coverage, width, height, 4326);
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "Export RAW \"%s\" (big) error: %s\n",
+		   coverage, sqlite3_errmsg (sqlite));
+	  *retcode += -14;
+	  goto error;
+      }
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_double (stmt, 1, (-1.0 * (double) width / 100.0) / 2.0);
+    sqlite3_bind_double (stmt, 2, (-1.0 * (double) height / 100.0) / 2.0);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	    {
+		if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
+		  {
+		      blob = (unsigned char *) sqlite3_column_blob (stmt, 0);
+		      blob_sz = sqlite3_column_bytes (stmt, 0);
+		      if (blob_sz != check_grid_size (width, height, sample))
+			{
+			    fprintf (stderr,
+				     "Unexpected Export RAW (big) size: %d\n",
+				     blob_sz);
+			    *retcode += -15;
+			    goto error;
+			}
+		      if (!check_grid_odd
+			  (width, 101, 101, blob, sample, 1,
+			   "Export RAW (big)"))
+			{
+			    *retcode += -16;
+			    goto error;
+			}
+		      if (!check_grid_even
+			  (width, 101, 102, blob, sample, 1,
+			   "ExportSection RAW (big)"))
+			{
+			    *retcode += -17;
+			    goto error;
+			}
+		  }
+	    }
+	  else
+	    {
+		fprintf (stderr,
+			 "Export RAW (big); sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (sqlite));
+		*retcode += -18;
+		goto error;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    stmt = NULL;
+    if (ok <= 0)
+      {
+	  fprintf (stderr, "ERROR: Export RAW (big) \"%s\"\n", coverage);
+	  *retcode += -19;
+	  goto error;
+      }
+
+    blob = NULL;
+    blob_sz = 0;
+/* Checking RAW pixels - big endian buffer / Section */
+    sql = sqlite3_mprintf ("SELECT RL2_ExportSectionRawPixels("
+			   "%Q, 2, %d, %d, MakePoint(?, ?, %d), 0.01, 0.01, 1)",
+			   coverage, width, height, 4326);
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    sqlite3_free (sql);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "ExportSection RAW \"%s\" (big) error: %s\n",
+		   coverage, sqlite3_errmsg (sqlite));
+	  *retcode += -20;
+	  goto error;
+      }
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    sqlite3_bind_double (stmt, 1, (-1.0 * (double) width / 100.0) / 2.0);
+    sqlite3_bind_double (stmt, 2, (-1.0 * (double) height / 100.0) / 2.0);
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	    {
+		if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
+		  {
+		      blob = (unsigned char *) sqlite3_column_blob (stmt, 0);
+		      blob_sz = sqlite3_column_bytes (stmt, 0);
+		      if (blob_sz != check_grid_size (width, height, sample))
+			{
+			    fprintf (stderr,
+				     "Unexpected ExportSection RAW (big) size: %d\n",
+				     blob_sz);
+			    *retcode += -21;
+			    goto error;
+			}
+		      if (!check_grid_odd
+			  (width, 101, 101, blob, sample, 1,
+			   "ExportSection RAW (big)"))
+			{
+			    *retcode += -22;
+			    goto error;
+			}
+		      if (!check_grid_even
+			  (width, 101, 102, blob, sample, 1,
+			   "ExportSection RAW (big)"))
+			{
+			    *retcode += -23;
+			    goto error;
+			}
+		  }
+	    }
+	  else
+	    {
+		fprintf (stderr,
+			 "ExportSection RAW (big); sqlite3_step() error: %s\n",
+			 sqlite3_errmsg (sqlite));
+		*retcode += -24;
+		goto error;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    stmt = NULL;
+    if (ok <= 0)
+      {
+	  fprintf (stderr, "ERROR: ExportSection RAW (big) \"%s\"\n", coverage);
+	  *retcode += -25;
+	  goto error;
+      }
+
+/* testing base-resolution - Coverage */
+    if (rl2_resolve_base_resolution_from_dbms
+	(sqlite, coverage, 0, 0, &x_res, &y_res) != RL2_OK)
+      {
+	  fprintf (stderr, "ERROR: unable to get BaseResolution (Coverage)\n");
+	  *retcode += -26;
+	  goto error;
+      }
+    if (x_res != 0.01)
+      {
+	  fprintf (stderr,
+		   "Unexpected BaseResolution (Coverage, horz): %1.6f\n",
+		   x_res);
+	  *retcode += -27;
+	  goto error;
+      }
+    if (y_res != 0.01)
+      {
+	  fprintf (stderr,
+		   "Unexpected BaseResolution (Coverage, vert): %1.6f\n",
+		   y_res);
+	  *retcode += -28;
+	  goto error;
+      }
+/* testing base-resolution - Section */
+    if (rl2_resolve_base_resolution_from_dbms
+	(sqlite, coverage, 1, 2, &x_res, &y_res) != RL2_OK)
+      {
+	  fprintf (stderr, "ERROR: unable to get BaseResolution (Section)\n");
+	  *retcode += -29;
+	  goto error;
+      }
+    if (x_res != 0.01)
+      {
+	  fprintf (stderr, "Unexpected BaseResolution (Section, horz): %1.6f\n",
+		   x_res);
+	  *retcode += -30;
+	  goto error;
+      }
+    if (y_res != 0.01)
+      {
+	  fprintf (stderr, "Unexpected BaseResolution (Sectuib, vert): %1.6f\n",
+		   y_res);
+	  *retcode += -31;
+	  goto error;
+      }
+
+    return 1;
+
+  error:
+    if (stmt != NULL)
+	sqlite3_finalize (stmt);
+    if (little_blob != NULL)
+	free (little_blob);
+    if (big_blob != NULL)
+	free (big_blob);
+    return 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+    int result = 0;
+    int ret;
+    char *err_msg = NULL;
+    sqlite3 *db_handle;
+    void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
+
+    if (argc > 1 || argv[0] == NULL)
+	argc = 1;		/* silencing stupid compiler warnings */
+
+/* opening and initializing the "memory" test DB */
+    ret = sqlite3_open_v2 (":memory:", &db_handle,
+			   SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "sqlite3_open_v2() error: %s\n",
+		   sqlite3_errmsg (db_handle));
+	  return -1;
+      }
+    spatialite_init_ex (db_handle, cache, 0);
+    rl2_init (db_handle, priv_data, 0);
+    ret =
+	sqlite3_exec (db_handle, "SELECT InitSpatialMetadata(1)", NULL, NULL,
+		      &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "InitSpatialMetadata() error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -2;
+      }
+    ret =
+	sqlite3_exec (db_handle, "SELECT CreateRasterCoveragesTable()", NULL,
+		      NULL, &err_msg);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "CreateRasterCoveragesTable() error: %s\n", err_msg);
+	  sqlite3_free (err_msg);
+	  return -3;
+      }
+
+/*  RAW UINT8 (GRID) tests */
+    ret = -100;
+    if (!test_grid (db_handle, RL2_SAMPLE_INT8, &ret))
+	return ret;
+    ret = -200;
+    if (!test_grid (db_handle, RL2_SAMPLE_UINT8, &ret))
+	return ret;
+    ret = -300;
+    if (!test_grid (db_handle, RL2_SAMPLE_INT16, &ret))
+	return ret;
+    ret = -400;
+    if (!test_grid (db_handle, RL2_SAMPLE_UINT16, &ret))
+	return ret;
+    ret = -500;
+    if (!test_grid (db_handle, RL2_SAMPLE_INT32, &ret))
+	return ret;
+    ret = -600;
+    if (!test_grid (db_handle, RL2_SAMPLE_UINT32, &ret))
+	return ret;
+    ret = -700;
+    if (!test_grid (db_handle, RL2_SAMPLE_FLOAT, &ret))
+	return ret;
+    ret = -800;
+    if (!test_grid (db_handle, RL2_SAMPLE_DOUBLE, &ret))
+	return ret;
+
+/* closing the DB */
+    sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
+    spatialite_shutdown ();
+    return result;
+}
diff --git a/test/test_section.c b/test/test_section.c
index 037205b..77112a0 100644
--- a/test/test_section.c
+++ b/test/test_section.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
diff --git a/test/test_svg.c b/test/test_svg.c
index eb4fbc8..0353c10 100644
--- a/test/test_svg.c
+++ b/test/test_svg.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
diff --git a/test/test_text_symbolizer.c b/test/test_text_symbolizer.c
new file mode 100644
index 0000000..1d23ab4
--- /dev/null
+++ b/test/test_text_symbolizer.c
@@ -0,0 +1,1488 @@
+/*
+
+ test_text_symbolizer.c -- RasterLite-2 Test Case
+
+ Author: Sandro Furieri <a.furieri at lqt.it>
+
+ ------------------------------------------------------------------------------
+ 
+ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ 
+ The contents of this file are subject to the Mozilla Public License Version
+ 1.1 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+ 
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the
+License.
+
+The Original Code is the RasterLite2 library
+
+The Initial Developer of the Original Code is Alessandro Furieri
+ 
+Portions created by the Initial Developer are Copyright (C) 2015
+the Initial Developer. All Rights Reserved.
+
+Contributor(s):
+
+Alternatively, the contents of this file may be used under the terms of
+either the GNU General Public License Version 2 or later (the "GPL"), or
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+in which case the provisions of the GPL or the LGPL are applicable instead
+of those above. If you wish to allow use of your version of this file only
+under the terms of either the GPL or the LGPL, and not to allow others to
+use your version of this file under the terms of the MPL, indicate your
+decision by deleting the provisions above and replace them with the notice
+and other provisions required by the GPL or the LGPL. If you do not delete
+the provisions above, a recipient may use your version of this file under
+the terms of any one of the MPL, the GPL or the LGPL.
+ 
+*/
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "sqlite3.h"
+#include "spatialite.h"
+
+#include "rasterlite2/rasterlite2.h"
+
+static int
+test_symbolizer (sqlite3 * db_handle, const char *coverage,
+		 const char *style_name, int *retcode)
+{
+/* testing a TextSymbolizer */
+    rl2FeatureTypeStylePtr style;
+    rl2VectorSymbolizerPtr symbolizer;
+    rl2TextSymbolizerPtr text;
+    int intval;
+    int ret;
+    double dblval;
+    double dblval2;
+    const char *string;
+    unsigned char red;
+    unsigned char green;
+    unsigned char blue;
+    int scale_forbidden;
+    style =
+	rl2_create_feature_type_style_from_dbms (db_handle, coverage,
+						 style_name);
+    if (style == NULL)
+      {
+	  fprintf (stderr, "Unable to retrieve style '%s'\n", style_name);
+	  *retcode += 1;
+	  return 0;
+      }
+
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 1.0, NULL,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s)\n",
+		   style_name);
+	  *retcode += 2;
+	  return 0;
+      }
+
+    if (rl2_is_valid_vector_symbolizer (symbolizer, &intval) != RL2_OK)
+      {
+	  fprintf (stderr, "%s: Unable to get Vector Symbolizer Validity #1\n",
+		   style_name);
+	  *retcode += 3;
+	  return 0;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr, "%s: Unexpected Vector Symbolizer Validity #1: %d\n",
+		   style_name, intval);
+	  *retcode += 4;
+	  return 0;
+      }
+
+    if (rl2_get_vector_symbolizer_count (symbolizer, &intval) != RL2_OK)
+      {
+	  fprintf (stderr, "%s: Unable to get Vector Symbolizer Count #1\n",
+		   style_name);
+	  *retcode += 5;
+	  return 0;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr, "%s: Unexpected Vector Symbolizer Count #1: %d\n",
+		   style_name, intval);
+	  *retcode += 6;
+	  return 0;
+      }
+
+    if (rl2_get_vector_symbolizer_item_type (symbolizer, 0, &intval) != RL2_OK)
+      {
+	  fprintf (stderr, "%s: Unable to get Vector Symbolizer Item Type #1\n",
+		   style_name);
+	  *retcode += 7;
+	  return 0;
+      }
+    if (intval != RL2_TEXT_SYMBOLIZER)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Vector Symbolizer Item Type #1: %d\n",
+		   style_name, intval);
+	  *retcode += 8;
+	  return 0;
+      }
+
+    text = rl2_get_text_symbolizer (symbolizer, 0);
+    if (text == NULL)
+      {
+	  fprintf (stderr, "%s: Unable to get a Text Symbolizer #1\n",
+		   style_name);
+	  *retcode += 9;
+	  return 0;
+      }
+
+    string = rl2_text_symbolizer_get_label (text);
+    intval = 0;
+    if (string != NULL)
+      {
+	  if (strcmp (string, "some_column") == 0)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s; Unexpected Text Symbolizer GetLabel #1: %s\n",
+		   style_name, string);
+	  *retcode += 10;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_get_font_families_count (text, &intval) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Text Symbolizer GetFontFamiliesCount #1\n",
+		   style_name);
+	  *retcode += 11;
+	  return 0;
+      }
+    red = 0;
+    if (strcmp (style_name, "label_1") == 0
+	|| strcmp (style_name, "label_2") == 0)
+      {
+	  if (intval == 2)
+	      red = 1;
+      }
+    if (strcmp (style_name, "label_3") == 0)
+      {
+	  if (intval == 0)
+	      red = 1;
+      }
+    if (red != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Text Symbolizer GetFontFamiliesCount #1: %d\n",
+		   style_name, intval);
+	  *retcode += 12;
+	  return 0;
+      }
+
+    string = rl2_text_symbolizer_get_font_family_name (text, 0);
+    if (strcmp (style_name, "label_3") == 0)
+      {
+	  if (string != NULL)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Text Symbolizer GetFontFamilyName #1\n",
+			 style_name);
+		*retcode += 13;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (string == NULL)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Text Symbolizer GetFontFamilyName #1\n",
+			 style_name);
+		*retcode += 14;
+		return 0;
+	    }
+      }
+    intval = 0;
+    if (strcmp (style_name, "label_1") == 0
+	|| strcmp (style_name, "label_2") == 0)
+      {
+	  if (strcmp (string, "Courier") == 0)
+	      intval = 1;
+      }
+    else
+	intval = 1;
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s; Unexpected Text Symbolizer GetFontFamilyName #1: %s\n",
+		   style_name, string);
+	  *retcode += 15;
+	  return 0;
+      }
+
+    string = rl2_text_symbolizer_get_font_family_name (text, 1);
+    if (strcmp (style_name, "label_3") == 0)
+      {
+	  if (string != NULL)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Text Symbolizer GetFontFamilyName #2\n",
+			 style_name);
+		*retcode += 16;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (string == NULL)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Text Symbolizer GetFontFamilyName #2\n",
+			 style_name);
+		*retcode += 17;
+		return 0;
+	    }
+      }
+    intval = 0;
+    if (strcmp (style_name, "label_1") == 0
+	|| strcmp (style_name, "label_2") == 0)
+      {
+	  if (strcmp (string, "Arial") == 0)
+	      intval = 1;
+      }
+    else
+	intval = 1;
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s; Unexpected Text Symbolizer GetFontFamilyName #2: %s\n",
+		   style_name, string);
+	  *retcode += 18;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_get_font_style (text, &red) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Text Symbolizer GetFontStyle #1\n",
+		   style_name);
+	  *retcode += 19;
+	  return 0;
+      }
+    intval = 0;
+    if (strcmp (style_name, "label_1") == 0)
+      {
+	  if (red == RL2_FONT_STYLE_ITALIC)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "label_2") == 0)
+      {
+	  if (red == RL2_FONT_STYLE_OBLIQUE)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "label_3") == 0)
+      {
+	  if (red == RL2_FONT_STYLE_NORMAL)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Text Symbolizer GetFontStyle #1: %02x\n",
+		   style_name, red);
+	  *retcode += 20;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_get_font_weight (text, &red) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Text Symbolizer GetFontWeight #1\n",
+		   style_name);
+	  *retcode += 21;
+	  return 0;
+      }
+    intval = 0;
+    if (strcmp (style_name, "label_1") == 0)
+      {
+	  if (red == RL2_FONT_WEIGHT_BOLD)
+	      intval = 1;
+      }
+    else
+      {
+	  if (red == RL2_FONT_WEIGHT_NORMAL)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Text Symbolizer GetFontWeight #1: %02x\n",
+		   style_name, red);
+	  *retcode += 22;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_get_font_size (text, &dblval) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Text Symbolizer GetFontSize #1\n",
+		   style_name);
+	  *retcode += 23;
+	  return 0;
+      }
+    intval = 0;
+    if (strcmp (style_name, "label_1") == 0)
+      {
+	  if (dblval == 12.5)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "label_2") == 0)
+      {
+	  if (dblval == 7.5)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "label_3") == 0)
+      {
+	  if (dblval == 10.0)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Text Symbolizer GetFontSize #1: %1.4f\n",
+		   style_name, dblval);
+	  *retcode += 24;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_get_label_placement_mode (text, &red) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Text Symbolizer GetLabelPlacementMode #1\n",
+		   style_name);
+	  *retcode += 25;
+	  return 0;
+      }
+    intval = 0;
+    if (strcmp (style_name, "label_1") == 0)
+      {
+	  if (red == RL2_LABEL_PLACEMENT_POINT)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "label_2") == 0)
+      {
+	  if (red == RL2_LABEL_PLACEMENT_LINE)
+	      intval = 1;
+      }
+    if (strcmp (style_name, "label_3") == 0)
+      {
+	  if (red == RL2_LABEL_PLACEMENT_UNKNOWN)
+	      intval = 1;
+      }
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Text Symbolizer GetLabelPlacementMode #1: %02x\n",
+		   style_name, red);
+	  *retcode += 26;
+	  return 0;
+      }
+
+    ret =
+	rl2_text_symbolizer_get_point_placement_anchor_point (text, &dblval,
+							      &dblval2);
+    if (strcmp (style_name, "label_2") == 0
+	|| strcmp (style_name, "label_3") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Text Symbolizer GetPointPlacementAnchorPoint #1\n",
+			 style_name);
+		*retcode += 27;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Text Symbolizer GetPointPlacementAnchorPoint #1\n",
+			 style_name);
+		*retcode += 28;
+		return 0;
+	    }
+      }
+    intval = 0;
+    if (strcmp (style_name, "label_1") == 0)
+      {
+	  if (dblval == 2.0 && dblval2 == 4.0)
+	      intval = 1;
+      }
+    else
+	intval = 1;
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Text Symbolizer GetPointPlacementAnchorPoint #1: %1.4f %1.4f\n",
+		   style_name, dblval, dblval2);
+	  *retcode += 29;
+	  return 0;
+      }
+
+    ret =
+	rl2_text_symbolizer_get_point_placement_displacement (text, &dblval,
+							      &dblval2);
+    if (strcmp (style_name, "label_2") == 0
+	|| strcmp (style_name, "label_3") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Text Symbolizer GetPointPlacementDisplacement #1\n",
+			 style_name);
+		*retcode += 30;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Text Symbolizer GetPointPlacementDisplacement #1\n",
+			 style_name);
+		*retcode += 31;
+		return 0;
+	    }
+      }
+    intval = 0;
+    if (strcmp (style_name, "label_1") == 0)
+      {
+	  if (dblval == 10.0 && dblval2 == 5.0)
+	      intval = 1;
+      }
+    else
+	intval = 1;
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Text Symbolizer GetPointPlacementDisplacement #1: %1.4f %1.4f\n",
+		   style_name, dblval, dblval2);
+	  *retcode += 32;
+	  return 0;
+      }
+
+    ret = rl2_text_symbolizer_get_point_placement_rotation (text, &dblval);
+    if (strcmp (style_name, "label_2") == 0
+	|| strcmp (style_name, "label_3") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Text Symbolizer GetPointPlacementRotation #1\n",
+			 style_name);
+		*retcode += 33;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Text Symbolizer GetPointPlacementRotation #1\n",
+			 style_name);
+		*retcode += 34;
+		return 0;
+	    }
+      }
+    intval = 0;
+    if (strcmp (style_name, "label_1") == 0)
+      {
+	  if (dblval == 15.0)
+	      intval = 1;
+      }
+    else
+	intval = 1;
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Text Symbolizer GetPointPlacementRotation #1: %1.4f\n",
+		   style_name, dblval);
+	  *retcode += 35;
+	  return 0;
+      }
+
+    ret =
+	rl2_text_symbolizer_get_line_placement_perpendicular_offset (text,
+								     &dblval);
+    if (strcmp (style_name, "label_1") == 0
+	|| strcmp (style_name, "label_3") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Text Symbolizer GetLinePlacementPerpendicularOffset #1\n",
+			 style_name);
+		*retcode += 36;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Text Symbolizer GetLinePlacementPerpendicularOffset #1\n",
+			 style_name);
+		*retcode += 37;
+		return 0;
+	    }
+      }
+    intval = 0;
+    if (strcmp (style_name, "label_2") == 0)
+      {
+	  if (dblval == 13.0)
+	      intval = 1;
+      }
+    else
+	intval = 1;
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Text Symbolizer GetLinePlacementPerpendicularOffset #1: %1.4f\n",
+		   style_name, dblval);
+	  *retcode += 38;
+	  return 0;
+      }
+
+    ret = rl2_text_symbolizer_get_line_placement_is_repeated (text, &intval);
+    if (strcmp (style_name, "label_1") == 0
+	|| strcmp (style_name, "label_3") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Text Symbolizer GetLinePlacementIsRepeated #1\n",
+			 style_name);
+		*retcode += 39;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Text Symbolizer GetLinePlacementIsRepeated #1\n",
+			 style_name);
+		*retcode += 40;
+		return 0;
+	    }
+      }
+    red = 0;
+    if (strcmp (style_name, "label_2") == 0)
+      {
+	  if (intval == 1)
+	      red = 1;
+      }
+    else
+	red = 1;
+    if (red != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Text Symbolizer GetLinePlacementIsRepeated #1: %d\n",
+		   style_name, intval);
+	  *retcode += 41;
+	  return 0;
+      }
+
+    ret = rl2_text_symbolizer_get_line_placement_initial_gap (text, &dblval);
+    if (strcmp (style_name, "label_1") == 0
+	|| strcmp (style_name, "label_3") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Text Symbolizer GetLinePlacementInitialGap #1\n",
+			 style_name);
+		*retcode += 42;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Text Symbolizer GetLinePlacementInitialGap #1\n",
+			 style_name);
+		*retcode += 43;
+		return 0;
+	    }
+      }
+    intval = 0;
+    if (strcmp (style_name, "label_2") == 0)
+      {
+	  if (dblval == 6.5)
+	      intval = 1;
+      }
+    else
+	intval = 1;
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Text Symbolizer GetLinePlacementInitialGap #1: %1.4f\n",
+		   style_name, dblval);
+	  *retcode += 44;
+	  return 0;
+      }
+
+    ret = rl2_text_symbolizer_get_line_placement_gap (text, &dblval);
+    if (strcmp (style_name, "label_1") == 0
+	|| strcmp (style_name, "label_3") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Text Symbolizer GetLinePlacementGap #1\n",
+			 style_name);
+		*retcode += 45;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Text Symbolizer GetLinePlacementGap #1\n",
+			 style_name);
+		*retcode += 46;
+		return 0;
+	    }
+      }
+    intval = 0;
+    if (strcmp (style_name, "label_2") == 0)
+      {
+	  if (dblval == 12.0)
+	      intval = 1;
+      }
+    else
+	intval = 1;
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Text Symbolizer GetLinePlacementGap #1: %1.4f\n",
+		   style_name, dblval);
+	  *retcode += 47;
+	  return 0;
+      }
+
+    ret = rl2_text_symbolizer_get_line_placement_is_aligned (text, &intval);
+    if (strcmp (style_name, "label_1") == 0
+	|| strcmp (style_name, "label_3") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Text Symbolizer GetLinePlacementIsAligned #1\n",
+			 style_name);
+		*retcode += 48;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Text Symbolizer GetLinePlacementIsAligned #1\n",
+			 style_name);
+		*retcode += 49;
+		return 0;
+	    }
+      }
+    red = 0;
+    if (strcmp (style_name, "label_2") == 0)
+      {
+	  if (intval == 1)
+	      red = 1;
+      }
+    else
+	red = 1;
+    if (red != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Text Symbolizer GetLinePlacementIsAligned #1: %d\n",
+		   style_name, intval);
+	  *retcode += 50;
+	  return 0;
+      }
+
+    ret =
+	rl2_text_symbolizer_get_line_placement_generalize_line (text, &intval);
+    if (strcmp (style_name, "label_1") == 0
+	|| strcmp (style_name, "label_3") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Text Symbolizer GetLinePlacementGeneralizeLine #1\n",
+			 style_name);
+		*retcode += 51;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Text Symbolizer GetLinePlacementGeneralizeLine #1\n",
+			 style_name);
+		*retcode += 52;
+		return 0;
+	    }
+      }
+    red = 0;
+    if (strcmp (style_name, "label_2") == 0)
+      {
+	  if (intval == 1)
+	      red = 1;
+      }
+    else
+	red = 1;
+    if (red != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Text Symbolizer GetLinePlacementGeneralizeLine #1: %d\n",
+		   style_name, intval);
+	  *retcode += 53;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_has_halo (text, &intval) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Text Symbolizer HasHalo #1\n",
+		   style_name);
+	  *retcode += 54;
+	  return 0;
+      }
+    red = 0;
+    if (strcmp (style_name, "label_1") == 0)
+      {
+	  if (intval == 1)
+	      red = 1;
+      }
+    if (strcmp (style_name, "label_2") == 0)
+      {
+	  if (intval == 1)
+	      red = 1;
+      }
+    if (strcmp (style_name, "label_3") == 0)
+      {
+	  if (intval == 0)
+	      red = 1;
+      }
+    if (red != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Text Symbolizer HasHalo #1: %d\n",
+		   style_name, intval);
+	  *retcode += 56;
+	  return 0;
+      }
+
+    ret = rl2_text_symbolizer_get_halo_radius (text, &dblval);
+    if (strcmp (style_name, "label_3") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Text Symbolizer GetHaloRadius #1\n",
+			 style_name);
+		*retcode += 57;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Text Symbolizer GetHaloRadius #1\n",
+			 style_name);
+		*retcode += 58;
+		return 0;
+	    }
+      }
+    intval = 0;
+    if (strcmp (style_name, "label_1") == 0)
+      {
+	  if (dblval == 1.0)
+	      intval = 1;
+      }
+    else if (strcmp (style_name, "label_2") == 0)
+      {
+	  if (dblval == 2.5)
+	      intval = 1;
+      }
+    else
+	intval = 1;
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Text Symbolizer GetHaloRadius #1: %1.4f\n",
+		   style_name, dblval);
+	  *retcode += 59;
+	  return 0;
+      }
+
+    ret = rl2_text_symbolizer_has_halo_fill (text, &intval);
+    if (strcmp (style_name, "label_3") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Text Symbolizer HasHaloFill #1\n",
+			 style_name);
+		*retcode += 60;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Text Symbolizer HasHaloFill #1\n",
+			 style_name);
+		*retcode += 61;
+		return 0;
+	    }
+      }
+    red = 0;
+    if (strcmp (style_name, "label_1") == 0)
+      {
+	  if (intval == 1)
+	      red = 1;
+      }
+    if (strcmp (style_name, "label_2") == 0)
+      {
+	  if (intval == 1)
+	      red = 1;
+      }
+    if (strcmp (style_name, "label_3") == 0)
+	red = 1;
+    if (red != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Text Symbolizer HasHaloFill #1: %d\n",
+		   style_name, intval);
+	  *retcode += 62;
+	  return 0;
+      }
+
+    ret = rl2_text_symbolizer_get_halo_fill_color (text, &red, &green, &blue);
+    if (strcmp (style_name, "label_3") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Text Symbolizer HaloFillColor #1\n",
+			 style_name);
+		*retcode += 61;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Text Symbolizer HaloFillColor #1\n",
+			 style_name);
+		*retcode += 62;
+		return 0;
+	    }
+      }
+    intval = 0;
+    if (strcmp (style_name, "label_1") == 0)
+      {
+	  if (red == 0xff && green == 0x80 && blue == 0x00)
+	      intval = 1;
+      }
+    else
+	intval = 1;
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Text Symbolizer HaloFillColor #1: #%02x%02x%02x\n",
+		   style_name, red, green, blue);
+	  *retcode += 63;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_has_fill (text, &intval) != RL2_OK)
+      {
+	  fprintf (stderr,
+		   "%s: Unable to get Text Symbolizer HasFill #1\n",
+		   style_name);
+	  *retcode += 64;
+	  return 0;
+      }
+    red = 0;
+    if (strcmp (style_name, "label_1") == 0)
+      {
+	  if (intval == 1)
+	      red = 1;
+      }
+    if (strcmp (style_name, "label_2") == 0)
+      {
+	  if (intval == 1)
+	      red = 1;
+      }
+    if (strcmp (style_name, "label_3") == 0)
+      {
+	  if (intval == 0)
+	      red = 1;
+      }
+    if (red != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Text Symbolizer HasFill #1: %d\n",
+		   style_name, intval);
+	  *retcode += 65;
+	  return 0;
+      }
+
+    ret = rl2_text_symbolizer_get_fill_color (text, &red, &green, &blue);
+    if (strcmp (style_name, "label_3") == 0)
+      {
+	  if (ret == RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unexpected success Text Symbolizer FillColor #1\n",
+			 style_name);
+		*retcode += 66;
+		return 0;
+	    }
+      }
+    else
+      {
+	  if (ret != RL2_OK)
+	    {
+		fprintf (stderr,
+			 "%s: Unable to get Text Symbolizer FillColor #1\n",
+			 style_name);
+		*retcode += 67;
+		return 0;
+	    }
+      }
+    intval = 0;
+    if (strcmp (style_name, "label_1") == 0)
+      {
+	  if (red == 0x06 && green == 0x0a && blue == 0x0f)
+	      intval = 1;
+      }
+    else if (strcmp (style_name, "label_2") == 0)
+      {
+	  if (red == 0x10 && green == 0x20 && blue == 0x30)
+	      intval = 1;
+      }
+    else
+	intval = 1;
+    if (intval != 1)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Text Symbolizer FillColor #1: #%02x%02x%02x\n",
+		   style_name, red, green, blue);
+	  *retcode += 69;
+	  return 0;
+      }
+
+    rl2_destroy_feature_type_style (style);
+    return 1;
+}
+
+static int
+test_style (sqlite3 * db_handle, const char *coverage,
+	    const char *style_name, int *retcode)
+{
+/* testing a FeatureType Style (TextSymbolizers) */
+    rl2FeatureTypeStylePtr style;
+    rl2VectorSymbolizerPtr symbolizer;
+    rl2TextSymbolizerPtr text;
+    rl2VariantArrayPtr value;
+    int intval;
+    double dblval;
+    double dblval2;
+    const char *string;
+    unsigned char red;
+    unsigned char green;
+    unsigned char blue;
+    int scale_forbidden;
+    style =
+	rl2_create_feature_type_style_from_dbms (db_handle, coverage,
+						 style_name);
+    if (style == NULL)
+      {
+	  fprintf (stderr, "Unable to retrieve style '%s'\n", style_name);
+	  *retcode += 1;
+	  return 0;
+      }
+
+    string = rl2_get_feature_type_style_name (style);
+    if (string == NULL)
+      {
+	  fprintf (stderr, "Unable to retrieve style name '%s'\n", style_name);
+	  *retcode += 2;
+	  return 0;
+      }
+    if (strcmp (string, "text_style") != 0)
+      {
+	  fprintf (stderr, "%s: Unexpected style name '%s'\n", style_name,
+		   string);
+	  *retcode += 3;
+	  return 0;
+      }
+
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 1.0, NULL,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s)\n",
+		   style_name);
+	  *retcode += 4;
+	  return 0;
+      }
+
+    if (rl2_get_vector_symbolizer_count (symbolizer, &intval) != RL2_OK)
+      {
+	  fprintf (stderr, "%s: Unable to get Vector Symbolizer Count #2\n",
+		   style_name);
+	  *retcode += 5;
+	  return 0;
+      }
+    if (intval != 2)
+      {
+	  fprintf (stderr, "%s: Unexpected Vector Symbolizer Count #2: %d\n",
+		   style_name, intval);
+	  *retcode += 6;
+	  return 0;
+      }
+
+    if (rl2_get_vector_symbolizer_item_type (symbolizer, 1, &intval) != RL2_OK)
+      {
+	  fprintf (stderr, "%s: Unable to get Vector Symbolizer Item Type #2\n",
+		   style_name);
+	  *retcode += 7;
+	  return 0;
+      }
+    if (intval != RL2_TEXT_SYMBOLIZER)
+      {
+	  fprintf (stderr,
+		   "%s: Unexpected Vector Symbolizer Item Type #2: %d\n",
+		   style_name, intval);
+	  *retcode += 8;
+	  return 0;
+      }
+
+    text = rl2_get_text_symbolizer (symbolizer, 1);
+    if (text == NULL)
+      {
+	  fprintf (stderr, "%s: Unable to get a Text Symbolizer #2\n",
+		   style_name);
+	  *retcode += 9;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_get_label (NULL) != NULL)
+      {
+	  fprintf (stderr, "Unexpected success: Text Symbolizer GetLabel #2\n");
+	  *retcode += 10;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_get_font_families_count (NULL, &intval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Text Symbolizer GetFontFamiliesCount #2\n");
+	  *retcode += 11;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_get_font_family_name (text, 10) != NULL)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Text Symbolizer GetFontFamilyName #2\n");
+	  *retcode += 12;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_get_font_family_name (NULL, 0) != NULL)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Text Symbolizer GetFontFamilyName #2\n");
+	  *retcode += 13;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_get_font_style (NULL, &red) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Text Symbolizer GetFontStyle #2\n");
+	  *retcode += 14;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_get_font_weight (NULL, &red) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Text Symbolizer GetFontWeight #2\n");
+	  *retcode += 15;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_get_font_size (NULL, &dblval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Text Symbolizer GetFontSize #2\n");
+	  *retcode += 16;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_get_label_placement_mode (NULL, &red) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Text Symbolizer GetLabelPlacementMode #2\n");
+	  *retcode += 17;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_get_point_placement_anchor_point
+	(NULL, &dblval, &dblval2) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Text Symbolizer GetPointPlacementAnchorPoint #2\n");
+	  *retcode += 18;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_get_point_placement_displacement
+	(NULL, &dblval, &dblval2) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Text Symbolizer GetPointPlacementDisplacement #2\n");
+	  *retcode += 19;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_get_point_placement_rotation (NULL, &dblval) ==
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Text Symbolizer GetPointPlacementRotation #2\n");
+	  *retcode += 20;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_get_line_placement_perpendicular_offset
+	(NULL, &dblval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Text Symbolizer GetLinePlacementPerpendicularOffset #2\n");
+	  *retcode += 21;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_get_line_placement_is_repeated (NULL, &intval) ==
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Text Symbolizer GetLinePlacementIsRepeated #2\n");
+	  *retcode += 22;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_get_line_placement_initial_gap (NULL, &dblval) ==
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Text Symbolizer GetLinePlacementInitialGap #2\n");
+	  *retcode += 23;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_get_line_placement_gap (NULL, &dblval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Text Symbolizer GetLinePlacementGap #2\n");
+	  *retcode += 24;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_get_line_placement_is_aligned (NULL, &intval) ==
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Text Symbolizer GetLinePlacementIsAligned #2\n");
+	  *retcode += 25;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_get_line_placement_generalize_line (NULL, &intval)
+	== RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Text Symbolizer GetLinePlacementGeneralizeLine #2\n");
+	  *retcode += 26;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_has_halo (NULL, &intval) == RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected success: Text Symbolizer HasHalo #2\n");
+	  *retcode += 27;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_get_halo_radius (NULL, &dblval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Text Symbolizer GetHaloRadius #2\n");
+	  *retcode += 28;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_has_halo_fill (NULL, &intval) == RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Text Symbolizer HasHaloFill #2\n");
+	  *retcode += 29;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_get_halo_fill_color (NULL, &red, &green, &blue) ==
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Text Symbolizer GetHaloFillColor #2\n");
+	  *retcode += 30;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_has_fill (NULL, &intval) == RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected success: Text Symbolizer HasFill #2\n");
+	  *retcode += 31;
+	  return 0;
+      }
+
+    if (rl2_text_symbolizer_get_fill_color (NULL, &red, &green, &blue) ==
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "Unexpected success: Text Symbolizer GetFillColor #2\n");
+	  *retcode += 32;
+	  return 0;
+      }
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #1\n");
+	  *retcode += 33;
+	  return 0;
+      }
+    string = "*emilia#Romagna";
+    if (rl2_set_variant_text (value, 0, "name", string, strlen (string)) !=
+	RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #1\n");
+	  *retcode += 34;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #2\n",
+		   style_name);
+	  *retcode += 35;
+	  return 0;
+      }
+    text = rl2_get_text_symbolizer (symbolizer, 0);
+    if (text == NULL)
+      {
+	  fprintf (stderr, "Unable to get Text Symbolizer #2\n");
+	  *retcode += 36;
+	  return 0;
+      }
+    if (rl2_text_symbolizer_get_fill_color (text, &red, &green, &blue) !=
+	RL2_OK)
+      {
+	  fprintf (stderr, "Unable to get Text Symbolizer GetFillColor #2\n");
+	  *retcode += 37;
+	  return 0;
+      }
+    if (red != 0x60 || green != 0x72 || blue != 0x84)
+      {
+	  fprintf (stderr,
+		   "Unexpected Text Symbolizer GetStrokeColor #2: %02x%02x%02x\n",
+		   red, green, blue);
+	  *retcode += 38;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    value = rl2_create_variant_array (1);
+    if (value == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VariantArray #2\n");
+	  *retcode += 39;
+	  return 0;
+      }
+    string = "*em*lia#Romagnola";
+    if (rl2_set_variant_text (value, 0, "name", string, strlen (string)) !=
+	RL2_OK)
+      {
+	  fprintf (stderr, "Unexpected failure: SetVariantValue #2\n");
+	  *retcode += 40;
+	  return 0;
+      }
+    symbolizer =
+	rl2_get_symbolizer_from_feature_type_style (style, 5000000.0, value,
+						    &scale_forbidden);
+    if (symbolizer == NULL)
+      {
+	  fprintf (stderr, "Unexpected NULL VectorSymbolizer (%s) #3\n",
+		   style_name);
+	  *retcode += 41;
+	  return 0;
+      }
+    text = rl2_get_text_symbolizer (symbolizer, 0);
+    if (text == NULL)
+      {
+	  fprintf (stderr, "Unable to get Text Symbolizer #3\n");
+	  *retcode += 42;
+	  return 0;
+      }
+    if (rl2_text_symbolizer_get_fill_color (text, &red, &green, &blue) !=
+	RL2_OK)
+      {
+	  fprintf (stderr, "Unable to get Text Symbolizer GetFillColor #3\n");
+	  *retcode += 43;
+	  return 0;
+      }
+    if (red != 0x60 || green != 0x72 || blue != 0x84)
+      {
+	  fprintf (stderr,
+		   "Unexpected Text Symbolizer GetStrokeColor #3: %02x%02x%02x\n",
+		   red, green, blue);
+	  *retcode += 44;
+	  return 0;
+      }
+    rl2_destroy_variant_array (value);
+
+    intval = rl2_get_feature_type_style_columns_count (style);
+    if (intval != 2)
+      {
+	  fprintf (stderr,
+		   "Unexpected GetFeatureTypeStyleColumnsCount #1: %d\n",
+		   intval);
+	  *retcode += 45;
+	  return 0;
+      }
+
+    string = rl2_get_feature_type_style_column_name (style, 0);
+    if (strcasecmp (string, "name") != 0)
+      {
+	  fprintf (stderr,
+		   "Unexpected GetFeatureTypeStyleColumnName #1: \"%s\"\n",
+		   string);
+	  *retcode += 46;
+	  return 0;
+      }
+
+    string = rl2_get_feature_type_style_column_name (style, 1);
+    if (strcasecmp (string, "some_column") != 0)
+      {
+	  fprintf (stderr,
+		   "Unexpected GetFeatureTypeStyleColumnName #2: \"%s\"\n",
+		   string);
+	  *retcode += 47;
+	  return 0;
+      }
+
+    intval = rl2_get_feature_type_style_columns_count (NULL);
+    if (intval != 0)
+      {
+	  fprintf (stderr,
+		   "Unexpected GetFeatureTypeStyleColumnsCount #2: %d\n",
+		   intval);
+	  *retcode += 48;
+	  return 0;
+      }
+
+    rl2_destroy_feature_type_style (style);
+    return 1;
+}
+
+int
+main (int argc, char *argv[])
+{
+    int result = 0;
+    int ret;
+    sqlite3 *db_handle;
+    void *cache = spatialite_alloc_connection ();
+
+    if (argc > 1 || argv[0] == NULL)
+	argc = 1;		/* silencing stupid compiler warnings */
+
+/* opening and initializing the "memory" test DB */
+    ret = sqlite3_open_v2 ("symbolizers.sqlite", &db_handle,
+			   SQLITE_OPEN_READONLY, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "sqlite3_open_v2() error: %s\n",
+		   sqlite3_errmsg (db_handle));
+	  return -1;
+      }
+    spatialite_init_ex (db_handle, cache, 0);
+
+/* tests */
+    ret = -100;
+    if (!test_symbolizer (db_handle, "points", "label_1", &ret))
+	return ret;
+    ret = -200;
+    if (!test_symbolizer (db_handle, "lines", "label_2", &ret))
+	return ret;
+    ret = -300;
+    if (!test_symbolizer (db_handle, "points", "label_3", &ret))
+	return ret;
+    ret = -400;
+    if (!test_style (db_handle, "lines", "text_style", &ret))
+	return ret;
+
+/* closing the DB */
+    sqlite3_close (db_handle);
+    spatialite_shutdown ();
+    return result;
+}
diff --git a/test/test_tifin.c b/test/test_tifin.c
index 6c2ebd0..5080a2a 100644
--- a/test/test_tifin.c
+++ b/test/test_tifin.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -136,31 +136,34 @@ test_tiff (const char *name, unsigned char sample_type,
 	  return -2;
       }
 
-    if (rl2_eval_tiff_origin_compatibility (coverage, origin, -1) != RL2_TRUE)
+    if (rl2_eval_tiff_origin_compatibility (coverage, origin, -1, 0) !=
+	RL2_TRUE)
       {
 	  fprintf (stderr, "Coverage/TIFF mismatch: %s\n", name);
 	  return -3;
       }
 
-    if (rl2_get_tile_from_tiff_origin (coverage, origin, 1, 0, -1) != NULL)
+    if (rl2_get_tile_from_tiff_origin (coverage, origin, 1, 0, -1, 0) != NULL)
       {
 	  fprintf (stderr, "Unexpected result: startRow mismatch\n");
 	  return -4;
       }
 
-    if (rl2_get_tile_from_tiff_origin (coverage, origin, 0, 1, -1) != NULL)
+    if (rl2_get_tile_from_tiff_origin (coverage, origin, 0, 1, -1, 0) != NULL)
       {
 	  fprintf (stderr, "Unexpected result: startCol mismatch\n");
 	  return -5;
       }
 
-    if (rl2_get_tile_from_tiff_origin (coverage, origin, 22000, 0, -1) != NULL)
+    if (rl2_get_tile_from_tiff_origin (coverage, origin, 22000, 0, -1, 0) !=
+	NULL)
       {
 	  fprintf (stderr, "Unexpected result: startRow too big\n");
 	  return -6;
       }
 
-    if (rl2_get_tile_from_tiff_origin (coverage, origin, 0, 22000, -1) != NULL)
+    if (rl2_get_tile_from_tiff_origin (coverage, origin, 0, 22000, -1, 0) !=
+	NULL)
       {
 	  fprintf (stderr, "Unexpected result: startCol too big\n");
 	  return -7;
@@ -222,7 +225,7 @@ test_tiff (const char *name, unsigned char sample_type,
 		sprintf (tile_name, "%s_%04d_%04d", name, row, col);
 		raster =
 		    rl2_get_tile_from_tiff_origin (coverage, origin, row, col,
-						   -1);
+						   -1, 0);
 		if (raster == NULL)
 		  {
 		      fprintf (stderr,
@@ -390,27 +393,27 @@ test_null ()
     coverage =
 	rl2_create_coverage ("alpha", RL2_SAMPLE_UINT8, RL2_PIXEL_GRAYSCALE, 1,
 			     RL2_COMPRESSION_PNG, 0, 432, 432, NULL);
-    raster = rl2_get_tile_from_tiff_origin (NULL, origin, 0, 0, -1);
+    raster = rl2_get_tile_from_tiff_origin (NULL, origin, 0, 0, -1, 0);
     if (raster != NULL)
       {
 	  fprintf (stderr,
 		   "Unexpected success: TIFF Get Tile - NULL coverage\n");
 	  return -43;
       }
-    raster = rl2_get_tile_from_tiff_origin (coverage, NULL, 0, 0, -1);
+    raster = rl2_get_tile_from_tiff_origin (coverage, NULL, 0, 0, -1, 0);
     if (raster != NULL)
       {
 	  fprintf (stderr, "Unexpected success: TIFF Get Tile - NULL origin\n");
 	  return -44;
       }
-    raster = rl2_get_tile_from_tiff_origin (coverage, origin, 3, 0, -1);
+    raster = rl2_get_tile_from_tiff_origin (coverage, origin, 3, 0, -1, 0);
     if (raster != NULL)
       {
 	  fprintf (stderr,
 		   "Unexpected success: TIFF Get Tile - invalid tile row\n");
 	  return -45;
       }
-    raster = rl2_get_tile_from_tiff_origin (coverage, origin, 0, 3, -1);
+    raster = rl2_get_tile_from_tiff_origin (coverage, origin, 0, 3, -1, 0);
     if (raster != NULL)
       {
 	  fprintf (stderr,
@@ -530,19 +533,20 @@ test_null ()
     coverage =
 	rl2_create_coverage ("alpha", RL2_SAMPLE_4_BIT, RL2_PIXEL_PALETTE, 1,
 			     RL2_COMPRESSION_PNG, 0, 432, 432, NULL);
-    if (rl2_eval_tiff_origin_compatibility (NULL, origin, -1) == RL2_TRUE)
+    if (rl2_eval_tiff_origin_compatibility (NULL, origin, -1, 0) == RL2_TRUE)
       {
 	  fprintf (stderr,
 		   "Unexpected success: TIFF Compatibility - NULL Coverage\n");
 	  return -62;
       }
-    if (rl2_eval_tiff_origin_compatibility (coverage, NULL, -1) == RL2_TRUE)
+    if (rl2_eval_tiff_origin_compatibility (coverage, NULL, -1, 0) == RL2_TRUE)
       {
 	  fprintf (stderr,
 		   "Unexpected success: TIFF Compatibility - NULL origin\n");
 	  return -63;
       }
-    if (rl2_eval_tiff_origin_compatibility (coverage, origin, -1) == RL2_TRUE)
+    if (rl2_eval_tiff_origin_compatibility (coverage, origin, -1, 0) ==
+	RL2_TRUE)
       {
 	  fprintf (stderr,
 		   "Unexpected success: TIFF Compatibility - mismatching sample\n");
@@ -552,7 +556,8 @@ test_null ()
     coverage =
 	rl2_create_coverage ("alpha", RL2_SAMPLE_UINT8, RL2_PIXEL_PALETTE, 1,
 			     RL2_COMPRESSION_PNG, 0, 432, 432, NULL);
-    if (rl2_eval_tiff_origin_compatibility (coverage, origin, -1) == RL2_TRUE)
+    if (rl2_eval_tiff_origin_compatibility (coverage, origin, -1, 0) ==
+	RL2_TRUE)
       {
 	  fprintf (stderr,
 		   "Unexpected success: TIFF Compatibility - mismatching pixel\n");
diff --git a/test/test_vectors.c b/test/test_vectors.c
new file mode 100644
index 0000000..fbacd83
--- /dev/null
+++ b/test/test_vectors.c
@@ -0,0 +1,199 @@
+/*
+
+ test_vectors.c -- RasterLite-2 Test Case
+
+ Author: Sandro Furieri <a.furieri at lqt.it>
+
+ ------------------------------------------------------------------------------
+ 
+ Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ 
+ The contents of this file are subject to the Mozilla Public License Version
+ 1.1 (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+ http://www.mozilla.org/MPL/
+ 
+Software distributed under the License is distributed on an "AS IS" basis,
+WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+for the specific language governing rights and limitations under the
+License.
+
+The Original Code is the RasterLite2 library
+
+The Initial Developer of the Original Code is Alessandro Furieri
+ 
+Portions created by the Initial Developer are Copyright (C) 2015
+the Initial Developer. All Rights Reserved.
+
+Contributor(s):
+
+Alternatively, the contents of this file may be used under the terms of
+either the GNU General Public License Version 2 or later (the "GPL"), or
+the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+in which case the provisions of the GPL or the LGPL are applicable instead
+of those above. If you wish to allow use of your version of this file only
+under the terms of either the GPL or the LGPL, and not to allow others to
+use your version of this file under the terms of the MPL, indicate your
+decision by deleting the provisions above and replace them with the notice
+and other provisions required by the GPL or the LGPL. If you do not delete
+the provisions above, a recipient may use your version of this file under
+the terms of any one of the MPL, the GPL or the LGPL.
+ 
+*/
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "sqlite3.h"
+#include "spatialite.h"
+
+#include "rasterlite2/rasterlite2.h"
+
+static int
+test_default_style (sqlite3 * sqlite, int *retcode)
+{
+/* testing Default style */
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+    const char *sql = "SELECT coverage_name, "
+	"GetMapImageFromVector(coverage_name, BuildMbr(-180,-90,180,90), 1024, 512) "
+	"FROM vector_coverages WHERE coverage_name like 'test_%'";
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "SQL error #1: %s\n", sqlite3_errmsg (sqlite));
+	  *retcode += -1;
+	  return 0;
+      }
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	    {
+		const char *name = (const char *) sqlite3_column_text (stmt, 0);
+		unsigned char *blob =
+		    (unsigned char *) sqlite3_column_blob (stmt, 1);
+		int blob_sz = sqlite3_column_bytes (stmt, 1);
+		char *path = sqlite3_mprintf ("./vector_%s_default.png", name);
+		FILE *out = fopen (path, "wb");
+		if (out != NULL)
+		  {
+		      fwrite (blob, 1, blob_sz, out);
+		      fclose (out);
+		      unlink (path);
+		  }
+		sqlite3_free (path);
+	    }
+	  else
+	    {
+		fprintf (stderr,
+			 "sqlite3_step() error #1: %s\n",
+			 sqlite3_errmsg (sqlite));
+		*retcode += -2;
+		sqlite3_finalize (stmt);
+		return 0;
+	    }
+      }
+
+    sqlite3_finalize (stmt);
+    return 1;
+}
+
+static int
+test_styles (sqlite3 * sqlite, int *retcode)
+{
+/* testing Styles */
+    int ret;
+    sqlite3_stmt *stmt = NULL;
+    const char *sql = "SELECT coverage_name, name, "
+	"GetMapImageFromVector(coverage_name, BuildMbr(-180,-90,180,90), 1024, 512, name) "
+	"FROM SE_vector_styled_layers_view WHERE coverage_name like 'test_%'";
+    ret = sqlite3_prepare_v2 (sqlite, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "SQL error #2: %s\n", sqlite3_errmsg (sqlite));
+	  *retcode += -1;
+	  return 0;
+      }
+    while (1)
+      {
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;
+	  if (ret == SQLITE_ROW)
+	    {
+		const char *name = (const char *) sqlite3_column_text (stmt, 0);
+		const char *style =
+		    (const char *) sqlite3_column_text (stmt, 1);
+		unsigned char *blob =
+		    (unsigned char *) sqlite3_column_blob (stmt, 2);
+		int blob_sz = sqlite3_column_bytes (stmt, 2);
+		char *path =
+		    sqlite3_mprintf ("./vector_%s_%s.png", name, style);
+		FILE *out = fopen (path, "wb");
+		if (out != NULL)
+		  {
+		      fwrite (blob, 1, blob_sz, out);
+		      fclose (out);
+		      unlink (path);
+		  }
+		sqlite3_free (path);
+	    }
+	  else
+	    {
+		fprintf (stderr,
+			 "sqlite3_step() error #1: %s\n",
+			 sqlite3_errmsg (sqlite));
+		*retcode += -2;
+		sqlite3_finalize (stmt);
+		return 0;
+	    }
+      }
+
+    sqlite3_finalize (stmt);
+    return 1;
+}
+
+int
+main (int argc, char *argv[])
+{
+    int result = 0;
+    int ret;
+    sqlite3 *db_handle;
+    void *cache = spatialite_alloc_connection ();
+    void *priv_data = rl2_alloc_private ();
+
+    if (argc > 1 || argv[0] == NULL)
+	argc = 1;		/* silencing stupid compiler warnings */
+
+/* opening and initializing the "memory" test DB */
+    ret = sqlite3_open_v2 ("symbolizers.sqlite", &db_handle,
+			   SQLITE_OPEN_READONLY, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "sqlite3_open_v2() error: %s\n",
+		   sqlite3_errmsg (db_handle));
+	  return -1;
+      }
+    spatialite_init_ex (db_handle, cache, 0);
+    rl2_init (db_handle, priv_data, 0);
+
+/* tests */
+    ret = -100;
+    if (!test_default_style (db_handle, &ret))
+	return ret;
+    ret = -200;
+    if (!test_styles (db_handle, &ret))
+	return ret;
+
+/* closing the DB */
+    sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
+    spatialite_shutdown ();
+    return result;
+}
diff --git a/test/test_webp.c b/test/test_webp.c
index 48ba8f9..d279176 100644
--- a/test/test_webp.c
+++ b/test/test_webp.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -44,8 +44,12 @@ the terms of any one of the MPL, the GPL or the LGPL.
 #include <stdio.h>
 #include <memory.h>
 
+#include "config.h"
+
 #include "rasterlite2/rasterlite2.h"
 
+#ifndef OMIT_WEBP		/* only if WebP is enabled */
+
 static int
 test_no_alpha_webp (const char *path)
 {
@@ -628,14 +632,18 @@ test_no_alpha_webp (const char *path)
     return 1;
 }
 
+#endif /* end WebP conditional */
+
 int
 main (int argc, char *argv[])
 {
     if (argc > 1 || argv[0] == NULL)
 	argc = 1;		/* silencing stupid compiler warnings */
 
+#ifndef OMIT_WEBP
     if (!test_no_alpha_webp ("./webp_no_alpha.webp"))
 	return -1;
+#endif
 
     return 0;
 }
diff --git a/test/test_wms1.c b/test/test_wms1.c
index 6885c2b..8909fd3 100644
--- a/test/test_wms1.c
+++ b/test/test_wms1.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -156,7 +156,7 @@ test_GetCapabilities_tuscany (rl2WmsCachePtr cache)
 	    }
       }
     count = get_wms_layer_crs_count (layer);
-    if (count != 5)
+    if (count != 8)
       {
 	  fprintf (stderr, "GetWmsLayerCrsCount: unexpected result %d\n",
 		   count);
@@ -222,7 +222,7 @@ test_GetCapabilities_tuscany (rl2WmsCachePtr cache)
 
 /* testing Child Layer */
     count = get_wms_layer_children_count (layer);
-    if (count != 12)
+    if (count != 13)
       {
 	  fprintf (stderr, "GetWmsLayerChildrenCount: unexpected result %d\n",
 		   count);
@@ -273,7 +273,7 @@ test_GetCapabilities_tuscany (rl2WmsCachePtr cache)
 	    }
       }
     count = get_wms_layer_crs_count (child);
-    if (count != 6)
+    if (count != 9)
       {
 	  fprintf (stderr,
 		   "GetWmsLayerCrsCount (Child): unexpected result %d\n",
@@ -281,9 +281,10 @@ test_GetCapabilities_tuscany (rl2WmsCachePtr cache)
 	  return -30;
       }
     str = get_wms_layer_crs (child, 3);
-    if (strcmp (str, "EPSG:4326") != 0)
+    if (strcmp (str, "EPSG:3003") != 0)
       {
-	  fprintf (stderr, "GetWmsLayerCRS (Child): unexpected result \"%s\"\n",
+	  fprintf (stderr,
+		   "GetWmsLayerCRS (Child) #1: unexpected result \"%s\"\n",
 		   str);
 	  return -31;
       }
@@ -712,7 +713,8 @@ test_GetCapabilities_arizona (rl2WmsCachePtr cache)
     str = get_wms_layer_crs (child, 3);
     if (strcmp (str, "EPSG:3857") != 0)
       {
-	  fprintf (stderr, "GetWmsLayerCRS (Child): unexpected result \"%s\"\n",
+	  fprintf (stderr,
+		   "GetWmsLayerCRS (Child) #2: unexpected result \"%s\"\n",
 		   str);
 	  return -131;
       }
@@ -1126,7 +1128,8 @@ test_GetCapabilities_rer (rl2WmsCachePtr cache)
     str = get_wms_layer_crs (child, 3);
     if (strcmp (str, "EPSG:3857") != 0)
       {
-	  fprintf (stderr, "GetWmsLayerCRS (Child): unexpected result \"%s\"\n",
+	  fprintf (stderr,
+		   "GetWmsLayerCRS (Child) #3: unexpected result \"%s\"\n",
 		   str);
 	  return -131;
       }
@@ -1353,6 +1356,8 @@ test_GetFeatureInfo_gml ()
     double my;
     double ratio;
     sqlite3 *sqlite;
+    const unsigned char *blob;
+    int blob_sz;
     gaiaGeomCollPtr geom;
     void *cache = spatialite_alloc_connection ();
 
@@ -1428,11 +1433,18 @@ test_GetFeatureInfo_gml ()
 		   count);
 	  return -206;
       }
-    geom = get_wms_feature_attribute_geometry (ftr, 0);
+    if (get_wms_feature_attribute_blob_geometry (ftr, 0, &blob, &blob_sz) !=
+	RL2_OK)
+      {
+	  fprintf (stderr,
+		   "GetFeatureAttributeValue (GML-Geom): unexpected failure\n");
+	  return -207;
+      }
+    geom = gaiaFromSpatiaLiteBlobWkb (blob, blob_sz);
     if (geom == NULL)
       {
 	  fprintf (stderr,
-		   "GetFeatureAttributeValue (GML-Geom): unexpected NULL\n");
+		   "GetFeatureAttributeValue (GML-Geom): unexpected failure\n");
 	  return -207;
       }
     else if (geom->Srid != 3003)
@@ -1442,6 +1454,7 @@ test_GetFeatureInfo_gml ()
 		   geom->Srid);
 	  return -208;
       }
+    gaiaFreeGeomColl (geom);
     str = get_wms_feature_attribute_name (ftr, 4);
     if (strcmp (str, "CODCOM") != 0)
       {
@@ -1458,8 +1471,8 @@ test_GetFeatureInfo_gml ()
 		   str);
 	  return -210;
       }
-    geom = get_wms_feature_attribute_geometry (ftr, 4);
-    if (geom != NULL)
+    if (get_wms_feature_attribute_blob_geometry (ftr, 4, &blob, &blob_sz) !=
+	RL2_ERROR)
       {
 	  fprintf (stderr,
 		   "GetFeatureAttributeValue (GML-Geom): unexpected result\n");
@@ -1497,7 +1510,8 @@ test_GetFeatureInfo_xml ()
     double my;
     double ratio;
     sqlite3 *sqlite;
-    gaiaGeomCollPtr geom;
+    const unsigned char *blob;
+    int blob_sz;
     void *cache = spatialite_alloc_connection ();
 
     ret =
@@ -1569,8 +1583,8 @@ test_GetFeatureInfo_xml ()
 		   str);
 	  return -306;
       }
-    geom = get_wms_feature_attribute_geometry (ftr, 0);
-    if (geom != NULL)
+    if (get_wms_feature_attribute_blob_geometry (ftr, 0, &blob, &blob_sz) !=
+	RL2_ERROR)
       {
 	  fprintf (stderr,
 		   "GetFeatureAttributeValue (XML-Geom): unexpected value\n");
@@ -1623,6 +1637,14 @@ main (int argc, char *argv[])
     if (argc > 1 || argv[0] == NULL)
 	argc = 1;		/* silencing stupid compiler warnings */
 
+    if (getenv ("ENABLE_RL2_WEB_TESTS") == NULL)
+      {
+	  fprintf (stderr, "this testcase has been skipped !!!\n\n"
+		   "you can enable all testcases requiring an Internet connection\n"
+		   "by setting the environment variable \"ENABLE_RL2_WEB_TESTS=1\"\n");
+	  return 0;
+      }
+
 /* creating a WMS-Cache */
     cache = create_wms_cache ();
     if (cache == NULL)
@@ -1771,7 +1793,7 @@ main (int argc, char *argv[])
 	  return -91;
       }
     val = get_wms_cache_current_size (cache);
-    if (val != 4526)
+    if (val != 3395)
       {
 	  fprintf (stderr, "GetWmsCacheCurrentSize: unexpected result %d\n",
 		   val);
@@ -1797,7 +1819,7 @@ main (int argc, char *argv[])
 	  return -95;
       }
     dblval = get_wms_total_download_size (cache);
-    if (dblval != 50030.00)
+    if (dblval != 57552.00)
       {
 	  fprintf (stderr, "GetWmsTotalDownloadSize: unexpected result %1.2f\n",
 		   dblval);
diff --git a/test/test_wms2.c b/test/test_wms2.c
index 6ca4b8d..31cc716 100644
--- a/test/test_wms2.c
+++ b/test/test_wms2.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -419,9 +419,9 @@ test_GetCapabilities (rl2WmsCachePtr cache)
 		   str);
 	  return -49;
       }
-    str = get_wms_tile_pattern_sample_url (pattern);
+    xurl = get_wms_tile_pattern_sample_url (pattern);
     if (strcmp
-	(str,
+	(xurl,
 	 "request=GetMap&layers=global_mosaic&srs=EPSG:4326&format=image/jpeg&styles=visual&width=512&height=512&bbox=-180,58,-148,90")
 	!= 0)
       {
@@ -430,6 +430,7 @@ test_GetCapabilities (rl2WmsCachePtr cache)
 		   str);
 	  return -50;
       }
+    free (xurl);
     int_res = get_wms_tile_pattern_tile_width (layer, 0);
     if (int_res != 512)
       {
@@ -614,6 +615,14 @@ main (int argc, char *argv[])
     if (argc > 1 || argv[0] == NULL)
 	argc = 1;		/* silencing stupid compiler warnings */
 
+    if (getenv ("ENABLE_RL2_WEB_TESTS") == NULL)
+      {
+	  fprintf (stderr, "this testcase has been skipped !!!\n\n"
+		   "you can enable all testcases requiring an Internet connection\n"
+		   "by setting the environment variable \"ENABLE_RL2_WEB_TESTS=1\"\n");
+	  return 0;
+      }
+
 /* creating a WMS-Cache */
     cache = create_wms_cache ();
     if (cache == NULL)
diff --git a/test/test_wr_tiff.c b/test/test_wr_tiff.c
index 0071bb7..d9bcd73 100644
--- a/test/test_wr_tiff.c
+++ b/test/test_wr_tiff.c
@@ -18,7 +18,7 @@ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.
 
-The Original Code is the SpatiaLite library
+The Original Code is the RasterLite2 library
 
 The Initial Developer of the Original Code is Alessandro Furieri
  
@@ -1567,7 +1567,8 @@ check_origin (const char *path, const char *tfw_path, int srid, double minx,
 	    {
 		fprintf (stderr, "ERROR: unable to create a Pixel\n");
 	    }
-	  raster = rl2_get_tile_from_tiff_origin (coverage, origin, 0, 0, -1);
+	  raster =
+	      rl2_get_tile_from_tiff_origin (coverage, origin, 0, 0, -1, 0);
 	  if (raster == NULL)
 	    {
 		fprintf (stderr, "ERROR: unable to retrieve a TIFF tile (1)\n");
@@ -1706,7 +1707,7 @@ check_origin (const char *path, const char *tfw_path, int srid, double minx,
 	    };
 	  rl2_destroy_raster (raster);
 	  raster =
-	      rl2_get_tile_from_tiff_origin (coverage, origin, 512, 512, -1);
+	      rl2_get_tile_from_tiff_origin (coverage, origin, 512, 512, -1, 0);
 	  if (raster == NULL)
 	    {
 		fprintf (stderr, "ERROR: unable to retrieve a TIFF tile (2)\n");
@@ -4627,7 +4628,7 @@ do_one_grid_double_test (const unsigned char *rgb, sqlite3 * handle,
     rl2RasterPtr raster;
     int tile_size = 128;
     const char *tfw_path;
-    char *tfw;
+    char *tfw = NULL;
     unsigned char xsample_type;
     unsigned char xpixel_type;
     unsigned char alias_pixel_type;
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 94c2150..09684ee 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -1,20 +1,27 @@
 AM_CFLAGS = @LIBPNG_CFLAGS@ @LIBWEBP_CFLAGS@ @LIBLZMA_CFLAGS@ \
 	@LIBSPATIALITE_CFLAGS@ @LIBCAIRO_CFLAGS@ @LIBCURL_CFLAGS@ \
-	@LIBXML2_CFLAGS@
+	@LIBXML2_CFLAGS@ @LIBFREETYPE2_CFLAGS@
 AM_LDFLAGS = -L../src 
 
-bin_PROGRAMS = rl2tool wmslite
+bin_PROGRAMS = rl2sniff rl2tool wmslite
 
 AM_CPPFLAGS = @CFLAGS@
 AM_CPPFLAGS += -I$(top_srcdir)/headers
 
+rl2sniff_SOURCES = rl2sniff.c
+
 rl2tool_SOURCES = rl2tool.c
 
 wmslite_SOURCES = wmslite.c
 
+rl2sniff_LDADD = @LIBPNG_LIBS@ @LIBWEBP_LIBS@ @LIBLZMA_LIBS@ \
+	@LIBSPATIALITE_LIBS@ @LIBCAIRO_LIBS@ @LIBCURL_LIBS@ \
+	@LIBXML2_LIBS@ @LIBFREETYPE2_LIBS@ \
+	-lrasterlite2 
+	
 rl2tool_LDADD = @LIBPNG_LIBS@ @LIBWEBP_LIBS@ @LIBLZMA_LIBS@ \
 	@LIBSPATIALITE_LIBS@ @LIBCAIRO_LIBS@ @LIBCURL_LIBS@ \
-	@LIBXML2_LIBS@ \
+	@LIBXML2_LIBS@ @LIBFREETYPE2_LIBS@ \
 	-lrasterlite2 
 
 if MINGW
@@ -25,7 +32,7 @@ wmslite_LDADD = @LIBPNG_LIBS@ @LIBWEBP_LIBS@ @LIBLZMA_LIBS@ \
 else
 wmslite_LDADD = @LIBPNG_LIBS@ @LIBWEBP_LIBS@ @LIBLZMA_LIBS@ \
 	@LIBSPATIALITE_LIBS@ @LIBCAIRO_LIBS@ @LIBCURL_LIBS@ \
-	@LIBXML2_LIBS@ \
+	@LIBXML2_LIBS@ @LIBFREETYPE2_LIBS@ \
 	-lrasterlite2 
 endif
 
diff --git a/tools/Makefile.in b/tools/Makefile.in
index 496f7c0..38016a2 100644
--- a/tools/Makefile.in
+++ b/tools/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.13.4 from Makefile.am.
+# Makefile.in generated by automake 1.15 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -15,7 +15,17 @@
 @SET_MAKE@
 
 VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
 am__make_running_with_option = \
   case $${target_option-} in \
       ?) ;; \
@@ -78,10 +88,8 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-bin_PROGRAMS = rl2tool$(EXEEXT) wmslite$(EXEEXT)
+bin_PROGRAMS = rl2sniff$(EXEEXT) rl2tool$(EXEEXT) wmslite$(EXEEXT)
 subdir = tools
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
-	$(top_srcdir)/depcomp
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
@@ -89,19 +97,23 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 am__installdirs = "$(DESTDIR)$(bindir)"
 PROGRAMS = $(bin_PROGRAMS)
-am_rl2tool_OBJECTS = rl2tool.$(OBJEXT)
-rl2tool_OBJECTS = $(am_rl2tool_OBJECTS)
-rl2tool_DEPENDENCIES =
+am_rl2sniff_OBJECTS = rl2sniff.$(OBJEXT)
+rl2sniff_OBJECTS = $(am_rl2sniff_OBJECTS)
+rl2sniff_DEPENDENCIES =
 AM_V_lt = $(am__v_lt_ at AM_V@)
 am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
 am__v_lt_0 = --silent
 am__v_lt_1 = 
+am_rl2tool_OBJECTS = rl2tool.$(OBJEXT)
+rl2tool_OBJECTS = $(am_rl2tool_OBJECTS)
+rl2tool_DEPENDENCIES =
 am_wmslite_OBJECTS = wmslite.$(OBJEXT)
 wmslite_OBJECTS = $(am_wmslite_OBJECTS)
 wmslite_DEPENDENCIES =
@@ -139,8 +151,9 @@ AM_V_CCLD = $(am__v_CCLD_ at AM_V@)
 am__v_CCLD_ = $(am__v_CCLD_ at AM_DEFAULT_V@)
 am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
-SOURCES = $(rl2tool_SOURCES) $(wmslite_SOURCES)
-DIST_SOURCES = $(rl2tool_SOURCES) $(wmslite_SOURCES)
+SOURCES = $(rl2sniff_SOURCES) $(rl2tool_SOURCES) $(wmslite_SOURCES)
+DIST_SOURCES = $(rl2sniff_SOURCES) $(rl2tool_SOURCES) \
+	$(wmslite_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -165,6 +178,7 @@ am__define_uniq_tagged_files = \
   done | $(am__uniquify_input)`
 ETAGS = etags
 CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -196,6 +210,8 @@ ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 FGREP = @FGREP@
+FREETYPE2_CFLAGS = @FREETYPE2_CFLAGS@
+FREETYPE2_LIBS = @FREETYPE2_LIBS@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
@@ -208,6 +224,8 @@ LIBCAIRO_CFLAGS = @LIBCAIRO_CFLAGS@
 LIBCAIRO_LIBS = @LIBCAIRO_LIBS@
 LIBCURL_CFLAGS = @LIBCURL_CFLAGS@
 LIBCURL_LIBS = @LIBCURL_LIBS@
+LIBFREETYPE2_CFLAGS = @LIBFREETYPE2_CFLAGS@
+LIBFREETYPE2_LIBS = @LIBFREETYPE2_LIBS@
 LIBLZMA_CFLAGS = @LIBLZMA_CFLAGS@
 LIBLZMA_LIBS = @LIBLZMA_LIBS@
 LIBOBJS = @LIBOBJS@
@@ -306,20 +324,26 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 AM_CFLAGS = @LIBPNG_CFLAGS@ @LIBWEBP_CFLAGS@ @LIBLZMA_CFLAGS@ \
 	@LIBSPATIALITE_CFLAGS@ @LIBCAIRO_CFLAGS@ @LIBCURL_CFLAGS@ \
-	@LIBXML2_CFLAGS@
+	@LIBXML2_CFLAGS@ @LIBFREETYPE2_CFLAGS@
 
 AM_LDFLAGS = -L../src 
 AM_CPPFLAGS = @CFLAGS@ -I$(top_srcdir)/headers
+rl2sniff_SOURCES = rl2sniff.c
 rl2tool_SOURCES = rl2tool.c
 wmslite_SOURCES = wmslite.c
+rl2sniff_LDADD = @LIBPNG_LIBS@ @LIBWEBP_LIBS@ @LIBLZMA_LIBS@ \
+	@LIBSPATIALITE_LIBS@ @LIBCAIRO_LIBS@ @LIBCURL_LIBS@ \
+	@LIBXML2_LIBS@ @LIBFREETYPE2_LIBS@ \
+	-lrasterlite2 
+
 rl2tool_LDADD = @LIBPNG_LIBS@ @LIBWEBP_LIBS@ @LIBLZMA_LIBS@ \
 	@LIBSPATIALITE_LIBS@ @LIBCAIRO_LIBS@ @LIBCURL_LIBS@ \
-	@LIBXML2_LIBS@ \
+	@LIBXML2_LIBS@ @LIBFREETYPE2_LIBS@ \
 	-lrasterlite2 
 
 @MINGW_FALSE at wmslite_LDADD = @LIBPNG_LIBS@ @LIBWEBP_LIBS@ @LIBLZMA_LIBS@ \
 @MINGW_FALSE@	@LIBSPATIALITE_LIBS@ @LIBCAIRO_LIBS@ @LIBCURL_LIBS@ \
- at MINGW_FALSE@	@LIBXML2_LIBS@ \
+ at MINGW_FALSE@	@LIBXML2_LIBS@ @LIBFREETYPE2_LIBS@ \
 @MINGW_FALSE@	-lrasterlite2 
 
 @MINGW_TRUE at wmslite_LDADD = @LIBPNG_LIBS@ @LIBWEBP_LIBS@ @LIBLZMA_LIBS@ \
@@ -343,7 +367,6 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__confi
 	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
 	  $(AUTOMAKE) --gnu tools/Makefile
-.PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
 	  *config.status*) \
@@ -411,6 +434,10 @@ clean-binPROGRAMS:
 	echo " rm -f" $$list; \
 	rm -f $$list
 
+rl2sniff$(EXEEXT): $(rl2sniff_OBJECTS) $(rl2sniff_DEPENDENCIES) $(EXTRA_rl2sniff_DEPENDENCIES) 
+	@rm -f rl2sniff$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(rl2sniff_OBJECTS) $(rl2sniff_LDADD) $(LIBS)
+
 rl2tool$(EXEEXT): $(rl2tool_OBJECTS) $(rl2tool_DEPENDENCIES) $(EXTRA_rl2tool_DEPENDENCIES) 
 	@rm -f rl2tool$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(rl2tool_OBJECTS) $(rl2tool_LDADD) $(LIBS)
@@ -425,6 +452,7 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rl2sniff.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rl2tool.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/wmslite.Po at am__quote@
 
@@ -433,14 +461,14 @@ distclean-compile:
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c $<
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ $<
 
 .c.obj:
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+ at am__fastdepCC_FALSE@	$(AM_V_CC at am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
 
 .c.lo:
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -660,6 +688,8 @@ uninstall-am: uninstall-binPROGRAMS
 	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
 	tags tags-am uninstall uninstall-am uninstall-binPROGRAMS
 
+.PRECIOUS: Makefile
+
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/tools/rl2sniff.c b/tools/rl2sniff.c
new file mode 100644
index 0000000..4a6b83b
--- /dev/null
+++ b/tools/rl2sniff.c
@@ -0,0 +1,1487 @@
+/* 
+/ rl2sniff
+/
+/ a listing/sniffing tool supporting RasterLite2
+/
+/ version 1.0, 2014 August 12
+/
+/ Author: Sandro Furieri a.furieri at lqt.it
+/
+/ Copyright (C) 2014  Alessandro Furieri
+/
+/    This program is free software: you can redistribute it and/or modify
+/    it under the terms of the GNU General Public License as published by
+/    the Free Software Foundation, either version 3 of the License, or
+/    (at your option) any later version.
+/
+/    This program is distributed in the hope that it will be useful,
+/    but WITHOUT ANY WARRANTY; without even the implied warranty of
+/    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+/    GNU General Public License for more details.
+/
+/    You should have received a copy of the GNU General Public License
+/    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+/
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <float.h>
+#include <limits.h>
+#include <time.h>
+
+#include <sys/types.h>
+#if defined(_WIN32) && !defined(__MINGW32__)
+#include <io.h>
+#include <direct.h>
+#else
+#include <unistd.h>
+#include <dirent.h>
+#endif
+
+#include "config.h"
+
+/*
+/ the following patch supporting GeoTiff headers
+/ was kindly contributed by Brad Hards on 2011-09-02
+/ for libgaigraphics (the ancestor of librasterlite2)
+*/
+#ifdef HAVE_GEOTIFF_GEOTIFF_H
+#include <geotiff/geotiff.h>
+#include <geotiff/xtiffio.h>
+#include <geotiff/geo_tiffp.h>
+#include <geotiff/geo_keyp.h>
+#include <geotiff/geovalues.h>
+#include <geotiff/geo_normalize.h>
+#elif HAVE_LIBGEOTIFF_GEOTIFF_H
+#include <libgeotiff/geotiff.h>
+#include <libgeotiff/xtiffio.h>
+#include <libgeotiff/geo_tiffp.h>
+#include <libgeotiff/geo_keyp.h>
+#include <libgeotiff/geovalues.h>
+#include <libgeotiff/geo_normalize.h>
+#else
+#include <geotiff.h>
+#include <xtiffio.h>
+#include <geo_tiffp.h>
+#include <geo_keyp.h>
+#include <geovalues.h>
+#include <geo_normalize.h>
+#endif
+
+#include <rasterlite2/rasterlite2.h>
+#include <rasterlite2/rl2tiff.h>
+
+#include <spatialite/gaiaaux.h>
+#include <spatialite.h>
+
+#define ARG_NONE	0
+#define ARG_SRC_PATH	1
+#define ARG_DIR_PATH	2
+#define ARG_FILE_EXT	3
+
+#ifdef _WIN32
+#define strcasecmp	_stricmp
+#endif /* not WIN32 */
+
+static int
+parse_ncols (const char *str, unsigned int *width)
+{
+/* attempting to parse the NCOLS item */
+    if (strncasecmp (str, "ncols ", 6) == 0)
+      {
+	  *width = atoi (str + 6);
+	  return 1;
+      }
+    return 0;
+}
+
+static int
+parse_nrows (const char *str, unsigned int *height)
+{
+/* attempting to parse the NROWS item */
+    if (strncasecmp (str, "nrows ", 6) == 0)
+      {
+	  *height = atoi (str + 6);
+	  return 1;
+      }
+    return 0;
+}
+
+static int
+parse_xllcorner (const char *str, double *minx)
+{
+/* attempting to parse the XLLCORNER item */
+    if (strncasecmp (str, "xllcorner ", 10) == 0)
+      {
+	  *minx = atof (str + 10);
+	  return 1;
+      }
+    return 0;
+}
+
+static int
+parse_yllcorner (const char *str, double *miny)
+{
+/* attempting to parse the YLLCORNER item */
+    if (strncasecmp (str, "yllcorner ", 10) == 0)
+      {
+	  *miny = atof (str + 10);
+	  return 1;
+      }
+    return 0;
+}
+
+static int
+parse_xllcenter (const char *str, double *minx)
+{
+/* attempting to parse the XLLCENTER item */
+    if (strncasecmp (str, "xllcenter ", 10) == 0)
+      {
+	  *minx = atof (str + 10);
+	  return 1;
+      }
+    return 0;
+}
+
+static int
+parse_yllcenter (const char *str, double *miny)
+{
+/* attempting to parse the YLLCENTER item */
+    if (strncasecmp (str, "yllcenter ", 10) == 0)
+      {
+	  *miny = atof (str + 10);
+	  return 1;
+      }
+    return 0;
+}
+
+static int
+parse_cellsize (const char *str, double *xres)
+{
+/* attempting to parse the CELLSIZE item */
+    if (strncasecmp (str, "cellsize ", 9) == 0)
+      {
+	  *xres = atof (str + 9);
+	  return 1;
+      }
+    return 0;
+}
+
+static int
+parse_nodata (const char *str, double *no_data)
+{
+/* attempting to parse the NODATA_value item */
+    if (strncasecmp (str, "NODATA_value ", 13) == 0)
+      {
+	  *no_data = atof (str + 13);
+	  return 1;
+      }
+    return 0;
+}
+
+static int
+get_ascii_header (FILE * in, unsigned int *width, unsigned int *height,
+		  double *minx, double *miny, double *maxx, double *maxy,
+		  double *xres, double *yres, double *no_data)
+{
+/* attempting to parse the ASCII Header */
+    char buf[1024];
+    char *p_out = buf;
+    int line_no = 0;
+    int c;
+    int ok_ncols = 0;
+    int ok_nrows = 0;
+    int ok_xll = 0;
+    int ok_yll = 0;
+    int ok_cellsize = 0;
+    int ok_nodata = 0;
+
+    while ((c = getc (in)) != EOF)
+      {
+	  if (c == '\r')
+	      continue;
+	  if (c == '\n')
+	    {
+		*p_out = '\0';
+		if (parse_ncols (buf, width))
+		    ok_ncols++;
+		if (parse_nrows (buf, height))
+		    ok_nrows++;
+		if (parse_xllcorner (buf, minx))
+		    ok_xll++;
+		if (parse_xllcenter (buf, minx))
+		    ok_xll++;
+		if (parse_yllcorner (buf, miny))
+		    ok_yll++;
+		if (parse_yllcenter (buf, miny))
+		    ok_yll++;
+		if (parse_cellsize (buf, xres))
+		    ok_cellsize++;
+		if (parse_nodata (buf, no_data))
+		    ok_nodata++;
+		line_no++;
+		if (line_no == 6)
+		    break;
+		p_out = buf;
+		continue;
+	    }
+	  if ((p_out - buf) >= 1024)
+	      goto error;
+	  *p_out++ = c;
+      }
+    if (ok_ncols == 1 && ok_nrows == 1 && ok_xll == 1 && ok_yll == 1
+	&& ok_cellsize == 1 && ok_nodata == 1)
+	;
+    else
+	goto error;
+
+    *maxx = *minx + ((double) (*width) * *xres);
+    *yres = *xres;
+    *maxy = *miny + ((double) (*height) * *yres);
+    return 1;
+
+  error:
+    *width = 0;
+    *height = 0;
+    *minx = DBL_MAX;
+    *miny = DBL_MAX;
+    *maxx = 0.0 - DBL_MAX;
+    *maxy = 0.0 - DBL_MAX;
+    *xres = 0.0;
+    *yres = 0.0;
+    *no_data = DBL_MAX;
+    return 0;
+}
+
+static int
+is_ascii_grid (const char *path)
+{
+/* testing for an ASCII Grid */
+    int len = strlen (path);
+    if (len > 4)
+      {
+	  if (strcasecmp (path + len - 4, ".asc") == 0)
+	      return 1;
+      }
+    return 0;
+}
+
+static int
+is_jpeg_image (const char *path)
+{
+/* testing for a JPEG image */
+    int len = strlen (path);
+    if (len > 4)
+      {
+	  if (strcasecmp (path + len - 4, ".jpg") == 0)
+	      return 1;
+      }
+    return 0;
+}
+
+#ifndef OMIT_OPENJPEG		/* only if OpenJpeg is enabled */
+
+static int
+is_jpeg2000_image (const char *path)
+{
+/* testing for a Jpeg2000 image */
+    int len = strlen (path);
+    if (len > 4)
+      {
+	  if (strcasecmp (path + len - 4, ".jp2") == 0)
+	      return 1;
+      }
+    return 0;
+}
+
+#endif /* end OpenJpeg conditional */
+
+static void
+do_sniff_ascii_grid (const char *src_path, int with_md5)
+{
+/* sniffing an ASCII Grid */
+    FILE *in;
+    unsigned int width = 0;
+    unsigned int height = 0;
+    double minX = 0.0;
+    double minY = 0.0;
+    double maxX = 0.0;
+    double maxY = 0.0;
+    double x_res = 0.0;
+    double y_res = 0.0;
+    double no_data = 0.0;
+    char *md5 = NULL;
+
+    in = fopen (src_path, "rb");
+    if (in == NULL)
+	return;
+    if (!get_ascii_header
+	(in, &width, &height, &minX, &minY, &maxX, &maxY, &x_res, &y_res,
+	 &no_data))
+	goto error;
+
+    if (with_md5)
+	md5 = rl2_compute_file_md5_checksum (src_path);
+
+    printf
+	("ASCII Grid\t%s\t%s\t%u\t%u\t%s\t%s\t%u\t%1.8f\t%s\t%d\t%1.12f\t%1.12f\t%1.8f\t%1.8f\t%1.8f\t%1.8f\n",
+	 (md5 == NULL) ? "" : md5, src_path, width, height, "unkwnown",
+	 "DATAGRID", 1, no_data, "NONE", -1, x_res, y_res, minX, minY, maxX,
+	 maxY);
+
+  error:
+    if (md5)
+	free (md5);
+    if (in != NULL)
+	fclose (in);
+}
+
+static int
+is_valid_float (char *str)
+{
+/* testing for a valid worldfile float value */
+    char *p = str;
+    int point = 0;
+    int sign = 0;
+    int digit = 0;
+    int len = strlen (str);
+    int i;
+
+    for (i = len - 1; i >= 0; i--)
+      {
+	  /* suppressing any trailing blank */
+	  if (str[i] == ' ' || str[i] == '\t' || str[i] == '\r')
+	      str[i] = '\0';
+	  else
+	      break;
+      }
+
+    while (1)
+      {
+	  /* skipping leading blanks */
+	  if (*p != ' ' && *p != '\t')
+	      break;
+	  p++;
+      }
+
+/* testing for a well formatted float */
+    while (1)
+      {
+	  if (*p == '\0')
+	      break;
+	  if (*p >= '0' && *p <= '9')
+	      digit++;
+	  else if (*p == '.')
+	      point++;
+	  else if (*p == ',')
+	    {
+		*p = '.';
+		point++;
+	    }
+	  else if (*p == '+' || *p == '-')
+	    {
+		if (digit == 0 && point == 0 && sign == 0)
+		    ;
+		else
+		    return 0;
+	    }
+	  else
+	      return 0;
+	  p++;
+      }
+    if (digit > 0 && sign <= 1 && point <= 1)
+	return 1;
+    return 0;
+}
+
+static int
+parse_worldfile (const char *path, unsigned int width, unsigned int height,
+		 double *minx, double *miny, double *maxx, double *maxy,
+		 double *pres_x, double *pres_y)
+{
+/* attemtping to parse a WorldFile */
+    int line_no = 0;
+    int ok_res_x = 0;
+    int ok_res_y = 0;
+    int ok_x = 0;
+    int ok_y = 0;
+    char buf[1024];
+    char *p = buf;
+    double x = 0.0;
+    double y = 0.0;
+    double res_x = 0.0;
+    double res_y = 0.0;
+    FILE *in = fopen (path, "rb");
+
+    if (in == NULL)
+	return 0;
+
+    while (1)
+      {
+	  int c = getc (in);
+	  if (c == '\r')
+	      continue;
+	  if (c == '\n' || c == EOF)
+	    {
+		*p = '\0';
+		if (line_no == 0)
+		  {
+		      if (is_valid_float (buf))
+			{
+			    res_x = atof (buf);
+			    ok_res_x = 1;
+			}
+		  }
+		if (line_no == 3)
+		  {
+		      if (is_valid_float (buf))
+			{
+			    res_y = atof (buf) * -1.0;
+			    ok_res_y = 1;
+			}
+		  }
+		if (line_no == 4)
+		  {
+		      if (is_valid_float (buf))
+			{
+			    x = atof (buf);
+			    ok_x = 1;
+			}
+		  }
+		if (line_no == 5)
+		  {
+		      if (is_valid_float (buf))
+			{
+			    y = atof (buf);
+			    ok_y = 1;
+			}
+		  }
+		if (c == EOF)
+		    break;
+		p = buf;
+		line_no++;
+		continue;
+	    }
+	  *p++ = c;
+      }
+    fclose (in);
+
+    if (ok_x && ok_y && ok_res_x && ok_res_y)
+      {
+	  *minx = x;
+	  *maxy = y;
+	  *maxx = *minx + ((double) width * res_x);
+	  *miny = *maxy - ((double) height * res_y);
+	  *pres_x = res_x;
+	  *pres_y = res_y;
+	  return 1;
+      }
+    return 0;
+}
+
+static void
+do_sniff_jpeg_image (const char *src_path, int worldfile, int with_md5)
+{
+/* sniffing a JPEG image */
+    unsigned int width;
+    unsigned int height;
+    unsigned char pixel_type;
+    int is_geo = 0;
+    double minX;
+    double minY;
+    double maxX;
+    double maxY;
+    double x_res;
+    double y_res;
+    const char *pixel = "RGB";
+    unsigned int bands = 3;
+    char *jgw_path = NULL;
+    char *md5 = NULL;
+
+    if (rl2_get_jpeg_infos (src_path, &width, &height, &pixel_type) != RL2_OK)
+	return;
+    if (pixel_type == RL2_PIXEL_GRAYSCALE)
+      {
+	  pixel = "GRAYSCALE";
+	  bands = 1;
+      }
+    if (worldfile)
+      {
+	  jgw_path = rl2_build_worldfile_path (src_path, ".jgw");
+	  if (jgw_path != NULL)
+	    {
+		is_geo =
+		    parse_worldfile (jgw_path, width, height, &minX, &minY,
+				     &maxX, &maxY, &x_res, &y_res);
+		free (jgw_path);
+	    }
+	  if (!is_geo)
+	    {
+		jgw_path = rl2_build_worldfile_path (src_path, ".jpgw");
+		if (jgw_path != NULL)
+		  {
+		      is_geo =
+			  parse_worldfile (jgw_path, width, height, &minX,
+					   &minY, &maxX, &maxY, &x_res, &y_res);
+		      free (jgw_path);
+		  }
+	    }
+	  if (!is_geo)
+	    {
+		jgw_path = rl2_build_worldfile_path (src_path, ".wld");
+		if (jgw_path != NULL)
+		  {
+		      is_geo =
+			  parse_worldfile (jgw_path, width, height, &minX,
+					   &minY, &maxX, &maxY, &x_res, &y_res);
+		      free (jgw_path);
+		  }
+	    }
+      }
+
+    if (with_md5)
+	md5 = rl2_compute_file_md5_checksum (src_path);
+    if (is_geo)
+	printf
+	    ("JPEG+JGW\t%s\t%s\t%u\t%u\t%s\t%s\t%u\t\t%s\t%d\t%1.12f\t%1.12f\t%1.8f\t%1.8f\t%1.8f\t%1.8f\n",
+	     (md5 == NULL) ? "" : md5, src_path, width, height, "UINT8", pixel,
+	     bands, "JPEG", -1, x_res, y_res, minX, minY, maxX, maxY);
+    else
+	printf ("JPEG\t%s\t%s\t%u\t%u\t%s\t%s\t%u\t\t%s\n",
+		(md5 == NULL) ? "" : md5, src_path, width, height, "UINT8",
+		pixel, bands, "JPEG");
+}
+
+#ifndef OMIT_OPENJPEG		/* only if OpenJpeg is enabled */
+
+static void
+do_sniff_jpeg2000_image (const char *src_path, int worldfile, int with_md5)
+{
+/* sniffing a Jpeg2000 image */
+    unsigned int width;
+    unsigned int height;
+    unsigned char sample_type;
+    unsigned char pixel_type;
+    unsigned char num_bands;
+    int is_geo = 0;
+    double minX;
+    double minY;
+    double maxX;
+    double maxY;
+    double x_res;
+    double y_res;
+    const char *pixel = "UNKNOWN";
+    const char *sample = "UNKNOWN";
+    char *j2w_path = NULL;
+    char *md5 = NULL;
+    unsigned int tile_width;
+    unsigned int tile_height;
+    unsigned char num_levels;
+
+    if (rl2_get_jpeg2000_infos
+	(src_path, &width, &height, &sample_type, &pixel_type, &num_bands,
+	 &tile_width, &tile_height, &num_levels) != RL2_OK)
+	return;
+    if (pixel_type == RL2_PIXEL_GRAYSCALE)
+	pixel = "GRAYSCALE";
+    if (pixel_type == RL2_PIXEL_DATAGRID)
+	pixel = "DATAGRID";
+    if (pixel_type == RL2_PIXEL_MULTIBAND)
+	pixel = "MULTIBAND";
+    if (pixel_type == RL2_PIXEL_RGB)
+	pixel = "RGB";
+    if (sample_type == RL2_SAMPLE_UINT8)
+	sample = "UINT8";
+    if (sample_type == RL2_SAMPLE_UINT16)
+	sample = "UINT16";
+    if (worldfile)
+      {
+	  j2w_path = rl2_build_worldfile_path (src_path, ".j2w");
+	  if (j2w_path != NULL)
+	    {
+		is_geo =
+		    parse_worldfile (j2w_path, width, height, &minX, &minY,
+				     &maxX, &maxY, &x_res, &y_res);
+		free (j2w_path);
+	    }
+	  if (!is_geo)
+	    {
+		j2w_path = rl2_build_worldfile_path (src_path, ".wld");
+		if (j2w_path != NULL)
+		  {
+		      is_geo =
+			  parse_worldfile (j2w_path, width, height, &minX,
+					   &minY, &maxX, &maxY, &x_res, &y_res);
+		      free (j2w_path);
+		  }
+	    }
+      }
+
+    if (with_md5)
+	md5 = rl2_compute_file_md5_checksum (src_path);
+    if (is_geo)
+	printf
+	    ("Jpeg2000+J2W\t%s\t%s\t%u\t%u\t%s\t%s\t%u\t\t%s\t%d\t%1.12f\t%1.12f\t%1.8f\t%1.8f\t%1.8f\t%1.8f\n",
+	     (md5 == NULL) ? "" : md5, src_path, width, height, sample, pixel,
+	     num_bands, "Jpeg2000", -1, x_res, y_res, minX, minY, maxX, maxY);
+    else
+	printf ("JPEG\t%s\t%s\t%u\t%u\t%s\t%s\t%u\t\t%s\n",
+		(md5 == NULL) ? "" : md5, src_path, width, height, sample,
+		pixel, num_bands, "Jpeg2000");
+}
+
+#endif /* end OpenJpeg conditional */
+
+static int
+recover_incomplete_geotiff (TIFF * in, uint32 width, uint32 height,
+			    double *minX, double *minY, double *maxX,
+			    double *maxY, double *hResolution,
+			    double *vResolution)
+{
+/* final desperate attempt to recover an incomplete GeoTIFF */
+    double *tie_points;
+    double *scale;
+    uint16 count;
+    double res_x = DBL_MAX;
+    double res_y = DBL_MAX;
+    double x = DBL_MAX;
+    double y = DBL_MAX;
+
+    if (TIFFGetField (in, TIFFTAG_GEOPIXELSCALE, &count, &scale))
+      {
+	  if (count >= 2 && scale[0] != 0.0 && scale[1] != 0.0)
+	    {
+		res_x = scale[0];
+		res_y = scale[1];
+	    }
+      }
+    if (TIFFGetField (in, TIFFTAG_GEOTIEPOINTS, &count, &tie_points))
+      {
+	  int i;
+	  int max_count = count / 6;
+	  for (i = 0; i < max_count; i++)
+	    {
+		x = tie_points[i * 6 + 3];
+		y = tie_points[i * 6 + 4];
+	    }
+      }
+    if (x == DBL_MAX || y == DBL_MAX || res_x == DBL_MAX || res_y == DBL_MAX)
+	return 0;
+
+/* computing the pixel resolution */
+    *minX = x;
+    *maxX = x + ((double) width * res_x);
+    *minY = y - ((double) height * res_y);
+    *maxY = y;
+    *hResolution = (*maxX - *minX) / (double) width;
+    *vResolution = (*maxY - *minY) / (double) height;
+    return 1;
+}
+
+static void
+sniff_tiff_pixel (TIFF * in, uint16 * bitspersample, uint16 * samplesperpixel,
+		  uint16 * photometric, uint16 * sampleformat,
+		  uint16 * compression)
+{
+/* retrieving the TIFF sample and pixel type */
+    uint16 value16;
+    if (TIFFGetField (in, TIFFTAG_BITSPERSAMPLE, &value16) != 0)
+	*bitspersample = value16;
+    else
+	*bitspersample = 1;
+    if (TIFFGetField (in, TIFFTAG_SAMPLESPERPIXEL, &value16) != 0)
+	*samplesperpixel = value16;
+    else
+	*samplesperpixel = 1;
+    if (TIFFGetField (in, TIFFTAG_PHOTOMETRIC, &value16) != 0)
+	*photometric = value16;
+    else
+	*photometric = 0;
+    if (TIFFGetField (in, TIFFTAG_SAMPLEFORMAT, &value16) != 0)
+	*sampleformat = value16;
+    else
+	*sampleformat = 1;
+    if (TIFFGetField (in, TIFFTAG_COMPRESSION, &value16) != 0)
+	*compression = value16;
+    else
+	*compression = 1;
+
+}
+
+static void
+do_sniff_geotiff_image (const char *src_path, int with_md5)
+{
+/* sniffing a GeoTIFF image */
+    uint32 width = 0;
+    uint32 height = 0;
+    uint16 bitspersample;
+    uint16 bands;
+    uint16 photometric;
+    uint16 sampleformat;
+    uint16 tiff_compression;
+    const char *sample = "unknown";
+    const char *pixel = "unknown";
+    const char *compression = "unknown";
+    int is_geotiff = 0;
+    int srid = -1;
+    double cx;
+    double cy;
+    double minX;
+    double minY;
+    double maxX;
+    double maxY;
+    double x_res;
+    double y_res;
+    GTIFDefn definition;
+    char *md5 = NULL;
+    TIFF *in = (TIFF *) 0;
+    GTIF *gtif = (GTIF *) 0;
+
+/* suppressing TIFF messages */
+    TIFFSetErrorHandler (NULL);
+    TIFFSetWarningHandler (NULL);
+
+/* reading from file */
+    in = XTIFFOpen (src_path, "r");
+    if (in == NULL)
+	goto error;
+    gtif = GTIFNew (in);
+    if (gtif == NULL)
+	goto error;
+
+/* retrieving the TIFF dimensions */
+    TIFFGetField (in, TIFFTAG_IMAGELENGTH, &height);
+    TIFFGetField (in, TIFFTAG_IMAGEWIDTH, &width);
+    sniff_tiff_pixel (in, &bitspersample, &bands, &photometric, &sampleformat,
+		      &tiff_compression);
+    switch (sampleformat)
+      {
+      case SAMPLEFORMAT_UINT:
+	  switch (bitspersample)
+	    {
+	    case 1:
+		sample = "1-BIT";
+		break;
+	    case 2:
+		sample = "2-BIT";
+		break;
+	    case 4:
+		sample = "4-BIT";
+		break;
+	    case 8:
+		sample = "UINT8";
+		break;
+	    case 16:
+		sample = "UINT16";
+		break;
+	    case 32:
+		sample = "UINT32";
+		break;
+	    };
+	  break;
+      case SAMPLEFORMAT_INT:
+	  switch (bitspersample)
+	    {
+	    case 8:
+		sample = "INT8";
+		break;
+	    case 16:
+		sample = "INT16";
+		break;
+	    case 32:
+		sample = "INT32";
+		break;
+	    };
+	  break;
+      case SAMPLEFORMAT_IEEEFP:
+	  switch (bitspersample)
+	    {
+	    case 32:
+		sample = "FLOAT";
+		break;
+	    case 64:
+		sample = "DOUBLE";
+		break;
+	    };
+	  break;
+      };
+    switch (photometric)
+      {
+      case PHOTOMETRIC_RGB:
+	  if (bitspersample == 8 || bitspersample == 16)
+	    {
+		if (bands == 3)
+		    pixel = "RGB";
+		else
+		    pixel = "MULTIBAND";
+	    }
+	  break;
+      case PHOTOMETRIC_PALETTE:
+	  if ((bitspersample == 1 || bitspersample == 2 || bitspersample == 4
+	       || bitspersample == 8) && bands == 1)
+	      pixel = "PALETTE";
+	  break;
+      case PHOTOMETRIC_MINISWHITE:
+      case PHOTOMETRIC_MINISBLACK:
+	  if (bitspersample == 1 && bands == 1)
+	      pixel = "MONOCHROME";
+	  else if ((bitspersample == 2 || bitspersample == 4
+		    || bitspersample == 8) && bands == 1)
+	      pixel = "GRAYSCALE";
+	  else if ((bitspersample == 16 || bitspersample == 32
+		    || bitspersample == 64) && bands == 1)
+	      pixel = "DATAGRID";
+      };
+    switch (tiff_compression)
+      {
+      case COMPRESSION_NONE:
+	  compression = "NONE";
+	  break;
+      case COMPRESSION_CCITTRLE:
+	  compression = "RLE";
+	  break;
+      case COMPRESSION_CCITTFAX3:
+	  compression = "FAX3";
+	  break;
+      case COMPRESSION_CCITTFAX4:
+	  compression = "FAX4";
+	  break;
+      case COMPRESSION_LZW:
+	  compression = "LZW";
+	  break;
+      case COMPRESSION_OJPEG:
+	  compression = "OldJPEG";
+	  break;
+      case COMPRESSION_JPEG:
+	  compression = "JPEG";
+	  break;
+      case COMPRESSION_DEFLATE:
+	  compression = "DEFLATE";
+	  break;
+      case COMPRESSION_ADOBE_DEFLATE:
+	  compression = "AdobeDEFLATE";
+	  break;
+      case COMPRESSION_JP2000:
+	  compression = "JP2000";
+	  break;
+      case COMPRESSION_LZMA:
+	  compression = "LZMA";
+	  break;
+      };
+
+    if (!GTIFGetDefn (gtif, &definition))
+	goto recover;
+/* retrieving the EPSG code */
+    if (definition.PCS == 32767)
+      {
+	  if (definition.GCS != 32767)
+	      srid = definition.GCS;
+      }
+    else
+	srid = definition.PCS;
+
+/* computing the corners coords */
+    cx = 0.0;
+    cy = 0.0;
+    GTIFImageToPCS (gtif, &cx, &cy);
+    minX = cx;
+    maxY = cy;
+    cx = 0.0;
+    cy = height;
+    GTIFImageToPCS (gtif, &cx, &cy);
+    minY = cy;
+    cx = width;
+    cy = 0.0;
+    GTIFImageToPCS (gtif, &cx, &cy);
+    maxX = cx;
+
+/* computing the pixel resolution */
+    x_res = (maxX - minX) / (double) width;
+    y_res = (maxY - minY) / (double) height;
+    is_geotiff = 1;
+    goto print;
+
+  recover:
+    is_geotiff =
+	recover_incomplete_geotiff (in, width, height, &minX, &minY, &maxX,
+				    &maxY, &x_res, &y_res);
+
+  print:
+    if (with_md5)
+	md5 = rl2_compute_file_md5_checksum (src_path);
+
+    if (is_geotiff)
+	printf
+	    ("GeoTIFF\t%s\t%s\t%u\t%u\t%s\t%s\t%u\t\t%s\t%d\t%1.12f\t%1.12f\t%1.8f\t%1.8f\t%1.8f\t%1.8f\n",
+	     (md5 == NULL) ? "" : md5, src_path, width, height, sample, pixel,
+	     bands, compression, srid, x_res, y_res, minX, minY, maxX, maxY);
+    else
+	printf ("TIFF\t%s\t%s\t%u\t%u\t%s\t%s\t%u\t\t%s\n",
+		(md5 == NULL) ? "" : md5, src_path, width, height, sample,
+		pixel, bands, compression);
+
+  error:
+    if (in != (TIFF *) 0)
+	XTIFFClose (in);
+    if (gtif != (GTIF *) 0)
+	GTIFFree (gtif);
+    if (md5)
+	free (md5);
+}
+
+static void
+do_sniff_tiff_image (const char *src_path, int with_md5)
+{
+/* sniffing a TIFF image */
+    uint32 width = 0;
+    uint32 height = 0;
+    uint16 bitspersample;
+    uint16 bands;
+    uint16 photometric;
+    uint16 sampleformat;
+    uint16 tiff_compression;
+    const char *sample = "unknown";
+    const char *pixel = "unknown";
+    const char *compression = "unknown";
+    int is_geotiff = 0;
+    double minX;
+    double minY;
+    double maxX;
+    double maxY;
+    double x_res;
+    double y_res;
+    char *tfw_path = NULL;
+    char *md5 = NULL;
+    TIFF *in = (TIFF *) 0;
+
+/* suppressing TIFF messages */
+    TIFFSetErrorHandler (NULL);
+    TIFFSetWarningHandler (NULL);
+
+/* reading from file */
+    in = TIFFOpen (src_path, "r");
+    if (in == NULL)
+	goto error;
+
+/* retrieving the TIFF dimensions */
+    TIFFGetField (in, TIFFTAG_IMAGELENGTH, &height);
+    TIFFGetField (in, TIFFTAG_IMAGEWIDTH, &width);
+    sniff_tiff_pixel (in, &bitspersample, &bands, &photometric, &sampleformat,
+		      &tiff_compression);
+    switch (sampleformat)
+      {
+      case SAMPLEFORMAT_UINT:
+	  switch (bitspersample)
+	    {
+	    case 1:
+		sample = "1-BIT";
+		break;
+	    case 2:
+		sample = "2-BIT";
+		break;
+	    case 4:
+		sample = "4-BIT";
+		break;
+	    case 8:
+		sample = "UINT8";
+		break;
+	    case 16:
+		sample = "UINT16";
+		break;
+	    case 32:
+		sample = "UINT32";
+		break;
+	    };
+	  break;
+      case SAMPLEFORMAT_INT:
+	  switch (bitspersample)
+	    {
+	    case 8:
+		sample = "INT8";
+		break;
+	    case 16:
+		sample = "INT16";
+		break;
+	    case 32:
+		sample = "INT32";
+		break;
+	    };
+	  break;
+      case SAMPLEFORMAT_IEEEFP:
+	  switch (bitspersample)
+	    {
+	    case 32:
+		sample = "FLOAT";
+		break;
+	    case 64:
+		sample = "DOUBLE";
+		break;
+	    };
+	  break;
+      };
+    switch (photometric)
+      {
+      case PHOTOMETRIC_RGB:
+	  if (bitspersample == 8 || bitspersample == 16)
+	    {
+		if (bands == 3)
+		    pixel = "RGB";
+		else
+		    pixel = "MULTIBAND";
+	    }
+	  break;
+      case PHOTOMETRIC_PALETTE:
+	  if ((bitspersample == 1 || bitspersample == 2 || bitspersample == 4
+	       || bitspersample == 8) && bands == 1)
+	      pixel = "PALETTE";
+	  break;
+      case PHOTOMETRIC_MINISWHITE:
+      case PHOTOMETRIC_MINISBLACK:
+	  if (bitspersample == 1 && bands == 1)
+	      pixel = "MONOCHROME";
+	  else if ((bitspersample == 2 || bitspersample == 4
+		    || bitspersample == 8) && bands == 1)
+	      pixel = "GRAYSCALE";
+	  else if ((bitspersample == 16 || bitspersample == 32
+		    || bitspersample == 64) && bands == 1)
+	      pixel = "DATAGRID";
+      };
+    switch (tiff_compression)
+      {
+      case COMPRESSION_NONE:
+	  compression = "NONE";
+	  break;
+      case COMPRESSION_CCITTRLE:
+	  compression = "RLE";
+	  break;
+      case COMPRESSION_CCITTFAX3:
+	  compression = "FAX3";
+	  break;
+      case COMPRESSION_CCITTFAX4:
+	  compression = "FAX4";
+	  break;
+      case COMPRESSION_LZW:
+	  compression = "LZW";
+	  break;
+      case COMPRESSION_OJPEG:
+	  compression = "OldJPEG";
+	  break;
+      case COMPRESSION_JPEG:
+	  compression = "JPEG";
+	  break;
+      case COMPRESSION_DEFLATE:
+	  compression = "DEFLATE";
+	  break;
+      case COMPRESSION_ADOBE_DEFLATE:
+	  compression = "AdobeDEFLATE";
+	  break;
+      case COMPRESSION_JP2000:
+	  compression = "JP2000";
+	  break;
+      case COMPRESSION_LZMA:
+	  compression = "LZMA";
+	  break;
+      };
+
+    tfw_path = rl2_build_worldfile_path (src_path, ".tfw");
+    if (tfw_path != NULL)
+      {
+	  is_geotiff =
+	      parse_worldfile (tfw_path, width, height, &minX, &minY, &maxX,
+			       &maxY, &x_res, &y_res);
+	  free (tfw_path);
+      }
+    if (!is_geotiff)
+      {
+	  tfw_path = rl2_build_worldfile_path (src_path, ".tifw");
+	  if (tfw_path != NULL)
+	    {
+		is_geotiff =
+		    parse_worldfile (tfw_path, width, height, &minX, &minY,
+				     &maxX, &maxY, &x_res, &y_res);
+		free (tfw_path);
+	    }
+      }
+    if (!is_geotiff)
+      {
+	  tfw_path = rl2_build_worldfile_path (src_path, ".wld");
+	  if (tfw_path != NULL)
+	    {
+		is_geotiff =
+		    parse_worldfile (tfw_path, width, height, &minX, &minY,
+				     &maxX, &maxY, &x_res, &y_res);
+		free (tfw_path);
+	    }
+      }
+
+    if (with_md5)
+	md5 = rl2_compute_file_md5_checksum (src_path);
+    if (is_geotiff)
+	printf
+	    ("TIFF+TFW\t%s\t%s\t%u\t%u\t%s\t%s\t%u\t\t%s\t%d\t%1.12f\t%1.12f\t%1.8f\t%1.8f\t%1.8f\t%1.8f\n",
+	     (md5 == NULL) ? "" : md5, src_path, width, height, sample, pixel,
+	     bands, compression, -1, x_res, y_res, minX, minY, maxX, maxY);
+    else
+	printf ("TIFF\t%s\t%s\t%u\t%u\t%s\t%s\t%u\t\t%s\n",
+		(md5 == NULL) ? "" : md5, src_path, width, height, sample,
+		pixel, bands, compression);
+
+  error:
+    if (in != (TIFF *) 0)
+	TIFFClose (in);
+    if (md5)
+	free (md5);
+}
+
+static void
+do_sniff_file (const char *src_path, int worldfile, int with_md5)
+{
+/* sniffing a single file */
+    if (is_ascii_grid (src_path))
+	do_sniff_ascii_grid (src_path, with_md5);
+    if (is_jpeg_image (src_path))
+	do_sniff_jpeg_image (src_path, worldfile, with_md5);
+
+#ifndef OMIT_OPENJPEG		/* only if OpenJpeg is enabled */
+    if (is_jpeg2000_image (src_path))
+	do_sniff_jpeg2000_image (src_path, worldfile, with_md5);
+#endif /* end OpenJpeg conditional */
+
+    if (worldfile)
+	do_sniff_tiff_image (src_path, with_md5);
+    else
+	do_sniff_geotiff_image (src_path, with_md5);
+}
+
+static int
+check_extension_match (const char *file_name, const char *file_ext)
+{
+/* checks the file extension */
+    const char *mark = NULL;
+    const char *p = file_name;
+    int len;
+    char *ext;
+    int match = 0;
+    if (file_ext == NULL)
+      {
+	  /* any supported extension */
+	  while (*p != '\0')
+	    {
+		if (*p == '.')
+		    mark = p;
+		p++;
+	    }
+	  if (mark == NULL)
+	      return 0;
+	  if (strcasecmp (mark, ".tif") == 0)
+	      return 1;
+	  if (strcasecmp (mark, ".jpg") == 0)
+	      return 1;
+	  if (strcasecmp (mark, ".asc") == 0)
+	      return 1;
+	  return 0;
+      }
+
+    len = strlen (file_ext);
+    if (*file_ext == '.')
+      {
+	  /* file extension starts with dot */
+	  ext = malloc (len + 1);
+	  strcpy (ext, file_ext);
+      }
+    else
+      {
+	  /* file extension doesn't start with dot */
+	  ext = malloc (len + 2);
+	  *ext = '.';
+	  strcpy (ext + 1, file_ext);
+      }
+    while (*p != '\0')
+      {
+	  if (*p == '.')
+	      mark = p;
+	  p++;
+      }
+    if (mark == NULL)
+      {
+	  free (ext);
+	  return 0;
+      }
+    match = strcasecmp (mark, ext);
+    free (ext);
+    if (match == 0)
+	return 1;
+    return 0;
+}
+
+static int
+do_sniff_dir (const char *dir_path, const char *file_ext, int worldfile,
+	      int with_md5)
+{
+/* sniffing a whole directory */
+#if defined(_WIN32) && !defined(__MINGW32__)
+/* Visual Studio .NET */
+    struct _finddata_t c_file;
+    intptr_t hFile;
+    int cnt = 0;
+    int total = 0;
+    char *search;
+    char *path;
+    int ret;
+    if (_chdir (dir_path) < 0)
+	return 0;
+    search = sqlite3_mprintf ("*%s", file_ext);
+    if ((hFile = _findfirst (search, &c_file)) == -1L)
+	;
+    else
+      {
+	  while (1)
+	    {
+		if ((c_file.attrib & _A_RDONLY) == _A_RDONLY
+		    || (c_file.attrib & _A_NORMAL) == _A_NORMAL)
+		    total++;
+		if (_findnext (hFile, &c_file) != 0)
+		    break;
+	    }
+	  _findclose (hFile);
+	  if ((hFile = _findfirst (search, &c_file)) == -1L)
+	      ;
+	  else
+	    {
+		while (1)
+		  {
+		      if ((c_file.attrib & _A_RDONLY) == _A_RDONLY
+			  || (c_file.attrib & _A_NORMAL) == _A_NORMAL)
+			{
+			    path =
+				sqlite3_mprintf ("%s/%s", dir_path,
+						 c_file.name);
+			    ret =
+				do_import_file (handle, path, cvg, section,
+						worldfile, force_srid,
+						pyramidize, sample_type,
+						pixel_type, num_bands, tile_w,
+						tile_h, compression, quality,
+						stmt_data, stmt_tils, stmt_sect,
+						stmt_levl, stmt_upd_sect,
+						verbose, cnt + 1, total);
+			    sqlite3_free (path);
+			    if (!ret)
+				goto error;
+			    cnt++;
+			}
+		      if (_findnext (hFile, &c_file) != 0)
+			  break;
+		  }
+	      error:
+		_findclose (hFile);
+	    }
+	  sqlite3_free (search);
+	  return cnt;
+#else
+/* not Visual Studio .NET */
+    int cnt = 0;
+    int total = 0;
+    char *path;
+    struct dirent *entry;
+    char dir_fullpath[4096];
+    DIR *dir;
+#ifdef _WIN32
+    _chdir (dir_path);
+#else /* not WIN32 */
+    chdir (dir_path);
+#endif
+    dir = opendir (".");
+    if (!dir)
+	return 0;
+    while (1)
+      {
+	  /* counting how many valid entries */
+	  entry = readdir (dir);
+	  if (!entry)
+	      break;
+	  if (!check_extension_match (entry->d_name, file_ext))
+	      continue;
+	  total++;
+      }
+    rewinddir (dir);
+#ifdef _WIN32
+    _getcwd (dir_fullpath, 4096);
+#else /* not WIN32 */
+    getcwd (dir_fullpath, 4096);
+#endif
+    while (1)
+      {
+	  /* scanning dir-entries */
+	  entry = readdir (dir);
+	  if (!entry)
+	      break;
+	  if (!check_extension_match (entry->d_name, file_ext))
+	      continue;
+#ifdef _WIN32
+	  path = sqlite3_mprintf ("%s\\%s", dir_fullpath, entry->d_name);
+#else /* not WIN32 */
+	  path = sqlite3_mprintf ("%s/%s", dir_fullpath, entry->d_name);
+#endif
+	  do_sniff_file (path, worldfile, with_md5);
+	  sqlite3_free (path);
+	  cnt++;
+      }
+    closedir (dir);
+    return cnt;
+#endif
+}
+
+static void
+open_db (sqlite3 ** handle, void *cache, void *priv_data)
+{
+/* opening the DB */
+    sqlite3 *db_handle;
+    int ret;
+
+    *handle = NULL;
+    fprintf (stderr, "     SQLite version: %s\n", sqlite3_libversion ());
+    fprintf (stderr, " SpatiaLite version: %s\n", spatialite_version ());
+    fprintf (stderr, "RasterLite2 version: %s\n\n", rl2_version ());
+
+    ret =
+	sqlite3_open_v2 (":memory:", &db_handle,
+			 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
+    if (ret != SQLITE_OK)
+      {
+	  fprintf (stderr, "cannot open ':memory:': %s\n",
+		   sqlite3_errmsg (db_handle));
+	  sqlite3_close (db_handle);
+	  return;
+      }
+    spatialite_init_ex (db_handle, cache, 0);
+    rl2_init (db_handle, priv_data, 0);
+
+    *handle = db_handle;
+    return;
+}
+
+static void
+do_help ()
+{
+/* printing the argument list */
+    fprintf (stderr, "\n\nusage: rl2sniff ARGLIST\n");
+    fprintf (stderr,
+	     "==============================================================\n");
+    fprintf (stderr,
+	     "-h or --help                    print this help message\n");
+    fprintf (stderr,
+	     "-src or --src-path    pathname  single Image/Raster path\n");
+    fprintf (stderr, "-dir or --dir-path    pathname  directory path\n");
+    fprintf (stderr,
+	     "-ext or --file-ext    extension file extension (e.g. .tif)\n");
+    fprintf (stderr, "-wf or --worldfile              requires a Worldfile\n");
+    fprintf (stderr,
+	     "-md5 or --md5-checksum          enabling MD5 checksums\n");
+}
+
+int
+main (int argc, char *argv[])
+{
+/* the MAIN function simply perform arguments checking */
+    sqlite3 *handle;
+    int i;
+    int next_arg = ARG_NONE;
+    const char *src_path = NULL;
+    const char *dir_path = ".";
+    const char *file_ext = NULL;
+    int worldfile = 0;
+    int with_md5 = 0;
+    int error = 0;
+    void *cache;
+    void *priv_data;
+
+    for (i = 1; i < argc; i++)
+      {
+	  /* parsing the invocation arguments */
+	  if (next_arg != ARG_NONE)
+	    {
+		switch (next_arg)
+		  {
+		  case ARG_SRC_PATH:
+		      src_path = argv[i];
+		      break;
+		  case ARG_DIR_PATH:
+		      dir_path = argv[i];
+		      break;
+		  case ARG_FILE_EXT:
+		      file_ext = argv[i];
+		      break;
+		  };
+		next_arg = ARG_NONE;
+		continue;
+	    }
+
+	  if (strcasecmp (argv[i], "--help") == 0
+	      || strcmp (argv[i], "-h") == 0)
+	    {
+		do_help ();
+		return -1;
+	    }
+	  if (strcmp (argv[i], "-src") == 0
+	      || strcasecmp (argv[i], "--src-path") == 0)
+	    {
+		next_arg = ARG_SRC_PATH;
+		continue;
+	    }
+	  if (strcmp (argv[i], "-dir") == 0
+	      || strcasecmp (argv[i], "--dir-path") == 0)
+	    {
+		next_arg = ARG_DIR_PATH;
+		continue;
+	    }
+	  if (strcmp (argv[i], "-ext") == 0
+	      || strcasecmp (argv[i], "--file-ext") == 0)
+	    {
+		next_arg = ARG_FILE_EXT;
+		continue;
+	    }
+	  if (strcmp (argv[i], "-wf") == 0
+	      || strcasecmp (argv[i], "--worldfile") == 0)
+	    {
+		worldfile = 1;
+		continue;
+	    }
+	  if (strcmp (argv[i], "-md5") == 0
+	      || strcasecmp (argv[i], "--enable-md5") == 0)
+	    {
+		with_md5 = 1;
+		continue;
+	    }
+	  fprintf (stderr, "unknown argument: %s\n", argv[i]);
+	  error = 1;
+      }
+    if (error)
+      {
+	  do_help ();
+	  return -1;
+      }
+
+/* opening the DB */
+    cache = spatialite_alloc_connection ();
+    priv_data = rl2_alloc_private ();
+    open_db (&handle, cache, priv_data);
+    if (!handle)
+	return -1;
+
+    printf ("image_format\tMD5_checksum\timage_path\twidth\theight\tsample_type"
+	    "\tpixel_type\tbands\tno_data\tcompression\tsrid\tx_resolution"
+	    "\ty_resolution\tmin_x\tmin_y\tmax_x\tmax_y\n");
+    if (src_path != NULL)
+	do_sniff_file (src_path, worldfile, with_md5);
+    else
+	do_sniff_dir (dir_path, file_ext, worldfile, with_md5);
+
+    sqlite3_close (handle);
+    rl2_cleanup_private (priv_data);
+    spatialite_cleanup_ex (cache);
+    spatialite_shutdown ();
+    return 0;
+}
diff --git a/tools/rl2tool.c b/tools/rl2tool.c
index 0dbc1ed..a27ee23 100644
--- a/tools/rl2tool.c
+++ b/tools/rl2tool.c
@@ -1,5 +1,5 @@
 /* 
-/ rl2_tool
+/ rl2tool
 /
 / a generic tool supporting RasterLite2 DataSources
 /
@@ -29,14 +29,7 @@
 #include <string.h>
 #include <float.h>
 #include <limits.h>
-
-#include <sys/types.h>
-#if defined(_WIN32) && !defined(__MINGW32__)
-#include <io.h>
-#include <direct.h>
-#else
-#include <dirent.h>
-#endif
+#include <time.h>
 
 #include <rasterlite2/rasterlite2.h>
 #include <rasterlite2/rl2tiff.h>
@@ -50,14 +43,15 @@
 #define ARG_MODE_DROP		2
 #define ARG_MODE_IMPORT		3
 #define ARG_MODE_EXPORT		4
-#define ARG_MODE_DELETE		5
-#define ARG_MODE_PYRAMIDIZE	6
-#define ARG_MODE_PYRMONO	7
-#define ARG_MODE_DE_PYRAMIDIZE	8
-#define ARG_MODE_LIST		9
-#define ARG_MODE_CATALOG	10
-#define ARG_MODE_MAP		11
-#define ARG_MODE_HISTOGRAM	12
+#define ARG_MODE_SECT_EXPORT	5
+#define ARG_MODE_DELETE		6
+#define ARG_MODE_PYRAMIDIZE	7
+#define ARG_MODE_PYRMONO	8
+#define ARG_MODE_DE_PYRAMIDIZE	9
+#define ARG_MODE_LIST		10
+#define ARG_MODE_CATALOG	12
+#define ARG_MODE_MAP		13
+#define ARG_MODE_HISTOGRAM	14
 
 #define ARG_DB_PATH		10
 #define ARG_SRC_PATH		11
@@ -66,29 +60,41 @@
 #define ARG_FILE_EXT		14
 #define ARG_COVERAGE		15
 #define ARG_SECTION		16
-#define ARG_SAMPLE		17
-#define ARG_PIXEL		18
-#define ARG_NUM_BANDS		19
-#define ARG_COMPRESSION		20
-#define ARG_QUALITY		21
-#define ARG_TILE_WIDTH		22
-#define ARG_TILE_HEIGHT		23
-#define ARG_BAND_INDEX	24
-#define ARG_IMG_WIDTH		25
-#define ARG_IMG_HEIGHT		26
-#define ARG_SRID		27
-#define ARG_RESOLUTION		28
-#define ARG_X_RESOLUTION	29
-#define ARG_Y_RESOLUTION	30
-#define ARG_MINX		31
-#define ARG_MINY		32
-#define ARG_MAXX		33
-#define ARG_MAXY		34
-#define ARG_CX			35
-#define ARG_CY			36
-#define ARG_NO_DATA		37
-#define ARG_VIRT_LEVELS	38
+#define ARG_SECTION_ID		17
+#define ARG_SAMPLE		18
+#define ARG_PIXEL		19
+#define ARG_NUM_BANDS		20
+#define ARG_COMPRESSION		21
+#define ARG_QUALITY		22
+#define ARG_TILE_WIDTH		23
+#define ARG_TILE_HEIGHT		24
+#define ARG_BAND_INDEX		25
+#define ARG_IMG_WIDTH		26
+#define ARG_IMG_HEIGHT		27
+#define ARG_SRID		28
+#define ARG_RESOLUTION		29
+#define ARG_X_RESOLUTION	30
+#define ARG_Y_RESOLUTION	31
+#define ARG_MINX		32
+#define ARG_MINY		33
+#define ARG_MAXX		34
+#define ARG_MAXY		35
+#define ARG_CX			36
+#define ARG_CY			37
+#define ARG_NO_DATA		38
+#define ARG_VIRT_LEVELS		39
+#define ARG_STRICT_RES		40
+#define ARG_MIXED_RES		41
+#define ARG_PATHS		42
+#define ARG_MD5			43
+#define ARG_SUMMARY		44
+#define ARG_RED_BAND	45
+#define ARG_GREEN_BAND	46
+#define ARG_BLUE_BAND	47
+#define ARG_NIR_BAND	48
+#define ARG_AUTO_NDVI	49
 
+#define ARG_MAX_THREADS		98
 #define ARG_CACHE_SIZE		99
 
 #ifdef _WIN32
@@ -362,7 +368,10 @@ exec_create (sqlite3 * handle, const char *coverage,
 	     unsigned char sample, unsigned char pixel, unsigned char num_bands,
 	     unsigned char compression, int quality, unsigned short tile_width,
 	     unsigned short tile_height, int srid, double x_res, double y_res,
-	     rl2PixelPtr no_data)
+	     rl2PixelPtr no_data, int red_band, int green_band, int blue_band,
+	     int nir_band, int auto_ndvi, int strict_resolution,
+	     int mixed_resolutions, int section_paths, int section_md5,
+	     int section_summary)
 {
 /* performing CREATE */
     rl2PalettePtr palette = NULL;
@@ -387,22 +396,49 @@ exec_create (sqlite3 * handle, const char *coverage,
     if (rl2_create_dbms_coverage
 	(handle, coverage, sample, pixel, num_bands, compression, quality,
 	 tile_width, tile_height, srid, x_res, y_res, no_data,
-	 palette) != RL2_OK)
+	 palette, strict_resolution, mixed_resolutions, section_paths,
+	 section_md5, section_summary) != RL2_OK)
 	return 0;
 
+    if (pixel == RL2_PIXEL_MULTIBAND)
+      {
+	  if (red_band >= 0 && green_band >= 0 && blue_band >= 0
+	      && nir_band >= 0)
+	    {
+		if (rl2_set_dbms_coverage_default_bands
+		    (handle, coverage, red_band, green_band, blue_band,
+		     nir_band) != RL2_OK)
+		    return 0;
+		if (auto_ndvi >= 0)
+		  {
+		      if (rl2_enable_dbms_coverage_auto_ndvi
+			  (handle, coverage, auto_ndvi) != RL2_OK)
+			  return 0;
+		  }
+	    }
+      }
+
     printf ("\rRaster Coverage \"%s\" successfully created\n", coverage);
     return 1;
 }
 
 static int
-exec_import (sqlite3 * handle, const char *src_path, const char *dir_path,
-	     const char *file_ext, const char *coverage,
+exec_import (sqlite3 * handle, int max_threads, const char *src_path,
+	     const char *dir_path, const char *file_ext, const char *coverage,
 	     int worldfile, int force_srid, int pyramidize)
 {
 /* performing IMPORT */
+    time_t start;
+    time_t now;
+    time_t diff;
+    int days;
+    int hours;
+    int mins;
+    int secs;
     int ret;
     rl2CoveragePtr cvg = NULL;
 
+    time (&start);
     cvg = rl2_create_coverage_from_dbms (handle, coverage);
     if (cvg == NULL)
       {
@@ -412,15 +448,33 @@ exec_import (sqlite3 * handle, const char *src_path, const char *dir_path,
 
     if (src_path != NULL)
 	ret =
-	    rl2_load_raster_into_dbms (handle, src_path, cvg, worldfile,
-				       force_srid, pyramidize);
+	    rl2_load_raster_into_dbms (handle, max_threads, src_path, cvg,
+				       worldfile, force_srid, pyramidize, 1);
     else
 	ret =
-	    rl2_load_mrasters_into_dbms (handle, dir_path, file_ext, cvg,
-					 worldfile, force_srid, pyramidize);
+	    rl2_load_mrasters_into_dbms (handle, max_threads, dir_path,
+					 file_ext, cvg, worldfile, force_srid,
+					 pyramidize, 1);
     rl2_destroy_coverage (cvg);
+
     if (ret == RL2_OK)
-	return 1;
+      {
+	  time (&now);
+	  diff = now - start;
+	  days = diff / 86400;
+	  hours = (diff - (days * 86400)) / 3600;
+	  mins = (diff - (days * 86400) - (hours / 3600)) / 60;
+	  secs = diff - (mins * 60);
+	  if (days > 0)
+	      printf (">> Total time: %d days %d hours %d mins %02d secs\n",
+		      days, hours, mins, secs);
+	  else if (hours > 0)
+	      printf (">> Total time: %d hours %d mins %02d secs\n", hours,
+		      mins, secs);
+	  else
+	      printf (">> Total time: %d mins %02d secs\n", mins, secs);
+	  return 1;
+      }
     return 0;
 }
 
@@ -451,20 +505,191 @@ is_jpeg_image (const char *path)
 }
 
 static int
-exec_export (sqlite3 * handle, const char *dst_path, const char *coverage,
-	     double x_res, double y_res, double minx, double miny, double maxx,
-	     double maxy, unsigned short width, unsigned short height)
+is_tiff_image (const char *path)
+{
+/* testing for a TIFF Image */
+    int len = strlen (path);
+    if (len > 4)
+      {
+	  if (strcasecmp (path + len - 4, ".tif") == 0)
+	      return 1;
+      }
+    return 0;
+}
+
+static int
+exec_export (sqlite3 * handle, int max_threads, const char *dst_path,
+	     unsigned char compression, const char *coverage,
+	     int base_resolution, double x_res, double y_res, double cx,
+	     double cy, double minx, double miny, double maxx, double maxy,
+	     unsigned int width, unsigned int height)
 {
 /* performing EXPORT */
     rl2CoveragePtr cvg = rl2_create_coverage_from_dbms (handle, coverage);
     if (cvg == NULL)
 	return 0;
+
+    if (base_resolution)
+      {
+	  /* attempting to retrieve the base-resolution */
+	  char *dumb1;
+	  char *dumb2;
+	  int err_bbox = 0;
+	  double ext_x;
+	  double ext_y;
+	  rl2_resolve_base_resolution_from_dbms (handle, coverage, 0, 0, &x_res,
+						 &y_res);
+	  if (minx == DBL_MAX && miny == DBL_MAX && maxx == DBL_MAX
+	      && maxy == DBL_MAX)
+	    {
+		/* tie-point: Center Point */
+		if (cx == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Center-X\n");
+		      err_bbox = 1;
+		  }
+		if (cy == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Center-Y\n");
+		      err_bbox = 1;
+		  }
+		if (err_bbox)
+		    goto error;
+		ext_x = (double) (width) * x_res;
+		ext_y = (double) (height) * y_res;
+		minx = cx - (ext_x / 2.0);
+		maxx = minx + ext_x;
+		miny = cy - (ext_y / 2.0);
+		maxy = miny + ext_y;
+	    }
+	  else if (cx == DBL_MAX && cy == DBL_MAX && maxx == DBL_MAX
+		   && maxy == DBL_MAX)
+	    {
+		/* tie-point: LowerLeft Corner */
+		if (minx == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Min-X\n");
+		      err_bbox = 1;
+		  }
+		if (miny == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Min-Y\n");
+		      err_bbox = 1;
+		  }
+		if (err_bbox)
+		    goto error;
+		ext_x = (double) (width) * x_res;
+		ext_y = (double) (height) * y_res;
+		maxx = minx + ext_x;
+		maxy = miny + ext_y;
+		cx = minx + (ext_x / 2.0);
+		cy = miny + (ext_y / 2.0);
+	    }
+	  else if (cx == DBL_MAX && cy == DBL_MAX && minx == DBL_MAX
+		   && maxy == DBL_MAX)
+	    {
+		/* tie-point: LowerRight Corner */
+		if (maxx == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Max-X\n");
+		      err_bbox = 1;
+		  }
+		if (miny == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Min-Y\n");
+		      err_bbox = 1;
+		  }
+		if (err_bbox)
+		    goto error;
+		ext_x = (double) (width) * x_res;
+		ext_y = (double) (height) * y_res;
+		minx = maxx - ext_x;
+		maxy = miny + ext_y;
+		cx = maxx - (ext_x / 2.0);
+		cy = miny + (ext_y / 2.0);
+	    }
+	  else if (cx == DBL_MAX && cy == DBL_MAX && maxx == DBL_MAX
+		   && miny == DBL_MAX)
+	    {
+		/* tie-point: UpperLeft Corner */
+		if (minx == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Min-X\n");
+		      err_bbox = 1;
+		  }
+		if (maxy == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Max-Y\n");
+		      err_bbox = 1;
+		  }
+		if (err_bbox)
+		    goto error;
+		ext_x = (double) (width) * x_res;
+		ext_y = (double) (height) * y_res;
+		maxx = minx + ext_x;
+		miny = maxy - ext_y;
+		cx = minx + (ext_x / 2.0);
+		cy = maxy - (ext_y / 2.0);
+	    }
+	  else if (cx == DBL_MAX && cy == DBL_MAX && minx == DBL_MAX
+		   && miny == DBL_MAX)
+	    {
+		/* tie-point: UpperRight Corner */
+		if (maxx == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Max-X\n");
+		      err_bbox = 1;
+		  }
+		if (maxy == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Max-Y\n");
+		      err_bbox = 1;
+		  }
+		if (err_bbox)
+		    goto error;
+		ext_x = (double) (width) * x_res;
+		ext_y = (double) (height) * y_res;
+		minx = maxx - ext_x;
+		miny = maxy - ext_y;
+		cx = maxx - (ext_x / 2.0);
+		cy = maxy - (ext_y / 2.0);
+	    }
+	  else
+	    {
+		/* invalid tie-point */
+		fprintf (stderr,
+			 "*** ERROR *** invalid output image tie-point\n");
+		err_bbox = 1;
+	    }
+	  if (err_bbox)
+	      goto error;
+	  dumb1 = formatLong (minx);
+	  dumb2 = formatLat (miny);
+	  printf (" Lower-Left Corner: %s %s\n", dumb1, dumb2);
+	  sqlite3_free (dumb1);
+	  sqlite3_free (dumb2);
+	  dumb1 = formatLong (maxx);
+	  dumb2 = formatLat (maxy);
+	  printf ("Upper-Right Corner: %s %s\n", dumb1, dumb2);
+	  sqlite3_free (dumb1);
+	  sqlite3_free (dumb2);
+	  cx = minx + ((maxx - minx) / 2.0);
+	  cy = miny + ((maxy - miny) / 2.0);
+	  dumb1 = formatLong (cx);
+	  dumb2 = formatLat (cy);
+	  printf ("            Center: %s %s\n", dumb1, dumb2);
+	  sqlite3_free (dumb1);
+	  sqlite3_free (dumb2);
+	  fprintf (stderr,
+		   "===========================================================\n\n");
+      }
+
     if (is_ascii_grid (dst_path))
       {
 	  /* export an ASCII Grid */
 	  if (rl2_export_ascii_grid_from_dbms
-	      (handle, dst_path, cvg, x_res, minx, miny, maxx, maxy, width,
-	       height, 0, 4) != RL2_OK)
+	      (handle, max_threads, dst_path, cvg, x_res, minx, miny, maxx,
+	       maxy, width, height, 0, 4) != RL2_OK)
 	      goto error;
       }
     else if (is_jpeg_image (dst_path))
@@ -478,16 +703,291 @@ exec_export (sqlite3 * handle, const char *dst_path, const char *coverage,
 		    with_worldfile = 1;
 	    }
 	  if (rl2_export_jpeg_from_dbms
-	      (handle, dst_path, cvg, x_res, y_res, minx, miny, maxx, maxy,
-	       width, height, 85, with_worldfile) != RL2_OK)
+	      (handle, max_threads, dst_path, cvg, x_res, y_res, minx, miny,
+	       maxx, maxy, width, height, 85, with_worldfile) != RL2_OK)
 	      goto error;
       }
     else
       {
 	  /* export a GeoTIFF */
 	  if (rl2_export_geotiff_from_dbms
-	      (handle, dst_path, cvg, x_res, y_res, minx, miny, maxx, maxy,
-	       width, height, RL2_COMPRESSION_NONE, 256, 0) != RL2_OK)
+	      (handle, max_threads, dst_path, cvg, x_res, y_res, minx, miny,
+	       maxx, maxy, width, height, compression, 256, 0) != RL2_OK)
+	      goto error;
+      }
+    rl2_destroy_coverage (cvg);
+    return 1;
+  error:
+    rl2_destroy_coverage (cvg);
+    return 0;
+}
+
+static int
+exec_section_export (sqlite3 * handle, int max_threads, const char *dst_path,
+		     unsigned char compression, const char *coverage,
+		     const char *section, int ok_section_id,
+		     sqlite3_int64 section_id, int base_resolution,
+		     double x_res, double y_res, double cx, double cy,
+		     double minx, double miny, double maxx, double maxy,
+		     unsigned int width, unsigned int height, int full_section)
+{
+/* performing SECTION-EXPORT */
+    rl2CoveragePtr cvg = rl2_create_coverage_from_dbms (handle, coverage);
+    if (cvg == NULL)
+	return 0;
+
+    if (!ok_section_id)
+      {
+	  /* attempting to resolve the Section Name into a SectionID */
+	  int duplicate = 0;
+	  if (rl2_get_dbms_section_id
+	      (handle, coverage, section, &section_id, &duplicate) != RL2_OK)
+	    {
+		if (duplicate)
+		    fprintf (stderr,
+			     "Ambiguous name: Section \"%s\" in Coverage \"%s\" is not Unique\n",
+			     section, coverage);
+		else
+		    fprintf (stderr,
+			     "Section \"%s\" does not exists in Coverage \"%s\"\n",
+			     section, coverage);
+		goto error;
+	    }
+      }
+
+    if (base_resolution)
+      {
+	  /* attempting to retrieve the base-resolution */
+	  char *dumb1;
+	  char *dumb2;
+	  if (rl2_resolve_base_resolution_from_dbms
+	      (handle, coverage, 1, section_id, &x_res, &y_res) != RL2_OK)
+	    {
+		fprintf (stderr, "*** Unable to retrieve the BaseResolution\n");
+		goto error;
+	    }
+	  dumb1 = formatFloat (x_res);
+	  dumb2 = formatFloat (y_res);
+	  printf ("        Pixel size: X=%s Y=%s\n", dumb1, dumb2);
+	  sqlite3_free (dumb1);
+	  sqlite3_free (dumb2);
+      }
+
+    if (full_section)
+      {
+	  char *dumb1;
+	  char *dumb2;
+	  if (rl2_resolve_full_section_from_dbms
+	      (handle, coverage, section_id, x_res, y_res, &minx, &miny, &maxx,
+	       &maxy, &width, &height) != RL2_OK)
+	    {
+		fprintf (stderr, "*** Unable to resolve Full Section Extent\n");
+		goto error;
+	    }
+	  printf ("        Image Size: %u x %u\n", width, height);
+	  dumb1 = formatLong (minx);
+	  dumb2 = formatLat (miny);
+	  printf (" Lower-Left Corner: %s %s\n", dumb1, dumb2);
+	  sqlite3_free (dumb1);
+	  sqlite3_free (dumb2);
+	  dumb1 = formatLong (maxx);
+	  dumb2 = formatLat (maxy);
+	  printf ("Upper-Right Corner: %s %s\n", dumb1, dumb2);
+	  sqlite3_free (dumb1);
+	  sqlite3_free (dumb2);
+	  cx = minx + ((maxx - minx) / 2.0);
+	  cy = miny + ((maxy - miny) / 2.0);
+	  dumb1 = formatLong (cx);
+	  dumb2 = formatLat (cy);
+	  printf ("            Center: %s %s\n", dumb1, dumb2);
+	  sqlite3_free (dumb1);
+	  sqlite3_free (dumb2);
+	  fprintf (stderr,
+		   "===========================================================\n\n");
+      }
+    else if (base_resolution)
+      {
+	  char *dumb1;
+	  char *dumb2;
+	  int err_bbox = 0;
+	  double ext_x;
+	  double ext_y;
+	  if (minx == DBL_MAX && miny == DBL_MAX && maxx == DBL_MAX
+	      && maxy == DBL_MAX)
+	    {
+		/* tie-point: Center Point */
+		if (cx == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Center-X\n");
+		      err_bbox = 1;
+		  }
+		if (cy == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Center-Y\n");
+		      err_bbox = 1;
+		  }
+		if (err_bbox)
+		    goto error;
+		ext_x = (double) (width) * x_res;
+		ext_y = (double) (height) * y_res;
+		minx = cx - (ext_x / 2.0);
+		maxx = minx + ext_x;
+		miny = cy - (ext_y / 2.0);
+		maxy = miny + ext_y;
+	    }
+	  else if (cx == DBL_MAX && cy == DBL_MAX && maxx == DBL_MAX
+		   && maxy == DBL_MAX)
+	    {
+		/* tie-point: LowerLeft Corner */
+		if (minx == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Min-X\n");
+		      err_bbox = 1;
+		  }
+		if (miny == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Min-Y\n");
+		      err_bbox = 1;
+		  }
+		if (err_bbox)
+		    goto error;
+		ext_x = (double) (width) * x_res;
+		ext_y = (double) (height) * y_res;
+		maxx = minx + ext_x;
+		maxy = miny + ext_y;
+		cx = minx + (ext_x / 2.0);
+		cy = miny + (ext_y / 2.0);
+	    }
+	  else if (cx == DBL_MAX && cy == DBL_MAX && minx == DBL_MAX
+		   && maxy == DBL_MAX)
+	    {
+		/* tie-point: LowerRight Corner */
+		if (maxx == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Max-X\n");
+		      err_bbox = 1;
+		  }
+		if (miny == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Min-Y\n");
+		      err_bbox = 1;
+		  }
+		if (err_bbox)
+		    goto error;
+		ext_x = (double) (width) * x_res;
+		ext_y = (double) (height) * y_res;
+		minx = maxx - ext_x;
+		maxy = miny + ext_y;
+		cx = maxx - (ext_x / 2.0);
+		cy = miny + (ext_y / 2.0);
+	    }
+	  else if (cx == DBL_MAX && cy == DBL_MAX && maxx == DBL_MAX
+		   && miny == DBL_MAX)
+	    {
+		/* tie-point: UpperLeft Corner */
+		if (minx == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Min-X\n");
+		      err_bbox = 1;
+		  }
+		if (maxy == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Max-Y\n");
+		      err_bbox = 1;
+		  }
+		if (err_bbox)
+		    goto error;
+		ext_x = (double) (width) * x_res;
+		ext_y = (double) (height) * y_res;
+		maxx = minx + ext_x;
+		miny = maxy - ext_y;
+		cx = minx + (ext_x / 2.0);
+		cy = maxy - (ext_y / 2.0);
+	    }
+	  else if (cx == DBL_MAX && cy == DBL_MAX && minx == DBL_MAX
+		   && miny == DBL_MAX)
+	    {
+		/* tie-point: UpperRight Corner */
+		if (maxx == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Max-X\n");
+		      err_bbox = 1;
+		  }
+		if (maxy == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Max-Y\n");
+		      err_bbox = 1;
+		  }
+		if (err_bbox)
+		    goto error;
+		ext_x = (double) (width) * x_res;
+		ext_y = (double) (height) * y_res;
+		minx = maxx - ext_x;
+		miny = maxy - ext_y;
+		cx = maxx - (ext_x / 2.0);
+		cy = maxy - (ext_y / 2.0);
+	    }
+	  else
+	    {
+		/* invalid tie-point */
+		fprintf (stderr,
+			 "*** ERROR *** invalid output image tie-point\n");
+		err_bbox = 1;
+	    }
+	  if (err_bbox)
+	      goto error;
+	  dumb1 = formatLong (minx);
+	  dumb2 = formatLat (miny);
+	  printf (" Lower-Left Corner: %s %s\n", dumb1, dumb2);
+	  sqlite3_free (dumb1);
+	  sqlite3_free (dumb2);
+	  dumb1 = formatLong (maxx);
+	  dumb2 = formatLat (maxy);
+	  printf ("Upper-Right Corner: %s %s\n", dumb1, dumb2);
+	  sqlite3_free (dumb1);
+	  sqlite3_free (dumb2);
+	  cx = minx + ((maxx - minx) / 2.0);
+	  cy = miny + ((maxy - miny) / 2.0);
+	  dumb1 = formatLong (cx);
+	  dumb2 = formatLat (cy);
+	  printf ("            Center: %s %s\n", dumb1, dumb2);
+	  sqlite3_free (dumb1);
+	  sqlite3_free (dumb2);
+	  fprintf (stderr,
+		   "===========================================================\n\n");
+      }
+
+    if (is_ascii_grid (dst_path))
+      {
+	  /* export an ASCII Grid */
+	  if (rl2_export_section_ascii_grid_from_dbms
+	      (handle, max_threads, dst_path, cvg, section_id, x_res, minx,
+	       miny, maxx, maxy, width, height, 0, 4) != RL2_OK)
+	      goto error;
+      }
+    else if (is_jpeg_image (dst_path))
+      {
+	  /* export a JPEG Image (with possible WorldFile) */
+	  int srid;
+	  int with_worldfile = 0;
+	  if (rl2_get_coverage_srid (cvg, &srid) == RL2_OK)
+	    {
+		if (srid > 0)
+		    with_worldfile = 1;
+	    }
+	  if (rl2_export_section_jpeg_from_dbms
+	      (handle, max_threads, dst_path, cvg, section_id, x_res, y_res,
+	       minx, miny, maxx, maxy, width, height, 85,
+	       with_worldfile) != RL2_OK)
+	      goto error;
+      }
+    else
+      {
+	  /* export a GeoTIFF */
+	  if (rl2_export_section_geotiff_from_dbms
+	      (handle, max_threads, dst_path, cvg, section_id, x_res, y_res,
+	       minx, miny, maxx, maxy, width, height, compression, 256,
+	       0) != RL2_OK)
 	      goto error;
       }
     rl2_destroy_coverage (cvg);
@@ -520,23 +1020,33 @@ exec_drop (sqlite3 * handle, const char *coverage)
 }
 
 static int
-exec_delete (sqlite3 * handle, const char *coverage, const char *section)
+exec_delete (sqlite3 * handle, const char *coverage, const char *section,
+	     int ok_section_id, sqlite3_int64 section_id)
 {
 /* deleting a Raster Section */
     rl2CoveragePtr cvg = NULL;
-    sqlite3_int64 section_id;
 
     cvg = rl2_create_coverage_from_dbms (handle, coverage);
     if (cvg == NULL)
 	goto error;
 
-    if (rl2_get_dbms_section_id (handle, coverage, section, &section_id) !=
-	RL2_OK)
+    if (!ok_section_id)
       {
-	  fprintf (stderr,
-		   "Section \"%s\" does not exists in Coverage \"%s\"\n",
-		   section, coverage);
-	  goto error;
+	  /* attempting to resolve the Section Name into a SectionID */
+	  int duplicate = 0;
+	  if (rl2_get_dbms_section_id
+	      (handle, coverage, section, &section_id, &duplicate) != RL2_OK)
+	    {
+		if (duplicate)
+		    fprintf (stderr,
+			     "Ambiguous name: Section \"%s\" in Coverage \"%s\" is not Unique\n",
+			     section, coverage);
+		else
+		    fprintf (stderr,
+			     "Section \"%s\" does not exists in Coverage \"%s\"\n",
+			     section, coverage);
+		goto error;
+	    }
       }
 
     if (rl2_delete_dbms_section (handle, coverage, section_id) != RL2_OK)
@@ -552,17 +1062,41 @@ exec_delete (sqlite3 * handle, const char *coverage, const char *section)
 }
 
 static int
-exec_pyramidize (sqlite3 * handle, const char *coverage, const char *section,
-		 int force_pyramid)
+exec_pyramidize (sqlite3 * handle, int max_threads, const char *coverage,
+		 const char *section, int ok_section_id,
+		 sqlite3_int64 section_id, int force_pyramid)
 {
 /* building Pyramid levels */
     int ret;
-    if (section == NULL)
-	ret = rl2_build_all_section_pyramids (handle, coverage, force_pyramid);
-    else
+    if (section == NULL && !ok_section_id)
 	ret =
-	    rl2_build_section_pyramid (handle, coverage, section,
-				       force_pyramid);
+	    rl2_build_all_section_pyramids (handle, max_threads, coverage,
+					    force_pyramid, 1);
+    else
+      {
+	  if (!ok_section_id)
+	    {
+		/* attempting to resolve the Section Name into a SectionID */
+		int duplicate = 0;
+		if (rl2_get_dbms_section_id
+		    (handle, coverage, section, &section_id,
+		     &duplicate) != RL2_OK)
+		  {
+		      if (duplicate)
+			  fprintf (stderr,
+				   "Ambiguous name: Section \"%s\" in Coverage \"%s\" is not Unique\n",
+				   section, coverage);
+		      else
+			  fprintf (stderr,
+				   "Section \"%s\" does not exists in Coverage \"%s\"\n",
+				   section, coverage);
+		      return 0;
+		  }
+	    }
+	  ret =
+	      rl2_build_section_pyramid (handle, max_threads, coverage,
+					 section_id, force_pyramid, 1);
+      }
     if (ret == RL2_OK)
 	return 1;
     return 0;
@@ -573,21 +1107,43 @@ exec_pyramidize_monolithic (sqlite3 * handle, const char *coverage,
 			    int virt_levels)
 {
 /* building Pyramid levels (Monolithic) */
-    int ret = rl2_build_monolithic_pyramid (handle, coverage, virt_levels);
+    int ret = rl2_build_monolithic_pyramid (handle, coverage, virt_levels, 1);
     if (ret == RL2_OK)
 	return 1;
     return 0;
 }
 
 static int
-exec_de_pyramidize (sqlite3 * handle, const char *coverage, const char *section)
+exec_de_pyramidize (sqlite3 * handle, const char *coverage, const char *section,
+		    int ok_section_id, sqlite3_int64 section_id)
 {
 /* deleting Pyramid levels */
     int ret;
-    if (section == NULL)
+    if (section == NULL && !ok_section_id)
 	ret = rl2_delete_all_pyramids (handle, coverage);
     else
-	ret = rl2_delete_section_pyramid (handle, coverage, section);
+      {
+	  if (!ok_section_id)
+	    {
+		/* attempting to resolve the Section Name into a SectionID */
+		int duplicate = 0;
+		if (rl2_get_dbms_section_id
+		    (handle, coverage, section, &section_id,
+		     &duplicate) != RL2_OK)
+		  {
+		      if (duplicate)
+			  fprintf (stderr,
+				   "Ambiguous name: Section \"%s\" in Coverage \"%s\" is not Unique\n",
+				   section, coverage);
+		      else
+			  fprintf (stderr,
+				   "Section \"%s\" does not exists in Coverage \"%s\"\n",
+				   section, coverage);
+		      return 0;
+		  }
+	    }
+	  ret = rl2_delete_section_pyramid (handle, coverage, section_id);
+      }
     if (ret == RL2_OK)
 	return 1;
     return 0;
@@ -833,6 +1389,30 @@ get_pyramid_infos (sqlite3 * handle, const char *coverage)
 }
 
 static int
+valid_default_band_settings (int num_bands, int red_band, int green_band,
+			     int blue_band, int nir_band)
+{
+/* testing if the default band settings have to be considered valid */
+    if (num_bands < 4)
+	return 0;
+    if (red_band < 0 || red_band >= num_bands)
+	return 0;
+    if (green_band < 0 || green_band >= num_bands)
+	return 0;
+    if (blue_band < 0 || blue_band >= num_bands)
+	return 0;
+    if (nir_band < 0 || nir_band >= num_bands)
+	return 0;
+    if (red_band == green_band || red_band == blue_band || red_band == nir_band)
+	return 0;
+    if (green_band == blue_band || green_band == nir_band)
+	return 0;
+    if (blue_band == nir_band)
+	return 0;
+    return 1;
+}
+
+static int
 exec_catalog (sqlite3 * handle)
 {
 /* Rasterlite-2 datasources Catalog */
@@ -852,7 +1432,8 @@ exec_catalog (sqlite3 * handle)
 	"num_bands, compression, quality, tile_width, tile_height, "
 	"horz_resolution, vert_resolution, srid, auth_name, auth_srid, "
 	"ref_sys_name, extent_minx, extent_miny, extent_maxx, extent_maxy, "
-	"nodata_pixel, palette, statistics "
+	"nodata_pixel, palette, statistics, red_band_index, green_band_index, "
+	"blue_band_index, nir_band_index, eneble_auto_ndvi "
 	"FROM raster_coverages_ref_sys ORDER BY coverage_name";
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
@@ -900,6 +1481,11 @@ exec_catalog (sqlite3 * handle)
 		double mxy = DBL_MAX;
 		const unsigned char *blob;
 		int blob_sz;
+		int red_band = -1;
+		int green_band = -1;
+		int blue_band = -1;
+		int nir_band = -1;
+		int auto_ndvi = -1;
 		if (sqlite3_column_type (stmt, 16) == SQLITE_FLOAT)
 		  {
 		      mnx = sqlite3_column_double (stmt, 16);
@@ -948,6 +1534,16 @@ exec_catalog (sqlite3 * handle)
 			  rl2_deserialize_dbms_raster_statistics (blob,
 								  blob_sz);
 		  }
+		if (sqlite3_column_type (stmt, 23) == SQLITE_INTEGER)
+		    red_band = sqlite3_column_int (stmt, 23);
+		if (sqlite3_column_type (stmt, 24) == SQLITE_INTEGER)
+		    green_band = sqlite3_column_int (stmt, 24);
+		if (sqlite3_column_type (stmt, 25) == SQLITE_INTEGER)
+		    blue_band = sqlite3_column_int (stmt, 25);
+		if (sqlite3_column_type (stmt, 26) == SQLITE_INTEGER)
+		    nir_band = sqlite3_column_int (stmt, 26);
+		if (sqlite3_column_type (stmt, 27) == SQLITE_INTEGER)
+		    auto_ndvi = sqlite3_column_int (stmt, 27);
 		pyramid = get_pyramid_infos (handle, name);
 		count++;
 		printf
@@ -963,9 +1559,17 @@ exec_catalog (sqlite3 * handle)
 		if (strcmp (compression, "NONE") == 0)
 		    printf ("          Compression: NONE (uncompressed)\n");
 		else if (strcmp (compression, "DEFLATE") == 0)
-		    printf ("          Compression: DEFLATE (zip, lossless)\n");
+		    printf
+			("          Compression: DEFLATE DeltaFilter (zip, lossless)\n");
+		else if (strcmp (compression, "DEFLATE_NO") == 0)
+		    printf
+			("          Compression: DEFLATE noDelta (zip, lossless)\n");
 		else if (strcmp (compression, "LZMA") == 0)
-		    printf ("          Compression: LZMA (7-zip, lossless)\n");
+		    printf
+			("          Compression: LZMA DeltaFilter (7-zip, lossless)\n");
+		else if (strcmp (compression, "LZMA_NO") == 0)
+		    printf
+			("          Compression: LZMA noDelta (7-zip, lossless)\n");
 		else if (strcmp (compression, "PNG") == 0)
 		    printf ("          Compression: PNG, lossless\n");
 		else if (strcmp (compression, "JPEG") == 0)
@@ -976,8 +1580,15 @@ exec_catalog (sqlite3 * handle)
 		    printf ("          Compression: WEBP, lossless\n");
 		else if (strcmp (compression, "FAX4") == 0)
 		    printf ("          Compression: CCITT-FAX4 lossless\n");
+		else if (strcmp (compression, "CHARLS") == 0)
+		    printf ("          Compression: CHARLS, lossless\n");
+		else if (strcmp (compression, "JP2") == 0)
+		    printf ("          Compression: Jpeg2000 (lossy)\n");
+		else if (strcmp (compression, "LL_JP2") == 0)
+		    printf ("          Compression: Jpeg20000, lossless\n");
 		if (strcmp (compression, "JPEG") == 0
-		    || strcmp (compression, "WEBP") == 0)
+		    || strcmp (compression, "WEBP") == 0
+		    || strcmp (compression, "JP2") == 0)
 		    printf ("  Compression Quality: %d\n", quality);
 		printf ("   Tile Size (pixels): %d x %d\n", tileW, tileH);
 		hres = formatFloat (x_res);
@@ -1093,6 +1704,33 @@ exec_catalog (sqlite3 * handle)
 		      printf ("\n");
 
 		  }
+		if (strcmp (pixel, "MULTIBAND") == 0)
+		  {
+		      printf
+			  ("-------------------------------------------------------------------------------\n");
+		      if (valid_default_band_settings
+			  (bands, red_band, green_band, blue_band, nir_band))
+			{
+			    printf ("       Red band index: %d\n", red_band);
+			    printf ("     Green band index: %d\n", green_band);
+			    printf ("      Blue band index: %d\n", blue_band);
+			    printf ("       NIR band index: %d\n", nir_band);
+			    if (auto_ndvi >= 0)
+				printf ("            Auto NDVI: %s\n",
+					auto_ndvi ? "Enabled" : "Disabled");
+			}
+		      else
+			{
+			    printf
+				("       Red band index: *** undefined ***\n");
+			    printf
+				("     Green band index: *** undefined ***\n");
+			    printf
+				("      Blue band index: *** undefined ***\n");
+			    printf
+				("       NIR band index: *** undefined ***\n");
+			}
+		  }
 		if (palette != NULL)
 		  {
 		      /* printing an eventual Palette */
@@ -1262,7 +1900,8 @@ exec_catalog (sqlite3 * handle)
 }
 
 static int
-exec_list (sqlite3 * handle, const char *coverage, const char *section)
+exec_list (sqlite3 * handle, const char *coverage, const char *section,
+	   int ok_section_id, sqlite3_int64 section_id)
 {
 /* Rasterlite-2 datasource Sections list */
     char *sql;
@@ -1280,7 +1919,7 @@ exec_list (sqlite3 * handle, const char *coverage, const char *section)
     int last_id;
     int first;
 
-    if (section == NULL)
+    if (section == NULL && !ok_section_id)
       {
 	  /* all sections */
 	  xsections = sqlite3_mprintf ("%s_sections", coverage);
@@ -1310,6 +1949,26 @@ exec_list (sqlite3 * handle, const char *coverage, const char *section)
     else
       {
 	  /* single section */
+	  char sctn[1024];
+	  if (!ok_section_id)
+	    {
+		/* attempting to resolve the Section Name into a SectionID */
+		int duplicate = 0;
+		if (rl2_get_dbms_section_id
+		    (handle, coverage, section, &section_id,
+		     &duplicate) != RL2_OK)
+		  {
+		      if (duplicate)
+			  fprintf (stderr,
+				   "Ambiguous name: Section \"%s\" in Coverage \"%s\" is not Unique\n",
+				   section, coverage);
+		      else
+			  fprintf (stderr,
+				   "Section \"%s\" does not exists in Coverage \"%s\"\n",
+				   section, coverage);
+		      return 0;
+		  }
+	    }
 	  xsections = sqlite3_mprintf ("%s_sections", coverage);
 	  xxsections = gaiaDoubleQuotedSql (xsections);
 	  sqlite3_free (xsections);
@@ -1319,6 +1978,7 @@ exec_list (sqlite3 * handle, const char *coverage, const char *section)
 	  xdata = sqlite3_mprintf ("%s_tile_data", coverage);
 	  xxdata = gaiaDoubleQuotedSql (xdata);
 	  sqlite3_free (xdata);
+	  sprintf (sctn, "%lld", section_id);
 	  sql =
 	      sqlite3_mprintf
 	      ("SELECT s.section_id, s.section_name, s.width, s.height, "
@@ -1328,9 +1988,9 @@ exec_list (sqlite3 * handle, const char *coverage, const char *section)
 	       "FROM \"%s\" AS s "
 	       "JOIN \"%s\" AS t ON (s.section_id = t.section_id) "
 	       "JOIN \"%s\" AS d ON (d.tile_id = t.tile_id) "
-	       "WHERE s.section_name = %Q "
+	       "WHERE s.section_id = %s "
 	       "GROUP BY s.section_id, t.pyramid_level", xxsections,
-	       xxtiles, xxdata, section);
+	       xxtiles, xxdata, sctn);
 	  free (xxsections);
 	  free (xxtiles);
 	  free (xxdata);
@@ -1541,7 +2201,7 @@ exec_list (sqlite3 * handle, const char *coverage, const char *section)
 
 static int
 exec_map (sqlite3 * handle, const char *coverage, const char *dst_path,
-	  unsigned short width, unsigned short height)
+	  unsigned int width, unsigned int height)
 {
 /* Rasterlite-2 datasource Map */
     char *sql;
@@ -1563,9 +2223,10 @@ exec_map (sqlite3 * handle, const char *coverage, const char *dst_path,
     double cy;
     double base_x;
     double base_y;
-    int row;
-    int col;
+    unsigned int row;
+    unsigned int col;
     unsigned char *p_alpha;
+    int half_transparent;
     rl2GraphicsContextPtr ctx = NULL;
     rl2RasterPtr rst = NULL;
     rl2SectionPtr img = NULL;
@@ -1648,7 +2309,8 @@ exec_map (sqlite3 * handle, const char *coverage, const char *dst_path,
       }
 /* setting up a black Font */
     font =
-	rl2_graph_create_font (16, RL2_FONTSTYLE_ITALIC, RL2_FONTWEIGHT_BOLD);
+	rl2_graph_create_toy_font (NULL, 16, RL2_FONTSTYLE_ITALIC,
+				   RL2_FONTWEIGHT_BOLD);
     if (font == NULL)
       {
 	  fprintf (stderr, "Unable to create a Font\n");
@@ -1710,8 +2372,9 @@ exec_map (sqlite3 * handle, const char *coverage, const char *dst_path,
 		      double cy = y + (h / 2.0);
 		      gaiaFreeGeomColl (geom);
 		      /* setting up a RED pen */
-		      rl2_graph_set_pen (ctx, 255, 0, 0, 255, 2.0,
-					 RL2_PENSTYLE_SOLID);
+		      rl2_graph_set_solid_pen (ctx, 255, 0, 0, 255, 2.0,
+					       RL2_PEN_CAP_BUTT,
+					       RL2_PEN_JOIN_MITER);
 		      /* setting up a Gray solid semi-transparent Brush */
 		      rl2_graph_set_brush (ctx, 255, 255, 255, 204);
 		      rl2_graph_draw_rectangle (ctx, x, y, w, h);
@@ -1719,8 +2382,9 @@ exec_map (sqlite3 * handle, const char *coverage, const char *dst_path,
 						 &pre_y, &t_width, &t_height,
 						 &post_x, &post_y);
 		      /* setting up a white pen */
-		      rl2_graph_set_pen (ctx, 255, 255, 255, 255, 2.0,
-					 RL2_PENSTYLE_SOLID);
+		      rl2_graph_set_solid_pen (ctx, 255, 255, 255, 255, 2.0,
+					       RL2_PEN_CAP_BUTT,
+					       RL2_PEN_JOIN_MITER);
 		      /* setting up a white solid semi-transparent Brush */
 		      rl2_graph_set_brush (ctx, 255, 255, 255, 255);
 		      rl2_graph_draw_rectangle (ctx, cx - (t_width / 2.0),
@@ -1728,7 +2392,8 @@ exec_map (sqlite3 * handle, const char *coverage, const char *dst_path,
 						t_width, t_height);
 		      rl2_graph_draw_text (ctx, section_name,
 					   cx - (t_width / 2.0),
-					   cy + (t_height / 2.0), 0.0);
+					   cy + (t_height / 2.0), 0.0, 0.0,
+					   0.0);
 		  }
 	    }
 	  else
@@ -1748,7 +2413,7 @@ exec_map (sqlite3 * handle, const char *coverage, const char *dst_path,
 	  fprintf (stderr, "invalid RGB buffer from Graphics Context\n");
 	  goto error;
       }
-    alpha = rl2_graph_get_context_alpha_array (ctx);
+    alpha = rl2_graph_get_context_alpha_array (ctx, &half_transparent);
     if (alpha == NULL)
       {
 	  fprintf (stderr, "invalid Alpha buffer from Graphics Context\n");
@@ -1814,6 +2479,7 @@ exec_map (sqlite3 * handle, const char *coverage, const char *dst_path,
 
 static int
 exec_histogram (sqlite3 * handle, const char *coverage, const char *section,
+		int ok_section_id, sqlite3_int64 section_id,
 		unsigned char band_index, const char *dst_path)
 {
 /* Rasterlite-2 PNG Histogram */
@@ -1823,16 +2489,37 @@ exec_histogram (sqlite3 * handle, const char *coverage, const char *section,
     char *xxsections;
     sqlite3_stmt *stmt = NULL;
 
-    if (section != NULL)
+    if (section != NULL || ok_section_id)
       {
 	  /* Histogram from Section-level Statistics */
+	  char sctn[1024];
+	  if (!ok_section_id)
+	    {
+		/* attempting to resolve the Section Name into a SectionID */
+		int duplicate = 0;
+		if (rl2_get_dbms_section_id
+		    (handle, coverage, section, &section_id,
+		     &duplicate) != RL2_OK)
+		  {
+		      if (duplicate)
+			  fprintf (stderr,
+				   "Ambiguous name: Section \"%s\" in Coverage \"%s\" is not Unique\n",
+				   section, coverage);
+		      else
+			  fprintf (stderr,
+				   "Section \"%s\" does not exists in Coverage \"%s\"\n",
+				   section, coverage);
+		      return 0;
+		  }
+	    }
 	  xsections = sqlite3_mprintf ("%s_sections", coverage);
 	  xxsections = gaiaDoubleQuotedSql (xsections);
 	  sqlite3_free (xsections);
+	  sprintf (sctn, "%lld", section_id);
 	  sql =
 	      sqlite3_mprintf
 	      ("SELECT RL2_GetBandStatistics_Histogram(statistics, ?) "
-	       "FROM \"%s\"", xxsections);
+	       "FROM \"%s\" WHERE section_id = %s", xxsections, sctn);
 	  free (xxsections);
       }
     else
@@ -1909,7 +2596,7 @@ spatialite_autocreate (sqlite3 * db)
     int ret;
     char sql[1024];
     char *err_msg = NULL;
-    int count;
+    int count = 0;
     int i;
     char **results;
     int rows;
@@ -1960,7 +2647,8 @@ spatialite_autocreate (sqlite3 * db)
 }
 
 static void
-open_db (const char *path, sqlite3 ** handle, int cache_size, void *cache)
+open_db (const char *path, sqlite3 ** handle, int cache_size, void *cache,
+	 void *priv_data)
 {
 /* opening the DB */
     sqlite3 *db_handle;
@@ -2009,7 +2697,7 @@ open_db (const char *path, sqlite3 ** handle, int cache_size, void *cache)
 	  sprintf (sql, "PRAGMA cache_size=%d", cache_size);
 	  sqlite3_exec (db_handle, sql, NULL, NULL, NULL);
       }
-    rl2_init (db_handle, 0);
+    rl2_init (db_handle, priv_data, 0);
 
 /* checking the GEOMETRY_COLUMNS table */
     strcpy (sql, "PRAGMA table_info(geometry_columns)");
@@ -2095,12 +2783,15 @@ static int
 check_create_args (const char *db_path, const char *coverage, int sample,
 		   int pixel, int num_bands, int compression, int *quality,
 		   int tile_width, int tile_height, int srid, double x_res,
-		   double y_res, rl2PixelPtr pxl)
+		   double y_res, rl2PixelPtr pxl, int red_band, int green_band,
+		   int blue_band, int nir_band, int auto_ndvi,
+		   int strict_resolution, int mixed_resolutions,
+		   int section_paths, int section_md5, int section_summary)
 {
 /* checking/printing CREATE args */
     int err = 0;
     int res_error = 0;
-    printf ("\n\nrl2_tool: request is CREATE\n");
+    printf ("\n\nrl2tool: request is CREATE\n");
     printf ("===========================================================\n");
     if (db_path == NULL)
       {
@@ -2262,19 +2953,75 @@ check_create_args (const char *db_path, const char *coverage, int sample,
 			    rl2_get_pixel_sample_float (pxl, &flt_value);
 			    dummy = formatFloat (flt_value);
 			    printf ("%s", dummy);
-			    free (dummy);
+			    sqlite3_free (dummy);
 			    break;
 			case RL2_SAMPLE_DOUBLE:
 			    rl2_get_pixel_sample_double (pxl, &dbl_value);
 			    dummy = formatFloat (dbl_value);
 			    printf ("%s", dummy);
-			    free (dummy);
+			    sqlite3_free (dummy);
 			    break;
 			};
 		  }
-		fprintf (stderr, "\n");
+		printf ("\n");
 	    }
       }
+    if (pixel == RL2_PIXEL_MULTIBAND)
+      {
+	  if (valid_default_band_settings
+	      (num_bands, red_band, green_band, blue_band, nir_band))
+	    {
+		printf ("       Red band index: %d\n", red_band);
+		printf ("     Green band index: %d\n", green_band);
+		printf ("      Blue band index: %d\n", blue_band);
+		printf ("       NIR band index: %d\n", nir_band);
+		if (auto_ndvi >= 0)
+		    printf ("            Auto NDVI: %s\n",
+			    auto_ndvi ? "Enabled" : "Disabled");
+	    }
+	  else
+	    {
+		printf ("       Red band index: unknown\n");
+		printf ("     Green band index: unknown\n");
+		printf ("      Blue band index: unknown\n");
+		printf ("       NIR band index: unknown\n");
+	    }
+      }
+    if (rl2_is_supported_codec (compression) != 1)
+      {
+	  switch (compression)
+	    {
+	    case RL2_COMPRESSION_LZMA:
+	    case RL2_COMPRESSION_LZMA_NO:
+		fprintf (stderr,
+			 "*** ERROR *** librasterlite2 was built by disabling LZMA support\n");
+		err = 1;
+		break;
+	    case RL2_COMPRESSION_CHARLS:
+		fprintf (stderr,
+			 "*** ERROR *** librasterlite2 was built by disabling CharLS support\n");
+		err = 1;
+		break;
+	    case RL2_COMPRESSION_LOSSY_WEBP:
+	    case RL2_COMPRESSION_LOSSLESS_WEBP:
+		fprintf (stderr,
+			 "*** ERROR *** librasterlite2 was built by disabling WebP support\n");
+		err = 1;
+		break;
+	    case RL2_COMPRESSION_LOSSY_JP2:
+	    case RL2_COMPRESSION_LOSSLESS_JP2:
+		fprintf (stderr,
+			 "*** ERROR *** librasterlite2 was built by disabling OpenJpeg support\n");
+		err = 1;
+		break;
+	    default:
+		fprintf (stderr,
+			 "*** ERROR *** unknown codec (%02x) isn't actually supported\n",
+			 compression);
+		err = 1;
+		break;
+	    };
+      }
     switch (compression)
       {
       case RL2_COMPRESSION_NONE:
@@ -2282,11 +3029,21 @@ check_create_args (const char *db_path, const char *coverage, int sample,
 	  *quality = 100;
 	  break;
       case RL2_COMPRESSION_DEFLATE:
-	  printf ("          Compression: DEFLATE (zip, lossless)\n");
+	  printf
+	      ("          Compression: DEFLATE DeltaFilter (zip, lossless)\n");
+	  *quality = 100;
+	  break;
+      case RL2_COMPRESSION_DEFLATE_NO:
+	  printf ("          Compression: DEFLATE noDelta (zip, lossless)\n");
 	  *quality = 100;
 	  break;
       case RL2_COMPRESSION_LZMA:
-	  printf ("          Compression: LZMA (7-zip, lossless)\n");
+	  printf
+	      ("          Compression: LZMA DeltaFilter (7-zip, lossless)\n");
+	  *quality = 100;
+	  break;
+      case RL2_COMPRESSION_LZMA_NO:
+	  printf ("          Compression: LZMA noDelta (7-zip, lossless)\n");
 	  *quality = 100;
 	  break;
       case RL2_COMPRESSION_GIF:
@@ -2321,6 +3078,22 @@ check_create_args (const char *db_path, const char *coverage, int sample,
 	  printf ("          Compression: CCITT FAX4, lossless\n");
 	  *quality = 100;
 	  break;
+      case RL2_COMPRESSION_CHARLS:
+	  printf ("          Compression: CHARLS, lossless\n");
+	  *quality = 100;
+	  break;
+      case RL2_COMPRESSION_LOSSY_JP2:
+	  printf ("          Compression: JP2 (lossy)\n");
+	  if (*quality < 0)
+	      *quality = 80;
+	  if (*quality > 100)
+	      *quality = 100;
+	  printf ("  Compression Quality: %d\n", *quality);
+	  break;
+      case RL2_COMPRESSION_LOSSLESS_JP2:
+	  printf ("          Compression: JP2, lossless\n");
+	  *quality = 100;
+	  break;
       default:
 	  fprintf (stderr, "*** ERROR *** unknown compression\n");
 	  err = 1;
@@ -2340,26 +3113,42 @@ check_create_args (const char *db_path, const char *coverage, int sample,
       }
     else
 	printf ("                 Srid: %d\n", srid);
-    if (x_res == DBL_MAX || y_res <= 0.0)
-      {
-	  fprintf (stderr, "*** ERROR *** invalid X pixel size\n");
-	  err = 1;
-	  res_error = 1;
-      }
-    if (y_res == DBL_MAX || y_res <= 0.0)
-      {
-	  fprintf (stderr, "*** ERROR *** invalid Y pixel size\n");
-	  err = 1;
-	  res_error = 1;
-      }
-    if (x_res > 0.0 && y_res > 0.0 && !res_error)
+    if (mixed_resolutions)
+	;
+    else
       {
-	  char *hres = formatFloat (x_res);
-	  char *vres = formatFloat (y_res);
-	  printf ("Pixel base resolution: X=%s Y=%s\n", hres, vres);
-	  sqlite3_free (hres);
-	  sqlite3_free (vres);
+	  if (x_res == DBL_MAX || y_res <= 0.0)
+	    {
+		fprintf (stderr, "*** ERROR *** invalid X pixel size\n");
+		err = 1;
+		res_error = 1;
+	    }
+	  if (y_res == DBL_MAX || y_res <= 0.0)
+	    {
+		fprintf (stderr, "*** ERROR *** invalid Y pixel size\n");
+		err = 1;
+		res_error = 1;
+	    }
+	  if (x_res > 0.0 && y_res > 0.0 && !res_error)
+	    {
+		char *hres = formatFloat (x_res);
+		char *vres = formatFloat (y_res);
+		printf ("Pixel base resolution: X=%s Y=%s\n", hres, vres);
+		sqlite3_free (hres);
+		sqlite3_free (vres);
+	    }
       }
+    printf ("======= Coverage Policies =======\n");
+    printf ("Strict Resolution check: %s\n",
+	    !strict_resolution ? "Disabled" : "Enabled");
+    printf (" Mixed Resolutions mode: %s\n",
+	    !mixed_resolutions ? "Disabled" : "Enabled");
+    printf ("  Section's Input Paths: %s\n",
+	    !section_paths ? "Disabled" : "Enabled");
+    printf (" Section's MD5 Checksum: %s\n",
+	    !section_md5 ? "Disabled" : "Enabled");
+    printf ("  Section's XML Summary: %s\n",
+	    !section_summary ? "Disabled" : "Enabled");
     printf ("===========================================================\n\n");
     return err;
 }
@@ -2367,12 +3156,12 @@ check_create_args (const char *db_path, const char *coverage, int sample,
 static int
 check_import_args (const char *db_path, const char *src_path,
 		   const char *dir_path, const char *file_ext,
-		   const char *coverage, const char *section, int worldfile,
-		   int srid, int pyramidize)
+		   const char *coverage, int worldfile, int srid,
+		   int pyramidize)
 {
 /* checking/printing IMPORT args */
     int err = 0;
-    printf ("\n\nrl2_tool; request is IMPORT\n");
+    printf ("\n\nrl2tool; request is IMPORT\n");
     printf ("===========================================================\n");
     if (db_path == NULL)
       {
@@ -2419,10 +3208,6 @@ check_import_args (const char *db_path, const char *src_path,
       }
     else
 	printf ("             Coverage: %s\n", coverage);
-    if (section == NULL)
-	printf ("              Section: from file name\n");
-    else
-	printf ("              Section: %s\n", section);
     if (worldfile)
       {
 	  if (srid <= 0)
@@ -2443,10 +3228,11 @@ check_import_args (const char *db_path, const char *src_path,
 
 static int
 check_export_args (const char *db_path, const char *dst_path,
-		   const char *coverage, double x_res, double y_res,
+		   unsigned char compression, const char *coverage,
+		   int base_resolution, double x_res, double y_res,
 		   double *minx, double *miny, double *maxx, double *maxy,
-		   double *cx, double *cy, unsigned short *width,
-		   unsigned short *height)
+		   double *cx, double *cy, unsigned int *width,
+		   unsigned int *height)
 {
 /* checking/printing EXPORT args */
     double ext_x;
@@ -2454,16 +3240,361 @@ check_export_args (const char *db_path, const char *dst_path,
     char *dumb1;
     char *dumb2;
     int err = 0;
+    int no_res = 0;
+    int err_bbox = 0;
+    printf ("\n\nrl2tool; request is EXPORT\n");
+    printf ("===========================================================\n");
+    if (db_path == NULL)
+      {
+	  fprintf (stderr, "*** ERROR *** no DB path was specified\n");
+	  err = 1;
+      }
+    else
+	printf ("           DB path: %s\n", db_path);
+    if (dst_path == NULL)
+      {
+	  fprintf (stderr, "*** ERROR *** no output path was specified\n");
+	  err = 1;
+      }
+    else
+      {
+	  const char *file_type = "*** UNSUPPORTED ***";
+	  if (is_jpeg_image (dst_path))
+	      file_type = "JPEG";
+	  else if (is_ascii_grid (dst_path))
+	      file_type = "ASCII Grid";
+	  else if (is_tiff_image (dst_path))
+	      file_type = "GeoTIFF";
+	  if (strcmp (file_type, "*** UNSUPPORTED ***") == 0)
+	    {
+		fprintf (stderr, "*** ERROR *** unsupported file format !!!\n");
+		err = 1;
+	    }
+	  printf ("       output path: %s (%s)\n", dst_path, file_type);
+	  if (strcmp (file_type, "GeoTIFF") == 0)
+	    {
+		switch (compression)
+		  {
+		  case RL2_COMPRESSION_CCITTFAX3:
+		      printf ("       compression: FAX3\n");
+		      break;
+		  case RL2_COMPRESSION_CCITTFAX4:
+		      printf ("       compression: FAX4\n");
+		      break;
+		  case RL2_COMPRESSION_DEFLATE:
+		      printf ("       compression: DEFLATE\n");
+		      break;
+		  case RL2_COMPRESSION_LZW:
+		      printf ("       compression: LZW\n");
+		      break;
+		  case RL2_COMPRESSION_LZMA:
+		      printf ("       compression: LZMA\n");
+		      break;
+		  case RL2_COMPRESSION_JPEG:
+		      printf ("       compression: JPEG\n");
+		      break;
+		  default:
+		      printf ("       compression: NONE\n");
+		      break;
+		  };
+	    }
+      }
+    if (coverage == NULL)
+      {
+	  fprintf (stderr, "*** ERROR *** no Coverage's name was specified\n");
+	  err = 1;
+      }
+    else
+	printf ("          Coverage: %s\n", coverage);
+    if (base_resolution && !err)
+	printf ("BaseResolution Selected\n");
+    else
+      {
+	  if (x_res == DBL_MAX || y_res <= 0.0)
+	    {
+		fprintf (stderr, "*** ERROR *** invalid X pixel size\n");
+		err = 1;
+		no_res = 1;
+	    }
+	  if (y_res == DBL_MAX || y_res <= 0.0)
+	    {
+		fprintf (stderr, "*** ERROR *** invalid Y pixel size\n");
+		err = 1;
+		no_res = 1;
+	    }
+	  if (x_res > 0.0 && y_res > 0.0 && !no_res)
+	    {
+		dumb1 = formatFloat (x_res);
+		dumb2 = formatFloat (y_res);
+		printf ("        Pixel size: X=%s Y=%s\n", dumb1, dumb2);
+		sqlite3_free (dumb1);
+		sqlite3_free (dumb2);
+	    }
+      }
+    if (*width == 0)
+      {
+	  fprintf (stderr, "*** ERROR *** NULL/ZERO image Width\n");
+	  err = 1;
+	  err_bbox = 1;
+      }
+    if (*height == 0)
+      {
+	  fprintf (stderr, "*** ERROR *** NULL/ZERO image Height\n");
+	  err = 1;
+	  err_bbox = 1;
+      }
+    if (!err)
+	printf ("        Image Size: %u x %u\n", *width, *height);
+    if (dst_path == NULL)
+      {
+	  fprintf (stderr,
+		   "*** ERROR *** no output Destination path was specified\n");
+	  err = 1;
+      }
+    if (!base_resolution)
+      {
+	  if (*minx == DBL_MAX && *miny == DBL_MAX && *maxx == DBL_MAX
+	      && *maxy == DBL_MAX)
+	    {
+		/* tie-point: Center Point */
+		if (*cx == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Center-X\n");
+		      err = 1;
+		      err_bbox = 1;
+		  }
+		if (*cy == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Center-Y\n");
+		      err = 1;
+		      err_bbox = 1;
+		  }
+		if (err_bbox)
+		    goto error;
+		ext_x = (double) (*width) * x_res;
+		ext_y = (double) (*height) * y_res;
+		*minx = *cx - (ext_x / 2.0);
+		*maxx = *minx + ext_x;
+		*miny = *cy - (ext_y / 2.0);
+		*maxy = *miny + ext_y;
+	    }
+	  else if (*cx == DBL_MAX && *cy == DBL_MAX && *maxx == DBL_MAX
+		   && *maxy == DBL_MAX)
+	    {
+		/* tie-point: LowerLeft Corner */
+		if (*minx == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Min-X\n");
+		      err = 1;
+		      err_bbox = 1;
+		  }
+		if (*miny == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Min-Y\n");
+		      err = 1;
+		      err_bbox = 1;
+		  }
+		if (err_bbox)
+		    goto error;
+		ext_x = (double) (*width) * x_res;
+		ext_y = (double) (*height) * y_res;
+		*maxx = *minx + ext_x;
+		*maxy = *miny + ext_y;
+		*cx = *minx + (ext_x / 2.0);
+		*cy = *miny + (ext_y / 2.0);
+	    }
+	  else if (*cx == DBL_MAX && *cy == DBL_MAX && *minx == DBL_MAX
+		   && *maxy == DBL_MAX)
+	    {
+		/* tie-point: LowerRight Corner */
+		if (*maxx == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Max-X\n");
+		      err = 1;
+		      err_bbox = 1;
+		  }
+		if (*miny == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Min-Y\n");
+		      err = 1;
+		      err_bbox = 1;
+		  }
+		if (err_bbox)
+		    goto error;
+		ext_x = (double) (*width) * x_res;
+		ext_y = (double) (*height) * y_res;
+		*minx = *maxx - ext_x;
+		*maxy = *miny + ext_y;
+		*cx = *maxx - (ext_x / 2.0);
+		*cy = *miny + (ext_y / 2.0);
+	    }
+	  else if (*cx == DBL_MAX && *cy == DBL_MAX && *maxx == DBL_MAX
+		   && *miny == DBL_MAX)
+	    {
+		/* tie-point: UpperLeft Corner */
+		if (*minx == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Min-X\n");
+		      err = 1;
+		      err_bbox = 1;
+		  }
+		if (*maxy == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Max-Y\n");
+		      err = 1;
+		      err_bbox = 1;
+		  }
+		if (err_bbox)
+		    goto error;
+		ext_x = (double) (*width) * x_res;
+		ext_y = (double) (*height) * y_res;
+		*maxx = *minx + ext_x;
+		*miny = *maxy - ext_y;
+		*cx = *minx + (ext_x / 2.0);
+		*cy = *maxy - (ext_y / 2.0);
+	    }
+	  else if (*cx == DBL_MAX && *cy == DBL_MAX && *minx == DBL_MAX
+		   && *miny == DBL_MAX)
+	    {
+		/* tie-point: UpperRight Corner */
+		if (*maxx == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Max-X\n");
+		      err = 1;
+		      err_bbox = 1;
+		  }
+		if (*maxy == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Max-Y\n");
+		      err = 1;
+		      err_bbox = 1;
+		  }
+		if (err_bbox)
+		    goto error;
+		ext_x = (double) (*width) * x_res;
+		ext_y = (double) (*height) * y_res;
+		*minx = *maxx - ext_x;
+		*miny = *maxy - ext_y;
+		*cx = *maxx - (ext_x / 2.0);
+		*cy = *maxy - (ext_y / 2.0);
+	    }
+	  else
+	    {
+		/* invalid tie-point */
+		fprintf (stderr,
+			 "*** ERROR *** invalid output image tie-point\n");
+		err = 1;
+		err_bbox = 1;
+	    }
+      }
+  error:
+    if (!base_resolution)
+      {
+	  if (err_bbox)
+	    {
+		fprintf (stderr,
+			 "*** ERROR *** unable to determine the BBOX of output image\n");
+		err = 1;
+	    }
+	  else
+	    {
+		dumb1 = formatLong (*minx);
+		dumb2 = formatLat (*miny);
+		printf (" Lower-Left Corner: %s %s\n", dumb1, dumb2);
+		sqlite3_free (dumb1);
+		sqlite3_free (dumb2);
+		dumb1 = formatLong (*maxx);
+		dumb2 = formatLat (*maxy);
+		printf ("Upper-Right Corner: %s %s\n", dumb1, dumb2);
+		sqlite3_free (dumb1);
+		sqlite3_free (dumb2);
+		dumb1 = formatLong (*cx);
+		dumb2 = formatLat (*cy);
+		printf ("            Center: %s %s\n", dumb1, dumb2);
+		sqlite3_free (dumb1);
+		sqlite3_free (dumb2);
+	    }
+	  fprintf (stderr,
+		   "===========================================================\n\n");
+      }
+    return err;
+}
+
+static int
+check_section_export_args (const char *db_path, const char *dst_path,
+			   unsigned char compression, const char *coverage,
+			   const char *section, int ok_section_id,
+			   sqlite3_int64 section_id, int base_resolution,
+			   double x_res, double y_res, double *minx,
+			   double *miny, double *maxx, double *maxy, double *cx,
+			   double *cy, unsigned int *width,
+			   unsigned int *height, int full_section)
+{
+/* checking/printing SECTION-EXPORT args */
+    double ext_x;
+    double ext_y;
+    char *dumb1;
+    char *dumb2;
+    int err = 0;
+    int no_res = 0;
     int err_bbox = 0;
-    printf ("\n\nrl2_tool; request is EXPORT\n");
+    printf ("\n\nrl2tool; request is SECTION-EXPORT\n");
     printf ("===========================================================\n");
     if (db_path == NULL)
       {
 	  fprintf (stderr, "*** ERROR *** no DB path was specified\n");
 	  err = 1;
       }
-    else
-	printf ("           DB path: %s\n", db_path);
+    else
+	printf ("           DB path: %s\n", db_path);
+    if (dst_path == NULL)
+      {
+	  fprintf (stderr, "*** ERROR *** no output path was specified\n");
+	  err = 1;
+      }
+    else
+      {
+	  const char *file_type = "*** UNSUPPORTED ***";
+	  if (is_jpeg_image (dst_path))
+	      file_type = "JPEG";
+	  else if (is_ascii_grid (dst_path))
+	      file_type = "ASCII Grid";
+	  else if (is_tiff_image (dst_path))
+	      file_type = "GeoTIFF";
+	  if (strcmp (file_type, "*** UNSUPPORTED ***") == 0)
+	    {
+		fprintf (stderr, "*** ERROR *** unsupported file format !!!\n");
+		err = 1;
+	    }
+	  printf ("       output path: %s (%s)\n", dst_path, file_type);
+	  if (strcmp (file_type, "GeoTIFF") == 0)
+	    {
+		switch (compression)
+		  {
+		  case RL2_COMPRESSION_CCITTFAX3:
+		      printf ("       compression: FAX3\n");
+		      break;
+		  case RL2_COMPRESSION_CCITTFAX4:
+		      printf ("       compression: FAX4\n");
+		      break;
+		  case RL2_COMPRESSION_DEFLATE:
+		      printf ("       compression: DEFLATE\n");
+		      break;
+		  case RL2_COMPRESSION_LZW:
+		      printf ("       compression: LZW\n");
+		      break;
+		  case RL2_COMPRESSION_LZMA:
+		      printf ("       compression: LZMA\n");
+		      break;
+		  case RL2_COMPRESSION_JPEG:
+		      printf ("       compression: JPEG\n");
+		      break;
+		  default:
+		      printf ("       compression: NONE\n");
+		      break;
+		  };
+	    }
+      }
     if (coverage == NULL)
       {
 	  fprintf (stderr, "*** ERROR *** no Coverage's name was specified\n");
@@ -2471,23 +3602,45 @@ check_export_args (const char *db_path, const char *dst_path,
       }
     else
 	printf ("          Coverage: %s\n", coverage);
-    if (x_res == DBL_MAX || y_res <= 0.0)
+    if (section == NULL && !ok_section_id)
       {
-	  fprintf (stderr, "*** ERROR *** invalid X pixel size\n");
+	  fprintf (stderr,
+		   "*** ERROR *** neither SectionName or SectionID was specified\n");
 	  err = 1;
       }
-    if (y_res == DBL_MAX || y_res <= 0.0)
+    else if (ok_section_id)
+	printf ("           Section: ID=%lld\n", section_id);
+    else
+	printf ("           Section: %s\n", section);
+    if (base_resolution && !err)
+	printf ("BaseResolution Selected\n");
+    else
       {
-	  fprintf (stderr, "*** ERROR *** invalid Y pixel size\n");
-	  err = 1;
+	  if (x_res == DBL_MAX || y_res <= 0.0)
+	    {
+		fprintf (stderr, "*** ERROR *** invalid X pixel size\n");
+		err = 1;
+		no_res = 1;
+	    }
+	  if (y_res == DBL_MAX || y_res <= 0.0)
+	    {
+		fprintf (stderr, "*** ERROR *** invalid Y pixel size\n");
+		err = 1;
+		no_res = 1;
+	    }
+	  if (x_res > 0.0 && y_res > 0.0 && !no_res)
+	    {
+		dumb1 = formatFloat (x_res);
+		dumb2 = formatFloat (y_res);
+		printf ("        Pixel size: X=%s Y=%s\n", dumb1, dumb2);
+		sqlite3_free (dumb1);
+		sqlite3_free (dumb2);
+	    }
       }
-    if (x_res > 0.0 && y_res > 0.0)
+    if (full_section)
       {
-	  dumb1 = formatFloat (x_res);
-	  dumb2 = formatFloat (y_res);
-	  printf ("        Pixel size: X=%s Y=%s\n", dumb1, dumb2);
-	  sqlite3_free (dumb1);
-	  sqlite3_free (dumb2);
+	  printf ("Full Section's Extent Selected\n");
+	  return err;
       }
     if (*width == 0)
       {
@@ -2509,165 +3662,172 @@ check_export_args (const char *db_path, const char *dst_path,
 		   "*** ERROR *** no output Destination path was specified\n");
 	  err = 1;
       }
-    if (*minx == DBL_MAX && *miny == DBL_MAX && *maxx == DBL_MAX
-	&& *maxy == DBL_MAX)
+    if (!base_resolution)
       {
-	  /* tie-point: Center Point */
-	  if (*cx == DBL_MAX)
+	  if (*minx == DBL_MAX && *miny == DBL_MAX && *maxx == DBL_MAX
+	      && *maxy == DBL_MAX)
 	    {
-		fprintf (stderr, "*** ERROR *** undeclared Center-X\n");
-		err = 1;
-		err_bbox = 1;
+		/* tie-point: Center Point */
+		if (*cx == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Center-X\n");
+		      err = 1;
+		      err_bbox = 1;
+		  }
+		if (*cy == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Center-Y\n");
+		      err = 1;
+		      err_bbox = 1;
+		  }
+		if (err_bbox)
+		    goto error;
+		ext_x = (double) (*width) * x_res;
+		ext_y = (double) (*height) * y_res;
+		*minx = *cx - (ext_x / 2.0);
+		*maxx = *minx + ext_x;
+		*miny = *cy - (ext_y / 2.0);
+		*maxy = *miny + ext_y;
 	    }
-	  if (*cy == DBL_MAX)
+	  else if (*cx == DBL_MAX && *cy == DBL_MAX && *maxx == DBL_MAX
+		   && *maxy == DBL_MAX)
 	    {
-		fprintf (stderr, "*** ERROR *** undeclared Center-Y\n");
-		err = 1;
-		err_bbox = 1;
+		/* tie-point: LowerLeft Corner */
+		if (*minx == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Min-X\n");
+		      err = 1;
+		      err_bbox = 1;
+		  }
+		if (*miny == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Min-Y\n");
+		      err = 1;
+		      err_bbox = 1;
+		  }
+		if (err_bbox)
+		    goto error;
+		ext_x = (double) (*width) * x_res;
+		ext_y = (double) (*height) * y_res;
+		*maxx = *minx + ext_x;
+		*maxy = *miny + ext_y;
+		*cx = *minx + (ext_x / 2.0);
+		*cy = *miny + (ext_y / 2.0);
 	    }
-	  if (err_bbox)
-	      goto error;
-	  ext_x = (double) (*width) * x_res;
-	  ext_y = (double) (*height) * y_res;
-	  *minx = *cx - (ext_x / 2.0);
-	  *maxx = *minx + ext_x;
-	  *miny = *cy - (ext_y / 2.0);
-	  *maxy = *miny + ext_y;
-      }
-    else if (*cx == DBL_MAX && *cy == DBL_MAX && *maxx == DBL_MAX
-	     && *maxy == DBL_MAX)
-      {
-	  /* tie-point: LowerLeft Corner */
-	  if (*minx == DBL_MAX)
+	  else if (*cx == DBL_MAX && *cy == DBL_MAX && *minx == DBL_MAX
+		   && *maxy == DBL_MAX)
 	    {
-		fprintf (stderr, "*** ERROR *** undeclared Min-X\n");
-		err = 1;
-		err_bbox = 1;
+		/* tie-point: LowerRight Corner */
+		if (*maxx == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Max-X\n");
+		      err = 1;
+		      err_bbox = 1;
+		  }
+		if (*miny == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Min-Y\n");
+		      err = 1;
+		      err_bbox = 1;
+		  }
+		if (err_bbox)
+		    goto error;
+		ext_x = (double) (*width) * x_res;
+		ext_y = (double) (*height) * y_res;
+		*minx = *maxx - ext_x;
+		*maxy = *miny + ext_y;
+		*cx = *maxx - (ext_x / 2.0);
+		*cy = *miny + (ext_y / 2.0);
 	    }
-	  if (*miny == DBL_MAX)
+	  else if (*cx == DBL_MAX && *cy == DBL_MAX && *maxx == DBL_MAX
+		   && *miny == DBL_MAX)
 	    {
-		fprintf (stderr, "*** ERROR *** undeclared Min-Y\n");
-		err = 1;
-		err_bbox = 1;
+		/* tie-point: UpperLeft Corner */
+		if (*minx == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Min-X\n");
+		      err = 1;
+		      err_bbox = 1;
+		  }
+		if (*maxy == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Max-Y\n");
+		      err = 1;
+		      err_bbox = 1;
+		  }
+		if (err_bbox)
+		    goto error;
+		ext_x = (double) (*width) * x_res;
+		ext_y = (double) (*height) * y_res;
+		*maxx = *minx + ext_x;
+		*miny = *maxy - ext_y;
+		*cx = *minx + (ext_x / 2.0);
+		*cy = *maxy - (ext_y / 2.0);
 	    }
-	  if (err_bbox)
-	      goto error;
-	  ext_x = (double) (*width) * x_res;
-	  ext_y = (double) (*height) * y_res;
-	  *maxx = *minx + ext_x;
-	  *maxy = *miny + ext_y;
-	  *cx = *minx + (ext_x / 2.0);
-	  *cy = *miny + (ext_y / 2.0);
-      }
-    else if (*cx == DBL_MAX && *cy == DBL_MAX && *minx == DBL_MAX
-	     && *maxy == DBL_MAX)
-      {
-	  /* tie-point: LowerRight Corner */
-	  if (*maxx == DBL_MAX)
+	  else if (*cx == DBL_MAX && *cy == DBL_MAX && *minx == DBL_MAX
+		   && *miny == DBL_MAX)
 	    {
-		fprintf (stderr, "*** ERROR *** undeclared Max-X\n");
-		err = 1;
-		err_bbox = 1;
+		/* tie-point: UpperRight Corner */
+		if (*maxx == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Max-X\n");
+		      err = 1;
+		      err_bbox = 1;
+		  }
+		if (*maxy == DBL_MAX)
+		  {
+		      fprintf (stderr, "*** ERROR *** undeclared Max-Y\n");
+		      err = 1;
+		      err_bbox = 1;
+		  }
+		if (err_bbox)
+		    goto error;
+		ext_x = (double) (*width) * x_res;
+		ext_y = (double) (*height) * y_res;
+		*minx = *maxx - ext_x;
+		*miny = *maxy - ext_y;
+		*cx = *maxx - (ext_x / 2.0);
+		*cy = *maxy - (ext_y / 2.0);
 	    }
-	  if (*miny == DBL_MAX)
+	  else
 	    {
-		fprintf (stderr, "*** ERROR *** undeclared Min-Y\n");
+		/* invalid tie-point */
+		fprintf (stderr,
+			 "*** ERROR *** invalid output image tie-point\n");
 		err = 1;
 		err_bbox = 1;
 	    }
-	  if (err_bbox)
-	      goto error;
-	  ext_x = (double) (*width) * x_res;
-	  ext_y = (double) (*height) * y_res;
-	  *minx = *maxx - ext_x;
-	  *maxy = *miny + ext_y;
-	  *cx = *maxx - (ext_x / 2.0);
-	  *cy = *miny + (ext_y / 2.0);
       }
-    else if (*cx == DBL_MAX && *cy == DBL_MAX && *maxx == DBL_MAX
-	     && *miny == DBL_MAX)
+  error:
+    if (!base_resolution)
       {
-	  /* tie-point: UpperLeft Corner */
-	  if (*minx == DBL_MAX)
-	    {
-		fprintf (stderr, "*** ERROR *** undeclared Min-X\n");
-		err = 1;
-		err_bbox = 1;
-	    }
-	  if (*maxy == DBL_MAX)
-	    {
-		fprintf (stderr, "*** ERROR *** undeclared Max-Y\n");
-		err = 1;
-		err_bbox = 1;
-	    }
 	  if (err_bbox)
-	      goto error;
-	  ext_x = (double) (*width) * x_res;
-	  ext_y = (double) (*height) * y_res;
-	  *maxx = *minx + ext_x;
-	  *miny = *maxy - ext_y;
-	  *cx = *minx + (ext_x / 2.0);
-	  *cy = *maxy - (ext_y / 2.0);
-      }
-    else if (*cx == DBL_MAX && *cy == DBL_MAX && *minx == DBL_MAX
-	     && *miny == DBL_MAX)
-      {
-	  /* tie-point: UpperRight Corner */
-	  if (*maxx == DBL_MAX)
 	    {
-		fprintf (stderr, "*** ERROR *** undeclared Max-X\n");
+		fprintf (stderr,
+			 "*** ERROR *** unable to determine the BBOX of output image\n");
 		err = 1;
-		err_bbox = 1;
 	    }
-	  if (*maxy == DBL_MAX)
+	  else
 	    {
-		fprintf (stderr, "*** ERROR *** undeclared Max-Y\n");
-		err = 1;
-		err_bbox = 1;
+		dumb1 = formatLong (*minx);
+		dumb2 = formatLat (*miny);
+		printf (" Lower-Left Corner: %s %s\n", dumb1, dumb2);
+		sqlite3_free (dumb1);
+		sqlite3_free (dumb2);
+		dumb1 = formatLong (*maxx);
+		dumb2 = formatLat (*maxy);
+		printf ("Upper-Right Corner: %s %s\n", dumb1, dumb2);
+		sqlite3_free (dumb1);
+		sqlite3_free (dumb2);
+		dumb1 = formatLong (*cx);
+		dumb2 = formatLat (*cy);
+		printf ("            Center: %s %s\n", dumb1, dumb2);
+		sqlite3_free (dumb1);
+		sqlite3_free (dumb2);
 	    }
-	  if (err_bbox)
-	      goto error;
-	  ext_x = (double) (*width) * x_res;
-	  ext_y = (double) (*height) * y_res;
-	  *minx = *maxx - ext_x;
-	  *miny = *maxy - ext_y;
-	  *cx = *maxx - (ext_x / 2.0);
-	  *cy = *maxy - (ext_y / 2.0);
-      }
-    else
-      {
-	  /* invalid tie-point */
-	  fprintf (stderr, "*** ERROR *** invalid output image tie-point\n");
-	  err = 1;
-	  err_bbox = 1;
-      }
-  error:
-    if (err_bbox)
-      {
 	  fprintf (stderr,
-		   "*** ERROR *** unable to determine the BBOX of output image\n");
-	  err = 1;
-      }
-    else
-      {
-	  dumb1 = formatLong (*minx);
-	  dumb2 = formatLat (*miny);
-	  printf (" Lower-Left Corner: %s %s\n", dumb1, dumb2);
-	  sqlite3_free (dumb1);
-	  sqlite3_free (dumb2);
-	  dumb1 = formatLong (*maxx);
-	  dumb2 = formatLat (*maxy);
-	  printf ("Upper-Right Corner: %s %s\n", dumb1, dumb2);
-	  sqlite3_free (dumb1);
-	  sqlite3_free (dumb2);
-	  dumb1 = formatLong (*cx);
-	  dumb2 = formatLat (*cy);
-	  printf ("            Center: %s %s\n", dumb1, dumb2);
-	  sqlite3_free (dumb1);
-	  sqlite3_free (dumb2);
+		   "===========================================================\n\n");
       }
-    fprintf (stderr,
-	     "===========================================================\n\n");
     return err;
 }
 
@@ -2676,7 +3836,7 @@ check_drop_args (const char *db_path, const char *coverage)
 {
 /* checking/printing DROP args */
     int err = 0;
-    printf ("\n\nrl2_tool; request is DROP\n");
+    printf ("\n\nrl2tool; request is DROP\n");
     printf ("===========================================================\n");
     if (db_path == NULL)
       {
@@ -2698,11 +3858,12 @@ check_drop_args (const char *db_path, const char *coverage)
 
 static int
 check_delete_args (const char *db_path, const char *coverage,
-		   const char *section)
+		   const char *section, int ok_section_id,
+		   sqlite3_int64 section_id)
 {
 /* checking/printing DELETE args */
     int err = 0;
-    printf ("\n\nrl2_tool; request is DELETE\n");
+    printf ("\n\nrl2tool; request is DELETE\n");
     printf ("===========================================================\n");
     if (db_path == NULL)
       {
@@ -2718,11 +3879,14 @@ check_delete_args (const char *db_path, const char *coverage,
       }
     else
 	printf ("Coverage: %s\n", coverage);
-    if (section == NULL)
+    if (section == NULL && !ok_section_id)
       {
-	  fprintf (stderr, "*** ERROR *** no Section's name was specified\n");
+	  fprintf (stderr,
+		   "*** ERROR *** neither SectionName or SectionID was specified\n");
 	  err = 1;
       }
+    else if (ok_section_id)
+	printf ("           Section: ID=%lld\n", section_id);
     else
 	printf ("Section: %s\n", section);
     printf ("===========================================================\n\n");
@@ -2731,11 +3895,12 @@ check_delete_args (const char *db_path, const char *coverage,
 
 static int
 check_pyramidize_args (const char *db_path, const char *coverage,
-		       const char *section, int force)
+		       const char *section, int ok_section_id,
+		       sqlite3_int64 section_id, int force)
 {
 /* checking/printing PYRAMIDIZE args */
     int err = 0;
-    printf ("\n\nrl2_tool; request is PYRAMIDIZE\n");
+    printf ("\n\nrl2tool; request is PYRAMIDIZE\n");
     printf ("===========================================================\n");
     if (db_path == NULL)
       {
@@ -2751,10 +3916,12 @@ check_pyramidize_args (const char *db_path, const char *coverage,
       }
     else
 	printf ("Coverage: %s\n", coverage);
-    if (section == NULL)
-	printf ("Section: All Sections\n");
+    if (section == NULL && !ok_section_id)
+	printf (" Section: All Sections\n");
+    else if (ok_section_id)
+	printf (" Section: ID=%lld\n", section_id);
     else
-	printf ("Section: %s\n", section);
+	printf (" Section: %s\n", section);
     if (force)
 	printf ("Unconditionally rebuilding all Pyramid Levels\n");
     else
@@ -2769,7 +3936,7 @@ check_pyramidize_monolithic_args (const char *db_path, const char *coverage,
 {
 /* checking/printing PYRAMIDIZE-MONOLITHIC args */
     int err = 0;
-    printf ("\n\nrl2_tool; request is PYRAMIDIZE-MONOLITHIC\n");
+    printf ("\n\nrl2tool; request is PYRAMIDIZE-MONOLITHIC\n");
     printf ("===========================================================\n");
     if (db_path == NULL)
       {
@@ -2795,11 +3962,12 @@ check_pyramidize_monolithic_args (const char *db_path, const char *coverage,
 
 static int
 check_de_pyramidize_args (const char *db_path, const char *coverage,
-			  const char *section)
+			  const char *section, int ok_section_id,
+			  sqlite3_int64 section_id)
 {
 /* checking/printing DE-PYRAMIDIZE args */
     int err = 0;
-    printf ("\n\nrl2_tool; request is DE-PYRAMIDIZE\n");
+    printf ("\n\nrl2tool; request is DE-PYRAMIDIZE\n");
     printf ("===========================================================\n");
     if (db_path == NULL)
       {
@@ -2815,22 +3983,25 @@ check_de_pyramidize_args (const char *db_path, const char *coverage,
       }
     else
 	printf ("Coverage: %s\n", coverage);
-    if (section == NULL)
-	printf ("Section: All Sections\n");
+    if (section == NULL && !ok_section_id)
+	printf (" Section: All Sections\n");
+    else if (ok_section_id)
+	printf (" Section: ID=%lld\n", section_id);
     else
-	printf ("Section: %s\n", section);
+	printf (" Section: %s\n", section);
     printf ("===========================================================\n\n");
     return err;
 }
 
 static int
 check_histogram_args (const char *db_path, const char *coverage,
-		      const char *section, unsigned char band_index,
+		      const char *section, int ok_section_id,
+		      sqlite3_int64 section_id, unsigned char band_index,
 		      const char *dst_path)
 {
 /* checking/printing HISTOGRAM args */
     int err = 0;
-    printf ("\n\nrl2_tool; request is HISTOGRAM\n");
+    printf ("\n\nrl2tool; request is HISTOGRAM\n");
     printf ("===========================================================\n");
     if (db_path == NULL)
       {
@@ -2846,8 +4017,13 @@ check_histogram_args (const char *db_path, const char *coverage,
       }
     else
 	printf ("   Coverage: %s\n", coverage);
-    if (section == NULL)
+    if (section == NULL && !ok_section_id)
 	printf ("             Histogram from Coverage-level Statistics\n");
+    else if (ok_section_id)
+      {
+	  printf ("   Section: ID=%lld\n", section_id);
+	  printf ("              Histogram from Section-level Statistics\n");
+      }
     else
       {
 	  printf ("   Section: %s\n", section);
@@ -2867,11 +4043,12 @@ check_histogram_args (const char *db_path, const char *coverage,
 }
 
 static int
-check_list_args (const char *db_path, const char *coverage, const char *section)
+check_list_args (const char *db_path, const char *coverage, const char *section,
+		 int ok_section_id, sqlite3_int64 section_id)
 {
 /* checking/printing LIST args */
     int err = 0;
-    printf ("\n\nrl2_tool; request is LIST\n");
+    printf ("\n\nrl2tool; request is LIST\n");
     printf ("===========================================================\n");
     if (db_path == NULL)
       {
@@ -2887,8 +4064,10 @@ check_list_args (const char *db_path, const char *coverage, const char *section)
       }
     else
 	printf ("Coverage: %s\n", coverage);
-    if (section == NULL)
+    if (section == NULL && !ok_section_id)
 	printf (" Section: All Sections\n");
+    else if (ok_section_id)
+	printf (" Section: ID=%lld\n", section_id);
     else
 	printf (" Section: %s\n", section);
     printf ("===========================================================\n\n");
@@ -2897,11 +4076,11 @@ check_list_args (const char *db_path, const char *coverage, const char *section)
 
 static int
 check_map_args (const char *db_path, const char *coverage, const char *dst_path,
-		unsigned short *width, unsigned short *height)
+		unsigned int *width, unsigned int *height)
 {
 /* checking/printing MAP args */
     int err = 0;
-    printf ("\n\nrl2_tool; request is MAP\n");
+    printf ("\n\nrl2tool; request is MAP\n");
     printf ("===========================================================\n");
     if (db_path == NULL)
       {
@@ -2943,7 +4122,7 @@ check_catalog_args (const char *db_path)
 {
 /* checking/printing CATALOG args */
     int err = 0;
-    printf ("\n\nrl2_tool; request is CATALOG\n");
+    printf ("\n\nrl2tool; request is CATALOG\n");
     printf ("===========================================================\n");
     if (db_path == NULL)
       {
@@ -2980,14 +4159,14 @@ parse_no_data (const char *in, unsigned char sample_type,
     const char *p;
     const char *start;
     const char *end;
-    char int8_value;
-    unsigned char uint8_value;
-    short int16_value;
-    unsigned short uint16_value;
-    int int32_value;
-    unsigned int uint32_value;
-    float flt_value;
-    double dbl_value;
+    char int8_value = 0;
+    unsigned char uint8_value = 0;
+    short int16_value = 0;
+    unsigned short uint16_value = 0;
+    int int32_value = 0;
+    unsigned int uint32_value = 0;
+    float flt_value = 0.0;
+    double dbl_value = 0.0;
     rl2PixelPtr pixel = NULL;
 
     switch (pixel_type)
@@ -3164,7 +4343,7 @@ static void
 do_help (int mode)
 {
 /* printing the argument list */
-    fprintf (stderr, "\n\nusage: rl2_tool MODE [ ARGLIST ]\n");
+    fprintf (stderr, "\n\nusage: rl2tool MODE [ ARGLIST ]\n");
     fprintf (stderr,
 	     "==============================================================\n");
     fprintf (stderr,
@@ -3215,7 +4394,26 @@ do_help (int mode)
 	  fprintf (stderr, "Compression Keywords:\n");
 	  fprintf (stderr, "----------------------------------\n");
 	  fprintf (stderr,
-		   "NONE DEFLATE LZMA GIF PNG JPEG WEBP LL_WEBP FAX3 FAX4\n\n");
+		   "NONE DEFLATE DEFLATE_NO LZMA LZMA_NO PNG JPEG WEBP LL_WEBP FAX4 CHARLS JP2 LL_JP2\n\n");
+	  fprintf (stderr, "Extra args supported by MULTIBAND:\n");
+	  fprintf (stderr, "----------------------------------\n");
+	  fprintf (stderr, "-red or --red-band     pixel    RED band index\n");
+	  fprintf (stderr,
+		   "-green or --green-band pixel    GREEN band index\n");
+	  fprintf (stderr, "-blue or --blue-band   pixel    BLUE band index\n");
+	  fprintf (stderr, "-nir or --nir-band     pixel    NIR band index\n");
+	  fprintf (stderr,
+		   "-ndvi or --auto-ndvi   boolean  Enabling/Disabling Auto NDVI\n\n");
+	  fprintf (stderr,
+		   "-strict or --strict-resolution  Enables Strict Resolution\n");
+	  fprintf (stderr,
+		   "-mixed or --mixed-resolution    Enables Mixed Resolutions\n");
+	  fprintf (stderr,
+		   "-paths or --input-paths         Enables Input Path recording\n");
+	  fprintf (stderr,
+		   "-nomd5 or --no-input-md5        Disables Input MD5 checksum\n");
+	  fprintf (stderr,
+		   "-noxml or --no-xml-summary      Disables Input MXL Summariy\n");
       }
     if (mode == ARG_NONE || mode == ARG_MODE_DROP)
       {
@@ -3266,7 +4464,10 @@ do_help (int mode)
 		   "-db or --db-path      pathname  RasterLite2 DB path\n");
 	  fprintf (stderr,
 		   "-dst or --dst-path    pathname  output Image/Raster path\n");
+	  fprintf (stderr,
+		   "-cpr or --compression keyword   TIFF Compression (see list)\n");
 	  fprintf (stderr, "-cov or --coverage    string    Coverage's name\n");
+	  fprintf (stderr, "-base or --base-resolution      base resolution\n");
 	  fprintf (stderr,
 		   "-res or --resolution  number    pixel resolution(X and Y)\n");
 	  fprintf (stderr,
@@ -3304,6 +4505,73 @@ do_help (int mode)
 		   "\t\t- Output Image UpperLeft corner: -minx AND -maxy\n");
 	  fprintf (stderr,
 		   "\t\t- Output Image UpperRight corner: -maxx AND -maxy\n\n");
+	  fprintf (stderr, "TIFF Compression Keywords:\n");
+	  fprintf (stderr, "----------------------------------\n");
+	  fprintf (stderr, "NONE DEFLATE LZMA JPEG LZW FAX3 FAX4\n\n");
+      }
+    if (mode == ARG_NONE || mode == ARG_MODE_SECT_EXPORT)
+      {
+	  /* MODE = SECTION-EXPORT */
+	  fprintf (stderr, "\nmode: SECTION-EXPORT\n");
+	  fprintf (stderr,
+		   "will export an external image from a Coverage/Section\n");
+	  fprintf (stderr,
+		   "==============================================================\n");
+	  fprintf (stderr,
+		   "-db or --db-path      pathname  RasterLite2 DB path\n");
+	  fprintf (stderr,
+		   "-dst or --dst-path    pathname  output Image/Raster path\n");
+	  fprintf (stderr,
+		   "-cpr or --compression keyword   TIFF Compression (see list)\n");
+	  fprintf (stderr, "-cov or --coverage    string    Coverage's name\n");
+	  fprintf (stderr, "-sec or --section-name string   Section's name\n");
+	  fprintf (stderr, "-sid or --section-id   number   Section's ID\n");
+	  fprintf (stderr, "-base or --base-resolution      base resolution\n");
+	  fprintf (stderr,
+		   "-res or --resolution   number   pixel resolution(X and Y)\n");
+	  fprintf (stderr,
+		   "-xres or --x-resol     number   pixel resolution(X specific)\n");
+	  fprintf (stderr,
+		   "-yres or --y-resol     number   pixel resolution(Y specific)\n");
+	  fprintf (stderr,
+		   "-full or --full-section         Full Section's extent: both\n");
+	  fprintf (stderr,
+		   "            Width and Height will be automatically computed\n");
+	  fprintf (stderr, "            accordingly to resolution.\n");
+	  fprintf (stderr,
+		   "-minx or --min-x       number   X coordinate (lower-left corner)\n");
+	  fprintf (stderr,
+		   "-miny or --min-y       number   Y coordinate (lower-left corner)\n");
+	  fprintf (stderr,
+		   "-maxx or --max-x       number   X coordinate (upper-right corner)\n");
+	  fprintf (stderr,
+		   "-maxy or --max-y       number   Y coordinate (upper-left corner)\n");
+	  fprintf (stderr,
+		   "-cx or --center-x      number   X coordinate (center)\n");
+	  fprintf (stderr,
+		   "-cy or --center-y      number   Y coordinate (center)\n");
+	  fprintf (stderr,
+		   "-outw or --out-width   number   image width (in pixels)\n");
+	  fprintf (stderr,
+		   "-outh or --out-height  number   image height (in pixels)\n\n");
+	  fprintf (stderr,
+		   "In order to export a raster you are expected to specify:\n");
+	  fprintf (stderr,
+		   "\t- the intended resolution (-res OR -xres AND -yres)\n");
+	  fprintf (stderr, "\t- the output image size (-outw AND -outh)\n");
+	  fprintf (stderr, "\t- a single tie-point, defined as one of:\n");
+	  fprintf (stderr, "\t\t- Output Image Center point: -cx AND -cy\n");
+	  fprintf (stderr,
+		   "\t\t- Output Image LowerLeft corner: -minx AND -miny\n");
+	  fprintf (stderr,
+		   "\t\t- Output Image LowerRight corner: -maxx AND -miny\n");
+	  fprintf (stderr,
+		   "\t\t- Output Image UpperLeft corner: -minx AND -maxy\n");
+	  fprintf (stderr,
+		   "\t\t- Output Image UpperRight corner: -maxx AND -maxy\n\n");
+	  fprintf (stderr, "TIFF Compression Keywords:\n");
+	  fprintf (stderr, "----------------------------------\n");
+	  fprintf (stderr, "NONE DEFLATE LZMA JPEG LZW FAX3 FAX4\n\n");
       }
     if (mode == ARG_NONE || mode == ARG_MODE_DELETE)
       {
@@ -3316,7 +4584,8 @@ do_help (int mode)
 		   "-db or --db-path      pathname  RasterLite2 DB path\n");
 	  fprintf (stderr, "-cov or --coverage    string    Coverage's name\n");
 	  fprintf (stderr,
-		   "-sec or --section     string    Section's name\n\n");
+		   "-sec or --section-name string   Section's name\n\n");
+	  fprintf (stderr, "-sid or --section-id   number   Section's ID\n");
       }
     if (mode == ARG_NONE || mode == ARG_MODE_PYRAMIDIZE)
       {
@@ -3330,7 +4599,9 @@ do_help (int mode)
 		   "-db or --db-path      pathname  RasterLite2 DB path\n");
 	  fprintf (stderr, "-cov or --coverage    string    Coverage's name\n");
 	  fprintf (stderr,
-		   "-sec or --section     string    optional: Section's name\n");
+		   "-sec or --section-name string   optional: Section's name\n");
+	  fprintf (stderr,
+		   "-sid or --section-id   number   optional: Section's ID\n");
 	  fprintf (stderr,
 		   "                                default is \"All Sections\"\n");
 	  fprintf (stderr,
@@ -3363,7 +4634,9 @@ do_help (int mode)
 		   "-db or --db-path      pathname  RasterLite2 DB path\n");
 	  fprintf (stderr, "-cov or --coverage    string    Coverage's name\n");
 	  fprintf (stderr,
-		   "-sec or --section     string    optional: Section's name\n");
+		   "-sec or --section-name string   optional: Section's name\n");
+	  fprintf (stderr,
+		   "-sid or --section-id   number   optional: Section's ID\n");
 	  fprintf (stderr,
 		   "                                default is \"All Sections\"\n");
       }
@@ -3378,7 +4651,9 @@ do_help (int mode)
 		   "-db or --db-path      pathname  RasterLite2 DB path\n");
 	  fprintf (stderr, "-cov or --coverage    string    Coverage's name\n");
 	  fprintf (stderr,
-		   "-sec or --section     string    optional: Section's name\n");
+		   "-sec or --section-name string   optional: Section's name\n");
+	  fprintf (stderr,
+		   "-sid or --section-id   number   optional: Section's ID\n");
 	  fprintf (stderr,
 		   "                                default is \"All Sections\"\n");
       }
@@ -3422,7 +4697,9 @@ do_help (int mode)
 		   "-db or --db-path      pathname  RasterLite2 DB path\n");
 	  fprintf (stderr, "-cov or --coverage    string    Coverage's name\n");
 	  fprintf (stderr,
-		   "-sec or --section     string    optional: Section's name\n");
+		   "-sec or --section-name string   optional: Section's name\n");
+	  fprintf (stderr,
+		   "-sid or --section-id   number   optional: Section's ID\n");
 	  fprintf (stderr,
 		   "                                default is \"Coverage statistics\"\n");
 	  fprintf (stderr,
@@ -3440,6 +4717,8 @@ do_help (int mode)
 	  fprintf (stderr,
 		   "==============================================================\n");
 	  fprintf (stderr,
+		   "-mt or --max-threads   num      max number of concurrent threads\n");
+	  fprintf (stderr,
 		   "-cs or --cache-size    num      DB cache size (how many pages)\n");
 	  fprintf (stderr,
 		   "-m or --in-memory               using IN-MEMORY database\n");
@@ -3453,6 +4732,7 @@ main (int argc, char *argv[])
 {
 /* the MAIN function simply perform arguments checking */
     sqlite3 *handle;
+    char *sql;
     int ret;
     char *sql_err = NULL;
     int i;
@@ -3464,6 +4744,8 @@ main (int argc, char *argv[])
     const char *file_ext = ".tif";
     const char *coverage = NULL;
     const char *section = NULL;
+    sqlite3_int64 section_id = 0;
+    int ok_section_id = 0;
     unsigned char sample = RL2_SAMPLE_UNKNOWN;
     unsigned char pixel = RL2_PIXEL_UNKNOWN;
     unsigned char compression = RL2_COMPRESSION_NONE;
@@ -3472,6 +4754,7 @@ main (int argc, char *argv[])
     int quality = -1;
     unsigned short tile_width = 512;
     unsigned short tile_height = 512;
+    int base_resolution = 0;
     double x_res = DBL_MAX;
     double y_res = DBL_MAX;
     double minx = DBL_MAX;
@@ -3480,8 +4763,8 @@ main (int argc, char *argv[])
     double maxy = DBL_MAX;
     double cx = DBL_MAX;
     double cy = DBL_MAX;
-    unsigned short width = 0;
-    unsigned short height = 0;
+    unsigned int width = 0;
+    unsigned int height = 0;
     int srid = -2;
     int virt_levels = 0;
     const char *no_data_str = NULL;
@@ -3492,11 +4775,25 @@ main (int argc, char *argv[])
     int in_memory = 0;
     int cache_size = 0;
     int journal_off = 0;
+    int full_section = 0;
     int error = 0;
     int mode = ARG_NONE;
     void *cache;
-    void *cache_mem;
+    void *priv_data;
+    void *cache_mem = NULL;
     char *hist_path = NULL;
+    int strict_resolution = 0;
+    int mixed_resolutions = 0;
+    int section_paths = 0;
+    int section_md5 = 1;
+    int section_summary = 1;
+    int red_band = -1;
+    int green_band = -1;
+    int blue_band = -1;
+    int nir_band = -1;
+    int auto_ndvi = -1;
+    int retcode = 0;
+    int max_threads = 1;
 
     if (argc >= 2)
       {
@@ -3509,6 +4806,8 @@ main (int argc, char *argv[])
 	      mode = ARG_MODE_IMPORT;
 	  if (strcasecmp (argv[1], "EXPORT") == 0)
 	      mode = ARG_MODE_EXPORT;
+	  if (strcasecmp (argv[1], "SECTION-EXPORT") == 0)
+	      mode = ARG_MODE_SECT_EXPORT;
 	  if (strcasecmp (argv[1], "DELETE") == 0)
 	      mode = ARG_MODE_DELETE;
 	  if (strcasecmp (argv[1], "PYRAMIDIZE") == 0)
@@ -3555,6 +4854,10 @@ main (int argc, char *argv[])
 		  case ARG_SECTION:
 		      section = argv[i];
 		      break;
+		  case ARG_SECTION_ID:
+		      section_id = atoll (argv[i]);
+		      ok_section_id = 1;
+		      break;
 		  case ARG_SAMPLE:
 		      if (strcasecmp (argv[i], "1-BIT") == 0)
 			  sample = RL2_SAMPLE_1_BIT;
@@ -3605,8 +4908,14 @@ main (int argc, char *argv[])
 			  compression = RL2_COMPRESSION_NONE;
 		      if (strcasecmp (argv[i], "DEFLATE") == 0)
 			  compression = RL2_COMPRESSION_DEFLATE;
+		      if (strcasecmp (argv[i], "DEFLATE_NO") == 0)
+			  compression = RL2_COMPRESSION_DEFLATE_NO;
 		      if (strcasecmp (argv[i], "LZMA") == 0)
 			  compression = RL2_COMPRESSION_LZMA;
+		      if (strcasecmp (argv[i], "LZMA_NO") == 0)
+			  compression = RL2_COMPRESSION_LZMA_NO;
+		      if (strcasecmp (argv[i], "LZW") == 0)
+			  compression = RL2_COMPRESSION_LZW;
 		      if (strcasecmp (argv[i], "GIF") == 0)
 			  compression = RL2_COMPRESSION_GIF;
 		      if (strcasecmp (argv[i], "PNG") == 0)
@@ -3621,6 +4930,12 @@ main (int argc, char *argv[])
 			  compression = RL2_COMPRESSION_CCITTFAX3;
 		      if (strcasecmp (argv[i], "FAX4") == 0)
 			  compression = RL2_COMPRESSION_CCITTFAX4;
+		      if (strcasecmp (argv[i], "CHARLS") == 0)
+			  compression = RL2_COMPRESSION_CHARLS;
+		      if (strcasecmp (argv[i], "JP2") == 0)
+			  compression = RL2_COMPRESSION_LOSSY_JP2;
+		      if (strcasecmp (argv[i], "LL_JP2") == 0)
+			  compression = RL2_COMPRESSION_LOSSLESS_JP2;
 		      break;
 		  case ARG_QUALITY:
 		      quality = atoi (argv[i]);
@@ -3677,9 +4992,27 @@ main (int argc, char *argv[])
 		  case ARG_IMG_HEIGHT:
 		      height = atoi (argv[i]);
 		      break;
+		  case ARG_RED_BAND:
+		      red_band = atoi (argv[i]);
+		      break;
+		  case ARG_GREEN_BAND:
+		      green_band = atoi (argv[i]);
+		      break;
+		  case ARG_BLUE_BAND:
+		      blue_band = atoi (argv[i]);
+		      break;
+		  case ARG_NIR_BAND:
+		      nir_band = atoi (argv[i]);
+		      break;
+		  case ARG_AUTO_NDVI:
+		      auto_ndvi = atoi (argv[i]);
+		      break;
 		  case ARG_CACHE_SIZE:
 		      cache_size = atoi (argv[i]);
 		      break;
+		  case ARG_MAX_THREADS:
+		      max_threads = atoi (argv[i]);
+		      break;
 		  };
 		next_arg = ARG_NONE;
 		continue;
@@ -3728,11 +5061,17 @@ main (int argc, char *argv[])
 		continue;
 	    }
 	  if (strcmp (argv[i], "-sec") == 0
-	      || strcasecmp (argv[i], "--section") == 0)
+	      || strcasecmp (argv[i], "--section-name") == 0)
 	    {
 		next_arg = ARG_SECTION;
 		continue;
 	    }
+	  if (strcmp (argv[i], "-sid") == 0
+	      || strcasecmp (argv[i], "--section-id") == 0)
+	    {
+		next_arg = ARG_SECTION_ID;
+		continue;
+	    }
 	  if (strcmp (argv[i], "-lev") == 0
 	      || strcasecmp (argv[i], "--virt-levels") == 0)
 	    {
@@ -3817,6 +5156,12 @@ main (int argc, char *argv[])
 		next_arg = ARG_RESOLUTION;
 		continue;
 	    }
+	  if (strcmp (argv[i], "-base") == 0
+	      || strcasecmp (argv[i], "--base-resolution") == 0)
+	    {
+		base_resolution = 1;
+		continue;
+	    }
 	  if (strcmp (argv[i], "-xres") == 0
 	      || strcasecmp (argv[i], "--x-resol") == 0)
 	    {
@@ -3871,6 +5216,36 @@ main (int argc, char *argv[])
 		next_arg = ARG_NO_DATA;
 		continue;
 	    }
+	  if (strcmp (argv[i], "-red") == 0
+	      || strcasecmp (argv[i], "--red-band") == 0)
+	    {
+		next_arg = ARG_RED_BAND;
+		continue;
+	    }
+	  if (strcmp (argv[i], "-green") == 0
+	      || strcasecmp (argv[i], "--green-band") == 0)
+	    {
+		next_arg = ARG_GREEN_BAND;
+		continue;
+	    }
+	  if (strcmp (argv[i], "-blue") == 0
+	      || strcasecmp (argv[i], "--blue-band") == 0)
+	    {
+		next_arg = ARG_BLUE_BAND;
+		continue;
+	    }
+	  if (strcmp (argv[i], "-nir") == 0
+	      || strcasecmp (argv[i], "--nir-band") == 0)
+	    {
+		next_arg = ARG_NIR_BAND;
+		continue;
+	    }
+	  if (strcmp (argv[i], "-ndvi") == 0
+	      || strcasecmp (argv[i], "--auto-ndvi") == 0)
+	    {
+		next_arg = ARG_AUTO_NDVI;
+		continue;
+	    }
 	  if (strcmp (argv[i], "-f") == 0
 	      || strcasecmp (argv[i], "--force") == 0)
 	    {
@@ -3889,6 +5264,49 @@ main (int argc, char *argv[])
 		worldfile = 1;
 		continue;
 	    }
+	  if (strcmp (argv[i], "-full") == 0
+	      || strcasecmp (argv[i], "--full-section") == 0)
+	    {
+		full_section = 1;
+		continue;
+	    }
+	  if (strcmp (argv[i], "-strict") == 0
+	      || strcasecmp (argv[i], "--strict-resolution") == 0)
+	    {
+		strict_resolution = 1;
+		continue;
+	    }
+	  if (strcmp (argv[i], "-mixed") == 0
+	      || strcasecmp (argv[i], "--mixed-resolutions") == 0)
+	    {
+		mixed_resolutions = 1;
+		strict_resolution = 0;
+		continue;
+	    }
+	  if (strcmp (argv[i], "-paths") == 0
+	      || strcasecmp (argv[i], "--input-paths") == 0)
+	    {
+		section_paths = 1;
+		continue;
+	    }
+	  if (strcmp (argv[i], "-nomd5") == 0
+	      || strcasecmp (argv[i], "--no-input-md5") == 0)
+	    {
+		section_md5 = 0;
+		continue;
+	    }
+	  if (strcmp (argv[i], "-noxml") == 0
+	      || strcasecmp (argv[i], "--no-xml-summary") == 0)
+	    {
+		section_summary = 0;
+		continue;
+	    }
+	  if (strcasecmp (argv[i], "--max-threads") == 0
+	      || strcmp (argv[i], "-mt") == 0)
+	    {
+		next_arg = ARG_MAX_THREADS;
+		continue;
+	    }
 	  if (strcasecmp (argv[i], "--cache-size") == 0
 	      || strcmp (argv[i], "-cs") == 0)
 	    {
@@ -3950,7 +5368,10 @@ main (int argc, char *argv[])
 	  error =
 	      check_create_args (db_path, coverage, sample, pixel, num_bands,
 				 compression, &quality, tile_width, tile_height,
-				 srid, x_res, y_res, no_data);
+				 srid, x_res, y_res, no_data, red_band,
+				 green_band, blue_band, nir_band, auto_ndvi,
+				 strict_resolution, mixed_resolutions,
+				 section_paths, section_md5, section_summary);
 	  break;
       case ARG_MODE_DROP:
 	  error = check_drop_args (db_path, coverage);
@@ -3958,31 +5379,45 @@ main (int argc, char *argv[])
       case ARG_MODE_IMPORT:
 	  error =
 	      check_import_args (db_path, src_path, dir_path, file_ext,
-				 coverage, section, worldfile, srid,
-				 pyramidize);
+				 coverage, worldfile, srid, pyramidize);
 	  break;
       case ARG_MODE_EXPORT:
 	  error =
-	      check_export_args (db_path, dst_path, coverage, x_res, y_res,
-				 &minx, &miny, &maxx, &maxy, &cx, &cy, &width,
-				 &height);
+	      check_export_args (db_path, dst_path, compression, coverage,
+				 base_resolution, x_res, y_res, &minx, &miny,
+				 &maxx, &maxy, &cx, &cy, &width, &height);
+	  break;
+      case ARG_MODE_SECT_EXPORT:
+	  error =
+	      check_section_export_args (db_path, dst_path, compression,
+					 coverage, section, ok_section_id,
+					 section_id, base_resolution, x_res,
+					 y_res, &minx, &miny, &maxx, &maxy, &cx,
+					 &cy, &width, &height, full_section);
 	  break;
       case ARG_MODE_DELETE:
-	  error = check_delete_args (db_path, coverage, section);
+	  error =
+	      check_delete_args (db_path, coverage, section, ok_section_id,
+				 section_id);
 	  break;
       case ARG_MODE_PYRAMIDIZE:
 	  error =
-	      check_pyramidize_args (db_path, coverage, section, force_pyramid);
+	      check_pyramidize_args (db_path, coverage, section, ok_section_id,
+				     section_id, force_pyramid);
 	  break;
       case ARG_MODE_PYRMONO:
 	  error =
 	      check_pyramidize_monolithic_args (db_path, coverage, virt_levels);
 	  break;
       case ARG_MODE_DE_PYRAMIDIZE:
-	  error = check_de_pyramidize_args (db_path, coverage, section);
+	  error =
+	      check_de_pyramidize_args (db_path, coverage, section,
+					ok_section_id, section_id);
 	  break;
       case ARG_MODE_LIST:
-	  error = check_list_args (db_path, coverage, section);
+	  error =
+	      check_list_args (db_path, coverage, section, ok_section_id,
+			       section_id);
 	  break;
       case ARG_MODE_MAP:
 	  error = check_map_args (db_path, coverage, dst_path, &width, &height);
@@ -3993,10 +5428,14 @@ main (int argc, char *argv[])
       case ARG_MODE_HISTOGRAM:
 	  if (dst_path == NULL)
 	    {
-		if (section == NULL)
+		if (section == NULL && !ok_section_id)
 		    hist_path =
 			sqlite3_mprintf ("./hist_%s_%d.png", coverage,
 					 band_index);
+		else if (ok_section_id)
+		    hist_path =
+			sqlite3_mprintf ("./hist_%s_ID%lld_%d.png", coverage,
+					 section_id, band_index);
 		else
 		    hist_path =
 			sqlite3_mprintf ("./hist_%s_%s_%d.png", coverage,
@@ -4004,8 +5443,8 @@ main (int argc, char *argv[])
 		dst_path = hist_path;
 	    }
 	  error =
-	      check_histogram_args (db_path, coverage, section, band_index,
-				    dst_path);
+	      check_histogram_args (db_path, coverage, section, ok_section_id,
+				    section_id, band_index, dst_path);
 	  break;
       default:
 	  fprintf (stderr, "did you forget setting some request MODE ?\n");
@@ -4023,7 +5462,8 @@ main (int argc, char *argv[])
     if (in_memory)
 	cache_size = 0;
     cache = spatialite_alloc_connection ();
-    open_db (db_path, &handle, cache_size, cache);
+    priv_data = rl2_alloc_private ();
+    open_db (db_path, &handle, cache_size, cache, priv_data);
     if (!handle)
 	return -1;
     if (in_memory)
@@ -4062,13 +5502,26 @@ main (int argc, char *argv[])
 	  handle = mem_db_handle;
 	  printf ("\nusing IN-MEMORY database\n");
 	  spatialite_cleanup_ex (cache);
+	  cache = NULL;
 	  cache_mem = spatialite_alloc_connection ();
 	  spatialite_init_ex (handle, cache_mem, 0);
       }
 
 /* properly setting up the connection */
     if (!set_connection (handle, journal_off))
-	goto stop;
+      {
+	  retcode = -1;
+	  goto stop;
+      }
+
+/* setting up MaxThreads */
+    if (max_threads < 1)
+	max_threads = 1;
+    if (max_threads > 64)
+	max_threads = 64;
+    sql = sqlite3_mprintf ("SELECT RL2_SetMaxThreads(%d)", max_threads);
+    sqlite3_exec (handle, sql, NULL, NULL, NULL);
+    sqlite3_free (sql);
 
 /* the complete operation is handled as an unique SQL Transaction */
     ret = sqlite3_exec (handle, "BEGIN", NULL, NULL, &sql_err);
@@ -4076,6 +5529,7 @@ main (int argc, char *argv[])
       {
 	  fprintf (stderr, "BEGIN TRANSACTION error: %s\n", sql_err);
 	  sqlite3_free (sql_err);
+	  retcode = -1;
 	  goto stop;
       }
 
@@ -4086,45 +5540,65 @@ main (int argc, char *argv[])
 	  ret =
 	      exec_create (handle, coverage, sample, pixel,
 			   num_bands, compression, quality, tile_width,
-			   tile_height, srid, x_res, y_res, no_data);
+			   tile_height, srid, x_res, y_res, no_data, red_band,
+			   green_band, blue_band, nir_band, auto_ndvi,
+			   strict_resolution, mixed_resolutions, section_paths,
+			   section_md5, section_summary);
 	  break;
       case ARG_MODE_DROP:
 	  ret = exec_drop (handle, coverage);
 	  break;
       case ARG_MODE_IMPORT:
 	  ret =
-	      exec_import (handle, src_path, dir_path, file_ext, coverage,
-			   worldfile, srid, pyramidize);
+	      exec_import (handle, max_threads, src_path, dir_path, file_ext,
+			   coverage, worldfile, srid, pyramidize);
 	  break;
       case ARG_MODE_EXPORT:
 	  ret =
-	      exec_export (handle, dst_path, coverage, x_res, y_res, minx, miny,
+	      exec_export (handle, max_threads, dst_path, compression, coverage,
+			   base_resolution, x_res, y_res, cx, cy, minx, miny,
 			   maxx, maxy, width, height);
 	  break;
+      case ARG_MODE_SECT_EXPORT:
+	  ret =
+	      exec_section_export (handle, max_threads, dst_path, compression,
+				   coverage, section, ok_section_id, section_id,
+				   base_resolution, x_res, y_res, cx, cy, minx,
+				   miny, maxx, maxy, width, height,
+				   full_section);
+	  break;
       case ARG_MODE_DELETE:
-	  ret = exec_delete (handle, coverage, section);
+	  ret =
+	      exec_delete (handle, coverage, section, ok_section_id,
+			   section_id);
 	  break;
       case ARG_MODE_PYRAMIDIZE:
-	  ret = exec_pyramidize (handle, coverage, section, force_pyramid);
+	  ret =
+	      exec_pyramidize (handle, max_threads, coverage, section,
+			       ok_section_id, section_id, force_pyramid);
 	  break;
       case ARG_MODE_PYRMONO:
 	  ret = exec_pyramidize_monolithic (handle, coverage, virt_levels);
 	  break;
       case ARG_MODE_DE_PYRAMIDIZE:
-	  ret = exec_de_pyramidize (handle, coverage, section);
+	  ret =
+	      exec_de_pyramidize (handle, coverage, section, ok_section_id,
+				  section_id);
 	  break;
       case ARG_MODE_CATALOG:
 	  ret = exec_catalog (handle);
 	  break;
       case ARG_MODE_LIST:
-	  ret = exec_list (handle, coverage, section);
+	  ret =
+	      exec_list (handle, coverage, section, ok_section_id, section_id);
 	  break;
       case ARG_MODE_MAP:
 	  ret = exec_map (handle, coverage, dst_path, width, height);
 	  break;
       case ARG_MODE_HISTOGRAM:
 	  ret =
-	      exec_histogram (handle, coverage, section, band_index, dst_path);
+	      exec_histogram (handle, coverage, section, ok_section_id,
+			      section_id, band_index, dst_path);
 	  break;
       };
 
@@ -4152,6 +5626,9 @@ main (int argc, char *argv[])
 	    case ARG_MODE_EXPORT:
 		op_name = "EXPORT";
 		break;
+	    case ARG_MODE_SECT_EXPORT:
+		op_name = "SECTION-EXPORT";
+		break;
 	    case ARG_MODE_DELETE:
 		op_name = "DELETE";
 		break;
@@ -4182,6 +5659,7 @@ main (int argc, char *argv[])
     else
       {
 	  /* invalidating the still pending SQL Transaction */
+	  retcode = -1;
 	  fprintf (stderr,
 		   "\nrestoring the DB to its previous state (ROLLBACK)\n");
 	  ret = sqlite3_exec (handle, "ROLLBACK", NULL, NULL, &sql_err);
@@ -4232,10 +5710,14 @@ main (int argc, char *argv[])
       }
 
   stop:
+    if (no_data != NULL)
+	rl2_destroy_pixel (no_data);
     if (hist_path != NULL)
 	sqlite3_free (hist_path);
     sqlite3_close (handle);
-    spatialite_cleanup_ex (cache);
+    rl2_cleanup_private (priv_data);
+    if (cache != NULL)
+	spatialite_cleanup_ex (cache);
     spatialite_shutdown ();
-    return 0;
+    return retcode;
 }
diff --git a/tools/wmslite.c b/tools/wmslite.c
index 0572c6b..8ab0bb2 100644
--- a/tools/wmslite.c
+++ b/tools/wmslite.c
@@ -52,7 +52,8 @@
 #define ARG_NONE		0
 #define ARG_DB_PATH		1
 #define ARG_IP_PORT		2
-#define ARG_CACHE_SIZE		3
+#define ARG_MAX_THREADS		3
+#define ARG_CACHE_SIZE		4
 
 #define WMS_ILLEGAL_REQUEST	0
 #define WMS_GET_CAPABILITIES	1
@@ -62,18 +63,19 @@
 #define WMS_TRANSPARENT		10
 #define WMS_OPAQUE		11
 
-#define WMS_INVALID_CRS		101
+#define WMS_INVALID_CRS			101
 #define WMS_INVALID_DIMENSION	102
-#define WMS_INVALID_BBOX	103
-#define WMS_INVALID_LAYER	104
-#define WMS_INVALID_GROUP	105
-#define WMS_INVALID_BGCOLOR	106
-#define WMS_INVALID_STYLE	107
-#define WMS_INVALID_FORMAT	108
+#define WMS_INVALID_BBOX		103
+#define WMS_INVALID_LAYER		104
+#define WMS_INVALID_GROUP		105
+#define WMS_INVALID_BGCOLOR		106
+#define WMS_INVALID_STYLE		107
+#define WMS_INVALID_FORMAT		108
 #define WMS_INVALID_TRANSPARENT	109
 #define WMS_NOT_EXISTING_LAYER	110
 #define WMS_LAYER_OUT_OF_BBOX	111
 #define WMS_MISMATCHING_SRID	112
+#define WMS_ILLEGAL_LAYER		113
 
 #define WMS_VERSION_UNKNOWN	0
 #define WMS_VERSION_100		100
@@ -81,15 +83,18 @@
 #define WMS_VERSION_111		111
 #define WMS_VERSION_130		130
 
-#define CONNECTION_INVALID		0
+#define CONNECTION_INVALID	0
 #define CONNECTION_AVAILABLE	1
-#define CONNECTION_BUSY			2
+#define CONNECTION_BUSY		2
+
+#define LAYER_TYPE_RASTER	0xaa
+#define LAYER_TYPE_VECTOR	0xbb
 
 #define LOG_SLOT_AVAILABLE	-100
 #define LOG_SLOT_BUSY		-200
 #define LOG_SLOT_READY		-300
 
-#define SEND_BLOK_SZ	8192
+#define SEND_BLOK_SZ		8192
 #define MAX_CONN		8
 #define MAX_LOG			256
 
@@ -116,6 +121,7 @@ struct glob_var
     struct wms_list *list;
     struct connections_pool *pool;
     void *cache;
+    void *priv_data;
 } glob;
 
 struct neutral_socket
@@ -127,6 +133,25 @@ struct neutral_socket
 #endif
 };
 
+struct wms_keyword
+{
+/* a struct wrapping a WMS Keyword */
+    char *keyword;
+    struct wms_keyword *next;
+};
+
+struct wms_alt_srid
+{
+/* a struct wrapping a WMS alternative SRID */
+    int srid;
+    int has_flipped_axes;
+    double minx;
+    double miny;
+    double maxx;
+    double maxy;
+    struct wms_alt_srid *next;
+};
+
 struct wms_style
 {
 /* a struct wrapping a WMS style */
@@ -137,6 +162,26 @@ struct wms_style
     struct wms_style *next;
 };
 
+struct wms_raster_layer
+{
+/* raster-specific layer infos */
+    unsigned char layer_type;
+    unsigned char sample;
+    unsigned char pixel;
+    unsigned char num_bands;
+    int jpeg;
+    int png;
+};
+
+struct wms_vector_layer
+{
+/* vector-specific layer infos */
+    unsigned char layer_type;
+    char *f_table_name;
+    char *f_geometry_column;
+    unsigned char has_spatial_index;
+};
+
 struct wms_layer
 {
 /* a struct wrapping a WMS layer */
@@ -145,7 +190,7 @@ struct wms_layer
     char *title;
     char *abstract;
     int srid;
-    int is_geographic;
+    int has_flipped_axes;
     double minx;
     double miny;
     double maxx;
@@ -154,22 +199,25 @@ struct wms_layer
     double geo_miny;
     double geo_maxx;
     double geo_maxy;
-    unsigned char sample;
-    unsigned char pixel;
-    unsigned char num_bands;
-    int jpeg;
-    int png;
+    unsigned char is_queryable;
+    void *layer_specific;
     int child_layer;
     struct wms_style *first_style;
     struct wms_style *last_style;
+    struct wms_alt_srid *first_srid;
+    struct wms_alt_srid *last_srid;
+    struct wms_keyword *first_keyword;
+    struct wms_keyword *last_keyword;
     struct wms_layer *next;
 };
 
 struct read_connection
 {
     void *cache;
+    void *priv_data;
     sqlite3 *handle;
-    sqlite3_stmt *stmt_get_map;
+    sqlite3_stmt *stmt_get_map_raster;
+    sqlite3_stmt *stmt_get_map_vector;
     int status;
 };
 
@@ -193,7 +241,7 @@ struct wms_group
     char *title;
     char *abstract;
     int srid;
-    int is_geographic;
+    int has_flipped_axes;
     double minx;
     double miny;
     double maxx;
@@ -230,7 +278,8 @@ struct wms_args
 {
 /* a struct wrapping a WMS request URL */
     sqlite3 *db_handle;
-    sqlite3_stmt *stmt_get_map;
+    sqlite3_stmt *stmt_get_map_raster;
+    sqlite3_stmt *stmt_get_map_vector;
     char *service_name;
     struct wms_argument *first;
     struct wms_argument *last;
@@ -238,6 +287,7 @@ struct wms_args
     int wms_version;
     int error;
     const char *layer;
+    unsigned char layer_type;
     int srid;
     int swap_xy;
     double minx;
@@ -313,118 +363,349 @@ struct server_log
     time_t last_update;
 };
 
+static void
+destroy_wms_keyword (struct wms_keyword *keyword)
+{
+/* memory cleanup - destroying a Keyword */
+    if (keyword == NULL)
+	return;
+    if (keyword->keyword != NULL)
+	free (keyword->keyword);
+    free (keyword);
+}
+
+static struct wms_keyword *
+alloc_wms_keyword (const char *keyword)
+{
+/* creating a WMS Keyword */
+    int len;
+    struct wms_keyword *kw = malloc (sizeof (struct wms_keyword));
+    if (kw == NULL)
+	return NULL;
+    len = strlen (keyword);
+    kw->keyword = malloc (len + 1);
+    strcpy (kw->keyword, keyword);
+    kw->next = NULL;
+    return kw;
+}
+
+static void
+destroy_wms_alt_srid (struct wms_alt_srid *alt_srid)
+{
+/* memory cleanup - destroying an alternative Srid */
+    if (alt_srid == NULL)
+	return;
+    free (alt_srid);
+}
+
+static struct wms_alt_srid *
+alloc_wms_alt_srid (int srid, int has_flipped_axes, double minx, double miny,
+		    double maxx, double maxy)
+{
+/* creating a WMS alternative Srid */
+    struct wms_alt_srid *alt_srid = malloc (sizeof (struct wms_alt_srid));
+    if (alt_srid == NULL)
+	return NULL;
+    alt_srid->srid = srid;
+    alt_srid->has_flipped_axes = has_flipped_axes;
+    alt_srid->minx = minx;
+    alt_srid->miny = miny;
+    alt_srid->maxx = maxx;
+    alt_srid->maxy = maxy;
+    alt_srid->next = NULL;
+    return alt_srid;
+}
+
+static void
+destroy_wms_style (struct wms_style *style)
+{
+/* memory cleanup - destroying a Raster Style */
+    if (style == NULL)
+	return;
+    if (style->name != NULL)
+	free (style->name);
+    if (style->title != NULL)
+	free (style->title);
+    if (style->abstract != NULL)
+	free (style->abstract);
+    free (style);
+}
+
 static struct wms_style *
 alloc_wms_style (const char *name, const char *title, const char *abstract)
 {
 /* creating a WMS Raster Style */
     int len;
     struct wms_style *style = malloc (sizeof (struct wms_style));
+    if (style == NULL)
+	goto error;
+    style->name = NULL;
+    style->title = NULL;
+    style->abstract = NULL;
+
     style->valid = 1;
     len = strlen (name);
     style->name = malloc (len + 1);
+    if (style->name == NULL)
+	goto error;
     strcpy (style->name, name);
-    if (title == NULL)
-	style->title = NULL;
-    else
+    if (title != NULL)
       {
 	  len = strlen (title);
 	  style->title = malloc (len + 1);
+	  if (style->title == NULL)
+	      goto error;
 	  strcpy (style->title, title);
       }
-    if (abstract == NULL)
-	style->abstract = NULL;
-    else
+    if (abstract != NULL)
       {
 	  len = strlen (abstract);
 	  style->abstract = malloc (len + 1);
+	  if (style->abstract == NULL)
+	      goto error;
 	  strcpy (style->abstract, abstract);
       }
     style->next = NULL;
     return style;
+
+  error:
+    destroy_wms_style (style);
+    return NULL;
 }
 
 static void
-destroy_wms_style (struct wms_style *style)
+destroy_wms_layer (struct wms_layer *lyr)
 {
-/* memory cleanup - destroying a Raster Style */
-    if (style == NULL)
+/* memory cleanup - freeing a WMS layer item */
+    struct wms_style *style;
+    struct wms_style *style_n;
+    struct wms_alt_srid *alt_srid;
+    struct wms_alt_srid *alt_srid_n;
+    struct wms_keyword *keyword;
+    struct wms_keyword *keyword_n;
+    if (lyr == NULL)
 	return;
-    if (style->name != NULL)
-	free (style->name);
-    if (style->title != NULL)
-	free (style->title);
-    if (style->abstract != NULL)
-	free (style->abstract);
-    free (style);
+    if (lyr->layer_name != NULL)
+	free (lyr->layer_name);
+    if (lyr->title != NULL)
+	free (lyr->title);
+    if (lyr->abstract != NULL)
+	free (lyr->abstract);
+    if (lyr->layer_specific != NULL)
+      {
+	  struct wms_vector_layer *vector_specific =
+	      (struct wms_vector_layer *) (lyr->layer_specific);
+	  if (vector_specific->layer_type == LAYER_TYPE_VECTOR)
+	    {
+		if (vector_specific->f_table_name != NULL)
+		    free (vector_specific->f_table_name);
+		if (vector_specific->f_geometry_column != NULL)
+		    free (vector_specific->f_geometry_column);
+	    }
+	  free (lyr->layer_specific);
+      }
+    style = lyr->first_style;
+    while (style != NULL)
+      {
+	  style_n = style->next;
+	  destroy_wms_style (style);
+	  style = style_n;
+      }
+    alt_srid = lyr->first_srid;
+    while (alt_srid != NULL)
+      {
+	  alt_srid_n = alt_srid->next;
+	  destroy_wms_alt_srid (alt_srid);
+	  alt_srid = alt_srid_n;
+      }
+    keyword = lyr->first_keyword;
+    while (keyword != NULL)
+      {
+	  keyword_n = keyword->next;
+	  destroy_wms_keyword (keyword);
+	  keyword = keyword_n;
+      }
+    free (lyr);
 }
 
 static struct wms_layer *
-alloc_wms_layer (const char *layer, const char *title, const char *abstract,
-		 int srid, int is_geographic, double minx, double miny,
-		 double maxx, double maxy, unsigned char sample,
-		 unsigned char pixel, unsigned char num_bands)
+alloc_wms_raster_layer (const char *layer, const char *title,
+			const char *abstract, int srid, int has_flipped_axes,
+			double geo_minx, double geo_miny, double geo_maxx,
+			double geo_maxy, double minx, double miny, double maxx,
+			double maxy, unsigned char sample, unsigned char pixel,
+			unsigned char num_bands, unsigned char is_queryable)
 {
-/* creating a WMS layer item */
+/* creating a WMS layer item of the Raster type */
     int len;
+    struct wms_raster_layer *specific =
+	malloc (sizeof (struct wms_raster_layer));
     struct wms_layer *lyr = malloc (sizeof (struct wms_layer));
+    if (specific != NULL)
+	specific->layer_type = LAYER_TYPE_RASTER;
+    if (lyr != NULL)
+      {
+	  lyr->layer_name = NULL;
+	  lyr->title = NULL;
+	  lyr->abstract = NULL;
+	  lyr->layer_specific = specific;
+      }
+    if (specific == NULL)
+	goto error;
+    if (lyr == NULL)
+	goto error;
+
     lyr->valid = 1;
     len = strlen (layer);
     lyr->layer_name = malloc (len + 1);
+    if (lyr->layer_name == NULL)
+	goto error;
     strcpy (lyr->layer_name, layer);
-    len = strlen (title);
-    lyr->title = malloc (len + 1);
-    strcpy (lyr->title, title);
-    len = strlen (abstract);
-    lyr->abstract = malloc (len + 1);
-    strcpy (lyr->abstract, abstract);
+    if (title != NULL)
+      {
+	  len = strlen (title);
+	  lyr->title = malloc (len + 1);
+	  if (lyr->title == NULL)
+	      goto error;
+	  strcpy (lyr->title, title);
+      }
+    if (abstract != NULL)
+      {
+	  len = strlen (abstract);
+	  lyr->abstract = malloc (len + 1);
+	  if (lyr->abstract == NULL)
+	      goto error;
+	  strcpy (lyr->abstract, abstract);
+      }
     lyr->srid = srid;
-    lyr->is_geographic = is_geographic;
+    lyr->has_flipped_axes = has_flipped_axes;
+    lyr->geo_minx = geo_minx;
+    lyr->geo_miny = geo_miny;
+    lyr->geo_maxx = geo_maxx;
+    lyr->geo_maxy = geo_maxy;
     lyr->minx = minx;
     lyr->miny = miny;
     lyr->maxx = maxx;
     lyr->maxy = maxy;
-    lyr->sample = sample;
-    lyr->pixel = pixel;
-    lyr->num_bands = num_bands;
+    lyr->is_queryable = is_queryable;
+    specific->sample = sample;
+    specific->pixel = pixel;
+    specific->num_bands = num_bands;
     if (pixel == RL2_PIXEL_MONOCHROME || pixel == RL2_PIXEL_PALETTE)
       {
-	  lyr->png = 1;
-	  lyr->jpeg = 0;
+	  specific->png = 1;
+	  specific->jpeg = 0;
       }
     else
       {
-	  lyr->png = 1;
-	  lyr->jpeg = 1;
+	  specific->png = 1;
+	  specific->jpeg = 1;
       }
     lyr->child_layer = 0;
     lyr->first_style = NULL;
     lyr->last_style = NULL;
+    lyr->first_srid = NULL;
+    lyr->last_srid = NULL;
+    lyr->first_keyword = NULL;
+    lyr->last_keyword = NULL;
     lyr->next = NULL;
     return lyr;
+
+  error:
+    destroy_wms_layer (lyr);
+    return NULL;
 }
 
-static void
-destroy_wms_layer (struct wms_layer *lyr)
+static struct wms_layer *
+alloc_wms_vector_layer (const char *layer, const char *f_table_name,
+			const char *f_geometry_column, const char *title,
+			const char *abstract, int srid, int has_flipped_axes,
+			double geo_minx, double geo_miny, double geo_maxx,
+			double geo_maxy, double minx, double miny, double maxx,
+			double maxy, unsigned char has_spatial_index,
+			unsigned char is_queryable)
 {
-/* memory cleanup - freeing a WMS layer item */
-    struct wms_style *style;
-    struct wms_style *style_n;
+/* creating a WMS layer item of the Vector type */
+    int len;
+    struct wms_vector_layer *specific =
+	malloc (sizeof (struct wms_vector_layer));
+    struct wms_layer *lyr = malloc (sizeof (struct wms_layer));
+    if (specific != NULL)
+      {
+	  lyr->layer_specific = specific;
+	  specific->layer_type = LAYER_TYPE_VECTOR;
+	  specific->f_table_name = NULL;
+	  specific->f_geometry_column = NULL;
+      }
+    if (lyr != NULL)
+      {
+	  lyr->layer_name = NULL;
+	  lyr->title = NULL;
+	  lyr->abstract = NULL;
+	  lyr->layer_specific = specific;
+      }
+    if (specific == NULL)
+	goto error;
     if (lyr == NULL)
-	return;
-    if (lyr->layer_name != NULL)
-	free (lyr->layer_name);
-    if (lyr->title != NULL)
-	free (lyr->title);
-    if (lyr->abstract != NULL)
-	free (lyr->abstract);
-    style = lyr->first_style;
-    while (style != NULL)
+	goto error;
+
+    lyr->valid = 1;
+    len = strlen (layer);
+    lyr->layer_name = malloc (len + 1);
+    if (lyr->layer_name == NULL)
+	goto error;
+    strcpy (lyr->layer_name, layer);
+    if (title != NULL)
       {
-	  style_n = style->next;
-	  destroy_wms_style (style);
-	  style = style_n;
+	  len = strlen (title);
+	  lyr->title = malloc (len + 1);
+	  if (lyr->title == NULL)
+	      goto error;
+	  strcpy (lyr->title, title);
       }
-    free (lyr);
+    if (abstract != NULL)
+      {
+	  len = strlen (abstract);
+	  lyr->abstract = malloc (len + 1);
+	  if (lyr->abstract == NULL)
+	      goto error;
+	  strcpy (lyr->abstract, abstract);
+      }
+    lyr->srid = srid;
+    lyr->has_flipped_axes = has_flipped_axes;
+    lyr->geo_minx = geo_minx;
+    lyr->geo_miny = geo_miny;
+    lyr->geo_maxx = geo_maxx;
+    lyr->geo_maxy = geo_maxy;
+    lyr->minx = minx;
+    lyr->miny = miny;
+    lyr->maxx = maxx;
+    lyr->maxy = maxy;
+    lyr->is_queryable = is_queryable;
+    len = strlen (f_table_name);
+    specific->f_table_name = malloc (len + 1);
+    if (specific->f_table_name == NULL)
+	goto error;
+    strcpy (specific->f_table_name, f_table_name);
+    len = strlen (f_geometry_column);
+    specific->f_geometry_column = malloc (len + 1);
+    if (specific->f_geometry_column == NULL)
+	goto error;
+    strcpy (specific->f_geometry_column, f_geometry_column);
+    specific->has_spatial_index = has_spatial_index;
+    lyr->child_layer = 0;
+    lyr->first_style = NULL;
+    lyr->last_style = NULL;
+    lyr->first_srid = NULL;
+    lyr->last_srid = NULL;
+    lyr->first_keyword = NULL;
+    lyr->last_keyword = NULL;
+    lyr->next = NULL;
+    return lyr;
+
+  error:
+    destroy_wms_layer (lyr);
+    return NULL;
 }
 
 static struct wms_layer_ref *
@@ -547,7 +828,7 @@ add_style_to_wms_layer (struct wms_list *list, const char *coverage_name,
 			const char *name, const char *title,
 			const char *abstract)
 {
-/* appending a Raster Style to a WMS Layer */
+/* appending an SLD/SE Style to a WMS Layer */
     struct wms_layer *lyr;
     if (list == NULL)
 	return;
@@ -590,7 +871,7 @@ add_default_styles (struct wms_list *list)
 		count++;
 		style = style->next;
 	    }
-	  if (count && !has_default)
+	  if (!count || !has_default)
 	    {
 		/* appending a Default style */
 		struct wms_style *style =
@@ -668,6 +949,59 @@ add_default_group_styles (struct wms_list *list)
       }
 }
 
+static void
+add_alt_srid_to_wms_layer (struct wms_list *list, const char *coverage_name,
+			   int srid, int has_flipped_axes, double minx,
+			   double miny, double maxx, double maxy)
+{
+/* appending an alternative SRID to a WMS Layer */
+    struct wms_layer *lyr;
+    if (list == NULL)
+	return;
+    lyr = list->first_layer;
+    while (lyr != NULL)
+      {
+	  if (strcmp (lyr->layer_name, coverage_name) == 0)
+	    {
+		struct wms_alt_srid *alt_srid =
+		    alloc_wms_alt_srid (srid, has_flipped_axes, minx, miny,
+					maxx, maxy);
+		if (lyr->first_srid == NULL)
+		    lyr->first_srid = alt_srid;
+		if (lyr->last_srid != NULL)
+		    lyr->last_srid->next = alt_srid;
+		lyr->last_srid = alt_srid;
+		return;
+	    }
+	  lyr = lyr->next;
+      }
+}
+
+static void
+add_keyword_to_wms_layer (struct wms_list *list, const char *coverage_name,
+			  const char *keyword)
+{
+/* appending a Keyword to a WMS Layer */
+    struct wms_layer *lyr;
+    if (list == NULL)
+	return;
+    lyr = list->first_layer;
+    while (lyr != NULL)
+      {
+	  if (strcmp (lyr->layer_name, coverage_name) == 0)
+	    {
+		struct wms_keyword *kw = alloc_wms_keyword (keyword);
+		if (lyr->first_keyword == NULL)
+		    lyr->first_keyword = kw;
+		if (lyr->last_keyword != NULL)
+		    lyr->last_keyword->next = kw;
+		lyr->last_keyword = kw;
+		return;
+	    }
+	  lyr = lyr->next;
+      }
+}
+
 static struct wms_argument *
 alloc_wms_argument (char *name, char *value)
 {
@@ -699,12 +1033,16 @@ close_connection (struct read_connection *conn)
 /* closing a connection */
     if (conn == NULL)
 	return;
-    if (conn->stmt_get_map != NULL)
-	sqlite3_finalize (conn->stmt_get_map);
+    if (conn->stmt_get_map_raster != NULL)
+	sqlite3_finalize (conn->stmt_get_map_raster);
+    if (conn->stmt_get_map_vector != NULL)
+	sqlite3_finalize (conn->stmt_get_map_vector);
     if (conn->handle != NULL)
 	sqlite3_close (conn->handle);
     if (conn->cache != NULL)
 	spatialite_cleanup_ex (conn->cache);
+    if (conn->priv_data != NULL)
+	rl2_cleanup_private (conn->priv_data);
     conn->status = CONNECTION_INVALID;
 }
 
@@ -727,14 +1065,17 @@ destroy_connections_pool (struct connections_pool *pool)
 }
 
 static void
-connection_init (struct read_connection *conn, const char *path)
+connection_init (struct read_connection *conn, const char *path,
+		 int max_threads)
 {
 /* creating a read connection */
     int ret;
     sqlite3 *db_handle;
-    sqlite3_stmt *stmt;
+    sqlite3_stmt *stmt_raster = NULL;
+    sqlite3_stmt *stmt_vector = NULL;
     void *cache;
-    const char *sql;
+    void *priv_data;
+    char *sql;
 
     ret =
 	sqlite3_open_v2 (path, &db_handle,
@@ -749,25 +1090,49 @@ connection_init (struct read_connection *conn, const char *path)
       }
     cache = spatialite_alloc_connection ();
     spatialite_init_ex (db_handle, cache, 0);
-    rl2_init (db_handle, 0);
+    priv_data = rl2_alloc_private ();
+    rl2_init (db_handle, priv_data, 0);
+
+/* setting up MaxThreads */
+    if (max_threads < 1)
+	max_threads = 1;
+    if (max_threads > 64)
+	max_threads = 64;
+    sql = sqlite3_mprintf ("SELECT RL2_SetMaxThreads(%d)", max_threads);
+    sqlite3_exec (db_handle, sql, NULL, NULL, NULL);
+    sqlite3_free (sql);
 
-/* creating the GetMap SQL statement */
+/* creating the GetMap SQL statement (Raster) */
     sql =
-	"SELECT RL2_GetMapImage(?, BuildMbr(?, ?, ?, ?), ?, ?, ?, ?, ?, ?, ?)";
-    ret = sqlite3_prepare_v2 (db_handle, sql, strlen (sql), &stmt, NULL);
+	"SELECT RL2_GetMapImageFromRaster(?, BuildMbr(?, ?, ?, ?), ?, ?, ?, ?, ?, ?, ?)";
+    ret = sqlite3_prepare_v2 (db_handle, sql, strlen (sql), &stmt_raster, NULL);
     if (ret != SQLITE_OK)
-      {
-	  sqlite3_close (db_handle);
-	  spatialite_cleanup_ex (cache);
-      }
+	goto error;
+/* creating the GetMap SQL statement (Vector) */
+    sql =
+	"SELECT RL2_GetMapImageFromVector(?, BuildMbr(?, ?, ?, ?), ?, ?, ?, ?, ?, ?, ?)";
+    ret = sqlite3_prepare_v2 (db_handle, sql, strlen (sql), &stmt_vector, NULL);
+    if (ret != SQLITE_OK)
+	goto error;
     conn->handle = db_handle;
-    conn->stmt_get_map = stmt;
+    conn->stmt_get_map_raster = stmt_raster;
+    conn->stmt_get_map_vector = stmt_vector;
     conn->cache = cache;
+    conn->priv_data = priv_data;
     conn->status = CONNECTION_AVAILABLE;
+    return;
+
+  error:
+    if (stmt_raster != NULL)
+	sqlite3_finalize (stmt_raster);
+    if (stmt_vector != NULL)
+	sqlite3_finalize (stmt_vector);
+    sqlite3_close (db_handle);
+    spatialite_cleanup_ex (cache);
 }
 
 static struct connections_pool *
-alloc_connections_pool (const char *path)
+alloc_connections_pool (const char *path, int max_threads)
 {
 /* creating and initializing the connections pool */
     int i;
@@ -782,7 +1147,8 @@ alloc_connections_pool (const char *path)
 	  /* initializing empty connections */
 	  conn = &(pool->connections[i]);
 	  conn->handle = NULL;
-	  conn->stmt_get_map = NULL;
+	  conn->stmt_get_map_raster = NULL;
+	  conn->stmt_get_map_vector = NULL;
 	  conn->cache = NULL;
 	  conn->status = CONNECTION_INVALID;
       }
@@ -790,7 +1156,7 @@ alloc_connections_pool (const char *path)
       {
 	  /* creating the connections */
 	  conn = &(pool->connections[i]);
-	  connection_init (conn, path);
+	  connection_init (conn, path, max_threads);
       }
     count = 0;
     for (i = 0; i < MAX_CONN; i++)
@@ -1193,6 +1559,8 @@ clean_shutdown ()
 	sqlite3_close (glob.handle);
     if (glob.cache != NULL)
 	spatialite_cleanup_ex (glob.cache);
+    if (glob.priv_data != NULL)
+	rl2_cleanup_private (glob.priv_data);
     spatialite_shutdown ();
     fprintf (stderr, "wmslite shutdown completed ... bye bye\n\n");
 }
@@ -1227,7 +1595,8 @@ alloc_wms_args (const char *service_name)
 	return NULL;
     args = malloc (sizeof (struct wms_args));
     args->db_handle = NULL;
-    args->stmt_get_map = NULL;
+    args->stmt_get_map_raster = NULL;
+    args->stmt_get_map_vector = NULL;
     len = strlen (service_name);
     args->service_name = malloc (len + 1);
     strcpy (args->service_name, service_name);
@@ -1572,7 +1941,8 @@ parse_bgcolor (const char *bgcolor, unsigned char *red, unsigned char *green,
 static int
 exists_layer (struct wms_list *list, const char *layer, int srid,
 	      int wms_version, int *swap_xy, double minx, double miny,
-	      double maxx, double maxy, const char **layer_name)
+	      double maxx, double maxy, const char **layer_name,
+	      unsigned char *layer_type)
 {
 /* checking a required layer for validity */
     struct wms_group *grp;
@@ -1582,9 +1952,10 @@ exists_layer (struct wms_list *list, const char *layer, int srid,
 	  /* searching a genuine Layer */
 	  if (strcmp (lyr->layer_name, layer) == 0)
 	    {
+		struct wms_vector_layer *specific = lyr->layer_specific;
 		if (lyr->srid != srid)
 		    return WMS_MISMATCHING_SRID;
-		if (wms_version == WMS_VERSION_130 && lyr->is_geographic)
+		if (wms_version == WMS_VERSION_130 && lyr->has_flipped_axes)
 		    *swap_xy = 1;
 		else
 		    *swap_xy = 0;
@@ -1611,6 +1982,12 @@ exists_layer (struct wms_list *list, const char *layer, int srid,
 			  return WMS_LAYER_OUT_OF_BBOX;
 		  }
 		*layer_name = lyr->layer_name;
+		if (specific->layer_type == LAYER_TYPE_VECTOR)
+		    *layer_type = LAYER_TYPE_VECTOR;
+		else if (specific->layer_type == LAYER_TYPE_RASTER)
+		    *layer_type = LAYER_TYPE_RASTER;
+		else
+		    return WMS_ILLEGAL_LAYER;
 		return 0;
 	    }
 	  lyr = lyr->next;
@@ -1625,7 +2002,7 @@ exists_layer (struct wms_list *list, const char *layer, int srid,
 		    return WMS_INVALID_GROUP;
 		if (grp->srid != srid)
 		    return WMS_MISMATCHING_SRID;
-		if (wms_version == WMS_VERSION_130 && grp->is_geographic)
+		if (wms_version == WMS_VERSION_130 && grp->has_flipped_axes)
 		    *swap_xy = 1;
 		else
 		    *swap_xy = 0;
@@ -1763,6 +2140,7 @@ check_wms_request (struct wms_list *list, struct wms_args *args)
 		int srid;
 		const char *layer;
 		const char *layer_name;
+		unsigned char layer_type;
 		int swap_xy = 0;
 		double minx;
 		double miny;
@@ -1837,10 +2215,11 @@ check_wms_request (struct wms_list *list, struct wms_args *args)
 		  }
 		ret =
 		    exists_layer (list, layer, srid, wms_version, &swap_xy,
-				  minx, miny, maxx, maxy, &layer_name);
+				  minx, miny, maxx, maxy, &layer_name,
+				  &layer_type);
 		if (ret == WMS_NOT_EXISTING_LAYER || ret == WMS_INVALID_GROUP
 		    || ret == WMS_LAYER_OUT_OF_BBOX
-		    || ret == WMS_MISMATCHING_SRID)
+		    || ret == WMS_MISMATCHING_SRID || ret == WMS_ILLEGAL_LAYER)
 		  {
 		      args->error = ret;
 		      return 200;
@@ -1848,6 +2227,7 @@ check_wms_request (struct wms_list *list, struct wms_args *args)
 		args->request_type = WMS_GET_MAP;
 		args->wms_version = wms_version;
 		args->layer = layer_name;
+		args->layer_type = layer_type;
 		args->srid = srid;
 		args->swap_xy = swap_xy;
 		if (wms_version == WMS_VERSION_130 && swap_xy)
@@ -1989,8 +2369,8 @@ get_current_timestamp ()
     char *dummy;
     struct tm *xtm;
     time_t now;
-    const char *day;
-    const char *month;
+    const char *day = NULL;
+    const char *month = NULL;
     time (&now);
     xtm = gmtime (&now);
     switch (xtm->tm_wday)
@@ -2239,12 +2619,15 @@ build_http_error (int http_status, gaiaOutBufferPtr xml_response, int port_no)
 }
 
 static void
-build_get_capabilities (struct wms_list *list, char **cached, int *cached_len)
+build_get_capabilities (struct wms_list *list, char **cached, int *cached_len,
+			int port_no)
 {
 /* preparing the WMS GetCapabilities XML document */
     struct wms_layer *lyr;
     struct wms_group *grp;
     struct wms_style *style;
+    struct wms_alt_srid *alt_srid;
+    struct wms_keyword *keyword;
     char *dummy;
     gaiaOutBuffer xml_text;
     gaiaOutBufferInitialize (&xml_text);
@@ -2264,8 +2647,12 @@ build_get_capabilities (struct wms_list *list, char **cached, int *cached_len)
 			   "<Abstract>A simple light-weight WMS server for testing RasterLite2 Coverages.</Abstract>\r\n");
     gaiaAppendToOutBuffer (&xml_text,
 			   "<KeywordList>\r\n<Keyword>maps</Keyword>\r\n</KeywordList>\r\n");
-    gaiaAppendToOutBuffer (&xml_text,
-			   "<OnlineResource xlink:href=\"http://127.0.0.1:8080/wmslite?\" ");
+    dummy =
+	sqlite3_mprintf
+	("<OnlineResource xlink:href=\"http://127.0.0.1:%d/wmslite?\" ",
+	 port_no);
+    gaiaAppendToOutBuffer (&xml_text, dummy);
+    sqlite3_free (dummy);
     gaiaAppendToOutBuffer (&xml_text,
 			   "xlink:type=\"simple\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/>\r\n");
     gaiaAppendToOutBuffer (&xml_text,
@@ -2299,8 +2686,12 @@ build_get_capabilities (struct wms_list *list, char **cached, int *cached_len)
 			   "<Capability>\r\n<Request>\r\n<GetCapabilities>\r\n");
     gaiaAppendToOutBuffer (&xml_text,
 			   "<Format>text/xml</Format>\r\n<DCPType>\r\n<HTTP>\r\n");
-    gaiaAppendToOutBuffer (&xml_text,
-			   "<Get><OnlineResource xlink:href=\"http://127.0.0.1:8080/wmslite?\" ");
+    dummy =
+	sqlite3_mprintf
+	("<Get><OnlineResource xlink:href=\"http://127.0.0.1:%d/wmslite?\" ",
+	 port_no);
+    gaiaAppendToOutBuffer (&xml_text, dummy);
+    sqlite3_free (dummy);
     gaiaAppendToOutBuffer (&xml_text,
 			   "xlink:type=\"simple\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Get>\r\n");
     gaiaAppendToOutBuffer (&xml_text,
@@ -2311,8 +2702,12 @@ build_get_capabilities (struct wms_list *list, char **cached, int *cached_len)
     gaiaAppendToOutBuffer (&xml_text, "<Format>application/x-pdf</Format>\r\n");
     gaiaAppendToOutBuffer (&xml_text, "<Format>image/tiff</Format>\r\n");
     gaiaAppendToOutBuffer (&xml_text, "<DCPType>\r\n<HTTP>\r\n<Get>");
-    gaiaAppendToOutBuffer (&xml_text,
-			   "<OnlineResource xlink:href=\"http://127.0.0.1:8080/wmslite?\" ");
+    dummy =
+	sqlite3_mprintf
+	("<OnlineResource xlink:href=\"http://127.0.0.1:%d/wmslite?\" ",
+	 port_no);
+    gaiaAppendToOutBuffer (&xml_text, dummy);
+    sqlite3_free (dummy);
     gaiaAppendToOutBuffer (&xml_text,
 			   "xlink:type=\"simple\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Get>\r\n");
     gaiaAppendToOutBuffer (&xml_text,
@@ -2341,8 +2736,12 @@ build_get_capabilities (struct wms_list *list, char **cached, int *cached_len)
 		lyr = lyr->next;
 		continue;
 	    }
-	  gaiaAppendToOutBuffer (&xml_text,
-				 "<Layer queryable=\"0\" opaque=\"0\" cascaded=\"0\">\r\n");
+	  dummy =
+	      sqlite3_mprintf
+	      ("<Layer queryable=\"%d\" opaque=\"0\" cascaded=\"0\">\r\n",
+	       lyr->is_queryable);
+	  gaiaAppendToOutBuffer (&xml_text, dummy);
+	  sqlite3_free (dummy);
 	  dummy = sqlite3_mprintf ("<Name>%s</Name>\r\n", lyr->layer_name);
 	  gaiaAppendToOutBuffer (&xml_text, dummy);
 	  sqlite3_free (dummy);
@@ -2353,12 +2752,36 @@ build_get_capabilities (struct wms_list *list, char **cached, int *cached_len)
 	      sqlite3_mprintf ("<Abstract>%s</Abstract>\r\n", lyr->abstract);
 	  gaiaAppendToOutBuffer (&xml_text, dummy);
 	  sqlite3_free (dummy);
-	  dummy = sqlite3_mprintf ("<CRS>EPSG:%d</CRS>\r\n", lyr->srid);
-	  gaiaAppendToOutBuffer (&xml_text, dummy);
-	  sqlite3_free (dummy);
-	  gaiaAppendToOutBuffer (&xml_text, "<EX_GeographicBoundingBox>");
-	  dummy =
-	      sqlite3_mprintf ("<westBoundLongitude>%1.6f</westBoundLongitude>",
+	  if (lyr->first_keyword != NULL)
+	    {
+		gaiaAppendToOutBuffer (&xml_text, "<KeywordList>\r\n");
+		keyword = lyr->first_keyword;
+		while (keyword != NULL)
+		  {
+		      dummy =
+			  sqlite3_mprintf ("<Keyword>%s</Keyword>\r\n",
+					   keyword->keyword);
+		      gaiaAppendToOutBuffer (&xml_text, dummy);
+		      sqlite3_free (dummy);
+		      keyword = keyword->next;
+		  }
+		gaiaAppendToOutBuffer (&xml_text, "</KeywordList>\r\n");
+	    }
+	  dummy = sqlite3_mprintf ("<CRS>EPSG:%d</CRS>\r\n", lyr->srid);
+	  gaiaAppendToOutBuffer (&xml_text, dummy);
+	  sqlite3_free (dummy);
+	  alt_srid = lyr->first_srid;
+	  while (alt_srid != NULL)
+	    {
+		dummy =
+		    sqlite3_mprintf ("<CRS>EPSG:%d</CRS>\r\n", alt_srid->srid);
+		gaiaAppendToOutBuffer (&xml_text, dummy);
+		sqlite3_free (dummy);
+		alt_srid = alt_srid->next;
+	    }
+	  gaiaAppendToOutBuffer (&xml_text, "<EX_GeographicBoundingBox>");
+	  dummy =
+	      sqlite3_mprintf ("<westBoundLongitude>%1.6f</westBoundLongitude>",
 			       lyr->geo_minx);
 	  gaiaAppendToOutBuffer (&xml_text, dummy);
 	  sqlite3_free (dummy);
@@ -2378,7 +2801,7 @@ build_get_capabilities (struct wms_list *list, char **cached, int *cached_len)
 	  gaiaAppendToOutBuffer (&xml_text, dummy);
 	  sqlite3_free (dummy);
 	  gaiaAppendToOutBuffer (&xml_text, "</EX_GeographicBoundingBox>\r\n");
-	  if (lyr->is_geographic)
+	  if (lyr->has_flipped_axes)
 	      dummy = sqlite3_mprintf ("<BoundingBox CRS=\"EPSG:%d\" "
 				       "minx=\"%1.6f\" miny=\"%1.6f\" maxx=\"%1.6f\" maxy=\"%1.6f\"/>\r\n",
 				       lyr->srid, lyr->miny, lyr->minx,
@@ -2390,6 +2813,25 @@ build_get_capabilities (struct wms_list *list, char **cached, int *cached_len)
 				       lyr->maxx, lyr->maxy);
 	  gaiaAppendToOutBuffer (&xml_text, dummy);
 	  sqlite3_free (dummy);
+	  alt_srid = lyr->first_srid;
+	  while (alt_srid != NULL)
+	    {
+		if (alt_srid->has_flipped_axes)
+		    dummy = sqlite3_mprintf ("<BoundingBox CRS=\"EPSG:%d\" "
+					     "minx=\"%1.6f\" miny=\"%1.6f\" maxx=\"%1.6f\" maxy=\"%1.6f\"/>\r\n",
+					     alt_srid->srid, alt_srid->miny,
+					     alt_srid->minx, alt_srid->maxy,
+					     alt_srid->maxx);
+		else
+		    dummy = sqlite3_mprintf ("<BoundingBox CRS=\"EPSG:%d\" "
+					     "minx=\"%1.6f\" miny=\"%1.6f\" maxx=\"%1.6f\" maxy=\"%1.6f\"/>\r\n",
+					     alt_srid->srid, alt_srid->minx,
+					     alt_srid->miny, alt_srid->maxx,
+					     alt_srid->maxy);
+		gaiaAppendToOutBuffer (&xml_text, dummy);
+		sqlite3_free (dummy);
+		alt_srid = alt_srid->next;
+	    }
 	  style = lyr->first_style;
 	  while (style != NULL)
 	    {
@@ -2473,7 +2915,7 @@ build_get_capabilities (struct wms_list *list, char **cached, int *cached_len)
 	  gaiaAppendToOutBuffer (&xml_text, dummy);
 	  sqlite3_free (dummy);
 	  gaiaAppendToOutBuffer (&xml_text, "</EX_GeographicBoundingBox>\r\n");
-	  if (grp->is_geographic)
+	  if (grp->has_flipped_axes)
 	      dummy = sqlite3_mprintf ("<BoundingBox CRS=\"EPSG:%d\" "
 				       "minx=\"%1.6f\" miny=\"%1.6f\" maxx=\"%1.6f\" maxy=\"%1.6f\"/>\r\n",
 				       grp->srid, grp->miny, grp->minx,
@@ -2527,8 +2969,12 @@ build_get_capabilities (struct wms_list *list, char **cached, int *cached_len)
 		      continue;
 		  }
 		lyr = ref->layer_ref;
-		gaiaAppendToOutBuffer (&xml_text,
-				       "<Layer queryable=\"0\" opaque=\"0\" cascaded=\"0\">\r\n");
+		dummy =
+		    sqlite3_mprintf
+		    ("<Layer queryable=\"%d\" opaque=\"0\" cascaded=\"0\">\r\n",
+		     lyr->is_queryable);
+		gaiaAppendToOutBuffer (&xml_text, dummy);
+		sqlite3_free (dummy);
 		dummy =
 		    sqlite3_mprintf ("<Name>%s</Name>\r\n", lyr->layer_name);
 		gaiaAppendToOutBuffer (&xml_text, dummy);
@@ -2571,7 +3017,7 @@ build_get_capabilities (struct wms_list *list, char **cached, int *cached_len)
 		sqlite3_free (dummy);
 		gaiaAppendToOutBuffer (&xml_text,
 				       "</EX_GeographicBoundingBox>\r\n");
-		if (lyr->is_geographic)
+		if (lyr->has_flipped_axes)
 		    dummy = sqlite3_mprintf ("<BoundingBox CRS=\"EPSG:%d\" "
 					     "minx=\"%1.6f\" miny=\"%1.6f\" maxx=\"%1.6f\" maxy=\"%1.6f\"/>\r\n",
 					     lyr->srid, lyr->miny, lyr->minx,
@@ -2718,7 +3164,10 @@ wms_get_map (struct wms_args *args, int socket, struct server_log_item *log)
     int black_sz;
     char bgcolor[16];
 
-    stmt = args->stmt_get_map;
+    if (args->layer_type == LAYER_TYPE_VECTOR)
+	stmt = args->stmt_get_map_vector;
+    else
+	stmt = args->stmt_get_map_raster;
     sqlite3_reset (stmt);
     sqlite3_clear_bindings (stmt);
     sqlite3_bind_text (stmt, 1, args->layer, strlen (args->layer),
@@ -2954,7 +3403,8 @@ win32_http_request (void *data)
       {
 	  /* preparing the WMS GetMap payload */
 	  args->db_handle = req->conn->handle;
-	  args->stmt_get_map = req->conn->stmt_get_map;
+	  args->stmt_get_map_raster = req->conn->stmt_get_map_raster;
+	  args->stmt_get_map_vector = req->conn->stmt_get_map_vector;
 	  log_get_map_1 (req->log, timestamp, http_status, method, url, args);
 	  wms_get_map (args, req->socket, req->log);
       }
@@ -3065,7 +3515,8 @@ berkeley_http_request (void *data)
       {
 	  /* preparing the WMS GetMap payload */
 	  args->db_handle = req->conn->handle;
-	  args->stmt_get_map = req->conn->stmt_get_map;
+	  args->stmt_get_map_raster = req->conn->stmt_get_map_raster;
+	  args->stmt_get_map_vector = req->conn->stmt_get_map_vector;
 	  log_get_map_1 (req->log, timestamp, http_status, method, url, args);
 	  wms_get_map (args, req->socket, req->log);
       }
@@ -3315,7 +3766,7 @@ do_accept_loop (struct neutral_socket *skt, struct wms_list *list, int port_no,
 }
 
 static int
-do_start_http (int port_no, struct neutral_socket *srv_skt)
+do_start_http (int port_no, struct neutral_socket *srv_skt, int max_threads)
 {
 /* starting the HTTP server */
 #ifdef _WIN32
@@ -3384,57 +3835,17 @@ do_start_http (int port_no, struct neutral_socket *srv_skt)
     fprintf (stderr, "    HTTP micro-server listening on port: %d\n", port_no);
     fprintf (stderr,
 	     "======================================================\n");
+    fprintf (stderr, "                 RasterLite2 MaxThreads: %d\n",
+	     max_threads);
+    fprintf (stderr,
+	     "======================================================\n");
     return 1;
 }
 
-static int
-get_geographic_extent (sqlite3 * handle, struct wms_layer *lyr)
-{
-/* computing the Geographic Bounding Box for some WMS layer */
-    int retcode = 0;
-    const char *sql;
-    sqlite3_stmt *stmt = NULL;
-    int ret;
-    sql = "SELECT MbrMinX(g.g), MbrMinY(g.g), MbrMaxX(g.g), MbrMaxY(g.g) "
-	"FROM (SELECT ST_Transform(BuildMbr(?, ?, ?, ?, ?), 4326) AS g) AS g";
-    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
-    if (ret != SQLITE_OK)
-      {
-	  lyr->geo_minx = -180.0;
-	  lyr->geo_miny = -90.0;
-	  lyr->geo_maxx = 180.0;
-	  lyr->geo_maxy = 90.0;
-	  return 0;
-      }
-    sqlite3_reset (stmt);
-    sqlite3_clear_bindings (stmt);
-    sqlite3_bind_double (stmt, 1, lyr->minx);
-    sqlite3_bind_double (stmt, 2, lyr->miny);
-    sqlite3_bind_double (stmt, 3, lyr->maxx);
-    sqlite3_bind_double (stmt, 4, lyr->maxy);
-    sqlite3_bind_int (stmt, 5, lyr->srid);
-    while (1)
-      {
-	  ret = sqlite3_step (stmt);
-	  if (ret == SQLITE_DONE)
-	      break;
-	  if (ret == SQLITE_ROW)
-	    {
-		lyr->geo_minx = sqlite3_column_double (stmt, 0);
-		lyr->geo_miny = sqlite3_column_double (stmt, 1);
-		lyr->geo_maxx = sqlite3_column_double (stmt, 2);
-		lyr->geo_maxy = sqlite3_column_double (stmt, 3);
-		retcode = 1;
-	    }
-      }
-    sqlite3_finalize (stmt);
-    return retcode;
-}
-
 static void
-compute_geographic_extents (sqlite3 * handle, struct wms_list *list)
+complete_layer_config (sqlite3 * handle, struct wms_list *list)
 {
-/* computing the Geographic Bounding Box for every WMS layer */
+/* completing the configuration for every WMS layer */
     struct wms_group *grp;
     struct wms_layer *lyr;
 
@@ -3442,10 +3853,7 @@ compute_geographic_extents (sqlite3 * handle, struct wms_list *list)
     lyr = list->first_layer;
     while (lyr != NULL)
       {
-	  if (get_geographic_extent (handle, lyr))
-	      fprintf (stderr, "Publishing layer \"%s\"\n", lyr->layer_name);
-	  else
-	      lyr->valid = 0;
+	  fprintf (stderr, "Publishing layer \"%s\"\n", lyr->layer_name);
 	  lyr = lyr->next;
       }
 
@@ -3499,7 +3907,7 @@ compute_geographic_extents (sqlite3 * handle, struct wms_list *list)
 		      if (ref == grp->first_child)
 			{
 			    grp->srid = l->srid;
-			    grp->is_geographic = l->is_geographic;
+			    grp->has_flipped_axes = l->has_flipped_axes;
 			    if (l->minx < minx)
 				minx = l->minx;
 			    if (l->maxx > maxx)
@@ -3600,38 +4008,38 @@ compute_geographic_extents (sqlite3 * handle, struct wms_list *list)
 }
 
 static int
-check_geographic_srid (sqlite3 * handle, int srid)
+unsupported_codec (const char *compression)
 {
-/* testing if some SRID is of the Geographic type */
-    int ret;
-    char *sql;
-    char **results;
-    int rows;
-    int columns;
-    int i;
-    int geo = -1;
-
-    sql = sqlite3_mprintf ("SELECT Count(*) FROM spatial_ref_sys "
-			   "WHERE srid = %d AND proj4text LIKE '%%+proj=longlat%%'",
-			   srid);
-    ret = sqlite3_get_table (handle, sql, &results, &rows, &columns, NULL);
-    sqlite3_free (sql);
-    if (ret != SQLITE_OK)
-	goto skip;
-
-    for (i = 1; i <= rows; i++)
-	geo = atoi (results[(i * columns) + 0]);
-    sqlite3_free_table (results);
-  skip:
-    if (geo > 0)
+/* testing for unsupported optional codecs */
+    if (strcasecmp (compression, "LZMA") == 0
+	&& rl2_is_supported_codec (RL2_COMPRESSION_LZMA) != 1)
+	return 1;
+    if (strcasecmp (compression, "LZMA_NO") == 0
+	&& rl2_is_supported_codec (RL2_COMPRESSION_LZMA_NO) != 1)
+	return 1;
+    if (strcasecmp (compression, "CHARLS") == 0
+	&& rl2_is_supported_codec (RL2_COMPRESSION_CHARLS) != 1)
+	return 1;
+    if (strcasecmp (compression, "WEBP") == 0
+	&& rl2_is_supported_codec (RL2_COMPRESSION_LOSSY_WEBP) != 1)
+	return 1;
+    if (strcasecmp (compression, "LL_WEBP") == 0
+	&& rl2_is_supported_codec (RL2_COMPRESSION_LOSSLESS_WEBP) != 1)
+	return 1;
+    if (strcasecmp (compression, "JP2") == 0
+	&& rl2_is_supported_codec (RL2_COMPRESSION_LOSSY_JP2) != 1)
+	return 1;
+    if (strcasecmp (compression, "LL_JP2") == 0
+	&& rl2_is_supported_codec (RL2_COMPRESSION_LOSSLESS_JP2) != 1)
 	return 1;
     return 0;
 }
 
 static struct wms_layer *
-load_layer (sqlite3 * handle, sqlite3_stmt * stmt)
+load_raster_layer (sqlite3 * handle, sqlite3_stmt * stmt)
 {
-/* creating a WMS layer from the resultset */
+/* creating a WMS layer (Raster) from the resultset */
+    unsigned char is_queryable = 0;
     struct wms_layer *lyr = NULL;
     const char *coverage_name = (const char *) sqlite3_column_text (stmt, 0);
     const char *title = (const char *) sqlite3_column_text (stmt, 1);
@@ -3640,143 +4048,236 @@ load_layer (sqlite3 * handle, sqlite3_stmt * stmt)
     const char *pixel_type = (const char *) sqlite3_column_text (stmt, 4);
     int num_bands = sqlite3_column_int (stmt, 5);
     int srid = sqlite3_column_int (stmt, 6);
-    double minx = sqlite3_column_double (stmt, 7);
-    double miny = sqlite3_column_double (stmt, 8);
-    double maxx = sqlite3_column_double (stmt, 9);
-    double maxy = sqlite3_column_double (stmt, 10);
-    int is_geographic = check_geographic_srid (handle, srid);
+    double geo_minx = sqlite3_column_double (stmt, 7);
+    double geo_miny = sqlite3_column_double (stmt, 8);
+    double geo_maxx = sqlite3_column_double (stmt, 9);
+    double geo_maxy = sqlite3_column_double (stmt, 10);
+    double minx = sqlite3_column_double (stmt, 11);
+    double miny = sqlite3_column_double (stmt, 12);
+    double maxx = sqlite3_column_double (stmt, 13);
+    double maxy = sqlite3_column_double (stmt, 14);
+    const char *compression = (const char *) sqlite3_column_text (stmt, 15);
+    int has_flipped_axes = 0;
+    if (sqlite3_column_type (stmt, 16) == SQLITE_INTEGER)
+      {
+	  if (sqlite3_column_int (stmt, 16) != 0)
+	      is_queryable = 1;
+      }
+    if (unsupported_codec (compression))
+	return NULL;
+    if (!srid_has_flipped_axes (handle, srid, &has_flipped_axes))
+	has_flipped_axes = 0;
     if (strcmp (sample_type, "1-BIT") == 0
 	&& strcmp (pixel_type, "MONOCHROME") == 0 && num_bands == 1)
 	lyr =
-	    alloc_wms_layer (coverage_name, title, abstract, srid,
-			     is_geographic, minx, miny, maxx, maxy,
-			     RL2_SAMPLE_1_BIT, RL2_PIXEL_MONOCHROME, 1);
+	    alloc_wms_raster_layer (coverage_name, title, abstract, srid,
+				    has_flipped_axes, geo_minx, geo_miny,
+				    geo_maxx, geo_maxy, minx, miny, maxx, maxy,
+				    RL2_SAMPLE_1_BIT, RL2_PIXEL_MONOCHROME, 1,
+				    is_queryable);
     if (strcmp (sample_type, "1-BIT") == 0
 	&& strcmp (pixel_type, "PALETTE") == 0 && num_bands == 1)
 	lyr =
-	    alloc_wms_layer (coverage_name, title, abstract, srid,
-			     is_geographic, minx, miny, maxx, maxy,
-			     RL2_SAMPLE_1_BIT, RL2_PIXEL_PALETTE, 1);
+	    alloc_wms_raster_layer (coverage_name, title, abstract, srid,
+				    has_flipped_axes, geo_minx, geo_miny,
+				    geo_maxx, geo_maxy, minx, miny, maxx, maxy,
+				    RL2_SAMPLE_1_BIT, RL2_PIXEL_PALETTE, 1,
+				    is_queryable);
     if (strcmp (sample_type, "2-BIT") == 0
 	&& strcmp (pixel_type, "PALETTE") == 0 && num_bands == 1)
 	lyr =
-	    alloc_wms_layer (coverage_name, title, abstract, srid,
-			     is_geographic, minx, miny, maxx, maxy,
-			     RL2_SAMPLE_2_BIT, RL2_PIXEL_PALETTE, 1);
+	    alloc_wms_raster_layer (coverage_name, title, abstract, srid,
+				    has_flipped_axes, geo_minx, geo_miny,
+				    geo_maxx, geo_maxy, minx, miny, maxx, maxy,
+				    RL2_SAMPLE_2_BIT, RL2_PIXEL_PALETTE, 1,
+				    is_queryable);
     if (strcmp (sample_type, "4-BIT") == 0
 	&& strcmp (pixel_type, "PALETTE") == 0 && num_bands == 1)
 	lyr =
-	    alloc_wms_layer (coverage_name, title, abstract, srid,
-			     is_geographic, minx, miny, maxx, maxy,
-			     RL2_SAMPLE_4_BIT, RL2_PIXEL_PALETTE, 1);
+	    alloc_wms_raster_layer (coverage_name, title, abstract, srid,
+				    has_flipped_axes, geo_minx, geo_miny,
+				    geo_maxx, geo_maxy, minx, miny, maxx, maxy,
+				    RL2_SAMPLE_4_BIT, RL2_PIXEL_PALETTE, 1,
+				    is_queryable);
     if (strcmp (sample_type, "UINT8") == 0
 	&& strcmp (pixel_type, "PALETTE") == 0 && num_bands == 1)
 	lyr =
-	    alloc_wms_layer (coverage_name, title, abstract, srid,
-			     is_geographic, minx, miny, maxx, maxy,
-			     RL2_SAMPLE_UINT8, RL2_PIXEL_PALETTE, 1);
+	    alloc_wms_raster_layer (coverage_name, title, abstract, srid,
+				    has_flipped_axes, geo_minx, geo_miny,
+				    geo_maxx, geo_maxy, minx, miny, maxx, maxy,
+				    RL2_SAMPLE_UINT8, RL2_PIXEL_PALETTE, 1,
+				    is_queryable);
     if (strcmp (sample_type, "UINT8") == 0
 	&& strcmp (pixel_type, "GRAYSCALE") == 0 && num_bands == 1)
 	lyr =
-	    alloc_wms_layer (coverage_name, title, abstract, srid,
-			     is_geographic, minx, miny, maxx, maxy,
-			     RL2_SAMPLE_UINT8, RL2_PIXEL_GRAYSCALE, 1);
-    if (strcmp (sample_type, "UINT8") == 0
-	&& strcmp (pixel_type, "RGB") == 0 && num_bands == 3)
+	    alloc_wms_raster_layer (coverage_name, title, abstract, srid,
+				    has_flipped_axes, geo_minx, geo_miny,
+				    geo_maxx, geo_maxy, minx, miny, maxx, maxy,
+				    RL2_SAMPLE_UINT8, RL2_PIXEL_GRAYSCALE, 1,
+				    is_queryable);
+    if (strcmp (sample_type, "UINT8") == 0 && strcmp (pixel_type, "RGB") == 0
+	&& num_bands == 3)
 	lyr =
-	    alloc_wms_layer (coverage_name, title, abstract, srid,
-			     is_geographic, minx, miny, maxx, maxy,
-			     RL2_SAMPLE_UINT8, RL2_PIXEL_RGB, 3);
-    if (strcmp (sample_type, "UINT16") == 0
-	&& strcmp (pixel_type, "RGB") == 0 && num_bands == 3)
+	    alloc_wms_raster_layer (coverage_name, title, abstract, srid,
+				    has_flipped_axes, geo_minx, geo_miny,
+				    geo_maxx, geo_maxy, minx, miny, maxx, maxy,
+				    RL2_SAMPLE_UINT8, RL2_PIXEL_RGB, 3,
+				    is_queryable);
+    if (strcmp (sample_type, "UINT16") == 0 && strcmp (pixel_type, "RGB") == 0
+	&& num_bands == 3)
 	lyr =
-	    alloc_wms_layer (coverage_name, title, abstract, srid,
-			     is_geographic, minx, miny, maxx, maxy,
-			     RL2_SAMPLE_UINT16, RL2_PIXEL_RGB, 3);
+	    alloc_wms_raster_layer (coverage_name, title, abstract, srid,
+				    has_flipped_axes, geo_minx, geo_miny,
+				    geo_maxx, geo_maxy, minx, miny, maxx, maxy,
+				    RL2_SAMPLE_UINT16, RL2_PIXEL_RGB, 3,
+				    is_queryable);
     if (strcmp (sample_type, "UINT8") == 0
 	&& strcmp (pixel_type, "MULTIBAND") == 0 && num_bands >= 2
 	&& num_bands < 255)
 	lyr =
-	    alloc_wms_layer (coverage_name, title, abstract, srid,
-			     is_geographic, minx, miny, maxx, maxy,
-			     RL2_SAMPLE_UINT8, RL2_PIXEL_MULTIBAND, num_bands);
+	    alloc_wms_raster_layer (coverage_name, title, abstract, srid,
+				    has_flipped_axes, geo_minx, geo_miny,
+				    geo_maxx, geo_maxy, minx, miny, maxx, maxy,
+				    RL2_SAMPLE_UINT8, RL2_PIXEL_MULTIBAND,
+				    num_bands, is_queryable);
     if (strcmp (sample_type, "UINT16") == 0
 	&& strcmp (pixel_type, "MULTIBAND") == 0 && num_bands >= 2
 	&& num_bands < 255)
 	lyr =
-	    alloc_wms_layer (coverage_name, title, abstract, srid,
-			     is_geographic, minx, miny, maxx, maxy,
-			     RL2_SAMPLE_UINT16, RL2_PIXEL_MULTIBAND, num_bands);
+	    alloc_wms_raster_layer (coverage_name, title, abstract, srid,
+				    has_flipped_axes, geo_minx, geo_miny,
+				    geo_maxx, geo_maxy, minx, miny, maxx, maxy,
+				    RL2_SAMPLE_UINT16, RL2_PIXEL_MULTIBAND,
+				    num_bands, is_queryable);
     if (strcmp (sample_type, "INT8") == 0
 	&& strcmp (pixel_type, "DATAGRID") == 0 && num_bands == 1)
 	lyr =
-	    alloc_wms_layer (coverage_name, title, abstract, srid,
-			     is_geographic, minx, miny, maxx, maxy,
-			     RL2_SAMPLE_INT8, RL2_PIXEL_DATAGRID, 1);
+	    alloc_wms_raster_layer (coverage_name, title, abstract, srid,
+				    has_flipped_axes, geo_minx, geo_miny,
+				    geo_maxx, geo_maxy, minx, miny, maxx, maxy,
+				    RL2_SAMPLE_INT8, RL2_PIXEL_DATAGRID, 1,
+				    is_queryable);
     if (strcmp (sample_type, "UINT8") == 0
 	&& strcmp (pixel_type, "DATAGRID") == 0 && num_bands == 1)
 	lyr =
-	    alloc_wms_layer (coverage_name, title, abstract, srid,
-			     is_geographic, minx, miny, maxx, maxy,
-			     RL2_SAMPLE_UINT8, RL2_PIXEL_DATAGRID, 1);
+	    alloc_wms_raster_layer (coverage_name, title, abstract, srid,
+				    has_flipped_axes, geo_minx, geo_miny,
+				    geo_maxx, geo_maxy, minx, miny, maxx, maxy,
+				    RL2_SAMPLE_UINT8, RL2_PIXEL_DATAGRID, 1,
+				    is_queryable);
     if (strcmp (sample_type, "INT16") == 0
 	&& strcmp (pixel_type, "DATAGRID") == 0 && num_bands == 1)
 	lyr =
-	    alloc_wms_layer (coverage_name, title, abstract, srid,
-			     is_geographic, minx, miny, maxx, maxy,
-			     RL2_SAMPLE_INT16, RL2_PIXEL_DATAGRID, 1);
+	    alloc_wms_raster_layer (coverage_name, title, abstract, srid,
+				    has_flipped_axes, geo_minx, geo_miny,
+				    geo_maxx, geo_maxy, minx, miny, maxx, maxy,
+				    RL2_SAMPLE_INT16, RL2_PIXEL_DATAGRID, 1,
+				    is_queryable);
     if (strcmp (sample_type, "UINT16") == 0
 	&& strcmp (pixel_type, "DATAGRID") == 0 && num_bands == 1)
 	lyr =
-	    alloc_wms_layer (coverage_name, title, abstract, srid,
-			     is_geographic, minx, miny, maxx, maxy,
-			     RL2_SAMPLE_UINT16, RL2_PIXEL_DATAGRID, 1);
+	    alloc_wms_raster_layer (coverage_name, title, abstract, srid,
+				    has_flipped_axes, geo_minx, geo_miny,
+				    geo_maxx, geo_maxy, minx, miny, maxx, maxy,
+				    RL2_SAMPLE_UINT16, RL2_PIXEL_DATAGRID, 1,
+				    is_queryable);
     if (strcmp (sample_type, "INT32") == 0
 	&& strcmp (pixel_type, "DATAGRID") == 0 && num_bands == 1)
 	lyr =
-	    alloc_wms_layer (coverage_name, title, abstract, srid,
-			     is_geographic, minx, miny, maxx, maxy,
-			     RL2_SAMPLE_INT32, RL2_PIXEL_DATAGRID, 1);
+	    alloc_wms_raster_layer (coverage_name, title, abstract, srid,
+				    has_flipped_axes, geo_minx, geo_miny,
+				    geo_maxx, geo_maxy, minx, miny, maxx, maxy,
+				    RL2_SAMPLE_INT32, RL2_PIXEL_DATAGRID, 1,
+				    is_queryable);
     if (strcmp (sample_type, "UINT32") == 0
 	&& strcmp (pixel_type, "DATAGRID") == 0 && num_bands == 1)
 	lyr =
-	    alloc_wms_layer (coverage_name, title, abstract, srid,
-			     is_geographic, minx, miny, maxx, maxy,
-			     RL2_SAMPLE_UINT32, RL2_PIXEL_DATAGRID, 1);
+	    alloc_wms_raster_layer (coverage_name, title, abstract, srid,
+				    has_flipped_axes, geo_minx, geo_miny,
+				    geo_maxx, geo_maxy, minx, miny, maxx, maxy,
+				    RL2_SAMPLE_UINT32, RL2_PIXEL_DATAGRID, 1,
+				    is_queryable);
     if (strcmp (sample_type, "FLOAT") == 0
 	&& strcmp (pixel_type, "DATAGRID") == 0 && num_bands == 1)
 	lyr =
-	    alloc_wms_layer (coverage_name, title, abstract, srid,
-			     is_geographic, minx, miny, maxx, maxy,
-			     RL2_SAMPLE_FLOAT, RL2_PIXEL_DATAGRID, 1);
+	    alloc_wms_raster_layer (coverage_name, title, abstract, srid,
+				    has_flipped_axes, geo_minx, geo_miny,
+				    geo_maxx, geo_maxy, minx, miny, maxx, maxy,
+				    RL2_SAMPLE_FLOAT, RL2_PIXEL_DATAGRID, 1,
+				    is_queryable);
     if (strcmp (sample_type, "DOUBLE") == 0
 	&& strcmp (pixel_type, "DATAGRID") == 0 && num_bands == 1)
 	lyr =
-	    alloc_wms_layer (coverage_name, title, abstract, srid,
-			     is_geographic, minx, miny, maxx, maxy,
-			     RL2_SAMPLE_DOUBLE, RL2_PIXEL_DATAGRID, 1);
+	    alloc_wms_raster_layer (coverage_name, title, abstract, srid,
+				    has_flipped_axes, geo_minx, geo_miny,
+				    geo_maxx, geo_maxy, minx, miny, maxx, maxy,
+				    RL2_SAMPLE_DOUBLE, RL2_PIXEL_DATAGRID, 1,
+				    is_queryable);
     return lyr;
 }
 
-static struct wms_list *
-get_raster_coverages (sqlite3 * handle)
+static struct wms_layer *
+load_vector_layer (sqlite3 * handle, sqlite3_stmt * stmt)
+{
+/* creating a WMS layer (Vector) from the resultset */
+    unsigned char is_queryable = 0;
+    struct wms_layer *lyr = NULL;
+    const char *coverage_name = (const char *) sqlite3_column_text (stmt, 0);
+    const char *f_table_name = (const char *) sqlite3_column_text (stmt, 1);
+    const char *f_geometry_column =
+	(const char *) sqlite3_column_text (stmt, 2);
+    const char *title = (const char *) sqlite3_column_text (stmt, 3);
+    const char *abstract = (const char *) sqlite3_column_text (stmt, 4);
+    int srid = sqlite3_column_int (stmt, 5);
+    double geo_minx = sqlite3_column_double (stmt, 6);
+    double geo_miny = sqlite3_column_double (stmt, 7);
+    double geo_maxx = sqlite3_column_double (stmt, 8);
+    double geo_maxy = sqlite3_column_double (stmt, 9);
+    double minx = sqlite3_column_double (stmt, 10);
+    double miny = sqlite3_column_double (stmt, 11);
+    double maxx = sqlite3_column_double (stmt, 12);
+    double maxy = sqlite3_column_double (stmt, 13);
+    int spidx = sqlite3_column_int (stmt, 14);
+    unsigned char has_spatial_index = 0;
+    int has_flipped_axes = 0;
+    if (sqlite3_column_type (stmt, 15) == SQLITE_INTEGER)
+      {
+	  if (sqlite3_column_int (stmt, 15) != 0)
+	      is_queryable = 1;
+      }
+    if (spidx == 1)
+	has_spatial_index = 1;
+    if (!srid_has_flipped_axes (handle, srid, &has_flipped_axes))
+	has_flipped_axes = 0;
+    lyr =
+	alloc_wms_vector_layer (coverage_name, f_table_name, f_geometry_column,
+				title, abstract, srid, has_flipped_axes,
+				geo_minx, geo_miny, geo_maxx, geo_maxy, minx,
+				miny, maxx, maxy, has_spatial_index,
+				is_queryable);
+    return lyr;
+}
+
+static int
+get_raster_coverages (sqlite3 * handle, struct wms_list *list)
 {
 /* preparing a list of available Raster Coverages */
-    struct wms_list *list = NULL;
     int ret;
     sqlite3_stmt *stmt;
     const char *sql;
 
-/* loading all layers */
+/* loading all raster layers */
     sql = "SELECT coverage_name, title, abstract, sample_type, "
-	"pixel_type, num_bands, srid, extent_minx, extent_miny, extent_maxx, extent_maxy "
-	"FROM raster_coverages "
-	"WHERE extent_minx IS NOT NULL AND extent_miny IS NOT NULL "
+	"pixel_type, num_bands, srid, geo_minx, geo_miny, geo_maxx, "
+	"geo_maxy, extent_minx, extent_miny, extent_maxx, extent_maxy, "
+	"compression, is_queryable FROM raster_coverages "
+	"WHERE geo_minx IS NOT NULL AND geo_miny IS NOT NULL "
+	"AND geo_maxx IS NOT NULL AND geo_maxy IS NOT NULL "
+	"AND extent_minx IS NOT NULL AND extent_miny IS NOT NULL "
 	"AND extent_maxx IS NOT NULL AND extent_maxy IS NOT NULL";
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
-	return NULL;
-    list = alloc_wms_list ();
+	return 0;
     while (1)
       {
 	  /* scrolling the result set rows */
@@ -3785,7 +4286,7 @@ get_raster_coverages (sqlite3 * handle)
 	      break;		/* end of result set */
 	  if (ret == SQLITE_ROW)
 	    {
-		struct wms_layer *lyr = load_layer (handle, stmt);
+		struct wms_layer *lyr = load_raster_layer (handle, stmt);
 		if (lyr != NULL)
 		  {
 		      if (list->first_layer == NULL)
@@ -3794,12 +4295,78 @@ get_raster_coverages (sqlite3 * handle)
 			  list->last_layer->next = lyr;
 		      list->last_layer = lyr;
 		  }
+		else
+		    goto error;
 	    }
       }
     sqlite3_finalize (stmt);
+    return 1;
+
+  error:
+    sqlite3_finalize (stmt);
+    return 0;
+}
+
+static int
+get_vector_coverages (sqlite3 * handle, struct wms_list *list)
+{
+/* preparing a list of available Vector Coverages */
+    int ret;
+    sqlite3_stmt *stmt;
+    const char *sql;
+
+/* loading all vector layers */
+    sql = "SELECT c.coverage_name, c.f_table_name, c.f_geometry_column, "
+	"c.title, c.abstract, g.srid, c.geo_minx, c.geo_miny, c.geo_maxx, "
+	"c.geo_maxy, c.extent_minx, c.extent_miny, c.extent_maxx, "
+	"c.extent_maxy, g.spatial_index_enabled, c.is_queryable "
+	"FROM vector_coverages AS c JOIN geometry_columns AS g ON "
+	"(Upper(c.f_table_name) = Upper(g.f_table_name) AND "
+	"Upper(c.f_geometry_column) = Upper(g.f_geometry_column)) "
+	"WHERE c.extent_minx IS NOT NULL AND c.extent_miny IS NOT NULL "
+	"AND c.extent_maxx IS NOT NULL AND c.extent_maxy IS NOT NULL";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return 0;
+    while (1)
+      {
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		struct wms_layer *lyr = load_vector_layer (handle, stmt);
+		if (lyr != NULL)
+		  {
+		      if (list->first_layer == NULL)
+			  list->first_layer = lyr;
+		      if (list->last_layer != NULL)
+			  list->last_layer->next = lyr;
+		      list->last_layer = lyr;
+		  }
+		else
+		    goto error;
+	    }
+      }
+    sqlite3_finalize (stmt);
+    return 1;
+
+  error:
+    sqlite3_finalize (stmt);
+    return 0;
+}
+
+static int
+get_group_coverages (sqlite3 * handle, struct wms_list *list)
+{
+/* preparing a list of available Raster Coverages */
+    int ret;
+    sqlite3_stmt *stmt;
+    const char *sql;
 
 /* loading layer groups */
-    sql = "SELECT g.group_name, g.title, g.abstract, c.coverage_name "
+    sql = "SELECT g.group_name, g.title, g.abstract, c.raster_coverage_name "
 	"FROM SE_styled_groups AS g "
 	"LEFT JOIN  SE_styled_group_refs AS c ON (g.group_name = c.group_name) "
 	"ORDER BY c.paint_order";
@@ -3833,6 +4400,8 @@ get_raster_coverages (sqlite3 * handle)
 		      grp = grp->next;
 		  }
 		grp = alloc_wms_group (group_name, title, abstract);
+		if (grp == NULL)
+		    goto error;
 		if (list->first_group == NULL)
 		    list->first_group = grp;
 		if (list->last_group != NULL)
@@ -3862,15 +4431,11 @@ get_raster_coverages (sqlite3 * handle)
 	    }
       }
     sqlite3_finalize (stmt);
-    if (list->first_layer == NULL && list->first_group == NULL)
-	goto error;
-
-    return list;
+    return 1;
 
   error:
-    if (list != NULL)
-	destroy_wms_list (list);
-    return NULL;
+    sqlite3_finalize (stmt);
+    return 0;
 }
 
 static void
@@ -3880,7 +4445,42 @@ get_raster_styles (sqlite3 * handle, struct wms_list *list)
     int ret;
     sqlite3_stmt *stmt;
     const char *sql = "SELECT coverage_name, name, title, abstract "
-	"FROM SE_raster_styled_layers_view " "ORDER BY coverage_name, style_id";
+	"FROM SE_raster_styled_layers_view ORDER BY coverage_name, name";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return;
+    while (1)
+      {
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		const char *title = NULL;
+		const char *abstract = NULL;
+		const char *coverage_name =
+		    (const char *) sqlite3_column_text (stmt, 0);
+		const char *name = (const char *) sqlite3_column_text (stmt, 1);
+		if (sqlite3_column_type (stmt, 2) == SQLITE_TEXT)
+		    title = (const char *) sqlite3_column_text (stmt, 2);
+		if (sqlite3_column_type (stmt, 3) == SQLITE_TEXT)
+		    abstract = (const char *) sqlite3_column_text (stmt, 3);
+		add_style_to_wms_layer (list, coverage_name, name, title,
+					abstract);
+	    }
+      }
+    sqlite3_finalize (stmt);
+}
+
+static void
+get_vector_styles (sqlite3 * handle, struct wms_list *list)
+{
+/* retrieving all declared Vector Styles */
+    int ret;
+    sqlite3_stmt *stmt;
+    const char *sql = "SELECT coverage_name, name, title, abstract "
+	"FROM SE_vector_styled_layers_view ORDER BY coverage_name, name";
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
 	return;
@@ -3906,7 +4506,6 @@ get_raster_styles (sqlite3 * handle, struct wms_list *list)
 	    }
       }
     sqlite3_finalize (stmt);
-    add_default_styles (list);
 }
 
 static void
@@ -3916,7 +4515,7 @@ get_group_styles (sqlite3 * handle, struct wms_list *list)
     int ret;
     sqlite3_stmt *stmt;
     const char *sql = "SELECT group_name, name, title, abstract "
-	"FROM SE_group_styles_view " "ORDER BY group_name, style_id";
+	"FROM SE_group_styles_view ORDER BY group_name, style_id";
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
 	return;
@@ -3946,7 +4545,148 @@ get_group_styles (sqlite3 * handle, struct wms_list *list)
 }
 
 static void
-open_db (const char *path, sqlite3 ** handle, int cache_size, void *cache)
+get_raster_alt_srids (sqlite3 * handle, struct wms_list *list)
+{
+/* retrieving all declared Raster alternative SRIDs */
+    int ret;
+    sqlite3_stmt *stmt;
+    const char *sql = "SELECT coverage_name, srid, extent_minx, extent_miny, "
+	"extent_maxx, extent_maxy FROM raster_coverages_srid "
+	"WHERE extent_minx IS NOT NULL AND extent_miny IS NOT NULL "
+	"AND extent_maxx IS NOT NULL AND extent_maxy IS NOT NULL "
+	"ORDER BY coverage_name, srid";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return;
+    while (1)
+      {
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		const char *coverage_name =
+		    (const char *) sqlite3_column_text (stmt, 0);
+		int srid = sqlite3_column_int (stmt, 1);
+		double minx = sqlite3_column_double (stmt, 2);
+		double miny = sqlite3_column_double (stmt, 3);
+		double maxx = sqlite3_column_double (stmt, 4);
+		double maxy = sqlite3_column_double (stmt, 5);
+		int has_flipped_axes = 1;
+		if (!srid_has_flipped_axes (handle, srid, &has_flipped_axes))
+		    has_flipped_axes = 0;
+		add_alt_srid_to_wms_layer (list, coverage_name, srid,
+					   has_flipped_axes, minx, miny, maxx,
+					   maxy);
+	    }
+      }
+    sqlite3_finalize (stmt);
+}
+
+static void
+get_vector_alt_srids (sqlite3 * handle, struct wms_list *list)
+{
+/* retrieving all declared Vector alternative SRIDs */
+    int ret;
+    sqlite3_stmt *stmt;
+    const char *sql = "SELECT coverage_name, srid, extent_minx, extent_miny, "
+	"extent_maxx, extent_maxy FROM vector_coverages_srid "
+	"WHERE extent_minx IS NOT NULL AND extent_miny IS NOT NULL "
+	"AND extent_maxx IS NOT NULL AND extent_maxy IS NOT NULL "
+	"ORDER BY coverage_name, srid";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return;
+    while (1)
+      {
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		const char *coverage_name =
+		    (const char *) sqlite3_column_text (stmt, 0);
+		int srid = sqlite3_column_int (stmt, 1);
+		double minx = sqlite3_column_double (stmt, 2);
+		double miny = sqlite3_column_double (stmt, 3);
+		double maxx = sqlite3_column_double (stmt, 4);
+		double maxy = sqlite3_column_double (stmt, 5);
+		int has_flipped_axes = 1;
+		if (!srid_has_flipped_axes (handle, srid, &has_flipped_axes))
+		    has_flipped_axes = 0;
+		add_alt_srid_to_wms_layer (list, coverage_name, srid,
+					   has_flipped_axes, minx, miny, maxx,
+					   maxy);
+	    }
+      }
+    sqlite3_finalize (stmt);
+}
+
+static void
+get_raster_keywords (sqlite3 * handle, struct wms_list *list)
+{
+/* retrieving all declared Raster Keywords */
+    int ret;
+    sqlite3_stmt *stmt;
+    const char *sql =
+	"SELECT coverage_name, keyword FROM raster_coverages_keyword "
+	"WHERE keyword IS NOT NULL ORDER BY coverage_name, keyword";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return;
+    while (1)
+      {
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		const char *coverage_name =
+		    (const char *) sqlite3_column_text (stmt, 0);
+		const char *keyword =
+		    (const char *) sqlite3_column_text (stmt, 1);
+		add_keyword_to_wms_layer (list, coverage_name, keyword);
+	    }
+      }
+    sqlite3_finalize (stmt);
+}
+
+static void
+get_vector_keywords (sqlite3 * handle, struct wms_list *list)
+{
+/* retrieving all declared Vector Keywords */
+    int ret;
+    sqlite3_stmt *stmt;
+    const char *sql =
+	"SELECT coverage_name, keyword FROM vector_coverages_keyword "
+	"WHERE keyword IS NOT NULL ORDER BY coverage_name, keyword";
+    ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
+    if (ret != SQLITE_OK)
+	return;
+    while (1)
+      {
+	  /* scrolling the result set rows */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		const char *coverage_name =
+		    (const char *) sqlite3_column_text (stmt, 0);
+		const char *keyword =
+		    (const char *) sqlite3_column_text (stmt, 1);
+		add_keyword_to_wms_layer (list, coverage_name, keyword);
+	    }
+      }
+    sqlite3_finalize (stmt);
+}
+
+static void
+open_db (const char *path, sqlite3 ** handle, int cache_size, void *cache,
+	 void *priv_data)
 {
 /* opening the DB */
     sqlite3 *db_handle;
@@ -3987,7 +4727,7 @@ open_db (const char *path, sqlite3 ** handle, int cache_size, void *cache)
 	  return;
       }
     spatialite_init_ex (db_handle, cache, 0);
-    rl2_init (db_handle, 0);
+    rl2_init (db_handle, priv_data, 0);
 /* enabling WAL journaling */
     sprintf (sql, "PRAGMA journal_mode=WAL");
     sqlite3_exec (db_handle, sql, NULL, NULL, NULL);
@@ -4013,6 +4753,8 @@ do_help ()
     fprintf (stderr,
 	     "-p or --ip-port       number    IP port number [default: 8080]\n\n");
     fprintf (stderr,
+	     "-mt or --max-threads   num      max number of concurrent threads\n");
+    fprintf (stderr,
 	     "-cs or --cache-size    num      DB cache size (how many pages)\n");
     fprintf (stderr,
 	     "-dbg or --debug                 verbose debugginh mode\n");
@@ -4034,11 +4776,13 @@ main (int argc, char *argv[])
     int port_no = 8080;
     int cache_size = 0;
     void *cache;
+    void *priv_data;
     struct wms_list *list = NULL;
     struct connections_pool *pool;
     struct server_log *log;
     char *cached_capabilities = NULL;
     int cached_capabilities_len = 0;
+    int max_threads = 1;
 
 /* installing the signal handlers */
     glob.handle = NULL;
@@ -4048,6 +4792,7 @@ main (int argc, char *argv[])
     glob.list = NULL;
     glob.pool = NULL;
     glob.cache = NULL;
+    glob.priv_data = NULL;
 #ifdef _WIN32
     SetConsoleCtrlHandler (signal_handler, TRUE);
 #else
@@ -4071,6 +4816,9 @@ main (int argc, char *argv[])
 		  case ARG_CACHE_SIZE:
 		      cache_size = atoi (argv[i]);
 		      break;
+		  case ARG_MAX_THREADS:
+		      max_threads = atoi (argv[i]);
+		      break;
 		  };
 		next_arg = ARG_NONE;
 		continue;
@@ -4094,6 +4842,12 @@ main (int argc, char *argv[])
 		next_arg = ARG_IP_PORT;
 		continue;
 	    }
+	  if (strcasecmp (argv[i], "--max-threads") == 0
+	      || strcmp (argv[i], "-mt") == 0)
+	    {
+		next_arg = ARG_MAX_THREADS;
+		continue;
+	    }
 	  if (strcasecmp (argv[i], "--cache-size") == 0
 	      || strcmp (argv[i], "-cs") == 0)
 	    {
@@ -4127,33 +4881,67 @@ main (int argc, char *argv[])
 	  return -1;
       }
 
+/* normalizing MaxThreads */
+    if (max_threads < 1)
+	max_threads = 1;
+    if (max_threads > 64)
+	max_threads = 64;
+
 /* opening the DB */
     cache = spatialite_alloc_connection ();
     glob.cache = cache;
-    open_db (db_path, &handle, cache_size, cache);
+    priv_data = rl2_alloc_private ();
+    glob.priv_data = priv_data;
+    open_db (db_path, &handle, cache_size, cache, priv_data);
     if (!handle)
 	return -1;
     glob.handle = handle;
-
-    list = get_raster_coverages (handle);
+    list = alloc_wms_list ();
     if (list == NULL)
       {
+	  fprintf (stderr, "unable to allocate WMS Layers\n");
+	  goto stop;
+      }
+
+    if (!get_raster_coverages (handle, list))
+      {
+	  fprintf (stderr, "unable to retrieve Raster Coverages\n");
+	  goto stop;
+      }
+    if (!get_vector_coverages (handle, list))
+      {
+	  fprintf (stderr, "unable to retrieve Vector Coverages\n");
+	  goto stop;
+      }
+    if (!get_group_coverages (handle, list))
+      {
+	  fprintf (stderr, "unable to retrieve Group Coverages\n");
+	  goto stop;
+      }
+    if (list->first_layer == NULL)
+      {
 	  fprintf (stderr,
-		   "the DB \"%s\" doesn't contain any valid Raster Coverage\n",
+		   "the DB \"%s\" doesn't contain any valid Raster or Vector Coverage\n",
 		   db_path);
 	  goto stop;
       }
 
     get_raster_styles (handle, list);
+    get_vector_styles (handle, list);
     get_group_styles (handle, list);
+    add_default_styles (list);
+    get_raster_alt_srids (handle, list);
+    get_vector_alt_srids (handle, list);
+    get_raster_keywords (handle, list);
+    get_vector_keywords (handle, list);
     glob.list = list;
-    compute_geographic_extents (handle, list);
+    complete_layer_config (handle, list);
     build_get_capabilities (list, &cached_capabilities,
-			    &cached_capabilities_len);
+			    &cached_capabilities_len, port_no);
     glob.cached_capabilities = cached_capabilities;
 
 /* creating the read connections pool */
-    pool = alloc_connections_pool (db_path);
+    pool = alloc_connections_pool (db_path, max_threads);
     if (pool == NULL)
       {
 	  fprintf (stderr, "ERROR: unable to initialize a connections pool\n");
@@ -4171,7 +4959,7 @@ main (int argc, char *argv[])
     glob.log = log;
 
 /* starting the HTTP server */
-    if (!do_start_http (port_no, &skt_ptr))
+    if (!do_start_http (port_no, &skt_ptr, max_threads))
 	goto stop;
 
 /* starting the logging facility */

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/librasterlite2.git



More information about the Pkg-grass-devel mailing list