Initial commit based on common repo commit ffeb9c9b

This commit is contained in:
2021-04-22 15:57:00 +02:00
commit 8b2a408e6f
107 changed files with 61542 additions and 0 deletions

1
libs/3rd-party/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1 @@
subdirs(mseed)

7
libs/3rd-party/mseed/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,7 @@
SET(LIB_NAME mseed)
FILE(GLOB SOURCES "*.cpp" "*.c" "*.h")
ADD_LIBRARY(${LIB_NAME} STATIC ${SOURCES})
SET_TARGET_PROPERTIES(${LIB_NAME} PROPERTIES COMPILE_FLAGS -fPIC)

1183
libs/3rd-party/mseed/fileutils.c vendored Normal file

File diff suppressed because it is too large Load Diff

1407
libs/3rd-party/mseed/genutils.c vendored Normal file

File diff suppressed because it is too large Load Diff

150
libs/3rd-party/mseed/gswap.c vendored Normal file
View File

@ -0,0 +1,150 @@
/***************************************************************************
* gswap.c:
*
* Functions for generalized, in-pace byte swapping between LSBF and
* MSBF byte orders.
*
* Some standard integer types are needed, namely uint8_t and
* uint32_t, (these are normally declared by including inttypes.h or
* stdint.h). Each function expects it's input to be a void pointer
* to a quantity of the appropriate size.
*
* There are two versions of most routines, one that works on
* quantities regardless of alignment (gswapX) and one that works on
* memory aligned quantities (gswapXa). The memory aligned versions
* (gswapXa) are much faster than the other versions (gswapX), but the
* memory *must* be aligned.
*
* Written by Chad Trabant,
* IRIS Data Management Center
*
* Version: 2010.006
***************************************************************************/
#include "lmplatform.h"
/* Swap routines that work on any (aligned or not) quantities */
void
ms_gswap2 ( void *data2 )
{
uint8_t temp;
union
{
uint8_t c[2];
} dat;
memcpy( &dat, data2, 2 );
temp = dat.c[0];
dat.c[0] = dat.c[1];
dat.c[1] = temp;
memcpy( data2, &dat, 2 );
}
void
ms_gswap3 ( void *data3 )
{
uint8_t temp;
union
{
uint8_t c[3];
} dat;
memcpy( &dat, data3, 3 );
temp = dat.c[0];
dat.c[0] = dat.c[2];
dat.c[2] = temp;
memcpy( data3, &dat, 3 );
}
void
ms_gswap4 ( void *data4 )
{
uint8_t temp;
union {
uint8_t c[4];
} dat;
memcpy( &dat, data4, 4 );
temp = dat.c[0];
dat.c[0] = dat.c[3];
dat.c[3] = temp;
temp = dat.c[1];
dat.c[1] = dat.c[2];
dat.c[2] = temp;
memcpy( data4, &dat, 4 );
}
void
ms_gswap8 ( void *data8 )
{
uint8_t temp;
union
{
uint8_t c[8];
} dat;
memcpy( &dat, data8, 8 );
temp = dat.c[0];
dat.c[0] = dat.c[7];
dat.c[7] = temp;
temp = dat.c[1];
dat.c[1] = dat.c[6];
dat.c[6] = temp;
temp = dat.c[2];
dat.c[2] = dat.c[5];
dat.c[5] = temp;
temp = dat.c[3];
dat.c[3] = dat.c[4];
dat.c[4] = temp;
memcpy( data8, &dat, 8 );
}
/* Swap routines that work on memory aligned quantities */
void
ms_gswap2a ( void *data2 )
{
uint16_t *data = data2;
*data=(((*data>>8)&0xff) | ((*data&0xff)<<8));
}
void
ms_gswap4a ( void *data4 )
{
uint32_t *data = data4;
*data=(((*data>>24)&0xff) | ((*data&0xff)<<24) |
((*data>>8)&0xff00) | ((*data&0xff00)<<8));
}
void
ms_gswap8a ( void *data8 )
{
uint32_t *data4 = data8;
uint32_t h0, h1;
h0 = data4[0];
h0 = (((h0>>24)&0xff) | ((h0&0xff)<<24) |
((h0>>8)&0xff00) | ((h0&0xff00)<<8));
h1 = data4[1];
h1 = (((h1>>24)&0xff) | ((h1&0xff)<<24) |
((h1>>8)&0xff00) | ((h1&0xff00)<<8));
data4[0] = h1;
data4[1] = h0;
}

106
libs/3rd-party/mseed/libmseed.def vendored Normal file
View File

@ -0,0 +1,106 @@
LIBRARY libmseed.dll
EXPORTS
msr_parse
msr_parse_selection
msr_unpack
msr_pack
msr_pack_header
msr_init
msr_free
msr_free_blktchain
msr_addblockette
msr_normalize_header
msr_duplicate
msr_samprate
msr_nomsamprate
msr_starttime
msr_starttime_uc
msr_endtime
msr_srcname
msr_print
msr_host_latency
ms_detect
ms_parse_raw
mst_init
mst_free
mst_initgroup
mst_freegroup
mst_findmatch
mst_findadjacent
mst_addmsr
mst_addspan
mst_addmsrtogroup
mst_addtracetogroup
mst_groupheal
mst_groupsort
mst_srcname
mst_printtracelist
mst_printsynclist
mst_printgaplist
mst_pack
mst_packgroup
mstl_init
mstl_free
mstl_addmsr
mstl_printtracelist
mstl_printsynclist
mstl_printgaplist
ms_readmsr
ms_readmsr_r
ms_readmsr_main
ms_readtraces
ms_readtraces_timewin
ms_readtraces_selection
ms_readtracelist
ms_readtracelist_timewin
ms_readtracelist_selection
msr_writemseed
mst_writemseed
mst_writemseedgroup
ms_recsrcname
ms_splitsrcname
ms_strncpclean
ms_strncpopen
ms_doy2md
ms_md2doy
ms_btime2hptime
ms_btime2isotimestr
ms_btime2mdtimestr
ms_btime2seedtimestr
ms_hptime2btime
ms_hptime2isotimestr
ms_hptime2mdtimestr
ms_hptime2seedtimestr
ms_time2hptime
ms_seedtimestr2hptime
ms_timestr2hptime
ms_nomsamprate
ms_genfactmult
ms_ratapprox
ms_bigendianhost
ms_dabs
ms_samplesize
ms_encodingstr
ms_blktdesc
ms_blktlen
ms_errorstr
ms_log
ms_log_l
ms_loginit
ms_loginit_l
ms_matchselect
msr_matchselect
ms_addselect
ms_addselect_comp
ms_readselectionsfile
ms_freeselections
ms_printselections
ms_gswap2
ms_gswap3
ms_gswap4
ms_gswap8
ms_gswap2a
ms_gswap4a
ms_gswap8a
msr_unpack_steim2
msr_unpack_steim1

735
libs/3rd-party/mseed/libmseed.h vendored Normal file
View File

