Index: test/core/testwkb.c
===================================================================
--- test/core/testwkb.c	(revision 5321)
+++ test/core/testwkb.c	(working copy)
@@ -165,7 +165,7 @@
 "0A000000"         /* SRID (int32 10) */
 "0100"             /* width (uint16 1) */
 "0100"             /* height (uint16 1) */
-"00"               /* First band type (1BB, in memory) */
+"40"               /* First band type (1BB, in memory, hasnodata) */
 "00"               /* nodata value (0) */
 "01"               /* pix(0,0) == 1 */
     ;
@@ -187,6 +187,7 @@
         CHECK(band);
         CHECK_EQUALS(rt_band_get_pixtype(ctx, band), PT_1BB);
         CHECK(!rt_band_is_offline(ctx, band));
+        CHECK(rt_band_get_hasnodata_flag(ctx, band));
         CHECK_EQUALS(rt_band_get_nodata(ctx, band), 0);
         CHECK_EQUALS(rt_band_get_pixel(ctx, band, 0, 0), 1);
     }
@@ -219,7 +220,7 @@
 "0A000000"         /* SRID (int32 10) */
 "0300"             /* width (uint16 3) */
 "0200"             /* height (uint16 2) */
-"03"               /* First band type (8BSI, in memory) */
+"43"               /* First band type (8BSI, in memory, hasnodata) */
 "FF"               /* nodata value (-1) */
 "FF"               /* pix(0,0) == -1 */
 "00"               /* pix(1,0) ==  0 */
@@ -246,6 +247,7 @@
         CHECK(band);
         CHECK_EQUALS(rt_band_get_pixtype(ctx, band), PT_8BSI);
         CHECK(!rt_band_is_offline(ctx, band));
+        CHECK(rt_band_get_hasnodata_flag(ctx,band));
         CHECK_EQUALS(rt_band_get_nodata(ctx, band), -1);
         CHECK_EQUALS(rt_band_get_pixel(ctx, band, 0, 0), -1);
         CHECK_EQUALS(rt_band_get_pixel(ctx, band, 1, 0), 0);
@@ -323,6 +325,7 @@
         CHECK(band);
         CHECK_EQUALS(rt_band_get_pixtype(ctx, band), PT_16BSI);
         CHECK(!rt_band_is_offline(ctx, band));
+        CHECK(!rt_band_get_hasnodata_flag(ctx, band));
         CHECK_EQUALS(rt_band_get_nodata(ctx, band), -1);
         CHECK_EQUALS(rt_band_get_pixel(ctx, band, 0, 0), -1);
         CHECK_EQUALS(rt_band_get_pixel(ctx, band, 1, 0), 0);
@@ -387,6 +390,7 @@
         CHECK(band);
         CHECK_EQUALS(rt_band_get_pixtype(ctx, band), PT_16BSI);
         CHECK(!rt_band_is_offline(ctx, band));
+        CHECK(!rt_band_get_hasnodata_flag(ctx,band));
         CHECK_EQUALS(rt_band_get_nodata(ctx, band), -1);
         CHECK_EQUALS(rt_band_get_pixel(ctx, band, 0, 0), -1);
         CHECK_EQUALS(rt_band_get_pixel(ctx, band, 1, 0), 0);
@@ -424,7 +428,7 @@
 "0000000A"         /* SRID (int32 10) */
 "0003"             /* width (uint16 3) */
 "0002"             /* height (uint16 2) */
-"85"               /* First band type (16BSI, on disk) */
+"C5"               /* First band type (16BSI, on disk, hasnodata) */
 "FFFF"             /* nodata value (-1) */
 "03"               /* ext band num == 3 */
 /* ext band path == /tmp/t.tif */
@@ -448,6 +452,7 @@
         CHECK(band);
         CHECK_EQUALS(rt_band_get_pixtype(ctx, band), PT_16BSI);
         CHECK(rt_band_is_offline(ctx, band));
+        CHECK(rt_band_get_hasnodata_flag(ctx,band));
         CHECK_EQUALS(rt_band_get_nodata(ctx, band), -1);
         printf("ext band path: %s\n", rt_band_get_ext_path(ctx, band));
         printf("ext band  num: %u\n", rt_band_get_ext_band_num(ctx, band));
@@ -483,7 +488,7 @@
 "FFFFFFFF"         /* SRID (int32 -1) */
 "0300"             /* width (uint16 3) */
 "0100"             /* height (uint16 1) */
