Call containing all GSE util function (compression/decompression) More...
#include <Gse.h>
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) |
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
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().
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
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.
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] |