@ -0,0 +1,735 @@
/***************************************************************************
* libmseed.h:
*
* Interface declarations for the Mini-SEED library (libmseed).
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License
* as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This library 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
* Library General Public License (GNU-LGPL) for more details. The
* GNU-LGPL and further information can be found here:
* http://www.gnu.org/
*
* Written by Chad Trabant
* IRIS Data Management Center
***************************************************************************/
#ifndef LIBMSEED_H
#define LIBMSEED_H 1
#ifdef __cplusplus
extern "C" {
#endif
#include "lmplatform.h"
#define LIBMSEED_VERSION "2.13"
#define LIBMSEED_RELEASE "2014.234"
#define MINRECLEN 128 /* Minimum Mini-SEED record length, 2^7 bytes */
/* Note: the SEED specification minimum is 256 */
#define MAXRECLEN 1048576 /* Maximum Mini-SEED record length, 2^20 bytes */
/* SEED data encoding types */
#define DE_ASCII 0
#define DE_INT16 1
#define DE_INT32 3
#define DE_FLOAT32 4
#define DE_FLOAT64 5
#define DE_STEIM1 10
#define DE_STEIM2 11
#define DE_GEOSCOPE24 12
#define DE_GEOSCOPE163 13
#define DE_GEOSCOPE164 14
#define DE_CDSN 16
#define DE_SRO 30
#define DE_DWWSSN 32
/* Library return and error code values, error values should always be negative */
#define MS_ENDOFFILE 1 /* End of file reached return value */
#define MS_NOERROR 0 /* No error */
#define MS_GENERROR -1 /* Generic unspecified error */
#define MS_NOTSEED -2 /* Data not SEED */
#define MS_WRONGLENGTH -3 /* Length of data read was not correct */
#define MS_OUTOFRANGE -4 /* SEED record length out of range */
#define MS_UNKNOWNFORMAT -5 /* Unknown data encoding format */
#define MS_STBADCOMPFLAG -6 /* Steim, invalid compression flag(s) */
/* Define the high precision time tick interval as 1/modulus seconds */
/* Default modulus of 1000000 defines tick interval as a microsecond */
#define HPTMODULUS 1000000
/* Error code for routines that normally return a high precision time.
* The time value corresponds to '1902/1/1 00:00:00.000000' with the
* default HPTMODULUS */
#define HPTERROR -2145916800000000LL
/* Macros to scale between Unix/POSIX epoch time & high precision time */
#define MS_EPOCH2HPTIME(X) X * (hptime_t) HPTMODULUS
#define MS_HPTIME2EPOCH(X) X / HPTMODULUS
/* Macro to test a character for data record indicators */
#define MS_ISDATAINDICATOR(X) (X=='D' || X=='R' || X=='Q' || X=='M')
/* Macro to test default sample rate tolerance: abs(1-sr1/sr2) < 0.0001 */
#define MS_ISRATETOLERABLE(A,B) (ms_dabs (1.0 - (A / B)) < 0.0001)
/* Macro to test for sane year and day values, used primarily to
* determine if byte order swapping is needed.
*
* Year : between 1900 and 2100
* Day : between 1 and 366
*
* This test is non-unique (non-deterministic) for days 1, 256 and 257
* in the year 2056 because the swapped values are also within range.
*/
#define MS_ISVALIDYEARDAY(Y,D) (Y >= 1900 && Y <= 2100 && D >= 1 && D <= 366)
/* Macro to test memory for a SEED data record signature by checking
* SEED data record header values at known byte offsets to determine
* if the memory contains a valid record.
*
* Offset = Value
* [0-5] = Digits, spaces or NULL, SEED sequence number
* 6 = Data record quality indicator
* 7 = Space or NULL [not valid SEED]
* 24 = Start hour (0-23)
* 25 = Start minute (0-59)
* 26 = Start second (0-60)
*
* Usage:
* MS_ISVALIDHEADER ((char *)X) X buffer must contain at least 27 bytes
*/
#define MS_ISVALIDHEADER(X) ( \
(isdigit ((unsigned char) *(X)) || *(X) == ' ' || !*(X) ) && \
(isdigit ((unsigned char) *(X+1)) || *(X+1) == ' ' || !*(X+1) ) && \
(isdigit ((unsigned char) *(X+2)) || *(X+2) == ' ' || !*(X+2) ) && \
(isdigit ((unsigned char) *(X+3)) || *(X+3) == ' ' || !*(X+3) ) && \
(isdigit ((unsigned char) *(X+4)) || *(X+4) == ' ' || !*(X+4) ) && \
(isdigit ((unsigned char) *(X+5)) || *(X+5) == ' ' || !*(X+5) ) && \
MS_ISDATAINDICATOR(*(X+6)) && \
(*(X+7) == ' ' || *(X+7) == '\0') && \
(int)(*(X+24)) >= 0 && (int)(*(X+24)) <= 23 && \
(int)(*(X+25)) >= 0 && (int)(*(X+25)) <= 59 && \
(int)(*(X+26)) >= 0 && (int)(*(X+26)) <= 60)
/* Macro to test memory for a blank/noise SEED data record signature
* by checking for a valid SEED sequence number and padding characters
* to determine if the memory contains a valid blank/noise record.
*
* Offset = Value
* [0-5] = Digits or NULL, SEED sequence number
* [6-47] = Space character (ASCII 32), remainder of fixed header
*
* Usage:
* MS_ISVALIDBLANK ((char *)X) X buffer must contain at least 27 bytes
*/
#define MS_ISVALIDBLANK(X) ((isdigit ((unsigned char) *(X)) || !*(X) ) && \
(isdigit ((unsigned char) *(X+1)) || !*(X+1) ) && \
(isdigit ((unsigned char) *(X+2)) || !*(X+2) ) && \
(isdigit ((unsigned char) *(X+3)) || !*(X+3) ) && \
(isdigit ((unsigned char) *(X+4)) || !*(X+4) ) && \
(isdigit ((unsigned char) *(X+5)) || !*(X+5) ) && \
(*(X+6)==' ')&&(*(X+7)==' ')&&(*(X+8)==' ') && \
(*(X+9)==' ')&&(*(X+10)==' ')&&(*(X+11)==' ') && \
(*(X+12)==' ')&&(*(X+13)==' ')&&(*(X+14)==' ') && \
(*(X+15)==' ')&&(*(X+16)==' ')&&(*(X+17)==' ') && \
(*(X+18)==' ')&&(*(X+19)==' ')&&(*(X+20)==' ') && \
(*(X+21)==' ')&&(*(X+22)==' ')&&(*(X+23)==' ') && \
(*(X+24)==' ')&&(*(X+25)==' ')&&(*(X+26)==' ') && \
(*(X+27)==' ')&&(*(X+28)==' ')&&(*(X+29)==' ') && \
(*(X+30)==' ')&&(*(X+31)==' ')&&(*(X+32)==' ') && \
(*(X+33)==' ')&&(*(X+34)==' ')&&(*(X+35)==' ') && \
(*(X+36)==' ')&&(*(X+37)==' ')&&(*(X+38)==' ') && \
(*(X+39)==' ')&&(*(X+40)==' ')&&(*(X+41)==' ') && \
(*(X+42)==' ')&&(*(X+43)==' ')&&(*(X+44)==' ') && \
(*(X+45)==' ')&&(*(X+46)==' ')&&(*(X+47)==' ') )
/* A simple bitwise AND test to return 0 or 1 */
#define bit(x,y) (x&y)?1:0
/* Require a large (>= 64-bit) integer type for hptime_t */
typedef int64_t hptime_t;
/* A single byte flag type */
typedef int8_t flag;
/* SEED binary time */
typedef struct btime_s
{
uint16_t year;
uint16_t day;
uint8_t hour;
uint8_t min;
uint8_t sec;
uint8_t unused;
uint16_t fract;
} LMP_PACKED
BTime;
/* Fixed section data of header */
struct fsdh_s
{
char sequence_number[6];
char dataquality;
char reserved;
char station[5];
char location[2];
char channel[3];
char network[2];
BTime start_time;
uint16_t numsamples;
int16_t samprate_fact;
int16_t samprate_mult;
uint8_t act_flags;
uint8_t io_flags;
uint8_t dq_flags;
uint8_t numblockettes;
int32_t time_correct;
uint16_t data_offset;
uint16_t blockette_offset;
} LMP_PACKED;
/* Blockette 100, Sample Rate (without header) */
struct blkt_100_s
{
float samprate;
int8_t flags;
uint8_t reserved[3];
} LMP_PACKED;
/* Blockette 200, Generic Event Detection (without header) */
struct blkt_200_s
{
float amplitude;
float period;
float background_estimate;
uint8_t flags;
uint8_t reserved;
BTime time;
char detector[24];
} LMP_PACKED;
/* Blockette 201, Murdock Event Detection (without header) */
struct blkt_201_s
{
float amplitude;
float period;
float background_estimate;
uint8_t flags;
uint8_t reserved;
BTime time;
uint8_t snr_values[6];
uint8_t loopback;
uint8_t pick_algorithm;
char detector[24];
} LMP_PACKED;
/* Blockette 300, Step Calibration (without header) */
struct blkt_300_s
{
BTime time;
uint8_t numcalibrations;
uint8_t flags;
uint32_t step_duration;
uint32_t interval_duration;
float amplitude;
char input_channel[3];
uint8_t reserved;
uint32_t reference_amplitude;
char coupling[12];
char rolloff[12];
} LMP_PACKED;
/* Blockette 310, Sine Calibration (without header) */
struct blkt_310_s
{
BTime time;
uint8_t reserved1;
uint8_t flags;
uint32_t duration;
float period;
float amplitude;
char input_channel[3];
uint8_t reserved2;
uint32_t reference_amplitude;
char coupling[12];
char rolloff[12];
} LMP_PACKED;
/* Blockette 320, Pseudo-random Calibration (without header) */
struct blkt_320_s
{
BTime time;
uint8_t reserved1;
uint8_t flags;
uint32_t duration;
float ptp_amplitude;
char input_channel[3];
uint8_t reserved2;
uint32_t reference_amplitude;
char coupling[12];
char rolloff[12];
char noise_type[8];
} LMP_PACKED;
/* Blockette 390, Generic Calibration (without header) */
struct blkt_390_s
{
BTime time;
uint8_t reserved1;
uint8_t flags;
uint32_t duration;
float amplitude;
char input_channel[3];
uint8_t reserved2;
} LMP_PACKED;
/* Blockette 395, Calibration Abort (without header) */
struct blkt_395_s
{
BTime time;
uint8_t reserved[2];
} LMP_PACKED;
/* Blockette 400, Beam (without header) */
struct blkt_400_s
{
float azimuth;
float slowness;
uint16_t configuration;
uint8_t reserved[2];
} LMP_PACKED;
/* Blockette 405, Beam Delay (without header) */
struct blkt_405_s
{
uint16_t delay_values[1];
};
/* Blockette 500, Timing (without header) */
struct blkt_500_s
{
float vco_correction;
BTime time;
int8_t usec;
uint8_t reception_qual;
uint32_t exception_count;
char exception_type[16];
char clock_model[32];
char clock_status[128];
} LMP_PACKED;
/* Blockette 1000, Data Only SEED (without header) */
struct blkt_1000_s
{
uint8_t encoding;
uint8_t byteorder;
uint8_t reclen;
uint8_t reserved;
} LMP_PACKED;
/* Blockette 1001, Data Extension (without header) */
struct blkt_1001_s
{
uint8_t timing_qual;
int8_t usec;
uint8_t reserved;
uint8_t framecnt;
} LMP_PACKED;
/* Blockette 2000, Opaque Data (without header) */
struct blkt_2000_s
{
uint16_t length;
uint16_t data_offset;
uint32_t recnum;
uint8_t byteorder;
uint8_t flags;
uint8_t numheaders;
char payload[1];
} LMP_PACKED;
/* Blockette chain link, generic linkable blockette index */
typedef struct blkt_link_s
{
uint16_t blktoffset; /* Offset to this blockette */
uint16_t blkt_type; /* Blockette type */
uint16_t next_blkt; /* Offset to next blockette */
void *blktdata; /* Blockette data */
uint16_t blktdatalen; /* Length of blockette data in bytes */
struct blkt_link_s *next;
}
BlktLink;
typedef struct StreamState_s
{
int64_t packedrecords; /* Count of packed records */
int64_t packedsamples; /* Count of packed samples */
int32_t lastintsample; /* Value of last integer sample packed */
flag comphistory; /* Control use of lastintsample for compression history */
}
StreamState;
typedef struct MSRecord_s {
char *record; /* Mini-SEED record */
int32_t reclen; /* Length of Mini-SEED record in bytes */
/* Pointers to SEED data record structures */
struct fsdh_s *fsdh; /* Fixed Section of Data Header */
BlktLink *blkts; /* Root of blockette chain */
struct blkt_100_s *Blkt100; /* Blockette 100, if present */
struct blkt_1000_s *Blkt1000; /* Blockette 1000, if present */
struct blkt_1001_s *Blkt1001; /* Blockette 1001, if present */
/* Common header fields in accessible form */
int32_t sequence_number; /* SEED record sequence number */
char network[11]; /* Network designation, NULL terminated */
char station[11]; /* Station designation, NULL terminated */
char location[11]; /* Location designation, NULL terminated */
char channel[11]; /* Channel designation, NULL terminated */
char dataquality; /* Data quality indicator */
hptime_t starttime; /* Record start time, corrected (first sample) */
double samprate; /* Nominal sample rate (Hz) */
int64_t samplecnt; /* Number of samples in record */
int8_t encoding; /* Data encoding format */
int8_t byteorder; /* Original/Final byte order of record */
/* Data sample fields */
void *datasamples; /* Data samples, 'numsamples' of type 'sampletype'*/
int64_t numsamples; /* Number of data samples in datasamples */
char sampletype; /* Sample type code: a, i, f, d */
/* Stream oriented state information */
StreamState *ststate; /* Stream processing state information */
}
MSRecord;
/* Container for a continuous trace, linkable */
typedef struct MSTrace_s {
char network[11]; /* Network designation, NULL terminated */
char station[11]; /* Station designation, NULL terminated */
char location[11]; /* Location designation, NULL terminated */
char channel[11]; /* Channel designation, NULL terminated */
char dataquality; /* Data quality indicator */
char type; /* MSTrace type code */
hptime_t starttime; /* Time of first sample */
hptime_t endtime; /* Time of last sample */
double samprate; /* Nominal sample rate (Hz) */
int64_t samplecnt; /* Number of samples in trace coverage */
void *datasamples; /* Data samples, 'numsamples' of type 'sampletype' */
int64_t numsamples; /* Number of data samples in datasamples */
char sampletype; /* Sample type code: a, i, f, d */
void *prvtptr; /* Private pointer for general use, unused by libmseed */
StreamState *ststate; /* Stream processing state information */
struct MSTrace_s *next; /* Pointer to next trace */
}
MSTrace;
/* Container for a group (chain) of traces */
typedef struct MSTraceGroup_s {
int32_t numtraces; /* Number of MSTraces in the trace chain */
struct MSTrace_s *traces; /* Root of the trace chain */
}
MSTraceGroup;
/* Container for a continuous trace segment, linkable */
typedef struct MSTraceSeg_s {
hptime_t starttime; /* Time of first sample */
hptime_t endtime; /* Time of last sample */
double samprate; /* Nominal sample rate (Hz) */
int64_t samplecnt; /* Number of samples in trace coverage */
void *datasamples; /* Data samples, 'numsamples' of type 'sampletype'*/
int64_t numsamples; /* Number of data samples in datasamples */
char sampletype; /* Sample type code: a, i, f, d */
void *prvtptr; /* Private pointer for general use, unused by libmseed */
struct MSTraceSeg_s *prev; /* Pointer to previous segment */
struct MSTraceSeg_s *next; /* Pointer to next segment */
}
MSTraceSeg;
/* Container for a trace ID, linkable */
typedef struct MSTraceID_s {
char network[11]; /* Network designation, NULL terminated */
char station[11]; /* Station designation, NULL terminated */
char location[11]; /* Location designation, NULL terminated */
char channel[11]; /* Channel designation, NULL terminated */
char dataquality; /* Data quality indicator */
char srcname[45]; /* Source name (Net_Sta_Loc_Chan_Qual), NULL terminated */
char type; /* Trace type code */
hptime_t earliest; /* Time of earliest sample */
hptime_t latest; /* Time of latest sample */
void *prvtptr; /* Private pointer for general use, unused by libmseed */
int32_t numsegments; /* Number of segments for this ID */
struct MSTraceSeg_s *first; /* Pointer to first of list of segments */
struct MSTraceSeg_s *last; /* Pointer to last of list of segments */
struct MSTraceID_s *next; /* Pointer to next trace */
}
MSTraceID;
/* Container for a continuous trace segment, linkable */
typedef struct MSTraceList_s {
int32_t numtraces; /* Number of traces in list */
struct MSTraceID_s *traces; /* Pointer to list of traces */
struct MSTraceID_s *last; /* Pointer to last used trace in list */
}
MSTraceList;
/* Data selection structure time window definition containers */
typedef struct SelectTime_s {
hptime_t starttime; /* Earliest data for matching channels */
hptime_t endtime; /* Latest data for matching channels */
struct SelectTime_s *next;
} SelectTime;
/* Data selection structure definition containers */
typedef struct Selections_s {
char srcname[100]; /* Matching (globbing) source name: Net_Sta_Loc_Chan_Qual */
struct SelectTime_s *timewindows;
struct Selections_s *next;
} Selections;
/* Global variables (defined in pack.c) and macros to set/force
* pack byte orders */
extern flag packheaderbyteorder;
extern flag packdatabyteorder;
#define MS_PACKHEADERBYTEORDER(X) (packheaderbyteorder = X);
#define MS_PACKDATABYTEORDER(X) (packdatabyteorder = X);
/* Global variables (defined in unpack.c) and macros to set/force
* unpack byte orders */
extern flag unpackheaderbyteorder;
extern flag unpackdatabyteorder;
#define MS_UNPACKHEADERBYTEORDER(X) (unpackheaderbyteorder = X);
#define MS_UNPACKDATABYTEORDER(X) (unpackdatabyteorder = X);
/* Global variables (defined in unpack.c) and macros to set/force
* encoding and fallback encoding */
extern int unpackencodingformat;
extern int unpackencodingfallback;
#define MS_UNPACKENCODINGFORMAT(X) (unpackencodingformat = X);
#define MS_UNPACKENCODINGFALLBACK(X) (unpackencodingfallback = X);
/* Mini-SEED record related functions */
extern int msr_parse (char *record, int recbuflen, MSRecord **ppmsr, int reclen,
flag dataflag, flag verbose);
extern int msr_parse_selection ( char *recbuf, int recbuflen, int64_t *offset,
MSRecord **ppmsr, int reclen,
Selections *selections, flag dataflag, flag verbose );
extern int msr_unpack (char *record, int reclen, MSRecord **ppmsr,
flag dataflag, flag verbose);
extern int msr_pack (MSRecord *msr, void (*record_handler) (char *, int, void *),
void *handlerdata, int64_t *packedsamples, flag flush, flag verbose );
extern int msr_pack_header (MSRecord *msr, flag normalize, flag verbose);
extern int msr_unpack_data (MSRecord *msr, int swapflag, flag verbose);
extern MSRecord* msr_init (MSRecord *msr);
extern void msr_free (MSRecord **ppmsr);
extern void msr_free_blktchain (MSRecord *msr);
extern BlktLink* msr_addblockette (MSRecord *msr, char *blktdata, int length,
int blkttype, int chainpos);
extern int msr_normalize_header (MSRecord *msr, flag verbose);
extern MSRecord* msr_duplicate (MSRecord *msr, flag datadup);
extern double msr_samprate (MSRecord *msr);
extern double msr_nomsamprate (MSRecord *msr);
extern hptime_t msr_starttime (MSRecord *msr);
extern hptime_t msr_starttime_uc (MSRecord *msr);
extern hptime_t msr_endtime (MSRecord *msr);
extern char* msr_srcname (MSRecord *msr, char *srcname, flag quality);
extern void msr_print (MSRecord *msr, flag details);
extern double msr_host_latency (MSRecord *msr);
extern int ms_detect (const char *record, int recbuflen);
extern int ms_parse_raw (char *record, int maxreclen, flag details, flag swapflag);
/* MSTrace related functions */
extern MSTrace* mst_init (MSTrace *mst);
extern void mst_free (MSTrace **ppmst);
extern MSTraceGroup* mst_initgroup (MSTraceGroup *mstg);
extern void mst_freegroup (MSTraceGroup **ppmstg);
extern MSTrace* mst_findmatch (MSTrace *startmst, char dataquality,
char *network, char *station, char *location, char *channel);
extern MSTrace* mst_findadjacent (MSTraceGroup *mstg, flag *whence, char dataquality,
char *network, char *station, char *location, char *channel,
double samprate, double sampratetol,
hptime_t starttime, hptime_t endtime, double timetol);
extern int mst_addmsr (MSTrace *mst, MSRecord *msr, flag whence);
extern int mst_addspan (MSTrace *mst, hptime_t starttime, hptime_t endtime,
void *datasamples, int64_t numsamples,
char sampletype, flag whence);
extern MSTrace* mst_addmsrtogroup (MSTraceGroup *mstg, MSRecord *msr, flag dataquality,
double timetol, double sampratetol);
extern MSTrace* mst_addtracetogroup (MSTraceGroup *mstg, MSTrace *mst);
extern int mst_groupheal (MSTraceGroup *mstg, double timetol, double sampratetol);
extern int mst_groupsort (MSTraceGroup *mstg, flag quality);
extern int mst_convertsamples (MSTrace *mst, char type, flag truncate);
extern char * mst_srcname (MSTrace *mst, char *srcname, flag quality);
extern void mst_printtracelist (MSTraceGroup *mstg, flag timeformat,
flag details, flag gaps);
extern void mst_printsynclist ( MSTraceGroup *mstg, char *dccid, flag subsecond );
extern void mst_printgaplist (MSTraceGroup *mstg, flag timeformat,
double *mingap, double *maxgap);
extern int mst_pack (MSTrace *mst, void (*record_handler) (char *, int, void *),
void *handlerdata, int reclen, flag encoding, flag byteorder,
int64_t *packedsamples, flag flush, flag verbose,
MSRecord *mstemplate);
extern int mst_packgroup (MSTraceGroup *mstg, void (*record_handler) (char *, int, void *),
void *handlerdata, int reclen, flag encoding, flag byteorder,
int64_t *packedsamples, flag flush, flag verbose,
MSRecord *mstemplate);
/* MSTraceList related functions */
extern MSTraceList * mstl_init ( MSTraceList *mstl );
extern void mstl_free ( MSTraceList **ppmstl, flag freeprvtptr );
extern MSTraceSeg * mstl_addmsr ( MSTraceList *mstl, MSRecord *msr, flag dataquality,
flag autoheal, double timetol, double sampratetol );
extern int mstl_convertsamples ( MSTraceSeg *seg, char type, flag truncate );
extern void mstl_printtracelist ( MSTraceList *mstl, flag timeformat,
flag details, flag gaps );
extern void mstl_printsynclist ( MSTraceList *mstl, char *dccid, flag subsecond );
extern void mstl_printgaplist (MSTraceList *mstl, flag timeformat,
double *mingap, double *maxgap);
/* Reading Mini-SEED records from files */
typedef struct MSFileParam_s
{
FILE *fp;
char filename[512];
char *rawrec;
int readlen;
int readoffset;
int packtype;
off_t packhdroffset;
off_t filepos;
off_t filesize;
int recordcount;
} MSFileParam;
extern int ms_readmsr (MSRecord **ppmsr, const char *msfile, int reclen, off_t *fpos, int *last,
flag skipnotdata, flag dataflag, flag verbose);
extern int ms_readmsr_r (MSFileParam **ppmsfp, MSRecord **ppmsr, const char *msfile, int reclen,
off_t *fpos, int *last, flag skipnotdata, flag dataflag, flag verbose);
extern int ms_readmsr_main (MSFileParam **ppmsfp, MSRecord **ppmsr, const char *msfile, int reclen,
off_t *fpos, int *last, flag skipnotdata, flag dataflag, Selections *selections, flag verbose);
extern int ms_readtraces (MSTraceGroup **ppmstg, const char *msfile, int reclen, double timetol, double sampratetol,
flag dataquality, flag skipnotdata, flag dataflag, flag verbose);
extern int ms_readtraces_timewin (MSTraceGroup **ppmstg, const char *msfile, int reclen, double timetol, double sampratetol,
hptime_t starttime, hptime_t endtime, flag dataquality, flag skipnotdata, flag dataflag, flag verbose);
extern int ms_readtraces_selection (MSTraceGroup **ppmstg, const char *msfile, int reclen, double timetol, double sampratetol,
Selections *selections, flag dataquality, flag skipnotdata, flag dataflag, flag verbose);
extern int ms_readtracelist (MSTraceList **ppmstl, const char *msfile, int reclen, double timetol, double sampratetol,
flag dataquality, flag skipnotdata, flag dataflag, flag verbose);
extern int ms_readtracelist_timewin (MSTraceList **ppmstl, const char *msfile, int reclen, double timetol, double sampratetol,
hptime_t starttime, hptime_t endtime, flag dataquality, flag skipnotdata, flag dataflag, flag verbose);
extern int ms_readtracelist_selection (MSTraceList **ppmstl, const char *msfile, int reclen, double timetol, double sampratetol,
Selections *selections, flag dataquality, flag skipnotdata, flag dataflag, flag verbose);
extern int msr_writemseed ( MSRecord *msr, const char *msfile, flag overwrite, int reclen,
flag encoding, flag byteorder, flag verbose );
extern int mst_writemseed ( MSTrace *mst, const char *msfile, flag overwrite, int reclen,
flag encoding, flag byteorder, flag verbose );
extern int mst_writemseedgroup ( MSTraceGroup *mstg, const char *msfile, flag overwrite,
int reclen, flag encoding, flag byteorder, flag verbose );
/* General use functions */
extern char* ms_recsrcname (char *record, char *srcname, flag quality);
extern int ms_splitsrcname (char *srcname, char *net, char *sta, char *loc, char *chan, char *qual);
extern int ms_strncpclean (char *dest, const char *source, int length);
extern int ms_strncpcleantail (char *dest, const char *source, int length);
extern int ms_strncpopen (char *dest, const char *source, int length);
extern int ms_doy2md (int year, int jday, int *month, int *mday);
extern int ms_md2doy (int year, int month, int mday, int *jday);
extern hptime_t ms_btime2hptime (BTime *btime);
extern char* ms_btime2isotimestr (BTime *btime, char *isotimestr);
extern char* ms_btime2mdtimestr (BTime *btime, char *mdtimestr);
extern char* ms_btime2seedtimestr (BTime *btime, char *seedtimestr);
extern int ms_hptime2btime (hptime_t hptime, BTime *btime);
extern char* ms_hptime2isotimestr (hptime_t hptime, char *isotimestr, flag subsecond);
extern char* ms_hptime2mdtimestr (hptime_t hptime, char *mdtimestr, flag subsecond);
extern char* ms_hptime2seedtimestr (hptime_t hptime, char *seedtimestr, flag subsecond);
extern hptime_t ms_time2hptime (int year, int day, int hour, int min, int sec, int usec);
extern hptime_t ms_seedtimestr2hptime (char *seedtimestr);
extern hptime_t ms_timestr2hptime (char *timestr);
extern double ms_nomsamprate (int factor, int multiplier);
extern int ms_genfactmult (double samprate, int16_t *factor, int16_t *multiplier);
extern int ms_ratapprox (double real, int *num, int *den, int maxval, double precision);
extern int ms_bigendianhost (void);
extern double ms_dabs (double val);
/* Lookup functions */
extern uint8_t ms_samplesize (const char sampletype);
extern char* ms_encodingstr (const char encoding);
extern char* ms_blktdesc (uint16_t blkttype);
extern uint16_t ms_blktlen (uint16_t blkttype, const char *blktdata, flag swapflag);
extern char * ms_errorstr (int errorcode);
/* Logging facility */
#define MAX_LOG_MSG_LENGTH 200 /* Maximum length of log messages */
/* Logging parameters */
typedef struct MSLogParam_s
{
void (*log_print)(char*);
const char *logprefix;
void (*diag_print)(char*);
const char *errprefix;
} MSLogParam;
extern int ms_log (int level, ...);
extern int ms_log_l (MSLogParam *logp, int level, ...);
extern void ms_loginit (void (*log_print)(char*), const char *logprefix,
void (*diag_print)(char*), const char *errprefix);
extern MSLogParam *ms_loginit_l (MSLogParam *logp,
void (*log_print)(char*), const char *logprefix,
void (*diag_print)(char*), const char *errprefix);
/* Selection functions */
extern Selections *ms_matchselect (Selections *selections, char *srcname,
hptime_t starttime, hptime_t endtime, SelectTime **ppselecttime);
extern Selections *msr_matchselect (Selections *selections, MSRecord *msr, SelectTime **ppselecttime);
extern int ms_addselect (Selections **ppselections, char *srcname,
hptime_t starttime, hptime_t endtime);
extern int ms_addselect_comp (Selections **ppselections, char *net, char* sta, char *loc,
char *chan, char *qual, hptime_t starttime, hptime_t endtime);
extern int ms_readselectionsfile (Selections **ppselections, char *filename);
extern void ms_freeselections (Selections *selections);
extern void ms_printselections (Selections *selections);
/* Generic byte swapping routines */
extern void ms_gswap2 ( void *data2 );
extern void ms_gswap3 ( void *data3 );
extern void ms_gswap4 ( void *data4 );
extern void ms_gswap8 ( void *data8 );
/* Generic byte swapping routines for memory aligned quantities */
extern void ms_gswap2a ( void *data2 );
extern void ms_gswap4a ( void *data4 );
extern void ms_gswap8a ( void *data8 );
/* Byte swap macro for the BTime struct */
#define MS_SWAPBTIME(x) \
ms_gswap2 (x.year); \
ms_gswap2 (x.day); \
ms_gswap2 (x.fract);
#ifdef __cplusplus
}
#endif
#endif /* LIBMSEED_H */