-"05"               /* First band type (16BSI, in memory) */
+"45"               /* First band type (16BSI, in memory, hasnodata) */
 "0100"             /* nodata value (1) */
 "0100"             /* pix(0,0) == 1 */
 "B401"             /* pix(1,0) == 436 */
@@ -507,6 +512,7 @@
         CHECK(band);
         CHECK_EQUALS(rt_band_get_pixtype(ctx, band), PT_16BSI);
         CHECK(!rt_band_is_offline(ctx, band));
+        CHECK(rt_band_get_hasnodata_flag(ctx,band));
         CHECK_EQUALS(rt_band_get_nodata(ctx, band), 1);
         CHECK_EQUALS(rt_band_get_pixel(ctx, band, 0, 0), 1);
         CHECK_EQUALS(rt_band_get_pixel(ctx, band, 1, 0), 436);
@@ -561,13 +567,13 @@
 "FFFFFFFF"          /* srid (int32 -1) */
 "0500"              /* width (uint16 5) */
 "0500"              /* height (uint16 5) */
-"04"                /* 1st band pixel type (8BUI, in memory) */
+"44"                /* 1st band pixel type (8BUI, in memory, hasnodata) */
 "00"                /* 1st band nodata 0 */
 "FDFEFDFEFEFDFEFEFDF9FAFEFEFCF9FBFDFEFEFDFCFAFEFEFE" /* 1st band pixels */
-"04"                /* 2nd band pixel type (8BUI, in memory) */
+"44"                /* 2nd band pixel type (8BUI, in memory, hasnodata) */
 "00"                /* 2nd band nodata 0 */
 "4E627AADD16076B4F9FE6370A9F5FE59637AB0E54F58617087" /* 2nd band pixels */
-"04"                /* 3rd band pixel type (8BUI, in memory) */
+"44"                /* 3rd band pixel type (8BUI, in memory, hasnodata) */
 "00"                /* 3rd band nodata 0 */
 "46566487A1506CA2E3FA5A6CAFFBFE4D566DA4CB3E454C5665" /* 3rd band pixels */
 ;
@@ -590,6 +596,7 @@
         CHECK(band);
         CHECK_EQUALS(rt_band_get_pixtype(ctx, band), PT_8BUI);
         CHECK(!rt_band_is_offline(ctx, band));
+        CHECK(rt_band_get_hasnodata_flag(ctx,band));
         CHECK_EQUALS(rt_band_get_nodata(ctx, band), 0);
         CHECK_EQUALS(rt_band_get_pixel(ctx, band, 0, 0), 253);
         CHECK_EQUALS(rt_band_get_pixel(ctx, band, 1, 0), 254);
@@ -604,6 +611,7 @@
         CHECK(band);
         CHECK_EQUALS(rt_band_get_pixtype(ctx, band), PT_8BUI);
         CHECK(!rt_band_is_offline(ctx, band));
+        CHECK(rt_band_get_hasnodata_flag(ctx,band));
         CHECK_EQUALS(rt_band_get_nodata(ctx, band), 0);
         CHECK_EQUALS(rt_band_get_pixel(ctx, band, 0, 0), 78);
         CHECK_EQUALS(rt_band_get_pixel(ctx, band, 1, 0), 98);
@@ -618,6 +626,7 @@
         CHECK(band);
         CHECK_EQUALS(rt_band_get_pixtype(ctx, band), PT_8BUI);
         CHECK(!rt_band_is_offline(ctx, band));
+        CHECK(rt_band_get_hasnodata_flag(ctx,band));
         CHECK_EQUALS(rt_band_get_nodata(ctx, band), 0);
         CHECK_EQUALS(rt_band_get_pixel(ctx, band, 0, 0), 70);
         CHECK_EQUALS(rt_band_get_pixel(ctx, band, 1, 0), 86);
Index: test/core/testapi.c
===================================================================
--- test/core/testapi.c	(revision 5321)
+++ test/core/testapi.c	(working copy)
@@ -26,7 +26,7 @@
     mem = malloc(datasize);
 
     rt_band band = rt_band_new_inline(ctx, width, height,
-                                      pixtype, 0, mem);
+                                      pixtype, 1, 0, mem);
     assert(band);
     bandNum = rt_raster_add_band(ctx, raster, band);
     assert(bandNum>=0);
