[GRASS-SVN] r67213 - grass/trunk/lib/gis

svn_grass at osgeo.org svn_grass at osgeo.org
Fri Dec 18 00:28:13 PST 2015


Author: mmetz
Date: 2015-12-18 00:28:13 -0800 (Fri, 18 Dec 2015)
New Revision: 67213

Added:
   grass/trunk/lib/gis/cmprbzip.c
   grass/trunk/lib/gis/cmprlz4.c
   grass/trunk/lib/gis/cmprrle.c
Log:
libgis: add more compression methods

Copied: grass/trunk/lib/gis/cmprbzip.c (from rev 67212, grass/trunk/lib/gis/cmprzlib.c)
===================================================================
--- grass/trunk/lib/gis/cmprbzip.c	                        (rev 0)
+++ grass/trunk/lib/gis/cmprbzip.c	2015-12-18 08:28:13 UTC (rev 67213)
@@ -0,0 +1,175 @@
+/*
+ ****************************************************************************
+ *                     -- GRASS Development Team --
+ *
+ * MODULE:      GRASS gis library
+ * FILENAME:    cmprbzip.c
+ * AUTHOR(S):   Markus Metz
+ * PURPOSE:     To provide an interface to libbzip2 for compressing and 
+ *              decompressing data.  Its primary use is in
+ *              the storage and reading of GRASS rasters.
+ *
+ * ALGORITHM:   http://www.bzip.org
+ * DATE CREATED: Nov 19 2015
+ * COPYRIGHT:   (C) 2015 by the GRASS Development Team
+ *
+ *              This program is free software under the GNU General Public
+ *              License (version 2 or greater). Read the file COPYING that 
+ *              comes with GRASS for details.
+ *
+ *****************************************************************************/
+
+/********************************************************************
+ * int                                                              *
+ * G_bz2_compress (src, srz_sz, dst, dst_sz)                        *
+ *     int src_sz, dst_sz;                                          *
+ *     unsigned char *src, *dst;                                    *
+ * ---------------------------------------------------------------- *
+ * This function is a wrapper around the bzip2 compression          *
+ * function. It uses an all or nothing call.                        *
+ * If you need a continuous compression scheme, you'll have to code *
+ * your own.                                                        *
+ * In order to do a single pass compression, the input src must be  *
+ * copied to a buffer 1% + 600 bytes larger than the data.  This    *
+ * may cause performance degradation.                               *
+ *                                                                  *
+ * The function either returns the number of bytes of compressed    *
+ * data in dst, or an error code.                                   *
+ *                                                                  *
+ * Errors include:                                                  *
+ *        -1 -- Compression failed.                                 *
+ *        -2 -- dst is too small.                                   *
+ *                                                                  *
+ * ================================================================ *
+ * int                                                              *
+ * G_bz2_expand (src, src_sz, dst, dst_sz)                          *
+ *     int src_sz, dst_sz;                                          *
+ *     unsigned char *src, *dst;                                    *
+ * ---------------------------------------------------------------- *
+ * This function is a wrapper around the bzip2 decompression        *
+ * function. It uses a single pass call to inflate().               *
+ * If you need a continuous expansion scheme, you'll have to code   *
+ * your own.                                                        *
+ *                                                                  *
+ * The function returns the number of bytes expanded into 'dst' or  *
+ * and error code.                                                  *
+ *                                                                  *
+ * Errors include:                                                  *
+ *        -1 -- Expansion failed.                                   *
+ *                                                                  *
+ ********************************************************************
+ */
+
+#include <grass/config.h>
+
+#ifdef HAVE_BZLIB_H
+#include <bzlib.h>
+#endif
+
+#include <grass/gis.h>
+#include <grass/glocale.h>
+
+
+int
+G_bz2_compress(unsigned char *src, int src_sz, unsigned char *dst,
+		int dst_sz)
+{
+    int err;
+    unsigned int i, nbytes, buf_sz;
+    unsigned char *buf;
+
+#ifndef HAVE_BZLIB_H
+    G_fatal_error(_("GRASS needs to be compiled with BZIP2 for BZIP2 compression"));
+    return -1;
+#else
+
+    /* Catch errors early */
+    if (src == NULL || dst == NULL)
+	return -1;
+
+    /* Don't do anything if src is empty */
+    if (src_sz <= 0)
+	return 0;
+
+    /* Output buffer has to be 1% + 600 bytes bigger for single pass compression */
+    buf_sz = (unsigned int)((double)dst_sz * 1.01 + (double)600);
+
+    if (NULL == (buf = (unsigned char *)
+		 G_calloc(buf_sz, sizeof(unsigned char))))
+	return -1;
+
+    /* Do single pass compression */
+    nbytes = buf_sz;
+    err = BZ2_bzBuffToBuffCompress((char *)buf, &nbytes, /* destination */
+                                   (char *)src, src_sz,  /* source */
+				   9,			 /* blockSize100k */ 
+				   0,                    /* verbosity */
+				   0);                   /* workFactor */
+    if (err != BZ_OK) {
+	G_free(buf);
+	return -1;
+    }
+
+    /* updated buf_sz is bytes of compressed data */
+    if (nbytes >= (unsigned int)src_sz) {
+	/* compression not possible */
+	G_free(buf);
+	return -2;
+    }
+
+    /* dst too small */
+    if ((unsigned int)dst_sz < nbytes)
+	return -2;
+
+    /* Copy the data from buf to dst */
+    for (i = 0; i < nbytes; i++)
+	dst[i] = buf[i];
+
+    G_free(buf);
+
+    return nbytes;
+#endif
+}				/* G_bz2_compress() */
+
+int
+G_bz2_expand(unsigned char *src, int src_sz, unsigned char *dst,
+	      int dst_sz)
+{
+    int err;
+    unsigned int nbytes;
+
+#ifndef HAVE_BZLIB_H
+    G_fatal_error(_("GRASS needs to be compiled with BZIP2 for BZIP2 compression"));
+    return -2;
+#else
+
+    /* Catch error condition */
+    if (src == NULL || dst == NULL)
+	return -2;
+
+    /* Don't do anything if either of these are true */
+    if (src_sz <= 0 || dst_sz <= 0)
+	return 0;
+
+
+    /* Do single pass decompression */
+    nbytes = dst_sz;
+    err = BZ2_bzBuffToBuffDecompress((char *)dst, &nbytes,  /* destination */
+                                     (char *)src, src_sz,   /* source */
+				     0,                     /* small */
+				     0);                    /* verbosity */
+
+    /* Number of bytes inflated to output stream is
+     * updated buffer size
+     */
+
+    if (!(err == BZ_OK)) {
+	return -1;
+    }
+
+    return nbytes;
+#endif
+}
+
+
+/* vim: set softtabstop=4 shiftwidth=4 expandtab: */