65
libs/3rd-party/mseed/lmplatform.c vendored Normal file
View File

@ -0,0 +1,65 @@
/***************************************************************************
* lmplatform.c:
*
* Platform portability routines.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License
* as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This library 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
* Library General Public License (GNU-LGPL) for more details. The
* GNU-LGPL and further information can be found here:
* http://www.gnu.org/
*
* Written by Chad Trabant, IRIS Data Management Center
*
* modified: 2010.304
***************************************************************************/
/* Define _LARGEFILE_SOURCE to get ftello/fseeko on some systems (Linux) */
#define _LARGEFILE_SOURCE 1
#include "lmplatform.h"
/***************************************************************************
* lmp_ftello:
*
* Return the current file position for the specified descriptor using
* the system's closest match to the POSIX ftello.
***************************************************************************/
off_t
lmp_ftello (FILE *stream)
{
#if defined(LMP_WIN32)
return (off_t) ftell (stream);
#else
return (off_t) ftello (stream);
#endif
} /* End of lmp_ftello() */
/***************************************************************************
* lmp_fseeko:
*
* Seek to a specific file position for the specified descriptor using
* the system's closest match to the POSIX fseeko.
***************************************************************************/
int
lmp_fseeko (FILE *stream, off_t offset, int whence)
{
#if defined(LMP_WIN32)
return (int) fseek (stream, (long int) offset, whence);
#else
return (int) fseeko (stream, offset, whence);
#endif
} /* End of lmp_fseeko() */

166
libs/3rd-party/mseed/lmplatform.h vendored Normal file
View File

@ -0,0 +1,166 @@
/***************************************************************************
* lmplatform.h:
*
* Platform specific headers. This file provides a basic level of platform
* portability.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License
* as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This library 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
* Library General Public License (GNU-LGPL) for more details. The
* GNU-LGPL and further information can be found here:
* http://www.gnu.org/
*
* Written by Chad Trabant, IRIS Data Management Center
*
* modified: 2014.074
***************************************************************************/
#ifndef LMPLATFORM_H
#define LMPLATFORM_H 1
#ifdef __cplusplus
extern "C" {
#endif
/* On some platforms (e.g. ARM) structures are aligned on word boundaries
by adding padding between the elements. This library uses structs that
map to SEED header/blockette structures that are required to have a
layout exactly as specified, i.e. no padding.
If "ATTRIBUTE_PACKED" is defined at compile time (e.g. -DATTRIBUTE_PACKED)
the preprocessor will use the define below to add the "packed" attribute
to effected structs. This attribute is supported by GCC and increasingly
more compilers.
*/
#if defined(ATTRIBUTE_PACKED)
#define LMP_PACKED __attribute__((packed))
#else
#define LMP_PACKED
#endif
/* Make some guesses about the system libraries based
* on the architecture. Currently the assumptions are:
* Linux => glibc2 libraries (LMP_GLIBC2)
* Sun => Solaris libraties (LMP_SOLARIS)
* BSD => BSD libraries, including Apple Mac OS X (LMP_BSD)
* WIN32 => WIN32 and Windows Sockets 2 (LMP_WIN32)
*/
#if defined(__linux__) || defined(__linux) || defined(__CYGWIN__)
#define LMP_GLIBC2 1
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <stdarg.h>
#include <inttypes.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/time.h>
#include <string.h>
#include <ctype.h>
#include <features.h>
#elif defined(__sun__) || defined(__sun)
#define LMP_SOLARIS 1
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <stdarg.h>
#include <inttypes.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/time.h>
#include <string.h>
#include <ctype.h>
#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
#define LMP_BSD 1
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <stdarg.h>
#include <inttypes.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/time.h>
#include <string.h>
#include <ctype.h>
#elif defined(WIN32) || defined(WIN64)
#define LMP_WIN32 1
#include <windows.h>
#include <stdarg.h>
#include <winsock.h>
#include <stdio.h>
#include <sys/types.h>
#include <ctype.h>
#if defined(_MSC_VER)
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
#define strtoull _strtoui64
#define strdup _strdup
#define fileno _fileno
#endif
#if defined(__MINGW32__)
#define fstat _fstat
#define stat _stat
#endif
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int int16_t;
typedef unsigned short int uint16_t;
typedef signed int int32_t;
typedef unsigned int uint32_t;
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <stdarg.h>
#include <inttypes.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/time.h>
#include <string.h>
#include <ctype.h>
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int int16_t;
typedef unsigned short int uint16_t;
typedef signed int int32_t;
typedef unsigned int uint32_t;
typedef signed long long int64_t;
typedef unsigned long long uint64_t;
#endif
extern off_t lmp_ftello (FILE *stream);
extern int lmp_fseeko (FILE *stream, off_t offset, int whence);
#ifdef __cplusplus
}
#endif
#endif /* LMPLATFORM_H */

334
libs/3rd-party/mseed/logging.c vendored Normal file
View File

@ -0,0 +1,334 @@
/***************************************************************************
* logging.c
*
* Log handling routines for libmseed
*
* Chad Trabant
* IRIS Data Management Center
*
* modified: 2014.197
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "libmseed.h"
void ms_loginit_main (MSLogParam *logp,
void (*log_print)(char*), const char *logprefix,
void (*diag_print)(char*), const char *errprefix);
int ms_log_main (MSLogParam *logp, int level, va_list *varlist);
/* Initialize the global logging parameters */
MSLogParam gMSLogParam = {NULL, NULL, NULL, NULL};
/***************************************************************************
* ms_loginit:
*
* Initialize the global logging parameters.
*
* See ms_loginit_main() description for usage.
***************************************************************************/
void
ms_loginit (void (*log_print)(char*), const char *logprefix,
void (*diag_print)(char*), const char *errprefix)
{
ms_loginit_main(&gMSLogParam, log_print, logprefix, diag_print, errprefix);
} /* End of ms_loginit() */
/***************************************************************************
* ms_loginit_l:
*
* Initialize MSLogParam specific logging parameters. If the logging parameters
* have not been initialized (log == NULL) new parameter space will
* be allocated.
*
* See ms_loginit_main() description for usage.
*
* Returns a pointer to the created/re-initialized MSLogParam struct
* on success and NULL on error.
***************************************************************************/
MSLogParam *
ms_loginit_l (MSLogParam *logp,
void (*log_print)(char*), const char *logprefix,
void (*diag_print)(char*), const char *errprefix)
{
MSLogParam *llog;
if ( logp == NULL )
{
llog = (MSLogParam *) malloc (sizeof(MSLogParam));
if ( llog == NULL )
{
ms_log (2, "ms_loginit_l(): Cannot allocate memory\n");
return NULL;
}
llog->log_print = NULL;
llog->logprefix = NULL;
llog->diag_print = NULL;
llog->errprefix = NULL;
}
else
{
llog = logp;
}
ms_loginit_main (llog, log_print, logprefix, diag_print, errprefix);
return llog;
} /* End of ms_loginit_l() */
/***************************************************************************
* ms_loginit_main:
*
* Initialize the logging subsystem. Given values determine how ms_log()
* and ms_log_l() emit messages.
*
* This function modifies the logging parameters in the passed MSLogParam.
*
* Any log/error printing functions indicated must except a single
* argument, namely a string (char *). The ms_log() and
* ms_log_r() functions format each message and then pass the result
* on to the log/error printing functions.
*
* If the log/error prefixes have been set they will be pre-pended to the
* message.
*
* Use NULL for the function pointers or the prefixes if they should not
* be changed from previously set or default values. The default behavior
* of the logging subsystem is given in the example below.
*
* Example: ms_loginit_main (0, (void*)&printf, NULL, (void*)&printf, "error: ");
***************************************************************************/
void
ms_loginit_main (MSLogParam *logp,
void (*log_print)(char*), const char *logprefix,
void (*diag_print)(char*), const char *errprefix)
{
if ( ! logp )
return;
if ( log_print )
logp->log_print = log_print;
if ( logprefix )
{
if ( strlen(logprefix) >= MAX_LOG_MSG_LENGTH )
{
ms_log_l (logp, 2, 0, "log message prefix is too large\n");
}
else
{
logp->logprefix = logprefix;
}
}
if ( diag_print )
logp->diag_print = diag_print;
if ( errprefix )
{
if ( strlen(errprefix) >= MAX_LOG_MSG_LENGTH )
{
ms_log_l (logp, 2, 0, "error message prefix is too large\n");
}
else
{
logp->errprefix = errprefix;
}
}
return;
} /* End of ms_loginit_main() */
/***************************************************************************
* ms_log:
*
* A wrapper to ms_log_main() that uses the global logging parameters.
*
* See ms_log_main() description for return values.
***************************************************************************/
int
ms_log (int level, ...)
{
int retval;
va_list varlist;
va_start (varlist, level);
retval = ms_log_main (&gMSLogParam, level, &varlist);
va_end (varlist);
return retval;
} /* End of ms_log() */
/***************************************************************************
* ms_log_l:
*
* A wrapper to ms_log_main() that uses the logging parameters in a
* supplied MSLogParam. If the supplied pointer is NULL the global logging
* parameters will be used.
*
* See ms_log_main() description for return values.
***************************************************************************/
int
ms_log_l (MSLogParam *logp, int level, ...)
{
int retval;
va_list varlist;
MSLogParam *llog;
if ( ! logp )
llog = &gMSLogParam;
else
llog = logp;
va_start (varlist, level);
retval = ms_log_main (llog, level, &varlist);
va_end (varlist);
return retval;
} /* End of ms_log_l() */
/***************************************************************************
* ms_log_main:
*
* A standard logging/printing routine.
*
* The function uses logging parameters specified in the supplied
* MSLogParam.
*
* This function expects 2+ arguments: message level, fprintf format,
* and fprintf arguments.
*
* Three levels are recognized:
* 0 : Normal log messages, printed using log_print with logprefix
* 1 : Diagnostic messages, printed using diag_print with logprefix
* 2+ : Error messagess, printed using diag_print with errprefix
*
* This function builds the log/error message and passes to it as a
* string (char *) to the functions defined with ms_loginit() or
* ms_loginit_l(). If the log/error printing functions have not been
* defined messages will be printed with fprintf, log messages to
* stdout and error messages to stderr.
*
* If the log/error prefix's have been set with ms_loginit() or
* ms_loginit_l() they will be pre-pended to the message.
*
* All messages will be truncated to the MAX_LOG_MSG_LENGTH, this includes
* any set prefix.
*
* Returns the number of characters formatted on success, and a
* a negative value on error.
***************************************************************************/
int
ms_log_main (MSLogParam *logp, int level, va_list *varlist)
{
static char message[MAX_LOG_MSG_LENGTH];
int retvalue = 0;
int presize;
const char *format;
if ( ! logp )
{
fprintf(stderr, "ms_log_main() called without specifying log parameters");
return -1;
}
message[0] = '\0';
format = va_arg (*varlist, const char *);
if ( level >= 2 ) /* Error message */
{
if ( logp->errprefix != NULL )
{
strncpy (message, logp->errprefix, MAX_LOG_MSG_LENGTH);
message[MAX_LOG_MSG_LENGTH - 1] = '\0';
}
else
{
strncpy (message, "Error: ", MAX_LOG_MSG_LENGTH);
}
presize = strlen(message);
retvalue = vsnprintf (&message[presize],
MAX_LOG_MSG_LENGTH - presize,
format, *varlist);
message[MAX_LOG_MSG_LENGTH - 1] = '\0';
if ( logp->diag_print != NULL )
{
logp->diag_print (message);
}
else
{
fprintf(stderr, "%s", message);
}
}
else if ( level == 1 ) /* Diagnostic message */
{
if ( logp->logprefix != NULL )
{
strncpy (message, logp->logprefix, MAX_LOG_MSG_LENGTH);
message[MAX_LOG_MSG_LENGTH - 1] = '\0';
}
presize = strlen(message);
retvalue = vsnprintf (&message[presize],
MAX_LOG_MSG_LENGTH - presize,
format, *varlist);
message[MAX_LOG_MSG_LENGTH - 1] = '\0';
if ( logp->diag_print != NULL )
{
logp->diag_print (message);
}
else
{
fprintf(stderr, "%s", message);
}
}
else if ( level == 0 ) /* Normal log message */
{
if ( logp->logprefix != NULL )
{
strncpy (message, logp->logprefix, MAX_LOG_MSG_LENGTH);
message[MAX_LOG_MSG_LENGTH - 1] = '\0';
}
presize = strlen(message);
retvalue = vsnprintf (&message[presize],
MAX_LOG_MSG_LENGTH - presize,
format, *varlist);
message[MAX_LOG_MSG_LENGTH - 1] = '\0';
if ( logp->log_print != NULL )
{
logp->log_print (message);
}
else
{
fprintf(stdout, "%s", message);
}
}
return retvalue;
} /* End of ms_log_main() */