@@ -60,7 +60,7 @@
     size_t datasize = width * height;
     rt_raster raster = rt_raster_new(ctx, width, height);
     void * mem = calloc(datasize, sizeof(void));
-    rt_band band = rt_band_new_inline(ctx, width, height, PT_32BSI, 0, mem);
+    rt_band band = rt_band_new_inline(ctx, width, height, PT_32BSI, 1, 0, mem);
     
     /* Fill raster */
     rt_band_set_pixel(ctx, band, 0, 0, 1);
@@ -864,6 +864,27 @@
     }
 }
 
+static void testBandHasNoData(rt_context ctx, rt_band band)
+{
+    int flag;
+    int failure;
+
+    flag = rt_band_get_hasnodata_flag(ctx, band);
+    CHECK_EQUALS(flag, 1);
+
+    rt_band_set_hasnodata_flag(ctx, band, 0);
+    flag = rt_band_get_hasnodata_flag(ctx, band);
+    CHECK_EQUALS(flag, 0);
+
+    rt_band_set_hasnodata_flag(ctx, band, 10);
+    flag = rt_band_get_hasnodata_flag(ctx, band);
+    CHECK_EQUALS(flag, 1);
+
+    rt_band_set_hasnodata_flag(ctx, band, -10);
+    flag = rt_band_get_hasnodata_flag(ctx, band);
+    CHECK_EQUALS(flag, 1);
+}
+
 int
 main()
 {
@@ -1101,6 +1122,9 @@
     band_64BF = addBand(ctx, raster, PT_64BF);
     testBand64BF(ctx, band_64BF);
 
+    printf("Testing band hasnodata flag\n");
+    testBandHasNoData(ctx, band_64BF);
+
     deepRelease(ctx, raster);
     rt_context_destroy(ctx);
 
Index: rt_core/rt_api.c
===================================================================
--- rt_core/rt_api.c	(revision 5321)
+++ rt_core/rt_api.c	(working copy)
@@ -367,6 +367,7 @@
     int32_t offline;
     uint16_t width;
     uint16_t height;
+    int32_t hasnodata; /* a flag indicating if this band contains nodata values */
     double nodataval; /* int will be converted ... */
     int32_t ownsData; /* XXX mloskot: its behaviour needs to be documented */
     union {
@@ -378,7 +379,8 @@
 
 rt_band
 rt_band_new_inline(rt_context ctx, uint16_t width, uint16_t height,
-                   rt_pixtype pixtype, double nodataval, uint8_t* data)
+                   rt_pixtype pixtype, uint32_t hasnodata, double nodataval, 
+                   uint8_t* data)
 {
     rt_band band = NULL;
 
@@ -401,6 +403,7 @@
     band->offline = 0;
     band->width = width;
     band->height = height;
+    band->hasnodata = hasnodata;
     band->nodataval = nodataval;
     band->data.mem = data;
     band->ownsData = 0;
@@ -410,8 +413,8 @@
 
 rt_band
 rt_band_new_offline(rt_context ctx, uint16_t width, uint16_t height,
-                    rt_pixtype pixtype, double nodataval, uint8_t bandNum,
-                    const char* path)
+                    rt_pixtype pixtype, uint32_t hasnodata, double nodataval, 
+                    uint8_t bandNum, const char* path)
 {
     rt_band band = NULL;
 
@@ -434,6 +437,7 @@
     band->offline = 1;
     band->width = width;
     band->height = height;
+    band->hasnodata = hasnodata;
     band->nodataval = nodataval;
     band->data.offline.bandNum = bandNum;
 
@@ -469,7 +473,7 @@
 
     /* band->data content is externally owned */
     /* XXX jorgearevalo: not really... rt_band_from_wkb allocates memory for
-     * data.mem
+     * data.me
      */
     ctx->dealloc(band);
 }
@@ -611,6 +615,24 @@
 #endif /* OPTIMIZE_SPACE */
 
 int
+rt_band_get_hasnodata_flag(rt_context ctx, rt_band band)
+{
+    assert(NULL != ctx);
+    assert(NULL != band);
+
+    return band->hasnodata;    
+}
+
+void
+rt_band_set_hasnodata_flag(rt_context ctx, rt_band band, int flag)
+{
+    assert(NULL != ctx);
+    assert(NULL != band);
+
+    band->hasnodata = (flag) ? 1 : 0;
+}
+
+int
 rt_band_set_nodata(rt_context ctx, rt_band band, double val)
 {
     rt_pixtype pixtype = PT_END;
@@ -691,9 +713,13 @@
             break;
         default:
             ctx->err("Unknown pixeltype %d", pixtype);
+            band->hasnodata = 0;
             return -1;
     }
 
+    // the NODATA value was just set, so this band has NODATA
+    rt_band_set_hasnodata_flag(ctx, band, 1);
+
     if ( fabs(band->nodataval - val) > 0.0001 )
     {
 #ifdef RT_WARN_ON_TRUNCATION
@@ -952,7 +978,10 @@
     assert(NULL != ctx);
     assert(NULL != band);
 
-    return band->nodataval;
+    if (!band->hasnodata)
+        ctx->warn("Getting NODATA value for a band without NODATA values. Using %d", band->nodataval);
+
+    return band->nodataval;    
 }
 
 
@@ -2020,12 +2049,13 @@
 #define BANDTYPE_FLAGS_MASK 0xF0
 #define BANDTYPE_PIXTYPE_MASK 0x0F
 #define BANDTYPE_FLAG_OFFDB     (1<<7)
-#define BANDTYPE_FLAG_RESERVED1 (1<<6)
+#define BANDTYPE_FLAG_HASNODATA (1<<6)
 #define BANDTYPE_FLAG_RESERVED2 (1<<5)
 #define BANDTYPE_FLAG_RESERVED3 (1<<4)
 
 #define BANDTYPE_PIXTYPE(x) ((x)&BANDTYPE_PIXTYPE_MASK)
 #define BANDTYPE_IS_OFFDB(x) ((x)&BANDTYPE_FLAG_OFFDB)
+#define BANDTYPE_HAS_NODATA(x) ((x)&BANDTYPE_FLAG_HASNODATA)
 
 /* Read band from WKB as at start of band */
 static rt_band
@@ -2067,13 +2097,15 @@
 
     band->pixtype = type & BANDTYPE_PIXTYPE_MASK;
     band->offline = BANDTYPE_IS_OFFDB(type) ? 1 : 0;
+    band->hasnodata = BANDTYPE_HAS_NODATA(type) ? 1 : 0;
     band->width = width;
     band->height = height;
 
 #ifdef RT_API_DEBUG
-    ctx->info(" Band pixtype:%s, offline:%d",
+    ctx->info(" Band pixtype:%s, offline:%d, hasnodata:%d",
                 rt_pixtype_name(ctx, band->pixtype),
-                band->offline);
+                band->offline,
+                band->hasnodata);
 #endif
 
     /* Check there's enough bytes to read nodata value */
@@ -2591,6 +2623,7 @@
         /* Add band type */
         *ptr = band->pixtype;
         if ( band->offline ) *ptr |= BANDTYPE_FLAG_OFFDB;
+        if ( band->hasnodata ) *ptr |= BANDTYPE_FLAG_HASNODATA;
         ptr += 1;
 
 #if 0 // no padding required for WKB
@@ -2765,11 +2798,11 @@
         int pixbytes = rt_pixtype_size(ctx, pixtype);
 
         if ( pixbytes < 1 ) {
-            ctx->err("Corrupted band: unkonwn pixtype");
+            ctx->err("Corrupted band: unknown pixtype");
             return 0;
         }
 
-        /* Add space for band type and data padding */
+        /* Add space for band type, hasnodata flag and data padding */
         size += pixbytes;
 
         /* Add space for nodata value */
@@ -2872,10 +2905,8 @@
 
         /* Add band type */
         *ptr = band->pixtype;
-        if ( band->offline )
-        {
-            *ptr |= BANDTYPE_FLAG_OFFDB;
-        }
+        if ( band->offline ) { *ptr |= BANDTYPE_FLAG_OFFDB; }
+        if ( band->hasnodata ) { *ptr |= BANDTYPE_FLAG_HASNODATA; }
 
 #ifdef RT_API_DEBUG
         d_print_binary_hex(ctx, "PIXTYPE", dbg_ptr, size);
@@ -3068,6 +3099,7 @@
 #endif
 
         band->offline = BANDTYPE_IS_OFFDB(type) ? 1 : 0;
+        band->hasnodata = BANDTYPE_HAS_NODATA(type) ? 1: 0;
         band->width = rast->width;
         band->height = rast->height;
         band->ownsData = 0;
@@ -3144,6 +3176,7 @@
         }
 
 #ifdef RT_API_DEBUG