Copied: grass/trunk/lib/gis/cmprlz4.c (from rev 67212, grass/trunk/lib/gis/cmprzlib.c)
===================================================================
--- grass/trunk/lib/gis/cmprlz4.c	                        (rev 0)
+++ grass/trunk/lib/gis/cmprlz4.c	2015-12-18 08:28:13 UTC (rev 67213)
@@ -0,0 +1,145 @@
+/*
+ ****************************************************************************
+ *                     -- GRASS Development Team --
+ *
+ * MODULE:      GRASS gis library
+ * FILENAME:    cmprlz4.c
+ * AUTHOR(S):   Eric G. Miller <egm2 at jps.net>
+ *              Markus Metz
+ * PURPOSE:     To provide an interface to lz4 for compressing and 
+ *              decompressing data using LZ$.  It's primary use is in
+ *              the storage and reading of GRASS floating point rasters.
+ *
+ * ALGORITHM:   https://code.google.com/p/lz4/
+ * DATE CREATED: Dec 18 2015
+ * COPYRIGHT:   (C) 2015 by the GRASS Development Team
+ *
+ *              This program is free software under the GNU General Public
+ *              License (version 2 or greater). Read the file COPYING that 
+ *              comes with GRASS for details.
+ *
+ *****************************************************************************/
+
+/********************************************************************
+ * int                                                              *
+ * G_lz4_compress (src, srz_sz, dst, dst_sz)                        *
+ *     int src_sz, dst_sz;                                          *
+ *     unsigned char *src, *dst;                                    *
+ * ---------------------------------------------------------------- *
+ * This function is a wrapper around the LZ4 cimpression function.  *
+ * It uses an all or nothing call.                                  *
+ * If you need a continuous compression scheme, you'll have to code *
+ * your own.                                                        *
+ * In order to do a single pass compression, the input src must be  *
+ * copied to a buffer larger than the data.  This may cause         *
+ * performance degradation.                                         *
+ *                                                                  *
+ * The function either returns the number of bytes of compressed    *
+ * data in dst, or an error code.                                   *
+ *                                                                  *
+ * Errors include:                                                  *
+ *        -1 -- Compression failed.                                 *
+ *        -2 -- dst is too small.                                   *
+ *                                                                  *
+ * ================================================================ *
+ * int                                                              *
+ * G_lz4_expand (src, src_sz, dst, dst_sz)                          *
+ *     int src_sz, dst_sz;                                          *
+ *     unsigned char *src, *dst;                                    *
+ * ---------------------------------------------------------------- *
+ * This function is a wrapper around the lz4 decompression          *
+ * function.  It uses a single pass call.  If you need a continuous *
+ * expansion scheme, you'll have to code your own.                  *
+ *                                                                  *
+ * The function returns the number of bytes expanded into 'dst' or  *
+ * and error code.                                                  *
+ *                                                                  *
+ * Errors include:                                                  *
+ *        -1 -- Expansion failed.                                   *
+ *                                                                  *
+ ********************************************************************
+ */
+
+#include <grass/config.h>
+
+#include <grass/gis.h>
+#include <grass/glocale.h>
+
+#include "lz4.h"
+
+
+int
+G_lz4_compress(unsigned char *src, int src_sz, unsigned char *dst,
+		int dst_sz)
+{
+    int err, nbytes, buf_sz;
+    unsigned char *buf;
+
+    /* Catch errors early */
+    if (src == NULL || dst == NULL)
+	return -1;
+
+    /* Don't do anything if either of these are true */
+    if (src_sz <= 0 || dst_sz <= 0)
+	return 0;
+
+    /* Output buffer has to be larger for single pass compression */
+    buf_sz = LZ4_compressBound(src_sz);
+    if (NULL == (buf = (unsigned char *)
+		 G_calloc(buf_sz, sizeof(unsigned char))))
+	return -1;
+
+    /* Do single pass compression */
+    err = LZ4_compress_default((char *)src, (char *)buf, src_sz, buf_sz);
+    if (err <= 0) {
+	G_free(buf);
+	return -1;
+    }
+    if (err >= src_sz) {
+	/* compression not possible */
+	G_free(buf);
+	return -2;
+    }
+    
+    /* bytes of compressed data is return value */
+    nbytes = err;
+
+    /* Copy the data from buf to dst */
+    for (err = 0; err < nbytes; err++)
+	dst[err] = buf[err];
+
+    G_free(buf);
+
+    return nbytes;
+}
+
+int
+G_lz4_expand(unsigned char *src, int src_sz, unsigned char *dst,
+	      int dst_sz)
+{
+    int err, nbytes;
+
+    /* Catch error condition */
+    if (src == NULL || dst == NULL)
+	return -2;
+
+    /* Don't do anything if either of these are true */
+    if (src_sz <= 0 || dst_sz <= 0)
+	return 0;
+
+    /* Do single pass decompress */
+    err = LZ4_decompress_safe((char *)src, (char *)dst, src_sz, dst_sz);
+    /* err = LZ4_decompress_fast(src, dst, src_sz); */
+
+    /* Number of bytes inflated to output stream is return value */
+    nbytes = err;
+
+    if (nbytes != dst_sz) {
+	return -1;
+    }
+
+    return nbytes;
+}
+
+
+/* vim: set softtabstop=4 shiftwidth=4 expandtab: */

Copied: grass/trunk/lib/gis/cmprrle.c (from rev 67212, grass/trunk/lib/gis/cmprzlib.c)
===================================================================
--- grass/trunk/lib/gis/cmprrle.c	                        (rev 0)
+++ grass/trunk/lib/gis/cmprrle.c	2015-12-18 08:28:13 UTC (rev 67213)
@@ -0,0 +1,192 @@
+/*
+ ****************************************************************************
+ *                     -- GRASS Development Team --
+ *
+ * MODULE:      GRASS gis library
+ * FILENAME:    cmprrle.c
+ * AUTHOR(S):   Markus Metz
+ * PURPOSE:     To provide generic RLE for compressing and 
+ *              decompressing data.  Its primary use is in
+ *              the storage and reading of GRASS rasters.
+ *
+ * ALGORITHM:   Run Length Encoding
+ * DATE CREATED: Dec 18 2015
+ * COPYRIGHT:   (C) 2015 by the GRASS Development Team
+ *
+ *              This program is free software under the GNU General Public
+ *              License (version 2 or greater). Read the file COPYING that 
+ *              comes with GRASS for details.
+ *
+ *****************************************************************************/
+
+/********************************************************************
+ * int                                                              *
+ * G_rle_compress (src, srz_sz, dst, dst_sz)                        *
+ *     int src_sz, dst_sz;                                          *
+ *     unsigned char *src, *dst;                                    *
+ * ---------------------------------------------------------------- *
+ * This function compresses data with RLE.                          *
+ * It uses an all or nothing call.                                  *
+ * If you need a continuous compression scheme, you'll have to code *
+ * your own.                                                        *
+ *                                                                  *
+ * The function either returns the number of bytes of compressed    *
+ * data in dst, or an error code.                                   *
+ *                                                                  *
+ * Errors include:                                                  *
+ *        -1 -- Compression failed.                                 *
+ *        -2 -- dst is too small.                                   *
+ *                                                                  *
+ * ================================================================ *
+ * int                                                              *
+ * G_rle_expand (src, src_sz, dst, dst_sz)                          *
+ *     int src_sz, dst_sz;                                          *
+ *     unsigned char *src, *dst;                                    *
+ * ---------------------------------------------------------------- *
+ * This function decompresses data compresed with RLE.              *
+ * It is equivalent to a single pass call to an external expansion  * 
+ * function.                                                        *
+ * If you need a continuous expansion scheme, you'll have to code   *
+ * your own.                                                        *
+ *                                                                  *
+ * The function returns the number of bytes expanded into 'dst' or  *
+ * and error code.                                                  *
+ *                                                                  *
+ * Errors include:                                                  *
+ *        -1 -- Expansion failed.                                   *
+ *                                                                  *
+ ********************************************************************
+ */
+
+#include <grass/config.h>
+
+#include <grass/gis.h>
+#include <grass/glocale.h>
+
+
+int
+G_rle_compress(unsigned char *src, int src_sz, unsigned char *dst,
+		int dst_sz)
+{
+    int i, nbytes;
+    unsigned char prev_b; 
+    int cnt;
+
+    /* Catch errors early */
+    if (src == NULL || dst == NULL)
+	return -1;
+
+    /* Don't do anything if src is empty or smaller than 4 bytes */
+    if (src_sz <= 3)
+	return 0;
+
+    /* modified RLE:
+     * unit is 1 byte, only sequences longer than 1 are encoded
+     * single occurences don't have a following count
+     * multiple occurences are twice in dst, followed by the count
+     * example:
+     * ABBCCC
+     * is encoded as
+     * ABB2CC3 
+     */
+ 
+    prev_b = src[0];
+    cnt = 1;
+    nbytes = 0;
+    for (i = 1; i < src_sz; i++) {
+	if (prev_b != src[i] || cnt == 255) {
+	    /* write to dst */
+	    if (cnt == 1) {
+		if (nbytes >= dst_sz)
+		    return -2;
+		dst[nbytes++] = prev_b;
+	    }
+	    else {
+		/* cnt > 1 */
+		if (nbytes >= dst_sz - 2)
+		    return -2;
+		dst[nbytes++] = prev_b;
+		dst[nbytes++] = prev_b;
+		dst[nbytes++] = (unsigned char) cnt;
+	    }
+	    cnt = 0;
+	}
+	prev_b = src[i];
+	cnt++;
+    }
+    /* write out the last sequence */
+    if (cnt == 1) {
+	if (nbytes >= dst_sz)
+	    return -2;
+	dst[nbytes++] = prev_b;
+    }
+    else {
+	if (nbytes >= dst_sz - 2)
+	    return -2;
+	dst[nbytes++] = prev_b;
+	dst[nbytes++] = prev_b;
+	dst[nbytes++] = (unsigned char) cnt;
+    }
+
+    return nbytes;
+}
+
+int
+G_rle_expand(unsigned char *src, int src_sz, unsigned char *dst,
+		int dst_sz)
+{
+    int i, j, nbytes, cnt;
+    unsigned char prev_b;
+
+    /* Catch errors early */
+    if (src == NULL || dst == NULL)
+	return -1;
+
+    /* Don't do anything if src is empty */
+    if (src_sz <= 0)
+	return 0;
+
+    /* RLE expand */
+    prev_b = src[0];
+    cnt = 1;
+    nbytes = 0;
+    i = 1;
+    while (i < src_sz) {
+	/* single occurences don't have a following count
+	 * multiple occurences are twice in src, followed by the count */
+	if (cnt == 2) {
+	    if (i >= src_sz)
+		return -1;
+	    cnt = src[i];
+	    if (nbytes + cnt > dst_sz)
+		return -1;
+	    for (j = 0; j < cnt; j++) {
+		dst[nbytes++] = prev_b;
+	    }
+	    cnt = 0;
+	    i++;
+	    if (i >= src_sz)
+		return nbytes;
+	}
+	if (cnt == 1) {
+	    if (prev_b != src[i]) {
+		if (nbytes + cnt > dst_sz)
+		    return -1;
+		dst[nbytes++] = prev_b;
+		cnt = 0;
+	    }
+	}
+	prev_b = src[i];
+	cnt++;
+	i++;
+    }
+    if (nbytes >= dst_sz)
+	return -1;
+    if (cnt == 1)
+	dst[nbytes++] = prev_b;
+
+    return nbytes;
+}
+
+
+/* vim: set softtabstop=4 shiftwidth=4 expandtab: */



More information about the grass-commit mailing list