235
libs/3rd-party/mseed/lookup.c vendored Normal file
View File

@ -0,0 +1,235 @@
/***************************************************************************
* lookup.c:
*
* Generic lookup routines for Mini-SEED information.
*
* Written by Chad Trabant, ORFEUS/EC-Project MEREDIAN
*
* modified: 2006.346
***************************************************************************/
#include <string.h>
#include "libmseed.h"
/***************************************************************************
* ms_samplesize():
*
* Returns the sample size based on type code or 0 for unknown.
***************************************************************************/
uint8_t
ms_samplesize (const char sampletype)
{
switch (sampletype)
{
case 'a':
return 1;
case 'i':
case 'f':
return 4;
case 'd':
return 8;
default:
return 0;
} /* end switch */
} /* End of ms_samplesize() */
/***************************************************************************
* ms_encodingstr():
*
* Returns a string describing a data encoding format.
***************************************************************************/
char *
ms_encodingstr (const char encoding)
{
switch (encoding)
{
case 0:
return "ASCII text";
case 1:
return "16 bit integers";
case 2:
return "24 bit integers";
case 3:
return "32 bit integers";
case 4:
return "IEEE floating point";
case 5:
return "IEEE double precision float";
case 10:
return "STEIM 1 Compression";
case 11:
return "STEIM 2 Compression";
case 12:
return "GEOSCOPE Muxed 24 bit int";
case 13:
return "GEOSCOPE Muxed 16/3 bit gain/exp";
case 14:
return "GEOSCOPE Muxed 16/4 bit gain/exp";
case 15:
return "US National Network compression";
case 16:
return "CDSN 16 bit gain ranged";
case 17:
return "Graefenberg 16 bit gain ranged";
case 18:
return "IPG - Strasbourg 16 bit gain";
case 19:
return "STEIM 3 Compression";
case 30:
return "SRO Gain Ranged Format";
case 31:
return "HGLP Format";
case 32:
return "DWWSSN Format";
case 33:
return "RSTN 16 bit gain ranged";
default:
return "Unknown format code";
} /* end switch */
} /* End of ms_encodingstr() */
/***************************************************************************
* ms_blktdesc():
*
* Return a string describing a given blockette type or NULL if the
* type is unknown.
***************************************************************************/
char *
ms_blktdesc (uint16_t blkttype)
{
switch (blkttype)
{
case 100:
return "Sample Rate";
case 200:
return "Generic Event Detection";
case 201:
return "Murdock Event Detection";
case 300:
return "Step Calibration";
case 310:
return "Sine Calibration";
case 320:
return "Pseudo-random Calibration";
case 390:
return "Generic Calibration";
case 395:
return "Calibration Abort";
case 400:
return "Beam";
case 500:
return "Timing";
case 1000:
return "Data Only SEED";
case 1001:
return "Data Extension";
case 2000:
return "Opaque Data";
} /* end switch */
return NULL;
} /* End of ms_blktdesc() */
/***************************************************************************
* ms_blktlen():
*
* Returns the total length of a given blockette type in bytes or 0 if
* type unknown.
***************************************************************************/
uint16_t
ms_blktlen (uint16_t blkttype, const char *blkt, flag swapflag)
{
uint16_t blktlen = 0;
switch (blkttype)
{
case 100: /* Sample Rate */
blktlen = 12;
break;
case 200: /* Generic Event Detection */
blktlen = 28;
break;
case 201: /* Murdock Event Detection */
blktlen = 36;
break;
case 300: /* Step Calibration */
blktlen = 32;
break;
case 310: /* Sine Calibration */
blktlen = 32;
break;
case 320: /* Pseudo-random Calibration */
blktlen = 28;
break;
case 390: /* Generic Calibration */
blktlen = 28;
break;
case 395: /* Calibration Abort */
blktlen = 16;
break;
case 400: /* Beam */
blktlen = 16;
break;
case 500: /* Timing */
blktlen = 8;
break;
case 1000: /* Data Only SEED */
blktlen = 8;
break;
case 1001: /* Data Extension */
blktlen = 8;
break;
case 2000: /* Opaque Data */
/* First 2-byte field after the blockette header is the length */
if ( blkt )
{
memcpy ((void *) &blktlen, blkt+4, sizeof (int16_t));
if ( swapflag ) ms_gswap2 (&blktlen);
}
break;
} /* end switch */
return blktlen;
} /* End of ms_blktlen() */
/***************************************************************************
* ms_errorstr():
*
* Return a string describing a given libmseed error code or NULL if the
* code is unknown.
***************************************************************************/
char *
ms_errorstr (int errorcode)
{
switch (errorcode)
{
case MS_ENDOFFILE:
return "End of file reached";
case MS_NOERROR:
return "No error";
case MS_GENERROR:
return "Generic error";
case MS_NOTSEED:
return "No SEED data detected";
case MS_WRONGLENGTH:
return "Length of data read does not match record length";
case MS_OUTOFRANGE:
return "SEED record length out of range";
case MS_UNKNOWNFORMAT:
return "Unknown data encoding format";
case MS_STBADCOMPFLAG:
return "Bad Steim compression flag(s) detected";
} /* end switch */
return NULL;
} /* End of ms_blktdesc() */

1179
libs/3rd-party/mseed/msrutils.c vendored Normal file

File diff suppressed because it is too large Load Diff

1065
libs/3rd-party/mseed/pack.c vendored Normal file

File diff suppressed because it is too large Load Diff

699
libs/3rd-party/mseed/packdata.c vendored Normal file
View File

@ -0,0 +1,699 @@
/***********************************************************************
* Routines for packing INT_32, INT_16, FLOAT_32, FLOAT_64,
* STEIM1 and STEIM2 data records.
*
* Douglas Neuhauser
* Seismological Laboratory
* University of California, Berkeley
* doug@seismo.berkeley.edu
*
*
* modified Aug 2008:
* - Optimize Steim 1 & 2 packing routines using small, re-used buffers.
*
* modified Sep 2004:
* - Reworked and cleaned routines for use within libmseed.
* - Added float32 and float64 packing routines.
*
* Modified by Chad Trabant, IRIS Data Management Center
*
* modified: 2009.111
************************************************************************/
/*
* Copyright (c) 1996-2004 The Regents of the University of California.
* All Rights Reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for educational, research and non-profit purposes,
* without fee, and without a written agreement is hereby granted,
* provided that the above copyright notice, this paragraph and the
* following three paragraphs appear in all copies.
*
* Permission to incorporate this software into commercial products may
* be obtained from the Office of Technology Licensing, 2150 Shattuck
* Avenue, Suite 510, Berkeley, CA 94704.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
* FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
* INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND
* ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
* PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
* CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
* UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include "libmseed.h"
#include "packdata.h"
static int pad_steim_frame (DFRAMES*, int, int, int, int, int);
#define EMPTY_BLOCK(fn,wn) (fn+wn == 0)
#define X0 dframes->f[0].w[0].fw
#define XN dframes->f[0].w[1].fw
#define BIT4PACK(i,points_remaining) \
(points_remaining >= 7 && \
(minbits[i] <= 4) && (minbits[i+1] <= 4) && \
(minbits[i+2] <= 4) && (minbits[i+3] <= 4) && \
(minbits[i+4] <= 4) && (minbits[i+5] <= 4) && \
(minbits[i+6] <= 4))
#define BIT5PACK(i,points_remaining) \
(points_remaining >= 6 && \
(minbits[i] <= 5) && (minbits[i+1] <= 5) && \
(minbits[i+2] <= 5) && (minbits[i+3] <= 5) && \
(minbits[i+4] <= 5) && (minbits[i+5] <= 5))
#define BIT6PACK(i,points_remaining) \
(points_remaining >= 5 && \
(minbits[i] <= 6) && (minbits[i+1] <= 6) && \
(minbits[i+2] <= 6) && (minbits[i+3] <= 6) && \
(minbits[i+4] <= 6))
#define BYTEPACK(i,points_remaining) \
(points_remaining >= 4 && \
(minbits[i] <= 8) && (minbits[i+1] <= 8) && \
(minbits[i+2] <= 8) && (minbits[i+3] <= 8))
#define BIT10PACK(i,points_remaining) \
(points_remaining >= 3 && \
(minbits[i] <= 10) && (minbits[i+1] <= 10) && \
(minbits[i+2] <= 10))
#define BIT15PACK(i,points_remaining) \
(points_remaining >= 2 && \
(minbits[i] <= 15) && (minbits[i+1] <= 15))
#define HALFPACK(i,points_remaining) \
(points_remaining >= 2 && (minbits[i] <= 16) && (minbits[i+1] <= 16))
#define BIT30PACK(i,points_remaining) \
(points_remaining >= 1 && \
(minbits[i] <= 30))
#define MINBITS(diff,minbits) \
if (diff >= -8 && diff < 8) minbits = 4; \
else if (diff >= -16 && diff < 16) minbits = 5; \
else if (diff >= -32 && diff < 32) minbits = 6; \
else if (diff >= -128 && diff < 128) minbits = 8; \
else if (diff >= -512 && diff < 512) minbits = 10; \
else if (diff >= -16384 && diff < 16384) minbits = 15; \
else if (diff >= -32768 && diff < 32768) minbits = 16; \
else if (diff >= -536870912 && diff < 536870912) minbits = 30; \
else minbits = 32;
#define PACK(bits,n,m1,m2) { \
int i = 0; \
unsigned int val = 0; \
for (i=0;i<n;i++) { \
val = (val<<bits) | (diff[i]&m1); \
} \
val |= ((unsigned int)m2 << 30); \
dframes->f[fn].w[wn].fw = val; }
/************************************************************************
* msr_pack_int_16: *
* Pack integer data into INT_16 format. *
* Return: 0 on success, -1 on failure. *
************************************************************************/
int msr_pack_int_16
(int16_t *packed, /* output data array - packed */
int32_t *data, /* input data array */
int ns, /* desired number of samples to pack */
int max_bytes, /* max # of bytes for output buffer */
int pad, /* flag to specify padding to max_bytes */
int *pnbytes, /* number of bytes actually packed */
int *pnsamples, /* number of samples actually packed */
int swapflag) /* if data should be swapped */
{
int points_remaining = ns; /* number of samples remaining to pack */
int i = 0;
while (points_remaining > 0 && max_bytes >= 2)
{ /* Pack the next available data into INT_16 format */
if ( data[i] < -32768 || data[i] > 32767 )
ms_log (2, "msr_pack_int_16(%s): input sample out of range: %d\n",
PACK_SRCNAME, data[i]);
*packed = data[i];
if ( swapflag ) ms_gswap2 (packed);
packed++;
max_bytes -= 2;
points_remaining--;
i++;
}
*pnbytes = (ns - points_remaining) * 2;
/* Pad miniSEED block if necessary */
if (pad)
{
memset ((void *)packed, 0, max_bytes);
*pnbytes += max_bytes;
}
*pnsamples = ns - points_remaining;
return 0;
}
/************************************************************************
* msr_pack_int_32: *
* Pack integer data into INT_32 format. *
* Return: 0 on success, -1 on failure. *
************************************************************************/
int msr_pack_int_32
(int32_t *packed, /* output data array - packed */
int32_t *data, /* input data array - unpacked */
int ns, /* desired number of samples to pack */
int max_bytes, /* max # of bytes for output buffer */
int pad, /* flag to specify padding to max_bytes */
int *pnbytes, /* number of bytes actually packed */
int *pnsamples, /* number of samples actually packed */
int swapflag) /* if data should be swapped */
{
int points_remaining = ns; /* number of samples remaining to pack */
int i = 0;
while (points_remaining > 0 && max_bytes >= 4)
{ /* Pack the next available data into INT_32 format */
*packed = data[i];
if ( swapflag ) ms_gswap4 (packed);
packed++;
max_bytes -= 4;
points_remaining--;
i++;
}
*pnbytes = (ns - points_remaining) * 4;
/* Pad miniSEED block if necessary */
if (pad)
{
memset ((void *)packed, 0, max_bytes);
*pnbytes += max_bytes;
}
*pnsamples = ns - points_remaining;
return 0;
}
/************************************************************************
* msr_pack_float_32: *
* Pack float data into FLOAT32 format. *
* Return: 0 on success, -1 on error. *
************************************************************************/
int msr_pack_float_32
(float *packed, /* output data array - packed */
float *data, /* input data array - unpacked */
int ns, /* desired number of samples to pack */
int max_bytes, /* max # of bytes for output buffer */
int pad, /* flag to specify padding to max_bytes */
int *pnbytes, /* number of bytes actually packed */
int *pnsamples, /* number of samples actually packed */
int swapflag) /* if data should be swapped */
{
int points_remaining = ns; /* number of samples remaining to pack */
int i = 0;
while (points_remaining > 0 && max_bytes >= 4)
{
*packed = data[i];
if ( swapflag ) ms_gswap4 (packed);
packed++;
max_bytes -= 4;
points_remaining--;
i++;
}
*pnbytes = (ns - points_remaining) * 4;
/* Pad miniSEED block if necessary */
if (pad)
{
memset ((void *)packed, 0, max_bytes);
*pnbytes += max_bytes;
}
*pnsamples = ns - points_remaining;
return 0;
}
/************************************************************************
* msr_pack_float_64: *
* Pack double data into FLOAT64 format. *
* Return: 0 on success, -1 on error. *
************************************************************************/
int msr_pack_float_64
(double *packed, /* output data array - packed */
double *data, /* input data array - unpacked */
int ns, /* desired number of samples to pack */
int max_bytes, /* max # of bytes for output buffer */
int pad, /* flag to specify padding to max_bytes */
int *pnbytes, /* number of bytes actually packed */
int *pnsamples, /* number of samples actually packed */
int swapflag) /* if data should be swapped */
{
int points_remaining = ns; /* number of samples remaining to pack */
int i = 0;
while (points_remaining > 0 && max_bytes >= 8)
{
*packed = data[i];
if ( swapflag ) ms_gswap8 (packed);
packed++;
max_bytes -= 8;
points_remaining--;
i++;
}
*pnbytes = (ns - points_remaining) * 8;
/* Pad miniSEED block if necessary */
if (pad)
{
memset ((void *)packed, 0, max_bytes);
*pnbytes += max_bytes;
}
*pnsamples = ns - points_remaining;
return 0;
}
/************************************************************************
* msr_pack_steim1: *
* Pack data into STEIM1 data frames. *
* return: *
* 0 on success. *
* -1 on error. *
************************************************************************/
int msr_pack_steim1
(DFRAMES *dframes, /* ptr to data frames */
int32_t *data, /* ptr to unpacked data array */
int32_t d0, /* first difference value */
int ns, /* number of samples to pack */
int nf, /* total number of data frames */
int pad, /* flag to specify padding to nf */
int *pnframes, /* number of frames actually packed */
int *pnsamples, /* number of samples actually packed */
int swapflag) /* if data should be swapped */
{
int points_remaining = ns;
int points_packed = 0;
int32_t diff[4]; /* array of differences */
uint8_t minbits[4]; /* array of minimum bits for diffs */
int i, j;
int mask;
int ipt = 0; /* index of initial data to pack. */
int fn = 0; /* index of initial frame to pack. */
int wn = 2; /* index of initial word to pack. */
int32_t itmp;
int16_t stmp;
/* Calculate initial difference and minbits buffers */
diff[0] = d0;
MINBITS(diff[0],minbits[0]);
for (i=1; i < 4 && i < ns; i++)
{
diff[i] = data[i] - data[i-1];
MINBITS(diff[i],minbits[i]);
}
dframes->f[fn].ctrl = 0;
/* Set X0 and XN values in first frame */
X0 = data[0];
if ( swapflag ) ms_gswap4 (&X0);
dframes->f[0].ctrl = (dframes->f[0].ctrl<<2) | STEIM1_SPECIAL_MASK;
XN = data[ns-1];
if ( swapflag ) ms_gswap4 (&XN);
dframes->f[0].ctrl = (dframes->f[0].ctrl<<2) | STEIM1_SPECIAL_MASK;
while (points_remaining > 0)
{
points_packed = 0;
/* Pack the next available data into the most compact form */
if (BYTEPACK(0,points_remaining))
{
mask = STEIM1_BYTE_MASK;
for (j=0; j<4; j++) { dframes->f[fn].w[wn].byte[j] = diff[j]; }
points_packed = 4;
}
else if (HALFPACK(0,points_remaining))
{
mask = STEIM1_HALFWORD_MASK;
for (j=0; j<2; j++)
{
stmp = diff[j];
if ( swapflag ) ms_gswap2 (&stmp);
dframes->f[fn].w[wn].hw[j] = stmp;
}
points_packed = 2;
}
else
{
mask = STEIM1_FULLWORD_MASK;
itmp = diff[0];
if ( swapflag ) ms_gswap4 (&itmp);
dframes->f[fn].w[wn].fw = itmp;
points_packed = 1;
}
/* Append mask for this word to current mask */
dframes->f[fn].ctrl = (dframes->f[fn].ctrl<<2) | mask;
points_remaining -= points_packed;
ipt += points_packed;
/* Check for full frame or full block */
if (++wn >= VALS_PER_FRAME)
{
if ( swapflag ) ms_gswap4 (&dframes->f[fn].ctrl);
/* Reset output index to beginning of frame */
wn = 0;
/* If block is full, output block and reinitialize */
if (++fn >= nf) break;
dframes->f[fn].ctrl = 0;
}
/* Shift and re-fill difference and minbits buffers */
for ( i=points_packed; i < 4; i++ )
{
/* Shift remaining buffer entries */
diff[i-points_packed] = diff[i];
minbits[i-points_packed] = minbits[i];
}
for ( i=4-points_packed,j=ipt+(4-points_packed); i < 4 && j < ns; i++,j++ )
{
/* Re-fill entries */
diff[i] = data[j] - data[j-1];
MINBITS(diff[i],minbits[i]);
}
}
/* Update XN value in first frame */
XN = data[(ns-1)-points_remaining];
if ( swapflag ) ms_gswap4 (&XN);
/* End of data. Pad current frame and optionally rest of block */
/* Do not pad and output a completely empty block */
if ( ! EMPTY_BLOCK(fn,wn) )
{
*pnframes = pad_steim_frame (dframes, fn, wn, nf, swapflag, pad);
}
else
{
*pnframes = 0;
}
*pnsamples = ns - points_remaining;
return 0;
}
/************************************************************************
* msr_pack_steim2: *
* Pack data into STEIM1 data frames. *
* return: *
* 0 on success. *
* -1 on error. *
************************************************************************/
int msr_pack_steim2
(DFRAMES *dframes, /* ptr to data frames */
int32_t *data, /* ptr to unpacked data array */
int32_t d0, /* first difference value */
int ns, /* number of samples to pack */
int nf, /* total number of data frames to pack */
int pad, /* flag to specify padding to nf */
int *pnframes, /* number of frames actually packed */
int *pnsamples, /* number of samples actually packed */
int swapflag) /* if data should be swapped */
{
int points_remaining = ns;
int points_packed = 0;
int32_t diff[7]; /* array of differences */
uint8_t minbits[7]; /* array of minimum bits for diffs */
int i, j;
int mask;
int ipt = 0; /* index of initial data to pack. */
int fn = 0; /* index of initial frame to pack. */
int wn = 2; /* index of initial word to pack. */
/* Calculate initial difference and minbits buffers */
diff[0] = d0;
MINBITS(diff[0],minbits[0]);
for (i=1; i < 7 && i < ns; i++)
{
diff[i] = data[i] - data[i-1];
MINBITS(diff[i],minbits[i]);
}
dframes->f[fn].ctrl = 0;
/* Set X0 and XN values in first frame */
X0 = data[0];
if ( swapflag ) ms_gswap4 (&X0);
dframes->f[0].ctrl = (dframes->f[0].ctrl<<2) | STEIM2_SPECIAL_MASK;
XN = data[ns-1];
if ( swapflag ) ms_gswap4 (&XN);
dframes->f[0].ctrl = (dframes->f[0].ctrl<<2) | STEIM2_SPECIAL_MASK;
while (points_remaining > 0)
{
points_packed = 0;
/* Pack the next available datapoints into the most compact form */
if (BIT4PACK(0,points_remaining))
{
PACK(4,7,0x0000000f,02)
if ( swapflag ) ms_gswap4 (&dframes->f[fn].w[wn].fw);
mask = STEIM2_567_MASK;
points_packed = 7;
}
else if (BIT5PACK(0,points_remaining))
{
PACK(5,6,0x0000001f,01)
if ( swapflag ) ms_gswap4 (&dframes->f[fn].w[wn].fw);
mask = STEIM2_567_MASK;
points_packed = 6;
}
else if (BIT6PACK(0,points_remaining))
{
PACK(6,5,0x0000003f,00)
if ( swapflag ) ms_gswap4 (&dframes->f[fn].w[wn].fw);
mask = STEIM2_567_MASK;
points_packed = 5;
}
else if (BYTEPACK(0,points_remaining))
{
mask = STEIM2_BYTE_MASK;
for (j=0; j<4; j++) dframes->f[fn].w[wn].byte[j] = diff[j];
points_packed = 4;
}
else if (BIT10PACK(0,points_remaining))
{
PACK(10,3,0x000003ff,03)
if ( swapflag ) ms_gswap4 (&dframes->f[fn].w[wn].fw);
mask = STEIM2_123_MASK;
points_packed = 3;
}
else if (BIT15PACK(0,points_remaining))
{
PACK(15,2,0x00007fff,02)
if ( swapflag ) ms_gswap4 (&dframes->f[fn].w[wn].fw);
mask = STEIM2_123_MASK;
points_packed = 2;
}
else if (BIT30PACK(0,points_remaining))
{
PACK(30,1,0x3fffffff,01)
if ( swapflag ) ms_gswap4 (&dframes->f[fn].w[wn].fw);
mask = STEIM2_123_MASK;
points_packed = 1;
}
else
{
ms_log (2, "msr_pack_steim2(%s): Unable to represent difference in <= 30 bits\n",
PACK_SRCNAME);
return -1;
}
/* Append mask for this word to current mask */
dframes->f[fn].ctrl = (dframes->f[fn].ctrl<<2) | mask;
points_remaining -= points_packed;
ipt += points_packed;
/* Check for full frame or full block */
if (++wn >= VALS_PER_FRAME)
{
if ( swapflag ) ms_gswap4 (&dframes->f[fn].ctrl);
/* Reset output index to beginning of frame */
wn = 0;
/* If block is full, output block and reinitialize */
if (++fn >= nf) break;
dframes->f[fn].ctrl = 0;
}
/* Shift and re-fill difference and minbits buffers */
for ( i=points_packed; i < 7; i++ )
{
/* Shift remaining buffer entries */
diff[i-points_packed] = diff[i];
minbits[i-points_packed] = minbits[i];
}
for ( i=7-points_packed,j=ipt+(7-points_packed); i < 7 && j < ns; i++,j++ )
{
/* Re-fill entries */
diff[i] = data[j] - data[j-1];
MINBITS(diff[i],minbits[i]);
}
}
/* Update XN value in first frame */
XN = data[(ns-1)-points_remaining];
if ( swapflag ) ms_gswap4 (&XN);
/* End of data. Pad current frame and optionally rest of block */
/* Do not pad and output a completely empty block */
if ( ! EMPTY_BLOCK(fn,wn) )
{
*pnframes = pad_steim_frame (dframes, fn, wn, nf, swapflag, pad);
}
else
{
*pnframes = 0;
}
*pnsamples = ns - points_remaining;
return 0;
}
/************************************************************************
* pad_steim_frame: *
* Pad the rest of the data record with null values, *
* and optionally the rest of the total number of frames. *
* return: *
* total number of frames in record. *
************************************************************************/
static int pad_steim_frame
(DFRAMES *dframes,
int fn, /* current frame number. */
int wn, /* current work number. */
int nf, /* total number of data frames. */
int swapflag, /* flag to swap byte order of data. */
int pad) /* flag to pad # frames to nf. */
{
/* Finish off the current frame */
if (wn < VALS_PER_FRAME && fn < nf)
{
for (; wn < VALS_PER_FRAME; wn++)
{
dframes->f[fn].w[wn].fw = 0;
dframes->f[fn].ctrl = (dframes->f[fn].ctrl<<2) | STEIM1_SPECIAL_MASK;
}
if ( swapflag ) ms_gswap4 (&dframes->f[fn].ctrl);
fn++;
}
/* Fill the remaining frames in the block */
if (pad)
{
for (; fn<nf; fn++)
{
dframes->f[fn].ctrl = STEIM1_SPECIAL_MASK; /* mask for ctrl */
for (wn=0; wn<VALS_PER_FRAME; wn++)
{
dframes->f[fn].w[wn].fw = 0;
dframes->f[fn].ctrl = (dframes->f[fn].ctrl<<2) | STEIM1_SPECIAL_MASK;
}
if ( swapflag ) ms_gswap4 (&dframes->f[fn].ctrl);
}
}
return fn;
}
/************************************************************************
* msr_pack_text: *
* Pack text data into text format. Split input data on line *
* breaks so as to not split lines between records. *
* Return: 0 on success, -1 on error. *
************************************************************************/
int msr_pack_text
(char *packed, /* output data array - packed. */
char *data, /* input data array - unpacked. */
int ns, /* desired number of samples to pack. */
int max_bytes, /* max # of bytes for output buffer. */
int pad, /* flag to specify padding to max_bytes.*/
int *pnbytes, /* number of bytes actually packed. */
int *pnsamples) /* number of samples actually packed. */
{
int points_remaining = ns; /* number of samples remaining to pack. */
int last = -1;
int nbytes;
int i;
/* Split lines only if a single line will not fit in 1 record */
if (points_remaining > max_bytes)
{
/* Look for the last newline that will fit in output buffer */
for (i=max_bytes-1; i>=0; i--)
{
if (data[i] == '\n') {
last = i;
break;
}
}
if (last < 0) last = max_bytes - 1;
}
if (last < 0) last = points_remaining - 1;
nbytes = last + 1;
memcpy (packed, data, nbytes);
packed += nbytes;
max_bytes -= nbytes;
*pnbytes = nbytes;
*pnsamples = nbytes;
points_remaining -= nbytes;
/* Pad miniSEED block if necessary */
if (pad)
{
memset ((void *)packed, 0, max_bytes);
*pnbytes += max_bytes;
}
*pnsamples = ns - points_remaining;
return 0;
}

35
libs/3rd-party/mseed/packdata.h vendored Normal file
View File

@ -0,0 +1,35 @@
/***************************************************************************
* packdata.h:
*
* Interface declarations for the Mini-SEED packing routines in
* packdata.c
*
* modified: 2008.220
***************************************************************************/
#ifndef PACKDATA_H
#define PACKDATA_H 1
#ifdef __cplusplus
extern "C" {
#endif
#include "steimdata.h"
/* Pointer to srcname of record being packed, declared in pack.c */
extern char *PACK_SRCNAME;
extern int msr_pack_int_16 (int16_t*, int32_t*, int, int, int, int*, int*, int);
extern int msr_pack_int_32 (int32_t*, int32_t*, int, int, int, int*, int*, int);
extern int msr_pack_float_32 (float*, float*, int, int, int, int*, int*, int);
extern int msr_pack_float_64 (double*, double*, int, int, int, int*, int*, int);
extern int msr_pack_steim1 (DFRAMES*, int32_t*, int32_t, int, int, int, int*, int*, int);
extern int msr_pack_steim2 (DFRAMES*, int32_t*, int32_t, int, int, int, int*, int*, int);
extern int msr_pack_text (char *, char *, int, int, int, int*, int*);
#ifdef __cplusplus
}
#endif
#endif

1163
libs/3rd-party/mseed/parseutils.c vendored Normal file

File diff suppressed because it is too large Load Diff

680
libs/3rd-party/mseed/selection.c vendored Normal file
View File

@ -0,0 +1,680 @@
/***************************************************************************
* selection.c:
*
* Generic routines to manage selection lists.
*
* Written by Chad Trabant unless otherwise noted
* IRIS Data Management Center
*
* modified: 2014.197
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include "libmseed.h"
static int ms_globmatch (char *string, char *pattern);
/***************************************************************************
* ms_matchselect:
*
* Test the specified parameters for a matching selection entry. The
* srcname parameter may contain globbing characters. The NULL value
* (matching any times) for the start and end times is HPTERROR.
*
* Return Selections pointer to matching entry on successful match and
* NULL for no match or error.
***************************************************************************/
Selections *
ms_matchselect (Selections *selections, char *srcname, hptime_t starttime,
hptime_t endtime, SelectTime **ppselecttime)
{
Selections *findsl = NULL;
SelectTime *findst = NULL;
SelectTime *matchst = NULL;
if ( selections )
{
findsl = selections;
while ( findsl )
{
if ( ms_globmatch (srcname, findsl->srcname) )
{
findst = findsl->timewindows;
while ( findst )
{
if ( starttime != HPTERROR && findst->starttime != HPTERROR &&
(starttime < findst->starttime && ! (starttime <= findst->starttime && endtime >= findst->starttime)) )
{ findst = findst->next; continue; }
else if ( endtime != HPTERROR && findst->endtime != HPTERROR &&
(endtime > findst->endtime && ! (starttime <= findst->endtime && endtime >= findst->endtime)) )
{ findst = findst->next; continue; }
matchst = findst;
break;
}
}
if ( matchst )
break;
else
findsl = findsl->next;
}
}
if ( ppselecttime )
*ppselecttime = matchst;
return ( matchst ) ? findsl : NULL;
} /* End of ms_matchselect() */
/***************************************************************************
* msr_matchselect:
*
* A simple wrapper for calling ms_matchselect() using details from a
* MSRecord struct.
*
* Return Selections pointer to matching entry on successful match and
* NULL for no match or error.
***************************************************************************/
Selections *
msr_matchselect (Selections *selections, MSRecord *msr, SelectTime **ppselecttime)
{
char srcname[50];
hptime_t endtime;
if ( ! selections || ! msr )
return NULL;
msr_srcname (msr, srcname, 1);
endtime = msr_endtime (msr);
return ms_matchselect (selections, srcname, msr->starttime, endtime,
ppselecttime);
} /* End of msr_matchselect() */
/***************************************************************************
* ms_addselect:
*
* Add select parameters to a specified selection list. The srcname
* argument may contain globbing parameters. The NULL value (matching
* any value) for the start and end times is HPTERROR.
*
* Return 0 on success and -1 on error.
***************************************************************************/
int
ms_addselect (Selections **ppselections, char *srcname,
hptime_t starttime, hptime_t endtime)
{
Selections *newsl = NULL;
SelectTime *newst = NULL;
if ( ! ppselections || ! srcname )
return -1;
/* Allocate new SelectTime and populate */
if ( ! (newst = (SelectTime *) calloc (1, sizeof(SelectTime))) )
{
ms_log (2, "Cannot allocate memory\n");
return -1;
}
newst->starttime = starttime;
newst->endtime = endtime;
/* Add new Selections struct to begining of list */
if ( ! *ppselections )
{
/* Allocate new Selections and populate */
if ( ! (newsl = (Selections *) calloc (1, sizeof(Selections))) )
{
ms_log (2, "Cannot allocate memory\n");
return -1;
}
strncpy (newsl->srcname, srcname, sizeof(newsl->srcname));
newsl->srcname[sizeof(newsl->srcname) - 1] = '\0';
/* Add new Selections struct as first in list */
*ppselections = newsl;
newsl->timewindows = newst;
}
else
{
Selections *findsl = *ppselections;
Selections *matchsl = 0;
/* Search for matching Selectlink entry */
while ( findsl )
{
if ( ! strcmp (findsl->srcname, srcname) )
{
matchsl = findsl;
break;
}
findsl = findsl->next;
}
if ( matchsl )
{
/* Add time window selection to beginning of window list */
newst->next = matchsl->timewindows;
matchsl->timewindows = newst;
}
else
{
/* Allocate new Selections and populate */
if ( ! (newsl = (Selections *) calloc (1, sizeof(Selections))) )
{
ms_log (2, "Cannot allocate memory\n");
return -1;
}
strncpy (newsl->srcname, srcname, sizeof(newsl->srcname));
newsl->srcname[sizeof(newsl->srcname) - 1] = '\0';
/* Add new Selections to beginning of list */
newsl->next = *ppselections;
*ppselections = newsl;
newsl->timewindows = newst;
}
}
return 0;
} /* End of ms_addselect() */
/***************************************************************************
* ms_addselect_comp:
*
* Add select parameters to a specified selection list based on
* separate name components. The network, station, location, channel
* and quality arguments may contain globbing parameters. The NULL
* value (matching any value) for the start and end times is HPTERROR.
*
* If any of the naming parameters are not supplied (pointer is NULL)
* a wildcard for all matches is substituted. As a special case, if
* the location ID (loc) is set to "--" to match a space-space/blank
* ID it will be translated to an empty string to match libmseed's
* notation.
*
* Return 0 on success and -1 on error.
***************************************************************************/
int
ms_addselect_comp (Selections **ppselections, char *net, char* sta, char *loc,
char *chan, char *qual, hptime_t starttime, hptime_t endtime)
{
char srcname[100];
char selnet[20];
char selsta[20];
char selloc[20];
char selchan[20];
char selqual[20];
if ( ! ppselections )
return -1;
if ( net )
{
strncpy (selnet, net, sizeof(selnet));
selnet[sizeof(selnet)-1] = '\0';
}
else
strcpy (selnet, "*");
if ( sta )
{
strncpy (selsta, sta, sizeof(selsta));
selsta[sizeof(selsta)-1] = '\0';
}
else
strcpy (selsta, "*");
if ( loc )
{
/* Test for special case blank location ID */
if ( ! strcmp (loc, "--") )
selloc[0] = '\0';
else
{
strncpy (selloc, loc, sizeof(selloc));
selloc[sizeof(selloc)-1] = '\0';
}
}
else
strcpy (selloc, "*");
if ( chan )
{
strncpy (selchan, chan, sizeof(selchan));
selchan[sizeof(selchan)-1] = '\0';
}
else
strcpy (selchan, "*");
if ( qual )
{
strncpy (selqual, qual, sizeof(selqual));
selqual[sizeof(selqual)-1] = '\0';
}
else
strcpy (selqual, "?");
/* Create the srcname globbing match for this entry */
snprintf (srcname, sizeof(srcname), "%s_%s_%s_%s_%s",
selnet, selsta, selloc, selchan, selqual);
/* Add selection to list */
if ( ms_addselect (ppselections, srcname, starttime, endtime) )
return -1;
return 0;
} /* End of ms_addselect_comp() */
/***************************************************************************
* ms_readselectionsfile:
*
* Read a list of data selections from a file and them to the
* specified selections list. On errors this routine will leave
* allocated memory unreachable (leaked), it is expected that this is
* a program failing condition.
*
* As a special case if the filename is "-", selection lines will be
* read from stdin.
*
* Returns count of selections added on success and -1 on error.
***************************************************************************/
int
ms_readselectionsfile (Selections **ppselections, char *filename)
{
FILE *fp;
hptime_t starttime;
hptime_t endtime;
char selectline[200];
char *selnet;
char *selsta;
char *selloc;
char *selchan;
char *selqual;
char *selstart;
char *selend;
char *cp;
char next;
int selectcount = 0;
int linecount = 0;
if ( ! ppselections || ! filename )
return -1;
if ( strcmp (filename, "-" ) )
{
if ( ! (fp = fopen(filename, "rb")) )
{
ms_log (2, "Cannot open file %s: %s\n", filename, strerror(errno));
return -1;
}
}
else
{
/* Use stdin as special case */
fp = stdin;
}
while ( fgets (selectline, sizeof(selectline)-1, fp) )
{
selnet = 0;
selsta = 0;
selloc = 0;
selchan = 0;
selqual = 0;
selstart = 0;
selend = 0;
linecount++;
/* Guarantee termination */
selectline[sizeof(selectline)-1] = '\0';
/* End string at first newline character if any */
if ( (cp = strchr(selectline, '\n')) )
*cp = '\0';
/* Skip empty lines */
if ( ! strlen (selectline) )
continue;
/* Skip comment lines */
if ( *selectline == '#' )
continue;
/* Parse: identify components of selection and terminate */
cp = selectline;
next = 1;
while ( *cp )
{
if ( *cp == ' ' || *cp == '\t' ) { *cp = '\0'; next = 1; }
else if ( *cp == '#' ) { *cp = '\0'; break; }
else if ( next && ! selnet ) { selnet = cp; next = 0; }
else if ( next && ! selsta ) { selsta = cp; next = 0; }
else if ( next && ! selloc ) { selloc = cp; next = 0; }
else if ( next && ! selchan ) { selchan = cp; next = 0; }
else if ( next && ! selqual ) { selqual = cp; next = 0; }
else if ( next && ! selstart ) { selstart = cp; next = 0; }
else if ( next && ! selend ) { selend = cp; next = 0; }
else if ( next ) { *cp = '\0'; break; }
cp++;
}
/* Skip line if network, station, location and channel are not defined */
if ( ! selnet || ! selsta || ! selloc || ! selchan )
{
ms_log (2, "[%s] Skipping data selection line number %d\n", filename, linecount);
continue;
}
if ( selstart )
{
starttime = ms_seedtimestr2hptime (selstart);
if ( starttime == HPTERROR )
{
ms_log (2, "Cannot convert data selection start time (line %d): %s\n", linecount, selstart);
return -1;
}
}
else
{
starttime = HPTERROR;
}
if ( selend )
{
endtime = ms_seedtimestr2hptime (selend);
if ( endtime == HPTERROR )
{
ms_log (2, "Cannot convert data selection end time (line %d): %s\n", linecount, selend);
return -1;
}
}
else
{
endtime = HPTERROR;
}
/* Add selection to list */
if ( ms_addselect_comp (ppselections, selnet, selsta, selloc, selchan, selqual, starttime, endtime) )
{
ms_log (2, "[%s] Error adding selection on line %d\n", filename, linecount);
return -1;
}
selectcount++;
}
if ( fp != stdin )
fclose (fp);
return selectcount;
} /* End of ms_readselectionsfile() */
/***************************************************************************
* ms_freeselections:
*
* Free all memory associated with a Selections struct.
***************************************************************************/
void
ms_freeselections ( Selections *selections )
{
Selections *select;
Selections *selectnext;
SelectTime *selecttime;
SelectTime *selecttimenext;
if ( selections )
{
select = selections;
while ( select )
{
selectnext = select->next;
selecttime = select->timewindows;
while ( selecttime )
{
selecttimenext = selecttime->next;
free (selecttime);
selecttime = selecttimenext;
}
free (select);
select = selectnext;
}
}
} /* End of ms_freeselections() */
/***************************************************************************
* ms_printselections:
*
* Print the selections list using the ms_log() facility.
***************************************************************************/
void
ms_printselections ( Selections *selections )
{
Selections *select;
SelectTime *selecttime;
char starttime[50];
char endtime[50];
if ( ! selections )
return;
select = selections;
while ( select )
{
ms_log (0, "Selection: %s\n", select->srcname);
selecttime = select->timewindows;
while ( selecttime )
{
if ( selecttime->starttime != HPTERROR )
ms_hptime2seedtimestr (selecttime->starttime, starttime, 1);
else
strncpy (starttime, "No start time", sizeof(starttime)-1);
if ( selecttime->endtime != HPTERROR )
ms_hptime2seedtimestr (selecttime->endtime, endtime, 1);
else
strncpy (endtime, "No end time", sizeof(endtime)-1);
ms_log (0, " %30s %30s\n", starttime, endtime);
selecttime = selecttime->next;
}
select = select->next;
}
} /* End of ms_printselections() */
/***********************************************************************
* robust glob pattern matcher
* ozan s. yigit/dec 1994
* public domain
*
* glob patterns:
* * matches zero or more characters
* ? matches any single character
* [set] matches any character in the set
* [^set] matches any character NOT in the set
* where a set is a group of characters or ranges. a range
* is written as two characters seperated with a hyphen: a-z denotes
* all characters between a to z inclusive.
* [-set] set matches a literal hypen and any character in the set
* []set] matches a literal close bracket and any character in the set
*
* char matches itself except where char is '*' or '?' or '['
* \char matches char, including any pattern character
*
* examples:
* a*c ac abc abbc ...
* a?c acc abc aXc ...
* a[a-z]c aac abc acc ...
* a[-a-z]c a-c aac abc ...
*
* Revision 1.4 2004/12/26 12:38:00 ct
* Changed function name (amatch -> globmatch), variables and
* formatting for clarity. Also add matching header globmatch.h.
*
* Revision 1.3 1995/09/14 23:24:23 oz
* removed boring test/main code.
*
* Revision 1.2 94/12/11 10:38:15 oz
* charset code fixed. it is now robust and interprets all
* variations of charset [i think] correctly, including [z-a] etc.
*
* Revision 1.1 94/12/08 12:45:23 oz
* Initial revision
***********************************************************************/
#define GLOBMATCH_TRUE 1
#define GLOBMATCH_FALSE 0
#define GLOBMATCH_NEGATE '^' /* std char set negation char */
/***********************************************************************
* ms_globmatch:
*
* Check if a string matches a globbing pattern.
*
* Return 0 if string does not match pattern and non-zero otherwise.
**********************************************************************/
static int
ms_globmatch (char *string, char *pattern)
{
int negate;
int match;
int c;
while ( *pattern )
{
if ( !*string && *pattern != '*' )
return GLOBMATCH_FALSE;
switch ( c = *pattern++ )
{
case '*':
while ( *pattern == '*' )
pattern++;
if ( !*pattern )
return GLOBMATCH_TRUE;
if ( *pattern != '?' && *pattern != '[' && *pattern != '\\' )
while ( *string && *pattern != *string )
string++;
while ( *string )
{
if ( ms_globmatch(string, pattern) )
return GLOBMATCH_TRUE;
string++;
}
return GLOBMATCH_FALSE;
case '?':
if ( *string )
break;
return GLOBMATCH_FALSE;
/* set specification is inclusive, that is [a-z] is a, z and
* everything in between. this means [z-a] may be interpreted
* as a set that contains z, a and nothing in between.
*/
case '[':
if ( *pattern != GLOBMATCH_NEGATE )
negate = GLOBMATCH_FALSE;
else
{
negate = GLOBMATCH_TRUE;
pattern++;
}
match = GLOBMATCH_FALSE;
while ( !match && (c = *pattern++) )
{
if ( !*pattern )
return GLOBMATCH_FALSE;
if ( *pattern == '-' ) /* c-c */
{
if ( !*++pattern )
return GLOBMATCH_FALSE;
if ( *pattern != ']' )
{
if ( *string == c || *string == *pattern ||
( *string > c && *string < *pattern ) )
match = GLOBMATCH_TRUE;
}
else
{ /* c-] */
if ( *string >= c )
match = GLOBMATCH_TRUE;
break;
}
}
else /* cc or c] */
{
if ( c == *string )
match = GLOBMATCH_TRUE;
if ( *pattern != ']' )
{
if ( *pattern == *string )
match = GLOBMATCH_TRUE;
}
else
break;
}
}
if ( negate == match )
return GLOBMATCH_FALSE;
/*
* if there is a match, skip past the charset and continue on
*/
while ( *pattern && *pattern != ']' )
pattern++;
if ( !*pattern++ ) /* oops! */
return GLOBMATCH_FALSE;
break;
case '\\':
if ( *pattern )
c = *pattern++;
default:
if ( c != *string )
return GLOBMATCH_FALSE;
break;
}
string++;
}
return !*string;
} /* End of ms_globmatch() */

51
libs/3rd-party/mseed/steimdata.h vendored Normal file
View File