+        ctx->info(" Has NODATA flag %d", band-hasnodata);
         ctx->info(" NODATA value %d", band->nodataval);
 #endif
         /* Consistency checking (ptr is pixbytes-aligned) */
Index: rt_core/rt_api.h
===================================================================
--- rt_core/rt_api.h	(revision 5321)
+++ rt_core/rt_api.h	(working copy)
@@ -126,8 +126,8 @@
  */
 rt_band rt_band_new_inline(rt_context ctx,
                            uint16_t width, uint16_t height,
-                           rt_pixtype pixtype, double nodataval,
-                           uint8_t* data);
+                           rt_pixtype pixtype, uint32_t hasnodata,
+                           double nodataval, uint8_t* data);
 
 /**
  * Create an on-disk rt_band
@@ -150,8 +150,8 @@
  */
 rt_band rt_band_new_offline(rt_context ctx,
                             uint16_t width, uint16_t height,
-                            rt_pixtype pixtype, double nodataval,
-                            uint8_t bandNum, const char* path);
+                            rt_pixtype pixtype, uint32_t hasnodata,
+                            double nodataval, uint8_t bandNum, const char* path);
 
 /**
  * Return non-zero if the given band data is on
@@ -195,8 +195,25 @@
 /* Destroy a raster band */
 void rt_band_destroy(rt_context ctx, rt_band band);
 
