Index: trunk/src/blosc.c
===================================================================
--- trunk/src/blosc.c	(revision 146)
+++ trunk/src/blosc.c	(revision 147)
@@ -87,4 +87,5 @@
   int32_t ntbytes;
   uint32_t nbytes;
+  uint32_t maxbytes;
   uint32_t nblocks;
   uint32_t leftover;
@@ -133,5 +134,5 @@
 /* Shuffle & compress a single block */
 static int blosc_c(size_t blocksize, int32_t leftoverblock,
-                   uint32_t ntbytes, uint32_t nbytes,
+                   uint32_t ntbytes, uint32_t maxbytes,
                    uint8_t *src, uint8_t *dest, uint8_t *tmp)
 {
@@ -168,6 +169,6 @@
     ctbytes += sizeof(int32_t);
     maxout = neblock;
-    if (ntbytes+maxout > nbytes) {
-      maxout = nbytes - ntbytes;   /* avoid buffer overrun */
+    if (ntbytes+maxout > maxbytes) {
+      maxout = maxbytes - ntbytes;   /* avoid buffer overrun */
       if (maxout <= 0) {
         return 0;                  /* non-compressible block */
@@ -188,5 +189,5 @@
       /* Before doing the copy, check that we are not running into a
          buffer overflow. */
-      if ((ntbytes+neblock) > nbytes) {
+      if ((ntbytes+neblock) > maxbytes) {
         return 0;    /* Non-compressible data */
       }
@@ -279,5 +280,5 @@
   size_t blocksize = params.blocksize;
   int32_t ntbytes = params.ntbytes;
-  int32_t nbytes = params.nbytes;
+  uint32_t maxbytes = params.maxbytes;
   uint32_t nblocks = params.nblocks;
   int32_t leftover = params.nbytes % params.blocksize;
@@ -299,5 +300,5 @@
     }
     if (compress) {
-      cbytes = blosc_c(bsize, leftoverblock, ntbytes, nbytes,
+      cbytes = blosc_c(bsize, leftoverblock, ntbytes, maxbytes,
                        src+j*blocksize, dest+ntbytes, tmp);
       if (cbytes == 0) {
@@ -311,5 +312,5 @@
     }
     if (cbytes < 0) {
-      ntbytes = cbytes;         /* error in blosc_c / blosc_d */
+      ntbytes = cbytes;         /* error in blosc_c or blosc_d */
       break;
     }
@@ -319,8 +320,8 @@
   /* Final check for ntbytes (only in compression mode) */
   if (compress) {
-    if (ntbytes == nbytes) {
+    if (ntbytes == maxbytes) {
       ntbytes = 0;               /* non-compressible data */
     }
-    else if (ntbytes > nbytes) {
+    else if (ntbytes > maxbytes) {
       fprintf(stderr, "The impossible happened: buffer overflow!\n");
       ntbytes = -5;               /* too large buffer */
@@ -520,9 +521,13 @@
 
 
+/* The public routine for compression.  See blosc.h for docstrings. */
 unsigned int blosc_compress(int clevel, int shuffle, size_t typesize,
-                            size_t nbytes, const void *src, void *dest)
+                            size_t nbytes, const void *src, void *dest,
+                            size_t maxbytes)
 {
   uint8_t *_dest=NULL;         /* current pos for destination buffer */
-  uint8_t *flags;              /* flags for header */
+  uint8_t *flags;              /* flags for header.  Currently booked:
+                                  - 0: shuffled?
+                                  - 1: memcpy'ed? */
   uint32_t nblocks;            /* number of total blocks in buffer */
   uint32_t leftover;           /* extra bytes at end of buffer */
@@ -543,5 +548,5 @@
   }
   else if (nbytes < MIN_BUFFERSIZE) {
-    /* Too little buffer.  Just return without doing anything else. */
+    /* Buffer too small.  Just return without doing anything else. */
     return 0;
   }
@@ -596,4 +601,5 @@
   params.ntbytes = ntbytes;
   params.nbytes = nbytes;
+  params.maxbytes = maxbytes;
   params.nblocks = nblocks;
   params.leftover = leftover;
@@ -604,13 +610,24 @@
   /* Do the actual compression */
   ntbytes = do_job();
+
+  /* Last chance for fitting `src` buffer in `dest` */
+  if ((ntbytes == 0) && (nbytes+16 <= maxbytes)) {
+    /* Specify that this buffer is memcpy'ed (bit 2 set to 1 in flags) */
+    _dest = (uint8_t *)(dest);
+    _dest[2] = 0x2;
+    memcpy(dest+16, src, nbytes);
+    ntbytes = nbytes+16;
+  }
+
   /* Set the number of compressed bytes in header */
   *ntbytes_ = sw32(ntbytes);
 
-  assert((int32_t)ntbytes < (int32_t)nbytes);
+  assert((int32_t)ntbytes <= (int32_t)maxbytes);
   return ntbytes;
 }
 
 
-unsigned int blosc_decompress(const void *src, void *dest, size_t dest_size)
+/* The public routine for decompression.  See blosc.h for docstrings. */
+unsigned int blosc_decompress(const void *src, void *dest, size_t destsize)
 {
   uint8_t *_src=NULL;            /* current pos for source buffer */
@@ -637,4 +654,11 @@
   blocksize = sw32(((uint32_t *)_src)[1]);   /* block size */
   ctbytes = sw32(((uint32_t *)_src)[2]);     /* compressed buffer size */
+
+  /* Check whether this buffer is memcpy'ed */
+  if (flags == 0x2) {
+    memcpy(dest, src+16, nbytes);
+    return nbytes;
+  }
+
   _src += sizeof(int32_t)*3;
   bstarts = (uint32_t *)_src;
@@ -647,11 +671,10 @@
 
   /* Check zero typesizes.  From Blosc version format 2 on, this value
-   has been reserved for future use (most probably to indicate
-   uncompressible buffers). */
+   has been reserved for future use. */
   if ((version == 1) && (typesize == 0)) {
     typesize = 256;             /* 0 means 256 in format version 1 */
   }
 
-  if (nbytes > dest_size) {
+  if (nbytes > destsize) {
     /* This should never happen but just in case */
     return -1;
@@ -680,5 +703,5 @@
   ntbytes = do_job();
 
-  assert(ntbytes <= (int32_t)dest_size);
+  assert(ntbytes <= (int32_t)destsize);
   return ntbytes;
 }
@@ -764,5 +787,5 @@
   size_t ebsize;
   int32_t compress;
-  uint32_t nbytes;
+  uint32_t maxbytes;
   uint32_t ntbytes;
   uint32_t nblocks;
@@ -815,5 +838,5 @@
     ebsize = blocksize + params.typesize*sizeof(int32_t);
     compress = params.compress;
-    nbytes = params.nbytes;
+    maxbytes = params.maxbytes;
     nblocks = params.nblocks;
     leftover = params.leftover;
@@ -887,5 +910,5 @@
         ntdest = params.ntbytes;
         bstarts[nblock_] = sw32(ntdest);    /* update block start counter */
-        if ( (cbytes == 0) || (ntdest+cbytes > (int32_t)nbytes) ) {
+        if ( (cbytes == 0) || (ntdest+cbytes > (int32_t)maxbytes) ) {
           giveup_code = 0;                  /* uncompressible buffer */
           pthread_mutex_unlock(&count_mutex);
