All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines
Static Public Member Functions
GeopsyCore::Gse Class Reference

Call containing all GSE util function (compression/decompression) More...

#include <Gse.h>

List of all members.

Static Public Member Functions

static int checksum (int *data, int nData)
static char * compress6 (int nData, int *data, int &iComp)
static bool decompress6 (int nComp, const char *comp, int nData, int *data)
static void diff (int *data, int nData)
static void remdif (int *data, int nData)

Detailed Description

Call containing all GSE util function (compression/decompression)

Translated in C++ from Fortran by Marc Wathelet, in other to be portable on all architecture including AMD64.

Original notification in Fortran source:

The following data compression and decompression routines have been developped by Dr. Shane Ingate and Dr. Ken Muirhead, at the Australian Seismological Centre, Bureau of Mineral Resources, Canberra, Australia. They provided me with these routines in March 1989 during the session of the Group of Scientific Experts (GSE) in Geneva. These compression/decompression algorithms are used by all members of the GSE during the large-scale data exchange experiment GSETT-2, carried out from 1989 to 1991. It is recommended to use second differences and the six-bit compression. The second differences can be computed by two subsequent calls of subroutine DIF1 (see above). These routines are already running on many different machines. Because the AND function is not standard FORTRAN 77, this operation has been moved to a separate subroutine INTAND. All users of these routines will have to modify INTAND so that it performs correctly on their computers. Urs Kradolfer, Swiss Seismological Service


Member Function Documentation

int GeopsyCore::Gse::checksum ( int *  data,
int  nData 
) [static]

Compute checksum for GSE format from decompressed integer vector data which contains nData. Must be apply to fully decompressed data (including double difference).

Checksum calculation (Annex three, page 145)

References QGpCoreTools::abs(), and TRACE.

Referenced by GeopsyCore::Signal::writeGse().

{
  TRACE;
  int cs=0;
  int modulo=100000000;
  for(int i=0;i < nData;i++ ) {
    int iy=data[ i ];
    if( ::abs(iy) >= modulo) iy=iy - (iy/modulo) * modulo;
    cs=cs + iy;
    if( ::abs(cs) >= modulo)
      cs=cs - (cs/modulo) * modulo;
  }
  cs=::abs(cs);
  return cs;
}
char * GeopsyCore::Gse::compress6 ( int  nData,
int *  data,
int &  iComp 
) [static]

Compress integer data into printable ASCCI characters.

data is an array containing nData integers.

Compression uses the least significant six bits of an eight bit byte (ease ASCII conversion).

Coding:

Bit 76543210 76543210 76543210 (dec) 00101001 00111001 00000111 --> 604423 00110110 11000110 11111100 --> -604423

  • Bit 5 : continuation bit, if 0 then last byte for this sample.
  • Bit 4 : sign bit for first byte only. For others: data.
  • Bits 3 (or 4) to 0: data

If 6 bytes are required:

N data bits Value Byte 1 5 0x0000 001F Byte 2 5 0x0000 03FF Byte 3 5 0x0000 7FFF Byte 4 5 0x000F FFFF Byte 5 5 0x01FF FFFF Byte 6 4 0x1FFF FFFF

If 5 bytes are required:

N data bits Value Byte 1 5 0x0000 001F Byte 2 5 0x0000 03FF Byte 3 5 0x0000 7FFF Byte 4 5 0x000F FFFF Byte 5 4 0x00FF FFFF

If 4 bytes are required:

N data bits Value Byte 1 5 0x0000 001F Byte 2 5 0x0000 03FF Byte 3 5 0x0000 7FFF Byte 4 4 0x0007 FFFF

If 3 bytes are required:

N data bits Value Byte 1 5 0x0000 001F Byte 2 5 0x0000 03FF Byte 3 4 0x0000 3FFF

If 2 bytes are required:

N data bits Value Byte 1 5 0x0000 001F Byte 2 4 0x0000 01FF

If 1 byte is required:

N data bits Value Byte 1 4 0x0000 000F

Each byte is composed of an unsigned number between 0 and 63. GSE format includes a dedicated character table to convert to ASCII (only +, -, 0 to 9, A to Z, and a to z are used).

It returns a newly allocated pointer with the compressed data. iComp is set to the exact number of characters in the compressed-encoded buffer. iComp can be uninitialized.

Data may be decompressed with decompress6().

References TRACE.

Referenced by GeopsyCore::Signal::writeGse().