@ -0,0 +1,51 @@
/***************************************************************************
* steimdata.h:
*
* Declarations for Steim compression routines.
*
* modified: 2004.278
***************************************************************************/
#ifndef STEIMDATA_H
#define STEIMDATA_H 1
#ifdef __cplusplus
extern "C" {
#endif
#define STEIM1_FRAME_MAX_SAMPLES 60
#define STEIM2_FRAME_MAX_SAMPLES 105
#define VALS_PER_FRAME 15 /* # of ints for data per frame.*/
#define STEIM1_SPECIAL_MASK 0
#define STEIM1_BYTE_MASK 1
#define STEIM1_HALFWORD_MASK 2
#define STEIM1_FULLWORD_MASK 3
#define STEIM2_SPECIAL_MASK 0
#define STEIM2_BYTE_MASK 1
#define STEIM2_123_MASK 2
#define STEIM2_567_MASK 3
typedef union u_diff { /* union for Steim objects. */
int8_t byte[4]; /* 4 1-byte differences. */
int16_t hw[2]; /* 2 halfword differences. */
int32_t fw; /* 1 fullword difference. */
} U_DIFF;
typedef struct frame { /* frame in a seed data record. */
uint32_t ctrl; /* control word for frame. */
U_DIFF w[15]; /* compressed data. */
} FRAME;
typedef struct dframes { /* seed data frames. */
FRAME f[1]; /* data record header frames. */
} DFRAMES;
#ifdef __cplusplus
}
#endif
#endif /* STEIMDATA_H */

1277
libs/3rd-party/mseed/tracelist.c vendored Normal file

File diff suppressed because it is too large Load Diff

1855
libs/3rd-party/mseed/traceutils.c vendored Normal file

File diff suppressed because it is too large Load Diff

1083
libs/3rd-party/mseed/unpack.c vendored Normal file

File diff suppressed because it is too large Load Diff

892
libs/3rd-party/mseed/unpackdata.c vendored Normal file
View File

@ -0,0 +1,892 @@
/************************************************************************
* Routines for unpacking INT_16, INT_32, FLOAT_32, FLOAT_64,
* STEIM1, STEIM2, GEOSCOPE (24bit and gain ranged), CDSN, SRO
* and DWWSSN encoded data records.
*
* Some routines originated and were borrowed from qlib2 by:
*
* Douglas Neuhauser
* Seismographic Station
* University of California, Berkeley
* doug@seismo.berkeley.edu
*
* Modified by Chad Trabant,
* (previously) ORFEUS/EC-Project MEREDIAN
* (currently) IRIS Data Management Center
*
* modified: 2012.357
************************************************************************/
/*
* Copyright (c) 1996 The Regents of the University of California.
* All Rights Reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for educational, research and non-profit purposes,
* without fee, and without a written agreement is hereby granted,
* provided that the above copyright notice, this paragraph and the
* following three paragraphs appear in all copies.
*
* Permission to incorporate this software into commercial products may
* be obtained from the Office of Technology Licensing, 2150 Shattuck
* Avenue, Suite 510, Berkeley, CA 94704.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
* FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
* INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND
* ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
* PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
* CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
* UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include "libmseed.h"
#include "unpackdata.h"
#define MAX12 0x7ff /* maximum 12 bit positive # */
#define MAX14 0x1fff /* maximum 14 bit positive # */
#define MAX16 0x7fff /* maximum 16 bit positive # */
#define MAX24 0x7fffff /* maximum 24 bit positive # */
/* For Steim encodings */
#define X0 pf->w[0].fw
#define XN pf->w[1].fw
/************************************************************************
* msr_unpack_int_16: *
* *
* Unpack int_16 miniSEED data and place in supplied buffer. *
* *
* Return: # of samples returned. *
************************************************************************/
int msr_unpack_int_16
(int16_t *ibuf, /* ptr to input data. */
int num_samples, /* number of data samples in total. */
int req_samples, /* number of data desired by caller. */
int32_t *databuff, /* ptr to unpacked data array. */
int swapflag) /* if data should be swapped. */
{
int nd = 0; /* # of data points in packet. */
int16_t stmp;
if (num_samples < 0) return 0;
if (req_samples < 0) return 0;
for (nd=0; nd<req_samples && nd<num_samples; nd++) {
stmp = ibuf[nd];
if ( swapflag ) ms_gswap2a (&stmp);
databuff[nd] = stmp;
}
return nd;
} /* End of msr_unpack_int_16() */
/************************************************************************
* msr_unpack_int_32: *
* *
* Unpack int_32 miniSEED data and place in supplied buffer. *
* *
* Return: # of samples returned. *
************************************************************************/
int msr_unpack_int_32
(int32_t *ibuf, /* ptr to input data. */
int num_samples, /* number of data samples in total. */
int req_samples, /* number of data desired by caller. */
int32_t *databuff, /* ptr to unpacked data array. */
int swapflag) /* if data should be swapped. */
{
int nd = 0; /* # of data points in packet. */
int32_t itmp;
if (num_samples < 0) return 0;
if (req_samples < 0) return 0;
for (nd=0; nd<req_samples && nd<num_samples; nd++) {
itmp = ibuf[nd];
if ( swapflag) ms_gswap4a (&itmp);
databuff[nd] = itmp;
}
return nd;
} /* End of msr_unpack_int_32() */
/************************************************************************
* msr_unpack_float_32: *
* *
* Unpack float_32 miniSEED data and place in supplied buffer. *
* *
* Return: # of samples returned. *
************************************************************************/
int msr_unpack_float_32
(float *fbuf, /* ptr to input data. */
int num_samples, /* number of data samples in total. */
int req_samples, /* number of data desired by caller. */
float *databuff, /* ptr to unpacked data array. */
int swapflag) /* if data should be swapped. */
{
int nd = 0; /* # of data points in packet. */
float ftmp;
if (num_samples < 0) return 0;
if (req_samples < 0) return 0;
for (nd=0; nd<req_samples && nd<num_samples; nd++) {
memcpy (&ftmp, &fbuf[nd], sizeof(float));
if ( swapflag ) ms_gswap4a (&ftmp);
databuff[nd] = ftmp;
}
return nd;
} /* End of msr_unpack_float_32() */
/************************************************************************
* msr_unpack_float_64: *
* *
* Unpack float_64 miniSEED data and place in supplied buffer. *
* *
* Return: # of samples returned. *
************************************************************************/
int msr_unpack_float_64
(double *fbuf, /* ptr to input data. */
int num_samples, /* number of data samples in total. */
int req_samples, /* number of data desired by caller. */
double *databuff, /* ptr to unpacked data array. */
int swapflag) /* if data should be swapped. */
{
int nd = 0; /* # of data points in packet. */
double dtmp;
if (num_samples < 0) return 0;
if (req_samples < 0) return 0;
for (nd=0; nd<req_samples && nd<num_samples; nd++) {
memcpy (&dtmp, &fbuf[nd], sizeof(double));
if ( swapflag ) ms_gswap8a (&dtmp);
databuff[nd] = dtmp;
}
return nd;
} /* End of msr_unpack_float_64() */
/************************************************************************
* msr_unpack_steim1: *
* *
* Unpack STEIM1 data frames and place in supplied buffer. *
* See the SEED format manual for Steim-1 encoding details. *
* *
* Return: # of samples returned or negative error code. *
************************************************************************/
int msr_unpack_steim1
(FRAME *pf, /* ptr to Steim1 data frames. */
int nbytes, /* number of bytes in all data frames. */
int num_samples, /* number of data samples in all frames.*/
int req_samples, /* number of data desired by caller. */
int32_t *databuff, /* ptr to unpacked data array. */
int32_t *diffbuff, /* ptr to unpacked diff array. */
int32_t *px0, /* return X0, first sample in frame. */
int32_t *pxn, /* return XN, last sample in frame. */
int swapflag, /* if data should be swapped. */
int verbose)
{
int32_t *diff = diffbuff;
int32_t *data = databuff;
int32_t *prev;
int num_data_frames = nbytes / sizeof(FRAME);
int nd = 0; /* # of data points in packet. */
int fn; /* current frame number. */
int wn; /* current work number in the frame. */
int compflag; /* current compression flag. */
int nr, i;
int32_t last_data;
int32_t itmp;
int16_t stmp;
uint32_t ctrl;
if (num_samples < 0) return 0;
if (num_samples == 0) return 0;
if (req_samples < 0) return 0;
/* Extract forward and reverse integration constants in first frame */
*px0 = X0;
*pxn = XN;
if ( swapflag )
{
ms_gswap4a (px0);
ms_gswap4a (pxn);
}
if ( verbose > 2 )
ms_log (1, "%s: forward/reverse integration constants:\nX0: %d XN: %d\n",
UNPACK_SRCNAME, *px0, *pxn);
/* Decode compressed data in each frame */
for (fn = 0; fn < num_data_frames; fn++)
{
ctrl = pf->ctrl;
if ( swapflag ) ms_gswap4a (&ctrl);
for (wn = 0; wn < VALS_PER_FRAME; wn++)
{
if (nd >= num_samples) break;
compflag = (ctrl >> ((VALS_PER_FRAME-wn-1)*2)) & 0x3;
switch (compflag)
{
case STEIM1_SPECIAL_MASK:
/* Headers info -- skip it */
break;
case STEIM1_BYTE_MASK:
/* Next 4 bytes are 4 1-byte differences */
for (i=0; i < 4 && nd < num_samples; i++, nd++)
*diff++ = pf->w[wn].byte[i];
break;
case STEIM1_HALFWORD_MASK:
/* Next 4 bytes are 2 2-byte differences */
for (i=0; i < 2 && nd < num_samples; i++, nd++)
{
if ( swapflag )
{
stmp = pf->w[wn].hw[i];
ms_gswap2a (&stmp);
*diff++ = stmp;
}
else *diff++ = pf->w[wn].hw[i];
}
break;
case STEIM1_FULLWORD_MASK:
/* Next 4 bytes are 1 4-byte difference */
if ( swapflag )
{
itmp = pf->w[wn].fw;
ms_gswap4a (&itmp);
*diff++ = itmp;
}
else *diff++ = pf->w[wn].fw;
nd++;
break;
default:
/* Should NEVER get here */
ms_log (2, "msr_unpack_steim1(%s): invalid compression flag = %d\n",
UNPACK_SRCNAME, compflag);
return MS_STBADCOMPFLAG;
}
}
++pf;
}
/* Test if the number of samples implied by the data frames is the
* same number indicated in the header.
*/
if ( nd != num_samples )
{
ms_log (1, "Warning: msr_unpack_steim1(%s): number of samples indicated in header (%d) does not equal data (%d)\n",
UNPACK_SRCNAME, num_samples, nd);
}
/* For now, assume sample count in header to be correct. */
/* One way of "trimming" data from a block is simply to reduce */
/* the sample count. It is not clear from the documentation */
/* whether this is a valid or not, but it appears to be done */
/* by other program, so we should not complain about its effect. */
nr = req_samples;
/* Compute first value based on last_value from previous buffer. */
/* The two should correspond in all cases EXCEPT for the first */
/* record for each component (because we don't have a valid xn from */
/* a previous record). Although the Steim compression algorithm */
/* defines x(-1) as 0 for the first record, this only works for the */
/* first record created since coldstart of the datalogger, NOT the */
/* first record of an arbitrary starting record. */
/* In all cases, assume x0 is correct, since we don't have x(-1). */
data = databuff;
diff = diffbuff;
last_data = *px0;
if (nr > 0)
*data = *px0;
/* Compute all but first values based on previous value */
prev = data - 1;
while (--nr > 0 && --nd > 0)
last_data = *++data = *++diff + *++prev;
/* If a short count was requested compute the last sample in order */
/* to perform the integrity check comparison */
while (--nd > 0)
last_data = *++diff + last_data;
/* Verify that the last value is identical to xn = rev. int. constant */
if (last_data != *pxn)
{
ms_log (1, "%s: Warning: Data integrity check for Steim-1 failed, last_data=%d, xn=%d\n",
UNPACK_SRCNAME, last_data, *pxn);
}
return ((req_samples < num_samples) ? req_samples : num_samples);
} /* End of msr_unpack_steim1() */
/************************************************************************
* msr_unpack_steim2: *
* *
* Unpack STEIM2 data frames and place in supplied buffer. *
* See the SEED format manual for Steim-2 encoding details. *
* *
* Return: # of samples returned or negative error code. *
************************************************************************/
int msr_unpack_steim2
(FRAME *pf, /* ptr to Steim2 data frames. */
int nbytes, /* number of bytes in all data frames. */
int num_samples, /* number of data samples in all frames.*/
int req_samples, /* number of data desired by caller. */
int32_t *databuff, /* ptr to unpacked data array. */
int32_t *diffbuff, /* ptr to unpacked diff array. */
int32_t *px0, /* return X0, first sample in frame. */
int32_t *pxn, /* return XN, last sample in frame. */
int swapflag, /* if data should be swapped. */
int verbose)
{
int32_t *diff = diffbuff;
int32_t *data = databuff;
int32_t *prev;
int num_data_frames = nbytes / sizeof(FRAME);
int nd = 0; /* # of data points in packet. */
int fn; /* current frame number. */
int wn; /* current work number in the frame. */
int compflag; /* current compression flag. */
int nr, i;
int n, bits, m1, m2;
int32_t last_data;
int32_t val;
int8_t dnib;
uint32_t ctrl;
if (num_samples < 0) return 0;
if (num_samples == 0) return 0;
if (req_samples < 0) return 0;
/* Extract forward and reverse integration constants in first frame.*/
*px0 = X0;
*pxn = XN;
if ( swapflag )
{
ms_gswap4a (px0);
ms_gswap4a (pxn);
}
if ( verbose > 2 )
ms_log (1, "%s: forward/reverse integration constants: X0: %d XN: %d\n",
UNPACK_SRCNAME, *px0, *pxn);
/* Decode compressed data in each frame */
for (fn = 0; fn < num_data_frames; fn++)
{
ctrl = pf->ctrl;
if ( swapflag ) ms_gswap4a (&ctrl);
for (wn = 0; wn < VALS_PER_FRAME; wn++)
{
if (nd >= num_samples) break;
compflag = (ctrl >> ((VALS_PER_FRAME-wn-1)*2)) & 0x3;
switch (compflag)
{
case STEIM2_SPECIAL_MASK:
/* Headers info -- skip it */
break;
case STEIM2_BYTE_MASK:
/* Next 4 bytes are 4 1-byte differences */
for (i=0; i < 4 && nd < num_samples; i++, nd++)
*diff++ = pf->w[wn].byte[i];
break;
case STEIM2_123_MASK:
val = pf->w[wn].fw;
if ( swapflag ) ms_gswap4a (&val);
dnib = val >> 30 & 0x3;
switch (dnib)
{
case 1: /* 1 30-bit difference */
bits = 30; n = 1; m1 = 0x3fffffff; m2 = 0x20000000; break;
case 2: /* 2 15-bit differences */
bits = 15; n = 2; m1 = 0x00007fff; m2 = 0x00004000; break;
case 3: /* 3 10-bit differences */
bits = 10; n = 3; m1 = 0x000003ff; m2 = 0x00000200; break;
default: /* should NEVER get here */
ms_log (2, "msr_unpack_steim2(%s): invalid compflag, dnib, fn, wn = %d, %d, %d, %d\n",
UNPACK_SRCNAME, compflag, dnib, fn, wn);
return MS_STBADCOMPFLAG;
}
/* Uncompress the differences */
for (i=(n-1)*bits; i >= 0 && nd < num_samples; i-=bits, nd++)
{
*diff = (val >> i) & m1;
*diff = (*diff & m2) ? *diff | ~m1 : *diff;
diff++;
}
break;
case STEIM2_567_MASK:
val = pf->w[wn].fw;
if ( swapflag ) ms_gswap4a (&val);
dnib = val >> 30 & 0x3;
switch (dnib)
{
case 0: /* 5 6-bit differences */
bits = 6; n = 5; m1 = 0x0000003f; m2 = 0x00000020; break;
case 1: /* 6 5-bit differences */
bits = 5; n = 6; m1 = 0x0000001f; m2 = 0x00000010; break;
case 2: /* 7 4-bit differences */
bits = 4; n = 7; m1 = 0x0000000f; m2 = 0x00000008; break;
default:
ms_log (2, "msr_unpack_steim2(%s): invalid compflag, dnib, fn, wn = %d, %d, %d, %d\n",
UNPACK_SRCNAME, compflag, dnib, fn, wn);
return MS_STBADCOMPFLAG;
}
/* Uncompress the differences */
for (i=(n-1)*bits; i >= 0 && nd < num_samples; i-=bits, nd++)
{
*diff = (val >> i) & m1;
*diff = (*diff & m2) ? *diff | ~m1 : *diff;
diff++;
}
break;
default:
/* Should NEVER get here */
ms_log (2, "msr_unpack_steim2(%s): invalid compflag, fn, wn = %d, %d, %d - nsamp: %d\n",
UNPACK_SRCNAME, compflag, fn, wn, nd);
return MS_STBADCOMPFLAG;
}
}
++pf;
}
/* Test if the number of samples implied by the data frames is the
* same number indicated in the header.
*/
if ( nd != num_samples )
{
ms_log (1, "Warning: msr_unpack_steim2(%s): number of samples indicated in header (%d) does not equal data (%d)\n",
UNPACK_SRCNAME, num_samples, nd);
}
/* For now, assume sample count in header to be correct. */
/* One way of "trimming" data from a block is simply to reduce */
/* the sample count. It is not clear from the documentation */
/* whether this is a valid or not, but it appears to be done */
/* by other program, so we should not complain about its effect. */
nr = req_samples;
/* Compute first value based on last_value from previous buffer. */
/* The two should correspond in all cases EXCEPT for the first */
/* record for each component (because we don't have a valid xn from */
/* a previous record). Although the Steim compression algorithm */
/* defines x(-1) as 0 for the first record, this only works for the */
/* first record created since coldstart of the datalogger, NOT the */
/* first record of an arbitrary starting record. */
/* In all cases, assume x0 is correct, since we don't have x(-1). */
data = databuff;
diff = diffbuff;
last_data = *px0;
if (nr > 0)
*data = *px0;
/* Compute all but first values based on previous value */
prev = data - 1;
while (--nr > 0 && --nd > 0)
last_data = *++data = *++diff + *++prev;
/* If a short count was requested compute the last sample in order */
/* to perform the integrity check comparison */
while (--nd > 0)
last_data = *++diff + last_data;
/* Verify that the last value is identical to xn = rev. int. constant */
if (last_data != *pxn)
{
ms_log (1, "%s: Warning: Data integrity check for Steim-2 failed, last_data=%d, xn=%d\n",
UNPACK_SRCNAME, last_data, *pxn);
}
return ((req_samples < num_samples) ? req_samples : num_samples);
} /* End of msr_unpack_steim2() */
/* Defines for GEOSCOPE encoding */
#define GEOSCOPE_MANTISSA_MASK 0x0fff /* mask for mantissa */
#define GEOSCOPE_GAIN3_MASK 0x7000 /* mask for gainrange factor */
#define GEOSCOPE_GAIN4_MASK 0xf000 /* mask for gainrange factor */
#define GEOSCOPE_SHIFT 12 /* # bits in mantissa */
/************************************************************************
* msr_unpack_geoscope: *
* *
* Unpack GEOSCOPE gain ranged data (demultiplexed only) encoded *
* miniSEED data and place in supplied buffer. *
* *
* Return: # of samples returned. *
************************************************************************/
int msr_unpack_geoscope
(const char *edata, /* ptr to encoded data. */
int num_samples, /* number of data samples in total. */
int req_samples, /* number of data desired by caller. */
float *databuff, /* ptr to unpacked data array. */
int encoding, /* specific GEOSCOPE encoding type */
int swapflag) /* if data should be swapped. */
{
int nd = 0; /* # of data points in packet. */
int mantissa; /* mantissa from SEED data */
int gainrange; /* gain range factor */
int exponent; /* total exponent */
int k;
uint64_t exp2val;
int16_t sint;
double dsample = 0.0;
union {
uint8_t b[4];
uint32_t i;
} sample32;
if (num_samples < 0) return 0;
if (req_samples < 0) return 0;
/* Make sure we recognize this as a GEOSCOPE encoding format */
if ( encoding != DE_GEOSCOPE24 &&
encoding != DE_GEOSCOPE163 &&
encoding != DE_GEOSCOPE164 )
{
ms_log (2, "msr_unpack_geoscope(%s): unrecognized GEOSCOPE encoding: %d\n",
UNPACK_SRCNAME, encoding);
return -1;
}
for (nd=0; nd<req_samples && nd<num_samples; nd++)
{
switch (encoding)
{
case DE_GEOSCOPE24:
sample32.i = 0;
if ( swapflag )
for (k=0; k < 3; k++)
sample32.b[2-k] = edata[k];
else
for (k=0; k < 3; k++)
sample32.b[1+k] = edata[k];
mantissa = sample32.i;
/* Take 2's complement for mantissa for overflow */
if (mantissa > MAX24)
mantissa -= 2 * (MAX24 + 1);
/* Store */
dsample = (double) mantissa;
break;
case DE_GEOSCOPE163:
memcpy (&sint, edata, sizeof(int16_t));
if ( swapflag ) ms_gswap2a(&sint);
/* Recover mantissa and gain range factor */
mantissa = (sint & GEOSCOPE_MANTISSA_MASK);
gainrange = (sint & GEOSCOPE_GAIN3_MASK) >> GEOSCOPE_SHIFT;
/* Exponent is just gainrange for GEOSCOPE */
exponent = gainrange;
/* Calculate sample as mantissa / 2^exponent */
exp2val = (uint64_t) 1 << exponent;
dsample = ((double) (mantissa-2048)) / exp2val;
break;
case DE_GEOSCOPE164:
memcpy (&sint, edata, sizeof(int16_t));
if ( swapflag ) ms_gswap2a(&sint);
/* Recover mantissa and gain range factor */
mantissa = (sint & GEOSCOPE_MANTISSA_MASK);
gainrange = (sint & GEOSCOPE_GAIN4_MASK) >> GEOSCOPE_SHIFT;
/* Exponent is just gainrange for GEOSCOPE */
exponent = gainrange;
/* Calculate sample as mantissa / 2^exponent */
exp2val = (uint64_t) 1 << exponent;
dsample = ((double) (mantissa-2048)) / exp2val;
break;
}
/* Save sample in output array */
databuff[nd] = (float) dsample;
/* Increment edata pointer depending on size */
switch (encoding)
{
case DE_GEOSCOPE24:
edata += 3;
break;
case DE_GEOSCOPE163:
case DE_GEOSCOPE164:
edata += 2;
break;
}
}
return nd;
} /* End of msr_unpack_geoscope() */
/* Defines for CDSN encoding */
#define CDSN_MANTISSA_MASK 0x3fff /* mask for mantissa */
#define CDSN_GAINRANGE_MASK 0xc000 /* mask for gainrange factor */
#define CDSN_SHIFT 14 /* # bits in mantissa */
/************************************************************************
* msr_unpack_cdsn: *
* *
* Unpack CDSN gain ranged data encoded miniSEED data and place in *
* supplied buffer. *
* *
* Notes from original rdseed routine: *
* CDSN data are compressed according to the formula *
* *
* sample = M * (2 exp G) *
* *
* where *
* sample = seismic data sample *
* M = mantissa; biased mantissa B is written to tape *
* G = exponent of multiplier (i.e. gain range factor); *
* key K is written to tape *
* exp = exponentiation operation *
* B = M + 8191, biased mantissa, written to tape *
* K = key to multiplier exponent, written to tape *
* K may have any of the values 0 - 3, as follows: *
* 0 => G = 0, multiplier = 2 exp 0 = 1 *
* 1 => G = 2, multiplier = 2 exp 2 = 4 *
* 2 => G = 4, multiplier = 2 exp 4 = 16 *
* 3 => G = 7, multiplier = 2 exp 7 = 128 *
* Data are stored on tape in two bytes as follows: *
* fedc ba98 7654 3210 = bit number, power of two *
* KKBB BBBB BBBB BBBB = form of SEED data *
* where K = key to multiplier exponent and B = biased mantissa *
* *
* Masks to recover key to multiplier exponent and biased mantissa *
* from tape are: *
* fedc ba98 7654 3210 = bit number = power of two *
* 0011 1111 1111 1111 = 0x3fff = mask for biased mantissa *
* 1100 0000 0000 0000 = 0xc000 = mask for gain range key *
* *
* Return: # of samples returned. *
************************************************************************/
int msr_unpack_cdsn
(int16_t *edata, /* ptr to encoded data. */
int num_samples, /* number of data samples in total. */
int req_samples, /* number of data desired by caller. */
int32_t *databuff, /* ptr to unpacked data array. */
int swapflag) /* if data should be swapped. */
{
int32_t nd = 0; /* sample count */
int32_t mantissa; /* mantissa */
int32_t gainrange; /* gain range factor */
int32_t mult = -1; /* multiplier for gain range */
uint16_t sint;
int32_t sample;
if (num_samples < 0) return 0;
if (req_samples < 0) return 0;
for (nd=0; nd<req_samples && nd<num_samples; nd++)
{
memcpy (&sint, &edata[nd], sizeof(int16_t));
if ( swapflag ) ms_gswap2a(&sint);
/* Recover mantissa and gain range factor */
mantissa = (sint & CDSN_MANTISSA_MASK);
gainrange = (sint & CDSN_GAINRANGE_MASK) >> CDSN_SHIFT;
/* Determine multiplier from the gain range factor and format definition
* because shift operator is used later, these are powers of two */
if ( gainrange == 0 ) mult = 0;
else if ( gainrange == 1 ) mult = 2;
else if ( gainrange == 2 ) mult = 4;
else if ( gainrange == 3 ) mult = 7;
/* Unbias the mantissa */
mantissa -= MAX14;
/* Calculate sample from mantissa and multiplier using left shift
* mantissa << mult is equivalent to mantissa * (2 exp (mult)) */
sample = (mantissa << mult);
/* Save sample in output array */
databuff[nd] = sample;
}
return nd;
} /* End of msr_unpack_cdsn() */
/* Defines for SRO encoding */
#define SRO_MANTISSA_MASK 0x0fff /* mask for mantissa */
#define SRO_GAINRANGE_MASK 0xf000 /* mask for gainrange factor */
#define SRO_SHIFT 12 /* # bits in mantissa */
/************************************************************************
* msr_unpack_sro: *
* *
* Unpack SRO gain ranged data encoded miniSEED data and place in *
* supplied buffer. *
* *
* Notes from original rdseed routine: *
* SRO data are represented according to the formula *
* *
* sample = M * (b exp {[m * (G + agr)] + ar}) *
* *
* where *
* sample = seismic data sample *
* M = mantissa *
* G = gain range factor *
* b = base to be exponentiated = 2 for SRO *
* m = multiplier = -1 for SRO *
* agr = term to be added to gain range factor = 0 for SRO *
* ar = term to be added to [m * (gr + agr)] = 10 for SRO *
* exp = exponentiation operation *
* Data are stored in two bytes as follows: *
* fedc ba98 7654 3210 = bit number, power of two *
* GGGG MMMM MMMM MMMM = form of SEED data *
* where G = gain range factor and M = mantissa *
* Masks to recover gain range and mantissa: *
* fedc ba98 7654 3210 = bit number = power of two *
* 0000 1111 1111 1111 = 0x0fff = mask for mantissa *
* 1111 0000 0000 0000 = 0xf000 = mask for gain range *
* *
* Return: # of samples returned. *
************************************************************************/
int msr_unpack_sro
(int16_t *edata, /* ptr to encoded data. */
int num_samples, /* number of data samples in total. */
int req_samples, /* number of data desired by caller. */
int32_t *databuff, /* ptr to unpacked data array. */
int swapflag) /* if data should be swapped. */
{
int32_t nd = 0; /* sample count */
int32_t mantissa; /* mantissa */
int32_t gainrange; /* gain range factor */
int32_t add2gr; /* added to gainrage factor */
int32_t mult; /* multiplier for gain range */
int32_t add2result; /* added to multiplied gain rage */
int32_t exponent; /* total exponent */
uint16_t sint;
int32_t sample;
if (num_samples < 0) return 0;
if (req_samples < 0) return 0;
add2gr = 0;
mult = -1;
add2result = 10;
for (nd=0; nd<req_samples && nd<num_samples; nd++)
{
memcpy (&sint, &edata[nd], sizeof(int16_t));
if ( swapflag ) ms_gswap2a(&sint);
/* Recover mantissa and gain range factor */
mantissa = (sint & SRO_MANTISSA_MASK);
gainrange = (sint & SRO_GAINRANGE_MASK) >> SRO_SHIFT;
/* Take 2's complement for mantissa */
if ( mantissa > MAX12 )
mantissa -= 2 * (MAX12 + 1);
/* Calculate exponent, SRO exponent = 0..10 */
exponent = (mult * (gainrange + add2gr)) + add2result;
if ( exponent < 0 || exponent > 10 )
{
ms_log (2, "msr_unpack_sro(%s): SRO gain ranging exponent out of range: %d\n",
UNPACK_SRCNAME, exponent);
return MS_GENERROR;
}
/* Calculate sample as mantissa * 2^exponent */
sample = mantissa * ( (uint64_t) 1 << exponent );
/* Save sample in output array */
databuff[nd] = sample;
}
return nd;
} /* End of msr_unpack_sro() */
/************************************************************************
* msr_unpack_dwwssn: *
* *
* Unpack DWWSSN encoded miniSEED data and place in supplied buffer. *
* *
* Return: # of samples returned. *
************************************************************************/
int msr_unpack_dwwssn
(int16_t *edata, /* ptr to encoded data. */
int num_samples, /* number of data samples in total. */
int req_samples, /* number of data desired by caller. */
int32_t *databuff, /* ptr to unpacked data array. */
int swapflag) /* if data should be swapped. */
{
int32_t nd = 0; /* sample count */
int32_t sample;
uint16_t sint;
if (num_samples < 0) return 0;
if (req_samples < 0) return 0;
for (nd=0; nd<req_samples && nd<num_samples; nd++)
{
memcpy (&sint, &edata[nd], sizeof(uint16_t));
if ( swapflag ) ms_gswap2a(&sint);
sample = (int32_t) sint;
/* Take 2's complement for sample */
if ( sample > MAX16 )
sample -= 2 * (MAX16 + 1);
/* Save sample in output array */
databuff[nd] = sample;
}
return nd;
} /* End of msr_unpack_dwwssn() */