-/* Set nodata value
+/**
+ * Get hasnodata flag value
  * @param ctx : context, for thread safety
+ * @param band : the band on which to check the hasnodata flag
+ * @return the hasnodata flag.
+ */
+int rt_band_get_hasnodata_flag(rt_context ctx, rt_band band);
+
+/**
+ * Set hasnodata flag value
+ * @param ctx : context, for thread safety
+ * @param band : the band on which to set the hasnodata flag
+ * @param flag : the new hasnodata flag value. Must be 1 or 0.
+ */
+void rt_band_set_hasnodata_flag(rt_context ctx, rt_band band, int flag);
+
+/**
+ * Set nodata value
+ * @param ctx : context, for thread safety
  * @param band : the band to set nodata value to
  * @param val : the nodata value, must be in the range
  *              of values supported by this band's pixeltype
@@ -208,14 +225,16 @@
  */
 int rt_band_set_nodata(rt_context ctx, rt_band band, double val);
 
-/* Get nodata value
+/**
+ * Get nodata value
  * @param ctx : context, for thread safety
  * @param band : the band to set nodata value to
  * @return nodata value
  */
 double rt_band_get_nodata(rt_context ctx, rt_band band);
 
-/* Set pixel value
+/**
+ * Set pixel value
  * @param ctx : context, for thread safety
  * @param band : the band to set nodata value to
  * @param x : x ordinate
@@ -230,7 +249,8 @@
 int rt_band_set_pixel(rt_context ctx, rt_band band,
                       uint16_t x, uint16_t y, double val);
 
-/* Get pixel value
+/**
+ * Get pixel value
  *
  * @param ctx : context, for thread safety
  * @param band : the band to set nodata value to
Index: doc/RFC1-SerializedFormat
===================================================================
--- doc/RFC1-SerializedFormat	(revision 5321)
+++ doc/RFC1-SerializedFormat	(working copy)
@@ -113,14 +113,14 @@
 
  There are currently 12 supported pixel value types, so 4
  bits are enough to account for all. We'll reserve
- the upper 4 bits for generic flags (might eventually add
- hasnodatavalues or others) and define upmost as storage flag:
+ the upper 4 bits for generic flags and define upmost as
+ storage flag:
  
  #define BANDTYPE_FLAGS_MASK 0xF0
  #define BANDTYPE_PIXTYPE_MASK 0x0F
 
  #define BANDTYPE_FLAG_OFFDB     (1<<7)
- #define BANDTYPE_FLAG_RESERVED1 (1<<6)
+ #define BANDTYPE_FLAG_HASNODATA (1<<6)
  #define BANDTYPE_FLAG_RESERVED2 (1<<5)
  #define BANDTYPE_FLAG_RESERVED3 (1<<4)
 

