📄 steim.c
字号:
/*--------------------------------------------------------------------------*\ Name: encode_steim.c Purpose: translate signed long integers to steim compressed format. Usage: long Steim_comp( float * p_dbuf; DATA_HEADER * p_fsdh; ULONG Number_of_samples ; WORD data_rec_length; LONG * p_seed_data_records; note: HUGE is used for 80x86 based machines to force normalization of pointers. It is #defined null for use on real hardware. Output: An array of data records containing steim compressed data. Externals: char verbose - enables display of processing messages. Called by: main.c, or your favourite program. Calls: memcpy, printf Algorithm: The compressor is implemented as a Deterministic Finite Automaton. A second DFA takes over when the input tape (the raw data) ends. The transition table for the DFA is - note: _f signifies a final state. ---------------------------------------------------------- | # of | | # of | | bytes | | DIFS | | DIF | | to | DIF Current state | fits in | New State | unget | index ---------------+---------+----------------+-------+------- _START_STATE | 1 | _D1 | 0 | 0 _START_STATE | 2 | _D2 | 0 | 0 _START_STATE | 4 | _D4_f | 0 | 0 _D1 | 1 | _D1_D1 | 0 | 1 _D1 | 2 | _D2_D2_f | 0 | 1 _D1 | 4 | _D4_f | 1 | -1 _D2 | 1 | _D2_D2_f | 0 | 1 _D2 | 2 | _D2_D2_f | 0 | 1 _D2 | 4 | _D4_f | 1 | -1 _D1_D1 | 1 | _D1_D1_D1 | 0 | 2 _D1_D1 | 2 | _D2_D2_f | 1 | -1 _D1_D1 | 4 | _D2_D2_f | 1 | -1 _D1_D1_D1 | 1 | _D1_D1_D1_D1_f | 0 | 3 _D1_D1_D1 | 2 | _D2_D2_f | 2 | -1 _D1_D1_D1 | 4 | _D2_D2_f | 2 | -1 ---------------------------------------------------------- Problems: None known. Language: C, ANSI standard. Notes: This program was developed under OS/2 on a harris 80x86 machine. It can be run in DOS or OS/2 large model with HUGE (greater than 1 meg) data segments. To do this use -DHUGE in the cl command line. Author: Guy Stewart, Round Rock TX (512) 244-9081 IRIS Austin TX (512) 471-0405 Revision: 04/26/1991 G. Stewart Initial preliminary release 0.9 05/01/1991 G. Stewart First release of version 1.0 10/15/1992 A. Nance Added parms for data record blockettes primarily blk 100 Parms added: num_cont_blk, num_cont_blk_bytes, cont_blk, num_once_blk, num_once_blk_bytes, once_blk) 04/12/95 CL - added some bug fixes from Neuberger 03/27/97 CL - small bug fix in update_fsdh - fix for leap\*--------------------------------------------------------------------------*/#include <stdio.h>#include <memory.h> /* for memcpy */#include "steim.h"char verbose=0x00 ;#define TRUE 1#define FALSE 0#define _START_STATE 0#define _D1 1#define _D2 2#define _D1_D1 3#define _D1_D1_D1 4#define _D4_f 5#define _D2_D2_f 6#define _D1_D1_D1_D1_f 7/*-------------------------------------------------------------------------*\ _DATA_STATE - structure used to store the state of the current fixed section data header.\*-------------------------------------------------------------------------*/typedef struct _DATA_STATE { int get_new_x0 ; /* set TRUE if new x0 is needed */ LONG unused ; LONG x0, /* forward integration constant (x sub 0) */ xN ; /* reverse integration constant (x sub n) */ LONG w0 ; /* storage for all cks for a frame */ ULONG num_data_rec ; ULONG data_rec_length ; ULONG seed_frame ; ULONG seed_index ; ULONG record_offset ; int frames_per_record ; double sample_rate ; double left_over ; ULONG num_cont_blk; ULONG num_cont_blk_bytes; char *cont_blk; ULONG num_once_blk; ULONG num_once_blk_bytes; char *once_blk; } DATA_STATE ;int final[] = { 0, 0, 0, 0, 0, 1, 1, 1 } ;typedef struct _TRANSITION { int new_state ; int unget ; int dif_index ; } TRANSITION ;TRANSITION transition[] = { _D1 , 0, 0, _D2 , 0, 0, _D4_f , 0, 0, _D1_D1 , 0, 1, _D2_D2_f , 0, 1, _D4_f , 1, -1, _D2_D2_f , 0, 1, _D2_D2_f , 0, 1, _D4_f , 1, -1, _D1_D1_D1 , 0, 2, _D2_D2_f , 1, -1, _D2_D2_f , 1, -1, _D1_D1_D1_D1_f , 0, 3, _D2_D2_f , 2, -1, _D2_D2_f , 2, -1 } ;/*-------------------------------------------------------------------------*\ DISPLAY HEADER for debugging and profiling\*-------------------------------------------------------------------------*/void display_header( p_fsdh )DATA_HEADER * p_fsdh; { printf("-------------------------------------------\n"); printf("- SequenceNumber[6] %6.6s \n", p_fsdh->SequenceNumber ); printf("- Data_header_indicator %c \n", p_fsdh->Data_header_indicator ); printf("- Reserved_bytes_A %c \n", p_fsdh->Reserved_bytes_A ); printf("- Station_identifier_code[5] %5.5s \n", p_fsdh->Station_identifier_code ); printf("- Location_identifier[2] %2.2s \n", p_fsdh->Location_identifier ); printf("- Channel_identifier[3] %3.3s \n", p_fsdh->Channel_identifier ); printf("- Reserved_bytes_B[2] %2.2s \n", p_fsdh->Reserved_bytes_B ); printf("- Record_start_time\n" ) ; printf(" - year: %hu\n", p_fsdh->Record_start_time.year ); printf(" - day: %hu\n", p_fsdh->Record_start_time.day ); printf(" - hours: %hu\n", (short) p_fsdh->Record_start_time.hours ); printf(" - minutes: %hu\n", (short) p_fsdh->Record_start_time.minutes ); printf(" - seconds: %hu\n", (short) p_fsdh->Record_start_time.seconds ); printf(" - 1/10,000 seconds: %hu\n", p_fsdh->Record_start_time.frac_secs ); printf("- Number_of_samples %hu \n", p_fsdh->Number_of_samples ); printf("- Sample_rate_factor %hd \n", p_fsdh->Sample_rate_factor ); printf("- Sample_rate_multiplier %hd \n", p_fsdh->Sample_rate_multiplier ); printf("- Activity_flags %c \n", p_fsdh->Activity_flags ); printf("- IO_flags %c \n", p_fsdh->IO_flags ); printf("- Data_quality_flags %c \n", p_fsdh->Data_quality_flags ); printf("- Number_of_blockettes_follow %c \n", p_fsdh->Number_of_blockettes_follow ); printf("- Time_correction %ld \n", p_fsdh->Time_correction ); printf("- Beginning_of_data %hd \n", p_fsdh->Beginning_of_data ); printf("- First_blockette %hd \n", p_fsdh->First_blockette ); }/*-------------------------------------------------------------------------*\ STATISTICS function for debugging profiling\*-------------------------------------------------------------------------*/statistics( stat, tossed, Number_of_samples )ULONG stat[4] ;ULONG tossed ;ULONG Number_of_samples ; { ULONG total_bytes ; printf("-------------------------------------------\n"); printf("# of 4:1 = %lu\n", stat[1]); printf("# of 2:1 = %lu\n", stat[2]); printf("# of 1:1 = %lu\n", stat[3]); total_bytes = (stat[1] + stat[2] + stat[3]) * 4 ; printf(" total bytes = %lu\n", total_bytes ) ; printf("total deltas = %lu\n", stat[1]*4 + stat[2]*2 + stat[3]) ; printf("* comp ratio = %f : 1.0\n", (double)((double)Number_of_samples)/((double)total_bytes/4) ) ; printf("Slots tossed = %lu\n", tossed ) ; printf(" Ideal ratio = %f : 1.0\n", (double)((double)Number_of_samples)/((double)(total_bytes-tossed/4)/4) ) ; printf("\n\n* ratio does not include space used by headers, codes or\n"); printf( " integration constants\n"); }/*-------------------------------------------------------------------------*\ EVAL_RATE Compute the Sample rate in SPS (Samples Per Seconds\*-------------------------------------------------------------------------*/double eval_rate(Sample_rate_factor, Sample_rate_multiplier )WORD Sample_rate_factor ;WORD Sample_rate_multiplier ; { if ((Sample_rate_factor > 0) && (Sample_rate_multiplier > 0)) { return (double)Sample_rate_factor * (double)Sample_rate_multiplier ; } else if ((Sample_rate_factor > 0) && (Sample_rate_multiplier < 0)) { return (double)-Sample_rate_factor / (double)Sample_rate_multiplier ; } else if ((Sample_rate_factor < 0) && (Sample_rate_multiplier > 0)) { return (double)-Sample_rate_multiplier / (double)Sample_rate_factor ; } else if ((Sample_rate_factor < 0) && (Sample_rate_multiplier < 0)) { return (double)Sample_rate_multiplier / (double)Sample_rate_factor ; } }/*-------------------------------------------------------------------------*\ UPDATE FSDH TIME - compute ending time of data block using info in the fsdh header.\*-------------------------------------------------------------------------*/void update_fsdh_time( p_fsdh, ds )DATA_HEADER * p_fsdh ;DATA_STATE * ds ; { LONG delta_secs, delta_frac_secs ; ULONG delta; double delta_time ; /* change in time in 0.0001 seconds */ /*-----------------------------------------------------------*\ Setup delta time in seconds & fraction of seconds \*-----------------------------------------------------------*/ delta_time = ((double)p_fsdh->Number_of_samples*10000.0 / ds->sample_rate) + ds->left_over; delta = (ULONG) delta_time; ds->left_over = delta_time - (double)delta; delta_secs = (ULONG)delta_time/10000 ; delta_frac_secs = (LONG) (delta_time-((double)delta_secs*10000.0)) ; /*-----------------------------------------------------------*\ bubble delta_time through btime structure assigning times to Record start times. \*-----------------------------------------------------------*/ delta_frac_secs += p_fsdh->Record_start_time.frac_secs ; p_fsdh->Record_start_time.frac_secs = delta_frac_secs % 10000 ; delta_secs += (delta_frac_secs - p_fsdh->Record_start_time.frac_secs)/10000 ; delta_secs += p_fsdh->Record_start_time.seconds ; p_fsdh->Record_start_time.seconds = delta_secs % 60 ; delta_secs = p_fsdh->Record_start_time.minutes + delta_secs / 60 ; p_fsdh->Record_start_time.minutes = delta_secs % 60 ; delta_secs = p_fsdh->Record_start_time.hours + delta_secs / 60 ; p_fsdh->Record_start_time.hours = delta_secs % 24 ; delta_secs = p_fsdh->Record_start_time.day + delta_secs / 24 ; p_fsdh->Record_start_time.day = delta_secs % 367 ; }/*-------------------------------------------------------------------------*\ FINISH_RECORD - fill in the record fixed section data header.\*-------------------------------------------------------------------------*/finish_record( fp, p_seed_data_records, p_fsdh, ds )FILE *fp;int *p_seed_data_records;DATA_HEADER * p_fsdh ;DATA_STATE * ds ;{ char tmp[10]; /* copy record header */ if (verbose) { display_header(p_fsdh); } p_seed_data_records[ds->record_offset+1] = ds->x0 ; p_seed_data_records[ds->record_offset+2] = ds->xN ; ds->get_new_x0 = TRUE ; sprintf(tmp, "%06d", ds->num_data_rec + 1); memcpy(p_fsdh->SequenceNumber, tmp, strlen(tmp)); memcpy((char *)p_seed_data_records, (char *)p_fsdh, sizeof(DATA_HEADER)); memcpy((char *)p_seed_data_records+p_fsdh->First_blockette, (char *)ds->cont_blk, ds->num_cont_blk_bytes); /*-----------------------------------------------------------*\ Write data record ... \*-----------------------------------------------------------*/ if (fwrite (p_seed_data_records, ds->data_rec_length, 1, fp) != 1) { fprintf (stderr, "\tWARNING (output_steim): "); fprintf (stderr, "failed to properly write STEIM data to output file.\n"); fprintf (stderr, "\tExecution continuing.\n"); return(-1); } /*-----------------------------------------------------------*\ Set up _DATA_STATE for next record ... \*-----------------------------------------------------------*/ ds->num_data_rec++; /* start first frame of next record */ ds->seed_frame = 0; ds->seed_index = 3; /* leave room for w0, x0, xN */ ds->w0 = 0 ; /*-----------------------------------------------------------*\ Set up FSDH for next record ... \*-----------------------------------------------------------*/ update_fsdh_time(p_fsdh, ds ); p_fsdh->Number_of_samples = 0 ;#if 0 p_fsdh->Number_of_blockettes_follow = ds->num_cont_blk; if (ds->num_cont_blk) p_fsdh->First_blockette = 48 ; else p_fsdh->First_blockette = 0 ; p_fsdh->Beginning_of_data = 128; /* 64*ds->seed_frame; */#endif return(0);}/*-------------------------------------------------------------------------*\ ADD_WORD - append a compressed word to the data record.\*-------------------------------------------------------------------------*/Add_word(fp, p_seed_data_records, p_fsdh, wk, ck, ds )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -