[Liblas-commits] laszip: the (slower) rangecoder that was replaced
in laszip with...
liblas-commits at liblas.org
liblas-commits at liblas.org
Wed Dec 15 16:59:01 EST 2010
changeset 1fd6740c3f0a in /Volumes/Data/www/liblas.org/laszip
details: http://hg.liblas.orglaszip?cmd=changeset;node=1fd6740c3f0a
summary: the (slower) rangecoder that was replaced in laszip with the (faster) arithmetic coder in january 2010
diffstat:
src/rangedecoder.cpp | 337 ++++++++++++++++++++++++++++++++++++++++++++
src/rangedecoder.hpp | 127 ++++++++++++++++
src/rangeencoder.cpp | 385 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/rangeencoder.hpp | 116 +++++++++++++++
src/rangemodel.cpp | 248 ++++++++++++++++++++++++++++++++
src/rangemodel.hpp | 122 ++++++++++++++++
6 files changed, 1335 insertions(+), 0 deletions(-)
diffs (truncated from 1361 to 300 lines):
diff -r 7c3e352c29ee -r 1fd6740c3f0a src/rangedecoder.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/rangedecoder.cpp Wed Dec 15 13:58:44 2010 -0800
@@ -0,0 +1,337 @@
+/******************************************************************************
+ *
+ * Project: integrating laszip into liblas - http://liblas.org -
+ * Purpose:
+ * Author: Martin Isenburg
+ * isenburg at cs.unc.edu
+ *
+ ******************************************************************************
+ * Copyright (c) 2010, Martin Isenburg
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU Lesser General Licence as published
+ * by the Free Software Foundation.
+ *
+ * See the COPYING file for more information.
+ *
+ ****************************************************************************/
+
+/*
+===============================================================================
+
+ FILE: rangedecoder.cpp
+
+ CONTENTS:
+
+ see header file
+
+ PROGRAMMERS:
+
+ martin isenburg at cs.unc.edu
+
+ COPYRIGHT:
+
+ copyright (C) 2003 martin isenburg (isenburg at cs.unc.edu)
+
+ This software 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.
+
+ CHANGE HISTORY:
+
+ see header file
+
+===============================================================================
+*/
+#include "rangedecoder.hpp"
+#include "rangemodel.hpp"
+
+#include <string.h>
+#include <assert.h>
+
+RangeDecoder::RangeDecoder()
+{
+ instream = 0;
+}
+
+RangeDecoder::~RangeDecoder()
+{
+}
+
+I32 RangeDecoder::init(ByteStreamIn* instream)
+{
+ assert(instream);
+ this->instream = instream;
+ buffer = instream->getByte();
+ assert(buffer == HEADERBYTE);
+ buffer = instream->getByte();
+ low = buffer >> (8-EXTRA_BITS);
+ range = (U32)1 << EXTRA_BITS;
+ return 0;
+}
+
+void RangeDecoder::done()
+{
+ normalize(); /* use up all bytes */
+ instream = 0;
+}
+
+EntropyModel* RangeDecoder::createBitModel()
+{
+ return createSymbolModel(2);
+}
+
+void RangeDecoder::initBitModel(EntropyModel* model)
+{
+ initSymbolModel(model);
+}
+
+void RangeDecoder::destroyBitModel(EntropyModel* model)
+{
+ destroySymbolModel(model);
+}
+
+EntropyModel* RangeDecoder::createSymbolModel(U32 n)
+{
+ RangeModel* m = new RangeModel(n, FALSE);
+ return (EntropyModel*)m;
+}
+
+void RangeDecoder::initSymbolModel(EntropyModel* model, U32 *table)
+{
+ assert(model);
+ RangeModel* m = (RangeModel*)model;
+ m->init(table);
+}
+
+void RangeDecoder::destroySymbolModel(EntropyModel* model)
+{
+ RangeModel* m = (RangeModel*)model;
+ delete m;
+}
+
+U32 RangeDecoder::decodeBit(EntropyModel* model)
+{
+ return decodeSymbol(model);
+}
+
+U32 RangeDecoder::decodeSymbol(EntropyModel* model)
+{
+ RangeModel* m = (RangeModel*)model;
+ U32 sym;
+ U32 ltfreq;
+ U32 syfreq;
+ U32 tmp;
+ U32 lg_totf = m->lg_totf;
+
+ normalize();
+ help = this->range>>lg_totf;
+ ltfreq = low/help;
+#ifdef EXTRAFAST
+ ltfreq = ltfreq;
+#else
+ ltfreq = ((ltfreq>>lg_totf) ? (1<<lg_totf)-1 : ltfreq);
+#endif
+
+ sym = m->getsym(ltfreq);
+ m->getfreq(sym,&syfreq,<freq);
+
+ tmp = help * ltfreq;
+ low -= tmp;
+#ifdef EXTRAFAST
+ this->range = help * syfreq;
+#else
+ if ((ltfreq + syfreq) < (1u<<lg_totf))
+ {
+ this->range = help * syfreq;
+ }
+ else
+ {
+ this->range -= tmp;
+ }
+#endif
+
+ m->update(sym);
+
+ return sym;
+}
+
+/* Decode a bit without modelling */
+U32 RangeDecoder::readBit()
+{
+ U32 tmp;
+ tmp = culshift(1);
+ update(1, tmp, 2);
+ return tmp;
+}
+
+/* Decode bits without modelling */
+U32 RangeDecoder::readBits(U32 bits)
+{
+ U32 tmp;
+ if (bits > 21) // 22 bits
+ {
+ tmp = readShort();
+ U32 tmp1 = readBits(bits - 16) << 16;
+ return (tmp1|tmp);
+ }
+ tmp = culshift(bits);
+ update(1, tmp, 1u<<bits);
+ return tmp;
+}
+
+/* Decode a byte without modelling */
+U8 RangeDecoder::readByte()
+{
+ U8 tmp = culshift(8);
+ update(1, tmp, 1u<<8);
+ return tmp;
+}
+
+/* Decode a short without modelling */
+U16 RangeDecoder::readShort()
+{
+ unsigned short tmp = culshift(16);
+ update(1, tmp, 1u<<16);
+ return tmp;
+}
+
+/* Decode an unsigned int without modelling */
+U32 RangeDecoder::readInt()
+{
+ U32 lowerInt = readShort();
+ U32 upperInt = readShort();
+ return upperInt*U16_MAX_PLUS_ONE+lowerInt;
+}
+
+/* Decode a float without modelling */
+F32 RangeDecoder::readFloat()
+{
+ U32F32 u32f32;
+ u32f32.u32 = readInt();
+ return u32f32.f32;
+}
+
+/* Decode an unsigned 64 bit int without modelling */
+U64 RangeDecoder::readInt64()
+{
+ U64 lowerInt = readInt();
+ U64 upperInt = readInt();
+ return upperInt*U32_MAX_PLUS_ONE+lowerInt;
+}
+
+/* Decode a double without modelling */
+F64 RangeDecoder::readDouble()
+{
+ U64F64 u64f64;
+ u64f64.u64 = readInt64();
+ return u64f64.f64;
+}
+
+U32 RangeDecoder::culshift(U32 shift)
+{
+ U32 tmp;
+ normalize();
+ help = range>>shift;
+ tmp = low/help;
+#ifdef EXTRAFAST
+ return tmp;
+#else
+ return (tmp>>shift ? (1u<<shift)-1 : tmp);
+#endif
+}
+
+/* Update decoding state */
+/* sy_f is the interval length (frequency of the symbol) */
+/* lt_f is the lower end (frequency sum of < symbols) */
+/* tot_f is the total interval length (total frequency sum) */
+void RangeDecoder::update(U32 sy_f, U32 lt_f, U32 tot_f)
+{
+ U32 tmp;
+ tmp = help * lt_f;
+ low -= tmp;
+#ifdef EXTRAFAST
+ this->range = help * sy_f;
+#else
+ if (lt_f + sy_f < tot_f)
+ {
+ this->range = help * sy_f;
+ }
+ else
+ {
+ this->range -= tmp;
+ }
+#endif
+}
+
+inline void RangeDecoder::normalize()
+{
+ while (range <= BOTTOM_VALUE)
+ {
+ low = (low<<8) | ((buffer<<EXTRA_BITS)&0xff);
+ buffer = instream->getByte();
+ low |= buffer >> (8-EXTRA_BITS);
+ range <<= 8;
+ }
+}
+
+/*
+U32 RangeDecoder::readRange(U32 range)
+{
+ U32 tmp;
+ U32 tmp1;
+
+ if (range > 4194303) // 22 bits
+ {
+ tmp = readShort();
+ range = range >> 16;
+ range++;
+ tmp1 = readRange(range) << 16;
+ return (tmp1|tmp);
+ }
+
+ normalize();
+ help = this->range/range;
+ tmp = low/help;
+#ifdef EXTRAFAST
More information about the Liblas-commits
mailing list