40
libs/3rd-party/mseed/unpackdata.h vendored Normal file
View File

@ -0,0 +1,40 @@
/***************************************************************************
* unpack.h:
*
* Interface declarations for the Mini-SEED unpacking routines in
* unpackdata.c
*
* modified: 2009.111
***************************************************************************/
#ifndef UNPACKDATA_H
#define UNPACKDATA_H 1
#ifdef __cplusplus
extern "C" {
#endif
#include "steimdata.h"
/* Pointer to srcname of record being unpacked, declared in unpack.c */
extern char *UNPACK_SRCNAME;
extern int msr_unpack_int_16 (int16_t*, int, int, int32_t*, int);
extern int msr_unpack_int_32 (int32_t*, int, int, int32_t*, int);
extern int msr_unpack_float_32 (float*, int, int, float*, int);
extern int msr_unpack_float_64 (double*, int, int, double*, int);
extern int msr_unpack_steim1 (FRAME*, int, int, int, int32_t*, int32_t*,
int32_t*, int32_t*, int, int);
extern int msr_unpack_steim2 (FRAME*, int, int, int, int32_t*, int32_t*,
int32_t*, int32_t*, int, int);
extern int msr_unpack_geoscope (const char*, int, int, float*, int, int);
extern int msr_unpack_cdsn (int16_t*, int, int, int32_t*, int);
extern int msr_unpack_sro (int16_t*, int, int, int32_t*, int);
extern int msr_unpack_dwwssn (int16_t*, int, int, int32_t*, int);
#ifdef __cplusplus
}
#endif
#endif