⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unpack.c

📁 C编写的格式转换程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************** * unpack.c: * * Generic routines to unpack Mini-SEED records. * * Appropriate values from the record header will be byte-swapped to * the host order.  The purpose of this code is to provide a portable * way of accessing common SEED data record header information.  All * data structures in SEED 2.4 data records are supported.  The data * samples are optionally decompressed/unpacked. * * Written by Chad Trabant, *   ORFEUS/EC-Project MEREDIAN *   IRIS Data Management Center * * modified: 2007.178 ***************************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <ctype.h>#include "libmseed.h"#include "unpackdata.h"/* Function(s) internal to this file */static int msr_unpack_data (MSRecord * msr, int swapflag, int verbose);static int check_environment (int verbose);/* Header and data byte order flags controlled by environment variables *//* -2 = not checked, -1 = checked but not set, or 0 = LE and 1 = BE */flag unpackheaderbyteorder = -2;flag unpackdatabyteorder   = -2;/* Data encoding format/fallback controlled by environment variable *//* -2 = not checked, -1 = checked but not set, or = encoding */int unpackencodingformat   = -2;int unpackencodingfallback = -2;/* A pointer to the srcname of the record being unpacked */char *UNPACK_SRCNAME = NULL;/*************************************************************************** * msr_unpack: * * Unpack a SEED data record header/blockettes and populate a MSRecord * struct. All approriate fields are byteswapped, if needed, and * pointers to structured data are setup in addition to setting the * common header fields. * * If 'dataflag' is true the data samples are unpacked/decompressed * and the MSRecord->datasamples pointer is set appropriately.  The * data samples will be either 32-bit integers, 32-bit floats or * 64-bit floats (doubles) with the same byte order as the host * machine.  The MSRecord->numsamples will be set to the actual number * of samples unpacked/decompressed and MSRecord->sampletype will * indicated the sample type. * * All appropriate values will be byte-swapped to the host order, * including the data samples. * * All header values, blockette values and data samples will be * overwritten by subsequent calls to this function. * * If the msr struct is NULL it will be allocated. *  * Returns MS_NOERROR and populates the MSRecord struct at *ppmsr on * success, otherwise returns a libmseed error code (listed in * libmseed.h). ***************************************************************************/intmsr_unpack ( char *record, int reclen, MSRecord **ppmsr,	     flag dataflag, flag verbose ){  flag headerswapflag = 0;  flag dataswapflag = 0;  int retval;    MSRecord *msr = NULL;  char sequence_number[7];  char srcname[50];    /* For blockette parsing */  BlktLink *blkt_link;  uint16_t blkt_type;  uint16_t next_blkt;  uint32_t blkt_offset;  uint32_t blkt_length;    if ( ! ppmsr )    {      ms_log (2, "msr_unpack(): ppmsr argument cannot be NULL\n");      return MS_GENERROR;    }    /* Verify that record includes a valid header */  if ( ! MS_ISVALIDHEADER(record) )    {      ms_recsrcname (record, srcname, 1);      ms_log (2, "msr_unpack(%s) Record header & quality indicator unrecognized: '%c'\n", srcname);      ms_log (2, "msr_unpack(%s) This is not a valid Mini-SEED record\n", srcname);            return MS_NOTSEED;    }    /* Verify that passed record length is within supported range */  if ( reclen < MINRECLEN || reclen > MAXRECLEN )    {      ms_recsrcname (record, srcname, 1);      ms_log (2, "msr_unpack(%s): Record length is out of range: %d\n", srcname, reclen);      return MS_OUTOFRANGE;    }    /* Initialize the MSRecord */    if ( ! (*ppmsr = msr_init (*ppmsr)) )    return MS_GENERROR;    /* Shortcut pointer, historical and help readability */  msr = *ppmsr;    /* Set raw record pointer and record length */  msr->record = record;  msr->reclen = reclen;    /* Check environment variables if necessary */  if ( unpackheaderbyteorder == -2 ||       unpackdatabyteorder == -2 ||       unpackencodingformat == -2 ||       unpackencodingfallback == -2 )    if ( check_environment(verbose) )      return MS_GENERROR;    /* Allocate and copy fixed section of data header */  msr->fsdh = realloc (msr->fsdh, sizeof (struct fsdh_s));    if ( msr->fsdh == NULL )    {      ms_log (2, "msr_unpack(): Cannot allocate memory\n");      return MS_GENERROR;    }    memcpy (msr->fsdh, record, sizeof (struct fsdh_s));    /* Check to see if byte swapping is needed by testing the year */  if ( (msr->fsdh->start_time.year < 1920) ||       (msr->fsdh->start_time.year > 2020) )    headerswapflag = dataswapflag = 1;    /* Check if byte order is forced */  if ( unpackheaderbyteorder >= 0 )    {      headerswapflag = ( ms_bigendianhost() != unpackheaderbyteorder ) ? 1 : 0;    }    if ( unpackdatabyteorder >= 0 )    {      dataswapflag = ( ms_bigendianhost() != unpackdatabyteorder ) ? 1 : 0;    }    /* Swap byte order? */  if ( headerswapflag )    {      MS_SWAPBTIME (&msr->fsdh->start_time);      ms_gswap2a (&msr->fsdh->numsamples);      ms_gswap2a (&msr->fsdh->samprate_fact);      ms_gswap2a (&msr->fsdh->samprate_mult);      ms_gswap4a (&msr->fsdh->time_correct);      ms_gswap2a (&msr->fsdh->data_offset);      ms_gswap2a (&msr->fsdh->blockette_offset);    }    /* Populate some of the common header fields */  ms_strncpclean (sequence_number, msr->fsdh->sequence_number, 6);  msr->sequence_number = (int32_t) strtol (sequence_number, NULL, 10);  msr->dataquality = msr->fsdh->dataquality;  ms_strncpclean (msr->network, msr->fsdh->network, 2);  ms_strncpclean (msr->station, msr->fsdh->station, 5);  ms_strncpclean (msr->location, msr->fsdh->location, 2);  ms_strncpclean (msr->channel, msr->fsdh->channel, 3);  msr->samplecnt = msr->fsdh->numsamples;    /* Generate source name for MSRecord */  if ( msr_srcname (msr, srcname, 1) == NULL )    {      ms_log (2, "msr_unpack_data(): Cannot generate srcname\n");      return MS_GENERROR;    }    /* Set shared srcname pointer to source name */  UNPACK_SRCNAME = &srcname[0];    /* Report byte swapping status */  if ( verbose > 2 )    {      if ( headerswapflag )	ms_log (1, "%s: Byte swapping needed for unpacking of header\n",		UNPACK_SRCNAME);      else	ms_log (1, "%s: Byte swapping NOT needed for unpacking of header\n",		UNPACK_SRCNAME);    }    /* Traverse the blockettes */  blkt_offset = msr->fsdh->blockette_offset;    while ((blkt_offset != 0) &&	 (blkt_offset < reclen) &&	 (blkt_offset < MAXRECLEN))    {      /* Every blockette has a similar 4 byte header: type and next */      memcpy (&blkt_type, record + blkt_offset, 2);      blkt_offset += 2;      memcpy (&next_blkt, record + blkt_offset, 2);      blkt_offset += 2;            if ( headerswapflag )	{	  ms_gswap2 (&blkt_type);	  ms_gswap2 (&next_blkt);	}            /* Get blockette length */      blkt_length = ms_blktlen (blkt_type,				record + blkt_offset - 4,				headerswapflag);            if ( blkt_length == 0 )	{	  ms_log (2, "msr_unpack(%s): Unknown blockette length for type %d\n",		  UNPACK_SRCNAME, blkt_type);	  break;	}            /* Make sure blockette is contained within the msrecord buffer */      if ( (blkt_offset - 4 + blkt_length) > reclen )	{	  ms_log (2, "msr_unpack(%s): Blockette %d extends beyond record size, truncated?\n",		  UNPACK_SRCNAME, blkt_type);	  break;	}            if ( blkt_type == 100 )	{			/* Found a Blockette 100 */	  struct blkt_100_s *blkt_100;	  	  blkt_link = msr_addblockette (msr, record + blkt_offset,					sizeof (struct blkt_100_s),					blkt_type, 0);	  if ( ! blkt_link )	    break;	  	  blkt_link->next_blkt = next_blkt;	  	  blkt_100 = (struct blkt_100_s *) blkt_link->blktdata;	  	  if ( headerswapflag )	    {	      ms_gswap4 (&blkt_100->samprate);	    }	  	  msr->samprate = msr->Blkt100->samprate;	}      else if ( blkt_type == 200 )	{			/* Found a Blockette 200 */	  struct blkt_200_s *blkt_200;	  	  blkt_link = msr_addblockette (msr, record + blkt_offset,					sizeof (struct blkt_200_s),					blkt_type, 0);	  if ( ! blkt_link )	    break;	  	  blkt_link->next_blkt = next_blkt;	  	  blkt_200 = (struct blkt_200_s *) blkt_link->blktdata;	  	  if ( headerswapflag )	    {	      ms_gswap4 (&blkt_200->amplitude);	      ms_gswap4 (&blkt_200->period);	      ms_gswap4 (&blkt_200->background_estimate);	      MS_SWAPBTIME (&blkt_200->time);	    }	}      else if ( blkt_type == 201 )	{			/* Found a Blockette 201 */	  struct blkt_201_s *blkt_201;	  	  blkt_link = msr_addblockette (msr, record + blkt_offset,					sizeof (struct blkt_201_s),					blkt_type, 0);	  if ( ! blkt_link )	    break;	  	  blkt_link->next_blkt = next_blkt;	  	  blkt_201 = (struct blkt_201_s *) blkt_link->blktdata;	  	  if ( headerswapflag )	    {	      ms_gswap4 (&blkt_201->amplitude);	      ms_gswap4 (&blkt_201->period);	      ms_gswap4 (&blkt_201->background_estimate);	      MS_SWAPBTIME (&blkt_201->time);	    }	}            else if ( blkt_type == 300 )	{			/* Found a Blockette 300 */	  struct blkt_300_s *blkt_300;	  	  blkt_link = msr_addblockette (msr, record + blkt_offset,					sizeof (struct blkt_300_s),					blkt_type, 0);	  if ( ! blkt_link )	    break;	  	  blkt_link->next_blkt = next_blkt;	  	  blkt_300 = (struct blkt_300_s *) blkt_link->blktdata;	  	  if ( headerswapflag )	    {	      MS_SWAPBTIME (&blkt_300->time);	      ms_gswap4 (&blkt_300->step_duration);	      ms_gswap4 (&blkt_300->interval_duration);	      ms_gswap4 (&blkt_300->amplitude);	      ms_gswap4 (&blkt_300->reference_amplitude);	    }	}            else if ( blkt_type == 310 )	{			/* Found a Blockette 310 */	  struct blkt_310_s *blkt_310;	  	  blkt_link = msr_addblockette (msr, record + blkt_offset,					sizeof (struct blkt_310_s),					blkt_type, 0);	  if ( ! blkt_link )	    break;	  	  blkt_link->next_blkt = next_blkt;	  	  blkt_310 = (struct blkt_310_s *) blkt_link->blktdata;	  	  if ( headerswapflag )	    {	      MS_SWAPBTIME (&blkt_310->time);	      ms_gswap4 (&blkt_310->duration);	      ms_gswap4 (&blkt_310->period);	      ms_gswap4 (&blkt_310->amplitude);	      ms_gswap4 (&blkt_310->reference_amplitude);	    }	}            else if ( blkt_type == 320 )	{			/* Found a Blockette 320 */	  struct blkt_320_s *blkt_320;	  	  blkt_link = msr_addblockette (msr, record + blkt_offset,					sizeof (struct blkt_320_s),					blkt_type, 0);	  if ( ! blkt_link )	    break;	  	  blkt_link->next_blkt = next_blkt;	  	  blkt_320 = (struct blkt_320_s *) blkt_link->blktdata;	  	  if ( headerswapflag )	    {	      MS_SWAPBTIME (&blkt_320->time);	      ms_gswap4 (&blkt_320->duration);	      ms_gswap4 (&blkt_320->ptp_amplitude);	      ms_gswap4 (&blkt_320->reference_amplitude);	    }	}      else if ( blkt_type == 390 )	{			/* Found a Blockette 390 */	  struct blkt_390_s *blkt_390;	  	  blkt_link = msr_addblockette (msr, record + blkt_offset,					sizeof (struct blkt_390_s),					blkt_type, 0);	  if ( ! blkt_link )	    break;	  	  blkt_link->next_blkt = next_blkt;	  	  blkt_390 = (struct blkt_390_s *) blkt_link->blktdata;	  	  if ( headerswapflag )	    {	      MS_SWAPBTIME (&blkt_390->time);	      ms_gswap4 (&blkt_390->duration);	      ms_gswap4 (&blkt_390->amplitude);	    }	}      else if ( blkt_type == 395 )	{			/* Found a Blockette 395 */	  struct blkt_395_s *blkt_395;	  	  blkt_link = msr_addblockette (msr, record + blkt_offset,					sizeof (struct blkt_395_s),					blkt_type, 0);	  if ( ! blkt_link )	    break;	  	  blkt_link->next_blkt = next_blkt;	  	  blkt_395 = (struct blkt_395_s *) blkt_link->blktdata;	  	  if ( headerswapflag )	    {	      MS_SWAPBTIME (&blkt_395->time);	    }	}            else if ( blkt_type == 400 )	{			/* Found a Blockette 400 */	  struct blkt_400_s *blkt_400;	  	  blkt_link = msr_addblockette (msr, record + blkt_offset,					sizeof (struct blkt_400_s),					blkt_type, 0);	  if ( ! blkt_link )	    break;	  	  blkt_link->next_blkt = next_blkt;	  	  blkt_400 = (struct blkt_400_s *) blkt_link->blktdata;	  	  if ( headerswapflag )	    {	      ms_gswap4 (&blkt_400->azimuth);	      ms_gswap4 (&blkt_400->slowness);	      ms_gswap2 (&blkt_400->configuration);	    }	}            else if ( blkt_type == 405 )	{			/* Found a Blockette 405 */	  struct blkt_405_s *blkt_405;	  	  blkt_link = msr_addblockette (msr, record + blkt_offset,					sizeof (struct blkt_405_s),					blkt_type, 0);	  if ( ! blkt_link )	    break;	  	  blkt_link->next_blkt = next_blkt;	  	  blkt_405 = (struct blkt_405_s *) blkt_link->blktdata;	  	  if ( headerswapflag )	    {	      ms_gswap2 (&blkt_405->delay_values);	    }	  if ( verbose > 0 )	    {	      ms_log (1, "msr_unpack(%s): WARNING Blockette 405 cannot be fully supported\n",		      UNPACK_SRCNAME);	    }	}            else if ( blkt_type == 500 )	{			/* Found a Blockette 500 */	  struct blkt_500_s *blkt_500;	  	  blkt_link = msr_addblockette (msr, record + blkt_offset,					sizeof (struct blkt_500_s),					blkt_type, 0);	  if ( ! blkt_link )	    break;	  	  blkt_link->next_blkt = next_blkt;	  	  blkt_500 = (struct blkt_500_s *) blkt_link->blktdata;	  	  if ( headerswapflag )	    {	      ms_gswap4 (&blkt_500->vco_correction);	      MS_SWAPBTIME (&blkt_500->time);	      ms_gswap4 (&blkt_500->exception_count);	    }	}            else if ( blkt_type == 1000 )	{			/* Found a Blockette 1000 */	  struct blkt_1000_s *blkt_1000;	  	  blkt_link = msr_addblockette (msr, record + blkt_offset,					sizeof (struct blkt_1000_s),					blkt_type, 0);	  if ( ! blkt_link )	    break;	  	  blkt_link->next_blkt = next_blkt;	  blkt_1000 = (struct blkt_1000_s *) blkt_link->blktdata;	  	  /* Calculate record length in bytes as 2^(blkt_1000->reclen) */	  msr->reclen = (uint32_t) 1 << blkt_1000->reclen;	  	  /* Compare against the specified length */	  if ( msr->reclen != reclen && verbose )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -