summaryrefslogtreecommitdiffstats
path: root/compression
diff options
context:
space:
mode:
authorConstantin Jucovschi <cj@ubuntu.localdomain>2009-04-24 07:20:22 -0400
committerConstantin Jucovschi <cj@ubuntu.localdomain>2009-04-24 07:20:22 -0400
commit8f27e65bddd7d4b8515ce620fb485fdd78fcdf89 (patch)
treebd328a4dd4f92d32202241b5e3a7f36177792c5f /compression
downloadrasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.tar.gz
rasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.tar.xz
rasdaman-upstream-8f27e65bddd7d4b8515ce620fb485fdd78fcdf89.zip
Initial commitv8.0
Diffstat (limited to 'compression')
-rw-r--r--compression/Makefile.am37
-rw-r--r--compression/compresstime.hh46
-rw-r--r--compression/lincompstream.cc985
-rw-r--r--compression/lincompstream.hh553
-rw-r--r--compression/nocompstream.cc194
-rw-r--r--compression/nocompstream.hh101
-rw-r--r--compression/tilecompnone.cc104
-rw-r--r--compression/tilecompnone.hh68
-rw-r--r--compression/tilecompression.cc342
-rw-r--r--compression/tilecompression.hh201
10 files changed, 2631 insertions, 0 deletions
diff --git a/compression/Makefile.am b/compression/Makefile.am
new file mode 100644
index 0000000..73e3c68
--- /dev/null
+++ b/compression/Makefile.am
@@ -0,0 +1,37 @@
+# -*-Makefile-*- (for Emacs)
+#
+# This file is part of rasdaman community.
+#
+# Rasdaman community is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Rasdaman community is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+#
+# Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+# rasdaman GmbH.
+#
+# For more information please see <http://www.rasdaman.org>
+# or contact Peter Baumann via <baumann@rasdaman.com>.
+#
+# MAKEFILE FOR:
+# module compression
+#
+# COMMENTS:
+#
+##################################################################
+
+AM_CXXFLAGS=@CLIENTCXXFLAGS@
+AM_LDFLAGS=@CLIENTLDFLAGS@
+
+noinst_LIBRARIES = libcompression.a
+libcompression_a_SOURCES=nocompstream.cc nocompstream.hh tilecompression.cc \
+ tilecompression.hh tilecompnone.cc tilecompnone.hh \
+ compresstime.hh lincompstream.hh
diff --git a/compression/compresstime.hh b/compression/compresstime.hh
new file mode 100644
index 0000000..c83ad3b
--- /dev/null
+++ b/compression/compresstime.hh
@@ -0,0 +1,46 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: compresstime.hh
+ *
+ * MODULE: compression
+ * CLASS:
+ *
+ * PURPOSE: benchmark compression modules
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifndef _R_COMPRESS_TIME_HH_
+#define _R_COMPRESS_TIME_HH_
+
+#ifdef COMPBENCHMARK
+// for RMTimer
+#include "raslib/rmdebug.hh"
+#define CBENCH_STATEMENT(s) s
+#else
+#define CBENCH_STATEMENT(s)
+#endif
+
+#endif
diff --git a/compression/lincompstream.cc b/compression/lincompstream.cc
new file mode 100644
index 0000000..f5c8474
--- /dev/null
+++ b/compression/lincompstream.cc
@@ -0,0 +1,985 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: lincompstream.cc
+ *
+ * MODULE: compression
+ * CLASS: r_LinCompStream, r_LinDecompStream
+ *
+ * COMMENTS:
+ *
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "raslib/rminit.hh"
+#include "raslib/rmdebug.hh"
+#include "raslib/parseparams.hh"
+#include "raslib/memblockvec.hh"
+#include "compression/lincompstream.hh"
+// for creation of linear (de)compression streams from identifiers
+#include "compression/nocompstream.hh"
+#include "compression/rlestream.hh"
+#include "compression/zlibstream.hh"
+#include "compression/arithstream.hh"
+#include "compression/filestream.hh"
+#include "compression/compresstime.hh"
+
+
+
+const char r_Linear_Stream::bankNameSep = ':';
+
+
+r_Linear_Stream::r_Linear_Stream( void )
+{
+ params = NULL;
+ myTimer = NULL;
+}
+
+r_Linear_Stream::~r_Linear_Stream( void )
+{
+ if (params != NULL)
+ delete params;
+ CBENCH_STATEMENT(if (myTimer != NULL) delete myTimer);
+}
+
+
+r_Linear_Stream::r_Lin_Stream_Format r_Linear_Stream::get_id( const char *name )
+{
+ if (strcasecmp(name, "none") == 0)
+ return r_Lin_Stream_None;
+ else if (strcasecmp(name, "rle") == 0)
+ return r_Lin_Stream_RLE;
+ else if (strcasecmp(name, "zlib") == 0)
+ return r_Lin_Stream_ZLib;
+ else if (strcasecmp(name, "arith") == 0)
+ return r_Lin_Stream_Arith;
+ else if (strcasecmp(name, "file") == 0)
+ return r_Lin_Stream_File;
+ return r_Lin_Stream_NUMBER;
+}
+
+const char *r_Linear_Stream::get_format_string( r_Lin_Stream_Format fmt )
+{
+ switch (fmt)
+ {
+ case r_Lin_Stream_None:
+ return "None";
+ case r_Lin_Stream_RLE:
+ return "RLE";
+ case r_Lin_Stream_ZLib:
+ return "ZLib";
+ case r_Lin_Stream_Arith:
+ return "Arithmetic";
+ case r_Lin_Stream_File:
+ return "File";
+ default:
+ break;
+ }
+ return "???";
+}
+
+r_Linear_Stream::r_Lin_Stream_Format *r_Linear_Stream::get_bank_ids( const char *names )
+{
+ r_Lin_Stream_Format *fmts;
+ unsigned int number, i;
+ const char *d;
+ char buffer[32];
+ char *b;
+
+ d = names; number = 1;
+ while (*d != '\0')
+ {
+ if (*d == bankNameSep) number++;
+ d++;
+ }
+ fmts = new r_Lin_Stream_Format[number+1];
+ d = names; i = 0;
+ while (*d != '\0')
+ {
+ while (isspace((unsigned int)(*d))) d++;
+ b = buffer;
+ while ((!isspace((unsigned int)(*d))) && (*d != bankNameSep) && (*d != '\0')) *b++ = *d++;
+ *b = '\0';
+ if ((fmts[i++] = get_id(buffer)) == r_Lin_Stream_NUMBER)
+ {
+ RMInit::logOut << "r_Linear_Stream::get_bank_ids(): unknown format \""
+ << buffer << '\"' << endl;
+ delete [] fmts;
+ return NULL;
+ }
+ while (isspace((unsigned int)(*d))) d++;
+ if (*d == bankNameSep) d++;
+ }
+ fmts[i] = r_Lin_Stream_NUMBER;
+ if (i != number)
+ {
+ RMInit::logOut << "r_Linear_Stream::get_bank_ids(): warning, inconsistent stream number "
+ << i << ", should be " << number;
+ }
+ return fmts;
+}
+
+char *r_Linear_Stream::get_bank_string( const r_Lin_Stream_Format *ids )
+{
+ unsigned int i, len;
+ char *result, *b;
+
+ len = 0;
+ for (i=0; ids[i] != r_Lin_Stream_NUMBER; i++)
+ {
+ len += strlen(get_format_string(ids[i])) + 1;
+ }
+ result = new char[len+1];
+ b = result;
+ for (i=0; ids[i] != r_Lin_Stream_NUMBER; i++)
+ {
+ const char *str = get_format_string(ids[i]);
+ strcpy(b, str);
+ b += strlen(str);
+ *b++ = bankNameSep;
+ }
+ // remove trailing name separator
+ if (b != result) b--;
+ *b = '\0';
+
+ return result;
+}
+
+int r_Linear_Stream::set_num_symbols( unsigned int syms )
+{
+ // by default this is ignored by most streams (except for arithmetic coding)
+ return 0;
+}
+
+
+// this method should basically only be called when COMPBENCHMARK is defined
+void r_Linear_Stream::instantiate_timer( const char *func, int level )
+{
+#ifdef COMPBENCHMARK
+ if (myTimer != NULL)
+ delete myTimer;
+
+ myTimer = new RMTimer(get_name(), func, level);
+
+ myTimer->start();
+#endif
+}
+
+
+std::ostream &operator<<( std::ostream &s, r_Linear_Stream::r_Lin_Stream_Format fmt )
+{
+ s << r_Linear_Stream::get_format_string(fmt);
+ return s;
+}
+
+
+/*
+ * Linear compression storage
+ */
+
+r_Lin_Comp_Store::r_Lin_Comp_Store( r_ULong bsize )
+{
+ mblocks = NULL;
+ streamer = NULL;
+ cacheSize = bsize;
+ cacheOff = 0;
+ cache = NULL;
+}
+
+r_Lin_Comp_Store::r_Lin_Comp_Store( r_Lin_Comp_Stream *str, r_ULong csize )
+{
+ mblocks = NULL;
+ streamer = str;
+ cacheSize = csize;
+ cacheOff = 0;
+ cache = NULL;
+}
+
+r_Lin_Comp_Store::~r_Lin_Comp_Store( void )
+{
+ // although cache is used in both modes, it's merely a pointer to a block within
+ // mblocks in static mode and mustn't be freed directly in that case.
+ if (mblocks != NULL)
+ {
+ delete mblocks;
+ }
+ else if (cache != NULL)
+ {
+ delete [] ((char*)cache);
+ }
+}
+
+int r_Lin_Comp_Store::start( r_Bytes typeSize )
+{
+ if (streamer != NULL)
+ {
+ RMDBGONCE( 3, RMDebug::module_compression, "r_Lin_Comp_Store", "start() stream " << streamer->get_name() );
+ streamer->begin(typeSize);
+ cache = new char[cacheSize];
+ }
+ else
+ {
+ RMDBGONCE( 3, RMDebug::module_compression, "r_Lin_Comp_Store", "start() static, bsize " << cacheSize );
+ mblocks = new r_Memory_Block_Vector(cacheSize);
+ cache = mblocks->add();
+ }
+
+ if (cache == NULL)
+ return -1;
+
+ return 0;
+}
+
+void *r_Lin_Comp_Store::frag_ptr( void )
+{
+ return (void*)(((char*)cache) + cacheOff);
+}
+
+r_ULong r_Lin_Comp_Store::frag_size( void ) const
+{
+ return cacheSize - cacheOff;
+}
+
+int r_Lin_Comp_Store::frag_stored( r_ULong size )
+{
+ if (size != 0)
+ {
+ cacheOff += size;
+ if (cacheOff >= cacheSize)
+ {
+ if (streamer == NULL)
+ {
+ cache = mblocks->add();
+ }
+ else
+ {
+ if (streamer->put(cache, cacheOff) < 0)
+ return -1;
+ }
+ cacheOff = 0;
+ }
+ }
+ return 0;
+}
+
+int r_Lin_Comp_Store::put( const void *data, r_ULong size )
+{
+ const char *dptr = (const char*)data;
+ r_ULong left = size;
+
+ // note: cache in static mode!
+ while (left != 0)
+ {
+ r_ULong rest;
+
+ rest = cacheSize - cacheOff;
+#ifdef RMANDEBUG
+ if (rest == 0)
+ {
+ RMInit::logOut << "r_Lin_Comp_Store::put(): fatal error!" << endl;
+ throw r_Error (COMPRESSIONFAILED);
+ }
+#endif
+ if (rest > left)
+ rest = left;
+
+ if (rest != 0)
+ {
+ memcpy(((char*)cache) + cacheOff, dptr, rest);
+
+ if (frag_stored(rest) < 0)
+ return -1;
+
+ left -= rest;
+ dptr += rest;
+ }
+ }
+ return 0;
+}
+
+int r_Lin_Comp_Store::put( unsigned char val )
+{
+ ((unsigned char*)cache)[cacheOff] = val;
+ return frag_stored(1);
+}
+
+int r_Lin_Comp_Store::flush( void )
+{
+ if (streamer != NULL)
+ {
+ if (cacheOff != 0)
+ {
+ if (streamer->put(cache, cacheOff) < 0)
+ return -1;
+
+ cacheOff = 0;
+ }
+ }
+ return 0;
+}
+
+r_ULong r_Lin_Comp_Store::stop( void )
+{
+ RMDBGONCE( 3, RMDebug::module_compression, "r_Lin_Comp_Store", "stop()" );
+ if (streamer == NULL)
+ {
+ return mblocks->get_size(cacheOff);
+ }
+ else
+ {
+ if (flush() < 0)
+ return 0;
+
+ return streamer->end();
+ }
+}
+
+void r_Lin_Comp_Store::copy_data( void *dest )
+{
+ if (streamer == NULL)
+ {
+ mblocks->copy_data(dest, cacheOff);
+ }
+ else
+ {
+ streamer->copy_data(dest);
+ }
+}
+
+void r_Lin_Comp_Store::print_status( std::ostream &str ) const
+{
+ if (streamer == NULL)
+ {
+ str << "[static; " << mblocks->get_number() << " blocks, " << mblocks->get_size(cacheOff) << " bytes]";
+ }
+ else
+ {
+ str << "[stream: " << streamer->get_name() << ']';
+ }
+}
+
+
+std::ostream &operator<<( std::ostream &str, const r_Lin_Comp_Store &store )
+{
+ store.print_status(str);
+ return str;
+}
+
+
+
+
+/*
+ * Linear compression encoders...
+ */
+r_Lin_Comp_Stream::r_Lin_Comp_Stream( const r_Lin_Comp_Stream &src ) : r_Linear_Stream()
+{
+ target = NULL; // anything else would have bad side-effects...
+ streamer = src.streamer;
+ blockSize = src.blockSize;
+ autoDeleteStreams = 0;
+}
+
+r_Lin_Comp_Stream::r_Lin_Comp_Stream( void ) : r_Linear_Stream()
+{
+ target = NULL;
+ streamer = NULL;
+ blockSize = 4096;
+ autoDeleteStreams = 0;
+}
+
+r_Lin_Comp_Stream::~r_Lin_Comp_Stream( void )
+{
+ if (target != NULL)
+ delete target;
+
+ if (autoDeleteStreams != 0)
+ free_streams();
+}
+
+void r_Lin_Comp_Stream::set_block_size( r_ULong bsize )
+{
+ blockSize = bsize;
+}
+
+void r_Lin_Comp_Stream::set_stream( r_Lin_Comp_Stream *str )
+{
+ streamer = str;
+}
+
+r_Lin_Comp_Stream *r_Lin_Comp_Stream::get_stream( void )
+{
+ return streamer;
+}
+
+const r_Lin_Comp_Stream *r_Lin_Comp_Stream::get_stream( void ) const
+{
+ return streamer;
+}
+
+void r_Lin_Comp_Stream::print_bank_name( std::ostream &str ) const
+{
+ const r_Lin_Comp_Stream *s = streamer;
+
+ str << get_name();
+ while (s != NULL)
+ {
+ str << " : " << s->get_name();
+ s = s->get_stream();
+ }
+}
+
+void r_Lin_Comp_Stream::free_streams( void )
+{
+ r_Lin_Comp_Stream *s = streamer;
+
+ while (s != NULL)
+ {
+ r_Lin_Comp_Stream *next = s->get_stream();
+ delete s;
+ s = next;
+ }
+}
+
+const char *r_Lin_Comp_Stream::get_stream_file( void ) const
+{
+ const r_Lin_Comp_Stream *s = this;
+
+ while (s != NULL)
+ {
+ if (s->get_format() == r_Lin_Stream_File)
+ return ((r_File_Comp_Stream*)s)->get_file_name();
+ s = s->streamer;
+ }
+ return NULL;
+}
+
+int r_Lin_Comp_Stream::set_stream_file( const char *name )
+{
+ r_Lin_Comp_Stream *s = this;
+
+ while (s != NULL)
+ {
+ if (s->get_format() == r_Lin_Stream_File)
+ {
+ ((r_File_Comp_Stream*)s)->set_file_name(name);
+ return 1;
+ }
+ s = s->streamer;
+ }
+ return 0;
+}
+
+void r_Lin_Comp_Stream::set_storage_handler( const r_Storage_Man &newStore )
+{
+ mystore = newStore;
+}
+
+void r_Lin_Comp_Stream::set_params( const char *str )
+{
+ if (params != NULL)
+ params->process(str);
+}
+
+void r_Lin_Comp_Stream::init_target( void )
+{
+ if (target != NULL)
+ delete target;
+
+ if (streamer == NULL)
+ target = new r_Lin_Comp_Store(blockSize);
+ else
+ target = new r_Lin_Comp_Store(streamer);
+}
+
+void r_Lin_Comp_Stream::exit_target( void )
+{
+ if (target != NULL)
+ {
+ delete target;
+ target = NULL;
+ }
+}
+
+
+// static member function for creation
+r_Lin_Comp_Stream* r_Lin_Comp_Stream::create( r_Lin_Stream_Format fmt, const char *pstr ) throw(r_Error)
+{
+ switch (fmt)
+ {
+ case r_Lin_Stream_None:
+ return new r_No_Comp_Stream();
+ case r_Lin_Stream_RLE:
+ return new r_RLE_Comp_Stream();
+ case r_Lin_Stream_ZLib:
+ return new r_ZLib_Comp_Stream( pstr );
+ case r_Lin_Stream_Arith:
+ return new r_Arith_Comp_Stream();
+ case r_Lin_Stream_File:
+ return new r_File_Comp_Stream( pstr);
+ default:
+ RMInit::logOut << "Unknown linear compression format " << fmt << endl;
+ r_Error err(r_Error::r_Error_General);
+ throw(err);
+ }
+ return NULL;
+}
+
+// allocate a stream bank
+r_Lin_Comp_Stream* r_Lin_Comp_Stream::create( r_Lin_Stream_Format *ids, const char *pstr ) throw(r_Error)
+{
+ r_Lin_Comp_Stream *result = NULL;
+ unsigned int i;
+
+ for (i=0; ids[i] != r_Lin_Stream_NUMBER; i++) ;
+ try
+ {
+ for (; i!=0; i--)
+ {
+ r_Lin_Comp_Stream *str = create(ids[i-1], pstr);
+ str->set_stream(result);
+ result = str;
+ }
+ }
+ catch( r_Error &err )
+ {
+ if (result != NULL)
+ {
+ result->free_streams();
+ delete result;
+ }
+ throw(err);
+ }
+ // mark the root stream as a stream bank owning all child streams
+ if (result != NULL)
+ result->autoDeleteStreams = 1;
+
+ return result;
+}
+
+
+std::ostream &operator<<( std::ostream &str, const r_Lin_Comp_Stream &comp )
+{
+ comp.print_bank_name(str);
+ return str;
+}
+
+
+
+/*
+ * Linear decompression storage
+ */
+
+r_Lin_Decomp_Store::r_Lin_Decomp_Store( void )
+{
+ RMDBGONCE( 3, RMDebug::module_compression, "r_Lin_Decomp_Store", "r_Lin_Decomp_Store()" );
+ streamer = NULL;
+ cache = NULL;
+}
+
+r_Lin_Decomp_Store::r_Lin_Decomp_Store( r_Lin_Decomp_Stream *str, r_ULong csize )
+{
+ RMDBGONCE( 3, RMDebug::module_compression, "r_Lin_Decomp_Store", "r_Lin_Decomp_Store(" << str->get_name() << ')' );
+ streamer = str;
+ cacheSize = csize;
+ cache = new char[cacheSize];
+}
+
+r_Lin_Decomp_Store::~r_Lin_Decomp_Store( void )
+{
+ if (cache != NULL)
+ delete [] (char*)cache;
+}
+
+int r_Lin_Decomp_Store::start( r_Bytes typeSize, const void *data, r_ULong size )
+{
+ if (streamer == NULL)
+ {
+ RMDBGONCE( 4, RMDebug::module_compression, "r_Lin_Decomp_Store", "start() static" );
+ dataBase = data;
+ dataSize = size;
+ dataOffset = 0;
+ }
+ else
+ {
+ RMDBGONCE( 4, RMDebug::module_compression, "r_Lin_Decomp_Store", "start() stream " << streamer->get_name() );
+ cacheLevel = 0;
+ cacheOff = 0;
+ return streamer->begin(typeSize, data, size);
+ }
+ return 0;
+}
+
+int r_Lin_Decomp_Store::ensure_data( void )
+{
+ // in static mode, we don't have to do anything.
+ if ((streamer != NULL) && (cacheOff >= cacheLevel))
+ {
+ // returns 0 for OK or the _negative_ number of unread bytes
+ int status = streamer->get(cache, cacheSize);
+ if (status < 0)
+ {
+ cacheLevel = (r_ULong)((r_Long)cacheSize + (r_Long)status);
+ if (cacheLevel == 0)
+ return -1;
+ }
+ else
+ {
+ // total refill of cache possible
+ cacheLevel = cacheSize;
+ }
+ cacheOff = 0;
+ //cout << "CACHE LEVEL " << cacheLevel << endl;
+ return 1;
+ }
+ return 0;
+}
+
+int r_Lin_Decomp_Store::get( void *data, r_ULong size )
+{
+ r_ULong rest;
+
+ if (streamer == NULL)
+ {
+ rest = dataSize - dataOffset;
+ if (rest > size)
+ rest = size;
+ memcpy(data, ((const char*)dataBase) + dataOffset, rest);
+ dataOffset += rest;
+ if (rest < size)
+ return -((int)(size - rest));
+ }
+ else
+ {
+ r_ULong left = size;
+ char *dptr = (char*)data;
+
+ while (left != 0)
+ {
+ if (ensure_data() < 0)
+ return -((int)left);
+
+ rest = cacheLevel - cacheOff;
+ if (rest > left)
+ rest = left;
+
+ memcpy(dptr, ((char*)cache) + cacheOff, rest);
+ dptr += rest;
+ cacheOff += rest;
+ left -= rest;
+ }
+ }
+ return 0;
+}
+
+int r_Lin_Decomp_Store::get( unsigned char &val )
+{
+ if (streamer == NULL)
+ {
+ if (dataOffset >= dataSize)
+ return -1;
+
+ val = ((unsigned char*)dataBase)[dataOffset++];
+ }
+ else
+ {
+ if (ensure_data() < 0)
+ return -1;
+
+ val = ((unsigned char*)cache)[cacheOff++];
+ }
+ return 0;
+}
+
+int r_Lin_Decomp_Store::stop( void )
+{
+ RMDBGONCE( 4, RMDebug::module_compression, "r_Lin_Decomp_Store", "stop()" );
+ if (streamer != NULL)
+ {
+ return streamer->end();
+ }
+ return 0;
+}
+
+const void *r_Lin_Decomp_Store::frag_ptr( void ) const
+{
+ if (streamer == NULL)
+ return (const void*)(((char*)dataBase)+dataOffset);
+
+ return (const void*)(((char*)cache)+cacheOff);
+}
+
+r_ULong r_Lin_Decomp_Store::frag_size( void ) const
+{
+ if (streamer == NULL)
+ return dataSize - dataOffset;
+
+ return cacheLevel - cacheOff;
+}
+
+int r_Lin_Decomp_Store::frag_read( r_ULong size )
+{
+ if (streamer == NULL)
+ dataOffset += size;
+ else
+ cacheOff += size;
+
+ return 0;
+}
+
+void r_Lin_Decomp_Store::print_status( std::ostream &str ) const
+{
+ if (streamer == NULL)
+ {
+ str << "[static: current " << dataOffset << ", total " << dataSize << ']';
+ }
+ else
+ {
+ str << "[stream: " << streamer->get_name() << ']';
+ }
+}
+
+
+std::ostream &operator<<( std::ostream &str, const r_Lin_Decomp_Store &store )
+{
+ store.print_status(str);
+ return str;
+}
+
+
+
+/*
+ * linear compression decoders
+ */
+r_Lin_Decomp_Stream::r_Lin_Decomp_Stream( void )
+{
+ params = NULL;
+ source = NULL;
+ streamer = NULL;
+ autoDeleteStreams = 0;
+}
+
+r_Lin_Decomp_Stream::~r_Lin_Decomp_Stream( void )
+{
+ if (source != NULL)
+ delete source;
+
+ if (autoDeleteStreams != 0)
+ free_streams();
+}
+
+void r_Lin_Decomp_Stream::set_params( const char *str )
+{
+ if (params != NULL)
+ params->process(str);
+}
+
+void r_Lin_Decomp_Stream::set_stream( r_Lin_Decomp_Stream *str )
+{
+ streamer = str;
+}
+
+r_Lin_Decomp_Stream *r_Lin_Decomp_Stream::get_stream( void )
+{
+ return streamer;
+}
+
+const r_Lin_Decomp_Stream *r_Lin_Decomp_Stream::get_stream( void ) const
+{
+ return streamer;
+}
+
+void r_Lin_Decomp_Stream::print_bank_name( std::ostream &str ) const
+{
+ const r_Lin_Decomp_Stream *s = streamer;
+
+ str << get_name();
+ while (s != NULL)
+ {
+ str << " : " << s->get_name();
+ s = s->get_stream();
+ }
+}
+
+void r_Lin_Decomp_Stream::free_streams( void )
+{
+ r_Lin_Decomp_Stream *s = streamer;
+
+ while (s != NULL)
+ {
+ r_Lin_Decomp_Stream *next = s->get_stream();
+ delete s;
+ s = next;
+ }
+}
+
+const char *r_Lin_Decomp_Stream::get_stream_file( void ) const
+{
+ const r_Lin_Decomp_Stream *s = this;
+
+ while (s != NULL)
+ {
+ if (s->get_format() == r_Lin_Stream_File)
+ return ((r_File_Decomp_Stream*)s)->get_file_name();
+ s = s->streamer;
+ }
+ return NULL;
+}
+
+int r_Lin_Decomp_Stream::set_stream_file( const char *name )
+{
+ r_Lin_Decomp_Stream *s = this;
+
+ while (s != NULL)
+ {
+ if (s->get_format() == r_Lin_Stream_File)
+ {
+ ((r_File_Decomp_Stream*)s)->set_file_name(name);
+ return 1;
+ }
+ s = s->streamer;
+ }
+ return 0;
+}
+
+void r_Lin_Decomp_Stream::init_source( void )
+{
+ if (source != NULL)
+ delete source;
+
+ if (streamer == NULL)
+ source = new r_Lin_Decomp_Store();
+ else
+ source = new r_Lin_Decomp_Store(streamer);
+}
+
+void r_Lin_Decomp_Stream::exit_source( void )
+{
+ delete source;
+ source = NULL;
+}
+
+// static member function for creation
+r_Lin_Decomp_Stream* r_Lin_Decomp_Stream::create( r_Lin_Stream_Format fmt, const char *pstr ) throw(r_Error)
+{
+ switch (fmt)
+ {
+ case r_Lin_Stream_None:
+ return new r_No_Decomp_Stream();
+ case r_Lin_Stream_RLE:
+ return new r_RLE_Decomp_Stream();
+ case r_Lin_Stream_ZLib:
+ return new r_ZLib_Decomp_Stream();
+ case r_Lin_Stream_Arith:
+ return new r_Arith_Decomp_Stream();
+ case r_Lin_Stream_File:
+ return new r_File_Decomp_Stream( pstr );
+ default:
+ RMInit::logOut << "Unknown linear compression format " << fmt << endl;
+ r_Error err(r_Error::r_Error_General);
+ throw(err);
+ }
+ return NULL;
+}
+
+// allocate a stream bank
+r_Lin_Decomp_Stream* r_Lin_Decomp_Stream::create( r_Lin_Stream_Format *ids, const char *pstr ) throw(r_Error)
+{
+ r_Lin_Decomp_Stream *result = NULL;
+ unsigned int i;
+
+ for (i=0; ids[i] != r_Lin_Stream_NUMBER; i++) ;
+ try
+ {
+ for (; i!=0; i--)
+ {
+ r_Lin_Decomp_Stream *str = create(ids[i-1], pstr);
+ str->set_stream(result);
+ result = str;
+ }
+ }
+ catch( r_Error &err )
+ {
+ if (result != NULL)
+ {
+ result->free_streams();
+ delete result;
+ }
+ throw(err);
+ }
+ // mark the root stream as a stream bank owning all the child streams
+ if (result != NULL)
+ result->autoDeleteStreams = 1;
+
+ return result;
+}
+
+
+std::ostream &operator<<( std::ostream &str, const r_Lin_Decomp_Stream &decomp )
+{
+ decomp.print_bank_name(str);
+ return str;
+}
+
+
+
+/*
+ * The container object for matching compression / decompression streams
+ */
+
+r_Lin_Codec_Stream::r_Lin_Codec_Stream( void ) : comp(NULL), decomp(NULL)
+{
+}
+
+
+r_Lin_Codec_Stream::r_Lin_Codec_Stream( r_Linear_Stream::r_Lin_Stream_Format fmt, const char *pstr )
+{
+ comp = r_Lin_Comp_Stream::create(fmt, pstr);
+ decomp = r_Lin_Decomp_Stream::create(fmt, pstr);
+}
+
+
+r_Lin_Codec_Stream::r_Lin_Codec_Stream( r_Linear_Stream::r_Lin_Stream_Format *ids, const char *pstr )
+{
+ comp = r_Lin_Comp_Stream::create(ids, pstr);
+ decomp = r_Lin_Decomp_Stream::create(ids, pstr);
+}
+
+
+r_Lin_Codec_Stream::r_Lin_Codec_Stream( const r_Lin_Codec_Stream &lc )
+{
+ comp = lc.comp->clone();
+ decomp = lc.decomp->clone();
+}
+
+
+r_Lin_Codec_Stream::~r_Lin_Codec_Stream( void )
+{
+ if (comp != NULL)
+ delete comp;
+ if (decomp != NULL)
+ delete decomp;
+}
diff --git a/compression/lincompstream.hh b/compression/lincompstream.hh
new file mode 100644
index 0000000..2e6793e
--- /dev/null
+++ b/compression/lincompstream.hh
@@ -0,0 +1,553 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: lincompstream.hh
+ *
+ * MODULE: compression
+ * CLASS: r_Lin_Comp_Stream, r_Lin_Decomp_Stream
+ *
+ * PURPOSE:
+ * Abstract base class for linear compression streams
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifndef _LINCOMPSTREAM_H_
+#define _LINCOMPSTREAM_H_
+
+
+#include <stdio.h>
+#include <iostream>
+
+#include "raslib/error.hh"
+#include "raslib/storageman.hh"
+#include "raslib/odmgtypes.hh"
+
+
+
+
+class r_Parse_Params;
+class RMTimer;
+
+
+//@ManMemo: Module {\bf compression}
+
+/*@Doc:
+ r_Linear_Stream:
+ Abstract base class for linear compression and decompression strings.
+ Implements enumerator and common interface calls.
+ Linear streams are used to compress or uncompress data in a given format.
+ The can operate in static mode (the compressed data is stored to / read
+ from memory directly) or in streaming mode (the compressed data is stored
+ to / read from another linear stream, without having to buffer intermediate
+ data explicitly or in its entirety). Streaming mode results in nesting
+ linear streams, which can be done to arbitrary depth.
+*/
+
+class r_Linear_Stream
+{
+ public:
+ // stream identifiers
+ enum r_Lin_Stream_Format {
+ r_Lin_Stream_None,
+ r_Lin_Stream_RLE,
+ r_Lin_Stream_ZLib,
+ r_Lin_Stream_Arith,
+ r_Lin_Stream_File,
+ r_Lin_Stream_NUMBER // used as error code
+ };
+ /// default constructor
+ r_Linear_Stream( void );
+ /// destructor
+ virtual ~r_Linear_Stream( void );
+ /// identification
+ virtual r_Lin_Stream_Format get_format( void ) const = 0;
+ /// get the name of the stream, returns r_Lin_Stream_Void if unknown
+ virtual const char* get_name(void) const = 0;
+ /// set compression parameters from a string
+ virtual void set_params( const char *str ) = 0;
+ /// set number of symbols in the stream (used by e.g. arithmetic coders)
+ virtual int set_num_symbols( unsigned int syms );
+ /// get stream identifier from name
+ static r_Lin_Stream_Format get_id( const char *name );
+ /**
+ the name (case independent) may be one of the following
+
+ \begin{tabular}{ll}
+ none && r_No_(De)Comp_Stream\\
+ rle && r_RLE_(De)Comp_Stream\\
+ zlib && r_ZLib_(De)Comp_Stream\\
+ arith && r_Arith_(De)Comp_Stream\\
+ file && r_File_(De)Comp_Stream\\
+ end{tabular}
+ */
+ /// return the string representation of the given format
+ static const char *get_format_string( r_Lin_Stream_Format fmt );
+ /// return a linear stream bank (concatenated streams), terminated by r_Lin_Stream_NUMBER
+ static r_Lin_Stream_Format *get_bank_ids( const char *names );
+ /// return a string representation of the stream bank (caller frees with delete[])
+ static char *get_bank_string( const r_Lin_Stream_Format *ids );
+
+
+ protected:
+ /// instantiate the timer for benchmarking with a certain level
+ void instantiate_timer( const char *func, int level=0 );
+ /// parameters
+ r_Parse_Params *params;
+ /// timer for benchmarking; always defined to keep object size constant
+ RMTimer *myTimer;
+ /// the character used to separate stream names in stream banks
+ static const char bankNameSep;
+};
+
+
+//@ManMemo: Module {\bf compression}
+
+/// string output
+extern std::ostream &operator<<( std::ostream &s, r_Linear_Stream::r_Lin_Stream_Format fmt );
+
+
+
+//@ManMemo: Module {\bf compression}
+
+/*@Doc:
+ r_Lin_Comp_Store:
+ Class abstracting between storing compressed data statically in an object of
+ type r_Memory_Block_Vector or another r_Lin_Comp_Stream to unify normal and
+ (nested) streaming interface. There is a high-level and a low-level interface.
+ The high-level interface allows writing a specified number of bytes to the
+ object (which will redirect it to memory or stream automatically) and is the
+ preferred way. The low-level interface allows block-oriented, external
+ compression libraries like ZLib to operate by giving it a block to store
+ data to. In this case, use frag_ptr() to get the address of a block of
+ memory (``fragment'') which can be written to, the maximum size of which can
+ be obtained with frag_size() and write to it. After your data has been
+ written, you MUST call frag_stored() with the number of bytes you wrote to
+ frag_ptr(), otherwise subsequent calls of frag_ptr() will all return the
+ same data. See zlibstream for an implementation using the low-level
+ interface and the other streams on how the high-level interface is used.
+*/
+
+class r_Lin_Comp_Stream;
+class r_Memory_Block_Vector;
+
+class r_Lin_Comp_Store
+{
+ public:
+ /// constructor for static mode, receiving block size for r_Memory_Block_Vector.
+ r_Lin_Comp_Store( r_ULong bsize );
+ /// constructor for streaming mode, receiving stream compression object and cache size
+ r_Lin_Comp_Store( r_Lin_Comp_Stream *str, r_ULong csize=4096 );
+ /// destructor
+ ~r_Lin_Comp_Store( void );
+
+ /// start output
+ int start( r_Bytes typeSize );
+ /// write data; return 0 for OK, -1 for error
+ int put( const void *data, r_ULong size );
+ /// write single byte
+ int put( unsigned char val );
+ /// stop outputting data and return size
+ r_ULong stop( void );
+ /// copy the data
+ void copy_data( void *dest );
+ /// flush data
+ int flush( void );
+ /// get pointer to current fragment (low-level interface)
+ void *frag_ptr( void );
+ /// get the remaining space in the current fragmend (low-level interface)
+ r_ULong frag_size( void ) const;
+ /// notify that size bytes have been store to current fragmemt (low-level interface)
+ int frag_stored( r_ULong size );
+ /// print status
+ void print_status( std::ostream &str ) const;
+
+
+ protected:
+ /// memory block vector for static mode
+ r_Memory_Block_Vector *mblocks;
+ /// compression stream for streaming mode
+ r_Lin_Comp_Stream *streamer;
+ /// cache in streaming mode
+ void *cache;
+ /// size and current offset in both modes
+ r_ULong cacheSize;
+ r_ULong cacheOff;
+};
+
+extern std::ostream &operator<<( std::ostream &str, const r_Lin_Comp_Store &store );
+
+
+
+//@ManMemo: Module {\bf compression}
+
+/*@Doc:
+ Abstract base class for linear compression streams. Memory allocation is all
+ done transparently in the background. This class provides a common interface
+ to compression methods like zlib or RLE. It can operate in static or streaming
+ mode. In static mode, compressed data is stored explicitly in memory as a whole,
+ whereas in streaming mode, data merely streams through the object and is piped
+ into another object of type r_Lin_Comp_Stream; only a small amount of compressed
+ data is buffered internally for more efficiency. Use set_stream(str) with str != NULL
+ to activate streaming mode, using str as the receiving class.
+*/
+
+class r_Lin_Comp_Stream : public r_Linear_Stream
+{
+ public:
+ /// default constructor
+ r_Lin_Comp_Stream( void );
+ /// copy constructor
+ r_Lin_Comp_Stream( const r_Lin_Comp_Stream &src );
+ /// destructor
+ virtual ~r_Lin_Comp_Stream( void );
+
+ /// change memory handlers (don't change between begin() ... end()!)
+ virtual void set_storage_handler( const r_Storage_Man &newStore );
+
+ /// creation
+ static r_Lin_Comp_Stream* create( r_Lin_Stream_Format fmt, const char *pstr=NULL ) throw(r_Error);
+ /**
+ fmt may be one of the following:
+
+ \begin{tabular}{ll}
+ r_Lin_Stream_None && r_No_(De)Comp_Stream\\
+ r_Lin_Stream_RLE && r_RLE_(De)Comp_Stream\\
+ r_Lin_Stream_ZLib && r_ZLib_(De)Comp_Stream\\
+ r_Lin_Stream_Arith && r_Arith_(De)Comp_Stream\\
+ r_Lin_Stream_File && r_File_(De)Comp_Stream\\
+ \end{tabular}
+
+ In addition, theres r_Lin_Stream_NUMBER used as error code.
+ */
+
+ /// create a stream bank (format as returned by r_Linear_Stream::get_bank_ids() )
+ static r_Lin_Comp_Stream* create( r_Lin_Stream_Format *ids, const char *pstr=NULL ) throw(r_Error);
+
+ /// cloning
+ virtual r_Lin_Comp_Stream* clone( void ) const = 0;
+
+ /// set block size
+ void set_block_size( r_ULong bsize );
+ /// select streaming interface
+ void set_stream( r_Lin_Comp_Stream *str );
+ /*
+ Streamed compression doesn't buffer the data but writes it to the specified
+ lincompstream instead. This allows easy and efficient concatenation of
+ compression streams.
+ */
+ /// get read/write streamer object
+ r_Lin_Comp_Stream *get_stream( void );
+ /// get read-only streamer object
+ const r_Lin_Comp_Stream *get_stream( void ) const;
+ /// print the name of the entire stream bank (recursively)
+ void print_bank_name( std::ostream &str ) const;
+ /// free all child streams (recursively set by set_stream() )
+ void free_streams( void );
+ /// get the name of the output file, or NULL if stream bank doesn't contain file stream
+ const char *get_stream_file( void ) const;
+ /// set the name of the output file if stream bank contains file stream, otherwise return 0
+ int set_stream_file( const char *name );
+
+
+ //@Man: Interface
+ //@{
+ /**
+ typeSize is the size of the base type to encode which is important
+ for some derived classes (e.g. RLE). Make sure that all size arguments
+ must be multiples of typeSize later on. The value 1 should always
+ work, but will usually not be optimal.
+ the inputSize parameter of begin() is the size of the input data or
+ 0 for using defaults). This parameter directly influences the size
+ of the input buffer for some streams and should therefore be used
+ with care.
+ */
+ /// begin compression
+ virtual int begin( r_Bytes typeSize, r_ULong inputSize=0 ) = 0;
+ /// write data to stream
+ virtual int put( const void* data, r_ULong size ) = 0;
+ /// end compression
+ virtual void* end( r_ULong &size ) = 0;
+ /**
+ standard end call, allocates new (linear) memory, copies the data
+ there and frees all internal data
+ */
+ /// alternative end call, just finalizes the stream and returns the size
+ virtual r_ULong end( void ) = 0;
+ /// copy output data into linear memory
+ virtual void copy_data( void* dest ) = 0;
+ //@}
+ virtual void set_params( const char *str );
+
+
+ protected:
+ /// init the target object according to the mode
+ void init_target( void );
+ /// completely finished the target object
+ void exit_target( void );
+ /// memory management object, defaults to C-style
+ r_Storage_Man mystore;
+ /// storage abstraction object
+ r_Lin_Comp_Store *target;
+ /// compression stream for streaming mode
+ r_Lin_Comp_Stream *streamer;
+ /// block size for static mode
+ r_ULong blockSize;
+ /// automatically delete all child streams in destructor if bank constructor was used
+ int autoDeleteStreams;
+};
+
+
+//@ManMemo: Moduke {\bf compression}
+
+//@Doc: print the stream (bank) name of the compression stream to a C++ stream
+
+extern std::ostream &operator<<( std::ostream &str, const r_Lin_Comp_Stream &comp );
+
+
+
+//@ManMemo: Module {\bf compression}
+
+/*@Doc:
+ r_Lin_Decomp_Store:
+ Class abstracting between loading data from raw memory or from another r_Lin_Decomp_Stream
+ to unify normal and (nested) streaming interface. As in r_Lin_Comp_Store, there's a
+ high-level and a low-level interface. The high-level interface can be used to request
+ a specified number of bytes from the storage source (memory or another stream). The
+ low-level interface can be used for external, block-oriented compression libraries
+ like ZLib. Use frag_ptr() to get the start address of the input data and frag_size()
+ for the maximum number of bytes you can read from there. After you read a block, you
+ must call frag_read() with the size of the block as argument, otherwise frag_ptr()
+ will always return the same data. In addition, you should always call ensure_data()
+ before you call frag_ptr(). For an implementation of the low-level interface see
+ zlibstream and the other streams on how the high-level interface should be used.
+ */
+
+class r_Lin_Decomp_Stream;
+
+class r_Lin_Decomp_Store
+{
+ public:
+ /// constructor for static mode
+ r_Lin_Decomp_Store( void );
+ /// constructor for streaming mode, receiving stream decompression object and cache size
+ r_Lin_Decomp_Store( r_Lin_Decomp_Stream *str, r_ULong csize=4096 );
+ /// destructor
+ ~r_Lin_Decomp_Store( void );
+
+ /// start reading data
+ int start( r_Bytes typeSize, const void *data, r_ULong size );
+ /// read data, returns 0 for OK, negative number of unread bytes otherwise
+ int get( void *data, r_ULong size );
+ /// read single byte; returns 0 for OK, -1 for error
+ int get( unsigned char &val );
+ /// stop reading data
+ int stop( void );
+ /// makes sure there's some data in the cache in streaming mode, returns -1 if EOF
+ int ensure_data( void );
+ /// get pointer to current fragment (low-level interface)
+ const void *frag_ptr( void ) const;
+ /// get the valid bytes in the current fragment (low-level interface)
+ r_ULong frag_size( void ) const;
+ /// notify that size bytes have been read from the current fragment
+ int frag_read( r_ULong size );
+ /// print status
+ void print_status( std::ostream &str ) const;
+
+
+ protected:
+ /// start of compressed data in static mode
+ const void *dataBase;
+ /// size of compressed data in static mode
+ r_ULong dataSize;
+ /// current offset in compressed data in static mode
+ r_ULong dataOffset;
+ /// decompression stream in streaming mode
+ r_Lin_Decomp_Stream *streamer;
+ /// cache in streaming mode
+ void *cache;
+ /// cache size, current fill level and current offset in streaming mode
+ r_ULong cacheSize;
+ r_ULong cacheLevel;
+ r_ULong cacheOff;
+};
+
+extern std::ostream &operator<<( std::ostream &str, const r_Lin_Decomp_Store &store );
+
+
+
+//@ManMemo: Module {\bf compression}
+
+/*@Doc:
+ r_Lin_Decomp_Stream:
+ Abstract base class for linear decompression streams. Linear decompression streams
+ can operate in static mode (compressed data is read directly from memory) and
+ streaming mode (compressed data is read from another linear decompression stream).
+ In streaming mode, only a small amount of compressed data is ever buffered
+ internally for more efficiency. Use set_stream(str) with str != NULL to activate
+ streaming mode, using str as the stream providing the input data for this stream.
+ The data and size passed to the begin() method actually belong to str and are
+ passed to it automatically.
+ */
+
+class r_Lin_Decomp_Stream : public r_Linear_Stream
+{
+ public:
+ /// default constructor
+ r_Lin_Decomp_Stream( void );
+ /// destructor
+ virtual ~r_Lin_Decomp_Stream( void );
+
+ /// creation
+ static r_Lin_Decomp_Stream* create( r_Lin_Stream_Format fmt, const char *pstr=NULL ) throw(r_Error);
+ /**
+ for the values of fmt see r_Lin_Comp_Stream::create()
+ */
+ /// create a stream bank
+ static r_Lin_Decomp_Stream* create( r_Lin_Stream_Format *ids, const char *pstr=NULL ) throw(r_Error);
+
+ /// cloning
+ virtual r_Lin_Decomp_Stream* clone( void ) const = 0;
+
+ /// select streaming interface
+ void set_stream( r_Lin_Decomp_Stream *str );
+ /*
+ Streamed decompression doesn't read the data from linear memory but from another
+ object of type r_Lin_Decomp_Stream instead to allow easy and efficient concatenation
+ of decompression streams.
+ */
+ /// get read/write streamer object
+ r_Lin_Decomp_Stream *get_stream( void );
+ /// get read-only streamer object
+ const r_Lin_Decomp_Stream *get_stream( void ) const;
+ /// print the name of the entire stream bank (recursively)
+ void print_bank_name( std::ostream &str ) const;
+ /// free all child streams
+ void free_streams( void );
+ /// get the name of the output file, or NULL if stream bank doesn't contain file stream
+ const char *get_stream_file( void ) const;
+ /// set the name of the output file if stream bank contains file stream, otherwise return 0
+ int set_stream_file( const char *name );
+
+ //@Man: Interface
+ //@{
+ /**
+ You can use three approaches:
+ \begin{enumerate}
+ \item
+ supply dest to begin() and use the get(size) call which will
+ store data to dest and increment dest afterwards, or
+ \item
+ use get(buffer, size) (in that case dest is irrelevant), or
+ \item
+ supply dest to begin() to store the pointer internally, retrieve
+ the pointer later using getDestPtr() and use it in some other
+ way in get(buffer, size) calls.
+ \end{enumerate}
+ */
+ /// get the pointer to destination stored within the object
+ inline void* get_dest_ptr(void) {return destPtr;}
+ /// start decompression.
+ virtual int begin( r_Bytes typeSize, const void* data, r_ULong size,
+ void* dest=NULL ) = 0;
+ /// get() returns 0 for OK, otherwise the negative number of non-read bytes
+ virtual int get( void* buffer, r_ULong size ) = 0;
+ /// get data and store it in the internal destptr (which is incremented)
+ virtual int get( r_ULong size ) = 0;
+ /// end decompression
+ virtual int end( void ) = 0;
+ //@}
+ /// set compression parameters from string
+ virtual void set_params( const char *str );
+
+
+ protected:
+ /// prepare the storage abstraction object
+ void init_source( void );
+ /// finished with the storage abstraction object
+ void exit_source( void );
+ /// default destination
+ void* destPtr;
+ /// storage abstraction object
+ r_Lin_Decomp_Store *source;
+ /// stream object in streaming mode
+ r_Lin_Decomp_Stream *streamer;
+ /// automatically delete all child streams in destructor if bank constructor was used
+ int autoDeleteStreams;
+};
+
+
+//@ManMemo: Module {\bf compression}
+
+//@Doc: print the stream (bank) name of the decompression stream to a C++ stream
+
+extern std::ostream &operator<<( std::ostream &str, const r_Lin_Decomp_Stream &decomp );
+
+
+
+
+//@ManMemo: Module {\bf compression}
+
+/*@Doc:
+ Container class for matching compression and decompression streams
+*/
+
+class r_Lin_Codec_Stream
+{
+ public:
+ /// default constructor, should not be used
+ r_Lin_Codec_Stream( void );
+ /// constructor that creates the codecs
+ r_Lin_Codec_Stream( r_Linear_Stream::r_Lin_Stream_Format fmt, const char *pstr=NULL );
+ /**
+ for the values of fmt see r_Lin_Comp_Stream::create()
+ */
+ /// constructor for a codec bank
+ r_Lin_Codec_Stream( r_Linear_Stream::r_Lin_Stream_Format *ids, const char *pstr=NULL );
+
+ /// copy constructor
+ r_Lin_Codec_Stream( const r_Lin_Codec_Stream &lc );
+ /// destructor
+ ~r_Lin_Codec_Stream( void );
+
+ /// get the stream format
+ inline r_Linear_Stream::r_Lin_Stream_Format get_format( void ) {
+ return comp->get_format();
+ }
+ /// get the compression stream
+ inline r_Lin_Comp_Stream *get_comp_stream( void ) {
+ return comp;
+ }
+ /// get the decompression stream
+ inline r_Lin_Decomp_Stream *get_decomp_stream( void ) {
+ return decomp;
+ }
+
+
+ protected:
+ r_Lin_Comp_Stream *comp;
+ r_Lin_Decomp_Stream *decomp;
+};
+
+#endif
diff --git a/compression/nocompstream.cc b/compression/nocompstream.cc
new file mode 100644
index 0000000..a5758f7
--- /dev/null
+++ b/compression/nocompstream.cc
@@ -0,0 +1,194 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: nocompstream.cc
+ *
+ * MODULE: compression
+ * CLASS: r_No_Comp_Stream, r_No_Decomp_Stream
+ *
+ * COMMENTS:
+ *
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+
+#include "compression/nocompstream.hh"
+#include "compression/compresstime.hh"
+#include "raslib/rminit.hh"
+#include "raslib/rmdebug.hh"
+
+
+
+
+r_No_Comp_Stream::r_No_Comp_Stream( void ) : r_Lin_Comp_Stream()
+{
+ blockSize = 4096;
+}
+
+r_No_Comp_Stream::r_No_Comp_Stream( const r_No_Comp_Stream& src ) : r_Lin_Comp_Stream(src)
+{
+ blockSize = src.blockSize;
+}
+
+r_No_Comp_Stream::~r_No_Comp_Stream( void )
+{
+}
+
+int r_No_Comp_Stream::begin( r_Bytes typeSize, r_ULong inputSize )
+{
+ CBENCH_STATEMENT(instantiate_timer("compress", 0));
+ init_target();
+ int status = target->start(typeSize);
+ CBENCH_STATEMENT(myTimer->pause());
+ return status;
+}
+
+int r_No_Comp_Stream::put( const void* data, r_ULong size )
+{
+ CBENCH_STATEMENT(myTimer->resume());
+ int status = target->put(data, size);
+ CBENCH_STATEMENT(myTimer->pause());
+ return status;
+}
+
+void* r_No_Comp_Stream::end( r_ULong &size )
+{
+ CBENCH_STATEMENT(myTimer->resume());
+
+ size = target->stop();
+ void* result;
+
+ if (size == 0)
+ {
+ CBENCH_STATEMENT(myTimer->stop());
+ return NULL;
+ }
+
+ result = mystore.storage_alloc(size);
+
+ target->copy_data(result);
+
+ exit_target();
+
+ CBENCH_STATEMENT(myTimer->stop());
+
+ return result;
+}
+
+r_ULong r_No_Comp_Stream::end( void )
+{
+ CBENCH_STATEMENT(myTimer->resume());
+ r_ULong size = target->stop();
+ CBENCH_STATEMENT(myTimer->stop());
+ return size;
+}
+
+void r_No_Comp_Stream::copy_data( void* dest )
+{
+ target->copy_data(dest);
+
+ exit_target();
+}
+
+const char* r_No_Comp_Stream::get_name( void ) const
+{
+ return "r_No_Comp_Stream";
+}
+
+r_Linear_Stream::r_Lin_Stream_Format r_No_Comp_Stream::get_format( void ) const
+{
+ return r_Lin_Stream_None;
+}
+
+r_Lin_Comp_Stream* r_No_Comp_Stream::clone( void ) const
+{
+ return new r_No_Comp_Stream(*this);
+}
+
+
+
+
+r_No_Decomp_Stream::r_No_Decomp_Stream( void ) : r_Lin_Decomp_Stream()
+{
+}
+
+r_No_Decomp_Stream::r_No_Decomp_Stream( const r_No_Decomp_Stream& src ) : r_Lin_Decomp_Stream()
+{
+}
+
+r_No_Decomp_Stream::~r_No_Decomp_Stream( void )
+{
+}
+
+int r_No_Decomp_Stream::begin( r_Bytes typeSize, const void* data, r_ULong size, void* dest )
+{
+ CBENCH_STATEMENT(instantiate_timer("decompress", 0));
+ init_source();
+ int status = source->start(typeSize, data, size);
+ CBENCH_STATEMENT(myTimer->pause());
+ return status;
+}
+
+int r_No_Decomp_Stream::get( void* buffer, r_ULong size )
+{
+ CBENCH_STATEMENT(myTimer->resume());
+ int status = source->get(buffer, size);
+ CBENCH_STATEMENT(myTimer->pause());
+ return status;
+}
+
+int r_No_Decomp_Stream::get( r_ULong size )
+{
+ CBENCH_STATEMENT(myTimer->resume());
+ int status = get(destPtr, size);
+ destPtr = (void*)(((char*)destPtr) + size);
+ CBENCH_STATEMENT(myTimer->pause());
+ return status;
+}
+
+int r_No_Decomp_Stream::end( void )
+{
+ CBENCH_STATEMENT(myTimer->resume());
+ int status = source->stop();
+ exit_source();
+ CBENCH_STATEMENT(myTimer->stop());
+ return status;
+}
+
+const char* r_No_Decomp_Stream::get_name( void ) const
+{
+ return "r_No_Decomp_Stream";
+}
+
+r_Linear_Stream::r_Lin_Stream_Format r_No_Decomp_Stream::get_format( void ) const
+{
+ return r_Lin_Stream_None;
+}
+
+r_Lin_Decomp_Stream* r_No_Decomp_Stream::clone( void ) const
+{
+ return new r_No_Decomp_Stream(*this);
+}
diff --git a/compression/nocompstream.hh b/compression/nocompstream.hh
new file mode 100644
index 0000000..8f8aa0d
--- /dev/null
+++ b/compression/nocompstream.hh
@@ -0,0 +1,101 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: nocompstream.hh
+ *
+ * MODULE: compression
+ * CLASS: r_No_Comp_Stream, r_No_Decomp_Stream
+ *
+ * COMMENTS:
+ *
+*/
+
+#ifndef _NOCOMPSTREAM_H_
+#define _NOCOMPSTREAM_H_
+
+
+#include "compression/lincompstream.hh"
+
+
+
+//@ManMemo: Module {\bf compression}
+
+//@Man: compression
+
+/*@Doc:
+ Linear compression class implementing simple storage without
+ compression.
+*/
+
+class r_No_Comp_Stream : public r_Lin_Comp_Stream
+{
+public:
+ /// default constructor
+ r_No_Comp_Stream( void );
+ /// copy constructor
+ r_No_Comp_Stream( const r_No_Comp_Stream& src );
+ /// destructor
+ ~r_No_Comp_Stream( void );
+ /// identification
+ r_Lin_Stream_Format get_format( void ) const;
+ const char* get_name( void ) const;
+ /// cloning
+ r_Lin_Comp_Stream* clone( void ) const;
+ /// control compression
+ int begin( r_Bytes typeSize, r_ULong inputSize=0 );
+ int put( const void* data, r_ULong size );
+ void* end( r_ULong &size );
+ r_ULong end( void );
+ void copy_data( void* dest );
+};
+
+
+//@Man: Decompression
+
+/*@Doc:
+ Linear decompression class implementing simple storage without
+ decompression.
+*/
+class r_No_Decomp_Stream : public r_Lin_Decomp_Stream
+{
+public:
+ /// default constructor
+ r_No_Decomp_Stream( void );
+ /// copy constructor
+ r_No_Decomp_Stream( const r_No_Decomp_Stream& src );
+ /// destructor
+ ~r_No_Decomp_Stream( void );
+ /// identification
+ r_Lin_Stream_Format get_format( void ) const;
+ const char* get_name( void ) const;
+ /// cloning
+ r_Lin_Decomp_Stream* clone( void ) const;
+ /// control decompression
+ int begin( r_Bytes typeSize, const void* data, r_ULong size,
+ void* dest=NULL );
+ int get( void* buffer, r_ULong size );
+ int get( r_ULong size );
+ int end( void );
+};
+
+#endif
diff --git a/compression/tilecompnone.cc b/compression/tilecompnone.cc
new file mode 100644
index 0000000..12d4908
--- /dev/null
+++ b/compression/tilecompnone.cc
@@ -0,0 +1,104 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: tilecompnone.cc
+ *
+ * MODULE: compression
+ * CLASS: r_Tile_Comp_None
+ *
+ * COMMENTS:
+ *
+*/
+
+#include <string.h>
+
+#include "raslib/rminit.hh"
+#include "raslib/rmdebug.hh"
+#include "compression/tilecompnone.hh"
+
+
+r_Tile_Comp_None::r_Tile_Comp_None( const r_Minterval &dom, const r_Base_Type *type ) : r_Tile_Compression(dom, type)
+{
+ RMDBGONCE( 2, RMDebug::module_compression, "r_Tile_Comp_None", "r_Tile_Comp_None(dom,type)" );
+}
+
+
+r_Tile_Comp_None::r_Tile_Comp_None( const r_Tile_Comp_None &src) : r_Tile_Compression(src)
+{
+ RMDBGONCE( 2, RMDebug::module_compression, "r_Tile_Comp_None", "r_Tile_Comp_None(src)" );
+}
+
+
+r_Tile_Comp_None::~r_Tile_Comp_None( void )
+{
+ RMDBGONCE( 2, RMDebug::module_compression, "r_Tile_Comp_None", "~r_Tile_Comp_None()" );
+}
+
+
+void *r_Tile_Comp_None::compress( const void *src, r_ULong &size, const char *options )
+{
+ void *result;
+
+ RMDBGONCE( 2, RMDebug::module_compression, "r_Tile_Comp_None", "compress()" );
+
+ size = get_tile_size();
+ if ((result = mystore.storage_alloc(size)) != NULL)
+ memcpy(result, src, get_tile_size());
+ else
+ RMInit::logOut << "r_Tile_Comp_None::compress(): unable to allocate memory" << endl;
+
+ return result;
+}
+
+
+void *r_Tile_Comp_None::decompress( const void *src, r_ULong size, const char *options )
+{
+ void *result;
+
+ RMDBGONCE( 2, RMDebug::module_compression, "r_Tile_Comp_None", "decompress()" );
+
+ if ((result = mystore.storage_alloc(get_tile_size())) != NULL)
+ memcpy(result, src, get_tile_size());
+ else
+ RMInit::logOut << "r_Tile_Comp_None::decompress(): unable to allocate memory" << endl;
+
+ return result;
+}
+
+
+const char *r_Tile_Comp_None::get_name( void ) const
+{
+ return format_name_array;
+}
+
+
+r_Data_Format r_Tile_Comp_None::get_data_format( void ) const
+{
+ return r_Array;
+}
+
+
+r_Tile_Compression *r_Tile_Comp_None::clone( void ) const
+{
+ return new r_Tile_Comp_None(*this);
+}
diff --git a/compression/tilecompnone.hh b/compression/tilecompnone.hh
new file mode 100644
index 0000000..1c0ae3a
--- /dev/null
+++ b/compression/tilecompnone.hh
@@ -0,0 +1,68 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: tilecompnone.hh
+ *
+ * MODULE: compression
+ * CLASS: r_Tile_Comp_None
+ *
+ * COMMENTS:
+ *
+*/
+
+
+#ifndef _R_TILE_COMP_NONE_HH_
+#define _R_TILE_COMP_NONE_HH_
+
+#include "compression/tilecompression.hh"
+
+
+//@ManMemo: Module {\bf compression}
+
+/*@Doc:
+ Tile compression for no compression. This should normally not be used,
+ but in some cases it's required for cleaner modelling (e.g. an unsupported
+ data format is requested which is interpreted as uncompressed data).
+*/
+
+class r_Tile_Comp_None : public r_Tile_Compression
+{
+ public:
+ /// constructor
+ r_Tile_Comp_None( const r_Minterval &dom, const r_Base_Type *type );
+ /// copy constructor
+ r_Tile_Comp_None( const r_Tile_Comp_None &src );
+ /// destructor
+ ~r_Tile_Comp_None( void );
+ /// compress function
+ virtual void *compress( const void *data, r_ULong &size, const char *options=NULL );
+ /// decompress function
+ virtual void *decompress( const void *data, r_ULong size, const char *options=NULL );
+ /// identification
+ const char *get_name( void ) const;
+ r_Data_Format get_data_format( void ) const;
+ /// create a copy
+ r_Tile_Compression *clone( void ) const;
+};
+
+#endif
diff --git a/compression/tilecompression.cc b/compression/tilecompression.cc
new file mode 100644
index 0000000..f99a815
--- /dev/null
+++ b/compression/tilecompression.cc
@@ -0,0 +1,342 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: tilecompression.cc
+ *
+ * MODULE: compression
+ * CLASS: r_Tile_Compression
+ *
+ * COMMENTS:
+ *
+*/
+
+
+#include <stdlib.h>
+#include <string.h>
+
+
+#include "raslib/rmdebug.hh"
+#include "raslib/minterval.hh"
+#include "raslib/type.hh"
+#include "raslib/type.hh"
+#include "raslib/basetype.hh"
+#include "raslib/parseparams.hh"
+#include "raslib/primitivetype.hh"
+#include "raslib/structuretype.hh"
+
+#include "compression/tilecompression.hh"
+// for creating tile compression objects
+#include "compression/tilecompnone.hh"
+#include "compression/compresstime.hh"
+
+
+
+/*
+ * r_Tile_Compression class
+ */
+
+const r_Tile_Compression::tile_comp_format_t r_Tile_Compression::all_formats[] = {
+ { r_Array, format_name_array },
+ { r_RLE, format_name_rle },
+ { r_ZLib, format_name_zlib },
+ { r_Sep_RLE, format_name_sep_rle },
+ { r_Sep_ZLib, format_name_sep_zlib },
+ { r_Wavelet_Haar, format_name_wavelet_haar },
+ { r_Wavelet_Daubechies, format_name_wavelet_daubechies },
+ { r_Wavelet_QHaar, format_name_wavelet_qhaar },
+ // here we go the wavelets defined in r_Ortho_Wavelet_Factory
+ { r_Wavelet_Daub6, format_name_wavelet_daub6 },
+ { r_Wavelet_Daub8, format_name_wavelet_daub8 },
+ { r_Wavelet_Daub10, format_name_wavelet_daub10 },
+ { r_Wavelet_Daub12, format_name_wavelet_daub12 },
+ { r_Wavelet_Daub14, format_name_wavelet_daub14 },
+ { r_Wavelet_Daub16, format_name_wavelet_daub16 },
+ { r_Wavelet_Daub18, format_name_wavelet_daub18 },
+ { r_Wavelet_Daub20, format_name_wavelet_daub20 },
+ { r_Wavelet_Least8, format_name_wavelet_least8 },
+ { r_Wavelet_Least10, format_name_wavelet_least10 },
+ { r_Wavelet_Least12, format_name_wavelet_least12 },
+ { r_Wavelet_Least14, format_name_wavelet_least14 },
+ { r_Wavelet_Least16, format_name_wavelet_least16 },
+ { r_Wavelet_Least18, format_name_wavelet_least18 },
+ { r_Wavelet_Least20, format_name_wavelet_least20 },
+ { r_Wavelet_Coiflet6, format_name_wavelet_coiflet6 },
+ { r_Wavelet_Coiflet12, format_name_wavelet_coiflet12 },
+ { r_Wavelet_Coiflet18, format_name_wavelet_coiflet18 },
+ { r_Wavelet_Coiflet24, format_name_wavelet_coiflet24 },
+ { r_Wavelet_Coiflet30, format_name_wavelet_coiflet30 },
+ { r_TMC, format_name_tmc }
+};
+
+
+r_Tile_Compression::r_Tile_Compression( const r_Minterval &dom, const r_Base_Type *type ) : mydomain(dom)
+{
+ mytype = (r_Base_Type*)(type->clone());
+ compParams = NULL;
+ decompParams = NULL;
+ myTimer = NULL;
+}
+
+
+r_Tile_Compression::r_Tile_Compression( const r_Tile_Compression &src ) : mydomain(src.mydomain)
+{
+ mytype = (r_Base_Type*)(src.mytype->clone());
+ compParams = NULL;
+ decompParams = NULL;
+ myTimer = NULL;
+ mystore = src.mystore;
+}
+
+
+r_Tile_Compression::~r_Tile_Compression( void )
+{
+ delete mytype;
+
+ if (compParams != NULL)
+ delete compParams;
+ if (decompParams != NULL)
+ delete decompParams;
+ CBENCH_STATEMENT(if (myTimer != NULL) delete myTimer);
+}
+
+
+bool r_Tile_Compression::converts_endianness( void ) const
+{
+ return false;
+}
+
+
+r_Bytes r_Tile_Compression::get_type_size( void ) const
+{
+ return mytype->size();
+}
+
+
+r_ULong r_Tile_Compression::get_tile_size( void ) const
+{
+ unsigned int size;
+
+ if ((size = get_type_size()) == 0) return 0;
+
+ return size * mydomain.cell_count();
+}
+
+
+const r_Minterval &r_Tile_Compression::get_domain( void ) const
+{
+ return mydomain;
+}
+
+
+const r_Base_Type *r_Tile_Compression::get_base_type( void ) const
+{
+ return mytype;
+}
+
+
+void r_Tile_Compression::set_storage_handler( const r_Storage_Man &newStore )
+{
+ mystore = newStore;
+}
+
+
+// should only be called if COMPBENCHMARK is defined
+void r_Tile_Compression::instantiate_timer( const char *func, int level )
+{
+#ifdef COMPBENCHMARK
+ if (myTimer != NULL)
+ delete myTimer;
+
+ myTimer = new RMTimer(get_name(), func, level);
+ myTimer->start();
+#endif
+}
+
+
+void r_Tile_Compression::resume_timer( void )
+{
+ CBENCH_STATEMENT(myTimer->resume());
+}
+
+void r_Tile_Compression::pause_timer( void )
+{
+ CBENCH_STATEMENT(myTimer->pause());
+}
+
+
+
+void r_Tile_Compression::write_short( void *dest, r_Short val )
+{
+ unsigned char *dptr = (unsigned char*)dest;
+
+ dptr[0] = (val & 0xff);
+ dptr[1] = ((val >> 8) & 0xff);
+}
+
+
+void r_Tile_Compression::write_long( void *dest, r_Long val )
+{
+ unsigned char *dptr = (unsigned char*)dest;
+
+ dptr[0] = (val & 0xff);
+ dptr[1] = ((val >> 8) & 0xff);
+ dptr[2] = ((val >> 16) & 0xff);
+ dptr[3] = ((val >> 24) & 0xff);
+}
+
+
+void r_Tile_Compression::read_short( const void *src, r_Short &val )
+{
+ const unsigned char *sptr = (const unsigned char *)src;
+
+ val = (r_Short)(sptr[0] | (sptr[1] << 8));
+}
+
+
+void r_Tile_Compression::read_long( const void *src, r_Long &val )
+{
+ const unsigned char *sptr = (const unsigned char *)src;
+
+ val = (r_Long)(sptr[0] | (sptr[1] << 8) | (sptr[2] << 16) | (sptr[3] << 24));
+}
+
+
+r_Data_Format r_Tile_Compression::get_decomp_format( void ) const
+{
+ return r_Array;
+}
+
+
+unsigned int r_Tile_Compression::get_atom_info( const r_Base_Type* baseType, unsigned int* sizes, unsigned int* idxptr )
+{
+ unsigned int sum;
+ unsigned int idx;
+
+ RMDBGONCE( 3, RMDebug::module_compression, "r_Tile_Compression", "get_atom_info()" );
+
+ if (idxptr == NULL)
+ idx = 0;
+ else
+ idx = *idxptr;
+
+ if (baseType->isStructType())
+ {
+ r_Structure_Type* structType = (r_Structure_Type*)baseType;
+ r_Structure_Type::attribute_iterator iter(structType->defines_attribute_begin());
+
+ sum = 0;
+ while (iter != structType->defines_attribute_end())
+ {
+ r_Base_Type *newType = (r_Base_Type*)((*iter).type_of().clone());
+ if (newType->isStructType())
+ sum += get_atom_info(newType, sizes);
+ else
+ {
+ sum++;
+ if (sizes != NULL)
+ sizes[idx++] = newType->size();
+ }
+ delete newType;
+ iter++;
+ }
+ }
+ else
+ {
+ sum = 1;
+ if (sizes != NULL)
+ sizes[idx++] = baseType->size();
+ }
+
+ if (idxptr != NULL)
+ *idxptr = idx;
+
+ return sum;
+}
+
+
+const char *r_Tile_Compression::get_format_info( unsigned int number, r_Data_Format &fmt )
+{
+ unsigned int numFormats = sizeof(all_formats) / sizeof(tile_comp_format_t);
+
+ if (number >= numFormats)
+ return NULL;
+
+ fmt = all_formats[number].format;
+ return all_formats[number].name;
+}
+
+
+r_Tile_Compression::Support_Format r_Tile_Compression::check_data_format( r_Data_Format fmt )
+{
+ return r_Tile_Compression::COMPRESSION;
+}
+
+
+// create tile compression object from data format
+r_Tile_Compression *r_Tile_Compression::create( r_Data_Format fmt, const r_Minterval &dom, const r_Base_Type *type ) throw(r_Error)
+{
+ r_Tile_Compression *result;
+
+ switch (fmt)
+ {
+ // raw array data
+ case r_Array:
+ result = new r_Tile_Comp_None(dom, type);
+ break;
+ default:
+ RMInit::logOut << "r_Tile_Compression::create(): Unknown or unsupported tile compression " << fmt << endl;
+ r_Error err(r_Error::r_Error_General);
+ throw(err);
+ break;
+ }
+ return result;
+}
+
+
+// create tile compression object from algorithm name
+r_Tile_Compression *r_Tile_Compression::create( const char *name, const r_Minterval &dom, const r_Base_Type *type) throw(r_Error)
+{
+ return create(get_format_from_name(name), dom, type);
+}
+
+
+// get the data format for a compression name
+r_Data_Format r_Tile_Compression::get_format_from_name( const char *name ) throw(r_Error)
+{
+ unsigned int numFormats = sizeof(all_formats) / sizeof(tile_comp_format_t);
+ unsigned int i;
+
+ for (i=0; i<numFormats; i++)
+ {
+ if (strcasecmp(name, all_formats[i].name) == 0)
+ break;
+ }
+ if (i >= numFormats)
+ {
+ RMInit::logOut << "r_Tile_Compression::create(): Unknown compression algorithm " << name << endl;
+ r_Error err(r_Error::r_Error_General);
+ throw(err);
+ }
+ return all_formats[i].format;
+}
+
diff --git a/compression/tilecompression.hh b/compression/tilecompression.hh
new file mode 100644
index 0000000..6e954ce
--- /dev/null
+++ b/compression/tilecompression.hh
@@ -0,0 +1,201 @@
+/*
+* This file is part of rasdaman community.
+*
+* Rasdaman community is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* Rasdaman community is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with rasdaman community. If not, see <http://www.gnu.org/licenses/>.
+*
+* Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Peter Baumann /
+rasdaman GmbH.
+*
+* For more information please see <http://www.rasdaman.org>
+* or contact Peter Baumann via <baumann@rasdaman.com>.
+/
+/**
+ * INCLUDE: tilecompression.hh
+ *
+ * MODULE: compression
+ * CLASS: r_Tile_Compression
+ *
+ * COMMENTS:
+ *
+*/
+
+
+#ifndef _R_TILE_COMPRESSION_HH_
+#define _R_TILE_COMPRESSION_HH_
+
+
+#include <stdio.h>
+
+#include "raslib/error.hh"
+#include "raslib/minterval.hh"
+#include "raslib/mddtypes.hh"
+#include "raslib/odmgtypes.hh"
+#include "raslib/storageman.hh"
+
+
+class r_Base_Type;
+class r_Parse_Params;
+class RMTimer;
+
+
+//@ManMemo: Module: {\bf compression}
+
+/*@Doc:
+ Abstract base class for compression / decompression functionality
+ of tiles, to be executed on client or server. r_Tile_Compression is
+ used by both compressing and uncompressing classes.
+ */
+
+class r_Tile_Compression
+{
+ public:
+ /// enum used as return for check_data_format
+ enum Support_Format
+ { INVALID=0, COMPRESSION, CONVERSION };
+
+ /// default constructor, fixes size and layout of tile
+ r_Tile_Compression( const r_Minterval &dom, const r_Base_Type *type );
+ /// copy constructor
+ r_Tile_Compression( const r_Tile_Compression &src );
+ /// destructor
+ virtual ~r_Tile_Compression( void );
+
+ /// check support for fmt
+ static Support_Format check_data_format( r_Data_Format fmt );
+ /**
+ check whether there is support for the given data format; returns COMPRESSION
+ for a real compression format, CONVERSION for a data exchange format, INVALID othe */
+
+ /// create a compression class from the data format
+ static r_Tile_Compression *create( r_Data_Format fmt, const r_Minterval &dom, const r_Base_Type *type ) throw(r_Error);
+
+ /// create a compression class from the name of the compression algorithm
+ static r_Tile_Compression *create( const char *name, const r_Minterval &dom, const r_Base_Type *type ) throw(r_Error);
+
+ /// get a data format for a compression name
+ static r_Data_Format get_format_from_name( const char *name ) throw(r_Error);
+
+ /// read name and data format of available tile compression formats
+ static const char *get_format_info( unsigned int number, r_Data_Format &fmt );
+
+ /// compress
+ virtual void *compress( const void *data, r_ULong &size, const char *options = NULL ) = 0;
+ /**
+ compresses data, passes options to the underlying compression scheme
+ and returns a pointer to the compressed data and its size. Deallocate
+ the pointer with tilecomp_free() !
+ */
+
+ /// decompress
+ virtual void *decompress( const void *data, r_ULong size, const char *options = NULL ) = 0;
+ /**
+ decompresses the compressed data of size bytes, passing options to the
+ underlying decompression scheme and returns a pointer to the
+ decompressed data. Deallocate the pointer with tilecomp_free() !
+ */
+
+ /// data format after decompression
+ virtual r_Data_Format get_decomp_format( void ) const;
+ /**
+ data format after decompression. This allows easier integration of
+ data exchange formats with the compression mechanism: real compression
+ engines return r_Array, DEF containers return their DEF's data format.
+ This function need only be overloaded if the decompressed format differs
+ from r_Array.
+ */
+
+ /// check whether compression and decompression automatically do the
+ /// required endianness conversions (this is usually only true for
+ /// complex approaches like wavelets)
+ virtual bool converts_endianness( void ) const;
+
+ /// returns name of compression scheme
+ virtual const char *get_name( void ) const = 0;
+ /// returns compression scheme identifier
+ virtual r_Data_Format get_data_format( void ) const = 0;
+ /// make a copy of this compression scheme
+ virtual r_Tile_Compression *clone( void ) const = 0;
+
+ /// returns the size of one cell
+ r_Bytes get_type_size( void ) const;
+ /// returns the size of the uncompressed data
+ r_ULong get_tile_size( void ) const;
+ /// returns tile domain
+ const r_Minterval &get_domain( void ) const;
+ /// returns tile type
+ const r_Base_Type *get_base_type( void ) const;
+ /// resume timer (COMPBENCHMARK only)
+ void resume_timer( void );
+ /// pause timer (COMPBENCHMARK only)
+ void pause_timer( void );
+
+ /// set the storage handler
+ virtual void set_storage_handler( const r_Storage_Man &newStore );
+ /**
+ set the storage handler to use for memory (de)allocation of the
+ pointers returned from (de)compress. By default malloc/free are
+ used.
+ */
+
+ //@Man: internal<--> external data representations
+ /**
+ Since the tile compression class must run on client and server, the
+ data format must be well-specified on both. The following functions
+ take care of endianness and alignment.
+ */
+ /// write a short to dest
+ static void write_short( void *dest, r_Short val );
+ /// write a long to dest
+ static void write_long( void *dest, r_Long val );
+ /// read a short from dest
+ static void read_short( const void *src, r_Short &val );
+ /// write a short to dest
+ static void read_long( const void *src, r_Long &val );
+
+ /// structure for storing information about all data formats
+ typedef struct tile_comp_format_s {
+ r_Data_Format format;
+ const char *name;
+ } tile_comp_format_t;
+
+
+
+ protected:
+
+ /// get information about a base type's atomic types
+ static unsigned int get_atom_info( const r_Base_Type* baseType, unsigned int* sizes=NULL,
+ unsigned int *idxptr=NULL );
+ /**
+ return number of atomic types in base type, optionally return the
+ individual sizes in sizes. idxptr must be NULL (or missing) when calling.
+ */
+
+ /// instantiate timer for benchmarking with a given level
+ void instantiate_timer( const char *func, int level=0 );
+
+ r_Storage_Man mystore;
+
+ r_Minterval mydomain;
+ r_Base_Type *mytype;
+
+ r_Parse_Params *compParams;
+ r_Parse_Params *decompParams;
+
+ RMTimer *myTimer;
+
+ static const tile_comp_format_t all_formats[];
+};
+
+
+#endif