[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,&ltfreq);
+
+  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