/* Read ptrdicturation from a stream. */ void ptrdict_from_stream(section_t *root, FILE *f) { /* Note: We might want to switch to XML, i.e., using libXML2 eventually. This will make this stuff a lot easier, too. */ parser_t p; section_t *s; char keyword[MAX_KEYWORD+1]; char token[MAX_TOKEN+1]; char value[MAX_VALUE+1]; BOOL is_token; p.column = 1; p.row = 1; p.f = f; /* First line needs to be section with the name of the root section. */ read_next_keyword(&p, keyword, MAX_KEYWORD, &is_token); if (!strcmp(keyword, "section")) { /* Okay, it's the long format. */ read_next_value(&p, value, MAX_VALUE); if (strcmp(value, root->name)) { printf("[ptrdict_read] Error: Expected '%s' as the name of the first section in line %i.\n", root->name, p.row); exit(1); } ptrdict_lf_read_section(root, &p); } else if (!strcmp(keyword, root->name)) { /* Okay, it's the short format. */ read_next_token(&p, token, MAX_TOKEN); if (strcmp(token, "{")) { printf("[ptrdict_read] '{' expected in line %i.\n", p.row); exit(1); } ptrdict_sf_read_section(root, &p); } else { printf("[ptrdict_read] Error: Keyword 'section' or '%s' expected in line %i.\n", root->name, p.row); exit(1); } }
E_LOAD_RESULT load_pbm( image_t* img, void* file, const image_io_t* io ) { char buffer[ 40 ], pbm_format; size_t width, height, i, j, size; int val, max_val=0xFF; unsigned char* ptr; float scale=1.0f; /* read format identifyer */ io->read( buffer, 1, 3, file ); if( buffer[0]!='P' || buffer[1]<'1' || buffer[1]>'6' ) return ELR_FILE_CORRUPTED; if( !isspace( buffer[2] ) ) return ELR_FILE_CORRUPTED; /* save the format specifyer from the file */ pbm_format = buffer[1]; /* read image size */ read_next_value( file, io, buffer, sizeof(buffer) ); width = strtol( buffer, NULL, 10 ); read_next_value( file, io, buffer, sizeof(buffer) ); height = strtol( buffer, NULL, 10 ); /* read maximum color value if required */ if( pbm_format!='1' && pbm_format!='4' ) { read_next_value( file, io, buffer, sizeof(buffer) ); max_val = strtol( buffer, NULL, 10 ); /* BPM spec says, must be in [1,65535] range */ if( max_val<1 || max_val>65535 ) return ELR_FILE_CORRUPTED; /* compute scale factor for [0,255] range */ scale = 255.0f/((float)max_val); } /* Allocate the image buffer */ image_allocate_buffer( img, width, height, (pbm_format=='3' || pbm_format=='6') ? ECT_RGB8 : ECT_GRAYSCALE8 ); /* P1, P2 and P3 are ascii formats, P4, P5 and P6 are binary P1 and P4 are bitmap, P2 and P5 are grayscale, P3 and P6 are RGB */ ptr = img->image_buffer; size = width*height; if( pbm_format == '1' ) { for( j=0; j<size; ++j ) { read_next_value( file, io, buffer, sizeof(buffer) ); *(ptr++) = buffer[0]=='1' ? 255 : 0; } } else if( pbm_format == '2' ) { for( j=0; j<size; ++j ) { read_next_value( file, io, buffer, sizeof(buffer) ); val = strtol( buffer, NULL, 10 ); *(ptr++) = val * scale; } } else if( pbm_format == '3' ) { for( j=0; j<size; ++j ) { /* red */ read_next_value( file, io, buffer, sizeof(buffer) ); val = strtol( buffer, NULL, 10 ); *(ptr++) = val * scale; /* green */ read_next_value( file, io, buffer, sizeof(buffer) ); val = strtol( buffer, NULL, 10 ); *(ptr++) = val * scale; /* blue */ read_next_value( file, io, buffer, sizeof(buffer) ); val = strtol( buffer, NULL, 10 ); *(ptr++) = val * scale; } } else if( pbm_format == '4' ) { for( j=0; j<size; ++j ) { io->read( buffer, 1, 1, file ); /* decode bits */ for( i=0; i<8 && j<size; ++i, ++j ) { *(ptr++) = (buffer[0] & (1<<(7-i))) ? 255 : 0; } } } else if( pbm_format == '5' ) { if( max_val>255 ) { for( j=0; j<size; ++j ) { io->read( buffer, 1, 2, file ); val = READ_BIG_ENDIAN_16( buffer, 0 ); *(ptr++) = val * scale; } } else { io->read( ptr, 1, size, file ); for( j=0; j<size; ++j ) { *(ptr++) *= scale; } } } else if( pbm_format == '6' ) { if( max_val>255 ) { for( j=0; j<size; ++j ) { /* red */ io->read( buffer, 1, 2, file ); val = READ_BIG_ENDIAN_16( buffer, 0 ); *(ptr++) = val * scale; /* green */ io->read( buffer, 1, 2, file ); val = READ_BIG_ENDIAN_16( buffer, 0 ); *(ptr++) = val * scale; /* blue */ io->read( buffer, 1, 2, file ); val = READ_BIG_ENDIAN_16( buffer, 0 ); *(ptr++) = val * scale; } } else { io->read( ptr, 1, size*3, file ); for( j=0; j<size; ++j ) { *(ptr++) *= scale; /* red */ *(ptr++) *= scale; /* green */ *(ptr++) *= scale; /* blue */ } } } return ELR_SUCESS; }
/*************************************************************************** * collect_and_write: * * Attempt to connect to a device, slows down the loop checking * after 20 attempts with a larger delay to reduce pointless * work being done. * * Returns 0 on success and -1 otherwise. ***************************************************************************/ int collect_and_write() { int32_t idata[2000]; // enough space for data of 2 records hptime_t hptime; hptime_t start_hptime_est = 0; hptime_t last_hptime; DOUBLE dt, dt_est, sample_rate_est; DOUBLE start_hptime_current, record_window_current, record_window_est; DOUBLE prev_start_hptime_est = -1; int n_start_hptime_est; // debug hptime_t start_hptime_nominal = 0; hptime_t prev_start_next_hptime_est = 0; double diff_end, diff_end_cumul = 0.0; char seedtimestr[64]; // decay constant depends on required decay time and sample rate //double decay_minutes = 60.0; // 1 hour double decay_minutes = 1.0; double decay_consant = 1.0 / (decay_minutes * 60.0 * (double) nominal_sample_rate); // initialize last_hptime to current time last_hptime = current_utc_hptime(); // initialize dt_est based on nominal sample rate dt_est = (nominal_sample_rate == 80) ? 1.0 / SAMP_PER_SEC_80 : (nominal_sample_rate == 40) ? 1.0 / SAMP_PER_SEC_40 : 1.0 / SAMP_PER_SEC_20; // ‘a’: 20.032 SPS // ‘b’: 39.860 SPS // ‘c’: 79.719 SPS // initialize record_window_est based on nominal sample rate and record length record_window_est = dt_est * num_samples_in_record; if (DEBUG) { logprintf(MSG_FLAG, "Initialize: last_hptime=%lld, dt_est=%lld, dt=%lf, dt_end=%lf, dt_end_cumul=%lf)\n", last_hptime, dt_est, record_window_est); } int first = 1; MSRecord *pmsrecord = msr_init(NULL); strcpy(pmsrecord->network, station_network); strcpy(pmsrecord->station, station_name); strcpy(pmsrecord->location, ""); sprintf(pmsrecord->channel, "%s%s", channel_prefix, component); pmsrecord->samprate = 1.0; pmsrecord->reclen = SLRECSIZE; pmsrecord->encoding = mswrite_data_encoding_type_code; pmsrecord->byteorder = 1; pmsrecord->datasamples = idata; pmsrecord->numsamples = 0; pmsrecord->sampletype = 'i'; while (1) { // load data up to SLRECSIZE long ivalue; int nsamp = 0; start_hptime_current = 0; n_start_hptime_est = 0; while (nsamp < num_samples_in_record) { ivalue = read_next_value(&hptime, TIMEOUT_LARGE); if (ivalue == READ_ERROR || ivalue < MIN_DATA || ivalue > MAX_DATA) { logprintf(MSG_FLAG, "READ_ERROR: port=%s, nsamp=%d, ivalue=%ld\n", port_path, nsamp, ivalue); pmsrecord->datasamples = NULL; msr_free(&pmsrecord); return (-1); } if (DEBUG && nsamp == 0) { start_hptime_nominal = hptime; } idata[pmsrecord->numsamples + nsamp] = (int32_t) ivalue; dt = (DOUBLE) (hptime - last_hptime) / (DOUBLE) HPTMODULUS; last_hptime = hptime; if (verbose > 3) { logprintf(MSG_FLAG, "%d %ld %s (dt=%lf)\n", nsamp, ivalue, ms_hptime2seedtimestr(hptime, seedtimestr, 1), (double) dt); } // estimate start time and dt // use only later samples in record since writing previous record may delay reading of first samples of this record if (nsamp >= num_samples_in_record / 2) { // 20131107 AJL - use all samples, may give better start time estimate, since buffering should compensate for any delay of first samples //if (1) { // start time estimate is timestamp of current data minus dt_est*nsamp start_hptime_current += (hptime - (hptime_t) ((DOUBLE) 0.5 + dt_est * (DOUBLE) HPTMODULUS * (DOUBLE) nsamp)); n_start_hptime_est++; // accumulate dt_est using low-pass filter //dt_est = dt_est + (DOUBLE) decay_consant * (dt - dt_est); } nsamp++; } start_hptime_current /= n_start_hptime_est; if (prev_start_hptime_est > 0) { record_window_current = (DOUBLE) (start_hptime_current - prev_start_hptime_est) / (DOUBLE) HPTMODULUS; } else { record_window_current = record_window_est; } // accumulate record_window_est using low-pass filter record_window_est = record_window_est + (DOUBLE) decay_consant * (record_window_current - record_window_est); if (prev_start_hptime_est > 0) { start_hptime_est = prev_start_hptime_est + (hptime_t) ((DOUBLE) 0.5 + record_window_est * (DOUBLE) HPTMODULUS); } else { start_hptime_est = start_hptime_current; } prev_start_hptime_est = start_hptime_est; // test - truncate dt to 1/10000 s to match precision of miniseed btime //logprintf(MSG_FLAG, "0 sample_rate_est=%lf (dt=%lfs)\n", (double) ((DOUBLE) 1.0 / dt_est), (double) dt_est); dt_est = record_window_est / (DOUBLE) num_samples_in_record; sample_rate_est = (DOUBLE) 1.0 / dt_est; if (DEBUG) { diff_end = (double) (start_hptime_est - prev_start_next_hptime_est) / (double) HPTMODULUS; if (!first) diff_end_cumul += diff_end; logprintf(MSG_FLAG, "sample_rate_est=%lf (dt=%lfs)\n", (double) sample_rate_est, (double) dt_est); logprintf(MSG_FLAG, "start_hptime_est=%lld, start_hptime_nominal=%lld, dt=%lf, dt_end=%lf, dt_end_cumul=%lf)\n", start_hptime_est, start_hptime_nominal, (double) ((DOUBLE) (start_hptime_est - start_hptime_nominal) / (DOUBLE) HPTMODULUS), diff_end, diff_end_cumul); prev_start_next_hptime_est = start_hptime_est + (hptime_t) ((DOUBLE) 0.5 + dt_est * (DOUBLE) HPTMODULUS * (DOUBLE) nsamp); } pmsrecord->starttime = start_hptime_est - (DOUBLE) HPTMODULUS * pmsrecord->numsamples / pmsrecord->samprate; pmsrecord->samprate = mswrite_header_sample_rate > 0.0 ? mswrite_header_sample_rate : sample_rate_est; pmsrecord->numsamples += nsamp; int64_t npackedsamples = 0; if (msr_pack(pmsrecord, record_handler, NULL, &npackedsamples, 0, verbose) < 0) { logprintf(ERROR_FLAG, "Error encoding data!\n"); exit(1); } pmsrecord->numsamples -= npackedsamples; memmove(&idata[0], &idata[npackedsamples], pmsrecord->numsamples * 4); } return (0); }
/* Read the current section until 'endsection' is reached. */ void ptrdict_lf_read_section(section_t *self, parser_t *parser) { BOOL section_done = FALSE; section_t *s; property_t *p; char keyword[MAX_KEYWORD+1]; char value[MAX_VALUE+1]; char token[MAX_TOKEN+1]; BOOL is_token; self->provided = TRUE; if (self->provided_notification) *self->provided_notification = TRUE; while (!section_done && !at_end_of_file(parser)) { read_next_keyword(parser, keyword, MAX_KEYWORD, &is_token); if (is_token) { printf("[ptrdict_lf_read_section] Keyword expected in line %i.\n", parser->row); exit(1); } if (!strcmp(keyword, "endsection")) { read_next_value(parser, value, MAX_VALUE); if (strcmp(value, self->name)) { printf("[ptrdict_lf_read_section] Current open section is '%s', cannot close section '%s' in line %i.\n", self->name, value, parser->row); exit(1); } if (self->kind != SK_SECTION) { printf("[ptrdict_lf_read_section] Current open object '%s' is not a section (line %i).\n", self->name, parser->row); exit(1); } finish_line(parser); section_done = TRUE; } else if (!strcmp(keyword, "endmodule")) { read_next_value(parser, value, MAX_VALUE); if (strcmp(value, self->name)) { printf("[ptrdict_lf_read_section] Current open module is '%s', cannot close module '%s' in line %i.\n", self->name, value, parser->row); exit(1); } if (self->kind != SK_MODULE) { printf("[ptrdict_lf_read_section] Current open object '%s' is not a section (line %i).\n", self->name, parser->row); exit(1); } finish_line(parser); section_done = TRUE; } else if (!strcmp(keyword, "section")) { read_next_value(parser, value, MAX_VALUE); finish_line(parser); s = ptrdict_find_section(self, value); if (!s) { printf("[ptrdict_lf_read_section] Unknown section '%s' in line %i.\n", value, parser->row); ptrdict_enum_subsections(self, stdout); exit(1); } else if (s->kind == SK_MODULE) { printf("[ptrdict_lf_read_section] '%s' is a module identifier (line %i).\n", value, parser->row); exit(1); } ptrdict_lf_read_section(s, parser); } else if (!strcmp(keyword, "module")) { read_next_value(parser, value, MAX_VALUE); finish_line(parser); s = ptrdict_find_section(self, value); if (!s) { printf("[ptrdict_lf_read_section] Unknown section '%s' in line %i.\n", value, parser->row); ptrdict_enum_subsections(self, stdout); exit(1); } else if (s->kind == SK_SECTION) { printf("[ptrdict_lf_read_section] '%s' is a section identifier (line %i).\n", value, parser->row); exit(1); } ptrdict_lf_read_section(s, parser); } else { p = ptrdict_find_property(self, keyword); if (!p) { printf("[ptrdict_lf_read_section] Unknown keyword '%s' in line %i.\n" "Possibilities are 'section', 'module' or one of the properties of section '%s', which are:\n", keyword, parser->row, self->name); ptrdict_enum_properties(self, stdout); exit(1); } read_next_token(parser, token, MAX_TOKEN); if (strcmp(token, "=")) { printf("[ptrdict_lf_read_section] '=' expected for assignment of property '%s' in line %i.\n", keyword, parser->row); exit(1); } read_next_value(parser, value, MAX_VALUE); finish_line(parser); ptrdict_set_property(p, value); } } if (!section_done) { printf("[ptrdict_lf_read_section] Error: End-of-file reached, but keyword 'endsection' is missing (line %i).\n", parser->row); exit(1); } }
/* Read the current section until 'endsection' is reached. */ void ptrdict_sf_read_section(section_t *self, parser_t *parser) { BOOL section_done = FALSE; section_t *s; property_t *p; char keyword[MAX_KEYWORD+1]; char value[MAX_VALUE+1]; char token[MAX_TOKEN+1]; BOOL is_token; self->provided = TRUE; if (self->provided_notification) *self->provided_notification = TRUE; while (!section_done && !at_end_of_file(parser)) { read_next_keyword(parser, keyword, MAX_KEYWORD, &is_token); if (is_token) strcpy(token, keyword); else read_next_token(parser, token, MAX_TOKEN); if (!strcmp(token, "};")) { section_done = TRUE; } else if (!strcmp(token, "}")) { read_next_token(parser, token, MAX_TOKEN); if (strcmp(token, ";")) { printf("[ptrdict_sf_read_section] ';' expected in line %i.\n", parser->row); exit(1); } section_done = TRUE; } else if (!strcmp(token, "{};")) { /* This is an empty module. */ s = ptrdict_find_section(self, keyword); if (!s) { printf("[ptrdict_sf_read_section] Unknown section '%s' in line %i.\n", keyword, parser->row); ptrdict_enum_subsections(self, stdout); exit(1); } if (s->kind != SK_MODULE) { printf("[ptrdict_sf_read_section] Module expected, but section encountered in line %i.", parser->row); exit(1); } s->provided = TRUE; if (s->provided_notification) *s->provided_notification = TRUE; } else if (!strcmp(token, "{")) { /* We have a section or module */ s = ptrdict_find_section(self, keyword); if (!s) { printf("[ptrdict_sf_read_section] Unknown section '%s' in line %i.\n", keyword, parser->row); ptrdict_enum_subsections(self, stdout); exit(1); } ptrdict_sf_read_section(s, parser); } else if (!strcmp(token, "=")) { p = ptrdict_find_property(self, keyword); if (!p) { printf("[ptrdict_sf_read_section] Unknown property '%s' of section '%s' in line %i.\n" "Possibilities are:\n", keyword, self->name, parser->row); ptrdict_enum_properties(self, stdout); exit(1); } read_next_value(parser, value, MAX_VALUE); ptrdict_set_property(p, value); read_next_token(parser, token, MAX_TOKEN); if (strcmp(token, ";")) { printf("[ptrdict_sf_read_section] ';' expected in line %i.\n", parser->row); exit(1); } } else { printf("[ptrdict_sf_read_section] Syntax error in line %i. Token = '%s'\n", parser->row, token); exit(1); } } if (!section_done) { printf("[ptrdict_sf_read_section] Error: End-of-file reached, but file is incomplete."); exit(1); } }