[SCM] librasterlite branch, upstream, updated. upstream/1.1_svn11

David Paleino dapal at debian.org
Tue Sep 27 08:02:42 UTC 2011


The following commit has been merged in the upstream branch:
commit 4f5214520d8971736a6e2a9c0791fab7cc118a50
Author: David Paleino <dapal at debian.org>
Date:   Tue Sep 27 09:56:49 2011 +0200

    Imported Upstream version 1.1~svn11

diff --git a/Makefile-static-Linux b/Makefile-static-Linux
index c85673e..14cf835 100644
--- a/Makefile-static-Linux
+++ b/Makefile-static-Linux
@@ -65,7 +65,7 @@ all: ./static_bin/rasterlite_load ./static_bin/rasterlite_pyramid \
 	$(CC) ./src/rasterlite_grid.o -o ./static_bin/rasterlite_grid \
 	/usr/local/lib/libgeotiff.a \
 	/usr/lib/libtiff.a \
-	/usr/lib/libproj.a \
+	/usr/local/lib/libproj.a \
 	/usr/lib/libjpeg.a \
 	/usr/lib/libz.a -lm
 	strip --strip-all ./static_bin/rasterlite_grid
diff --git a/Makefile.am b/Makefile.am
index 2d54f54..714c225 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,7 +2,9 @@ SUBDIRS = headers epsilon lib src
 
 AUTOMAKE_OPTIONS = dist-zip
 
-EXTRA_DIST = Makefile-static-MinGW Makefile-static-Linux Makefile-static-MacOsX
+EXTRA_DIST = Makefile-static-MinGW Makefile-static-Linux \
+	Makefile-static-MacOsX makefile.vc nmake.opt \
+	librasterlite.def
 
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = rasterlite.pc
diff --git a/Makefile.in b/Makefile.in
index 38dd7f1..6c1db99 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -193,7 +193,10 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 SUBDIRS = headers epsilon lib src 
 AUTOMAKE_OPTIONS = dist-zip
-EXTRA_DIST = Makefile-static-MinGW Makefile-static-Linux Makefile-static-MacOsX
+EXTRA_DIST = Makefile-static-MinGW Makefile-static-Linux \
+	Makefile-static-MacOsX makefile.vc nmake.opt \
+	librasterlite.def
+
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = rasterlite.pc
 all: all-recursive
diff --git a/README b/README
index 3cc0f3d..7bb1360 100644
--- a/README
+++ b/README
@@ -185,4 +185,16 @@ and you'll get any statically-linked tool built into the ./static_bin dir.
 3.3.2: using Microsoft Visual Studio .NET
 -----------------------------------------
 
-Not currently supported
+We suppose you have already installed Visual Studio enabling the command line
+tools [you are expected to use the command prompt shell].
+
+We'll suppose you have unpacked the sources as
+C:\librasterlite-1.0
+
+> cd c:\librasterlite-1.0
+> nmake /f makefile.vc
+> nmake /f makefile.vc install
+
+Important notice: you can install any depending library [libtiff, jpeg ..]
+using the OSGeo4W installer: http://trac.osgeo.org/osgeo4w/
+
diff --git a/configure b/configure
index eea15e9..4d66564 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.61 for librasterlite 1.0.
+# Generated by GNU Autoconf 2.61 for librasterlite 1.1.
 #
 # Report bugs to <a.furieri @ lqt.it>.
 #
@@ -728,8 +728,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # Identity of this package.
 PACKAGE_NAME='librasterlite'
 PACKAGE_TARNAME='librasterlite'
-PACKAGE_VERSION='1.0'
-PACKAGE_STRING='librasterlite 1.0'
+PACKAGE_VERSION='1.1'
+PACKAGE_STRING='librasterlite 1.1'
 PACKAGE_BUGREPORT='a.furieri @ lqt.it'
 
 # Factoring default headers for most tests.
@@ -1398,7 +1398,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 librasterlite 1.0 to adapt to many kinds of systems.
+\`configure' configures librasterlite 1.1 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1468,7 +1468,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of librasterlite 1.0:";;
+     short | recursive ) echo "Configuration of librasterlite 1.1:";;
    esac
   cat <<\_ACEOF
 
@@ -1572,7 +1572,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-librasterlite configure 1.0
+librasterlite configure 1.1
 generated by GNU Autoconf 2.61
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1586,7 +1586,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 librasterlite $as_me 1.0, which was
+It was created by librasterlite $as_me 1.1, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   $ $0 $@
@@ -2283,7 +2283,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='librasterlite'
- VERSION='1.0'
+ VERSION='1.1'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -24567,7 +24567,7 @@ exec 6>&1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by librasterlite $as_me 1.0, which was
+This file was extended by librasterlite $as_me 1.1, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -24614,7 +24614,7 @@ Report bugs to <bug-autoconf at gnu.org>."
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
-librasterlite config.status 1.0
+librasterlite config.status 1.1
 configured by $0, generated by GNU Autoconf 2.61,
   with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
diff --git a/configure.ac b/configure.ac
index 2af8eaf..c5e04d0 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(librasterlite, 1.0, a.furieri @ lqt.it)
+AC_INIT(librasterlite, 1.1, a.furieri @ lqt.it)
 AC_LANG(C) 
 
 AM_INIT_AUTOMAKE 
diff --git a/epsilon/Makefile.am b/epsilon/Makefile.am
index e1676db..cd71a12 100644
--- a/epsilon/Makefile.am
+++ b/epsilon/Makefile.am
@@ -7,3 +7,5 @@ libepsilon_la_SOURCES = bit_io.c checksum.c cobs.c color.c common.c dc_level.c \
 noinst_HEADERS = bit_io.h checksum.h cobs.h color.h common.h daub97lift.h \
 	dc_level.h filter.h filterbank.h libmain.h list.h mem_alloc.h \
 	merge_split.h pad.h resample.h speck.h epsilon.h
+
+EXTRA_DIST = msvc/stdint.h msvc/inttypes.h
diff --git a/epsilon/Makefile.in b/epsilon/Makefile.in
index d14b8d5..5bb3ca0 100644
--- a/epsilon/Makefile.in
+++ b/epsilon/Makefile.in
@@ -190,6 +190,7 @@ noinst_HEADERS = bit_io.h checksum.h cobs.h color.h common.h daub97lift.h \
 	dc_level.h filter.h filterbank.h libmain.h list.h mem_alloc.h \
 	merge_split.h pad.h resample.h speck.h epsilon.h
 
+EXTRA_DIST = msvc/stdint.h msvc/inttypes.h
 all: all-am
 
 .SUFFIXES:
diff --git a/epsilon/bit_io.c b/epsilon/bit_io.c
index 1e526f3..20abdee 100644
--- a/epsilon/bit_io.c
+++ b/epsilon/bit_io.c
@@ -1,22 +1,23 @@
 /*
- * $Id: bit_io.c,v 1.12 2008/03/25 19:31:44 simakov Exp $
+ * $Id: bit_io.c,v 1.14 2010/02/05 23:50:21 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
diff --git a/epsilon/bit_io.h b/epsilon/bit_io.h
index c2cacaa..c45d15a 100644
--- a/epsilon/bit_io.h
+++ b/epsilon/bit_io.h
@@ -1,22 +1,23 @@
 /*
- * $Id: bit_io.h,v 1.15 2008/03/25 19:31:45 simakov Exp $
+ * $Id: bit_io.h,v 1.17 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
diff --git a/epsilon/checksum.c b/epsilon/checksum.c
index 638f1f7..337d413 100644
--- a/epsilon/checksum.c
+++ b/epsilon/checksum.c
@@ -1,22 +1,23 @@
 /*
- * $Id: checksum.c,v 1.13 2007/07/21 15:15:25 simakov Exp $
+ * $Id: checksum.c,v 1.15 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006-2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
@@ -146,11 +147,13 @@ crc32_t epsilon_crc32(unsigned char *data, int length)
 {
     crc32_t crc = 0xffffffff;
     int i;
+
     assert(length >= 0);
 
     for (i = 0; i < length; i++) {
         crc = crc32_table[(crc ^ data[i]) & 0xff] ^ (crc >> 8);
     }
+
     return crc ^ 0xffffffff;
 }
 
diff --git a/epsilon/checksum.h b/epsilon/checksum.h
index 90b2ea0..33f07bb 100644
--- a/epsilon/checksum.h
+++ b/epsilon/checksum.h
@@ -1,22 +1,23 @@
 /*
- * $Id: checksum.h,v 1.13 2007/07/21 15:15:25 simakov Exp $
+ * $Id: checksum.h,v 1.15 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006-2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
@@ -55,7 +56,7 @@ extern "C" {
  *  \param length Data length
  *
  *  \return Checksum */
-crc32_t adler32(unsigned char *data, int length);
+crc32_t epsilon_adler32(unsigned char *data, int length);
 
 /** Compute CRC-32 checksum
  *
@@ -65,7 +66,7 @@ crc32_t adler32(unsigned char *data, int length);
  *  \param length Data length
  *
  *  \return Checksum */
-crc32_t crc32(unsigned char *data, int length);
+crc32_t epsilon_crc32(unsigned char *data, int length);
 
 /*@}*/
 
diff --git a/epsilon/cobs.c b/epsilon/cobs.c
index 045699f..9ec11ba 100644
--- a/epsilon/cobs.c
+++ b/epsilon/cobs.c
@@ -1,22 +1,23 @@
 /*
- * $Id: cobs.c,v 1.12 2007/05/20 13:19:12 simakov Exp $
+ * $Id: cobs.c,v 1.14 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
diff --git a/epsilon/cobs.h b/epsilon/cobs.h
index bb486c9..cf2e43a 100644
--- a/epsilon/cobs.h
+++ b/epsilon/cobs.h
@@ -1,22 +1,23 @@
 /*
- * $Id: cobs.h,v 1.14 2007/05/20 13:19:12 simakov Exp $
+ * $Id: cobs.h,v 1.16 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
diff --git a/epsilon/color.c b/epsilon/color.c
index 8df9dba..37f3462 100644
--- a/epsilon/color.c
+++ b/epsilon/color.c
@@ -1,22 +1,23 @@
 /*
- * $Id: color.c,v 1.13 2008/03/29 21:37:06 simakov Exp $
+ * $Id: color.c,v 1.15 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
diff --git a/epsilon/color.h b/epsilon/color.h
index 797d0ae..590827a 100644
--- a/epsilon/color.h
+++ b/epsilon/color.h
@@ -1,22 +1,23 @@
 /*
- * $Id: color.h,v 1.16 2008/03/29 21:37:06 simakov Exp $
+ * $Id: color.h,v 1.18 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
diff --git a/epsilon/common.c b/epsilon/common.c
index 0073f59..6c39c76 100644
--- a/epsilon/common.c
+++ b/epsilon/common.c
@@ -1,22 +1,23 @@
 /*
- * $Id: common.c,v 1.13 2008/03/25 19:31:45 simakov Exp $
+ * $Id: common.c,v 1.15 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
diff --git a/epsilon/common.h b/epsilon/common.h
index 3a3f4fd..c5db1ed 100644
--- a/epsilon/common.h
+++ b/epsilon/common.h
@@ -1,22 +1,23 @@
 /*
- * $Id: common.h,v 1.27 2008/03/25 19:31:45 simakov Exp $
+ * $Id: common.h,v 1.30 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
@@ -38,6 +39,11 @@ extern "C" {
 /** \addtogroup misc Miscellanea */
 /*@{*/
 
+/* Use _snprintf instead of snprintf under MSVC compiler */
+#if defined(_WIN32) && !defined(__MINGW32__)
+#define snprintf    _snprintf
+#endif
+
 #ifdef HAVE_CONFIG_H
 # include <config.h>
 #endif
diff --git a/epsilon/daub97lift.h b/epsilon/daub97lift.h
index c35d389..4a80db3 100644
--- a/epsilon/daub97lift.h
+++ b/epsilon/daub97lift.h
@@ -1,22 +1,23 @@
 /*
- * $Id: daub97lift.h,v 1.2 2008/03/29 19:57:31 simakov Exp $
+ * $Id: daub97lift.h,v 1.4 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
diff --git a/epsilon/dc_level.c b/epsilon/dc_level.c
index 07868c3..423bd26 100644
--- a/epsilon/dc_level.c
+++ b/epsilon/dc_level.c
@@ -1,22 +1,23 @@
 /*
- * $Id: dc_level.c,v 1.9 2007/05/20 13:19:12 simakov Exp $
+ * $Id: dc_level.c,v 1.11 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
diff --git a/epsilon/dc_level.h b/epsilon/dc_level.h
index d5f4447..aac7be4 100644
--- a/epsilon/dc_level.h
+++ b/epsilon/dc_level.h
@@ -1,22 +1,23 @@
 /*
- * $Id: dc_level.h,v 1.11 2007/05/20 13:19:12 simakov Exp $
+ * $Id: dc_level.h,v 1.13 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
diff --git a/epsilon/epsilon.h b/epsilon/epsilon.h
index 648c330..9bbad45 100644
--- a/epsilon/epsilon.h
+++ b/epsilon/epsilon.h
@@ -1,22 +1,23 @@
 /*
- * $Id: epsilon.h,v 1.58 2007/07/22 15:45:02 simakov Exp $
+ * $Id: epsilon.h,v 1.61 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
@@ -237,7 +238,7 @@ typedef struct eps_block_header_tag {
         gs_hdr gs;
         /** Special information for TRUECOLOR blocks */
         tc_hdr tc;
-    };
+    } hdr_data;
 } eps_block_header;
 
 /** Query available filterbanks
diff --git a/epsilon/filter.c b/epsilon/filter.c
index bb7bbe2..d28c605 100644
--- a/epsilon/filter.c
+++ b/epsilon/filter.c
@@ -1,22 +1,23 @@
 /*
- * $Id: filter.c,v 1.18 2008/03/30 07:38:53 simakov Exp $
+ * $Id: filter.c,v 1.21 2010/04/05 06:11:55 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
@@ -79,6 +80,8 @@ inline local int symmetric_H_extension(int index, int length)
     return index;
 }
 
+/* Note: output_length parameter is not actually used but it's preserved
+ * in order to make downsample_signal() symmetric to and upsample_signal(). */
 inline local void downsample_signal(coeff_t *input_signal, coeff_t *output_signal,
                                     int input_length, int output_length, int phase)
 {
diff --git a/epsilon/filter.h b/epsilon/filter.h
index ebb2267..1a85aec 100644
--- a/epsilon/filter.h
+++ b/epsilon/filter.h
@@ -1,22 +1,23 @@
 /*
- * $Id: filter.h,v 1.19 2008/03/28 22:52:29 simakov Exp $
+ * $Id: filter.h,v 1.22 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
@@ -42,6 +43,11 @@
 extern "C" {
 #endif
 
+/* Use __inline instead of inline under MSVC compiler */
+#if defined(_MSC_VER) && !defined(__cplusplus)
+#define inline  __inline
+#endif
+
 /** \addtogroup wavelet Wavelet transform */
 /*@{*/
 
diff --git a/epsilon/filterbank.c b/epsilon/filterbank.c
index af43419..26f43fb 100644
--- a/epsilon/filterbank.c
+++ b/epsilon/filterbank.c
@@ -1,22 +1,23 @@
 /*
- * $Id: filterbank.c,v 1.12 2008/03/28 22:52:29 simakov Exp $
+ * $Id: filterbank.c,v 1.15 2010/03/19 22:57:29 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
@@ -1277,7 +1278,7 @@ static filterbank_t vaidyanathan = {
     &vaidyanathan_highpass_synthesis,
 };
 
-/* Coeflet �6 filter. */
+/* Coeflet C6 filter. */
 
 static coeff_t coiflet6_lowpass_analysis_coeffs[] = {
     0.038580777748,
diff --git a/epsilon/filterbank.h b/epsilon/filterbank.h
index d1a384e..0e1ada5 100644
--- a/epsilon/filterbank.h
+++ b/epsilon/filterbank.h
@@ -1,22 +1,23 @@
 /*
- * $Id: filterbank.h,v 1.15 2007/05/20 13:19:12 simakov Exp $
+ * $Id: filterbank.h,v 1.17 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
diff --git a/epsilon/libmain.c b/epsilon/libmain.c
index 599b553..e509bd6 100644
--- a/epsilon/libmain.c
+++ b/epsilon/libmain.c
@@ -1,22 +1,23 @@
 /*
- * $Id: libmain.c,v 1.59 2008/03/25 19:31:45 simakov Exp $
+ * $Id: libmain.c,v 1.63 2010/04/05 05:01:04 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006-2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
@@ -35,7 +36,6 @@
 #include <pad.h>
 #include <merge_split.h>
 #include <speck.h>
-#include <strings.h>
 #include <string.h>
 
 local void round_channel(coeff_t **in_channel, int **out_channel,
@@ -240,8 +240,10 @@ local int read_gs_header(unsigned char *buf, int buf_size,
     result = sscanf(str,
         "type=gs;W=%d;H=%d;w=%d;h=%d;x=%d;y=%d;"
         "m=%d;dc=%d;fb=%31[a-z0-9];chk=%x;crc=%x%n",
-        &hdr->gs.W, &hdr->gs.H, &hdr->gs.w, &hdr->gs.h,
-        &hdr->gs.x, &hdr->gs.y, &hdr->gs.mode, &hdr->gs.dc,
+        &hdr->hdr_data.gs.W, &hdr->hdr_data.gs.H,
+        &hdr->hdr_data.gs.w, &hdr->hdr_data.gs.h,
+        &hdr->hdr_data.gs.x, &hdr->hdr_data.gs.y,
+        &hdr->hdr_data.gs.mode, &hdr->hdr_data.gs.dc,
         fb_id, &hdr->chk, &hdr->crc, &n);
 
     unterminate_header(buf);
@@ -260,53 +262,55 @@ local int read_gs_header(unsigned char *buf, int buf_size,
     assert(hdr->hdr_size + hdr->data_size == buf_size);
 
     /* Check transform mode */
-    if ((hdr->gs.mode != EPS_MODE_NORMAL) && (hdr->gs.mode != EPS_MODE_OTLPF)) {
+    if ((hdr->hdr_data.gs.mode != EPS_MODE_NORMAL) &&
+        (hdr->hdr_data.gs.mode != EPS_MODE_OTLPF)) {
         return EPS_FORMAT_ERROR;
     }
 
     /* Check image (W, H) and block (w, y, w, h) parameters for consistency */
-    if ((hdr->gs.W <= 0) || (hdr->gs.H <= 0)) {
+    if ((hdr->hdr_data.gs.W <= 0) || (hdr->hdr_data.gs.H <= 0)) {
         return EPS_FORMAT_ERROR;
     }
 
-    if ((hdr->gs.w < 1) || (hdr->gs.h < 1)) {
+    if ((hdr->hdr_data.gs.w < 1) || (hdr->hdr_data.gs.h < 1)) {
         return EPS_FORMAT_ERROR;
     }
 
-    if (hdr->gs.w > EPS_MAX_BLOCK_SIZE + hdr->gs.mode == EPS_MODE_OTLPF) {
+    if (hdr->hdr_data.gs.w > EPS_MAX_BLOCK_SIZE + (hdr->hdr_data.gs.mode == EPS_MODE_OTLPF)) {
         return EPS_FORMAT_ERROR;
     }
 
-    if (hdr->gs.h > EPS_MAX_BLOCK_SIZE + hdr->gs.mode == EPS_MODE_OTLPF) {
+    if (hdr->hdr_data.gs.h > EPS_MAX_BLOCK_SIZE + (hdr->hdr_data.gs.mode == EPS_MODE_OTLPF)) {
         return EPS_FORMAT_ERROR;
     }
 
-    if ((hdr->gs.x < 0) || (hdr->gs.y < 0)) {
+    if ((hdr->hdr_data.gs.x < 0) || (hdr->hdr_data.gs.y < 0)) {
         return EPS_FORMAT_ERROR;
     }
 
-    if (hdr->gs.x + hdr->gs.w > hdr->gs.W) {
+    if (hdr->hdr_data.gs.x + hdr->hdr_data.gs.w > hdr->hdr_data.gs.W) {
         return EPS_FORMAT_ERROR;
     }
 
-    if (hdr->gs.y + hdr->gs.h > hdr->gs.H) {
+    if (hdr->hdr_data.gs.y + hdr->hdr_data.gs.h > hdr->hdr_data.gs.H) {
         return EPS_FORMAT_ERROR;
     }
 
     /* Check DC level */
-    if ((hdr->gs.dc < 0) || (hdr->gs.dc > 255)) {
+    if ((hdr->hdr_data.gs.dc < 0) || (hdr->hdr_data.gs.dc > 255)) {
         return EPS_FORMAT_ERROR;
     }
 
     /* Find filterbank by id */
-    if (fb = get_fb(fb_id)) {
-        hdr->gs.fb_id = fb->id;
+    fb = get_fb(fb_id);
+    if (fb) {
+        hdr->hdr_data.gs.fb_id = fb->id;
     } else {
-        hdr->gs.fb_id = NULL;
+        hdr->hdr_data.gs.fb_id = NULL;
     }
 
     /* EPS_MODE_NORMAL is the only valid choise for orthogonal filters */
-    if ((fb->type == ORTHOGONAL) && (hdr->gs.mode != EPS_MODE_NORMAL)) {
+    if ((fb->type == ORTHOGONAL) && (hdr->hdr_data.gs.mode != EPS_MODE_NORMAL)) {
         return EPS_FORMAT_ERROR;
     }
 
@@ -350,6 +354,7 @@ local int read_tc_header(unsigned char *buf, int buf_size,
 
     char *chk_pos;
     char *str;
+
     /* Sanity checks */
     if (!buf || !hdr) {
         return EPS_PARAM_ERROR;
@@ -376,16 +381,21 @@ local int read_tc_header(unsigned char *buf, int buf_size,
 
     /* Mark the position of header CRC field */
     chk_pos = strstr(str, "chk=");
+
     /* Parse header fields */
     result = sscanf(str,
         "type=tc;W=%d;H=%d;w=%d;h=%d;x=%d;y=%d;m=%d;"
         "r=%d;dc=%d:%d:%d;rt=%d:%d:%d;fb=%31[a-z0-9];"
         "chk=%x;crc=%x%n",
-        &hdr->tc.W, &hdr->tc.H, &hdr->tc.w, &hdr->tc.h,
-        &hdr->tc.x, &hdr->tc.y, &hdr->tc.mode, &hdr->tc.resample,
-        &hdr->tc.dc_Y, &hdr->tc.dc_Cb, &hdr->tc.dc_Cr,
-        &hdr->tc.Y_rt, &hdr->tc.Cb_rt, &hdr->tc.Cr_rt,
+        &hdr->hdr_data.tc.W, &hdr->hdr_data.tc.H,
+        &hdr->hdr_data.tc.w, &hdr->hdr_data.tc.h,
+        &hdr->hdr_data.tc.x, &hdr->hdr_data.tc.y,
+        &hdr->hdr_data.tc.mode, &hdr->hdr_data.tc.resample,
+        &hdr->hdr_data.tc.dc_Y, &hdr->hdr_data.tc.dc_Cb,
+        &hdr->hdr_data.tc.dc_Cr, &hdr->hdr_data.tc.Y_rt,
+        &hdr->hdr_data.tc.Cb_rt, &hdr->hdr_data.tc.Cr_rt,
         fb_id, &hdr->chk, &hdr->crc, &n);
+
     unterminate_header(buf);
 
     /* Check for parsing errors (see also sscanf(3)) */
@@ -402,76 +412,83 @@ local int read_tc_header(unsigned char *buf, int buf_size,
     assert(hdr->hdr_size + hdr->data_size == buf_size);
 
     /* Check transform mode */
-    if ((hdr->tc.mode != EPS_MODE_NORMAL) && (hdr->tc.mode != EPS_MODE_OTLPF)) {
+    if ((hdr->hdr_data.tc.mode != EPS_MODE_NORMAL) &&
+        (hdr->hdr_data.tc.mode != EPS_MODE_OTLPF))
+    {
         return EPS_FORMAT_ERROR;
     }
 
     /* Check image (W, H) and block (w, y, w, h) parameters for consistency */
-    if ((hdr->tc.W <= 0) || (hdr->tc.H <= 0)) {
+    if ((hdr->hdr_data.tc.W <= 0) || (hdr->hdr_data.tc.H <= 0)) {
         return EPS_FORMAT_ERROR;
     }
 
-    if ((hdr->tc.w < 1) || (hdr->tc.h < 1)) {
+    if ((hdr->hdr_data.tc.w < 1) || (hdr->hdr_data.tc.h < 1)) {
         return EPS_FORMAT_ERROR;
     }
 
-    if (hdr->tc.w > EPS_MAX_BLOCK_SIZE + hdr->tc.mode == EPS_MODE_OTLPF) {
+    if (hdr->hdr_data.tc.w > EPS_MAX_BLOCK_SIZE + (hdr->hdr_data.tc.mode == EPS_MODE_OTLPF)) {
         return EPS_FORMAT_ERROR;
     }
 
-    if (hdr->tc.h > EPS_MAX_BLOCK_SIZE + hdr->tc.mode == EPS_MODE_OTLPF) {
+    if (hdr->hdr_data.tc.h > EPS_MAX_BLOCK_SIZE + (hdr->hdr_data.tc.mode == EPS_MODE_OTLPF)) {
         return EPS_FORMAT_ERROR;
     }
 
-    if ((hdr->tc.x < 0) || (hdr->tc.y < 0)) {
+    if ((hdr->hdr_data.tc.x < 0) || (hdr->hdr_data.tc.y < 0)) {
         return EPS_FORMAT_ERROR;
     }
 
-    if (hdr->tc.x + hdr->tc.w > hdr->tc.W) {
+    if (hdr->hdr_data.tc.x + hdr->hdr_data.tc.w > hdr->hdr_data.tc.W) {
         return EPS_FORMAT_ERROR;
     }
 
-    if (hdr->tc.y + hdr->tc.h > hdr->tc.H) {
+    if (hdr->hdr_data.tc.y + hdr->hdr_data.tc.h > hdr->hdr_data.tc.H) {
         return EPS_FORMAT_ERROR;
     }
 
     /* Check resampling mode */
-    if ((hdr->tc.resample != EPS_RESAMPLE_444) &&
-        (hdr->tc.resample != EPS_RESAMPLE_420))
+    if ((hdr->hdr_data.tc.resample != EPS_RESAMPLE_444) &&
+        (hdr->hdr_data.tc.resample != EPS_RESAMPLE_420))
     {
         return EPS_FORMAT_ERROR;
     }
 
     /* Check DC level for Y, Cb and Cr channels */
-    if ((hdr->tc.dc_Y < 0) || (hdr->tc.dc_Y > 255)) {
+    if ((hdr->hdr_data.tc.dc_Y < 0) || (hdr->hdr_data.tc.dc_Y > 255)) {
         return EPS_FORMAT_ERROR;
     }
 
-    if ((hdr->tc.dc_Cb < 0) || (hdr->tc.dc_Cb > 255)) {
+    if ((hdr->hdr_data.tc.dc_Cb < 0) || (hdr->hdr_data.tc.dc_Cb > 255)) {
         return EPS_FORMAT_ERROR;
     }
 
-    if ((hdr->tc.dc_Cr < 0) || (hdr->tc.dc_Cr > 255)) {
+    if ((hdr->hdr_data.tc.dc_Cr < 0) || (hdr->hdr_data.tc.dc_Cr > 255)) {
         return EPS_FORMAT_ERROR;
     }
 
-    if ((hdr->tc.Y_rt <= 0) || (hdr->tc.Cb_rt <= 0) || (hdr->tc.Cr_rt <= 0)) {
+    if ((hdr->hdr_data.tc.Y_rt <= 0)  ||
+        (hdr->hdr_data.tc.Cb_rt <= 0) ||
+        (hdr->hdr_data.tc.Cr_rt <= 0))
+    {
         return EPS_FORMAT_ERROR;
     }
 
     /* Find filterbank by id */
-    if (fb = get_fb(fb_id)) {
-        hdr->tc.fb_id = fb->id;
+    fb = get_fb(fb_id);
+    if (fb) {
+        hdr->hdr_data.tc.fb_id = fb->id;
     } else {
-        hdr->tc.fb_id = NULL;
+        hdr->hdr_data.tc.fb_id = NULL;
     }
 
     /* EPS_MODE_NORMAL is the only valid choise for orthogonal filters */
-    if ((fb->type == ORTHOGONAL) && (hdr->tc.mode != EPS_MODE_NORMAL)) {
+    if ((fb->type == ORTHOGONAL) && (hdr->hdr_data.tc.mode != EPS_MODE_NORMAL)) {
         return EPS_FORMAT_ERROR;
     }
 
     assert(chk_pos);
+
     /* Compute header CRC and compare it against stored one */
     hdr_crc = epsilon_crc32(buf, chk_pos - (char *) buf);
     hdr_crc = (hdr_crc ^ (hdr_crc >> 16)) & 0xffff;
@@ -481,6 +498,7 @@ local int read_tc_header(unsigned char *buf, int buf_size,
     } else {
         hdr->chk_flag = EPS_BAD_CRC;
     }
+
     /* Compute data CRC and compare it against stored one */
     data_crc = epsilon_crc32(buf + hdr->hdr_size, hdr->data_size);
 
@@ -489,6 +507,7 @@ local int read_tc_header(unsigned char *buf, int buf_size,
     } else {
         hdr->crc_flag = EPS_BAD_CRC;
     }
+
     return EPS_OK;
 }
 
@@ -496,6 +515,7 @@ int eps_read_block_header(unsigned char *buf, int buf_size,
                           eps_block_header *hdr)
 {
     char *str;
+
     /* Sanity checks */
     if (!buf || !hdr) {
         return EPS_PARAM_ERROR;
@@ -544,6 +564,12 @@ int eps_read_block_header(unsigned char *buf, int buf_size,
             break;
         }
     }
+
+    /* This code is unreachable, just to be on a safe side */
+    assert(0);
+
+    /* Fake return disables 'not all control paths return a value' warning */
+    return EPS_FORMAT_ERROR;
 }
 
 char **eps_get_fb_info(int type)
@@ -646,11 +672,11 @@ int eps_encode_grayscale_block(unsigned char **block, int W, int H, int w, int h
         return EPS_PARAM_ERROR;
     }
 
-    if (w > EPS_MAX_BLOCK_SIZE + mode == EPS_MODE_OTLPF) {
+    if (w > EPS_MAX_BLOCK_SIZE + (mode == EPS_MODE_OTLPF)) {
         return EPS_PARAM_ERROR;
     }
 
-    if (h > EPS_MAX_BLOCK_SIZE + mode == EPS_MODE_OTLPF) {
+    if (h > EPS_MAX_BLOCK_SIZE + (mode == EPS_MODE_OTLPF)) {
         return EPS_PARAM_ERROR;
     }
 
@@ -782,15 +808,15 @@ int eps_decode_grayscale_block(unsigned char **block, unsigned char *buf,
         return EPS_PARAM_ERROR;
     }
 
-    if (!hdr->gs.fb_id) {
+    if (!hdr->hdr_data.gs.fb_id) {
         return EPS_UNSUPPORTED_FB;
     }
 
     /* Reset Y channel */
-    reset_Y(block, hdr->gs.w, hdr->gs.h);
+    reset_Y(block, hdr->hdr_data.gs.w, hdr->hdr_data.gs.h);
 
     /* Find filterbank from id */
-    fb = get_fb(hdr->gs.fb_id);
+    fb = get_fb(hdr->hdr_data.gs.fb_id);
     assert(fb);
 
     /* Unstuff data */
@@ -806,7 +832,8 @@ int eps_decode_grayscale_block(unsigned char **block, unsigned char *buf,
     }
 
     /* Compute block size */
-    block_size = get_block_size(hdr->gs.w, hdr->gs.h, hdr->gs.mode, 2);
+    block_size = get_block_size(hdr->hdr_data.gs.w, hdr->hdr_data.gs.h,
+        hdr->hdr_data.gs.mode, 2);
 
     /* Decode coefficients */
     int_block = (int **) malloc_2D(block_size, block_size, sizeof(int));
@@ -820,10 +847,10 @@ int eps_decode_grayscale_block(unsigned char **block, unsigned char *buf,
 
     /* Inverse wavelet transform */
     pad_block = (coeff_t **) malloc_2D(block_size, block_size, sizeof(coeff_t));
-    synthesis_2D(dwt_block, pad_block, block_size, hdr->gs.mode, fb);
+    synthesis_2D(dwt_block, pad_block, block_size, hdr->hdr_data.gs.mode, fb);
     free_2D((void *) dwt_block, block_size, block_size);
 
-    dc_int = (unsigned char) hdr->gs.dc;
+    dc_int = (unsigned char) hdr->hdr_data.gs.dc;
 
     /* DC level unshift */
     dc_level_unshift(pad_block, (coeff_t) dc_int,
@@ -831,7 +858,7 @@ int eps_decode_grayscale_block(unsigned char **block, unsigned char *buf,
 
     /* Extract original data */
     extract_channel(pad_block, block, block_size, block_size,
-        hdr->gs.w, hdr->gs.h);
+        hdr->hdr_data.gs.w, hdr->hdr_data.gs.h);
 
     free_2D((void *) pad_block, block_size, block_size);
 
@@ -938,11 +965,11 @@ int eps_encode_truecolor_block(unsigned char **block_R,
         return EPS_PARAM_ERROR;
     }
 
-    if (w > EPS_MAX_BLOCK_SIZE + mode == EPS_MODE_OTLPF) {
+    if (w > EPS_MAX_BLOCK_SIZE + (mode == EPS_MODE_OTLPF)) {
         return EPS_PARAM_ERROR;
     }
 
-    if (h > EPS_MAX_BLOCK_SIZE + mode == EPS_MODE_OTLPF) {
+    if (h > EPS_MAX_BLOCK_SIZE + (mode == EPS_MODE_OTLPF)) {
         return EPS_PARAM_ERROR;
     }
 
@@ -1286,14 +1313,14 @@ int eps_decode_truecolor_block(unsigned char **block_R,
     }
 
     /* Reset RGB channels */
-    reset_RGB(block_R, block_G, block_B, hdr->tc.w, hdr->tc.h);
+    reset_RGB(block_R, block_G, block_B, hdr->hdr_data.tc.w, hdr->hdr_data.tc.h);
 
     /* Find filterbank by id */
-    if (!hdr->tc.fb_id) {
+    if (!hdr->hdr_data.tc.fb_id) {
         return EPS_UNSUPPORTED_FB;
     }
 
-    fb = get_fb(hdr->tc.fb_id);
+    fb = get_fb(hdr->hdr_data.tc.fb_id);
     assert(fb);
 
     /* Unstaff data */
@@ -1304,7 +1331,7 @@ int eps_decode_truecolor_block(unsigned char **block_R,
         hdr->data_size, hdr->data_size);
 
     /* Consistency check */
-    if (unstuff_bytes > hdr->tc.Y_rt + hdr->tc.Cb_rt + hdr->tc.Cr_rt) {
+    if (unstuff_bytes > hdr->hdr_data.tc.Y_rt + hdr->hdr_data.tc.Cb_rt + hdr->hdr_data.tc.Cr_rt) {
         free(unstuff_buf);
         return EPS_FORMAT_ERROR;
     }
@@ -1323,15 +1350,16 @@ int eps_decode_truecolor_block(unsigned char **block_R,
         sizeof(unsigned char));
 
     /* Split stream into Y and (Cb + Cr) channels */
-    split_channels(unstuff_buf, buf_Y, buf_Cb_Cr, unstuff_bytes,
-                   hdr->tc.Y_rt, hdr->tc.Cb_rt + hdr->tc.Cr_rt,
+    split_channels(unstuff_buf, buf_Y, buf_Cb_Cr,
+                   unstuff_bytes, hdr->hdr_data.tc.Y_rt,
+                   hdr->hdr_data.tc.Cb_rt + hdr->hdr_data.tc.Cr_rt,
                    &speck_bytes_Y, &speck_bytes_Cb_Cr);
 
     /* No longer needed */
     free(unstuff_buf);
 
     /* Consistency check */
-    if (speck_bytes_Cb_Cr > hdr->tc.Cb_rt + hdr->tc.Cr_rt) {
+    if (speck_bytes_Cb_Cr > hdr->hdr_data.tc.Cb_rt + hdr->hdr_data.tc.Cr_rt) {
         free(buf_Y);
         free(buf_Cb_Cr);
         return EPS_FORMAT_ERROR;
@@ -1358,7 +1386,7 @@ int eps_decode_truecolor_block(unsigned char **block_R,
 
     /* Split merged (Cb + Cr) channel into Cb and Cr channels */
     split_channels(buf_Cb_Cr, buf_Cb, buf_Cr, speck_bytes_Cb_Cr,
-                   hdr->tc.Cb_rt, hdr->tc.Cr_rt,
+                   hdr->hdr_data.tc.Cb_rt, hdr->hdr_data.tc.Cr_rt,
                    &speck_bytes_Cb, &speck_bytes_Cr);
 
     /* No longer needed */
@@ -1377,10 +1405,10 @@ int eps_decode_truecolor_block(unsigned char **block_R,
     }
 
     /* Compute block sizes for full and resampled channels */
-    full_size = get_block_size(hdr->tc.w, hdr->tc.h, hdr->tc.mode, 4);
-    half_size = full_size / 2 + (hdr->tc.mode == EPS_MODE_OTLPF);
+    full_size = get_block_size(hdr->hdr_data.tc.w, hdr->hdr_data.tc.h, hdr->hdr_data.tc.mode, 4);
+    half_size = full_size / 2 + (hdr->hdr_data.tc.mode == EPS_MODE_OTLPF);
 
-    if (hdr->tc.resample == EPS_RESAMPLE_444) {
+    if (hdr->hdr_data.tc.resample == EPS_RESAMPLE_444) {
         block_Y_size = full_size;
         block_Cb_size = full_size;
         block_Cr_size = full_size;
@@ -1435,9 +1463,9 @@ int eps_decode_truecolor_block(unsigned char **block_R,
         sizeof(coeff_t));
 
     /* Inverse wavelet transform */
-    synthesis_2D(dwt_block_Y, block_Y, block_Y_size, hdr->tc.mode, fb);
-    synthesis_2D(dwt_block_Cb, block_Cb, block_Cb_size, hdr->tc.mode, fb);
-    synthesis_2D(dwt_block_Cr, block_Cr, block_Cr_size, hdr->tc.mode, fb);
+    synthesis_2D(dwt_block_Y, block_Y, block_Y_size, hdr->hdr_data.tc.mode, fb);
+    synthesis_2D(dwt_block_Cb, block_Cb, block_Cb_size, hdr->hdr_data.tc.mode, fb);
+    synthesis_2D(dwt_block_Cr, block_Cr, block_Cr_size, hdr->hdr_data.tc.mode, fb);
 
     /* No longer needed */
     free_2D((void *) dwt_block_Y, block_Y_size, block_Y_size);
@@ -1445,9 +1473,9 @@ int eps_decode_truecolor_block(unsigned char **block_R,
     free_2D((void *) dwt_block_Cr, block_Cr_size, block_Cr_size);
 
     /* Get DC values */
-    dc_Y_int = (unsigned char) hdr->tc.dc_Y;
-    dc_Cb_int = (unsigned char) hdr->tc.dc_Cb;
-    dc_Cr_int = (unsigned char) hdr->tc.dc_Cr;
+    dc_Y_int  = (unsigned char) hdr->hdr_data.tc.dc_Y;
+    dc_Cb_int = (unsigned char) hdr->hdr_data.tc.dc_Cb;
+    dc_Cr_int = (unsigned char) hdr->hdr_data.tc.dc_Cr;
 
     /* DC level unshift */
     dc_level_unshift(block_Y, (coeff_t) dc_Y_int,
@@ -1457,7 +1485,7 @@ int eps_decode_truecolor_block(unsigned char **block_R,
     dc_level_unshift(block_Cr, (coeff_t) dc_Cr_int,
         block_Cr_size, block_Cr_size);
 
-    if (hdr->tc.resample == EPS_RESAMPLE_444) {
+    if (hdr->hdr_data.tc.resample == EPS_RESAMPLE_444) {
         /* No upsampling */
         pad_block_Y = block_Y;
         pad_block_Cb = block_Cb;
@@ -1512,15 +1540,18 @@ int eps_decode_truecolor_block(unsigned char **block_R,
     /* Extract original data from R,G,B channels */
     extract_channel(pad_block_R, block_R,
                     full_size, full_size,
-                    hdr->tc.w, hdr->tc.h);
+                    hdr->hdr_data.tc.w,
+                    hdr->hdr_data.tc.h);
 
     extract_channel(pad_block_G, block_G,
                     full_size, full_size,
-                    hdr->tc.w, hdr->tc.h);
+                    hdr->hdr_data.tc.w,
+                    hdr->hdr_data.tc.h);
 
     extract_channel(pad_block_B, block_B,
                     full_size, full_size,
-                    hdr->tc.w, hdr->tc.h);
+                    hdr->hdr_data.tc.w,
+                    hdr->hdr_data.tc.h);
 
     /* No longer needed */
     free_2D((void *) pad_block_R, full_size, full_size);
diff --git a/epsilon/libmain.h b/epsilon/libmain.h
index b258940..fb9eafa 100644
--- a/epsilon/libmain.h
+++ b/epsilon/libmain.h
@@ -1,22 +1,23 @@
 /*
- * $Id: libmain.h,v 1.17 2007/06/15 18:09:16 simakov Exp $
+ * $Id: libmain.h,v 1.19 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
diff --git a/epsilon/list.c b/epsilon/list.c
index e9840bb..b336c4d 100644
--- a/epsilon/list.c
+++ b/epsilon/list.c
@@ -1,22 +1,23 @@
 /*
- * $Id: list.c,v 1.16 2007/05/20 13:19:12 simakov Exp $
+ * $Id: list.c,v 1.18 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
diff --git a/epsilon/list.h b/epsilon/list.h
index 35c50cf..e025c6f 100644
--- a/epsilon/list.h
+++ b/epsilon/list.h
@@ -1,22 +1,23 @@
 /*
- * $Id: list.h,v 1.17 2007/05/20 13:19:12 simakov Exp $
+ * $Id: list.h,v 1.19 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
diff --git a/epsilon/mem_alloc.c b/epsilon/mem_alloc.c
index 9d08b3b..04a9c33 100644
--- a/epsilon/mem_alloc.c
+++ b/epsilon/mem_alloc.c
@@ -1,22 +1,23 @@
 /*
- * $Id: mem_alloc.c,v 1.15 2007/05/20 13:19:12 simakov Exp $
+ * $Id: mem_alloc.c,v 1.17 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
diff --git a/epsilon/mem_alloc.h b/epsilon/mem_alloc.h
index e6df2c8..157217e 100644
--- a/epsilon/mem_alloc.h
+++ b/epsilon/mem_alloc.h
@@ -1,22 +1,23 @@
 /*
- * $Id: mem_alloc.h,v 1.14 2007/05/20 13:19:12 simakov Exp $
+ * $Id: mem_alloc.h,v 1.16 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
diff --git a/epsilon/merge_split.c b/epsilon/merge_split.c
index 3e5fc81..f18bfd0 100644
--- a/epsilon/merge_split.c
+++ b/epsilon/merge_split.c
@@ -1,22 +1,23 @@
 /*
- * $Id: merge_split.c,v 1.13 2007/05/20 13:19:12 simakov Exp $
+ * $Id: merge_split.c,v 1.15 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
diff --git a/epsilon/merge_split.h b/epsilon/merge_split.h
index 4147727..2d83af5 100644
--- a/epsilon/merge_split.h
+++ b/epsilon/merge_split.h
@@ -1,22 +1,23 @@
 /*
- * $Id: merge_split.h,v 1.15 2007/05/20 13:19:12 simakov Exp $
+ * $Id: merge_split.h,v 1.17 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
diff --git a/epsilon/msvc/inttypes.h b/epsilon/msvc/inttypes.h
new file mode 100644
index 0000000..5ae44bc
--- /dev/null
+++ b/epsilon/msvc/inttypes.h
@@ -0,0 +1,302 @@
+// ISO C9x  compliant inttypes.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
+//
+//  Copyright (c) 2006 Alexander Chemeris
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//   1. Redistributions of source code must retain the above copyright notice,
+//      this list of conditions and the following disclaimer.
+//
+//   2. Redistributions in binary form must reproduce the above copyright
+//      notice, this list of conditions and the following disclaimer in the
+//      documentation and/or other materials provided with the distribution.
+//
+//   3. The name of the author may be used to endorse or promote products
+//      derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_INTTYPES_H_ // [
+#define _MSC_INTTYPES_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include <stdint.h>
+
+// 7.8 Format conversion of integer types
+
+typedef struct {
+   intmax_t quot;
+   intmax_t rem;
+} imaxdiv_t;
+
+// 7.8.1 Macros for format specifiers
+
+// The fprintf macros for signed integers are:
+#define PRId8       "d"
+#define PRIi8       "i"
+#define PRIdLEAST8  "d"
+#define PRIiLEAST8  "i"
+#define PRIdFAST8   "d"
+#define PRIiFAST8   "i"
+
+#define PRId16       "hd"
+#define PRIi16       "hi"
+#define PRIdLEAST16  "hd"
+#define PRIiLEAST16  "hi"
+#define PRIdFAST16   "hd"
+#define PRIiFAST16   "hi"
+
+#define PRId32       "I32d"
+#define PRIi32       "I32i"
+#define PRIdLEAST32  "I32d"
+#define PRIiLEAST32  "I32i"
+#define PRIdFAST32   "I32d"
+#define PRIiFAST32   "I32i"
+
+#define PRId64       "I64d"
+#define PRIi64       "I64i"
+#define PRIdLEAST64  "I64d"
+#define PRIiLEAST64  "I64i"
+#define PRIdFAST64   "I64d"
+#define PRIiFAST64   "I64i"
+
+#define PRIdMAX     "I64d"
+#define PRIiMAX     "I64i"
+
+#define PRIdPTR     "Id"
+#define PRIiPTR     "Ii"
+
+// The fprintf macros for unsigned integers are:
+#define PRIo8       "o"
+#define PRIu8       "u"
+#define PRIx8       "x"
+#define PRIX8       "X"
+#define PRIoLEAST8  "o"
+#define PRIuLEAST8  "u"
+#define PRIxLEAST8  "x"
+#define PRIXLEAST8  "X"
+#define PRIoFAST8   "o"
+#define PRIuFAST8   "u"
+#define PRIxFAST8   "x"
+#define PRIXFAST8   "X"
+
+#define PRIo16       "ho"
+#define PRIu16       "hu"
+#define PRIx16       "hx"
+#define PRIX16       "hX"
+#define PRIoLEAST16  "ho"
+#define PRIuLEAST16  "hu"
+#define PRIxLEAST16  "hx"
+#define PRIXLEAST16  "hX"
+#define PRIoFAST16   "ho"
+#define PRIuFAST16   "hu"
+#define PRIxFAST16   "hx"
+#define PRIXFAST16   "hX"
+
+#define PRIo32       "I32o"
+#define PRIu32       "I32u"
+#define PRIx32       "I32x"
+#define PRIX32       "I32X"
+#define PRIoLEAST32  "I32o"
+#define PRIuLEAST32  "I32u"
+#define PRIxLEAST32  "I32x"
+#define PRIXLEAST32  "I32X"
+#define PRIoFAST32   "I32o"
+#define PRIuFAST32   "I32u"
+#define PRIxFAST32   "I32x"
+#define PRIXFAST32   "I32X"
+
+#define PRIo64       "I64o"
+#define PRIu64       "I64u"
+#define PRIx64       "I64x"
+#define PRIX64       "I64X"
+#define PRIoLEAST64  "I64o"
+#define PRIuLEAST64  "I64u"
+#define PRIxLEAST64  "I64x"
+#define PRIXLEAST64  "I64X"
+#define PRIoFAST64   "I64o"
+#define PRIuFAST64   "I64u"
+#define PRIxFAST64   "I64x"
+#define PRIXFAST64   "I64X"
+
+#define PRIoMAX     "I64o"
+#define PRIuMAX     "I64u"
+#define PRIxMAX     "I64x"
+#define PRIXMAX     "I64X"
+
+#define PRIoPTR     "Io"
+#define PRIuPTR     "Iu"
+#define PRIxPTR     "Ix"
+#define PRIXPTR     "IX"
+
+// The fscanf macros for signed integers are:
+#define SCNd8       "d"
+#define SCNi8       "i"
+#define SCNdLEAST8  "d"
+#define SCNiLEAST8  "i"
+#define SCNdFAST8   "d"
+#define SCNiFAST8   "i"
+
+#define SCNd16       "hd"
+#define SCNi16       "hi"
+#define SCNdLEAST16  "hd"
+#define SCNiLEAST16  "hi"
+#define SCNdFAST16   "hd"
+#define SCNiFAST16   "hi"
+
+#define SCNd32       "ld"
+#define SCNi32       "li"
+#define SCNdLEAST32  "ld"
+#define SCNiLEAST32  "li"
+#define SCNdFAST32   "ld"
+#define SCNiFAST32   "li"
+
+#define SCNd64       "I64d"
+#define SCNi64       "I64i"
+#define SCNdLEAST64  "I64d"
+#define SCNiLEAST64  "I64i"
+#define SCNdFAST64   "I64d"
+#define SCNiFAST64   "I64i"
+
+#define SCNdMAX     "I64d"
+#define SCNiMAX     "I64i"
+
+#ifdef _WIN64 // [
+#  define SCNdPTR     "I64d"
+#  define SCNiPTR     "I64i"
+#else  // _WIN64 ][
+#  define SCNdPTR     "ld"
+#  define SCNiPTR     "li"
+#endif  // _WIN64 ]
+
+// The fscanf macros for unsigned integers are:
+#define SCNo8       "o"
+#define SCNu8       "u"
+#define SCNx8       "x"
+#define SCNX8       "X"
+#define SCNoLEAST8  "o"
+#define SCNuLEAST8  "u"
+#define SCNxLEAST8  "x"
+#define SCNXLEAST8  "X"
+#define SCNoFAST8   "o"
+#define SCNuFAST8   "u"
+#define SCNxFAST8   "x"
+#define SCNXFAST8   "X"
+
+
+#define SCNo16       "ho"
+#define SCNu16       "hu"
+#define SCNx16       "hx"
+#define SCNX16       "hX"
+#define SCNoLEAST16  "ho"
+#define SCNuLEAST16  "hu"
+#define SCNxLEAST16  "hx"
+#define SCNXLEAST16  "hX"
+#define SCNoFAST16   "ho"
+#define SCNuFAST16   "hu"
+#define SCNxFAST16   "hx"
+#define SCNXFAST16   "hX"
+
+#define SCNo32       "lo"
+#define SCNu32       "lu"
+#define SCNx32       "lx"
+#define SCNX32       "lX"
+#define SCNoLEAST32  "lo"
+#define SCNuLEAST32  "lu"
+#define SCNxLEAST32  "lx"
+#define SCNXLEAST32  "lX"
+#define SCNoFAST32   "lo"
+#define SCNuFAST32   "lu"
+#define SCNxFAST32   "lx"
+#define SCNXFAST32   "lX"
+
+#define SCNo64       "I64o"
+#define SCNu64       "I64u"
+#define SCNx64       "I64x"
+#define SCNX64       "I64X"
+#define SCNoLEAST64  "I64o"
+#define SCNuLEAST64  "I64u"
+#define SCNxLEAST64  "I64x"
+#define SCNXLEAST64  "I64X"
+#define SCNoFAST64   "I64o"
+#define SCNuFAST64   "I64u"
+#define SCNxFAST64   "I64x"
+#define SCNXFAST64   "I64X"
+
+#define SCNoMAX     "I64o"
+#define SCNuMAX     "I64u"
+#define SCNxMAX     "I64x"
+#define SCNXMAX     "I64X"
+
+#ifdef _WIN64 // [
+#  define SCNoPTR     "I64o"
+#  define SCNuPTR     "I64u"
+#  define SCNxPTR     "I64x"
+#  define SCNXPTR     "I64X"
+#else  // _WIN64 ][
+#  define SCNoPTR     "lo"
+#  define SCNuPTR     "lu"
+#  define SCNxPTR     "lx"
+#  define SCNXPTR     "lX"
+#endif  // _WIN64 ]
+
+// 7.8.2 Functions for greatest-width integer types
+
+// 7.8.2.1 The imaxabs function
+#define imaxabs _abs64
+
+// 7.8.2.2 The imaxdiv function
+
+// This is modified version of div() function from Microsoft's div.c found
+// in %MSVC.NET%\crt\src\div.c
+#ifdef STATIC_IMAXDIV // [
+static
+#else // STATIC_IMAXDIV ][
+_inline
+#endif // STATIC_IMAXDIV ]
+imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
+{
+   imaxdiv_t result;
+
+   result.quot = numer / denom;
+   result.rem = numer % denom;
+
+   if (numer < 0 && result.rem > 0) {
+      // did division wrong; must fix up
+      ++result.quot;
+      result.rem -= denom;
+   }
+
+   return result;
+}
+
+// 7.8.2.3 The strtoimax and strtoumax functions
+#define strtoimax _strtoi64
+#define strtoumax _strtoui64
+
+// 7.8.2.4 The wcstoimax and wcstoumax functions
+#define wcstoimax _wcstoi64
+#define wcstoumax _wcstoui64
+
+
+#endif // _MSC_INTTYPES_H_ ]
diff --git a/epsilon/msvc/stdint.h b/epsilon/msvc/stdint.h
new file mode 100644
index 0000000..59d0673
--- /dev/null
+++ b/epsilon/msvc/stdint.h
@@ -0,0 +1,247 @@
+// ISO C9x  compliant stdint.h for Microsoft Visual Studio
+// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 
+// 
+//  Copyright (c) 2006-2008 Alexander Chemeris
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// 
+//   1. Redistributions of source code must retain the above copyright notice,
+//      this list of conditions and the following disclaimer.
+// 
+//   2. Redistributions in binary form must reproduce the above copyright
+//      notice, this list of conditions and the following disclaimer in the
+//      documentation and/or other materials provided with the distribution.
+// 
+//   3. The name of the author may be used to endorse or promote products
+//      derived from this software without specific prior written permission.
+// 
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// 
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _MSC_VER // [
+#error "Use this header only with Microsoft Visual C++ compilers!"
+#endif // _MSC_VER ]
+
+#ifndef _MSC_STDINT_H_ // [
+#define _MSC_STDINT_H_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#include <limits.h>
+
+// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
+// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
+// or compiler give many errors like this:
+//   error C2733: second C linkage of overloaded function 'wmemchr' not allowed
+#ifdef __cplusplus
+extern "C" {
+#endif
+#  include <wchar.h>
+#ifdef __cplusplus
+}
+#endif
+
+// Define _W64 macros to mark types changing their size, like intptr_t.
+#ifndef _W64
+#  if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
+#     define _W64 __w64
+#  else
+#     define _W64
+#  endif
+#endif
+
+
+// 7.18.1 Integer types
+
+// 7.18.1.1 Exact-width integer types
+
+// Visual Studio 6 and Embedded Visual C++ 4 doesn't
+// realize that, e.g. char has the same size as __int8
+// so we give up on __intX for them.
+#if (_MSC_VER < 1300)
+   typedef signed char       int8_t;
+   typedef signed short      int16_t;
+   typedef signed int        int32_t;
+   typedef unsigned char     uint8_t;
+   typedef unsigned short    uint16_t;
+   typedef unsigned int      uint32_t;
+#else
+   typedef signed __int8     int8_t;
+   typedef signed __int16    int16_t;
+   typedef signed __int32    int32_t;
+   typedef unsigned __int8   uint8_t;
+   typedef unsigned __int16  uint16_t;
+   typedef unsigned __int32  uint32_t;
+#endif
+typedef signed __int64       int64_t;
+typedef unsigned __int64     uint64_t;
+
+
+// 7.18.1.2 Minimum-width integer types
+typedef int8_t    int_least8_t;
+typedef int16_t   int_least16_t;
+typedef int32_t   int_least32_t;
+typedef int64_t   int_least64_t;
+typedef uint8_t   uint_least8_t;
+typedef uint16_t  uint_least16_t;
+typedef uint32_t  uint_least32_t;
+typedef uint64_t  uint_least64_t;
+
+// 7.18.1.3 Fastest minimum-width integer types
+typedef int8_t    int_fast8_t;
+typedef int16_t   int_fast16_t;
+typedef int32_t   int_fast32_t;
+typedef int64_t   int_fast64_t;
+typedef uint8_t   uint_fast8_t;
+typedef uint16_t  uint_fast16_t;
+typedef uint32_t  uint_fast32_t;
+typedef uint64_t  uint_fast64_t;
+
+// 7.18.1.4 Integer types capable of holding object pointers
+#ifdef _WIN64 // [
+   typedef signed __int64    intptr_t;
+   typedef unsigned __int64  uintptr_t;
+#else // _WIN64 ][
+   typedef _W64 signed int   intptr_t;
+   typedef _W64 unsigned int uintptr_t;
+#endif // _WIN64 ]
+
+// 7.18.1.5 Greatest-width integer types
+typedef int64_t   intmax_t;
+typedef uint64_t  uintmax_t;
+
+
+// 7.18.2 Limits of specified-width integer types
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [   See footnote 220 at page 257 and footnote 221 at page 259
+
+// 7.18.2.1 Limits of exact-width integer types
+#define INT8_MIN     ((int8_t)_I8_MIN)
+#define INT8_MAX     _I8_MAX
+#define INT16_MIN    ((int16_t)_I16_MIN)
+#define INT16_MAX    _I16_MAX
+#define INT32_MIN    ((int32_t)_I32_MIN)
+#define INT32_MAX    _I32_MAX
+#define INT64_MIN    ((int64_t)_I64_MIN)
+#define INT64_MAX    _I64_MAX
+#define UINT8_MAX    _UI8_MAX
+#define UINT16_MAX   _UI16_MAX
+#define UINT32_MAX   _UI32_MAX
+#define UINT64_MAX   _UI64_MAX
+
+// 7.18.2.2 Limits of minimum-width integer types
+#define INT_LEAST8_MIN    INT8_MIN
+#define INT_LEAST8_MAX    INT8_MAX
+#define INT_LEAST16_MIN   INT16_MIN
+#define INT_LEAST16_MAX   INT16_MAX
+#define INT_LEAST32_MIN   INT32_MIN
+#define INT_LEAST32_MAX   INT32_MAX
+#define INT_LEAST64_MIN   INT64_MIN
+#define INT_LEAST64_MAX   INT64_MAX
+#define UINT_LEAST8_MAX   UINT8_MAX
+#define UINT_LEAST16_MAX  UINT16_MAX
+#define UINT_LEAST32_MAX  UINT32_MAX
+#define UINT_LEAST64_MAX  UINT64_MAX
+
+// 7.18.2.3 Limits of fastest minimum-width integer types
+#define INT_FAST8_MIN    INT8_MIN
+#define INT_FAST8_MAX    INT8_MAX
+#define INT_FAST16_MIN   INT16_MIN
+#define INT_FAST16_MAX   INT16_MAX
+#define INT_FAST32_MIN   INT32_MIN
+#define INT_FAST32_MAX   INT32_MAX
+#define INT_FAST64_MIN   INT64_MIN
+#define INT_FAST64_MAX   INT64_MAX
+#define UINT_FAST8_MAX   UINT8_MAX
+#define UINT_FAST16_MAX  UINT16_MAX
+#define UINT_FAST32_MAX  UINT32_MAX
+#define UINT_FAST64_MAX  UINT64_MAX
+
+// 7.18.2.4 Limits of integer types capable of holding object pointers
+#ifdef _WIN64 // [
+#  define INTPTR_MIN   INT64_MIN
+#  define INTPTR_MAX   INT64_MAX
+#  define UINTPTR_MAX  UINT64_MAX
+#else // _WIN64 ][
+#  define INTPTR_MIN   INT32_MIN
+#  define INTPTR_MAX   INT32_MAX
+#  define UINTPTR_MAX  UINT32_MAX
+#endif // _WIN64 ]
+
+// 7.18.2.5 Limits of greatest-width integer types
+#define INTMAX_MIN   INT64_MIN
+#define INTMAX_MAX   INT64_MAX
+#define UINTMAX_MAX  UINT64_MAX
+
+// 7.18.3 Limits of other integer types
+
+#ifdef _WIN64 // [
+#  define PTRDIFF_MIN  _I64_MIN
+#  define PTRDIFF_MAX  _I64_MAX
+#else  // _WIN64 ][
+#  define PTRDIFF_MIN  _I32_MIN
+#  define PTRDIFF_MAX  _I32_MAX
+#endif  // _WIN64 ]
+
+#define SIG_ATOMIC_MIN  INT_MIN
+#define SIG_ATOMIC_MAX  INT_MAX
+
+#ifndef SIZE_MAX // [
+#  ifdef _WIN64 // [
+#     define SIZE_MAX  _UI64_MAX
+#  else // _WIN64 ][
+#     define SIZE_MAX  _UI32_MAX
+#  endif // _WIN64 ]
+#endif // SIZE_MAX ]
+
+// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
+#ifndef WCHAR_MIN // [
+#  define WCHAR_MIN  0
+#endif  // WCHAR_MIN ]
+#ifndef WCHAR_MAX // [
+#  define WCHAR_MAX  _UI16_MAX
+#endif  // WCHAR_MAX ]
+
+#define WINT_MIN  0
+#define WINT_MAX  _UI16_MAX
+
+#endif // __STDC_LIMIT_MACROS ]
+
+
+// 7.18.4 Limits of other integer types
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [   See footnote 224 at page 260
+
+// 7.18.4.1 Macros for minimum-width integer constants
+
+#define INT8_C(val)  val##i8
+#define INT16_C(val) val##i16
+#define INT32_C(val) val##i32
+#define INT64_C(val) val##i64
+
+#define UINT8_C(val)  val##ui8
+#define UINT16_C(val) val##ui16
+#define UINT32_C(val) val##ui32
+#define UINT64_C(val) val##ui64
+
+// 7.18.4.2 Macros for greatest-width integer constants
+#define INTMAX_C   INT64_C
+#define UINTMAX_C  UINT64_C
+
+#endif // __STDC_CONSTANT_MACROS ]
+
+
+#endif // _MSC_STDINT_H_ ]
diff --git a/epsilon/pad.c b/epsilon/pad.c
index 0e16ffd..38ea1b9 100644
--- a/epsilon/pad.c
+++ b/epsilon/pad.c
@@ -1,22 +1,23 @@
 /*
- * $Id: pad.c,v 1.13 2007/05/20 13:19:12 simakov Exp $
+ * $Id: pad.c,v 1.15 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
diff --git a/epsilon/pad.h b/epsilon/pad.h
index d6312a8..e44adeb 100644
--- a/epsilon/pad.h
+++ b/epsilon/pad.h
@@ -1,22 +1,23 @@
 /*
- * $Id: pad.h,v 1.15 2007/05/20 13:19:12 simakov Exp $
+ * $Id: pad.h,v 1.17 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
diff --git a/epsilon/resample.c b/epsilon/resample.c
index 8374047..3dd4f6b 100644
--- a/epsilon/resample.c
+++ b/epsilon/resample.c
@@ -1,22 +1,23 @@
 /*
- * $Id: resample.c,v 1.9 2007/05/20 13:19:12 simakov Exp $
+ * $Id: resample.c,v 1.11 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
diff --git a/epsilon/resample.h b/epsilon/resample.h
index 120c9b8..65ad0ef 100644
--- a/epsilon/resample.h
+++ b/epsilon/resample.h
@@ -1,22 +1,23 @@
 /*
- * $Id: resample.h,v 1.12 2007/05/20 13:19:12 simakov Exp $
+ * $Id: resample.h,v 1.14 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
diff --git a/epsilon/speck.c b/epsilon/speck.c
index dd1304d..23674b4 100644
--- a/epsilon/speck.c
+++ b/epsilon/speck.c
@@ -1,22 +1,23 @@
 /*
- * $Id: speck.c,v 1.58 2008/03/22 18:04:23 simakov Exp $
+ * $Id: speck.c,v 1.62 2010/04/05 05:01:04 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
@@ -259,6 +260,12 @@ local int significance_test(pixel_set *set, int threshold,
             break;
         }
     }
+
+    /* This code is unreachable, just to be on a safe side */
+    assert(0);
+
+    /* Fake return disables 'not all control paths return a value' warning */
+    return -1;
 }
 
 local void select_part_type(pixel_set *set)
@@ -1112,7 +1119,6 @@ void speck_decode(unsigned char *buf, int buf_size,
         threshold >>= 1;
     }
 
-mem_free:
     free(bb);
     free(I);
     free_LIS_slots(LIS_slots, channel_size);
diff --git a/epsilon/speck.h b/epsilon/speck.h
index 97a496f..42e468e 100644
--- a/epsilon/speck.h
+++ b/epsilon/speck.h
@@ -1,22 +1,23 @@
 /*
- * $Id: speck.h,v 1.48 2007/05/20 13:19:12 simakov Exp $
+ * $Id: speck.h,v 1.50 2010/02/05 23:50:22 simakov Exp $
  *
  * EPSILON - wavelet image compression library.
- * Copyright (C) 2006-2007 Alexander Simakov, <xander at entropyware.info>
+ * Copyright (C) 2006,2007,2010 Alexander Simakov, <xander at entropyware.info>
  *
- * 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 of the License, or
+ * This file is part of EPSILON
+ *
+ * EPSILON is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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,
+ * EPSILON 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.
+ * GNU Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with EPSILON.  If not, see <http://www.gnu.org/licenses/>.
  *
  * http://epsilon-project.sourceforge.net
  */
diff --git a/headers/rasterlite.h b/headers/rasterlite.h
index f87e25a..c1959bc 100644
--- a/headers/rasterlite.h
+++ b/headers/rasterlite.h
@@ -3,23 +3,23 @@
 /
 / public RasterLite declarations
 /
-/ version 1.0, 2009 June 1
+/ version 1.1, 2010 April 27
 /
 / Author: Sandro Furieri a.furieri at lqt.it
 /
 / Copyright (C) 2009  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
+/    it under the terms of the GNU Lesser 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.
+/    GNU Lesser General Public License for more details.
 /
-/    You should have received a copy of the GNU General Public License
+/    You should have received a copy of the GNU Lesser General Public License
 /    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 /
 */
@@ -39,6 +39,10 @@ extern "C"
 #endif
 
 #define GAIA_RGB_ARRAY	1001
+#define GAIA_RGBA_ARRAY	1002
+#define GAIA_ARGB_ARRAY	1003
+#define GAIA_BGR_ARRAY	1004
+#define GAIA_BGRA_ARRAY	1005
 
 #define RASTERLITE_OK	0
 #define RASTERLITE_ERROR	1
@@ -93,6 +97,35 @@ extern "C"
 						       int quality_factor,
 						       void **raster,
 						       int *size);
+    RASTERLITE_DECLARE int rasterliteGetRawImage (void *handle, double cx,
+						  double cy, double pixel_size,
+						  int width, int height,
+						  int raw_format,
+						  void **raster, int *size);
+    RASTERLITE_DECLARE int rasterliteGetRawImage2 (void *handle, double cx,
+						   double cy,
+						   double pixel_x_size,
+						   double pixel_y_size,
+						   int width, int height,
+						   int raw_format,
+						   void **raster, int *size);
+    RASTERLITE_DECLARE int rasterliteGetRawImageByRect (void *handle, double x1,
+							double y1, double x2,
+							double y2,
+							double pixel_size,
+							int width, int height,
+							int raw_format,
+							void **raster,
+							int *size);
+    RASTERLITE_DECLARE int rasterliteGetRawImageByRect2 (void *handle,
+							 double x1, double y1,
+							 double x2, double y2,
+							 double pixel_x_size,
+							 double pixel_y_size,
+							 int width, int height,
+							 int raw_format,
+							 void **raster,
+							 int *size);
     RASTERLITE_DECLARE int rasterliteIsError (void *handle);
     RASTERLITE_DECLARE const char *rasterliteGetPath (void *handle);
     RASTERLITE_DECLARE const char *rasterliteGetTablePrefix (void *handle);
@@ -131,6 +164,102 @@ extern "C"
 						    sqlite3_stmt ** stmt,
 						    int *use_rtree);
 
+/*
+/ utility functions returning a Raw image
+*/
+    RASTERLITE_DECLARE int rasterliteJpegBlobToRawImage (const void *blob,
+							 int blob_size,
+							 int raw_format,
+							 void **raw, int *width,
+							 int *height);
+    RASTERLITE_DECLARE int rasterlitePngBlobToRawImage (const void *blob,
+							int blob_size,
+							int raw_format,
+							void **raw, int *width,
+							int *height);
+    RASTERLITE_DECLARE int rasterliteGifBlobToRawImage (const void *blob,
+							int blob_size,
+							int raw_format,
+							void **raw, int *width,
+							int *height);
+    RASTERLITE_DECLARE int rasterliteTiffBlobToRawImage (const void *blob,
+							 int blob_size,
+							 int raw_format,
+							 void **raw, int *width,
+							 int *height);
+    RASTERLITE_DECLARE int rasterliteWaveletBlobToRawImage (const void *blob,
+							    int blob_size,
+							    int raw_format,
+							    void **raw,
+							    int *width,
+							    int *height);
+
+
+/*
+/ utility functions generating an image file from a Raw Image
+*/
+    RASTERLITE_DECLARE int rasterliteRawImageToJpegFile (const void *raw,
+							 int raw_format,
+							 int width, int height,
+							 const char *path,
+							 int quality);
+    RASTERLITE_DECLARE int rasterliteRawImageToPngFile (const void *raw,
+							int raw_format,
+							int width, int height,
+							const char *path);
+    RASTERLITE_DECLARE int rasterliteRawImageToGifFile (const void *raw,
+							int raw_format,
+							int width, int height,
+							const char *path);
+    RASTERLITE_DECLARE int rasterliteRawImageToGeoTiffFile (const void *raw,
+							    int raw_format,
+							    int width,
+							    int height,
+							    const char *path,
+							    double x_size,
+							    double y_size,
+							    double xllcorner,
+							    double yllcorner,
+							    const char
+							    *proj4text);
+
+/*
+/ utility functions generating an image mem-buffer from a Raw Image
+*/
+    RASTERLITE_DECLARE unsigned char *rasterliteRawImageToJpegMemBuf (const void
+								      *raw,
+								      int
+								      raw_format,
+								      int width,
+								      int
+								      height,
+								      int *size,
+								      int
+								      quality);
+    RASTERLITE_DECLARE unsigned char *rasterliteRawImageToPngMemBuf (const void
+								     *raw,
+								     int
+								     raw_format,
+								     int width,
+								     int height,
+								     int *size);
+    RASTERLITE_DECLARE unsigned char *rasterliteRawImageToGifMemBuf (const void
+								     *raw,
+								     int
+								     raw_format,
+								     int width,
+								     int height,
+								     int *size);
+    RASTERLITE_DECLARE unsigned char *rasterliteRawImageToTiffMemBuf (const void
+								      *raw,
+								      int
+								      raw_format,
+								      int width,
+								      int
+								      height,
+								      int
+								      *size);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/headers/rasterlite_internals.h b/headers/rasterlite_internals.h
index d237e6b..57fa287 100644
--- a/headers/rasterlite_internals.h
+++ b/headers/rasterlite_internals.h
@@ -3,23 +3,23 @@
 /
 / internal declarations
 /
-/ version 1.0, 2009 June 1
+/ version 1.1, 2010 Aprile 27
 /
 / Author: Sandro Furieri a.furieri at lqt.it
 /
 / Copyright (C) 2009  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
+/    it under the terms of the GNU Lesser 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.
+/    GNU Lesser General Public License for more details.
 /
-/    You should have received a copy of the GNU General Public License
+/    You should have received a copy of the GNU Lesser General Public License
 /    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 /
 */
@@ -47,6 +47,9 @@
 #define STRATEGY_RTREE	1
 #define STRATEGY_PLAIN	2
 
+#define RASTERLITE_TRUE	-1
+#define RASTERLITE_FALSE	-2
+
 #define true_color(r, g, b) (((r) << 16) + ((g) << 8) + (b))
 #define image_set_pixel(img, x, y, color) 	img->pixels[y][x] = color
 #define true_color_get_red(c) (((c) & 0xFF0000) >> 16)
@@ -182,39 +185,63 @@ typedef struct raster_lite_image
     int color_space;
 } rasterliteImage;
 
-typedef rasterliteImage *rasterliteImagePrt;
+typedef rasterliteImage *rasterliteImagePtr;
 
-extern rasterliteImagePrt image_create (int sx, int sy);
-extern void image_destroy (rasterliteImagePrt img);
-extern void image_fill (const rasterliteImagePrt img, int color);
-extern void make_thumbnail (const rasterliteImagePrt thumbnail,
-			    const rasterliteImagePrt image);
-extern void image_resize (const rasterliteImagePrt dst,
-			  const rasterliteImagePrt src);
+extern rasterliteImagePtr image_create (int sx, int sy);
+extern void image_destroy (rasterliteImagePtr img);
+extern void image_fill (const rasterliteImagePtr img, int color);
+extern void make_thumbnail (const rasterliteImagePtr thumbnail,
+			    const rasterliteImagePtr image);
+extern void image_resize (const rasterliteImagePtr dst,
+			  const rasterliteImagePtr src);
 
-extern void *image_to_jpeg (const rasterliteImagePrt img, int *size,
+extern void *image_to_jpeg (const rasterliteImagePtr img, int *size,
 			    int quality);
-extern void *image_to_jpeg_grayscale (const rasterliteImagePrt img, int *size,
+extern void *image_to_jpeg_grayscale (const rasterliteImagePtr img, int *size,
 				      int quality);
-extern void *image_to_wavelet (const rasterliteImagePrt img, int *size,
+extern void *image_to_wavelet (const rasterliteImagePtr img, int *size,
 			       int ratio);
-extern void *image_to_wavelet_grayscale (const rasterliteImagePrt img,
+extern void *image_to_wavelet_grayscale (const rasterliteImagePtr img,
 					 int *size, int ratio);
-extern void *image_to_png_palette (const rasterliteImagePrt img, int *size);
-extern void *image_to_png_grayscale (const rasterliteImagePrt img, int *size);
-extern void *image_to_png_rgb (const rasterliteImagePrt img, int *size);
-extern void *image_to_gif (const rasterliteImagePrt img, int *size);
-extern void *image_to_tiff_fax4 (const rasterliteImagePrt img, int *size);
-extern void *image_to_tiff_palette (const rasterliteImagePrt img, int *size);
-extern void *image_to_tiff_grayscale (const rasterliteImagePrt img, int *size);
-extern void *image_to_tiff_rgb (const rasterliteImagePrt img, int *size);
-extern void *image_to_rgb_array (const rasterliteImagePrt img, int *size);
+extern void *image_to_png_palette (const rasterliteImagePtr img, int *size);
+extern void *image_to_png_grayscale (const rasterliteImagePtr img, int *size);
+extern void *image_to_png_rgb (const rasterliteImagePtr img, int *size);
+extern void *image_to_gif (const rasterliteImagePtr img, int *size);
+extern void *image_to_tiff_fax4 (const rasterliteImagePtr img, int *size);
+extern void *image_to_tiff_palette (const rasterliteImagePtr img, int *size);
+extern void *image_to_tiff_grayscale (const rasterliteImagePtr img, int *size);
+extern void *image_to_tiff_rgb (const rasterliteImagePtr img, int *size);
+
+extern void *image_to_rgb_array (const rasterliteImagePtr img, int *size);
+extern void *image_to_rgba_array (int transparent_color,
+				  const rasterliteImagePtr img, int *size);
+extern void *image_to_argb_array (int transparent_color,
+				  const rasterliteImagePtr img, int *size);
+extern void *image_to_bgr_array (const rasterliteImagePtr img, int *size);
+extern void *image_to_bgra_array (int transparent_color,
+				  const rasterliteImagePtr img, int *size);
+
+extern rasterliteImagePtr image_from_rgb_array (const void *raw, int width,
+						int height);
+extern rasterliteImagePtr image_from_rgba_array (const void *raw, int width,
+						 int height);
+extern rasterliteImagePtr image_from_argb_array (const void *raw, int width,
+						 int height);
+extern rasterliteImagePtr image_from_bgr_array (const void *raw, int width,
+						int height);
+extern rasterliteImagePtr image_from_bgra_array (const void *raw, int width,
+						 int height);
+
+extern rasterliteImagePtr image_from_jpeg (int size, const void *data);
+extern rasterliteImagePtr image_from_png (int size, const void *data);
+extern rasterliteImagePtr image_from_gif (int size, const void *data);
+extern rasterliteImagePtr image_from_tiff (int size, const void *data);
+extern rasterliteImagePtr image_from_wavelet (int size, const void *data);
 
-extern rasterliteImagePrt image_from_jpeg (int size, const void *data);
-extern rasterliteImagePrt image_from_png (int size, const void *data);
-extern rasterliteImagePrt image_from_gif (int size, const void *data);
-extern rasterliteImagePrt image_from_tiff (int size, const void *data);
-extern rasterliteImagePrt image_from_wavelet (int size, const void *data);
+extern int is_image_monochrome (const rasterliteImagePtr img);
+extern int is_image_grayscale (const rasterliteImagePtr img);
+extern int is_image_palette256 (const rasterliteImagePtr img);
+extern void image_resample_as_palette256 (const rasterliteImagePtr img);
 
 extern int write_geotiff (const char *path, const void *raster, int size,
 			  double xsize, double ysize, double xllcorner,
diff --git a/lib/Makefile.am b/lib/Makefile.am
index e39c528..ce5b911 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -10,6 +10,8 @@ lib_LTLIBRARIES = librasterlite.la
 librasterlite_la_SOURCES = \
      rasterlite_io.c \
      rasterlite_image.c \
+     rasterlite_aux.c \
+     rasterlite_quantize.c \
      rasterlite_gif.c \
      rasterlite_png.c \
      rasterlite_jpeg.c \
@@ -17,7 +19,7 @@ librasterlite_la_SOURCES = \
      rasterlite_wavelet.c \
      rasterlite.c
 
-librasterlite_la_LDFLAGS = -version-info 1:0:0 -no-undefined
+librasterlite_la_LDFLAGS = -version-info 1:0:1 -no-undefined
 
 librasterlite_la_LIBADD = \
 	../epsilon/libepsilon.la \
diff --git a/lib/Makefile.in b/lib/Makefile.in
index 2c67ff4..0a7cd28 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -51,8 +51,9 @@ libLTLIBRARIES_INSTALL = $(INSTALL)
 LTLIBRARIES = $(lib_LTLIBRARIES)
 librasterlite_la_DEPENDENCIES = ../epsilon/libepsilon.la
 am_librasterlite_la_OBJECTS = rasterlite_io.lo rasterlite_image.lo \
-	rasterlite_gif.lo rasterlite_png.lo rasterlite_jpeg.lo \
-	rasterlite_tiff.lo rasterlite_wavelet.lo rasterlite.lo
+	rasterlite_aux.lo rasterlite_quantize.lo rasterlite_gif.lo \
+	rasterlite_png.lo rasterlite_jpeg.lo rasterlite_tiff.lo \
+	rasterlite_wavelet.lo rasterlite.lo
 librasterlite_la_OBJECTS = $(am_librasterlite_la_OBJECTS)
 librasterlite_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@@ -192,6 +193,8 @@ lib_LTLIBRARIES = librasterlite.la
 librasterlite_la_SOURCES = \
      rasterlite_io.c \
      rasterlite_image.c \
+     rasterlite_aux.c \
+     rasterlite_quantize.c \
      rasterlite_gif.c \
      rasterlite_png.c \
      rasterlite_jpeg.c \
@@ -199,7 +202,7 @@ librasterlite_la_SOURCES = \
      rasterlite_wavelet.c \
      rasterlite.c
 
-librasterlite_la_LDFLAGS = -version-info 1:0:0 -no-undefined
+librasterlite_la_LDFLAGS = -version-info 1:0:1 -no-undefined
 librasterlite_la_LIBADD = \
 	../epsilon/libepsilon.la \
 	-lgeotiff -ltiff -ljpeg -lpng -lspatialite -lproj
@@ -274,11 +277,13 @@ distclean-compile:
 	-rm -f *.tab.c
 
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rasterlite.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rasterlite_aux.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rasterlite_gif.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rasterlite_image.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rasterlite_io.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rasterlite_jpeg.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rasterlite_png.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rasterlite_quantize.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rasterlite_tiff.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rasterlite_wavelet.Plo at am__quote@
 
diff --git a/lib/rasterlite.c b/lib/rasterlite.c
index 197e1cd..b6e72af 100644
--- a/lib/rasterlite.c
+++ b/lib/rasterlite.c
@@ -3,23 +3,23 @@
 /
 / the RasterLite library core 
 /
-/ version 1.0, 2009 June 1
+/ version 1.1, 2010 April 27
 /
 / Author: Sandro Furieri a.furieri at lqt.it
 /
 / Copyright (C) 2009  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
+/    it under the terms of the GNU Lesser 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.
+/    GNU Lesser General Public License for more details.
 /
-/    You should have received a copy of the GNU General Public License
+/    You should have received a copy of the GNU Lesser General Public License
 /    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 /
 */
@@ -44,6 +44,10 @@
 #include "rasterlite.h"
 #include "rasterlite_internals.h"
 
+#ifdef _WIN32
+#define strcasecmp	_stricmp
+#endif /* not WIN32 */
+
 static void
 reset_error (rasterlitePtr handle)
 {
@@ -171,7 +175,7 @@ fetch_resolutions (rasterlitePtr handle)
 		/* retrieving query values */
 		pixel_x_size[levels] = sqlite3_column_double (stmt, 0);
 		pixel_y_size[levels] = sqlite3_column_double (stmt, 1);
-		tile_count[levels] = sqlite3_column_double (stmt, 2);
+		tile_count[levels] = sqlite3_column_int (stmt, 2);
 		levels++;
 	    }
 	  else
@@ -720,7 +724,7 @@ best_raster_resolution (rasterlitePtr handle, double requested_ratio_x,
 }
 
 static void
-mark_gray_rectangle (rasterliteImagePrt output, int base_x, int base_y,
+mark_gray_rectangle (rasterliteImagePtr output, int base_x, int base_y,
 		     int width, int height)
 {
 /* marking a gray rectangle */
@@ -753,7 +757,7 @@ mark_gray_rectangle (rasterliteImagePrt output, int base_x, int base_y,
 }
 
 static void
-copy_rectangle (rasterliteImagePrt output, rasterliteImagePrt input,
+copy_rectangle (rasterliteImagePtr output, rasterliteImagePtr input,
 		int transparent_color, int base_x, int base_y)
 {
 /* copying a raster rectangle */
@@ -826,7 +830,7 @@ rasterliteGetRaster2 (void *ext_handle, double cx, double cy,
     double max_x = cx + (map_width / 2.0);
     double min_y = cy - (map_height / 2.0);
     double max_y = cy + (map_height / 2.0);
-    rasterliteImagePrt output = NULL;
+    rasterliteImagePtr output = NULL;
     reset_error (handle);
     if (handle->handle == NULL || handle->stmt_rtree == NULL
 	|| handle->stmt_plain == NULL)
@@ -892,7 +896,7 @@ rasterliteGetRaster2 (void *ext_handle, double cx, double cy,
 	    {
 		/* retrieving query values */
 		gaiaGeomCollPtr geom = NULL;
-		rasterliteImagePrt img = NULL;
+		rasterliteImagePtr img = NULL;
 		if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
 		  {
 		      /* fetching Geometry */
@@ -948,7 +952,7 @@ rasterliteGetRaster2 (void *ext_handle, double cx, double cy,
 				;
 			    else
 			      {
-				  rasterliteImagePrt img2 = img;
+				  rasterliteImagePtr img2 = img;
 				  img = image_create (new_width, new_height);
 				  image_resize (img, img2);
 				  image_destroy (img2);
@@ -1146,6 +1150,332 @@ rasterliteGetRasterByRect (void *handle, double x1, double y1, double x2,
 }
 
 RASTERLITE_DECLARE int
+rasterliteGetRawImage2 (void *ext_handle, double cx, double cy,
+			double ext_pixel_x_size, double ext_pixel_y_size,
+			int width, int height, int raw_format, void **raster,
+			int *size)
+{
+/* trying to build the required RAW raster image */
+    rasterlitePtr handle = (rasterlitePtr) ext_handle;
+    int raster_size = 0;
+    void *tmp_raster = NULL;
+    char error[1024];
+    int ret;
+    double pixel_x_size;
+    double pixel_y_size;
+    int strategy;
+    sqlite3_stmt *stmt;
+    double map_width = (double) width * ext_pixel_x_size;
+    double map_height = (double) height * ext_pixel_y_size;
+    double min_x = cx - (map_width / 2.0);
+    double max_x = cx + (map_width / 2.0);
+    double min_y = cy - (map_height / 2.0);
+    double max_y = cy + (map_height / 2.0);
+    rasterliteImagePtr output = NULL;
+    reset_error (handle);
+    if (handle->handle == NULL || handle->stmt_rtree == NULL
+	|| handle->stmt_plain == NULL)
+      {
+	  sprintf (error, "invalid datasource");
+	  set_error (handle, error);
+	  *raster = NULL;
+	  *size = 0;
+	  return RASTERLITE_ERROR;
+      }
+    if (width < 64 || width > 32768 || height < 64 || height > 32768)
+      {
+	  sprintf (error, "invalid raster dims [%dh X %dv]", width, height);
+	  set_error (handle, error);
+	  *raster = NULL;
+	  *size = 0;
+	  return RASTERLITE_ERROR;
+      }
+    if (raw_format == GAIA_RGB_ARRAY || raw_format == GAIA_RGBA_ARRAY
+	|| raw_format == GAIA_ARGB_ARRAY || raw_format == GAIA_BGR_ARRAY
+	|| raw_format == GAIA_BGRA_ARRAY)
+	;
+    else
+      {
+	  sprintf (error, "invalid raster RAW format");
+	  set_error (handle, error);
+	  *raster = NULL;
+	  *size = 0;
+	  return RASTERLITE_ERROR;
+      }
+    if (best_raster_resolution
+	(ext_handle, ext_pixel_x_size, &pixel_x_size, &pixel_y_size,
+	 &strategy) != RASTERLITE_OK)
+      {
+	  *raster = NULL;
+	  *size = 0;
+	  return RASTERLITE_ERROR;
+      }
+    if (strategy == STRATEGY_RTREE)
+	stmt = handle->stmt_rtree;
+    else
+	stmt = handle->stmt_plain;
+/* creating the output image */
+    output = image_create (width, height);
+    output->color_space = COLORSPACE_MONOCHROME;
+    image_fill (output, handle->background_color);
+/* binding query params */
+    sqlite3_reset (stmt);
+    sqlite3_clear_bindings (stmt);
+    if (strategy == STRATEGY_RTREE)
+      {
+	  /* using the Spatial Index R*Tree */
+	  sqlite3_bind_double (stmt, 1, max_x);
+	  sqlite3_bind_double (stmt, 2, min_x);
+	  sqlite3_bind_double (stmt, 3, max_y);
+	  sqlite3_bind_double (stmt, 4, min_y);
+      }
+    else
+      {
+	  /* plain Table Scan */
+	  sqlite3_bind_double (stmt, 1, min_x);
+	  sqlite3_bind_double (stmt, 2, min_y);
+	  sqlite3_bind_double (stmt, 3, max_x);
+	  sqlite3_bind_double (stmt, 4, max_y);
+      }
+    sqlite3_bind_double (stmt, 5, pixel_x_size);
+    sqlite3_bind_double (stmt, 6, pixel_y_size);
+    while (1)
+      {
+	  /* scrolling the result set */
+	  ret = sqlite3_step (stmt);
+	  if (ret == SQLITE_DONE)
+	      break;		/* end of result set */
+	  if (ret == SQLITE_ROW)
+	    {
+		/* retrieving query values */
+		gaiaGeomCollPtr geom = NULL;
+		rasterliteImagePtr img = NULL;
+		if (sqlite3_column_type (stmt, 0) == SQLITE_BLOB)
+		  {
+		      /* fetching Geometry */
+		      const void *blob = sqlite3_column_blob (stmt, 0);
+		      int blob_size = sqlite3_column_bytes (stmt, 0);
+		      geom =
+			  gaiaFromSpatiaLiteBlobWkb ((const unsigned char *)
+						     blob, blob_size);
+		  }
+		if (sqlite3_column_type (stmt, 1) == SQLITE_BLOB)
+		  {
+		      /* fetching Raster Image */
+		      const void *blob = sqlite3_column_blob (stmt, 1);
+		      int blob_size = sqlite3_column_bytes (stmt, 1);
+		      int type = gaiaGuessBlobType (blob, blob_size);
+		      if (type == GAIA_JPEG_BLOB || type == GAIA_EXIF_BLOB
+			  || type == GAIA_EXIF_GPS_BLOB)
+			  img = image_from_jpeg (blob_size, (void *) blob);
+		      else if (type == GAIA_PNG_BLOB)
+			  img = image_from_png (blob_size, (void *) blob);
+		      else if (type == GAIA_GIF_BLOB)
+			  img = image_from_gif (blob_size, (void *) blob);
+		      else if (type == GAIA_TIFF_BLOB)
+			  img = image_from_tiff (blob_size, (void *) blob);
+		  }
+		if (geom && img)
+		  {
+		      /* resizing the image [tile] */
+		      double pre_width =
+			  internal_round (((double) (img->sx) * pixel_x_size) /
+					  ext_pixel_x_size);
+		      double pre_height =
+			  internal_round (((double) (img->sy) * pixel_y_size) /
+					  ext_pixel_y_size);
+		      int new_width = (int) pre_width + 1;
+		      int new_height = (int) pre_height + 1;
+		      double x = (geom->MinX - min_x) / ext_pixel_x_size;
+		      double y =
+			  (double) height -
+			  ((geom->MaxY - min_y) / ext_pixel_y_size);
+		      if (new_width > (img->sx * 2)
+			  || new_height > (img->sy * 2))
+			{
+			    /* TOO BIG: drawing a gray rectangle */
+			    mark_gray_rectangle (output, int_round (x),
+						 int_round (y), new_width,
+						 new_height);
+			}
+		      else
+			{
+			    /* resizing the raster tile */
+			    if (new_width == img->sx && new_height == img->sy)
+				;
+			    else
+			      {
+				  rasterliteImagePtr img2 = img;
+				  img = image_create (new_width, new_height);
+				  image_resize (img, img2);
+				  image_destroy (img2);
+			      }
+			    /* drawing the raster tile */
+			    copy_rectangle (output, img,
+					    handle->transparent_color,
+					    int_round (x), int_round (y));
+			    /* adjunsting the required colorspace */
+			    if (output->color_space == COLORSPACE_MONOCHROME)
+			      {
+				  if (img->color_space != COLORSPACE_MONOCHROME)
+				      output->color_space = img->color_space;
+			      }
+			    if (output->color_space == COLORSPACE_PALETTE)
+			      {
+				  if (img->color_space != COLORSPACE_PALETTE)
+				      output->color_space = COLORSPACE_RGB;
+			      }
+			    if (output->color_space == COLORSPACE_GRAYSCALE)
+			      {
+				  if (img->color_space != COLORSPACE_GRAYSCALE)
+				      output->color_space = COLORSPACE_RGB;
+			      }
+			}
+		  }
+		if (geom)
+		    gaiaFreeGeomColl (geom);
+		if (img)
+		    image_destroy (img);
+	    }
+	  else
+	    {
+		sprintf (error, "SQL error: %s\n",
+			 sqlite3_errmsg (handle->handle));
+		set_error (handle, error);
+		image_destroy (output);
+		*raster = NULL;
+		*size = 0;
+		return RASTERLITE_ERROR;
+	    }
+      }
+    if (raw_format == GAIA_RGB_ARRAY)
+      {
+	  tmp_raster = image_to_rgb_array (output, &raster_size);
+	  if (!tmp_raster)
+	    {
+		sprintf (error, "RGB ARRAY generation error\n");
+		set_error (handle, error);
+		image_destroy (output);
+		*raster = NULL;
+		*size = 0;
+		return RASTERLITE_ERROR;
+	    }
+      }
+    if (raw_format == GAIA_RGBA_ARRAY)
+      {
+	  tmp_raster =
+	      image_to_rgba_array (handle->transparent_color, output,
+				   &raster_size);
+	  if (!tmp_raster)
+	    {
+		sprintf (error, "RGBA ARRAY generation error\n");
+		set_error (handle, error);
+		image_destroy (output);
+		*raster = NULL;
+		*size = 0;
+		return RASTERLITE_ERROR;
+	    }
+      }
+    if (raw_format == GAIA_ARGB_ARRAY)
+      {
+	  tmp_raster =
+	      image_to_argb_array (handle->transparent_color, output,
+				   &raster_size);
+	  if (!tmp_raster)
+	    {
+		sprintf (error, "ARGB ARRAY generation error\n");
+		set_error (handle, error);
+		image_destroy (output);
+		*raster = NULL;
+		*size = 0;
+		return RASTERLITE_ERROR;
+	    }
+      }
+    if (raw_format == GAIA_BGR_ARRAY)
+      {
+	  tmp_raster = image_to_bgr_array (output, &raster_size);
+	  if (!tmp_raster)
+	    {
+		sprintf (error, "BGR ARRAY generation error\n");
+		set_error (handle, error);
+		image_destroy (output);
+		*raster = NULL;
+		*size = 0;
+		return RASTERLITE_ERROR;
+	    }
+      }
+    if (raw_format == GAIA_BGRA_ARRAY)
+      {
+	  tmp_raster =
+	      image_to_bgra_array (handle->transparent_color, output,
+				   &raster_size);
+	  if (!tmp_raster)
+	    {
+		sprintf (error, "BGRA ARRAY generation error\n");
+		set_error (handle, error);
+		image_destroy (output);
+		*raster = NULL;
+		*size = 0;
+		return RASTERLITE_ERROR;
+	    }
+      }
+
+    *raster = tmp_raster;
+    *size = raster_size;
+    image_destroy (output);
+    return RASTERLITE_OK;
+}
+
+RASTERLITE_DECLARE int
+rasterliteGetRawImage (void *handle, double cx, double cy, double pixel_size,
+		       int width, int height, int raw_format, void **raster,
+		       int *size)
+{
+/* trying to build the required raster image */
+    return rasterliteGetRawImage2 (handle, cx, cy, pixel_size, pixel_size,
+				   width, height, raw_format, raster, size);
+}
+
+RASTERLITE_DECLARE int
+rasterliteGetRawImageByRect2 (void *handle, double x1, double y1, double x2,
+			      double y2, double pixel_x_size,
+			      double pixel_y_size, int width, int height,
+			      int raw_format, void **raster, int *size)
+{
+/* trying to build the required raster image */
+    double cx;
+    double cy;
+    double min_x = x1;
+    double min_y = y1;
+    double max_x = x2;
+    double max_y = y2;
+    if (x2 < min_x)
+	min_x = x2;
+    if (x1 > max_x)
+	max_x = x1;
+    if (y2 < min_y)
+	min_y = y2;
+    if (y1 > max_y)
+	max_y = y1;
+    cx = min_x + ((max_x - min_x) / 2.0);
+    cy = min_y + ((max_y - min_y) / 2.0);
+    return rasterliteGetRawImage2 (handle, cx, cy, pixel_x_size, pixel_y_size,
+				   width, height, raw_format, raster, size);
+}
+
+RASTERLITE_DECLARE int
+rasterliteGetRawImageByRect (void *handle, double x1, double y1, double x2,
+			     double y2, double pixel_size, int width,
+			     int height, int raw_format, void **raster,
+			     int *size)
+{
+/* trying to build the required raster image */
+    return rasterliteGetRawImageByRect2 (handle, x1, y1, x2, y2, pixel_size,
+					 pixel_size, width, height, raw_format,
+					 raster, size);
+}
+
+RASTERLITE_DECLARE int
 rasterliteGetLevels (void *ext_handle)
 {
 /* returns the Pyramid Levels */
@@ -1243,7 +1573,7 @@ rasterliteWaveletToPng (const void *blob, int blob_size, void **png_blob,
 			int *png_size)
 {
 /* transforming a Wavelet compressed image into a PNG */
-    rasterliteImagePrt img;
+    rasterliteImagePtr img;
     void *png;
     int sz;
     img = image_from_wavelet (blob_size, blob);
diff --git a/lib/rasterlite_aux.c b/lib/rasterlite_aux.c
new file mode 100644
index 0000000..4fe0b80
--- /dev/null
+++ b/lib/rasterlite_aux.c
@@ -0,0 +1,1373 @@
+/* 
+/ rasterlite_aux.c
+/
+/ RAW image helpers
+/
+/ version 1.1, 2010 April 27
+/
+/ Author: Sandro Furieri a.furieri at lqt.it
+/
+/ Copyright (C) 2009  Alessandro Furieri
+/
+/    This program is free software: you can redistribute it and/or modify
+/    it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+/
+/    You should have received a copy of the GNU Lesser 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 <math.h>
+
+#ifdef _WIN32
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
+#include <geotiff.h>
+#include <xtiffio.h>
+#include <geo_normalize.h>
+#include <geovalues.h>
+#include <tiffio.h>
+
+#include <spatialite/sqlite3.h>
+#include <spatialite/gaiaexif.h>
+#include <spatialite/gaiageo.h>
+#include <spatialite.h>
+
+#include "rasterlite.h"
+#include "rasterlite_internals.h"
+
+RASTERLITE_DECLARE int
+rasterliteJpegBlobToRawImage (const void *blob, int blob_size, int raw_format,
+			      void **raw, int *width, int *height)
+{
+/* decompressing a Jpeg compressed image and returning a RAW image */
+    void *raw_array;
+    int size;
+    rasterliteImagePtr img = NULL;
+    char *errmsg;
+
+    if (raw_format == GAIA_RGB_ARRAY || raw_format == GAIA_RGBA_ARRAY
+	|| raw_format == GAIA_ARGB_ARRAY || raw_format == GAIA_BGR_ARRAY
+	|| raw_format == GAIA_BGRA_ARRAY)
+	;
+    else
+      {
+	  errmsg = "invalid raster RAW format";
+	  goto error;
+      }
+
+    img = image_from_jpeg (blob_size, blob);
+    if (!img)
+      {
+	  errmsg = "Jpeg decoder error";
+	  goto error;
+      }
+
+    if (raw_format == GAIA_RGB_ARRAY)
+      {
+	  raw_array = image_to_rgb_array (img, &size);
+	  if (!raw_array)
+	    {
+		errmsg = "RGB ARRAY generation error";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_RGBA_ARRAY)
+      {
+	  raw_array = image_to_rgba_array (-1, img, &size);
+	  if (!raw_array)
+	    {
+		errmsg = "RGBA ARRAY generation error";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_ARGB_ARRAY)
+      {
+	  raw_array = image_to_argb_array (-1, img, &size);
+	  if (!raw_array)
+	    {
+		errmsg = "ARGB ARRAY generation error";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGR_ARRAY)
+      {
+	  raw_array = image_to_bgr_array (img, &size);
+	  if (!raw_array)
+	    {
+		errmsg = "BGR ARRAY generation error";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGRA_ARRAY)
+      {
+	  raw_array = image_to_bgra_array (-1, img, &size);
+	  if (!raw_array)
+	    {
+		errmsg = "BGRA ARRAY generation error";
+		goto error;
+	    }
+      }
+
+    image_destroy (img);
+    *raw = raw_array;
+    *width = img->sx;
+    *height = img->sy;
+    return RASTERLITE_OK;
+
+  error:
+    fprintf (stderr, "%s\n", errmsg);
+    if (img)
+	image_destroy (img);
+    *raw = NULL;
+    *width = 0;
+    *height = 0;
+    return RASTERLITE_ERROR;
+}
+
+RASTERLITE_DECLARE int
+rasterlitePngBlobToRawImage (const void *blob, int blob_size, int raw_format,
+			     void **raw, int *width, int *height)
+{
+/* decompressing a Png compressed image and returning a RAW image*/
+    void *raw_array;
+    int size;
+    rasterliteImagePtr img = NULL;
+    char *errmsg;
+
+    if (raw_format == GAIA_RGB_ARRAY || raw_format == GAIA_RGBA_ARRAY
+	|| raw_format == GAIA_ARGB_ARRAY || raw_format == GAIA_BGR_ARRAY
+	|| raw_format == GAIA_BGRA_ARRAY)
+	;
+    else
+      {
+	  errmsg = "invalid raster RAW format";
+	  goto error;
+      }
+
+    img = image_from_png (blob_size, blob);
+    if (!img)
+      {
+	  errmsg = "Png decoder error";
+	  goto error;
+      }
+
+    if (raw_format == GAIA_RGB_ARRAY)
+      {
+	  raw_array = image_to_rgb_array (img, &size);
+	  if (!raw_array)
+	    {
+		errmsg = "RGB ARRAY generation error";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_RGBA_ARRAY)
+      {
+	  raw_array = image_to_rgba_array (-1, img, &size);
+	  if (!raw_array)
+	    {
+		errmsg = "RGBA ARRAY generation error";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_ARGB_ARRAY)
+      {
+	  raw_array = image_to_argb_array (-1, img, &size);
+	  if (!raw_array)
+	    {
+		errmsg = "ARGB ARRAY generation error";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGR_ARRAY)
+      {
+	  raw_array = image_to_bgr_array (img, &size);
+	  if (!raw_array)
+	    {
+		errmsg = "BGR ARRAY generation error";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGRA_ARRAY)
+      {
+	  raw_array = image_to_bgra_array (-1, img, &size);
+	  if (!raw_array)
+	    {
+		errmsg = "BGRA ARRAY generation error";
+		goto error;
+	    }
+      }
+
+    image_destroy (img);
+    *raw = raw_array;
+    *width = img->sx;
+    *height = img->sy;
+    return RASTERLITE_OK;
+
+  error:
+    fprintf (stderr, "%s\n", errmsg);
+    if (img)
+	image_destroy (img);
+    *raw = NULL;
+    *width = 0;
+    *height = 0;
+    return RASTERLITE_ERROR;
+}
+
+RASTERLITE_DECLARE int
+rasterliteGifBlobToRawImage (const void *blob, int blob_size, int raw_format,
+			     void **raw, int *width, int *height)
+{
+/* decompressing a GIF compressed image and returning a RAW image */
+    void *raw_array;
+    int size;
+    rasterliteImagePtr img = NULL;
+    char *errmsg;
+
+    if (raw_format == GAIA_RGB_ARRAY || raw_format == GAIA_RGBA_ARRAY
+	|| raw_format == GAIA_ARGB_ARRAY || raw_format == GAIA_BGR_ARRAY
+	|| raw_format == GAIA_BGRA_ARRAY)
+	;
+    else
+      {
+	  errmsg = "invalid raster RAW format";
+	  goto error;
+      }
+
+    img = image_from_gif (blob_size, blob);
+    if (!img)
+      {
+	  errmsg = "Gif decoder error";
+	  goto error;
+      }
+
+    if (raw_format == GAIA_RGB_ARRAY)
+      {
+	  raw_array = image_to_rgb_array (img, &size);
+	  if (!raw_array)
+	    {
+		errmsg = "RGB ARRAY generation error";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_RGBA_ARRAY)
+      {
+	  raw_array = image_to_rgba_array (-1, img, &size);
+	  if (!raw_array)
+	    {
+		errmsg = "RGBA ARRAY generation error";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_ARGB_ARRAY)
+      {
+	  raw_array = image_to_argb_array (-1, img, &size);
+	  if (!raw_array)
+	    {
+		errmsg = "ARGB ARRAY generation error";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGR_ARRAY)
+      {
+	  raw_array = image_to_bgr_array (img, &size);
+	  if (!raw_array)
+	    {
+		errmsg = "BGR ARRAY generation error";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGRA_ARRAY)
+      {
+	  raw_array = image_to_bgra_array (-1, img, &size);
+	  if (!raw_array)
+	    {
+		errmsg = "BGRA ARRAY generation error";
+		goto error;
+	    }
+      }
+
+    image_destroy (img);
+    *raw = raw_array;
+    *width = img->sx;
+    *height = img->sy;
+    return RASTERLITE_OK;
+
+  error:
+    fprintf (stderr, "%s\n", errmsg);
+    if (img)
+	image_destroy (img);
+    *raw = NULL;
+    *width = 0;
+    *height = 0;
+    return RASTERLITE_ERROR;
+}
+
+RASTERLITE_DECLARE int
+rasterliteTiffBlobToRawImage (const void *blob, int blob_size, int raw_format,
+			      void **raw, int *width, int *height)
+{
+/* decoding a TIFF encoded image and returning a RAW image */
+    void *raw_array;
+    int size;
+    rasterliteImagePtr img = NULL;
+    char *errmsg;
+
+    if (raw_format == GAIA_RGB_ARRAY || raw_format == GAIA_RGBA_ARRAY
+	|| raw_format == GAIA_ARGB_ARRAY || raw_format == GAIA_BGR_ARRAY
+	|| raw_format == GAIA_BGRA_ARRAY)
+	;
+    else
+      {
+	  errmsg = "invalid raster RAW format";
+	  goto error;
+      }
+
+    img = image_from_tiff (blob_size, blob);
+    if (!img)
+      {
+	  errmsg = "Tiff decoder error";
+	  goto error;
+      }
+
+    if (raw_format == GAIA_RGB_ARRAY)
+      {
+	  raw_array = image_to_rgb_array (img, &size);
+	  if (!raw_array)
+	    {
+		errmsg = "RGB ARRAY generation error";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_RGBA_ARRAY)
+      {
+	  raw_array = image_to_rgba_array (-1, img, &size);
+	  if (!raw_array)
+	    {
+		errmsg = "RGBA ARRAY generation error";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_ARGB_ARRAY)
+      {
+	  raw_array = image_to_argb_array (-1, img, &size);
+	  if (!raw_array)
+	    {
+		errmsg = "ARGB ARRAY generation error";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGR_ARRAY)
+      {
+	  raw_array = image_to_bgr_array (img, &size);
+	  if (!raw_array)
+	    {
+		errmsg = "BGR ARRAY generation error";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGRA_ARRAY)
+      {
+	  raw_array = image_to_bgra_array (-1, img, &size);
+	  if (!raw_array)
+	    {
+		errmsg = "BGRA ARRAY generation error";
+		goto error;
+	    }
+      }
+
+    image_destroy (img);
+    *raw = raw_array;
+    *width = img->sx;
+    *height = img->sy;
+    return RASTERLITE_OK;
+
+  error:
+    fprintf (stderr, "%s\n", errmsg);
+    if (img)
+	image_destroy (img);
+    *raw = NULL;
+    *width = 0;
+    *height = 0;
+    return RASTERLITE_ERROR;
+}
+
+RASTERLITE_DECLARE int
+rasterliteWaveletBlobToRawImage (const void *blob, int blob_size,
+				 int raw_format, void **raw, int *width,
+				 int *height)
+{
+/* decompressing a Wavelet compressed image and returning a RAW image */
+    void *raw_array;
+    int size;
+    rasterliteImagePtr img = NULL;
+    char *errmsg;
+
+    if (raw_format == GAIA_RGB_ARRAY || raw_format == GAIA_RGBA_ARRAY
+	|| raw_format == GAIA_ARGB_ARRAY || raw_format == GAIA_BGR_ARRAY
+	|| raw_format == GAIA_BGRA_ARRAY)
+	;
+    else
+      {
+	  errmsg = "invalid raster RAW format";
+	  goto error;
+      }
+
+    img = image_from_wavelet (blob_size, blob);
+    if (!img)
+      {
+	  errmsg = "Wavelet decoder error";
+	  goto error;
+      }
+
+    if (raw_format == GAIA_RGB_ARRAY)
+      {
+	  raw_array = image_to_rgb_array (img, &size);
+	  if (!raw_array)
+	    {
+		errmsg = "RGB ARRAY generation error";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_RGBA_ARRAY)
+      {
+	  raw_array = image_to_rgba_array (-1, img, &size);
+	  if (!raw_array)
+	    {
+		errmsg = "RGBA ARRAY generation error";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_ARGB_ARRAY)
+      {
+	  raw_array = image_to_argb_array (-1, img, &size);
+	  if (!raw_array)
+	    {
+		errmsg = "ARGB ARRAY generation error";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGR_ARRAY)
+      {
+	  raw_array = image_to_bgr_array (img, &size);
+	  if (!raw_array)
+	    {
+		errmsg = "BGR ARRAY generation error";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGRA_ARRAY)
+      {
+	  raw_array = image_to_bgra_array (-1, img, &size);
+	  if (!raw_array)
+	    {
+		errmsg = "BGRA ARRAY generation error";
+		goto error;
+	    }
+      }
+
+    image_destroy (img);
+    *raw = raw_array;
+    *width = img->sx;
+    *height = img->sy;
+    return RASTERLITE_OK;
+
+  error:
+    fprintf (stderr, "%s\n", errmsg);
+    if (img)
+	image_destroy (img);
+    *raw = NULL;
+    *width = 0;
+    *height = 0;
+    return RASTERLITE_ERROR;
+}
+
+RASTERLITE_DECLARE int
+rasterliteRawImageToJpegFile (const void *raw, int raw_format, int width,
+			      int height, const char *path, int quality)
+{
+/* exports a RAW image into a JPEG compressed file */
+    rasterliteImagePtr img = NULL;
+    void *blob = NULL;
+    int blob_size;
+    char *errmsg;
+    int err = 0;
+    FILE *out;
+
+    if (raw == NULL)
+      {
+	  errmsg = "NULL RAW image";
+	  goto error;
+      }
+    if (width <= 0 || height <= 0)
+      {
+	  errmsg = "invalid RAW image width/height";
+	  goto error;
+      }
+    if (raw_format == GAIA_RGB_ARRAY || raw_format == GAIA_RGBA_ARRAY
+	|| raw_format == GAIA_ARGB_ARRAY || raw_format == GAIA_BGR_ARRAY
+	|| raw_format == GAIA_BGRA_ARRAY)
+	;
+    else
+      {
+	  errmsg = "invalid raster RAW format";
+	  goto error;
+      }
+    if (raw_format == GAIA_RGB_ARRAY)
+      {
+	  img = image_from_rgb_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from RGB ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_RGBA_ARRAY)
+      {
+	  img = image_from_rgba_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from RGBA ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_ARGB_ARRAY)
+      {
+	  img = image_from_argb_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from ARGB ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGR_ARRAY)
+      {
+	  img = image_from_bgr_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from BGR ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGRA_ARRAY)
+      {
+	  img = image_from_bgra_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from BGRA ARRAY";
+		goto error;
+	    }
+      }
+
+/* compressing as JPEG */
+    if (is_image_grayscale (img) == RASTERLITE_TRUE)
+	blob = image_to_jpeg_grayscale (img, &blob_size, quality);
+    else
+	blob = image_to_jpeg (img, &blob_size, quality);
+    if (!blob)
+      {
+	  errmsg = "Jpeg encoder error";
+	  goto error;
+      }
+
+/* exporting to file */
+    out = fopen (path, "wb");
+    if (out == NULL)
+      {
+	  errmsg = "Unable to create output image";
+	  goto error;
+      }
+    if (fwrite (blob, 1, blob_size, out) != (size_t) blob_size)
+	err = 1;
+    fclose (out);
+    if (err)
+      {
+	  unlink (path);
+	  goto error;
+      }
+    free (blob);
+    image_destroy (img);
+    return RASTERLITE_OK;
+
+  error:
+    fprintf (stderr, "%s\n", errmsg);
+    if (img)
+	image_destroy (img);
+    if (blob)
+	free (blob);
+    return RASTERLITE_ERROR;
+}
+
+RASTERLITE_DECLARE unsigned char *
+rasterliteRawImageToJpegMemBuf (const void *raw, int raw_format, int width,
+				int height, int *size, int quality)
+{
+/* exports a RAW image into a JPEG compressed memory buffer */
+    rasterliteImagePtr img = NULL;
+    void *blob = NULL;
+    int blob_size;
+    char *errmsg;
+    int err = 0;
+
+    if (raw == NULL)
+      {
+	  errmsg = "NULL RAW image";
+	  goto error;
+      }
+    if (width <= 0 || height <= 0)
+      {
+	  errmsg = "invalid RAW image width/height";
+	  goto error;
+      }
+    if (raw_format == GAIA_RGB_ARRAY || raw_format == GAIA_RGBA_ARRAY
+	|| raw_format == GAIA_ARGB_ARRAY || raw_format == GAIA_BGR_ARRAY
+	|| raw_format == GAIA_BGRA_ARRAY)
+	;
+    else
+      {
+	  errmsg = "invalid raster RAW format";
+	  goto error;
+      }
+    if (raw_format == GAIA_RGB_ARRAY)
+      {
+	  img = image_from_rgb_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from RGB ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_RGBA_ARRAY)
+      {
+	  img = image_from_rgba_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from RGBA ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_ARGB_ARRAY)
+      {
+	  img = image_from_argb_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from ARGB ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGR_ARRAY)
+      {
+	  img = image_from_bgr_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from BGR ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGRA_ARRAY)
+      {
+	  img = image_from_bgra_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from BGRA ARRAY";
+		goto error;
+	    }
+      }
+
+/* compressing as JPEG */
+    if (is_image_grayscale (img) == RASTERLITE_TRUE)
+	blob = image_to_jpeg_grayscale (img, &blob_size, quality);
+    else
+	blob = image_to_jpeg (img, &blob_size, quality);
+    if (!blob)
+      {
+	  errmsg = "Jpeg encoder error";
+	  goto error;
+      }
+
+/* exporting the memory buffer */
+    image_destroy (img);
+    *size = blob_size;
+    return blob;
+
+  error:
+    fprintf (stderr, "%s\n", errmsg);
+    if (img)
+	image_destroy (img);
+    if (blob)
+	free (blob);
+    *size = 0;
+    return NULL;
+}
+
+RASTERLITE_DECLARE int
+rasterliteRawImageToPngFile (const void *raw, int raw_format, int width,
+			     int height, const char *path)
+{
+/* exports a RAW image into a PNG compressed file */
+    rasterliteImagePtr img = NULL;
+    void *blob = NULL;
+    int blob_size;
+    char *errmsg;
+    int err = 0;
+    FILE *out;
+
+    if (raw == NULL)
+      {
+	  errmsg = "NULL RAW image";
+	  goto error;
+      }
+    if (width <= 0 || height <= 0)
+      {
+	  errmsg = "invalid RAW image width/height";
+	  goto error;
+      }
+    if (raw_format == GAIA_RGB_ARRAY || raw_format == GAIA_RGBA_ARRAY
+	|| raw_format == GAIA_ARGB_ARRAY || raw_format == GAIA_BGR_ARRAY
+	|| raw_format == GAIA_BGRA_ARRAY)
+	;
+    else
+      {
+	  errmsg = "invalid raster RAW format";
+	  goto error;
+      }
+    if (raw_format == GAIA_RGB_ARRAY)
+      {
+	  img = image_from_rgb_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from RGB ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_RGBA_ARRAY)
+      {
+	  img = image_from_rgba_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from RGBA ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_ARGB_ARRAY)
+      {
+	  img = image_from_argb_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from ARGB ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGR_ARRAY)
+      {
+	  img = image_from_bgr_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from BGR ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGRA_ARRAY)
+      {
+	  img = image_from_bgra_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from BGRA ARRAY";
+		goto error;
+	    }
+      }
+
+/* compressing as PNG */
+    if (is_image_grayscale (img) == RASTERLITE_TRUE)
+	blob = image_to_png_grayscale (img, &blob_size);
+    else if (is_image_palette256 (img) == RASTERLITE_TRUE)
+	blob = image_to_png_palette (img, &blob_size);
+    else
+	blob = image_to_png_rgb (img, &blob_size);
+    if (!blob)
+      {
+	  errmsg = "Png encoder error";
+	  goto error;
+      }
+
+/* exporting to file */
+    out = fopen (path, "wb");
+    if (out == NULL)
+      {
+	  errmsg = "Unable to create output image";
+	  goto error;
+      }
+    if (fwrite (blob, 1, blob_size, out) != (size_t) blob_size)
+	err = 1;
+    fclose (out);
+    if (err)
+      {
+	  unlink (path);
+	  goto error;
+      }
+    free (blob);
+    image_destroy (img);
+    return RASTERLITE_OK;
+
+  error:
+    fprintf (stderr, "%s\n", errmsg);
+    if (img)
+	image_destroy (img);
+    if (blob)
+	free (blob);
+    return RASTERLITE_ERROR;
+}
+
+RASTERLITE_DECLARE unsigned char *
+rasterliteRawImageToPngMemBuf (const void *raw, int raw_format, int width,
+			       int height, int *size)
+{
+/* exports a RAW image into a PNG compressed memory buffer */
+    rasterliteImagePtr img = NULL;
+    void *blob = NULL;
+    int blob_size;
+    char *errmsg;
+    int err = 0;
+
+    if (raw == NULL)
+      {
+	  errmsg = "NULL RAW image";
+	  goto error;
+      }
+    if (width <= 0 || height <= 0)
+      {
+	  errmsg = "invalid RAW image width/height";
+	  goto error;
+      }
+    if (raw_format == GAIA_RGB_ARRAY || raw_format == GAIA_RGBA_ARRAY
+	|| raw_format == GAIA_ARGB_ARRAY || raw_format == GAIA_BGR_ARRAY
+	|| raw_format == GAIA_BGRA_ARRAY)
+	;
+    else
+      {
+	  errmsg = "invalid raster RAW format";
+	  goto error;
+      }
+    if (raw_format == GAIA_RGB_ARRAY)
+      {
+	  img = image_from_rgb_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from RGB ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_RGBA_ARRAY)
+      {
+	  img = image_from_rgba_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from RGBA ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_ARGB_ARRAY)
+      {
+	  img = image_from_argb_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from ARGB ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGR_ARRAY)
+      {
+	  img = image_from_bgr_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from BGR ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGRA_ARRAY)
+      {
+	  img = image_from_bgra_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from BGRA ARRAY";
+		goto error;
+	    }
+      }
+
+/* compressing as PNG */
+    if (is_image_grayscale (img) == RASTERLITE_TRUE)
+	blob = image_to_png_grayscale (img, &blob_size);
+    else if (is_image_palette256 (img) == RASTERLITE_TRUE)
+	blob = image_to_png_palette (img, &blob_size);
+    else
+	blob = image_to_png_rgb (img, &blob_size);
+    if (!blob)
+      {
+	  errmsg = "Png encoder error";
+	  goto error;
+      }
+
+/* exporting the memory buffer */
+    image_destroy (img);
+    *size = blob_size;
+    return blob;
+
+  error:
+    fprintf (stderr, "%s\n", errmsg);
+    if (img)
+	image_destroy (img);
+    if (blob)
+	free (blob);
+    *size = 0;
+    return NULL;
+}
+
+RASTERLITE_DECLARE int
+rasterliteRawImageToGifFile (const void *raw, int raw_format, int width,
+			     int height, const char *path)
+{
+/* exports a RAW image into a GIF compressed file */
+    rasterliteImagePtr img = NULL;
+    void *blob = NULL;
+    int blob_size;
+    char *errmsg;
+    int err = 0;
+    FILE *out;
+
+    if (raw == NULL)
+      {
+	  errmsg = "NULL RAW image";
+	  goto error;
+      }
+    if (width <= 0 || height <= 0)
+      {
+	  errmsg = "invalid RAW image width/height";
+	  goto error;
+      }
+    if (raw_format == GAIA_RGB_ARRAY || raw_format == GAIA_RGBA_ARRAY
+	|| raw_format == GAIA_ARGB_ARRAY || raw_format == GAIA_BGR_ARRAY
+	|| raw_format == GAIA_BGRA_ARRAY)
+	;
+    else
+      {
+	  errmsg = "invalid raster RAW format";
+	  goto error;
+      }
+    if (raw_format == GAIA_RGB_ARRAY)
+      {
+	  img = image_from_rgb_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from RGB ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_RGBA_ARRAY)
+      {
+	  img = image_from_rgba_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from RGBA ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_ARGB_ARRAY)
+      {
+	  img = image_from_argb_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from ARGB ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGR_ARRAY)
+      {
+	  img = image_from_bgr_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from BGR ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGRA_ARRAY)
+      {
+	  img = image_from_bgra_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from BGRA ARRAY";
+		goto error;
+	    }
+      }
+
+/* compressing as GIF */
+    if (is_image_palette256 (img) == RASTERLITE_FALSE)
+	image_resample_as_palette256 (img);
+
+    blob = image_to_gif (img, &blob_size);
+    if (!blob)
+      {
+	  errmsg = "Gif encoder error";
+	  goto error;
+      }
+
+/* exporting to file */
+    out = fopen (path, "wb");
+    if (out == NULL)
+      {
+	  errmsg = "Unable to create output image";
+	  goto error;
+      }
+    if (fwrite (blob, 1, blob_size, out) != (size_t) blob_size)
+	err = 1;
+    fclose (out);
+    if (err)
+      {
+	  unlink (path);
+	  goto error;
+      }
+    free (blob);
+    image_destroy (img);
+    return RASTERLITE_OK;
+
+  error:
+    fprintf (stderr, "%s\n", errmsg);
+    if (img)
+	image_destroy (img);
+    if (blob)
+	free (blob);
+    return RASTERLITE_ERROR;
+}
+
+RASTERLITE_DECLARE unsigned char *
+rasterliteRawImageToGifMemBuf (const void *raw, int raw_format, int width,
+			       int height, int *size)
+{
+/* exports a RAW image into a GIF compressed memory buffer */
+    rasterliteImagePtr img = NULL;
+    void *blob = NULL;
+    int blob_size;
+    char *errmsg;
+    int err = 0;
+
+    if (raw == NULL)
+      {
+	  errmsg = "NULL RAW image";
+	  goto error;
+      }
+    if (width <= 0 || height <= 0)
+      {
+	  errmsg = "invalid RAW image width/height";
+	  goto error;
+      }
+    if (raw_format == GAIA_RGB_ARRAY || raw_format == GAIA_RGBA_ARRAY
+	|| raw_format == GAIA_ARGB_ARRAY || raw_format == GAIA_BGR_ARRAY
+	|| raw_format == GAIA_BGRA_ARRAY)
+	;
+    else
+      {
+	  errmsg = "invalid raster RAW format";
+	  goto error;
+      }
+    if (raw_format == GAIA_RGB_ARRAY)
+      {
+	  img = image_from_rgb_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from RGB ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_RGBA_ARRAY)
+      {
+	  img = image_from_rgba_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from RGBA ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_ARGB_ARRAY)
+      {
+	  img = image_from_argb_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from ARGB ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGR_ARRAY)
+      {
+	  img = image_from_bgr_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from BGR ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGRA_ARRAY)
+      {
+	  img = image_from_bgra_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from BGRA ARRAY";
+		goto error;
+	    }
+      }
+
+/* compressing as GIF */
+    if (is_image_palette256 (img) == RASTERLITE_FALSE)
+	image_resample_as_palette256 (img);
+
+    blob = image_to_gif (img, &blob_size);
+    if (!blob)
+      {
+	  errmsg = "Gif encoder error";
+	  goto error;
+      }
+
+/* exporting the memory buffer */
+    image_destroy (img);
+    *size = blob_size;
+    return blob;
+
+  error:
+    fprintf (stderr, "%s\n", errmsg);
+    if (img)
+	image_destroy (img);
+    if (blob)
+	free (blob);
+    *size = 0;
+    return NULL;
+}
+
+RASTERLITE_DECLARE int
+rasterliteRawImageToGeoTiffFile (const void *raw, int raw_format, int width,
+				 int height, const char *path, double x_size,
+				 double y_size, double xllcorner,
+				 double yllcorner, const char *proj4text)
+{
+/* exports a RAW image into a TIFF encoded file */
+    rasterliteImagePtr img = NULL;
+    void *blob = NULL;
+    int blob_size;
+    char *errmsg;
+
+    if (raw == NULL)
+      {
+	  errmsg = "NULL RAW image";
+	  goto error;
+      }
+    if (width <= 0 || height <= 0)
+      {
+	  errmsg = "invalid RAW image width/height";
+	  goto error;
+      }
+    if (raw_format == GAIA_RGB_ARRAY || raw_format == GAIA_RGBA_ARRAY
+	|| raw_format == GAIA_ARGB_ARRAY || raw_format == GAIA_BGR_ARRAY
+	|| raw_format == GAIA_BGRA_ARRAY)
+	;
+    else
+      {
+	  errmsg = "invalid raster RAW format";
+	  goto error;
+      }
+    if (raw_format == GAIA_RGB_ARRAY)
+      {
+	  img = image_from_rgb_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from RGB ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_RGBA_ARRAY)
+      {
+	  img = image_from_rgba_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from RGBA ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_ARGB_ARRAY)
+      {
+	  img = image_from_argb_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from ARGB ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGR_ARRAY)
+      {
+	  img = image_from_bgr_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from BGR ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGRA_ARRAY)
+      {
+	  img = image_from_bgra_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from BGRA ARRAY";
+		goto error;
+	    }
+      }
+
+/* encoding as TIFF */
+    if (is_image_monochrome (img) == RASTERLITE_TRUE)
+	blob = image_to_tiff_fax4 (img, &blob_size);
+    else if (is_image_grayscale (img) == RASTERLITE_TRUE)
+	blob = image_to_tiff_grayscale (img, &blob_size);
+    else if (is_image_palette256 (img) == RASTERLITE_TRUE)
+	blob = image_to_tiff_palette (img, &blob_size);
+    else
+	blob = image_to_tiff_rgb (img, &blob_size);
+    if (!blob)
+      {
+	  errmsg = "Tiff encoder error";
+	  goto error;
+      }
+
+/* exporting to file as GeoTiff */
+    if (!write_geotiff
+	(path, blob, blob_size, x_size, y_size, xllcorner, yllcorner,
+	 proj4text))
+      {
+	  errmsg = "Unable to create output image";
+	  goto error;
+      }
+    free (blob);
+    image_destroy (img);
+    return RASTERLITE_OK;
+
+  error:
+    fprintf (stderr, "%s\n", errmsg);
+    if (img)
+	image_destroy (img);
+    if (blob)
+	free (blob);
+    return RASTERLITE_ERROR;
+}
+
+RASTERLITE_DECLARE unsigned char *
+rasterliteRawImageToTiffMemBuf (const void *raw, int raw_format, int width,
+				int height, int *size)
+{
+/* exports a RAW image into a TIFF encoded memory buffer */
+    rasterliteImagePtr img = NULL;
+    void *blob = NULL;
+    int blob_size;
+    char *errmsg;
+
+    if (raw == NULL)
+      {
+	  errmsg = "NULL RAW image";
+	  goto error;
+      }
+    if (width <= 0 || height <= 0)
+      {
+	  errmsg = "invalid RAW image width/height";
+	  goto error;
+      }
+    if (raw_format == GAIA_RGB_ARRAY || raw_format == GAIA_RGBA_ARRAY
+	|| raw_format == GAIA_ARGB_ARRAY || raw_format == GAIA_BGR_ARRAY
+	|| raw_format == GAIA_BGRA_ARRAY)
+	;
+    else
+      {
+	  errmsg = "invalid raster RAW format";
+	  goto error;
+      }
+    if (raw_format == GAIA_RGB_ARRAY)
+      {
+	  img = image_from_rgb_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from RGB ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_RGBA_ARRAY)
+      {
+	  img = image_from_rgba_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from RGBA ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_ARGB_ARRAY)
+      {
+	  img = image_from_argb_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from ARGB ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGR_ARRAY)
+      {
+	  img = image_from_bgr_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from BGR ARRAY";
+		goto error;
+	    }
+      }
+    if (raw_format == GAIA_BGRA_ARRAY)
+      {
+	  img = image_from_bgra_array (raw, width, height);
+	  if (!img)
+	    {
+		errmsg = "unable to get an image from BGRA ARRAY";
+		goto error;
+	    }
+      }
+
+/* encoding as TIFF */
+    if (is_image_monochrome (img) == RASTERLITE_TRUE)
+	blob = image_to_tiff_fax4 (img, &blob_size);
+    else if (is_image_grayscale (img) == RASTERLITE_TRUE)
+	blob = image_to_tiff_grayscale (img, &blob_size);
+    else if (is_image_palette256 (img) == RASTERLITE_TRUE)
+	blob = image_to_tiff_palette (img, &blob_size);
+    else
+	blob = image_to_tiff_rgb (img, &blob_size);
+    if (!blob)
+      {
+	  errmsg = "Tiff encoder error";
+	  goto error;
+      }
+
+/* exporting the memory buffer */
+    image_destroy (img);
+    *size = blob_size;
+    return blob;
+
+  error:
+    fprintf (stderr, "%s\n", errmsg);
+    if (img)
+	image_destroy (img);
+    if (blob)
+	free (blob);
+    *size = 0;
+    return NULL;
+}
diff --git a/lib/rasterlite_gif.c b/lib/rasterlite_gif.c
index 53282a4..125950e 100644
--- a/lib/rasterlite_gif.c
+++ b/lib/rasterlite_gif.c
@@ -3,23 +3,23 @@
 /
 / GIF auxiliary helpers
 /
-/ version 1.0, 2009 June 1
+/ version 1.1, 2010 April 27
 /
 / Author: Sandro Furieri a.furieri at lqt.it
 /
 / Copyright (C) 2009  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
+/    it under the terms of the GNU Lesser 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.
+/    GNU Lesser General Public License for more details.
 /
-/    You should have received a copy of the GNU General Public License
+/    You should have received a copy of the GNU Lesser General Public License
 /    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 /
 */
@@ -368,7 +368,7 @@ LWZReadByte (xgdIOCtx * fd, LZW_STATIC_DATA * sd, char flag,
 }
 
 static void
-ReadImage (rasterliteImagePrt im, xgdIOCtx * fd, int len, int height,
+ReadImage (rasterliteImagePtr im, xgdIOCtx * fd, int len, int height,
 	   unsigned char (*cmap)[256], int interlace, int *ZeroDataBlockP)
 {
     unsigned char c;
@@ -525,7 +525,7 @@ BumpPixel (GifCtx * ctx)
 }
 
 static int
-GIFNextPixel (rasterliteImagePrt img, GifCtx * ctx)
+GIFNextPixel (rasterliteImagePtr img, GifCtx * ctx)
 {
     int r;
     int **ptpixels = img->pixels;
@@ -673,7 +673,7 @@ gifPutWord (int w, xgdIOCtx * out)
 }
 
 static void
-GIFcompress (int init_bits, xgdIOCtxPtr outfile, rasterliteImagePrt img,
+GIFcompress (int init_bits, xgdIOCtxPtr outfile, rasterliteImagePtr img,
 	     GifCtx * ctx)
 {
 /*
@@ -772,7 +772,7 @@ GIFcompress (int init_bits, xgdIOCtxPtr outfile, rasterliteImagePrt img,
 static void
 GIFEncode (xgdIOCtxPtr fp, int GWidth, int GHeight, int GInterlace,
 	   int Background, int Transparent, int BitsPerPixel, int *Red,
-	   int *Green, int *Blue, rasterliteImagePrt img)
+	   int *Green, int *Blue, rasterliteImagePtr img)
 {
     int B;
     int RWidth, RHeight;
@@ -862,7 +862,7 @@ colorstobpp (int colors)
     return bpp;
 }
 
-static rasterliteImagePrt
+static rasterliteImagePtr
 xgdImageCreateFromGifCtx (xgdIOCtxPtr fd)
 {
     int BitPixel;
@@ -876,7 +876,7 @@ xgdImageCreateFromGifCtx (xgdIOCtxPtr fd)
     int bitPixel;
     int ZeroDataBlock = FALSE;
     int haveGlobalColormap;
-    rasterliteImagePrt im = 0;
+    rasterliteImagePtr im = 0;
     if (!ReadOK (fd, buf, 6))
       {
 	  return 0;
@@ -988,7 +988,7 @@ xgdImageCreateFromGifCtx (xgdIOCtxPtr fd)
 }
 
 static void
-xgdImageGifCtx (rasterliteImagePrt img, xgdIOCtxPtr out)
+xgdImageGifCtx (rasterliteImagePtr img, xgdIOCtxPtr out)
 {
     int BitsPerPixel;
     int mapping[256];
@@ -1028,7 +1028,7 @@ xgdImageGifCtx (rasterliteImagePrt img, xgdIOCtxPtr out)
 }
 
 extern void *
-image_to_gif (const rasterliteImagePrt img, int *size)
+image_to_gif (const rasterliteImagePtr img, int *size)
 {
 /* compressing an image as GIF */
     void *rv;
@@ -1039,11 +1039,11 @@ image_to_gif (const rasterliteImagePrt img, int *size)
     return rv;
 }
 
-extern rasterliteImagePrt
+extern rasterliteImagePtr
 image_from_gif (int size, const void *data)
 {
 /* uncompressing a GIF */
-    rasterliteImagePrt img;
+    rasterliteImagePtr img;
     xgdIOCtx *in = xgdNewDynamicCtxEx (size, data, 0);
     img = xgdImageCreateFromGifCtx (in);
     img->color_space = COLORSPACE_PALETTE;
diff --git a/lib/rasterlite_image.c b/lib/rasterlite_image.c
index 805dcb9..df1628e 100644
--- a/lib/rasterlite_image.c
+++ b/lib/rasterlite_image.c
@@ -3,23 +3,23 @@
 /
 / image methods
 /
-/ version 1.0, 2009 June 1
+/ version 1.1, 2010 April 27
 /
 / Author: Sandro Furieri a.furieri at lqt.it
 /
 / Copyright (C) 2009  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
+/    it under the terms of the GNU Lesser 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.
+/    GNU Lesser General Public License for more details.
 /
-/    You should have received a copy of the GNU General Public License
+/    You should have received a copy of the GNU Lesser General Public License
 /    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 /
 */
@@ -27,6 +27,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <float.h>
 #include <limits.h>
 
 #include <tiffio.h>
@@ -35,7 +36,7 @@
 
 #include "rasterlite_internals.h"
 
-extern rasterliteImagePrt
+extern rasterliteImagePtr
 image_create (int sx, int sy)
 {
 /*
@@ -44,7 +45,7 @@ image_create (int sx, int sy)
 */
     int i;
     int i2;
-    rasterliteImagePrt img;
+    rasterliteImagePtr img;
     img = malloc (sizeof (rasterliteImage));
     if (!img)
 	return NULL;
@@ -74,7 +75,7 @@ image_create (int sx, int sy)
 }
 
 extern void
-image_destroy (rasterliteImagePrt img)
+image_destroy (rasterliteImagePtr img)
 {
 /*
 / destroying a generic RGB image
@@ -91,7 +92,7 @@ image_destroy (rasterliteImagePrt img)
 }
 
 extern void
-image_fill (const rasterliteImagePrt img, int color)
+image_fill (const rasterliteImagePtr img, int color)
 {
 /* filling the image with given color */
     int x;
@@ -107,7 +108,7 @@ image_fill (const rasterliteImagePrt img, int color)
 }
 
 static void
-shrink_by (const rasterliteImagePrt dst, const rasterliteImagePrt src)
+shrink_by (const rasterliteImagePtr dst, const rasterliteImagePtr src)
 {
 /*
 / this code is widely base upon the original wxWidgets gwxImage wxImage::ShrinkBy(() function
@@ -119,24 +120,24 @@ shrink_by (const rasterliteImagePrt dst, const rasterliteImagePrt src)
     int x1;
     int y1;
     int y_offset;
-    unsigned int avgRed = 0;
-    unsigned int avgGreen = 0;
-    unsigned int avgBlue = 0;
-    unsigned int counter = 0;
+    int x_offset;
     int pixel;
-    printf ("shrink\n");
-    fflush (stdout);
     for (y = 0; y < dst->sy; y++)
       {
 	  for (x = 0; x < dst->sx; x++)
 	    {
 		/* determine average */
+		unsigned int avgRed = 0;
+		unsigned int avgGreen = 0;
+		unsigned int avgBlue = 0;
+		unsigned int counter = 0;
 		for (y1 = 0; y1 < yFactor; ++y1)
 		  {
 		      y_offset = (y * yFactor + y1) * src->sx;
 		      for (x1 = 0; x1 < xFactor; ++x1)
 			{
-			    pixel = src->pixels[y1][x1];
+			    x_offset = (x * xFactor) + x1;
+			    pixel = src->pixels[y_offset][x_offset];
 			    avgRed += true_color_get_red (pixel);
 			    avgGreen += true_color_get_green (pixel);
 			    avgBlue += true_color_get_blue (pixel);
@@ -152,7 +153,7 @@ shrink_by (const rasterliteImagePrt dst, const rasterliteImagePrt src)
 }
 
 extern void
-image_resize (const rasterliteImagePrt dst, const rasterliteImagePrt src)
+image_resize (const rasterliteImagePtr dst, const rasterliteImagePtr src)
 {
 /*
 / this function builds an ordinary quality resized image, applying pixel replication
@@ -192,8 +193,8 @@ image_resize (const rasterliteImagePrt dst, const rasterliteImagePrt src)
 #define floor2(exp) ((long) exp)
 
 extern void
-make_thumbnail (const rasterliteImagePrt thumbnail,
-		const rasterliteImagePrt image)
+make_thumbnail (const rasterliteImagePtr thumbnail,
+		const rasterliteImagePtr image)
 {
 /*
 / this function builds an high quality thumbnail image, applying pixel interpolation
@@ -293,7 +294,7 @@ make_thumbnail (const rasterliteImagePrt thumbnail,
 }
 
 extern void *
-image_to_rgb_array (const rasterliteImagePrt img, int *size)
+image_to_rgb_array (const rasterliteImagePtr img, int *size)
 {
 /* building a flat RGB array from this image */
     int x;
@@ -319,3 +320,413 @@ image_to_rgb_array (const rasterliteImagePrt img, int *size)
     *size = sz;
     return data;
 }
+
+extern void *
+image_to_rgba_array (int transparent_color, const rasterliteImagePtr img,
+		     int *size)
+{
+/* building a flat RGBA array from this image */
+    int x;
+    int y;
+    int pixel;
+    int r;
+    int g;
+    int b;
+    int a;
+    unsigned char *data = NULL;
+    unsigned char *p;
+    int sz = img->sx * img->sy * 4;
+    *size = 0;
+/* allocating the RGB array */
+    data = malloc (sz);
+    p = data;
+    for (y = 0; y < img->sy; y++)
+      {
+	  for (x = 0; x < img->sx; x++)
+	    {
+		pixel = img->pixels[y][x];
+		r = true_color_get_red (pixel);
+		g = true_color_get_green (pixel);
+		b = true_color_get_blue (pixel);
+		if (transparent_color == true_color (r, g, b))
+		    a = 0;
+		else
+		    a = 255;
+		*p++ = r;
+		*p++ = g;
+		*p++ = b;
+		*p++ = a;
+	    }
+      }
+    *size = sz;
+    return data;
+}
+
+extern void *
+image_to_argb_array (int transparent_color, const rasterliteImagePtr img,
+		     int *size)
+{
+/* building a flat ARGB array from this image */
+    int x;
+    int y;
+    int pixel;
+    int r;
+    int g;
+    int b;
+    int a;
+    unsigned char *data = NULL;
+    unsigned char *p;
+    int sz = img->sx * img->sy * 4;
+    *size = 0;
+/* allocating the RGB array */
+    data = malloc (sz);
+    p = data;
+    for (y = 0; y < img->sy; y++)
+      {
+	  for (x = 0; x < img->sx; x++)
+	    {
+		pixel = img->pixels[y][x];
+		r = true_color_get_red (pixel);
+		g = true_color_get_green (pixel);
+		b = true_color_get_blue (pixel);
+		if (transparent_color == true_color (r, g, b))
+		    a = 0;
+		else
+		    a = 255;
+		*p++ = a;
+		*p++ = r;
+		*p++ = g;
+		*p++ = b;
+	    }
+      }
+    *size = sz;
+    return data;
+}
+
+extern void *
+image_to_bgr_array (const rasterliteImagePtr img, int *size)
+{
+/* building a flat BGR array from this image */
+    int x;
+    int y;
+    int pixel;
+    unsigned char *data = NULL;
+    unsigned char *p;
+    int sz = img->sx * img->sy * 3;
+    *size = 0;
+/* allocating the RGB array */
+    data = malloc (sz);
+    p = data;
+    for (y = 0; y < img->sy; y++)
+      {
+	  for (x = 0; x < img->sx; x++)
+	    {
+		pixel = img->pixels[y][x];
+		*p++ = true_color_get_blue (pixel);
+		*p++ = true_color_get_green (pixel);
+		*p++ = true_color_get_red (pixel);
+	    }
+      }
+    *size = sz;
+    return data;
+}
+
+extern void *
+image_to_bgra_array (int transparent_color, const rasterliteImagePtr img,
+		     int *size)
+{
+/* building a flat BGRA array from this image */
+    int x;
+    int y;
+    int pixel;
+    int r;
+    int g;
+    int b;
+    int a;
+    unsigned char *data = NULL;
+    unsigned char *p;
+    int sz = img->sx * img->sy * 4;
+    *size = 0;
+/* allocating the RGB array */
+    data = malloc (sz);
+    p = data;
+    for (y = 0; y < img->sy; y++)
+      {
+	  for (x = 0; x < img->sx; x++)
+	    {
+		pixel = img->pixels[y][x];
+		r = true_color_get_red (pixel);
+		g = true_color_get_green (pixel);
+		b = true_color_get_blue (pixel);
+		if (transparent_color == true_color (r, g, b))
+		    a = 0;
+		else
+		    a = 255;
+		*p++ = b;
+		*p++ = g;
+		*p++ = r;
+		*p++ = a;
+	    }
+      }
+    *size = sz;
+    return data;
+}
+
+extern rasterliteImagePtr
+image_from_rgb_array (const void *raw, int width, int height)
+{
+/* building an image form this flat RGB array */
+    int x;
+    int y;
+    int r;
+    int g;
+    int b;
+    int pixel;
+    const unsigned char *data = raw;
+    const unsigned char *p;
+    rasterliteImagePtr img = image_create (width, height);
+    if (!img)
+	return NULL;
+    for (y = 0; y < img->sy; y++)
+      {
+	  p = data + (y * (width * 3));
+	  for (x = 0; x < img->sx; x++)
+	    {
+		r = *p++;
+		g = *p++;
+		b = *p++;
+		pixel = true_color (r, g, b);
+		img->pixels[y][x] = pixel;
+	    }
+      }
+    return img;
+}
+
+extern rasterliteImagePtr
+image_from_rgba_array (const void *raw, int width, int height)
+{
+/* building an image form this flat RGBA array */
+    int x;
+    int y;
+    int r;
+    int g;
+    int b;
+    int alpha;
+    int pixel;
+    const unsigned char *data = raw;
+    const unsigned char *p;
+    rasterliteImagePtr img = image_create (width, height);
+    if (!img)
+	return NULL;
+    for (y = 0; y < img->sy; y++)
+      {
+	  p = data + (y * (width * 4));
+	  for (x = 0; x < img->sx; x++)
+	    {
+		r = *p++;
+		g = *p++;
+		b = *p++;
+		alpha = *p++;
+		pixel = true_color (r, g, b);
+		img->pixels[y][x] = pixel;
+	    }
+      }
+    return img;
+}
+
+extern rasterliteImagePtr
+image_from_argb_array (const void *raw, int width, int height)
+{
+/* building an image form this flat ARGB array */
+    int x;
+    int y;
+    int r;
+    int g;
+    int b;
+    int alpha;
+    int pixel;
+    const unsigned char *data = raw;
+    const unsigned char *p;
+    rasterliteImagePtr img = image_create (width, height);
+    if (!img)
+	return NULL;
+    for (y = 0; y < img->sy; y++)
+      {
+	  p = data + (y * (width * 4));
+	  for (x = 0; x < img->sx; x++)
+	    {
+
+		alpha = *p++;
+		r = *p++;
+		g = *p++;
+		b = *p++;
+		pixel = true_color (r, g, b);
+		img->pixels[y][x] = pixel;
+	    }
+      }
+    return img;
+}
+
+extern rasterliteImagePtr
+image_from_bgr_array (const void *raw, int width, int height)
+{
+/* building an image form this flat BGR array */
+    int x;
+    int y;
+    int r;
+    int g;
+    int b;
+    int pixel;
+    const unsigned char *data = raw;
+    const unsigned char *p;
+    rasterliteImagePtr img = image_create (width, height);
+    if (!img)
+	return NULL;
+    for (y = 0; y < img->sy; y++)
+      {
+	  p = data + (y * (width * 3));
+	  for (x = 0; x < img->sx; x++)
+	    {
+		b = *p++;
+		g = *p++;
+		r = *p++;
+		pixel = true_color (r, g, b);
+		img->pixels[y][x] = pixel;
+	    }
+      }
+    return img;
+}
+
+extern rasterliteImagePtr
+image_from_bgra_array (const void *raw, int width, int height)
+{
+/* building an image form this flat BGRA array */
+    int x;
+    int y;
+    int r;
+    int g;
+    int b;
+    int alpha;
+    int pixel;
+    const unsigned char *data = raw;
+    const unsigned char *p;
+    rasterliteImagePtr img = image_create (width, height);
+    if (!img)
+	return NULL;
+    for (y = 0; y < img->sy; y++)
+      {
+	  p = data + (y * (width * 4));
+	  for (x = 0; x < img->sx; x++)
+	    {
+		b = *p++;
+		g = *p++;
+		r = *p++;
+		alpha = *p++;
+		pixel = true_color (r, g, b);
+		img->pixels[y][x] = pixel;
+	    }
+      }
+    return img;
+}
+
+extern int
+is_image_monochrome (rasterliteImagePtr img)
+{
+/* checking if this Image is into the Monochrome colorspace */
+    int x;
+    int y;
+    int pixel;
+    int r;
+    int g;
+    int b;
+    for (y = 0; y < img->sy; y++)
+      {
+	  for (x = 0; x < img->sx; x++)
+	    {
+		pixel = img->pixels[y][x];
+		r = true_color_get_red (pixel);
+		g = true_color_get_green (pixel);
+		b = true_color_get_blue (pixel);
+		if (r == 0 && g == 0 && b == 0)
+		    continue;
+		if (r == 255 && g == 255 && b == 255)
+		    continue;
+		return RASTERLITE_FALSE;
+	    }
+      }
+    return RASTERLITE_TRUE;
+}
+
+extern int
+is_image_grayscale (rasterliteImagePtr img)
+{
+/* checking if this Image is into the GrayScale colorspace */
+    int x;
+    int y;
+    int pixel;
+    int r;
+    int g;
+    int b;
+    for (y = 0; y < img->sy; y++)
+      {
+	  for (x = 0; x < img->sx; x++)
+	    {
+		pixel = img->pixels[y][x];
+		r = true_color_get_red (pixel);
+		g = true_color_get_green (pixel);
+		b = true_color_get_blue (pixel);
+		if (r == g && r == b)
+		    continue;
+		return RASTERLITE_FALSE;
+	    }
+      }
+    return RASTERLITE_TRUE;
+}
+
+static void
+palette_init (int *palette)
+{
+/* initializing an empty palette */
+    int x;
+    for (x = 0; x < 256; x++)
+	palette[x] = INT_MAX;
+}
+
+static int
+palette_check (int *palette, int pixel)
+{
+    int x;
+    for (x = 0; x < 256; x++)
+      {
+	  if (palette[x] == pixel)
+	      return RASTERLITE_TRUE;
+	  if (palette[x] == INT_MAX)
+	    {
+		palette[x] = pixel;
+		return RASTERLITE_TRUE;
+	    }
+      }
+    return RASTERLITE_FALSE;
+}
+
+extern int
+is_image_palette256 (rasterliteImagePtr img)
+{
+/* checking if this Image may be represented using a 256 colors palette */
+    int x;
+    int y;
+    int pixel;
+    int palette[256];
+    palette_init (palette);
+    for (y = 0; y < img->sy; y++)
+      {
+	  for (x = 0; x < img->sx; x++)
+	    {
+		pixel = img->pixels[y][x];
+		if (palette_check (palette, pixel) == RASTERLITE_TRUE)
+		    continue;
+		return RASTERLITE_FALSE;
+	    }
+      }
+    return RASTERLITE_TRUE;
+}
diff --git a/lib/rasterlite_io.c b/lib/rasterlite_io.c
index e956082..cacf5bc 100644
--- a/lib/rasterlite_io.c
+++ b/lib/rasterlite_io.c
@@ -3,23 +3,23 @@
 /
 / IO helper methods
 /
-/ version 1.0, 2009 June 1
+/ version 1.1, 2010 April 27
 /
 / Author: Sandro Furieri a.furieri at lqt.it
 /
 / Copyright (C) 2009  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
+/    it under the terms of the GNU Lesser 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.
+/    GNU Lesser General Public License for more details.
 /
-/    You should have received a copy of the GNU General Public License
+/    You should have received a copy of the GNU Lesser General Public License
 /    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 /
 */
diff --git a/lib/rasterlite_jpeg.c b/lib/rasterlite_jpeg.c
index 15342b0..4abe32d 100644
--- a/lib/rasterlite_jpeg.c
+++ b/lib/rasterlite_jpeg.c
@@ -3,23 +3,23 @@
 /
 / JPEG auxiliary helpers
 /
-/ version 1.0, 2009 June 1
+/ version 1.1, 2010 April 27
 /
 / Author: Sandro Furieri a.furieri at lqt.it
 /
 / Copyright (C) 2009  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
+/    it under the terms of the GNU Lesser 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.
+/    GNU Lesser General Public License for more details.
 /
-/    You should have received a copy of the GNU General Public License
+/    You should have received a copy of the GNU Lesser General Public License
 /    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 /
 */
@@ -111,7 +111,7 @@ fatal_jpeg_error (j_common_ptr cinfo)
     exit (99);
 }
 
-void
+static void
 init_source (j_decompress_ptr cinfo)
 {
     my_src_ptr src = (my_src_ptr) cinfo->src;
@@ -119,7 +119,7 @@ init_source (j_decompress_ptr cinfo)
 }
 
 #define END_JPEG_SEQUENCE "\r\n[*]--:END JPEG:--[*]\r\n"
-safeboolean
+static safeboolean
 fill_input_buffer (j_decompress_ptr cinfo)
 {
     my_src_ptr src = (my_src_ptr) cinfo->src;
@@ -155,7 +155,7 @@ fill_input_buffer (j_decompress_ptr cinfo)
     return TRUE;
 }
 
-void
+static void
 skip_input_data (j_decompress_ptr cinfo, long num_bytes)
 {
     my_src_ptr src = (my_src_ptr) cinfo->src;
@@ -171,7 +171,7 @@ skip_input_data (j_decompress_ptr cinfo, long num_bytes)
       }
 }
 
-void
+static void
 term_source (j_decompress_ptr cinfo)
 {
     if (cinfo)
@@ -259,7 +259,7 @@ jpeg_xgdIOCtx_dest (j_compress_ptr cinfo, xgdIOCtx * outfile)
 }
 
 static void
-xgdImageJpegCtx (rasterliteImagePrt img, xgdIOCtx * outfile, int quality,
+xgdImageJpegCtx (rasterliteImagePtr img, xgdIOCtx * outfile, int quality,
 		 int mode)
 {
     struct jpeg_compress_struct cinfo;
@@ -372,14 +372,14 @@ CMYKToRGB (int c, int m, int y, int k, int inverted)
 		       (255 - y) * (255 - k) / 255);
 }
 
-static rasterliteImagePrt
+static rasterliteImagePtr
 xgdImageCreateFromJpegCtx (xgdIOCtx * infile)
 {
     struct jpeg_decompress_struct cinfo;
     struct jpeg_error_mgr jerr;
     jmpbuf_wrapper jmpbufw;
     volatile JSAMPROW row = 0;
-    volatile rasterliteImagePrt img = 0;
+    volatile rasterliteImagePtr img = 0;
     JSAMPROW rowptr[1];
     int i, j, retval;
     JDIMENSION nrows;
@@ -394,7 +394,7 @@ xgdImageCreateFromJpegCtx (xgdIOCtx * infile)
 	  if (row)
 	      free (row);
 	  if (img)
-	      image_destroy ((rasterliteImagePrt) img);
+	      image_destroy ((rasterliteImagePtr) img);
 	  return 0;
       }
     cinfo.err->error_exit = fatal_jpeg_error;
@@ -573,18 +573,18 @@ xgdImageCreateFromJpegCtx (xgdIOCtx * infile)
 		 "jpeg-wrapper: warning: jpeg_finish_decompress reports suspended data source\n");
     jpeg_destroy_decompress (&cinfo);
     free (row);
-    return (rasterliteImagePrt) img;
+    return (rasterliteImagePtr) img;
   error:
     jpeg_destroy_decompress (&cinfo);
     if (row)
 	free (row);
     if (img)
-	image_destroy ((rasterliteImagePrt) img);
+	image_destroy ((rasterliteImagePtr) img);
     return 0;
 }
 
 extern void *
-image_to_jpeg (const rasterliteImagePrt img, int *size, int quality)
+image_to_jpeg (const rasterliteImagePtr img, int *size, int quality)
 {
 /* compressing an image as JPEG RGB */
     void *rv;
@@ -596,7 +596,7 @@ image_to_jpeg (const rasterliteImagePrt img, int *size, int quality)
 }
 
 extern void *
-image_to_jpeg_grayscale (const rasterliteImagePrt img, int *size, int quality)
+image_to_jpeg_grayscale (const rasterliteImagePtr img, int *size, int quality)
 {
 /* compressing an image as JPEG GRAYSCALE */
     void *rv;
@@ -607,11 +607,11 @@ image_to_jpeg_grayscale (const rasterliteImagePrt img, int *size, int quality)
     return rv;
 }
 
-extern rasterliteImagePrt
+extern rasterliteImagePtr
 image_from_jpeg (int size, const void *data)
 {
 /* uncompressing a JPEG */
-    rasterliteImagePrt img;
+    rasterliteImagePtr img;
     xgdIOCtx *in = xgdNewDynamicCtxEx (size, data, 0);
     img = xgdImageCreateFromJpegCtx (in);
     in->xgd_free (in);
diff --git a/lib/rasterlite_png.c b/lib/rasterlite_png.c
index 0ac0353..3f565f1 100644
--- a/lib/rasterlite_png.c
+++ b/lib/rasterlite_png.c
@@ -3,23 +3,23 @@
 /
 / PNG auxiliary helpers
 /
-/ version 1.0, 2009 June 1
+/ version 1.1, 2010 April 27
 /
 / Author: Sandro Furieri a.furieri at lqt.it
 /
 / Copyright (C) 2009  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
+/    it under the terms of the GNU Lesser 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.
+/    GNU Lesser General Public License for more details.
 /
-/    You should have received a copy of the GNU General Public License
+/    You should have received a copy of the GNU Lesser General Public License
 /    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 /
 */
@@ -100,7 +100,7 @@ xgdPngFlushData (png_structp png_ptr)
 	return;			/* does absolutely nothing - required in order to suppress warnings */
 }
 
-static rasterliteImagePrt
+static rasterliteImagePtr
 xgdImageCreateFromPngCtx (xgdIOCtx * infile)
 {
     png_byte sig[8];
@@ -115,7 +115,7 @@ xgdImageCreateFromPngCtx (xgdIOCtx * infile)
     int blue[256];
     png_bytep image_data = NULL;
     png_bytepp row_pointers = NULL;
-    rasterliteImagePrt im = NULL;
+    rasterliteImagePtr im = NULL;
     int i, j;
     volatile int palette_allocated = FALSE;
     memset (sig, 0, sizeof (sig));
@@ -123,7 +123,7 @@ xgdImageCreateFromPngCtx (xgdIOCtx * infile)
       {
 	  return NULL;
       }
-    if (!png_check_sig (sig, 8))
+    if (png_sig_cmp (sig, 0, 8))
       {
 	  return NULL;
       }
@@ -350,7 +350,7 @@ xgdImageCreateFromPngCtx (xgdIOCtx * infile)
 }
 
 static void
-xgdImagePngCtxPalette (rasterliteImagePrt img, xgdIOCtx * outfile, int level)
+xgdImagePngCtxPalette (rasterliteImagePtr img, xgdIOCtx * outfile, int level)
 {
     int i, j, bit_depth = 0, interlace_type;
     int width = img->sx;
@@ -472,7 +472,7 @@ xgdImagePngCtxPalette (rasterliteImagePrt img, xgdIOCtx * outfile, int level)
 }
 
 static void
-xgdImagePngCtxGrayscale (rasterliteImagePrt img, xgdIOCtx * outfile, int level)
+xgdImagePngCtxGrayscale (rasterliteImagePtr img, xgdIOCtx * outfile, int level)
 {
     int i, j, bit_depth = 0, interlace_type;
     int width = img->sx;
@@ -556,7 +556,7 @@ xgdImagePngCtxGrayscale (rasterliteImagePrt img, xgdIOCtx * outfile, int level)
 }
 
 static void
-xgdImagePngCtxRgb (rasterliteImagePrt img, xgdIOCtx * outfile, int level)
+xgdImagePngCtxRgb (rasterliteImagePtr img, xgdIOCtx * outfile, int level)
 {
     int i, j, bit_depth = 0, interlace_type;
     int width = img->sx;
@@ -648,7 +648,7 @@ xgdImagePngCtxRgb (rasterliteImagePrt img, xgdIOCtx * outfile, int level)
 }
 
 extern void *
-image_to_png_palette (rasterliteImagePrt img, int *size)
+image_to_png_palette (const rasterliteImagePtr img, int *size)
 {
 /* compressing an image as PNG PALETTE */
     void *rv;
@@ -660,7 +660,7 @@ image_to_png_palette (rasterliteImagePrt img, int *size)
 }
 
 extern void *
-image_to_png_grayscale (const rasterliteImagePrt img, int *size)
+image_to_png_grayscale (const rasterliteImagePtr img, int *size)
 {
 /* compressing an image as PNG GRAYSCALE */
     void *rv;
@@ -672,7 +672,7 @@ image_to_png_grayscale (const rasterliteImagePrt img, int *size)
 }
 
 extern void *
-image_to_png_rgb (const rasterliteImagePrt img, int *size)
+image_to_png_rgb (const rasterliteImagePtr img, int *size)
 {
 /* compressing an image as PNG RGB */
     void *rv;
@@ -683,11 +683,11 @@ image_to_png_rgb (const rasterliteImagePrt img, int *size)
     return rv;
 }
 
-extern rasterliteImagePrt
+extern rasterliteImagePtr
 image_from_png (int size, const void *data)
 {
 /* uncompressing a PNG */
-    rasterliteImagePrt img;
+    rasterliteImagePtr img;
     xgdIOCtx *in = xgdNewDynamicCtxEx (size, data, 0);
     img = xgdImageCreateFromPngCtx (in);
     in->xgd_free (in);
diff --git a/lib/rasterlite_quantize.c b/lib/rasterlite_quantize.c
new file mode 100644
index 0000000..edc26dd
--- /dev/null
+++ b/lib/rasterlite_quantize.c
@@ -0,0 +1,943 @@
+/* 
+/ rasterlite_quantize.c
+/
+/ quantization methods
+/
+/ version 1.1, 2010 April 27
+/
+/ Author: Sandro Furieri a.furieri at lqt.it
+/
+/ Copyright (C) 2009  Alessandro Furieri
+/
+/    This program is free software: you can redistribute it and/or modify
+/    it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+/
+/    You should have received a copy of the GNU Lesser General Public License
+/    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+/
+*/
+
+/* 
+/
+/ DISCLAIMER:
+/ all the following code merely is an 'ad hoc' adaption
+/ of the following LGPLed code:
+/
+//////////////////////////////////////////////////////////////////////////////
+/
+ median.c: median cut - reducing a high color bitmap to certain number of colors
+
+   Copyright (C) 2001, 2002 Martin Weber
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License
+   as published by the Free Software Foundation; either version 2.1 of
+   the License, or (at your option) any later version.
+
+   This library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+   USA. 
+*/
+
+#include <stdlib.h>
+
+#include <tiffio.h>
+#include <spatialite/sqlite3.h>
+#include <spatialite/gaiageo.h>
+
+#include "rasterlite_internals.h"
+
+#define MAXNUMCOLORS 256
+
+/* scale RGB distances by *2,*3,*1 */
+#define R_SCALE  <<1
+#define G_SCALE  *3
+#define B_SCALE
+
+#define BITS_IN_SAMPLE 	8
+
+#define R_SHIFT  	(BITS_IN_SAMPLE - PRECISION_R)
+#define G_SHIFT  	(BITS_IN_SAMPLE - PRECISION_G)
+#define B_SHIFT  	(BITS_IN_SAMPLE - PRECISION_B)
+
+#define PRECISION_R 	7
+#define PRECISION_G 	7
+#define PRECISION_B 	7
+
+#define HIST_R_ELEMS 	(1<<PRECISION_R)
+#define HIST_G_ELEMS 	(1<<PRECISION_G)
+#define HIST_B_ELEMS 	(1<<PRECISION_B)
+
+#define MR 		HIST_G_ELEMS*HIST_B_ELEMS
+#define MG 		HIST_B_ELEMS
+
+typedef unsigned long ColorFreq;
+typedef ColorFreq *Histogram;
+
+typedef struct
+{
+    int desired_number_of_colors;	/* Number of colors we will allow */
+    int actual_number_of_colors;	/* Number of colors actually needed */
+    int cmap[256];		/* colormap created by quantization */
+    ColorFreq freq[256];
+    Histogram histogram;	/* holds the histogram */
+} QuantizeObj;
+
+typedef struct
+{
+    /* The bounds of the box (inclusive); expressed as histogram indexes */
+    int Rmin, Rmax;
+    int Gmin, Gmax;
+    int Bmin, Bmax;
+    /* The volume (actually 2-norm) of the box */
+    int volume;
+    /* The number of nonzero histogram cells within this box */
+    long colorcount;
+} box, *boxptr;
+
+static void
+zero_histogram_rgb (Histogram histogram)
+{
+    int r, g, b;
+    for (r = 0; r < HIST_R_ELEMS; r++)
+	for (g = 0; g < HIST_G_ELEMS; g++)
+	    for (b = 0; b < HIST_B_ELEMS; b++)
+		histogram[r * MR + g * MG + b] = 0;
+}
+
+static void
+generate_histogram_rgb (Histogram histogram, rasterliteImagePtr image)
+{
+    int pixel;
+    int x;
+    int y;
+    int r;
+    int g;
+    int b;
+    ColorFreq *col;
+
+    zero_histogram_rgb (histogram);
+
+    for (y = 0; y < image->sy; y++)
+      {
+	  for (x = 0; x < image->sx; x++)
+	    {
+		pixel = image->pixels[y][x];
+		r = true_color_get_red (pixel);
+		g = true_color_get_green (pixel);
+		b = true_color_get_blue (pixel);
+		col = &histogram[(r >> R_SHIFT) * MR
+				 + (g >> G_SHIFT) * MG + (b >> B_SHIFT)];
+		(*col)++;
+	    }
+      }
+}
+
+
+static boxptr
+find_biggest_volume (boxptr boxlist, int numboxes)
+/* Find the splittable box with the largest (scaled) volume */
+/* Returns 0 if no splittable boxes remain */
+{
+    boxptr boxp;
+    int i;
+    int maxv = 0;
+    boxptr which = 0;
+
+    for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++)
+      {
+	  if (boxp->volume > maxv)
+	    {
+		which = boxp;
+		maxv = boxp->volume;
+	    }
+      }
+
+    return which;
+}
+
+
+static void
+update_box_rgb (Histogram histogram, boxptr boxp)
+/* Shrink the min/max bounds of a box to enclose only nonzero elements, */
+/* and recompute its volume and population */
+{
+    ColorFreq *histp;
+    int R, G, B;
+    int Rmin, Rmax, Gmin, Gmax, Bmin, Bmax;
+    int dist0, dist1, dist2;
+    long ccount;
+
+    Rmin = boxp->Rmin;
+    Rmax = boxp->Rmax;
+    Gmin = boxp->Gmin;
+    Gmax = boxp->Gmax;
+    Bmin = boxp->Bmin;
+    Bmax = boxp->Bmax;
+
+    if (Rmax > Rmin)
+	for (R = Rmin; R <= Rmax; R++)
+	    for (G = Gmin; G <= Gmax; G++)
+	      {
+		  histp = histogram + R * MR + G * MG + Bmin;
+		  for (B = Bmin; B <= Bmax; B++)
+		      if (*histp++ != 0)
+			{
+			    boxp->Rmin = Rmin = R;
+			    goto have_Rmin;
+			}
+	      }
+  have_Rmin:
+    if (Rmax > Rmin)
+	for (R = Rmax; R >= Rmin; R--)
+	    for (G = Gmin; G <= Gmax; G++)
+	      {
+		  histp = histogram + R * MR + G * MG + Bmin;
+		  for (B = Bmin; B <= Bmax; B++)
+		      if (*histp++ != 0)
+			{
+			    boxp->Rmax = Rmax = R;
+			    goto have_Rmax;
+			}
+	      }
+  have_Rmax:
+    if (Gmax > Gmin)
+	for (G = Gmin; G <= Gmax; G++)
+	    for (R = Rmin; R <= Rmax; R++)
+	      {
+		  histp = histogram + R * MR + G * MG + Bmin;
+		  for (B = Bmin; B <= Bmax; B++)
+		      if (*histp++ != 0)
+			{
+			    boxp->Gmin = Gmin = G;
+			    goto have_Gmin;
+			}
+	      }
+  have_Gmin:
+    if (Gmax > Gmin)
+	for (G = Gmax; G >= Gmin; G--)
+	    for (R = Rmin; R <= Rmax; R++)
+	      {
+		  histp = histogram + R * MR + G * MG + Bmin;
+		  for (B = Bmin; B <= Bmax; B++)
+		      if (*histp++ != 0)
+			{
+			    boxp->Gmax = Gmax = G;
+			    goto have_Gmax;
+			}
+	      }
+  have_Gmax:
+    if (Bmax > Bmin)
+	for (B = Bmin; B <= Bmax; B++)
+	    for (R = Rmin; R <= Rmax; R++)
+	      {
+		  histp = histogram + R * MR + Gmin * MG + B;
+		  for (G = Gmin; G <= Gmax; G++, histp += MG)
+		      if (*histp != 0)
+			{
+			    boxp->Bmin = Bmin = B;
+			    goto have_Bmin;
+			}
+	      }
+  have_Bmin:
+    if (Bmax > Bmin)
+	for (B = Bmax; B >= Bmin; B--)
+	    for (R = Rmin; R <= Rmax; R++)
+	      {
+		  histp = histogram + R * MR + Gmin * MG + B;
+		  for (G = Gmin; G <= Gmax; G++, histp += MG)
+		      if (*histp != 0)
+			{
+			    boxp->Bmax = Bmax = B;
+			    goto have_Bmax;
+			}
+	      }
+  have_Bmax:
+
+    /* Update box volume.
+     * We use 2-norm rather than real volume here; this biases the method
+     * against making long narrow boxes, and it has the side benefit that
+     * a box is splittable iff norm > 0.
+     * Since the differences are expressed in histogram-cell units,
+     * we have to shift back to JSAMPLE units to get consistent distances;
+     * after which, we scale according to the selected distance scale factors.
+     */
+    dist0 = Rmax - Rmin;
+    dist1 = Gmax - Gmin;
+    dist2 = Bmax - Bmin;
+    boxp->volume = dist0 * dist0 + dist1 * dist1 + dist2 * dist2;
+
+    /* Now scan remaining volume of box and compute population */
+    ccount = 0;
+    for (R = Rmin; R <= Rmax; R++)
+	for (G = Gmin; G <= Gmax; G++)
+	  {
+	      histp = histogram + R * MR + G * MG + Bmin;
+	      for (B = Bmin; B <= Bmax; B++, histp++)
+		  if (*histp != 0)
+		    {
+			ccount++;
+		    }
+	  }
+
+    boxp->colorcount = ccount;
+}
+
+
+static int
+median_cut_rgb (Histogram histogram, boxptr boxlist, int numboxes,
+		int desired_colors)
+/* Repeatedly select and split the largest box until we have enough boxes */
+{
+    int n, lb;
+    int R, G, B, cmax;
+    boxptr b1, b2;
+
+    while (numboxes < desired_colors)
+      {
+	  /* Select box to split.
+	   * Current algorithm: by population for first half, then by volume.
+	   */
+	  b1 = find_biggest_volume (boxlist, numboxes);
+
+	  if (b1 == 0)		/* no splittable boxes left! */
+	      break;
+	  b2 = boxlist + numboxes;	/* where new box will go */
+	  /* Copy the color bounds to the new box. */
+	  b2->Rmax = b1->Rmax;
+	  b2->Gmax = b1->Gmax;
+	  b2->Bmax = b1->Bmax;
+	  b2->Rmin = b1->Rmin;
+	  b2->Gmin = b1->Gmin;
+	  b2->Bmin = b1->Bmin;
+	  /* Choose which axis to split the box on.
+	   * Current algorithm: longest scaled axis.
+	   * See notes in update_box about scaling distances.
+	   */
+	  R = b1->Rmax - b1->Rmin;
+	  G = b1->Gmax - b1->Gmin;
+	  B = b1->Bmax - b1->Bmin;
+	  /* We want to break any ties in favor of green, then red, blue last.
+	   */
+	  cmax = G;
+	  n = 1;
+	  if (R > cmax)
+	    {
+		cmax = R;
+		n = 0;
+	    }
+	  if (B > cmax)
+	    {
+		n = 2;
+	    }
+	  /* Choose split point along selected axis, and update box bounds.
+	   * Current algorithm: split at halfway point.
+	   * (Since the box has been shrunk to minimum volume,
+	   * any split will produce two nonempty subboxes.)
+	   * Note that lb value is max for lower box, so must be < old max.
+	   */
+	  switch (n)
+	    {
+	    case 0:
+		lb = (b1->Rmax + b1->Rmin) / 2;
+		b1->Rmax = lb;
+		b2->Rmin = lb + 1;
+		break;
+	    case 1:
+		lb = (b1->Gmax + b1->Gmin) / 2;
+		b1->Gmax = lb;
+		b2->Gmin = lb + 1;
+		break;
+	    case 2:
+		lb = (b1->Bmax + b1->Bmin) / 2;
+		b1->Bmax = lb;
+		b2->Bmin = lb + 1;
+		break;
+	    }
+	  /* Update stats for boxes */
+	  update_box_rgb (histogram, b1);
+	  update_box_rgb (histogram, b2);
+	  numboxes++;
+      }
+    return numboxes;
+}
+
+
+static void
+compute_color_rgb (QuantizeObj * quantobj, Histogram histogram,
+		   boxptr boxp, int icolor)
+/* Compute representative color for a box, put it in colormap[icolor] */
+{
+    /* Current algorithm: mean weighted by pixels (not colors) */
+    /* Note it is important to get the rounding correct! */
+    ColorFreq *histp;
+    int R, G, B;
+    int Rmin, Rmax;
+    int Gmin, Gmax;
+    int Bmin, Bmax;
+    unsigned long count;
+    unsigned long total = 0;
+    unsigned long Rtotal = 0;
+    unsigned long Gtotal = 0;
+    unsigned long Btotal = 0;
+    int pixel;
+    int r;
+    int g;
+    int b;
+
+    Rmin = boxp->Rmin;
+    Rmax = boxp->Rmax;
+    Gmin = boxp->Gmin;
+    Gmax = boxp->Gmax;
+    Bmin = boxp->Bmin;
+    Bmax = boxp->Bmax;
+
+    for (R = Rmin; R <= Rmax; R++)
+	for (G = Gmin; G <= Gmax; G++)
+	  {
+	      histp = histogram + R * MR + G * MG + Bmin;
+	      for (B = Bmin; B <= Bmax; B++)
+		{
+		    if ((count = *histp++) != 0)
+		      {
+			  total += count;
+			  Rtotal +=
+			      ((R << R_SHIFT) + ((1 << R_SHIFT) >> 1)) * count;
+			  Gtotal +=
+			      ((G << G_SHIFT) + ((1 << G_SHIFT) >> 1)) * count;
+			  Btotal +=
+			      ((B << B_SHIFT) + ((1 << B_SHIFT) >> 1)) * count;
+		      }
+		}
+	  }
+
+    r = (unsigned char) ((Rtotal + (total >> 1)) / total);
+    g = (unsigned char) ((Gtotal + (total >> 1)) / total);
+    b = (unsigned char) ((Btotal + (total >> 1)) / total);
+    pixel = true_color (r, g, b);
+    quantobj->cmap[icolor] = pixel;
+    quantobj->freq[icolor] = total;
+}
+
+
+static void
+select_colors_rgb (QuantizeObj * quantobj, Histogram histogram)
+/* Master routine for color selection */
+{
+    boxptr boxlist;
+    int numboxes;
+    int desired = quantobj->desired_number_of_colors;
+    int i;
+
+    /* Allocate workspace for box list */
+    boxlist = malloc (desired * sizeof (box));
+
+    /* Initialize one box containing whole space */
+    numboxes = 1;
+    boxlist[0].Rmin = 0;
+    boxlist[0].Rmax = (1 << PRECISION_R) - 1;
+    boxlist[0].Gmin = 0;
+    boxlist[0].Gmax = (1 << PRECISION_G) - 1;
+    boxlist[0].Bmin = 0;
+    boxlist[0].Bmax = (1 << PRECISION_B) - 1;
+    /* Shrink it to actually-used volume and set its statistics */
+    update_box_rgb (histogram, boxlist);
+    /* Perform median-cut to produce final box list */
+    numboxes = median_cut_rgb (histogram, boxlist, numboxes, desired);
+    quantobj->actual_number_of_colors = numboxes;
+    /* Compute the representative color for each box, fill colormap */
+    for (i = 0; i < numboxes; i++)
+	compute_color_rgb (quantobj, histogram, boxlist + i, i);
+    free (boxlist);
+}
+
+
+/*
+ * These routines are concerned with the time-critical task of mapping input
+ * colors to the nearest color in the selected colormap.
+ *
+ * We re-use the histogram space as an "inverse color map", essentially a
+ * cache for the results of nearest-color searches.  All colors within a
+ * histogram cell will be mapped to the same colormap entry, namely the one
+ * closest to the cell's center.  This may not be quite the closest entry to
+ * the actual input color, but it's almost as good.  A zero in the cache
+ * indicates we haven't found the nearest color for that cell yet; the array
+ * is cleared to zeroes before starting the mapping pass.  When we find the
+ * nearest color for a cell, its colormap index plus one is recorded in the
+ * cache for future use.  The pass2 scanning routines call fill_inverse_cmap
+ * when they need to use an unfilled entry in the cache.
+ *
+ * Our method of efficiently finding nearest colors is based on the "locally
+ * sorted search" idea described by Heckbert and on the incremental distance
+ * calculation described by Spencer W. Thomas in chapter III.1 of Graphics
+ * Gems II (James Arvo, ed.  Academic Press, 1991).  Thomas points out that
+ * the distances from a given colormap entry to each cell of the histogram can
+ * be computed quickly using an incremental method: the differences between
+ * distances to adjacent cells themselves differ by a constant.  This allows a
+ * fairly fast implementation of the "brute force" approach of computing the
+ * distance from every colormap entry to every histogram cell.  Unfortunately,
+ * it needs a work array to hold the best-distance-so-far for each histogram
+ * cell (because the inner loop has to be over cells, not colormap entries).
+ * The work array elements have to be ints, so the work array would need
+ * 256Kb at our recommended precision.  This is not feasible in DOS machines.
+
+[ 256*1024/4 = 65,536 ]
+
+ * To get around these problems, we apply Thomas' method to compute the
+ * nearest colors for only the cells within a small subbox of the histogram.
+ * The work array need be only as big as the subbox, so the memory usage
+ * problem is solved.  Furthermore, we need not fill subboxes that are never
+ * referenced in pass2; many images use only part of the color gamut, so a
+ * fair amount of work is saved.  An additional advantage of this
+ * approach is that we can apply Heckbert's locality criterion to quickly
+ * eliminate colormap entries that are far away from the subbox; typically
+ * three-fourths of the colormap entries are rejected by Heckbert's criterion,
+ * and we need not compute their distances to individual cells in the subbox.
+ * The speed of this approach is heavily influenced by the subbox size: too
+ * small means too much overhead, too big loses because Heckbert's criterion
+ * can't eliminate as many colormap entries.  Empirically the best subbox
+ * size seems to be about 1/512th of the histogram (1/8th in each direction).
+ *
+ * Thomas' article also describes a refined method which is asymptotically
+ * faster than the brute-force method, but it is also far more complex and
+ * cannot efficiently be applied to small subboxes.  It is therefore not
+ * useful for programs intended to be portable to DOS machines.  On machines
+ * with plenty of memory, filling the whole histogram in one shot with Thomas'
+ * refined method might be faster than the present code --- but then again,
+ * it might not be any faster, and it's certainly more complicated.
+ */
+
+/* log2(histogram cells in update box) for each axis; this can be adjusted */
+#define BOX_R_LOG  (PRECISION_R-3)
+#define BOX_G_LOG  (PRECISION_G-3)
+#define BOX_B_LOG  (PRECISION_B-3)
+
+#define BOX_R_ELEMS  (1<<BOX_R_LOG)	/* # of hist cells in update box */
+#define BOX_G_ELEMS  (1<<BOX_G_LOG)
+#define BOX_B_ELEMS  (1<<BOX_B_LOG)
+
+#define BOX_R_SHIFT  (R_SHIFT + BOX_R_LOG)
+#define BOX_G_SHIFT  (G_SHIFT + BOX_G_LOG)
+#define BOX_B_SHIFT  (B_SHIFT + BOX_B_LOG)
+
+/*
+ * The next three routines implement inverse colormap filling.  They could
+ * all be folded into one big routine, but splitting them up this way saves
+ * some stack space (the mindist[] and bestdist[] arrays need not coexist)
+ * and may allow some compilers to produce better code by registerizing more
+ * inner-loop variables.
+ */
+
+static int
+find_nearby_colors (QuantizeObj * quantobj, int minR, int minG,
+		    int minB, int *colorlist)
+/* Locate the colormap entries close enough to an update box to be candidates
+ * for the nearest entry to some cell(s) in the update box.  The update box
+ * is specified by the center coordinates of its first cell.  The number of
+ * candidate colormap entries is returned, and their colormap indexes are
+ * placed in colorlist[].
+ * This routine uses Heckbert's "locally sorted search" criterion to select
+ * the colors that need further consideration.
+ */
+{
+    int numcolors = quantobj->actual_number_of_colors;
+    int maxR, maxG, maxB;
+    int centerR, centerG, centerB;
+    int i, x, ncolors;
+    int minmaxdist, min_dist = 0, max_dist, tdist;
+    int mindist[MAXNUMCOLORS];	/* min distance to colormap entry i */
+    int pixel;
+    int r;
+    int g;
+    int b;
+
+    /* Compute TRUE coordinates of update box's upper corner and center.
+     * Actually we compute the coordinates of the center of the upper-corner
+     * histogram cell, which are the upper bounds of the volume we care about.
+     * Note that since ">>" rounds down, the "center" values may be closer to
+     * min than to max; hence comparisons to them must be "<=", not "<".
+     */
+    maxR = minR + ((1 << BOX_R_SHIFT) - (1 << R_SHIFT));
+    centerR = (minR + maxR) >> 1;
+    maxG = minG + ((1 << BOX_G_SHIFT) - (1 << G_SHIFT));
+    centerG = (minG + maxG) >> 1;
+    maxB = minB + ((1 << BOX_B_SHIFT) - (1 << B_SHIFT));
+    centerB = (minB + maxB) >> 1;
+
+    /* For each color in colormap, find:
+     *  1. its minimum squared-distance to any point in the update box
+     *     (zero if color is within update box);
+     *  2. its maximum squared-distance to any point in the update box.
+     * Both of these can be found by considering only the corners of the box.
+     * We save the minimum distance for each color in mindist[];
+     * only the smallest maximum distance is of interest.
+     */
+    minmaxdist = 0x7FFFFFFFL;
+
+    for (i = 0; i < numcolors; i++)
+      {
+	  /* We compute the squared-R-distance term, then add in the other two. */
+	  pixel = quantobj->cmap[i];
+	  r = true_color_get_red (pixel);
+	  g = true_color_get_green (pixel);
+	  b = true_color_get_blue (pixel);
+	  x = r;
+	  if (x < minR)
+	    {
+		tdist = (x - minR) R_SCALE;
+		min_dist = tdist * tdist;
+		tdist = (x - maxR) R_SCALE;
+		max_dist = tdist * tdist;
+	    }
+	  else if (x > maxR)
+	    {
+		tdist = (x - maxR) R_SCALE;
+		min_dist = tdist * tdist;
+		tdist = (x - minR) R_SCALE;
+		max_dist = tdist * tdist;
+	    }
+	  else
+	    {
+		/* within cell range so no contribution to min_dist */
+		min_dist = 0;
+		if (x <= centerR)
+		  {
+		      tdist = (x - maxR) R_SCALE;
+		      max_dist = tdist * tdist;
+		  }
+		else
+		  {
+		      tdist = (x - minR) R_SCALE;
+		      max_dist = tdist * tdist;
+		  }
+	    }
+
+	  x = g;
+	  if (x < minG)
+	    {
+		tdist = (x - minG) G_SCALE;
+		min_dist += tdist * tdist;
+		tdist = (x - maxG) G_SCALE;
+		max_dist += tdist * tdist;
+	    }
+	  else if (x > maxG)
+	    {
+		tdist = (x - maxG) G_SCALE;
+		min_dist += tdist * tdist;
+		tdist = (x - minG) G_SCALE;
+		max_dist += tdist * tdist;
+	    }
+	  else
+	    {
+		/* within cell range so no contribution to min_dist */
+		if (x <= centerG)
+		  {
+		      tdist = (x - maxG) G_SCALE;
+		      max_dist += tdist * tdist;
+		  }
+		else
+		  {
+		      tdist = (x - minG) G_SCALE;
+		      max_dist += tdist * tdist;
+		  }
+	    }
+
+	  x = b;
+	  if (x < minB)
+	    {
+		tdist = (x - minB) B_SCALE;
+		min_dist += tdist * tdist;
+		tdist = (x - maxB) B_SCALE;
+		max_dist += tdist * tdist;
+	    }
+	  else if (x > maxB)
+	    {
+		tdist = (x - maxB) B_SCALE;
+		min_dist += tdist * tdist;
+		tdist = (x - minB) B_SCALE;
+		max_dist += tdist * tdist;
+	    }
+	  else
+	    {
+		/* within cell range so no contribution to min_dist */
+		if (x <= centerB)
+		  {
+		      tdist = (x - maxB) B_SCALE;
+		      max_dist += tdist * tdist;
+		  }
+		else
+		  {
+		      tdist = (x - minB) B_SCALE;
+		      max_dist += tdist * tdist;
+		  }
+	    }
+
+	  mindist[i] = min_dist;	/* save away the results */
+	  if (max_dist < minmaxdist)
+	      minmaxdist = max_dist;
+      }
+
+    /* Now we know that no cell in the update box is more than minmaxdist
+     * away from some colormap entry.  Therefore, only colors that are
+     * within minmaxdist of some part of the box need be considered.
+     */
+    ncolors = 0;
+    for (i = 0; i < numcolors; i++)
+      {
+	  if (mindist[i] <= minmaxdist)
+	      colorlist[ncolors++] = i;
+      }
+    return ncolors;
+}
+
+
+static void
+find_best_colors (QuantizeObj * quantobj, int minR, int minG,
+		  int minB, int numcolors, int *colorlist, int *bestcolor)
+/* Find the closest colormap entry for each cell in the update box,
+  given the list of candidate colors prepared by find_nearby_colors.
+  Return the indexes of the closest entries in the bestcolor[] array.
+  This routine uses Thomas' incremental distance calculation method to
+  find the distance from a colormap entry to successive cells in the box.
+ */
+{
+    int iR, iG, iB;
+    int i, icolor;
+    int *bptr;			/* pointer into bestdist[] array */
+    int *cptr;			/* pointer into bestcolor[] array */
+    int dist0, dist1;		/* initial distance values */
+    int dist2;			/* current distance in inner loop */
+    int xx0, xx1;		/* distance increments */
+    int xx2;
+    int inR, inG, inB;		/* initial values for increments */
+    int pixel;
+    int r;
+    int g;
+    int b;
+
+    /* This array holds the distance to the nearest-so-far color for each cell */
+    int bestdist[BOX_R_ELEMS * BOX_G_ELEMS * BOX_B_ELEMS];
+
+    /* Initialize best-distance for each cell of the update box */
+    bptr = bestdist;
+    for (i = BOX_R_ELEMS * BOX_G_ELEMS * BOX_B_ELEMS - 1; i >= 0; i--)
+	*bptr++ = 0x7FFFFFFFL;
+
+    /* For each color selected by find_nearby_colors,
+     * compute its distance to the center of each cell in the box.
+     * If that's less than best-so-far, update best distance and color number.
+     */
+
+    /* Nominal steps between cell centers ("x" in Thomas article) */
+#define STEP_R  ((1 << R_SHIFT) R_SCALE)
+#define STEP_G  ((1 << G_SHIFT) G_SCALE)
+#define STEP_B  ((1 << B_SHIFT) B_SCALE)
+
+    for (i = 0; i < numcolors; i++)
+      {
+	  icolor = colorlist[i];
+	  /* Compute (square of) distance from minR/G/B to this color */
+	  pixel = quantobj->cmap[icolor];
+	  r = true_color_get_red (pixel);
+	  g = true_color_get_green (pixel);
+	  b = true_color_get_blue (pixel);
+	  inR = (minR - r) R_SCALE;
+	  dist0 = inR * inR;
+	  inG = (minG - g) G_SCALE;
+	  dist0 += inG * inG;
+	  inB = (minB - b) B_SCALE;
+	  dist0 += inB * inB;
+	  /* Form the initial difference increments */
+	  inR = inR * (2 * STEP_R) + STEP_R * STEP_R;
+	  inG = inG * (2 * STEP_G) + STEP_G * STEP_G;
+	  inB = inB * (2 * STEP_B) + STEP_B * STEP_B;
+	  /* Now loop over all cells in box, updating distance per Thomas method */
+	  bptr = bestdist;
+	  cptr = bestcolor;
+	  xx0 = inR;
+	  for (iR = BOX_R_ELEMS - 1; iR >= 0; iR--)
+	    {
+		dist1 = dist0;
+		xx1 = inG;
+		for (iG = BOX_G_ELEMS - 1; iG >= 0; iG--)
+		  {
+		      dist2 = dist1;
+		      xx2 = inB;
+		      for (iB = BOX_B_ELEMS - 1; iB >= 0; iB--)
+			{
+			    if (dist2 < *bptr)
+			      {
+				  *bptr = dist2;
+				  *cptr = icolor;
+			      }
+			    dist2 += xx2;
+			    xx2 += 2 * STEP_B * STEP_B;
+			    bptr++;
+			    cptr++;
+			}
+		      dist1 += xx1;
+		      xx1 += 2 * STEP_G * STEP_G;
+		  }
+		dist0 += xx0;
+		xx0 += 2 * STEP_R * STEP_R;
+	    }
+      }
+}
+
+static void
+fill_inverse_cmap_rgb (QuantizeObj * quantobj, Histogram histogram,
+		       int R, int G, int B)
+/* Fill the inverse-colormap entries in the update box that contains
+ histogram cell R/G/B.  (Only that one cell MUST be filled, but
+ we can fill as many others as we wish.) */
+{
+    int minR, minG, minB;	/* lower left corner of update box */
+    int iR, iG, iB;
+    int *cptr;			/* pointer into bestcolor[] array */
+    ColorFreq *cachep;		/* pointer into main cache array */
+    /* This array lists the candidate colormap indexes. */
+    int colorlist[MAXNUMCOLORS];
+    int numcolors;		/* number of candidate colors */
+    /* This array holds the actually closest colormap index for each cell. */
+    int bestcolor[BOX_R_ELEMS * BOX_G_ELEMS * BOX_B_ELEMS];
+
+    /* Convert cell coordinates to update box ID */
+    R >>= BOX_R_LOG;
+    G >>= BOX_G_LOG;
+    B >>= BOX_B_LOG;
+
+    /* Compute TRUE coordinates of update box's origin corner.
+     * Actually we compute the coordinates of the center of the corner
+     * histogram cell, which are the lower bounds of the volume we care about.
+     */
+    minR = (R << BOX_R_SHIFT) + ((1 << R_SHIFT) >> 1);
+    minG = (G << BOX_G_SHIFT) + ((1 << G_SHIFT) >> 1);
+    minB = (B << BOX_B_SHIFT) + ((1 << B_SHIFT) >> 1);
+
+    /* Determine which colormap entries are close enough to be candidates
+     * for the nearest entry to some cell in the update box.
+     */
+    numcolors = find_nearby_colors (quantobj, minR, minG, minB, colorlist);
+
+    /* Determine the actually nearest colors. */
+    find_best_colors (quantobj, minR, minG, minB, numcolors, colorlist,
+		      bestcolor);
+
+    /* Save the best color numbers (plus 1) in the main cache array */
+    R <<= BOX_R_LOG;		/* convert ID back to base cell indexes */
+    G <<= BOX_G_LOG;
+    B <<= BOX_B_LOG;
+    cptr = bestcolor;
+    for (iR = 0; iR < BOX_R_ELEMS; iR++)
+      {
+	  for (iG = 0; iG < BOX_G_ELEMS; iG++)
+	    {
+		cachep = &histogram[(R + iR) * MR + (G + iG) * MG + B];
+		for (iB = 0; iB < BOX_B_ELEMS; iB++)
+		  {
+		      *cachep++ = (*cptr++) + 1;
+		  }
+	    }
+      }
+}
+
+/*  This is pass 1  */
+static void
+median_cut_pass1_rgb (QuantizeObj * quantobj, rasterliteImagePtr image)
+{
+    generate_histogram_rgb (quantobj->histogram, image);
+    select_colors_rgb (quantobj, quantobj->histogram);
+}
+
+
+/* Map some rows of pixels to the output colormapped representation. */
+static void
+median_cut_pass2_rgb (QuantizeObj * quantobj, rasterliteImagePtr image)
+ /* This version performs no dithering */
+{
+    Histogram histogram = quantobj->histogram;
+    ColorFreq *cachep;
+    int R, G, B;
+    int origR, origG, origB;
+    int row, col;
+    int width = image->sx;
+    int height = image->sy;
+    int pixel;
+
+    zero_histogram_rgb (histogram);
+
+    for (row = 0; row < height; row++)
+      {
+	  for (col = 0; col < width; col++)
+	    {
+		/* get pixel value and index into the cache */
+		pixel = image->pixels[row][col];
+		origR = true_color_get_red (pixel);
+		origG = true_color_get_green (pixel);
+		origB = true_color_get_blue (pixel);
+
+		/* get pixel value and index into the cache */
+		R = origR >> R_SHIFT;
+		G = origG >> G_SHIFT;
+		B = origB >> B_SHIFT;
+		cachep = &histogram[R * MR + G * MG + B];
+		/* If we have not seen this color before, find nearest
+		   colormap entry and update the cache */
+		if (*cachep == 0)
+		  {
+		      fill_inverse_cmap_rgb (quantobj, histogram, R, G, B);
+		  }
+		/* Now emit the colormap index for this cell */
+		pixel = quantobj->cmap[*cachep - 1];
+		image->pixels[row][col] = pixel;
+	    }
+      }
+}
+
+static QuantizeObj *
+initialize_median_cut (int num_colors)
+{
+    QuantizeObj *quantobj;
+
+    /* Initialize the data structures */
+    quantobj = malloc (sizeof (QuantizeObj));
+
+    quantobj->histogram = malloc (sizeof (ColorFreq) *
+				  HIST_R_ELEMS * HIST_G_ELEMS * HIST_B_ELEMS);
+    quantobj->desired_number_of_colors = num_colors;
+
+    return quantobj;
+}
+
+static void
+quantize_object_free (QuantizeObj * quantobj)
+{
+    free (quantobj->histogram);
+    free (quantobj);
+}
+
+extern void
+image_resample_as_palette256 (const rasterliteImagePtr img)
+{
+/* applies quantization to the current image, so to get 256 colors */
+    QuantizeObj *quantobj;
+
+    /* If a pointer was sent in, let's use it. */
+    quantobj = initialize_median_cut (256);
+    median_cut_pass1_rgb (quantobj, img);
+    median_cut_pass2_rgb (quantobj, img);
+    quantize_object_free (quantobj);
+}
diff --git a/lib/rasterlite_tiff.c b/lib/rasterlite_tiff.c
index 3447f5b..96f5c29 100644
--- a/lib/rasterlite_tiff.c
+++ b/lib/rasterlite_tiff.c
@@ -3,23 +3,23 @@
 /
 / TIFF auxiliary helpers
 /
-/ version 1.0, 2009 June 1
+/ version 1.1, 2010 April 27
 /
 / Author: Sandro Furieri a.furieri at lqt.it
 /
 / Copyright (C) 2009  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
+/    it under the terms of the GNU Lesser 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.
+/    GNU Lesser General Public License for more details.
 /
-/    You should have received a copy of the GNU General Public License
+/    You should have received a copy of the GNU Lesser General Public License
 /    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 /
 */
@@ -60,7 +60,7 @@ readproc (thandle_t clientdata, tdata_t data, tsize_t size)
 	return 0;
     len = size;
     if ((mem->current + size) >= (toff_t) mem->eof)
-	len = mem->eof - mem->current;
+	len = (tsize_t) (mem->eof - mem->current);
     memcpy (data, mem->buffer + mem->current, len);
     mem->current += len;
     return len;
@@ -76,7 +76,7 @@ writeproc (thandle_t clientdata, tdata_t data, tsize_t size)
     memcpy (mem->buffer + mem->current, (unsigned char *) data, size);
     mem->current += size;
     if (mem->current > (toff_t) mem->eof)
-	mem->eof = mem->current;
+	mem->eof = (tsize_t) (mem->current);
     return size;
 }
 
@@ -92,14 +92,14 @@ seekproc (thandle_t clientdata, toff_t offset, int whence)
 	      return (toff_t) - 1;
 	  mem->current += offset;
 	  if ((toff_t) mem->eof < mem->current)
-	      mem->eof = mem->current;
+	      mem->eof = (tsize_t) (mem->current);
 	  break;
       case SEEK_END:
 	  if ((int) (mem->eof + offset) < 0)
 	      return (toff_t) - 1;
 	  mem->current = mem->eof + offset;
-	  if ((off_t) mem->eof < mem->current)
-	      mem->eof = mem->current;
+	  if ((toff_t) mem->eof < mem->current)
+	      mem->eof = (tsize_t) (mem->current);
 	  break;
       case SEEK_SET:
       default:
@@ -107,7 +107,7 @@ seekproc (thandle_t clientdata, toff_t offset, int whence)
 	      return (toff_t) - 1;
 	  mem->current = offset;
 	  if ((toff_t) mem->eof < mem->current)
-	      mem->eof = mem->current;
+	      mem->eof = (tsize_t) (mem->current);
 	  break;
       };
     return mem->current;
@@ -147,7 +147,7 @@ unmapproc (thandle_t clientdata, tdata_t data, toff_t offset)
 }
 
 extern void *
-image_to_tiff_fax4 (const rasterliteImagePrt img, int *size)
+image_to_tiff_fax4 (const rasterliteImagePtr img, int *size)
 {
 /* compressing a bi-level (monocrhome) image as TIFF FAX-4 */
     unsigned char *tiff_image = NULL;
@@ -276,7 +276,7 @@ image_to_tiff_fax4 (const rasterliteImagePrt img, int *size)
 }
 
 extern void *
-image_to_tiff_palette (const rasterliteImagePrt img, int *size)
+image_to_tiff_palette (const rasterliteImagePtr img, int *size)
 {
 /* compressing a palettte image as TIFF  PALETTE */
     unsigned char *tiff_image = NULL;
@@ -373,7 +373,7 @@ image_to_tiff_palette (const rasterliteImagePrt img, int *size)
 }
 
 extern void *
-image_to_tiff_grayscale (const rasterliteImagePrt img, int *size)
+image_to_tiff_grayscale (const rasterliteImagePtr img, int *size)
 {
 /* compressing a grayscale image as TIFF  GRAYSCALE */
     unsigned char *tiff_image = NULL;
@@ -439,7 +439,7 @@ image_to_tiff_grayscale (const rasterliteImagePrt img, int *size)
 }
 
 extern void *
-image_to_tiff_rgb (const rasterliteImagePrt img, int *size)
+image_to_tiff_rgb (const rasterliteImagePtr img, int *size)
 {
 /* compressing an RGBimage as TIFF  RGB */
     unsigned char *tiff_image = NULL;
@@ -506,11 +506,11 @@ image_to_tiff_rgb (const rasterliteImagePrt img, int *size)
     return tiff_image;
 }
 
-extern rasterliteImagePrt
+extern rasterliteImagePtr
 image_from_tiff (int size, const void *data)
 {
 /* uncompressing a TIFF */
-    rasterliteImagePrt img;
+    rasterliteImagePtr img;
     uint16 bits_per_sample;
     uint16 samples_per_pixel;
     uint16 photometric;
diff --git a/lib/rasterlite_wavelet.c b/lib/rasterlite_wavelet.c
index 8defd8d..45617ca 100644
--- a/lib/rasterlite_wavelet.c
+++ b/lib/rasterlite_wavelet.c
@@ -3,23 +3,23 @@
 /
 / WAVELET auxiliary helpers
 /
-/ version 1.0, 2009 June 5
+/ version 1.1, 2010 April 27
 /
 / Author: Sandro Furieri a.furieri at lqt.it
 /
 / Copyright (C) 2009  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
+/    it under the terms of the GNU Lesser 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.
+/    GNU Lesser General Public License for more details.
 /
-/    You should have received a copy of the GNU General Public License
+/    You should have received a copy of the GNU Lesser General Public License
 /    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 /
 */
@@ -58,7 +58,7 @@ typedef struct decode_ctx_tag
     int H;
     int max_block_w;
     int max_block_h;
-    rasterliteImagePrt img;
+    rasterliteImagePtr img;
     int image_type;
     unsigned char *input;
     int in_size;
@@ -80,7 +80,7 @@ typedef struct encode_ctx_tag
     int resample;
     int W;
     int H;
-    rasterliteImagePrt img;
+    rasterliteImagePtr img;
     int image_type;
     unsigned char *output;
     int out_size;
@@ -180,34 +180,38 @@ guess_wavelet_type (decode_ctx * ctx, int *ext_type, int *width, int *height,
 	    }
 /* Image width */
 	  if (W == -1)
-	      W = type == EPS_GRAYSCALE_BLOCK ? hdr.gs.W : hdr.tc.W;
+	      W = type ==
+		  EPS_GRAYSCALE_BLOCK ? hdr.hdr_data.gs.W : hdr.hdr_data.tc.W;
 	  else
 	    {
-		if (type == EPS_GRAYSCALE_BLOCK ? W != hdr.gs.W : W != hdr.tc.W)
+		if (type == EPS_GRAYSCALE_BLOCK ? W != hdr.hdr_data.gs.W : W !=
+		    hdr.hdr_data.tc.W)
 		    return 0;
 	    }
 /* Image height */
 	  if (H == -1)
-	      H = type == EPS_GRAYSCALE_BLOCK ? hdr.gs.H : hdr.tc.H;
+	      H = type ==
+		  EPS_GRAYSCALE_BLOCK ? hdr.hdr_data.gs.H : hdr.hdr_data.tc.H;
 	  else
 	    {
-		if (type == EPS_GRAYSCALE_BLOCK ? H != hdr.gs.H : H != hdr.tc.H)
+		if (type == EPS_GRAYSCALE_BLOCK ? H != hdr.hdr_data.gs.H : H !=
+		    hdr.hdr_data.tc.H)
 		    return 0;
 	    }
 /* Maximal block width and height */
 	  if (type == EPS_GRAYSCALE_BLOCK)
 	    {
-		if (hdr.gs.w > w)
-		    w = hdr.gs.w;
-		if (hdr.gs.h > h)
-		    h = hdr.gs.h;
+		if (hdr.hdr_data.gs.w > w)
+		    w = hdr.hdr_data.gs.w;
+		if (hdr.hdr_data.gs.h > h)
+		    h = hdr.hdr_data.gs.h;
 	    }
 	  else
 	    {
-		if (hdr.tc.w > w)
-		    w = hdr.tc.w;
-		if (hdr.tc.h > h)
-		    h = hdr.tc.h;
+		if (hdr.hdr_data.tc.w > w)
+		    w = hdr.hdr_data.tc.w;
+		if (hdr.hdr_data.tc.h > h)
+		    h = hdr.hdr_data.tc.h;
 	    }
       }
 /* Rewind file and free buffer */
@@ -227,7 +231,7 @@ guess_wavelet_type (decode_ctx * ctx, int *ext_type, int *width, int *height,
 }
 
 static int
-encoder_read_grayscale (rasterliteImagePrt img, unsigned char **Y, int x,
+encoder_read_grayscale (rasterliteImagePtr img, unsigned char **Y, int x,
 			int y, int width, int height)
 {
 /* fetching GRAYSCALE pixels from the uncompressed image */
@@ -262,7 +266,7 @@ encoder_read_grayscale (rasterliteImagePrt img, unsigned char **Y, int x,
 }
 
 static int
-encoder_read_rgb (rasterliteImagePrt img, unsigned char **R, unsigned char **G,
+encoder_read_rgb (rasterliteImagePtr img, unsigned char **R, unsigned char **G,
 		  unsigned char **B, int x, int y, int width, int height)
 {
 /* fetching RGB pixels from the uncompressed image */
@@ -299,7 +303,7 @@ encoder_read_rgb (rasterliteImagePrt img, unsigned char **R, unsigned char **G,
 }
 
 static int
-decoder_write_grayscale (rasterliteImagePrt img, unsigned char **Y, int x,
+decoder_write_grayscale (rasterliteImagePtr img, unsigned char **Y, int x,
 			 int y, int width, int height)
 {
 /* feeding grayscale pixels into the uncompressed image */
@@ -332,7 +336,7 @@ decoder_write_grayscale (rasterliteImagePrt img, unsigned char **Y, int x,
 }
 
 static int
-decoder_write_rgb (rasterliteImagePrt img, unsigned char **R,
+decoder_write_rgb (rasterliteImagePtr img, unsigned char **R,
 		   unsigned char **G, unsigned char **B, int x, int y,
 		   int width, int height)
 {
@@ -490,8 +494,9 @@ encode_blocks (encode_ctx * ctx)
 		      /* Encode block */
 		      if (eps_encode_truecolor_block
 			  (R, G, B, W, H, w, h, x, y, ctx->resample, buf,
-			   &buf_size, ctx->Y_ratio, ctx->Cb_ratio,
-			   ctx->Cr_ratio, ctx->filter_id, ctx->mode) != EPS_OK)
+			   &buf_size, (int) (ctx->Y_ratio),
+			   (int) (ctx->Cb_ratio), (int) (ctx->Cr_ratio),
+			   ctx->filter_id, ctx->mode) != EPS_OK)
 			{
 			    /* All function parameters are checked at the moment,  so everything except EPS_OK is a logical error. */
 			    error_flag = 1;
@@ -536,7 +541,7 @@ encode_blocks (encode_ctx * ctx)
 }
 
 static void *
-wavelet_compress (rasterliteImagePrt img, int *size, int ratio, int image_type)
+wavelet_compress (rasterliteImagePtr img, int *size, int ratio, int image_type)
 {
 /* preparing the compression */
     int W;
@@ -686,7 +691,7 @@ decode_blocks (decode_ctx * ctx)
 	  if (ctx->image_type == IMAGE_WAVELET_BW)
 	    {
 		/* Skip over broken blocks */
-		if ((hdr.gs.W != W) || (hdr.gs.H != H))
+		if ((hdr.hdr_data.gs.W != W) || (hdr.hdr_data.gs.H != H))
 		    continue;
 		/* All function parameters are checked at the moment so everything except EPS_OK is a logical error. */
 		rc = eps_decode_grayscale_block (Y, buf, &hdr);
@@ -697,7 +702,8 @@ decode_blocks (decode_ctx * ctx)
 		      goto error;
 		  }
 		if (!decoder_write_grayscale
-		    (ctx->img, Y, hdr.gs.x, hdr.gs.y, hdr.gs.w, hdr.gs.h))
+		    (ctx->img, Y, hdr.hdr_data.gs.x, hdr.hdr_data.gs.y,
+		     hdr.hdr_data.gs.w, hdr.hdr_data.gs.h))
 		  {
 		      error_flag = 1;
 		      fprintf (stderr, "Wavelet-wrapper: cannot write block\n");
@@ -707,7 +713,7 @@ decode_blocks (decode_ctx * ctx)
 	  else
 	    {
 		/* Skip over broken blocks */
-		if ((hdr.tc.W != W) || (hdr.tc.H != H))
+		if ((hdr.hdr_data.tc.W != W) || (hdr.hdr_data.tc.H != H))
 		    continue;
 		/* Decode block */
 		rc = eps_decode_truecolor_block (R, G, B, buf, &hdr);
@@ -719,7 +725,8 @@ decode_blocks (decode_ctx * ctx)
 		  }
 		/* Write encoded block */
 		if (!decoder_write_rgb
-		    (ctx->img, R, G, B, hdr.tc.x, hdr.tc.y, hdr.tc.w, hdr.tc.h))
+		    (ctx->img, R, G, B, hdr.hdr_data.tc.x, hdr.hdr_data.tc.y,
+		     hdr.hdr_data.tc.w, hdr.hdr_data.tc.h))
 		  {
 		      error_flag = 1;
 		      fprintf (stderr, "Wavelet-wrapper: cannot write block\n");
@@ -775,11 +782,11 @@ check_footer (const void *data, int size)
     return 0;
 }
 
-static rasterliteImagePrt
+static rasterliteImagePtr
 wavelet_uncompress (int size, const void *data)
 {
 /* preparing the decompression */
-    rasterliteImagePrt img;
+    rasterliteImagePtr img;
     int ret;
     decode_ctx ctx;
 /* Input buffer size */
@@ -858,24 +865,24 @@ wavelet_uncompress (int size, const void *data)
 }
 
 extern void *
-image_to_wavelet (const rasterliteImagePrt img, int *size, int ratio)
+image_to_wavelet (const rasterliteImagePtr img, int *size, int ratio)
 {
 /* compressing an image as WAVELET RGB */
     return wavelet_compress (img, size, ratio, IMAGE_WAVELET_RGB);
 }
 
 extern void *
-image_to_wavelet_grayscale (const rasterliteImagePrt img, int *size, int ratio)
+image_to_wavelet_grayscale (const rasterliteImagePtr img, int *size, int ratio)
 {
 /* compressing an image as JPEG WAVELET GRAYSCALE */
     return wavelet_compress (img, size, ratio, IMAGE_WAVELET_BW);
 }
 
-extern rasterliteImagePrt
+extern rasterliteImagePtr
 image_from_wavelet (int size, const void *data)
 {
 /* uncompressing a WAVELET compressed image */
-    rasterliteImagePrt img;
+    rasterliteImagePtr img;
     img = wavelet_uncompress (size, data);
     return img;
 }
diff --git a/librasterlite.def b/librasterlite.def
new file mode 100644
index 0000000..d381fad
--- /dev/null
+++ b/librasterlite.def
@@ -0,0 +1,26 @@
+LIBRARY rasterlite.dll
+EXPORTS
+rasterliteClose
+rasterliteExportGeoTiff
+rasterliteGetBackgroundColor
+rasterliteGetBestAccess
+rasterliteGetExtent
+rasterliteGetLastError
+rasterliteGetLevels
+rasterliteGetPath
+rasterliteGetRaster
+rasterliteGetRaster2
+rasterliteGetRasterByRect
+rasterliteGetRasterByRect2
+rasterliteGetResolution
+rasterliteGetSpatialiteVersion
+rasterliteGetSqliteVersion
+rasterliteGetSrid
+rasterliteGetTablePrefix
+rasterliteGetTransparentColor
+rasterliteHasTransparentColor
+rasterliteIsError
+rasterliteOpen
+rasterliteSetBackgroundColor
+rasterliteSetTransparentColor
+rasterliteWaveletToPng
diff --git a/makefile.vc b/makefile.vc
new file mode 100644
index 0000000..b982398
--- /dev/null
+++ b/makefile.vc
@@ -0,0 +1,98 @@
+# $Id: makefile.vc 2009/11/18 Sandro Furieri $
+#
+# NMAKE Makefile to build librasterlite on Windows
+#
+!INCLUDE nmake.opt
+
+OBJ_EXT = obj
+EXT = $(OBJ_EXT)
+
+LIBOBJ = lib\rasterlite.$(EXT) lib\rasterlite_gif.$(EXT) \
+	lib\rasterlite_png.$(EXT) lib\rasterlite_jpeg.$(EXT) \
+	lib\rasterlite_tiff.$(EXT) lib\rasterlite_wavelet.$(EXT) \
+	lib\rasterlite_io.$(EXT) lib\rasterlite_image.$(EXT) \
+	epsilon\bit_io.$(EXT) epsilon\checksum.$(EXT) \
+	epsilon\cobs.$(EXT) epsilon\color.$(EXT) epsilon\common.$(EXT) \
+	epsilon\dc_level.$(EXT) epsilon\filter.$(EXT) \
+	epsilon\filterbank.$(EXT) epsilon\libmain.$(EXT) \
+	epsilon\list.$(EXT) epsilon\mem_alloc.$(EXT) \
+	epsilon\merge_split.$(EXT) epsilon\pad.$(EXT) \
+	epsilon\resample.$(EXT) epsilon\speck.$(EXT)
+RASTERLITE_DLL 	       =	rasterlite$(VERSION).dll
+
+CFLAGS	=	/nologo -IC:\OSGeo4W\include -I.\headers -I.\epsilon -I.\epsilon\msvc $(OPTFLAGS)
+
+default:	all
+
+all: rasterlite.lib rasterlite_i.lib rasterlite_grid.exe rasterlite_load.exe \
+	rasterlite_pyramid.exe rasterlite_tool.exe rasterlite_topmost.exe
+
+rasterlite.lib:	$(LIBOBJ)
+	if exist rasterlite.lib del rasterlite.lib
+	lib /out:rasterlite.lib $(LIBOBJ)
+
+$(RASTERLITE_DLL):	rasterlite_i.lib
+
+rasterlite_i.lib:	$(LIBOBJ)
+	link /debug /dll /def:librasterlite.def /out:$(RASTERLITE_DLL) \
+		/implib:rasterlite_i.lib $(LIBOBJ) \
+		C:\OSGeo4W\lib\jpeg_i.lib C:\OSGeo4W\lib\libtiff_i.lib \
+		C:\OSGeo4W\lib\libpng13.lib C:\OSGeo4W\lib\zlib.lib \
+		C:\OSGeo4W\lib\geotiff_i.lib C:\OSGeo4W\lib\spatialite_i.lib
+	if exist $(RASTERLITE_DLL).manifest mt -manifest \
+		$(RASTERLITE_DLL).manifest -outputresource:$(RASTERLITE_DLL);2
+
+rasterlite_grid.exe: $(RASTERLITE_DLL) src\rasterlite_grid.obj
+	link /debug src\rasterlite_grid.obj $(LIBOBJ) \
+	C:\OSGeo4W\lib\jpeg_i.lib C:\OSGeo4W\lib\libtiff_i.lib \
+	C:\OSGeo4W\lib\libpng13.lib C:\OSGeo4W\lib\zlib.lib \
+	C:\OSGeo4W\lib\geotiff_i.lib C:\OSGeo4W\lib\spatialite_i.lib
+
+rasterlite_load.exe: $(RASTERLITE_DLL) src\rasterlite_load.obj
+	link /debug src\rasterlite_load.obj $(LIBOBJ) \
+	C:\OSGeo4W\lib\jpeg_i.lib C:\OSGeo4W\lib\libtiff_i.lib \
+	C:\OSGeo4W\lib\libpng13.lib C:\OSGeo4W\lib\zlib.lib \
+	C:\OSGeo4W\lib\geotiff_i.lib C:\OSGeo4W\lib\spatialite_i.lib
+
+rasterlite_pyramid.exe: $(RASTERLITE_DLL) src\rasterlite_pyramid.obj
+	link /debug src\rasterlite_pyramid.obj $(LIBOBJ) \
+	C:\OSGeo4W\lib\jpeg_i.lib C:\OSGeo4W\lib\libtiff_i.lib \
+	C:\OSGeo4W\lib\libpng13.lib C:\OSGeo4W\lib\zlib.lib \
+	C:\OSGeo4W\lib\geotiff_i.lib C:\OSGeo4W\lib\spatialite_i.lib
+
+rasterlite_tool.exe: $(RASTERLITE_DLL) src\rasterlite_tool.obj
+	link /debug src\rasterlite_tool.obj $(LIBOBJ) \
+	C:\OSGeo4W\lib\jpeg_i.lib C:\OSGeo4W\lib\libtiff_i.lib \
+	C:\OSGeo4W\lib\libpng13.lib C:\OSGeo4W\lib\zlib.lib \
+	C:\OSGeo4W\lib\geotiff_i.lib C:\OSGeo4W\lib\spatialite_i.lib
+	
+rasterlite_topmost.exe: $(RASTERLITE_DLL) src\rasterlite_topmost.obj
+	link /debug src\rasterlite_topmost.obj $(LIBOBJ) \
+	C:\OSGeo4W\lib\jpeg_i.lib C:\OSGeo4W\lib\libtiff_i.lib \
+	C:\OSGeo4W\lib\libpng13.lib C:\OSGeo4W\lib\zlib.lib \
+	C:\OSGeo4W\lib\geotiff_i.lib C:\OSGeo4W\lib\spatialite_i.lib
+		
+.c.obj:
+	$(CC) $(CFLAGS) /c $*.c /Fo$@
+
+clean:
+	del *.dll
+	del *.exp
+	del *.manifest
+	del *.lib
+	del lib\*.obj
+	del epsilon\*.obj
+	del src\*.obj
+	del *.exe
+	del *.pdb
+
+install: all
+	-mkdir $(INSTDIR)
+	-mkdir $(INSTDIR)\bin
+	-mkdir $(INSTDIR)\lib
+	-mkdir $(INSTDIR)\include
+	copy *.dll $(INSTDIR)\bin
+	copy *.lib $(INSTDIR)\lib
+	copy *.exe $(INSTDIR)\bin
+	copy headers\rasterlite.h $(INSTDIR)\include
+	
diff --git a/nmake.opt b/nmake.opt
new file mode 100644
index 0000000..8472e1c
--- /dev/null
+++ b/nmake.opt
@@ -0,0 +1,12 @@
+# Directory tree where RasterLite will be installed.
+INSTDIR=C:\OSGeo4W
+
+# Uncomment the first for an optimized build, or the second for debug.
+OPTFLAGS=	/nologo /Ox /fp:precise /W3 /MD /D_CRT_SECURE_NO_WARNINGS \
+		/D_LARGE_FILE=1 /D_FILE_OFFSET_BITS=64 /D_LARGEFILE_SOURCE=1 
+#OPTFLAGS=	/nologo /Zi /MD /Fdrasterlite.pdb
+
+# Set the version number for the DLL.  Normally we leave this blank since
+# we want software that is dynamically loading the DLL to have no problem
+# with version numbers.
+VERSION=
diff --git a/src/rasterlite_grid.c b/src/rasterlite_grid.c
index 8269ab8..fa7e436 100644
--- a/src/rasterlite_grid.c
+++ b/src/rasterlite_grid.c
@@ -3,7 +3,7 @@
 /
 / a tool generating a GeoTIFF from am ASCII or BINARY Grid 
 /
-/ version 1.0, 2009 June 28
+/ version 1.1, 2010 April 27
 /
 / Author: Sandro Furieri a.furieri at lqt.it
 /
@@ -45,6 +45,10 @@
 #include <dirent.h>
 #endif
 
+#ifdef _WIN32
+#define strcasecmp	_stricmp
+#endif /* not WIN32 */
+
 #define ARG_NONE			0
 #define ARG_GRID_PATH		1
 #define ARG_COLOR_PATH		2
@@ -53,6 +57,11 @@
 #define ARG_EPSG_CODE		5
 #define ARG_NODATA_COLOR	6
 #define ARG_PROJ4TEXT		7
+#define ARG_MONO_COLOR		9
+#define ARG_Z_FACTOR		10
+#define ARG_SCALE			11
+#define ARG_AZIMUTH			12
+#define ARG_ALTITUDE		13
 
 #define ASCII_GRID	100
 #define FLOAT_GRID	101
@@ -63,6 +72,7 @@
 
 struct colorTable
 {
+/* a color table value range */
     double min;
     double max;
     unsigned char red;
@@ -70,6 +80,472 @@ struct colorTable
     unsigned char blue;
 };
 
+struct triple_scan
+{
+/* the 3-scanlines object for Shaded Relief */
+    int ncols;
+    double z_factor;
+    double scale_factor;
+    double altitude;
+    double azimuth;
+    int mono_color;
+    unsigned char mono_red;
+    unsigned char mono_green;
+    unsigned char mono_blue;
+    float no_data_value;
+    unsigned char no_red;
+    unsigned char no_green;
+    unsigned char no_blue;
+    float *row1;
+    float *row2;
+    float *row3;
+    float *current_row;
+};
+
+static int
+cmp_color_qsort (const void *p1, const void *p2)
+{
+/* compares two colorTable entries [for QSORT] */
+    struct colorTable *pc1 = (struct colorTable *) p1;
+    struct colorTable *pc2 = (struct colorTable *) p2;
+    if (pc1->min > pc2->min)
+	return 1;
+    if (pc1->min < pc2->min)
+	return -1;
+    if (pc1->max > pc2->max)
+	return 1;
+    if (pc1->max < pc2->max)
+	return -1;
+    return 0;
+}
+
+static int
+cmp_color_bsearch (const void *p1, const void *p2)
+{
+/* compares two colorTable entries [for BSEARCH] */
+    struct colorTable *pc1 = (struct colorTable *) p1;
+    struct colorTable *pc2 = (struct colorTable *) p2;
+    if (pc1->min >= pc2->min && pc1->min <= pc2->max)
+	return 0;
+    if (pc1->min > pc2->min)
+	return 1;
+    if (pc1->min < pc2->min)
+	return -1;
+    if (pc1->min > pc2->max)
+	return 1;
+    if (pc1->min < pc2->max)
+	return -1;
+    return 0;
+}
+
+static int
+match_color (struct colorTable *color_table, int colors, double value,
+	     unsigned char *red, unsigned char *green, unsigned char *blue)
+{
+/* mapping a value into the corresponding color */
+    struct colorTable *ret;
+    struct colorTable src;
+    src.min = value;
+    ret =
+	bsearch (&src, color_table, colors, sizeof (struct colorTable),
+		 cmp_color_bsearch);
+    if (ret)
+      {
+	  *red = ret->red;
+	  *green = ret->green;
+	  *blue = ret->blue;
+	  return 1;
+      }
+    return 0;
+}
+
+static struct triple_scan *
+triple_alloc (int ncols)
+{
+/* allocating the 3-scanlines object */
+    struct triple_scan *p = malloc (sizeof (struct triple_scan));
+    p->ncols = ncols;
+    p->row1 = malloc (sizeof (float) * ncols);
+    p->row2 = malloc (sizeof (float) * ncols);
+    p->row3 = malloc (sizeof (float) * ncols);
+    p->current_row = p->row1;
+    p->mono_color = 0;
+    p->mono_red = 0;
+    p->mono_green = 0;
+    p->mono_blue = 0;
+    p->no_data_value = 0.0;
+    p->no_red = 0;
+    p->no_green = 0;
+    p->no_blue = 0;
+    p->z_factor = 1.0;
+    p->scale_factor = 1.0;
+    p->altitude = 45.0;
+    p->azimuth = 315.0;
+    return p;
+}
+
+static void
+triple_free (struct triple_scan *p)
+{
+/* freeing the 3-scanlines object */
+    free (p->row1);
+    free (p->row2);
+    free (p->row3);
+    free (p);
+}
+
+static void
+triple_set_no_data (struct triple_scan *p, float no_data_value,
+		    unsigned char no_red, unsigned char no_green,
+		    unsigned char no_blue)
+{
+/* setting NODATA params */
+    p->no_data_value = no_data_value;
+    p->no_red = no_red;
+    p->no_green = no_green;
+    p->no_blue = no_blue;
+}
+
+static void
+triple_set_monochrome_params (struct triple_scan *p, int mono_color,
+			      unsigned char mono_red, unsigned char mono_green,
+			      unsigned char mono_blue)
+{
+/* setting ShadedRelief params */
+    p->mono_color = mono_color;
+    p->mono_red = mono_red;
+    p->mono_green = mono_green;
+    p->mono_blue = mono_blue;
+}
+
+static void
+triple_set_shaded_relief_params (struct triple_scan *p, double z, double scale,
+				 double alt, double az)
+{
+/* setting ShadedRelief params */
+    p->z_factor = z;
+    p->scale_factor = scale;
+    p->altitude = alt;
+    p->azimuth = az;
+}
+
+static void
+triple_rotate (struct triple_scan *p)
+{
+/* rotating the 3-scanlines */
+    if (p->current_row == p->row1)
+      {
+	  p->current_row = p->row2;
+	  goto zero_init;
+      }
+    if (p->current_row == p->row2)
+      {
+	  p->current_row = p->row3;
+	  goto zero_init;
+      }
+    p->current_row = p->row1;
+    p->row1 = p->row2;
+    p->row2 = p->row3;
+    p->row3 = p->current_row;
+  zero_init:
+    memset (p->current_row, 0, sizeof (float) * p->ncols);
+}
+
+static void
+triple_store_cell (struct triple_scan *p, int icol, float value)
+{
+/* storing a cell value into 3-scanlines */
+    if (icol < 0 || icol >= p->ncols)
+	return;
+    *(p->current_row + icol) = value;
+}
+
+static int
+triple_is_valid (struct triple_scan *p)
+{
+/* checking for validitity */
+    if (p->current_row == p->row3)
+	return 1;
+    return 0;
+}
+
+static void
+triple_shaded_relief (struct triple_scan *p, unsigned char *raster)
+{
+/* creating a shaded relief scanline */
+    int j;
+    int n;
+    double x;
+    double y;
+    double aspect;
+    double slope;
+    double cang;
+    int gray;
+    float afWin[9];
+    const double degreesToRadians = M_PI / 180.0;
+    const double altRadians = p->altitude * degreesToRadians;
+    const double azRadians = p->azimuth * degreesToRadians;
+    double red;
+    double green;
+    double blue;
+    double alpha;
+    int bContainsNull;
+    unsigned char *p_raster = raster;
+    unsigned char r;
+    unsigned char g;
+    unsigned char b;
+
+/*
+/ Move a 3x3 pafWindow over each cell 
+/ (where the cell in question is #4)
+/ 
+/      0 1 2
+/      3 4 5
+/      6 7 8
+*/
+    for (j = 0; j < p->ncols; j++)
+      {
+	  /* Exclude the edges */
+	  if (j == 0 || j == p->ncols - 1)
+	      continue;
+
+	  bContainsNull = 0;
+
+	  afWin[0] = p->row1[j - 1];
+	  afWin[1] = p->row1[j];
+	  afWin[2] = p->row1[j + 1];
+	  afWin[3] = p->row2[j - 1];
+	  afWin[4] = p->row2[j];
+	  afWin[5] = p->row2[j + 1];
+	  afWin[6] = p->row3[j - 1];
+	  afWin[7] = p->row3[j];
+	  afWin[8] = p->row3[j + 1];
+
+	  for (n = 0; n <= 8; n++)
+	    {
+		if (afWin[n] == p->no_data_value)
+		  {
+		      bContainsNull = 1;
+		      break;
+		  }
+	    }
+
+	  if (bContainsNull)
+	    {
+		/* We have nulls so write nullValue and move on */
+		r = p->no_red;
+		g = p->no_green;
+		b = p->no_blue;
+	    }
+	  else
+	    {
+		/* We have a valid 3x3 window. */
+
+		/* ---------------------------------------
+		 * Compute Hillshade
+		 */
+
+		/* First Slope ... */
+		x = p->z_factor * ((afWin[0] + afWin[3] + afWin[3] + afWin[6]) -
+				   (afWin[2] + afWin[5] + afWin[5] +
+				    afWin[8])) / (8.0 * p->scale_factor);
+
+		y = p->z_factor * ((afWin[6] + afWin[7] + afWin[7] + afWin[8]) -
+				   (afWin[0] + afWin[1] + afWin[1] +
+				    afWin[2])) / (8.0 * p->scale_factor);
+
+		slope = M_PI / 2 - atan (sqrt (x * x + y * y));
+
+		/* ... then aspect... */
+		aspect = atan2 (x, y);
+
+		/* ... then the shade value */
+		cang = sin (altRadians) * sin (slope) +
+		    cos (altRadians) * cos (slope) *
+		    cos (azRadians - M_PI / 2 - aspect);
+
+		if (cang <= 0.0)
+		    cang = 1.0;
+		else
+		    cang = 1.0 + (254.0 * cang);
+
+		if (p->mono_color)
+		  {
+		      /* using the monochrome base color + ALPHA */
+		      alpha = cang / 255.0;
+		      red = (double) (p->mono_red) * alpha;
+		      green = (double) (p->mono_green) * alpha;
+		      blue = (double) (p->mono_blue) * alpha;
+		      if (red < 0.0)
+			  red = 0.0;
+		      if (green < 0.0)
+			  green = 0.0;
+		      if (blue < 0.0)
+			  blue = 0.0;
+		      if (red > 255.0)
+			  red = 255.0;
+		      if (green > 255.0)
+			  green = 255.0;
+		      if (blue > 255.0)
+			  blue = 255.0;
+		      r = (unsigned char) red;
+		      g = (unsigned char) green;
+		      b = (unsigned) blue;
+		  }
+		else
+		  {
+		      /* plain gray-scale */
+		      gray = (int) cang;
+		      r = (unsigned char) gray;
+		      g = (unsigned char) gray;
+		      b = (unsigned) gray;
+		  }
+	    }
+	  *p_raster++ = r;
+	  *p_raster++ = g;
+	  *p_raster++ = b;
+      }
+}
+
+static int
+triple_shaded_relief_color (struct colorTable *color_table, int colors,
+			    struct triple_scan *p, unsigned char *raster,
+			    int row)
+{
+/* creating a shaded relief color scanline */
+    int j;
+    int n;
+    double x;
+    double y;
+    double aspect;
+    double slope;
+    double cang;
+    float afWin[9];
+    const double degreesToRadians = M_PI / 180.0;
+    const double altRadians = p->altitude * degreesToRadians;
+    const double azRadians = p->azimuth * degreesToRadians;
+    double red;
+    double green;
+    double blue;
+    double alpha;
+    double thisValue;
+    int bContainsNull;
+    unsigned char *p_raster = raster;
+    unsigned char r;
+    unsigned char g;
+    unsigned char b;
+
+/*
+/ Move a 3x3 pafWindow over each cell 
+/ (where the cell in question is #4)
+/ 
+/      0 1 2
+/      3 4 5
+/      6 7 8
+*/
+    for (j = 0; j < p->ncols; j++)
+      {
+	  /* Exclude the edges */
+	  if (j == 0 || j == p->ncols - 1)
+	      continue;
+
+	  bContainsNull = 0;
+
+	  afWin[0] = p->row1[j - 1];
+	  afWin[1] = p->row1[j];
+	  afWin[2] = p->row1[j + 1];
+	  afWin[3] = p->row2[j - 1];
+	  afWin[4] = p->row2[j];
+	  afWin[5] = p->row2[j + 1];
+	  afWin[6] = p->row3[j - 1];
+	  afWin[7] = p->row3[j];
+	  afWin[8] = p->row3[j + 1];
+
+	  thisValue = afWin[4];
+
+	  for (n = 0; n <= 8; n++)
+	    {
+		if (afWin[n] == p->no_data_value)
+		  {
+		      bContainsNull = 1;
+		      break;
+		  }
+	    }
+
+	  if (bContainsNull)
+	    {
+		/* We have nulls so write nullValue and move on */
+		r = p->no_red;
+		g = p->no_green;
+		b = p->no_blue;
+	    }
+	  else
+	    {
+		/* We have a valid 3x3 window. */
+
+		/* ---------------------------------------
+		 * Compute Hillshade
+		 */
+
+		/* First Slope ... */
+		x = p->z_factor * ((afWin[0] + afWin[3] + afWin[3] + afWin[6]) -
+				   (afWin[2] + afWin[5] + afWin[5] +
+				    afWin[8])) / (8.0 * p->scale_factor);
+
+		y = p->z_factor * ((afWin[6] + afWin[7] + afWin[7] + afWin[8]) -
+				   (afWin[0] + afWin[1] + afWin[1] +
+				    afWin[2])) / (8.0 * p->scale_factor);
+
+		slope = M_PI / 2 - atan (sqrt (x * x + y * y));
+
+		/* ... then aspect... */
+		aspect = atan2 (x, y);
+
+		/* ... then the shade value */
+		cang = sin (altRadians) * sin (slope) +
+		    cos (altRadians) * cos (slope) *
+		    cos (azRadians - M_PI / 2 - aspect);
+
+		if (cang <= 0.0)
+		    cang = 1.0;
+		else
+		    cang = 1.0 + (254.0 * cang);
+
+		/* merging the color + ALPHA */
+		if (!match_color (color_table, colors, thisValue, &r, &g, &b))
+		  {
+		      printf
+			  ("Grid row %d: unmatched value %1.8f; color not found\n",
+			   row, thisValue);
+		      return 0;
+		  }
+		alpha = cang / 255.0;
+		red = (double) r *alpha;
+		green = (double) g *alpha;
+		blue = (double) b *alpha;
+		if (red < 0.0)
+		    red = 0.0;
+		if (green < 0.0)
+		    green = 0.0;
+		if (blue < 0.0)
+		    blue = 0.0;
+		if (red > 255.0)
+		    red = 255.0;
+		if (green > 255.0)
+		    green = 255.0;
+		if (blue > 255.0)
+		    blue = 255.0;
+		r = (unsigned char) red;
+		g = (unsigned char) green;
+		b = (unsigned) blue;
+	    }
+	  *p_raster++ = r;
+	  *p_raster++ = g;
+	  *p_raster++ = b;
+      }
+    return 1;
+}
+
 static int
 parse_hex (const char hi, const char lo)
 {
@@ -350,7 +826,7 @@ parse_color_line (const char *buf, int row_no, double *min, double *max,
 }
 
 static struct colorTable *
-parse_color_table (const char *path)
+parse_color_table (const char *path, int *count)
 {
 /* parsing the Color Table */
     double min;
@@ -400,13 +876,7 @@ parse_color_table (const char *path)
       }
     if (lines == 0 || error > 0)
 	return NULL;
-    table = malloc (sizeof (struct colorTable) * (lines + 1));
-/* marking the last (stop) table item */
-    (table + lines)->min = DBL_MAX;
-    (table + lines)->max = DBL_MAX;
-    (table + lines)->red = 0;
-    (table + lines)->green = 0;
-    (table + lines)->blue = 0;
+    table = malloc (sizeof (struct colorTable) * (lines));
 /* closing and reopening the Color Table file */
     fclose (in);
     in = fopen (path, "rb");
@@ -457,6 +927,9 @@ parse_color_table (const char *path)
 	  table = NULL;
       }
     fclose (in);
+/* sorting the color table */
+    *count = lines;
+    qsort (table, lines, sizeof (struct colorTable), cmp_color_qsort);
     return table;
 }
 
@@ -504,29 +977,7 @@ parseOrderHeader (const char *row, const char *tag, int *value)
 }
 
 static int
-match_color (struct colorTable *color_table, double value, unsigned char *red,
-	     unsigned char *green, unsigned char *blue)
-{
-/* mapping a value into the corresponding color */
-    struct colorTable *p = color_table;
-    while (p)
-      {
-	  if (p->min == DBL_MAX)
-	      return 0;
-	  if (value >= p->min && value <= p->max)
-	    {
-		*red = p->red;
-		*green = p->green;
-		*blue = p->blue;
-		return 1;
-	    }
-	  p++;
-      }
-    return 0;
-}
-
-static int
-fetch_scanline (int row, struct colorTable *color_table, FILE * asc,
+fetch_scanline (int row, struct colorTable *color_table, int colors, FILE * asc,
 		unsigned char *raster, int columns, double nodata,
 		unsigned char no_red, unsigned char no_green,
 		unsigned char no_blue)
@@ -565,7 +1016,8 @@ fetch_scanline (int row, struct colorTable *color_table, FILE * asc,
 		  }
 		else
 		  {
-		      if (match_color (color_table, value, &red, &green, &blue))
+		      if (match_color
+			  (color_table, colors, value, &red, &green, &blue))
 			{
 			    *p_raster++ = red;
 			    *p_raster++ = green;
@@ -653,7 +1105,7 @@ check_endian_arch ()
 }
 
 static int
-fetch_float_scanline (int row, struct colorTable *color_table,
+fetch_float_scanline (int row, struct colorTable *color_table, int colors,
 		      unsigned char *floats, unsigned char *raster, int columns,
 		      double nodata, unsigned char no_red,
 		      unsigned char no_green, unsigned char no_blue,
@@ -679,7 +1131,8 @@ fetch_float_scanline (int row, struct colorTable *color_table,
 	    }
 	  else
 	    {
-		if (match_color (color_table, value, &red, &green, &blue))
+		if (match_color
+		    (color_table, colors, value, &red, &green, &blue))
 		  {
 		      *p_raster++ = red;
 		      *p_raster++ = green;
@@ -699,10 +1152,11 @@ fetch_float_scanline (int row, struct colorTable *color_table,
 }
 
 static void
-export_geoTiff_float (struct colorTable *color_table, const char *proj4text,
-		      const char *grid_path, const char *tiff_path,
-		      unsigned char no_red, unsigned char no_green,
-		      unsigned char no_blue, int verbose)
+export_geoTiff_float (struct colorTable *color_table, int colors,
+		      const char *proj4text, const char *grid_path,
+		      const char *tiff_path, unsigned char no_red,
+		      unsigned char no_green, unsigned char no_blue,
+		      int verbose)
 {
 /* exporting a FLOAT GRID as GeoTIFF */
     TIFF *tiff = NULL;
@@ -856,8 +1310,8 @@ export_geoTiff_float (struct colorTable *color_table, const char *proj4text,
 		goto stop;
 	    }
 	  if (fetch_float_scanline
-	      (row + 1, color_table, flt_buf, raster, ncols, nodata, no_red,
-	       no_green, no_blue, byteorder))
+	      (row + 1, color_table, colors, flt_buf, raster, ncols, nodata,
+	       no_red, no_green, no_blue, byteorder))
 	    {
 		if (TIFFWriteScanline (tiff, raster, row, 0) < 0)
 		  {
@@ -888,10 +1342,11 @@ export_geoTiff_float (struct colorTable *color_table, const char *proj4text,
 }
 
 static void
-export_geoTiff_ascii (struct colorTable *color_table, const char *proj4text,
-		      const char *grid_path, const char *tiff_path,
-		      unsigned char no_red, unsigned char no_green,
-		      unsigned char no_blue, int verbose)
+export_geoTiff_ascii (struct colorTable *color_table, int colors,
+		      const char *proj4text, const char *grid_path,
+		      const char *tiff_path, unsigned char no_red,
+		      unsigned char no_green, unsigned char no_blue,
+		      int verbose)
 {
 /* exporting an ASCII GRID as GeoTIFF */
     TIFF *tiff = NULL;
@@ -1015,7 +1470,7 @@ export_geoTiff_ascii (struct colorTable *color_table, const char *proj4text,
 		fflush (stderr);
 	    }
 	  if (fetch_scanline
-	      (row + 1, color_table, asc, raster, ncols, nodata, no_red,
+	      (row + 1, color_table, colors, asc, raster, ncols, nodata, no_red,
 	       no_green, no_blue))
 	    {
 		if (TIFFWriteScanline (tiff, raster, row, 0) < 0)
@@ -1044,60 +1499,544 @@ export_geoTiff_ascii (struct colorTable *color_table, const char *proj4text,
     fclose (asc);
 }
 
-static void
-do_help ()
+static int
+fetch_float_scanline_shaded (int row, unsigned char *floats, int columns,
+			     int byteorder, struct triple_scan *triplet)
 {
-/* printing the argument list */
-    fprintf (stderr, "\n\nusage: rasterlite_grid ARGLIST\n");
-    fprintf (stderr,
-	     "==============================================================\n");
-    fprintf (stderr,
-	     "-? or --help                      print this help message\n");
-    fprintf (stderr,
-	     "-g or --grid-path     pathname    the Grid path (input)\n");
-    fprintf (stderr,
-	     "-c or --color-path    pathname    the ColorTable path (input)\n");
-    fprintf (stderr,
-	     "-t or --tiff-path     pathname    the GeoTIFF path (output)\n");
-    fprintf (stderr,
-	     "-p or --proj4text     proj4text   the PROJ.4 parameters\n");
-    fprintf (stderr, "-f or --grid-format   grid-type   [ASCII | FLOAT]\n");
-    fprintf (stderr,
-	     "-n or --nodata-color  0xRRGGBB    [default = 0x000000]\n");
-    fprintf (stderr, "-v or --verbose                   verbose output\n");
+/* feeding a TIFF scanline from a FLOAT Grid */
+    int cell = 0;
+    double value;
+    unsigned char *ptr = floats;
+    int endian_arch = check_endian_arch ();
+    for (cell = 0; cell < columns; cell++)
+      {
+	  value = fetch_float (ptr, byteorder, endian_arch);
+	  triple_store_cell (triplet, cell, value);
+	  ptr += sizeof (float);
+      }
+    return 1;
 }
 
-int
-main (int argc, char *argv[])
+static void
+export_geoTiff_shaded_float (struct colorTable *color_table, int colors,
+			     const char *proj4text, const char *grid_path,
+			     const char *tiff_path, unsigned char no_red,
+			     unsigned char no_green, unsigned char no_blue,
+			     int mono_color, unsigned char mono_red,
+			     unsigned char mono_green, unsigned char mono_blue,
+			     double z_factor, double scale_factor,
+			     double azimuth, double altitude, int verbose)
 {
-/* the MAIN function simply perform arguments checking */
-    int i;
-    int next_arg = ARG_NONE;
-    const char *grid_path = NULL;
-    const char *color_path = NULL;
-    const char *tiff_path = NULL;
-    const char *proj4text = NULL;
-    int grid_type = -1;
-    int verbose = 0;
-    int error = 0;
-    struct colorTable *color_table = NULL;
-    unsigned char no_red = 0;
-    unsigned char no_green = 0;
-    unsigned char no_blue = 0;
-    char error_nodata_color[1024];
-    *error_nodata_color = '\0';
-    for (i = 1; i < argc; i++)
+/* exporting a FLOAT GRID as GeoTIFF */
+    TIFF *tiff = NULL;
+    GTIF *gtif = NULL;
+    int byteorder = BYTE_ORDER_NONE;
+    int c;
+    int row = 0;
+    char buf[1024];
+    char path[1024];
+    char *ptr = buf;
+    int err = 0;
+    int ncols = -1;
+    int nrows = -1;
+    double xllcorner = 0.0;
+    double yllcorner = 0.0;
+    double cellsize = 0.0;
+    double nodata = 0.0;
+    double tiepoint[6];
+    double pixsize[3];
+    struct triple_scan *triplet = NULL;
+    unsigned char *raster = NULL;
+    unsigned char *flt_buf = NULL;
+    size_t rd;
+    FILE *grid;
+
+/* parsing the Grid Header .hdr */
+    sprintf (path, "%s.hdr", grid_path);
+    grid = fopen (path, "rb");
+    if (!grid)
       {
-	  /* parsing the invocation arguments */
-	  if (next_arg != ARG_NONE)
+	  printf ("Open error: %s\n", path);
+	  return;
+      }
+    while ((c = getc (grid)) != EOF)
+      {
+	  if (c == '\r')
 	    {
-		switch (next_arg)
+		/* ignoring Return chars */
+		continue;
+	    }
+	  if (c == '\n')
+	    {
+		*ptr = '\0';
+		switch (row)
 		  {
-		  case ARG_GRID_PATH:
-		      grid_path = argv[i];
+		  case 0:
+		      if (!parseIntHeader (buf, "ncols ", &ncols))
+			  err = 1;
 		      break;
-		  case ARG_COLOR_PATH:
-		      color_path = argv[i];
+		  case 1:
+		      if (!parseIntHeader (buf, "nrows ", &nrows))
+			  err = 1;
+		      break;
+		  case 2:
+		      if (!parseDblHeader (buf, "xllcorner ", &xllcorner))
+			  err = 1;
+		      break;
+		  case 3:
+		      if (!parseDblHeader (buf, "yllcorner ", &yllcorner))
+			  err = 1;
+		      break;
+		  case 4:
+		      if (!parseDblHeader (buf, "cellsize ", &cellsize))
+			  err = 1;
+		      break;
+		  case 5:
+		      if (!parseDblHeader (buf, "NODATA_value ", &nodata))
+			  err = 1;
+		      break;
+		  case 6:
+		      if (!parseOrderHeader (buf, "byteorder ", &byteorder))
+			  err = 1;
+		      break;
+		  };
+		ptr = buf;
+		row++;
+		if (row == 7)
+		    break;
+		continue;
+	    }
+	  *ptr++ = c;
+      }
+    if (err)
+      {
+	  /* there was some error */
+	  printf ("Invalid FLOAT Grid Header format in: %s\n", path);
+	  goto stop;
+      }
+    fclose (grid);
+
+/* resizing CellSize */
+    cellsize = (cellsize * (double) ncols) / (double) (ncols - 2);
+
+/* parsing the Grid Cells .flt */
+    sprintf (path, "%s.flt", grid_path);
+    grid = fopen (path, "rb");
+    if (!grid)
+      {
+	  printf ("Open error: %s\n", path);
+	  return;
+      }
+/* creating the GeoTIFF file */
+    tiff = XTIFFOpen (tiff_path, "w");
+    if (!tiff)
+      {
+	  printf ("\tCould not open TIFF image '%s'\n", tiff_path);
+	  goto stop;
+      }
+    gtif = GTIFNew (tiff);
+    if (!gtif)
+      {
+	  printf ("\tCould not open GeoTIFF image '%s'\n", tiff_path);
+	  goto stop;
+      }
+
+/* writing the TIFF Tags */
+    TIFFSetField (tiff, TIFFTAG_IMAGEWIDTH, ncols - 2);
+    TIFFSetField (tiff, TIFFTAG_IMAGELENGTH, nrows - 2);
+    TIFFSetField (tiff, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
+    TIFFSetField (tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
+    TIFFSetField (tiff, TIFFTAG_ROWSPERSTRIP, 1);
+    TIFFSetField (tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+    TIFFSetField (tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
+    TIFFSetField (tiff, TIFFTAG_BITSPERSAMPLE, 8);
+    TIFFSetField (tiff, TIFFTAG_SAMPLESPERPIXEL, 3);
+
+/* writing the GeoTIFF Tags */
+    pixsize[0] = cellsize;
+    pixsize[1] = cellsize;
+    pixsize[2] = 0.0;
+    TIFFSetField (tiff, GTIFF_PIXELSCALE, 3, pixsize);
+    tiepoint[0] = 0.0;
+    tiepoint[1] = 0.0;
+    tiepoint[2] = 0.0;
+    tiepoint[3] = xllcorner;
+    tiepoint[4] = yllcorner + (cellsize * nrows);
+    tiepoint[5] = 0.0;
+    TIFFSetField (tiff, GTIFF_TIEPOINTS, 6, tiepoint);
+    GTIFSetFromProj4 (gtif, proj4text);
+    GTIFWriteKeys (gtif);
+    raster = malloc (ncols * 3);
+    flt_buf = malloc (sizeof (float) * ncols);
+
+/* initializing the TripleRow object */
+    triplet = triple_alloc (ncols);
+    triple_set_shaded_relief_params (triplet, z_factor, scale_factor, altitude,
+				     azimuth);
+    triple_set_monochrome_params (triplet, mono_color, mono_red, mono_green,
+				  mono_blue);
+    triple_set_no_data (triplet, nodata, no_red, no_green, no_blue);
+
+    for (row = 0; row < nrows; row++)
+      {
+	  if (verbose)
+	    {
+		fprintf (stderr, "writing scanline %d of %d\n", row + 1, nrows);
+		fflush (stderr);
+	    }
+	  rd = fread (flt_buf, 1, ncols * sizeof (float), grid);
+	  if (rd != (sizeof (float) * ncols))
+	    {
+		printf ("*** Grid read error ***\n");
+		printf ("An invalid GeoTIFF was generated ... aborting ...\n");
+		goto stop;
+	    }
+	  if (fetch_float_scanline_shaded
+	      (row + 1, flt_buf, ncols, byteorder, triplet))
+	    {
+		if (triple_is_valid (triplet))
+		  {
+		      int ret = 1;
+		      if (!color_table)
+			  triple_shaded_relief (triplet, raster);
+		      else
+			  ret =
+			      triple_shaded_relief_color (color_table, colors,
+							  triplet, raster,
+							  row + 1);
+		      if (!ret)
+			  goto stop;
+		      if (TIFFWriteScanline (tiff, raster, row - 2, 0) < 0)
+			{
+			    printf ("\tTIFF write error @ row=%d\n", row);
+			    printf
+				("An invalid GeoTIFF was generated ... aborting ...\n");
+			    goto stop;
+			}
+		  }
+		triple_rotate (triplet);
+	    }
+	  else
+	    {
+		printf ("*** Grid read error ***\n");
+		printf ("An invalid GeoTIFF was generated ... aborting ...\n");
+		goto stop;
+	    }
+      }
+
+  stop:
+    if (gtif)
+	GTIFFree (gtif);
+    if (tiff)
+	XTIFFClose (tiff);
+    if (raster)
+	free (raster);
+    if (flt_buf)
+	free (flt_buf);
+    fclose (grid);
+    if (triplet)
+	triple_free (triplet);
+}
+
+static int
+fetch_scanline_shaded (int row, FILE * asc, int columns,
+		       struct triple_scan *triplet)
+{
+/* feeding a TIFF scanline from an ASCII Grid */
+    int c;
+    int cell = 0;
+    char buf[1024];
+    char *ptr = buf;
+    double value;
+    while ((c = getc (asc)) != EOF)
+      {
+	  if (c == '\n')
+	      break;
+	  *ptr++ = c;
+	  if (c == ' ')
+	    {
+		/* value delimiter */
+		*ptr = '\0';
+		cell++;
+		if (cell > columns)
+		  {
+		      printf ("Grid row %d: exceding column\n", row);
+		      return 0;
+		  }
+		value = atof (buf);
+		triple_store_cell (triplet, cell, (float) value);
+		ptr = buf;
+	    }
+      }
+    return 1;
+}
+
+static void
+export_geoTiff_shaded_ascii (struct colorTable *color_table, int colors,
+			     const char *proj4text, const char *grid_path,
+			     const char *tiff_path, unsigned char no_red,
+			     unsigned char no_green, unsigned char no_blue,
+			     int mono_color, unsigned char mono_red,
+			     unsigned char mono_green, unsigned char mono_blue,
+			     double z_factor, double scale_factor,
+			     double azimuth, double altitude, int verbose)
+{
+/* exporting an ASCII GRID as GeoTIFF */
+    TIFF *tiff = NULL;
+    GTIF *gtif = NULL;
+    int c;
+    int row = 0;
+    char buf[1024];
+    char *ptr = buf;
+    int err = 0;
+    int ncols = -1;
+    int nrows = -1;
+    double xllcorner = 0.0;
+    double yllcorner = 0.0;
+    double cellsize = 0.0;
+    double nodata = 0.0;
+    double tiepoint[6];
+    double pixsize[3];
+    unsigned char *raster = NULL;
+    struct triple_scan *triplet = NULL;
+    FILE *asc = fopen (grid_path, "rb");
+    if (!asc)
+      {
+	  printf ("Open error: %s\n", grid_path);
+	  return;
+      }
+    while ((c = getc (asc)) != EOF)
+      {
+	  if (c == '\r')
+	    {
+		/* ignoring Return chars */
+		continue;
+	    }
+	  if (c == '\n')
+	    {
+		*ptr = '\0';
+		switch (row)
+		  {
+		  case 0:
+		      if (!parseIntHeader (buf, "ncols ", &ncols))
+			  err = 1;
+		      break;
+		  case 1:
+		      if (!parseIntHeader (buf, "nrows ", &nrows))
+			  err = 1;
+		      break;
+		  case 2:
+		      if (!parseDblHeader (buf, "xllcorner ", &xllcorner))
+			  err = 1;
+		      break;
+		  case 3:
+		      if (!parseDblHeader (buf, "yllcorner ", &yllcorner))
+			  err = 1;
+		      break;
+		  case 4:
+		      if (!parseDblHeader (buf, "cellsize ", &cellsize))
+			  err = 1;
+		      break;
+		  case 5:
+		      if (!parseDblHeader (buf, "NODATA_value ", &nodata))
+			  err = 1;
+		      break;
+		  };
+		ptr = buf;
+		row++;
+		if (row == 6)
+		    break;
+		continue;
+	    }
+	  *ptr++ = c;
+      }
+    if (err)
+      {
+	  /* there was some error */
+	  printf ("Invalid ASCII Grid format in: %s\n", grid_path);
+	  goto stop;
+      }
+
+/* resizing CellSize */
+    cellsize = (cellsize * (double) ncols) / (double) (ncols - 2);
+
+/* creating the GeoTIFF file */
+    tiff = XTIFFOpen (tiff_path, "w");
+    if (!tiff)
+      {
+	  printf ("\tCould not open TIFF image '%s'\n", tiff_path);
+	  goto stop;
+      }
+    gtif = GTIFNew (tiff);
+    if (!gtif)
+      {
+	  printf ("\tCould not open GeoTIFF image '%s'\n", tiff_path);
+	  goto stop;
+      }
+
+/* writing the TIFF Tags */
+    TIFFSetField (tiff, TIFFTAG_IMAGEWIDTH, ncols - 2);
+    TIFFSetField (tiff, TIFFTAG_IMAGELENGTH, nrows - 2);
+    TIFFSetField (tiff, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
+    TIFFSetField (tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
+    TIFFSetField (tiff, TIFFTAG_ROWSPERSTRIP, 1);
+    TIFFSetField (tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+    TIFFSetField (tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
+    TIFFSetField (tiff, TIFFTAG_BITSPERSAMPLE, 8);
+    TIFFSetField (tiff, TIFFTAG_SAMPLESPERPIXEL, 3);
+
+/* writing the GeoTIFF Tags */
+    pixsize[0] = cellsize;
+    pixsize[1] = cellsize;
+    pixsize[2] = 0.0;
+    TIFFSetField (tiff, GTIFF_PIXELSCALE, 3, pixsize);
+    tiepoint[0] = 0.0;
+    tiepoint[1] = 0.0;
+    tiepoint[2] = 0.0;
+    tiepoint[3] = xllcorner;
+    tiepoint[4] = yllcorner + (cellsize * nrows);
+    tiepoint[5] = 0.0;
+    TIFFSetField (tiff, GTIFF_TIEPOINTS, 6, tiepoint);
+    GTIFSetFromProj4 (gtif, proj4text);
+    GTIFWriteKeys (gtif);
+    raster = malloc (ncols * 3);
+
+/* initializing the TripleRow object */
+    triplet = triple_alloc (ncols);
+    triple_set_shaded_relief_params (triplet, z_factor, scale_factor, altitude,
+				     azimuth);
+    triple_set_monochrome_params (triplet, mono_color, mono_red, mono_green,
+				  mono_blue);
+    triple_set_no_data (triplet, nodata, no_red, no_green, no_blue);
+
+    for (row = 0; row < nrows; row++)
+      {
+	  if (verbose)
+	    {
+		fprintf (stderr, "writing scanline %d of %d\n", row + 1, nrows);
+		fflush (stderr);
+	    }
+	  if (fetch_scanline_shaded (row + 1, asc, ncols, triplet))
+	    {
+		if (triple_is_valid (triplet))
+		  {
+		      int ret = 1;
+		      if (!color_table)
+			  triple_shaded_relief (triplet, raster);
+		      else
+			  ret =
+			      triple_shaded_relief_color (color_table, colors,
+							  triplet, raster,
+							  row + 1);
+		      if (!ret)
+			  goto stop;
+		      if (TIFFWriteScanline (tiff, raster, row - 2, 0) < 0)
+			{
+			    printf ("\tTIFF write error @ row=%d\n", row);
+			    printf
+				("An invalid GeoTIFF was generated ... aborting ...\n");
+			    goto stop;
+			}
+		  }
+		triple_rotate (triplet);
+	    }
+	  else
+	    {
+		printf ("*** Grid read error ***\n");
+		printf ("An invalid GeoTIFF was generated ... aborting ...\n");
+		goto stop;
+	    }
+      }
+
+  stop:
+    if (gtif)
+	GTIFFree (gtif);
+    if (tiff)
+	XTIFFClose (tiff);
+    if (raster)
+	free (raster);
+    fclose (asc);
+    if (triplet)
+	triple_free (triplet);
+}
+
+static void
+do_help ()
+{
+/* printing the argument list */
+    fprintf (stderr, "\n\nusage: rasterlite_grid ARGLIST\n");
+    fprintf (stderr,
+	     "==============================================================\n");
+    fprintf (stderr,
+	     "-? or --help                      print this help message\n");
+    fprintf (stderr,
+	     "-g or --grid-path     pathname    the Grid path (input)\n");
+    fprintf (stderr,
+	     "-c or --color-path    pathname    the ColorTable path (input)\n");
+    fprintf (stderr,
+	     "-t or --tiff-path     pathname    the GeoTIFF path (output)\n");
+    fprintf (stderr,
+	     "-p or --proj4text     proj4text   the PROJ.4 parameters\n");
+    fprintf (stderr, "-f or --grid-format   grid-type   [ASCII | FLOAT]\n");
+    fprintf (stderr,
+	     "-n or --nodata-color  0xRRGGBB    [default = 0x000000]\n");
+    fprintf (stderr, "-v or --verbose                   verbose output\n\n");
+    fprintf (stderr, "Shaded Relief specific arguments:\n");
+    fprintf (stderr, "---------------------------------\n");
+    fprintf (stderr,
+	     "-sr or --shaded-relief            *disabled by default*\n");
+    fprintf (stderr, "-m or --monochrome    0xRRGGBB    [default = none]\n");
+    fprintf (stderr, "-z or --z-factor      numeric     [default = 1.0]\n");
+    fprintf (stderr, "-s or --scale-factor  numeric     [default = 1.0]\n");
+    fprintf (stderr, "-az or --azimuth      numeric     [default = 315.0]\n");
+    fprintf (stderr, "-al or --altitude     numeric     [default = 45.0]\n\n");
+    fprintf (stderr, "Please note: --monochrome and --color-path are\n");
+    fprintf (stderr, "mutually exclusive options\n");
+}
+
+int
+main (int argc, char *argv[])
+{
+/* the MAIN function simply perform arguments checking */
+    int i;
+    int next_arg = ARG_NONE;
+    const char *grid_path = NULL;
+    const char *color_path = NULL;
+    const char *tiff_path = NULL;
+    const char *proj4text = NULL;
+    int grid_type = -1;
+    int verbose = 0;
+    int error = 0;
+    struct colorTable *color_table = NULL;
+    unsigned char no_red = 0;
+    unsigned char no_green = 0;
+    unsigned char no_blue = 0;
+    char error_nodata_color[1024];
+    int shaded_relief = 0;
+    int mono_color = 0;
+    unsigned char mono_red = 0;
+    unsigned char mono_green = 0;
+    unsigned char mono_blue = 0;
+    char error_mono_color[1024];
+    double z_factor = 1.0;
+    double scale_factor = 1.0;
+    double azimuth = 315.0;
+    double altitude = 45.0;
+    int colors;
+    *error_nodata_color = '\0';
+    *error_mono_color = '\0';
+    for (i = 1; i < argc; i++)
+      {
+	  /* parsing the invocation arguments */
+	  if (next_arg != ARG_NONE)
+	    {
+		switch (next_arg)
+		  {
+		  case ARG_GRID_PATH:
+		      grid_path = argv[i];
+		      break;
+		  case ARG_COLOR_PATH:
+		      color_path = argv[i];
 		      break;
 		  case ARG_TIFF_PATH:
 		      tiff_path = argv[i];
@@ -1115,6 +2054,25 @@ main (int argc, char *argv[])
 		      if (!parse_rgb (argv[i], &no_red, &no_green, &no_blue))
 			  strcpy (error_nodata_color, argv[i]);
 		      break;
+		  case ARG_MONO_COLOR:
+		      if (!parse_rgb
+			  (argv[i], &mono_red, &mono_green, &mono_blue))
+			  strcpy (error_mono_color, argv[i]);
+		      else
+			  mono_color = 1;
+		      break;
+		  case ARG_Z_FACTOR:
+		      z_factor = atof (argv[i]);
+		      break;
+		  case ARG_SCALE:
+		      scale_factor = atof (argv[i]);
+		      break;
+		  case ARG_AZIMUTH:
+		      azimuth = atof (argv[i]);
+		      break;
+		  case ARG_ALTITUDE:
+		      altitude = atof (argv[i]);
+		      break;
 		  };
 		next_arg = ARG_NONE;
 		continue;
@@ -1195,6 +2153,66 @@ main (int argc, char *argv[])
 		verbose = 1;
 		continue;
 	    }
+	  if (strcasecmp (argv[i], "--shared-relief") == 0)
+	    {
+		shaded_relief = 1;
+		continue;
+	    }
+	  if (strcmp (argv[i], "-sr") == 0)
+	    {
+		shaded_relief = 1;
+		continue;
+	    }
+	  if (strcmp (argv[i], "-m") == 0)
+	    {
+		next_arg = ARG_MONO_COLOR;
+		continue;
+	    }
+	  if (strcasecmp (argv[i], "--monochrome") == 0)
+	    {
+		next_arg = ARG_MONO_COLOR;
+		continue;
+	    }
+	  if (strcmp (argv[i], "-z") == 0)
+	    {
+		next_arg = ARG_Z_FACTOR;
+		continue;
+	    }
+	  if (strcasecmp (argv[i], "--z-factor") == 0)
+	    {
+		next_arg = ARG_Z_FACTOR;
+		continue;
+	    }
+	  if (strcmp (argv[i], "-s") == 0)
+	    {
+		next_arg = ARG_SCALE;
+		continue;
+	    }
+	  if (strcasecmp (argv[i], "--scale-factor") == 0)
+	    {
+		next_arg = ARG_SCALE;
+		continue;
+	    }
+	  if (strcmp (argv[i], "-az") == 0)
+	    {
+		next_arg = ARG_AZIMUTH;
+		continue;
+	    }
+	  if (strcasecmp (argv[i], "--azimuth") == 0)
+	    {
+		next_arg = ARG_AZIMUTH;
+		continue;
+	    }
+	  if (strcmp (argv[i], "-al") == 0)
+	    {
+		next_arg = ARG_ALTITUDE;
+		continue;
+	    }
+	  if (strcasecmp (argv[i], "--altitude") == 0)
+	    {
+		next_arg = ARG_ALTITUDE;
+		continue;
+	    }
 	  fprintf (stderr, "unknown argument: %s\n", argv[i]);
 	  error = 1;
       }
@@ -1210,11 +2228,14 @@ main (int argc, char *argv[])
 		   "did you forget setting the --grid-path argument ?\n");
 	  error = 1;
       }
-    if (!color_path)
+    if (!shaded_relief)
       {
-	  fprintf (stderr,
-		   "did you forget setting the --color-path argument ?\n");
-	  error = 1;
+	  if (!color_path)
+	    {
+		fprintf (stderr,
+			 "did you forget setting the --color-path argument ?\n");
+		error = 1;
+	    }
       }
     if (!tiff_path)
       {
@@ -1239,6 +2260,17 @@ main (int argc, char *argv[])
 	  printf ("invalid NODATA color '%s'\n", error_nodata_color);
 	  error = 1;
       }
+    if (strlen (error_mono_color))
+      {
+	  printf ("invalid Shaded Relief Monochrome color '%s'\n",
+		  error_mono_color);
+	  error = 1;
+      }
+    if (color_path && mono_color)
+      {
+	  printf ("--monochrome and --color-path are mutually exclusive\n");
+	  error = 1;
+      }
     if (error)
       {
 	  do_help ();
@@ -1248,9 +2280,11 @@ main (int argc, char *argv[])
     printf ("             Arguments Summary\n");
     printf ("=====================================================\n");
     printf ("Grid       pathname: '%s'\n", grid_path);
-    printf ("ColorTable pathname: '%s'\n", color_path);
+    if (color_path)
+	printf ("ColorTable pathname: '%s'\n", color_path);
     printf ("GeoTIFF    pathname: '%s'\n", tiff_path);
     printf ("PROJ.4       string: '%s'\n", proj4text);
+    printf ("NoData        color: 0x%02x%02x%02x\n", no_red, no_green, no_blue);
     switch (grid_type)
       {
       case ASCII_GRID:
@@ -1263,19 +2297,57 @@ main (int argc, char *argv[])
 	  printf ("Grid Format: UNKNOWN\n");
 	  break;
       }
+    if (shaded_relief)
+      {
+	  printf ("\n           Shaded Relief arguments:\n");
+	  printf ("-----------------------------------------------------\n");
+	  printf ("Z-factor     : %1.4f\n", z_factor);
+	  printf ("Scale-factor : %1.4f\n", scale_factor);
+	  printf ("Azimuth      : %1.4f\n", azimuth);
+	  printf ("Altitude     : %1.4f\n", altitude);
+	  if (mono_color)
+	      printf ("Monochrome   : 0x%02x%02x%02x\n", mono_red, mono_green,
+		      mono_blue);
+      }
     printf ("=====================================================\n\n");
-    color_table = parse_color_table (color_path);
-    if (!color_table)
+    if (color_path)
       {
-	  fprintf (stderr, "\n*********** Invalid Color Table\n");
-	  return -1;
+	  color_table = parse_color_table (color_path, &colors);
+	  if (!color_table)
+	    {
+		fprintf (stderr, "\n*********** Invalid Color Table\n");
+		return -1;
+	    }
+      }
+    if (shaded_relief)
+      {
+	  if (grid_type == FLOAT_GRID)
+	      export_geoTiff_shaded_float (color_table, colors, proj4text,
+					   grid_path, tiff_path, no_red,
+					   no_green, no_blue, mono_color,
+					   mono_red, mono_green, mono_blue,
+					   z_factor, scale_factor, azimuth,
+					   altitude, verbose);
+	  else
+	      export_geoTiff_shaded_ascii (color_table, colors, proj4text,
+					   grid_path, tiff_path, no_red,
+					   no_green, no_blue, mono_color,
+					   mono_red, mono_green, mono_blue,
+					   z_factor, scale_factor, azimuth,
+					   altitude, verbose);
       }
-    if (grid_type == FLOAT_GRID)
-	export_geoTiff_float (color_table, proj4text, grid_path, tiff_path,
-			      no_red, no_green, no_blue, verbose);
     else
-	export_geoTiff_ascii (color_table, proj4text, grid_path, tiff_path,
-			      no_red, no_green, no_blue, verbose);
-    free (color_table);
+      {
+	  if (grid_type == FLOAT_GRID)
+	      export_geoTiff_float (color_table, colors, proj4text, grid_path,
+				    tiff_path, no_red, no_green, no_blue,
+				    verbose);
+	  else
+	      export_geoTiff_ascii (color_table, colors, proj4text, grid_path,
+				    tiff_path, no_red, no_green, no_blue,
+				    verbose);
+      }
+    if (color_table)
+	free (color_table);
     return 0;
 }
diff --git a/src/rasterlite_load.c b/src/rasterlite_load.c
index 92cd564..37fc6d8 100644
--- a/src/rasterlite_load.c
+++ b/src/rasterlite_load.c
@@ -3,7 +3,7 @@
 /
 / a tool for uploading GeoTIFF rasters into a SpatiaLite DB 
 /
-/ version 1.0, 2009 June 1
+/ version 1.1, 2010 April 27
 /
 / Author: Sandro Furieri a.furieri at lqt.it
 /
@@ -51,7 +51,7 @@
 #include "rasterlite.h"
 #include "rasterlite_internals.h"
 
-#if defined(_WIN32) && !defined(__MINGW32__)
+#ifdef _WIN32
 #define strcasecmp	_stricmp
 #endif /* not WIN32 */
 
@@ -66,7 +66,7 @@
 #define ARG_EPSG_CODE		8
 
 static int
-read_by_tile (TIFF * tif, rasterliteImagePrt img, struct geo_info *infos,
+read_by_tile (TIFF * tif, rasterliteImagePtr img, struct geo_info *infos,
 	      int baseVert, int baseHorz)
 {
 /* reading from a TIFF using TILES */
@@ -173,7 +173,7 @@ read_by_tile (TIFF * tif, rasterliteImagePrt img, struct geo_info *infos,
 }
 
 static int
-read_by_strip (TIFF * tif, rasterliteImagePrt img, struct geo_info *infos,
+read_by_strip (TIFF * tif, rasterliteImagePtr img, struct geo_info *infos,
 	       int baseVert, int baseHorz)
 {
 /* reading from a TIFF using STRIPS */
@@ -266,7 +266,7 @@ export_tile (TIFF * tif, struct geo_info *infos, int baseVert, int baseHorz,
     int ret;
     double xx;
     double yy;
-    rasterliteImagePrt img = NULL;
+    rasterliteImagePtr img = NULL;
     gaiaPolygonPtr polyg;
     tile->geometry = gaiaAllocGeomColl ();
     tile->tileNo = tileNo;
@@ -979,7 +979,7 @@ load_file (sqlite3 * handle, const char *file_path, const char *table,
 	  break;
       };
 /* retrieving the EPSG code */
-    infos.epsg = definition.GCS;
+    infos.epsg = definition.PCS;
 /* computing the corners coords */
     cx = 0.0;
     cy = 0.0;
@@ -1207,6 +1207,10 @@ load_file (sqlite3 * handle, const char *file_path, const char *table,
 	  goto stop;
       }
 
+    if (tif)
+	XTIFFClose (tif);
+    if (gtif)
+	GTIFFree (gtif);
     for (i = 0; i < NTILES; i++)
       {
 	  tile = &(infos.tiles[i]);
@@ -1267,8 +1271,8 @@ load_dir (sqlite3 * handle, const char *dir_path, const char *table,
 		      sprintf (file_path, "%s\\%s", dir_path, c_file.name);
 		      cnt +=
 			  load_file (handle, file_path, table, tile_size,
-				     test_mode, image_type, quality_factor,
-				     epsg_code);
+				     test_mode, verbose, image_type,
+				     quality_factor, epsg_code);
 		  }
 		if (_findnext (hFile, &c_file) != 0)
 		    break;
diff --git a/src/rasterlite_pyramid.c b/src/rasterlite_pyramid.c
index 293c432..7c08a1a 100644
--- a/src/rasterlite_pyramid.c
+++ b/src/rasterlite_pyramid.c
@@ -3,7 +3,7 @@
 /
 / a tool building raster pyramids into a SpatiaLite DB 
 /
-/ version 1.0, 2009 June 1
+/ version 1.1, 2010 April 27
 /
 / Author: Sandro Furieri a.furieri at lqt.it
 /
@@ -45,7 +45,7 @@
 #include "rasterlite.h"
 #include "rasterlite_internals.h"
 
-#if defined(_WIN32) && !defined(__MINGW32__)
+#ifdef _WIN32
 #define strcasecmp	_stricmp
 #endif /* not WIN32 */
 
@@ -261,11 +261,11 @@ find_tile (struct tiles_list *list, double x, double y, int mode)
     return NULL;
 }
 
-static rasterliteImagePrt
+static rasterliteImagePtr
 raster_decode (const void *blob, int blob_size)
 {
 /* trying to decode a BLOB as an image */
-    rasterliteImagePrt img = NULL;
+    rasterliteImagePtr img = NULL;
     int type = gaiaGuessBlobType (blob, blob_size);
     if (type == GAIA_JPEG_BLOB || type == GAIA_EXIF_BLOB
 	|| type == GAIA_EXIF_GPS_BLOB)
@@ -282,7 +282,7 @@ raster_decode (const void *blob, int blob_size)
 }
 
 static int
-get_tile (sqlite3 * handle, rasterliteImagePrt img, const char *table,
+get_tile (sqlite3 * handle, rasterliteImagePtr img, const char *table,
 	  sqlite3_int64 tile_id, int declared_x, int declared_y, int where)
 {
 /* fetching a raster tile */
@@ -297,7 +297,7 @@ get_tile (sqlite3 * handle, rasterliteImagePrt img, const char *table,
     int x;
     int y;
     int pixel;
-    rasterliteImagePrt tile_img = NULL;
+    rasterliteImagePtr tile_img = NULL;
     sprintf (sql, "SELECT raster FROM \"%s_rasters\" WHERE id = ?", table);
     ret = sqlite3_prepare_v2 (handle, sql, strlen (sql), &stmt, NULL);
     if (ret != SQLITE_OK)
@@ -424,7 +424,7 @@ get_tile (sqlite3 * handle, rasterliteImagePrt img, const char *table,
 
 static void
 thumbnail_export (sqlite3 * handle, sqlite3_stmt * stmt,
-		  rasterliteImagePrt img, int image_type, int quality_factor,
+		  rasterliteImagePtr img, int image_type, int quality_factor,
 		  struct thumbnail_tile *tile)
 {
 /* saving the thumbnail into the DB */
@@ -433,7 +433,7 @@ thumbnail_export (sqlite3 * handle, sqlite3_stmt * stmt,
     int blob_size;
     int width = img->sx / 2;
     int height = img->sy / 2;
-    rasterliteImagePrt thumbnail = image_create (width, height);
+    rasterliteImagePtr thumbnail = image_create (width, height);
     make_thumbnail (thumbnail, img);
     if (image_type == GAIA_TIFF_BLOB)
       {
@@ -588,7 +588,7 @@ build_pyramid_level (sqlite3 * handle, const char *table, int image_type,
     struct tile_item *tile_4;
     double x;
     double y;
-    rasterliteImagePrt img = NULL;
+    rasterliteImagePtr img = NULL;
     struct thumbnail_tile thumb_tiles[NTILES];
     struct thumbnail_tile *thumb_tile;
     int max_tile;
diff --git a/src/rasterlite_tool.c b/src/rasterlite_tool.c
index 8b62c8d..b47704c 100644
--- a/src/rasterlite_tool.c
+++ b/src/rasterlite_tool.c
@@ -3,7 +3,7 @@
 /
 / a tool generating rasters from a SpatiaLite DB 
 /
-/ version 1.0, 2009 June 1
+/ version 1.1, 2010 April 27
 /
 / Author: Sandro Furieri a.furieri at lqt.it
 /
@@ -55,6 +55,10 @@
 
 #define WRONG_COLOR			-100
 
+#ifdef _WIN32
+#define strcasecmp	_stricmp
+#endif /* not WIN32 */
+
 static int
 parse_hex (const char hi, const char lo)
 {
diff --git a/src/rasterlite_topmost.c b/src/rasterlite_topmost.c
index 49dfa86..1867293 100644
--- a/src/rasterlite_topmost.c
+++ b/src/rasterlite_topmost.c
@@ -3,7 +3,7 @@
 /
 / a tool building raster topmost pyramid's levels into a SpatiaLite DB 
 /
-/ version 1.0, 2009 June 25
+/ version 1.1, 2010 April 27
 /
 / Author: Sandro Furieri a.furieri at lqt.it
 /
@@ -41,7 +41,7 @@
 #include "rasterlite.h"
 #include "rasterlite_internals.h"
 
-#if defined(_WIN32) && !defined(__MINGW32__)
+#ifdef _WIN32
 #define strcasecmp	_stricmp
 #endif /* not WIN32 */
 
@@ -283,7 +283,7 @@ add_source (struct sources_list *list, const char *name, int count)
 }
 
 static void
-copy_rectangle (rasterliteImagePrt output, rasterliteImagePrt input,
+copy_rectangle (rasterliteImagePtr output, rasterliteImagePtr input,
 		int transparent_color, int base_x, int base_y)
 {
 /* copying a raster rectangle */
@@ -336,8 +336,8 @@ export_tile (struct top_info *info, int tile_width, int tile_height, int tileNo,
     int new_tile_width;
     int new_tile_height;
     gaiaPolygonPtr polyg;
-    rasterliteImagePrt full_size = NULL;
-    rasterliteImagePrt thumbnail = NULL;
+    rasterliteImagePtr full_size = NULL;
+    rasterliteImagePtr thumbnail = NULL;
     int srid;
 /* creating the full size image */
     full_size = image_create (tile_width, tile_height);
@@ -361,7 +361,7 @@ export_tile (struct top_info *info, int tile_width, int tile_height, int tileNo,
 	    {
 		/* retrieving query values */
 		gaiaGeomCollPtr geom = NULL;
-		rasterliteImagePrt img = NULL;
+		rasterliteImagePtr img = NULL;
 		if (sqlite3_column_type (info->stmt_query, 0) == SQLITE_BLOB)
 		  {
 		      /* fetching Geometry */

-- 
library supporting raster data sources for spatialite



More information about the Pkg-grass-devel mailing list