{
  TRACE;
  static uint continuationBit=0x20;
  int nComp=nData;
  iComp=0;
  char * comp=new char [ nComp ];
  unsigned int signBit;
  int val;
  for(int i=0; i < nData; i++ ) {
    if(data[i]<0) {
      val=-data[i];
      signBit=0x10;
    } else {
      val=data[i];
      signBit=0x00;
    }
    if(iComp+6>=nComp) {
      nComp=nComp << 1;
      char * tmp=new char [ nComp ];
      memcpy(tmp, comp, sizeof(char)*iComp);
      delete [] comp;
      comp=tmp;
    }
    if(val<=0x00003FFF) {
      if(val<=0x000001FF) {
        if(val<=0x0000000F) { // 1 byte
          comp[iComp++]=gseChar2ascii(val | signBit);
        } else { // 2 bytes
          comp[iComp++]=gseChar2ascii(((val & 0x000001E0) >> 5) | signBit | continuationBit);
          comp[iComp++]=gseChar2ascii(  val & 0x0000001F);
        }
      } else { // 3 bytes
        comp[iComp++]=gseChar2ascii(((val & 0x00003C00) >> 10) | signBit | continuationBit);
        comp[iComp++]=gseChar2ascii(((val & 0x000003E0) >> 5) | continuationBit);
        comp[iComp++]=gseChar2ascii(  val & 0x0000001F);
      }
    } else {
      if(val<=0x0007FFFF) { // 4 bytes
        comp[iComp++]=gseChar2ascii(((val & 0x00078000) >> 15) | signBit | continuationBit);
        comp[iComp++]=gseChar2ascii(((val & 0x00007C00) >> 10) | continuationBit);
        comp[iComp++]=gseChar2ascii(((val & 0x000003E0) >> 5) | continuationBit);
        comp[iComp++]=gseChar2ascii(  val & 0x0000001F);
      } else {
        if(val<=0x00FFFFFF) { // 5 bytes
          comp[iComp++]=gseChar2ascii(((val & 0x00F00000) >> 20) | signBit | continuationBit);
          comp[iComp++]=gseChar2ascii(((val & 0x000F8000) >> 15) | continuationBit);
          comp[iComp++]=gseChar2ascii(((val & 0x00007C00) >> 10) | continuationBit);
          comp[iComp++]=gseChar2ascii(((val & 0x000003E0) >> 5) | continuationBit);
          comp[iComp++]=gseChar2ascii(  val & 0x0000001F);
        } else { // 6 bytes
          if(val>0x1FFFFFFF) {
            val=0x1FFFFFFF;
          }
          comp[iComp++]=gseChar2ascii(((val & 0x1E000000) >> 25) | signBit | continuationBit);
          comp[iComp++]=gseChar2ascii(((val & 0x01F00000) >> 20) | continuationBit);
          comp[iComp++]=gseChar2ascii(((val & 0x000F8000) >> 15) | continuationBit);
          comp[iComp++]=gseChar2ascii(((val & 0x00007C00) >> 10) | continuationBit);
          comp[iComp++]=gseChar2ascii(((val & 0x000003E0) >> 5) | continuationBit);
          comp[iComp++]=gseChar2ascii(  val & 0x0000001F);
        }
      }
    }
  }
  return comp;
}
bool GeopsyCore::Gse::decompress6 ( int  nComp,
const char *  comp,
int  nData,
int *  data 
) [static]

Decompress integer data that has been compressed into ASCII characters and returns values in int format.

buf is an array containing n characters. nData is the number of expected integers data is the result vector.

It returns false and warns through log stream if compressed buffer does not contain nData integers.

See also:
compress6

References QGpCoreTools::endl(), QGpCoreTools::tr(), and TRACE.

{
  TRACE;
  bool continuationBit, signBit;
  int val;
  int iData=0;
  unsigned int gseChar;
  for(int i=0; i < nComp; i++ ) {
    if(isspace( comp[ i ] ))
      continue;
    gseChar=ascii2gseChar(comp[ i ] );
    continuationBit=gseChar & 0x20;
    signBit=gseChar & 0x10;
    gseChar=gseChar & 0x0F;
    val=gseChar;
    while(continuationBit) {
      i++;
      if(isspace( comp[ i ] ))
        continue;
      gseChar=ascii2gseChar(comp[ i ] );
      continuationBit=gseChar & 0x20;
      gseChar=gseChar & 0x1F;
      val=val << 5;
      val += gseChar;
    }
    if(signBit)
      val=-val;
    // Check the size of the output data vector
    if(iData==nData) {
      App::stream() << tr("Corrupted compressed data, more than %1 integers are "
                          "obtained after decompression" ).arg(nData) << endl;
      return false;
    }
    data[ iData ]=val;
    iData++;
  }
  if(iData!=nData) {
    App::stream() << tr("Corrupted compressed data, less than %1 integers are "
                        "obtained after decompression" ).arg(nData) << endl;
    return false;
  } else
    return true;
}
void GeopsyCore::Gse::diff ( int *  data,
int  nData 
) [static]

Computes the sample difference (used for data compression). This function is called twice for usual GSE formats

References TRACE.

Referenced by GeopsyCore::Signal::writeGse().

{
  TRACE;
  int lastVal=data[0], originalVal;
  for(int i=1; i< nData; i++) {
    originalVal=data[i];
    data[i]-= lastVal;
    lastVal=originalVal;
  }
}
void GeopsyCore::Gse::remdif ( int *  data,
int  nData 
) [static]

Removes the sample difference (used for data decompression) and restore original signal. This function is called twice for usual GSE formats

References TRACE.

{
  TRACE;
  for(int i=1; i< nData; i++) {
    data[i]+=data[i-1];
  }
}

The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines