/* This subroutine encapsulates the coding of the different event codes * into a unified signed code */ LOCAL void read_synamps_push_keys(transform_info_ptr tinfo, long position, int TrigVal, int KeyPad, int KeyBoard, enum NEUROSCAN_ACCEPTVALUES Accept) { struct read_synamps_storage * const local_arg=(struct read_synamps_storage *)tinfo->methods->local_storage; int code; if (Accept!=0 && (Accept<NAV_DCRESET || Accept>NAV_STARTSTOP)) { TRACEMS2(tinfo->emethods, 0, "read_synamps_push_keys: Unknown Accept value %d at position %d!\n", MSGPARM(Accept), MSGPARM(position)); return; } code=TrigVal-KeyPad+neuroscan_accept_translation[Accept]; if (code==0) { /* At least in Edit 4.x, KeyPad F2 is written as KeyBoard=0 with everything else 0 too... */ code= -(((KeyBoard&0xf)+1)<<4); } if (code==0) { TRACEMS1(tinfo->emethods, 0, "read_synamps_push_keys: Trigger with trigcode 0 at position %d!\n", MSGPARM(position)); } else { push_trigger(&local_arg->triggers, position, code, NULL); } }
/*{{{ trim(transform_info_ptr tinfo) {*/ METHODDEF DATATYPE * trim(transform_info_ptr tinfo) { struct trim_storage *local_arg=(struct trim_storage *)tinfo->methods->local_storage; transform_argument *args=tinfo->methods->arguments; int item, shift, nrofshifts=1; long nr_of_input_ranges,nr_of_ranges; long output_points; long rangeno, current_output_point=0; const Bool collapse=args[ARGS_COLLAPSE].is_set || args[ARGS_COLLAPSE_Q].is_set; const DATATYPE collapse_quantile=(args[ARGS_COLLAPSE].is_set&&args[ARGS_COLLAPSE].arg.i==COLLAPSE_BY_MEDIAN ? 0.5 : (args[ARGS_COLLAPSE_Q].is_set ? args[ARGS_COLLAPSE_Q].arg.d/100.0 : 0.0)); array myarray, newarray; DATATYPE *oldtsdata; DATATYPE *new_xdata=NULL; growing_buf ranges, tokenbuf; growing_buf triggers; growing_buf_init(&ranges); growing_buf_init(&tokenbuf); growing_buf_init(&triggers); if (tinfo->data_type==FREQ_DATA) { tinfo->nr_of_points=tinfo->nroffreq; nrofshifts=tinfo->nrofshifts; } /*{{{ Parse the ranges argument */ nr_of_input_ranges=growing_buf_count_tokens(&local_arg->rangearg); if (nr_of_input_ranges<=0 || nr_of_input_ranges%2!=0) { ERREXIT(tinfo->emethods, "trim: Need an even number of arguments >=2\n"); } nr_of_input_ranges/=2; output_points=0; growing_buf_allocate(&ranges, 0); growing_buf_allocate(&tokenbuf, 0); growing_buf_get_firsttoken(&local_arg->rangearg,&tokenbuf); while (tokenbuf.current_length>0) { struct range thisrange; if (args[ARGS_USE_CHANNEL].is_set) { int const channel=find_channel_number(tinfo,args[ARGS_USE_CHANNEL].arg.s); if (channel>=0) { DATATYPE const minval=get_value(tokenbuf.buffer_start, NULL); growing_buf_get_nexttoken(&local_arg->rangearg,&tokenbuf); DATATYPE const maxval=get_value(tokenbuf.buffer_start, NULL); array indata; tinfo_array(tinfo, &indata); indata.current_vector=channel; thisrange.offset= -1; /* Marks no start recorded yet */ do { DATATYPE const currval=indata.read_element(&indata); if (currval>=minval && currval<=maxval) { if (thisrange.offset== -1) { thisrange.offset=indata.current_element; thisrange.length= 1; } else { thisrange.length++; } } else { if (thisrange.offset!= -1) { growing_buf_append(&ranges, (char *)&thisrange, sizeof(struct range)); output_points+=(collapse ? 1 : thisrange.length); thisrange.offset= -1; } } array_advance(&indata); } while (indata.message==ARRAY_CONTINUE); if (thisrange.offset!= -1) { growing_buf_append(&ranges, (char *)&thisrange, sizeof(struct range)); output_points+=(collapse ? 1 : thisrange.length); } } else { ERREXIT1(tinfo->emethods, "set xdata_from_channel: Unknown channel name >%s<\n", MSGPARM(args[ARGS_USE_CHANNEL].arg.s)); } } else { if (args[ARGS_USE_XVALUES].is_set) { if (tinfo->xdata==NULL) create_xaxis(tinfo, NULL); thisrange.offset=decode_xpoint(tinfo, tokenbuf.buffer_start); growing_buf_get_nexttoken(&local_arg->rangearg,&tokenbuf); thisrange.length=decode_xpoint(tinfo, tokenbuf.buffer_start)-thisrange.offset+1; } else { thisrange.offset=gettimeslice(tinfo, tokenbuf.buffer_start); growing_buf_get_nexttoken(&local_arg->rangearg,&tokenbuf); thisrange.length=gettimeslice(tinfo, tokenbuf.buffer_start); if (thisrange.length==0) { thisrange.length=tinfo->nr_of_points-thisrange.offset; } } if (thisrange.length<=0) { ERREXIT1(tinfo->emethods, "trim: length is %d but must be >0.\n", MSGPARM(thisrange.length)); } growing_buf_append(&ranges, (char *)&thisrange, sizeof(struct range)); output_points+=(collapse ? 1 : thisrange.length); } growing_buf_get_nexttoken(&local_arg->rangearg,&tokenbuf); } /*}}} */ nr_of_ranges=ranges.current_length/sizeof(struct range); if (nr_of_ranges==0) { TRACEMS(tinfo->emethods, 0, "trim: No valid ranges selected, rejecting epoch.\n"); return NULL; } TRACEMS2(tinfo->emethods, 1, "trim: nr_of_ranges=%ld, output_points=%ld\n", MSGPARM(nr_of_ranges), MSGPARM(output_points)); newarray.nr_of_vectors=tinfo->nr_of_channels*nrofshifts; newarray.nr_of_elements=output_points; newarray.element_skip=tinfo->itemsize; if (array_allocate(&newarray)==NULL) { ERREXIT(tinfo->emethods, "trim: Error allocating memory.\n"); } oldtsdata=tinfo->tsdata; if (tinfo->xdata!=NULL) { /* Store xchannelname at the end of xdata, as in create_xaxis(); otherwise we'll have * a problem after free()'ing xdata... */ new_xdata=(DATATYPE *)malloc(output_points*sizeof(DATATYPE)+strlen(tinfo->xchannelname)+1); if (new_xdata==NULL) { ERREXIT(tinfo->emethods, "trim: Error allocating xdata memory.\n"); } } if (tinfo->triggers.buffer_start!=NULL) { struct trigger trig= *(struct trigger *)tinfo->triggers.buffer_start; growing_buf_allocate(&triggers, 0); /* Record the file position... */ if (collapse) { /* Make triggers in subsequent append() work as expected at least with * continuous reading */ trig.position=local_arg->current_epoch*nr_of_ranges; trig.code= -1; } growing_buf_append(&triggers, (char *)&trig, sizeof(struct trigger)); } for (rangeno=0; rangeno<nr_of_ranges; rangeno++) { struct range *rangep=((struct range *)(ranges.buffer_start))+rangeno; long const old_startpoint=(rangep->offset>0 ? rangep->offset : 0); long const new_startpoint=(rangep->offset<0 ? -rangep->offset : 0); /*{{{ Transfer the data*/ if (old_startpoint<tinfo->nr_of_points /* Skip this explicitly if no "real" point needs copying (length confined within negative offset) * since otherwise an endless loop can result as the stop conditions below look at the array * states and no array is touched... */ && new_startpoint<rangep->length) for (item=0; item<tinfo->itemsize; item++) { array_use_item(&newarray, item); for (shift=0; shift<nrofshifts; shift++) { tinfo_array(tinfo, &myarray); array_use_item(&myarray, item); do { DATATYPE sum=0.0; long reached_length=new_startpoint; myarray.current_element= old_startpoint; if (collapse) { newarray.current_element=current_output_point; newarray.message=ARRAY_CONTINUE; /* Otherwise the loop below may finish promptly... */ if (args[ARGS_COLLAPSE].is_set) switch (args[ARGS_COLLAPSE].arg.i) { case COLLAPSE_BY_HIGHEST: sum= -FLT_MAX; break; case COLLAPSE_BY_LOWEST: sum= FLT_MAX; break; default: break; } } else { newarray.current_element=current_output_point+new_startpoint; } if (collapse && collapse_quantile>0.0) { array helparray=myarray; helparray.ringstart=ARRAY_ELEMENT(&myarray); helparray.current_element=helparray.current_vector=0; helparray.nr_of_vectors=1; helparray.nr_of_elements=rangep->length; sum=array_quantile(&helparray,collapse_quantile); myarray.message=ARRAY_CONTINUE; } else do { if (reached_length>=rangep->length) break; if (args[ARGS_COLLAPSE].is_set) { DATATYPE const hold=array_scan(&myarray); switch (args[ARGS_COLLAPSE].arg.i) { case COLLAPSE_BY_SUMMATION: case COLLAPSE_BY_AVERAGING: sum+=hold; break; case COLLAPSE_BY_HIGHEST: if (hold>sum) sum=hold; break; case COLLAPSE_BY_LOWEST: if (hold<sum) sum=hold; break; default: break; } } else { array_write(&newarray, array_scan(&myarray)); } reached_length++; } while (newarray.message==ARRAY_CONTINUE && myarray.message==ARRAY_CONTINUE); if (collapse) { if (args[ARGS_COLLAPSE].is_set && args[ARGS_COLLAPSE].arg.i==COLLAPSE_BY_AVERAGING && item<tinfo->itemsize-tinfo->leaveright) sum/=reached_length; array_write(&newarray, sum); } if (newarray.message==ARRAY_CONTINUE) { array_nextvector(&newarray); } if (myarray.message==ARRAY_CONTINUE) { array_nextvector(&myarray); } } while (myarray.message==ARRAY_ENDOFVECTOR); tinfo->tsdata+=myarray.nr_of_vectors*myarray.nr_of_elements*myarray.element_skip; } tinfo->tsdata=oldtsdata; } /*}}} */ if (new_xdata!=NULL) { /*{{{ Transfer xdata*/ DATATYPE sum=0.0; long reached_length=new_startpoint; long point, newpoint; if (collapse) { newpoint=current_output_point; } else { newpoint=current_output_point+new_startpoint; } for (point=old_startpoint; point<tinfo->nr_of_points && reached_length<rangep->length; point++) { if (collapse) { sum+=tinfo->xdata[point]; } else { new_xdata[newpoint]=tinfo->xdata[point]; newpoint++; } reached_length++; } if (collapse) { /* Summation of x axis values does not appear to make sense, so we always average: */ new_xdata[newpoint]=sum/reached_length; } /*}}} */ /* Save xchannelname to the end of new_xdata */ strcpy((char *)(new_xdata+output_points),tinfo->xchannelname); } if (tinfo->triggers.buffer_start!=NULL) { /* Collect triggers... */ struct trigger *intrig=(struct trigger *)tinfo->triggers.buffer_start+1; while (intrig->code!=0) { if (intrig->position>=old_startpoint && intrig->position<old_startpoint+rangep->length) { struct trigger trig= *intrig; if (collapse) { trig.position=current_output_point; } else { trig.position=intrig->position-old_startpoint+current_output_point; } growing_buf_append(&triggers, (char *)&trig, sizeof(struct trigger)); } intrig++; } } current_output_point+=(collapse ? 1 : rangep->length); } if (new_xdata!=NULL) { free(tinfo->xdata); tinfo->xdata=new_xdata; tinfo->xchannelname=(char *)(new_xdata+output_points); } if (tinfo->triggers.buffer_start!=NULL) { struct trigger trig; /* Write end marker */ trig.position=0; trig.code=0; growing_buf_append(&triggers, (char *)&trig, sizeof(struct trigger)); growing_buf_free(&tinfo->triggers); tinfo->triggers=triggers; } tinfo->multiplexed=FALSE; tinfo->nr_of_points=output_points; if (tinfo->data_type==FREQ_DATA) { tinfo->nroffreq=tinfo->nr_of_points; } else { tinfo->beforetrig-=((struct range *)(ranges.buffer_start))->offset; tinfo->aftertrig=output_points-tinfo->beforetrig; } tinfo->length_of_output_region=tinfo->nr_of_points*tinfo->nr_of_channels*tinfo->itemsize*nrofshifts; local_arg->current_epoch++; growing_buf_free(&tokenbuf); growing_buf_free(&ranges); return newarray.start; }
start_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) { ppm_source_ptr source = (ppm_source_ptr) sinfo; int c; unsigned int w, h, maxval; boolean need_iobuffer, use_raw_buffer, need_rescale; if (getc(source->pub.input_file) != 'P') ERREXIT(cinfo, JERR_PPM_NOT); c = getc(source->pub.input_file); /* subformat discriminator character */ /* detect unsupported variants (ie, PBM) before trying to read header */ switch (c) { case '2': /* it's a text-format PGM file */ case '3': /* it's a text-format PPM file */ case '5': /* it's a raw-format PGM file */ case '6': /* it's a raw-format PPM file */ break; default: ERREXIT(cinfo, JERR_PPM_NOT); break; } /* fetch the remaining header info */ w = read_pbm_integer(cinfo, source->pub.input_file, 65535); h = read_pbm_integer(cinfo, source->pub.input_file, 65535); maxval = read_pbm_integer(cinfo, source->pub.input_file, 65535); if (w <= 0 || h <= 0 || maxval <= 0) /* error check */ ERREXIT(cinfo, JERR_PPM_NOT); cinfo->data_precision = BITS_IN_JSAMPLE; /* we always rescale data to this */ cinfo->image_width = (JDIMENSION) w; cinfo->image_height = (JDIMENSION) h; source->maxval = maxval; /* initialize flags to most common settings */ need_iobuffer = TRUE; /* do we need an I/O buffer? */ use_raw_buffer = FALSE; /* do we map input buffer onto I/O buffer? */ need_rescale = TRUE; /* do we need a rescale array? */ switch (c) { case '2': /* it's a text-format PGM file */ cinfo->input_components = 1; cinfo->in_color_space = JCS_GRAYSCALE; TRACEMS2(cinfo, 1, JTRC_PGM_TEXT, w, h); source->pub.get_pixel_rows = get_text_gray_row; need_iobuffer = FALSE; break; case '3': /* it's a text-format PPM file */ cinfo->input_components = 3; cinfo->in_color_space = JCS_RGB; TRACEMS2(cinfo, 1, JTRC_PPM_TEXT, w, h); source->pub.get_pixel_rows = get_text_rgb_row; need_iobuffer = FALSE; break; case '5': /* it's a raw-format PGM file */ cinfo->input_components = 1; cinfo->in_color_space = JCS_GRAYSCALE; TRACEMS2(cinfo, 1, JTRC_PGM, w, h); if (maxval > 255) { source->pub.get_pixel_rows = get_word_gray_row; } else if (maxval == MAXJSAMPLE && sizeof(JSAMPLE) == sizeof(U_CHAR)) { source->pub.get_pixel_rows = get_raw_row; use_raw_buffer = TRUE; need_rescale = FALSE; } else { source->pub.get_pixel_rows = get_scaled_gray_row; } break; case '6': /* it's a raw-format PPM file */ cinfo->input_components = 3; cinfo->in_color_space = JCS_RGB; TRACEMS2(cinfo, 1, JTRC_PPM, w, h); if (maxval > 255) { source->pub.get_pixel_rows = get_word_rgb_row; } else if (maxval == MAXJSAMPLE && sizeof(JSAMPLE) == sizeof(U_CHAR)) { source->pub.get_pixel_rows = get_raw_row; use_raw_buffer = TRUE; need_rescale = FALSE; } else { source->pub.get_pixel_rows = get_scaled_rgb_row; } break; } /* Allocate space for I/O buffer: 1 or 3 bytes or words/pixel. */ if (need_iobuffer) { source->buffer_width = (size_t) w * cinfo->input_components * ((maxval<=255) ? sizeof(U_CHAR) : (2*sizeof(U_CHAR))); source->iobuffer = (U_CHAR *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, source->buffer_width); } /* Create compressor input buffer. */ if (use_raw_buffer) { /* For unscaled raw-input case, we can just map it onto the I/O buffer. */ /* Synthesize a JSAMPARRAY pointer structure */ source->pixrow = (JSAMPROW) source->iobuffer; source->pub.buffer = & source->pixrow; source->pub.buffer_height = 1; } else { /* Need to translate anyway, so make a separate sample buffer. */ source->pub.buffer = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, (JDIMENSION) w * cinfo->input_components, (JDIMENSION) 1); source->pub.buffer_height = 1; } /* Compute the rescaling array if required. */ if (need_rescale) { INT32 val, half_maxval; /* On 16-bit-int machines we have to be careful of maxval = 65535 */ source->rescale = (JSAMPLE *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, (size_t) (((long) maxval + 1L) * sizeof(JSAMPLE))); half_maxval = maxval / 2; for (val = 0; val <= (INT32) maxval; val++) { /* The multiplication here must be done in 32 bits to avoid overflow */ source->rescale[val] = (JSAMPLE) ((val*MAXJSAMPLE + half_maxval)/maxval); } } }
/*{{{ write_synamps_init(transform_info_ptr tinfo) {*/ METHODDEF void write_synamps_init(transform_info_ptr tinfo) { struct write_synamps_storage *local_arg=(struct write_synamps_storage *)tinfo->methods->local_storage; transform_argument *args=tinfo->methods->arguments; double xmin, xmax, ymin, ymax; int NoOfChannels=tinfo->nr_of_channels; int channel; growing_buf_init(&local_arg->triggers); local_arg->output_format=(args[ARGS_OUTPUTFORMAT].is_set ? (enum output_formats)args[ARGS_OUTPUTFORMAT].arg.i : FORMAT_EEGFILE); local_arg->SCAN=fopen(args[ARGS_OFILE].arg.s, "r+b"); if (!args[ARGS_APPEND].is_set || local_arg->SCAN==NULL) { /* target does not exist*/ /*{{{ Create file*/ if (local_arg->SCAN!=NULL) fclose(local_arg->SCAN); /*{{{ Calculate the span in x-y channel positions*/ xmin=ymin= FLT_MAX; xmax=ymax= -FLT_MAX; for (channel=0; channel<tinfo->nr_of_channels; channel++) { const double this_x=tinfo->probepos[3*channel], this_y=tinfo->probepos[3*channel+1]; if (this_x>xmax) xmax=this_x; if (this_x<xmin) xmin=this_x; if (this_y>ymax) ymax=this_y; if (this_y<ymin) ymin=this_y; } if (xmax==xmin) { xmax+=0.5; xmin-=0.5; } if (ymax==ymin) { ymax+=0.5; ymin-=0.5; } /*}}} */ if ((local_arg->SCAN=fopen(args[ARGS_OFILE].arg.s, "wb"))==NULL) { ERREXIT1(tinfo->emethods, "write_synamps_init: Can't open %s\n", MSGPARM(args[ARGS_OFILE].arg.s)); } /*{{{ Many settings, taken from example files...*/ strcpy(local_arg->EEG.rev, "Version 3.0"); local_arg->EEG.AdditionalFiles=local_arg->EEG.NextFile=local_arg->EEG.PrevFile=0; switch (local_arg->output_format) { case FORMAT_EEGFILE: local_arg->EEG.review = 1; local_arg->EEG.savemode=NSM_EEGF; local_arg->EEG.type = NTY_EPOCHED; local_arg->EEG.ContinousType=0; local_arg->EEG.nsweeps=local_arg->EEG.compsweeps=local_arg->EEG.acceptcnt=0; break; case FORMAT_CNTFILE: local_arg->EEG.review = 1; local_arg->EEG.savemode=NSM_CONT; local_arg->EEG.type = 0; local_arg->EEG.ContinousType=NST_SYNAMPS-NST_CONT0; local_arg->EEG.nsweeps=1; local_arg->EEG.compsweeps=local_arg->EEG.acceptcnt=0; break; case FORMAT_AVGFILE: local_arg->EEG.review = 0; local_arg->EEG.savemode=NSM_AVGD; local_arg->EEG.type = NTY_AVERAGED; local_arg->EEG.ContinousType=0; local_arg->EEG.nsweeps=local_arg->EEG.compsweeps=local_arg->EEG.acceptcnt=(tinfo->nrofaverages>0 ? tinfo->nrofaverages : 1); break; } /* Since the comment can be of arbitrary length and thus also larger than the * rest of the header, we should limit ourselves to the size of the id field */ strncpy(local_arg->EEG.id, tinfo->comment, sizeof(local_arg->EEG.id)); /* The date is coded in the comment, and read_synamps appends the date and time * from the corresponding fields and the contents of the id field, so that * the comment2time reader could be confused by the two date/time fields if we * would not somehow invalidate remnants of the date field here... */ {char *slash; while ((slash=strchr(local_arg->EEG.id, '/'))!=NULL) { *slash='|'; } } strcpy(local_arg->EEG.oper, "Unspecified"); strcpy(local_arg->EEG.doctor, "Unspecified"); strcpy(local_arg->EEG.referral, "Unspecified"); strcpy(local_arg->EEG.hospital, "Unspecified"); strcpy(local_arg->EEG.patient, "Unspecified"); local_arg->EEG.age = 0; local_arg->EEG.sex = 'U'; local_arg->EEG.hand = 'U'; strcpy(local_arg->EEG.med, "Unspecified"); strcpy(local_arg->EEG.category, "Unspecified"); strcpy(local_arg->EEG.state, "Unspecified"); strcpy(local_arg->EEG.label, "Unspecified"); {short dd, mm, yy, yyyy, hh, mi, ss; if (comment2time(tinfo->comment, &dd, &mm, &yy, &yyyy, &hh, &mi, &ss)) { char buffer[16]; /* Must be long enough to fit date (10) and time (12) +1 */ /* This is necessary because the date field was devised for 2-digit years. * With 4-digit years it uses all 10 bytes and the trailing zero * does not fit in any more. */ snprintf(buffer, 16, "%02d/%02d/%04d", mm, dd, yyyy); strncpy(local_arg->EEG.date, buffer, sizeof(local_arg->EEG.date)); snprintf(buffer, 16, "%02d:%02d:%02d", hh, mi, ss); strncpy(local_arg->EEG.time, buffer, sizeof(local_arg->EEG.time)); } } local_arg->EEG.rejectcnt = 0; local_arg->EEG.pnts=(tinfo->data_type==FREQ_DATA ? tinfo->nroffreq : tinfo->nr_of_points); local_arg->EEG.nchannels=NoOfChannels; local_arg->EEG.avgupdate=1; local_arg->EEG.domain=(tinfo->data_type==FREQ_DATA ? 1 : 0); local_arg->EEG.variance=0; local_arg->EEG.rate=(uint16_t)rint(tinfo->sfreq); if (tinfo->data_type==FREQ_DATA) { /* I know that this field is supposed to contain the taper window size in %, but we need some way to store basefreq and 'rate' is only integer... */ local_arg->EEG.SpectWinLength=tinfo->basefreq; } if (local_arg->EEG.rate==0) { local_arg->EEG.rate=1; TRACEMS(tinfo->emethods, 0, "write_synamps_init: Rate was zero, corrected to 1!\n"); } local_arg->EEG.scale=3.4375; /* This is a common sensitivity factor, used if sensitivities for channels are zero */ local_arg->EEG.veogcorrect=0; local_arg->EEG.heogcorrect=0; local_arg->EEG.aux1correct=0; local_arg->EEG.aux2correct=0; local_arg->EEG.veogtrig=15; /* Trigger threshold in percent of the maximum */ local_arg->EEG.heogtrig=10; local_arg->EEG.aux1trig=10; local_arg->EEG.aux2trig=10; local_arg->EEG.veogchnl=find_channel_number(tinfo, "VEOG"); local_arg->EEG.heogchnl=find_channel_number(tinfo, "HEOG"); local_arg->EEG.veogdir=0; /* 0=positive, 1=negative */ local_arg->EEG.veog_n=10; /* "Number of points per waveform", really: minimum acceptable # averages */ local_arg->EEG.heog_n=10; local_arg->EEG.veogmaxcnt=(int16_t)rint(0.3*tinfo->sfreq); /* "Number of observations per point", really: event window size in points */ local_arg->EEG.heogmaxcnt=(int16_t)rint(0.5*tinfo->sfreq); local_arg->EEG.AmpSensitivity=10; /* External Amplifier gain */ local_arg->EEG.baseline=0; local_arg->EEG.reject=0; local_arg->EEG.trigtype=2; /* 2=Port */ local_arg->EEG.trigval=255; /* Hold */ local_arg->EEG.dir=0; /* Invert (negative up)=0 */ local_arg->EEG.dispmin= -1; /* displayed y range */ local_arg->EEG.dispmax= +1; local_arg->EEG.DisplayXmin=local_arg->EEG.AutoMin=local_arg->EEG.rejstart=local_arg->EEG.offstart=local_arg->EEG.xmin= -tinfo->beforetrig/tinfo->sfreq; local_arg->EEG.DisplayXmax=local_arg->EEG.AutoMax=local_arg->EEG.rejstop=local_arg->EEG.offstop=local_arg->EEG.xmax= tinfo->aftertrig/tinfo->sfreq; local_arg->EEG.zmin=0.0; local_arg->EEG.zmax=0.1; strcpy(local_arg->EEG.ref, "A1-A2"); strcpy(local_arg->EEG.screen, "--------"); local_arg->EEG.CalMode=2; local_arg->EEG.CalMethod=0; local_arg->EEG.CalUpdate=1; local_arg->EEG.CalBaseline=0; local_arg->EEG.CalSweeps=5; local_arg->EEG.CalAttenuator=1; local_arg->EEG.CalPulseVolt=1; local_arg->EEG.CalPulseStart=0; local_arg->EEG.CalPulseStop=0; local_arg->EEG.CalFreq=10; strcpy(local_arg->EEG.taskfile, "--------"); strcpy(local_arg->EEG.seqfile, "--------"); /* Otherwise tries to read a seqfile */ local_arg->EEG.HeadGain=150; local_arg->EEG.FspFValue=2.5; local_arg->EEG.FspBlockSize=200; local_arg->EEG.fratio=1.0; local_arg->EEG.minor_rev=12; /* Necessary ! Otherwise a different file structure is assumed... */ local_arg->EEG.eegupdate=1; local_arg->EEG.xscale=local_arg->EEG.yscale=0; local_arg->EEG.xsize=40; local_arg->EEG.ysize=20; local_arg->EEG.ACmode=0; local_arg->EEG.XScaleValue=XSCALEVALUE; local_arg->EEG.XScaleInterval=XSCALEINTERVAL; local_arg->EEG.YScaleValue=YSCALEVALUE; local_arg->EEG.YScaleInterval=YSCALEINTERVAL; local_arg->EEG.ScaleToolX1=20; local_arg->EEG.ScaleToolY1=170; local_arg->EEG.ScaleToolX2=23.1535; local_arg->EEG.ScaleToolY2=153.87; local_arg->EEG.port=715; local_arg->EEG.NumSamples=0; local_arg->EEG.FilterFlag=0; local_arg->EEG.LowCutoff=4; local_arg->EEG.LowPoles=2; local_arg->EEG.HighCutoff=50; local_arg->EEG.HighPoles=2; local_arg->EEG.FilterType=3; local_arg->EEG.FilterDomain=1; local_arg->EEG.SnrFlag=0; local_arg->EEG.CoherenceFlag=0; local_arg->EEG.ContinousSeconds=4; local_arg->EEG.ChannelOffset=sizeof(int16_t); local_arg->EEG.AutoCorrectFlag=0; local_arg->EEG.DCThreshold='F'; /*}}} */ /*{{{ Write SETUP structure*/ # ifndef LITTLE_ENDIAN change_byteorder((char *)&local_arg->EEG, sm_SETUP); # endif write_struct((char *)&local_arg->EEG, sm_SETUP, local_arg->SCAN); # ifndef LITTLE_ENDIAN change_byteorder((char *)&local_arg->EEG, sm_SETUP); # endif /*}}} */ if ((local_arg->Channels=(ELECTLOC *)calloc(NoOfChannels,sizeof(ELECTLOC)))==NULL) { ERREXIT(tinfo->emethods, "write_synamps_init: Error allocating Channels list\n"); } for (channel=0; channel<NoOfChannels; channel++) { /*{{{ Settings in the channel structure*/ strncpy(local_arg->Channels[channel].lab, tinfo->channelnames[channel],sizeof(local_arg->Channels[channel].lab)); local_arg->Channels[channel].reference=0; local_arg->Channels[channel].skip=0; local_arg->Channels[channel].reject=0; local_arg->Channels[channel].display=1; local_arg->Channels[channel].bad=0; local_arg->Channels[channel].n=(local_arg->output_format==FORMAT_AVGFILE ? local_arg->EEG.acceptcnt : (local_arg->output_format==FORMAT_CNTFILE ? 0 : 1)); local_arg->Channels[channel].avg_reference=0; local_arg->Channels[channel].ClipAdd=0; local_arg->Channels[channel].x_coord= (tinfo->probepos[3*channel ]-xmin)/(xmax-xmin)*RANGE_TO_COVER+XOFFSET; local_arg->Channels[channel].y_coord=((ymax-tinfo->probepos[3*channel+1])/(ymax-ymin)*RANGE_TO_COVER+YOFFSET)/3; local_arg->Channels[channel].veog_wt=0; local_arg->Channels[channel].veog_std=0; local_arg->Channels[channel].heog_wt=0; local_arg->Channels[channel].heog_std=0; local_arg->Channels[channel].baseline=0; local_arg->Channels[channel].Filtered=0; local_arg->Channels[channel].sensitivity=204.8/args[ARGS_CONVFACTOR].arg.d; /* This arranges for conv_factor to act as the expected product before integer truncation */ local_arg->Channels[channel].Gain=5; local_arg->Channels[channel].HiPass=0; /* 0=DC */ local_arg->Channels[channel].LoPass=4; local_arg->Channels[channel].Page=0; local_arg->Channels[channel].Size=0; local_arg->Channels[channel].Impedance=0; local_arg->Channels[channel].PhysicalChnl=channel; /* Channel mapping */ local_arg->Channels[channel].Rectify=0; local_arg->Channels[channel].calib=1.0; /*}}} */ /*{{{ Write ELECTLOC struct*/ # ifndef LITTLE_ENDIAN change_byteorder((char *)&local_arg->Channels[channel], sm_ELECTLOC); # endif write_struct((char *)&local_arg->Channels[channel], sm_ELECTLOC, local_arg->SCAN); # ifndef LITTLE_ENDIAN change_byteorder((char *)&local_arg->Channels[channel], sm_ELECTLOC); # endif /*}}} */ } local_arg->SizeofHeader = ftell(local_arg->SCAN); TRACEMS2(tinfo->emethods, 1, "write_synamps_init: Creating file %s, format `%s'\n", MSGPARM(args[ARGS_OFILE].arg.s), MSGPARM(neuroscan_subtype_names[NEUROSCAN_SUBTYPE(&local_arg->EEG)])); /*}}} */ } else { /*{{{ Append to file*/ enum NEUROSCAN_SUBTYPES SubType; if (read_struct((char *)&local_arg->EEG, sm_SETUP, local_arg->SCAN)==0) { ERREXIT(tinfo->emethods, "write_synamps_init: Can't read file header.\n"); } # ifndef LITTLE_ENDIAN change_byteorder((char *)&local_arg->EEG, sm_SETUP); # endif NoOfChannels = local_arg->EEG.nchannels; /*{{{ Allocate channel header*/ if ((local_arg->Channels=(ELECTLOC *)malloc(NoOfChannels*sizeof(ELECTLOC)))==NULL) { ERREXIT(tinfo->emethods, "write_synamps_init: Error allocating Channels list\n"); } /*}}} */ for (channel=0; channel<NoOfChannels; channel++) { if (read_struct((char *)&local_arg->Channels[channel], sm_ELECTLOC, local_arg->SCAN)==0) { ERREXIT(tinfo->emethods, "write_synamps_init: Can't read channel headers.\n"); } # ifndef LITTLE_ENDIAN change_byteorder((char *)&local_arg->Channels[channel], sm_ELECTLOC); # endif } local_arg->SizeofHeader = ftell(local_arg->SCAN); SubType=NEUROSCAN_SUBTYPE(&local_arg->EEG); switch (SubType) { case NST_EPOCHS: if (local_arg->output_format!=FORMAT_EEGFILE) { TRACEMS(tinfo->emethods, 0, "write_synamps_init: Appending to epoch file, discarding option -c\n"); local_arg->output_format=FORMAT_EEGFILE; } fseek(local_arg->SCAN, 0, SEEK_END); break; case NST_CONTINUOUS: case NST_SYNAMPS: { TEEG TagType; EVENT1 event; if (local_arg->output_format!=FORMAT_CNTFILE) { TRACEMS(tinfo->emethods, 0, "write_synamps_init: Appending to continuous file, assuming option -c\n"); local_arg->output_format=FORMAT_CNTFILE; } fseek(local_arg->SCAN, local_arg->EEG.EventTablePos, SEEK_SET); /* Here we face two evils in one header: Coding enums as chars and * allowing longs at odd addresses. Well... */ if (1==read_struct((char *)&TagType, sm_TEEG, local_arg->SCAN)) { # ifndef LITTLE_ENDIAN change_byteorder((char *)&TagType, sm_TEEG); # endif if (TagType.Teeg==TEEG_EVENT_TAB1) { /*{{{ Read the event table*/ int tag; int const ntags=TagType.Size/sm_EVENT1[0].offset; /* sm_EVENT1[0].offset is sizeof(EVENT1) in the file. */ for (tag=0; tag<ntags; tag++) { if (1!=read_struct((char *)&event, sm_EVENT1, local_arg->SCAN)) { ERREXIT(tinfo->emethods, "write_synamps_init: Can't read an event table entry.\n"); break; } # ifndef LITTLE_ENDIAN change_byteorder((char *)&event, sm_EVENT1); # endif { int const TrigVal=event.StimType &0xff; int const KeyBoard=event.KeyBoard&0xf; int const KeyPad=Event_KeyPad_value(event); int const Accept=Event_Accept_value(event); int code=TrigVal-KeyPad+neuroscan_accept_translation[Accept]; if (code==0) { code= -((KeyBoard+1)<<4); } push_trigger(&local_arg->triggers,offset2point(tinfo, event.Offset),code,NULL); } } /*}}} */ } else { ERREXIT(tinfo->emethods, "write_synamps_init: Type 2 events are not yet supported.\n"); } } else { ERREXIT(tinfo->emethods, "write_synamps_init: Can't read the event table header.\n"); } fseek(local_arg->SCAN, local_arg->EEG.EventTablePos, SEEK_SET); } break; default: ERREXIT1(tinfo->emethods, "write_synamps: Cannot append to file type `%s'\n", MSGPARM(neuroscan_subtype_names[SubType])); break; } /* Conformance to the incoming epochs is checked in write_synamps */ TRACEMS1(tinfo->emethods, 1, "write_synamps_init: Appending to file %s\n", MSGPARM(args[ARGS_OFILE].arg.s)); /*}}} */ } tinfo->methods->init_done=TRUE; }
start_input_tga (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) { tga_source_ptr source = (tga_source_ptr) sinfo; U_CHAR targaheader[18]; int idlen, cmaptype, subtype, flags, interlace_type, components; unsigned int width, height, maplen; boolean is_bottom_up; #define GET_2B(offset) ((unsigned int) UCH(targaheader[offset]) + \ (((unsigned int) UCH(targaheader[offset+1])) << 8)) if (! ReadOK(source->pub.input_file, targaheader, 18)) ERREXIT(cinfo, JERR_INPUT_EOF); /* Pretend "15-bit" pixels are 16-bit --- we ignore attribute bit anyway */ if (targaheader[16] == 15) targaheader[16] = 16; idlen = UCH(targaheader[0]); cmaptype = UCH(targaheader[1]); subtype = UCH(targaheader[2]); maplen = GET_2B(5); width = GET_2B(12); height = GET_2B(14); source->pixel_size = UCH(targaheader[16]) >> 3; flags = UCH(targaheader[17]); /* Image Descriptor byte */ is_bottom_up = ((flags & 0x20) == 0); /* bit 5 set => top-down */ interlace_type = flags >> 6; /* bits 6/7 are interlace code */ if (cmaptype > 1 || /* cmaptype must be 0 or 1 */ source->pixel_size < 1 || source->pixel_size > 4 || (UCH(targaheader[16]) & 7) != 0 || /* bits/pixel must be multiple of 8 */ interlace_type != 0) /* currently don't allow interlaced image */ ERREXIT(cinfo, JERR_TGA_BADPARMS); if (subtype > 8) { /* It's an RLE-coded file */ source->read_pixel = read_rle_pixel; source->block_count = source->dup_pixel_count = 0; subtype -= 8; } else { /* Non-RLE file */ source->read_pixel = read_non_rle_pixel; } /* Now should have subtype 1, 2, or 3 */ components = 3; /* until proven different */ cinfo->in_color_space = JCS_RGB; switch (subtype) { case 1: /* Colormapped image */ if (source->pixel_size == 1 && cmaptype == 1) source->get_pixel_rows = get_8bit_row; else ERREXIT(cinfo, JERR_TGA_BADPARMS); TRACEMS2(cinfo, 1, JTRC_TGA_MAPPED, width, height); break; case 2: /* RGB image */ switch (source->pixel_size) { case 2: source->get_pixel_rows = get_16bit_row; break; case 3: source->get_pixel_rows = get_24bit_row; break; case 4: source->get_pixel_rows = get_32bit_row; break; default: ERREXIT(cinfo, JERR_TGA_BADPARMS); break; } TRACEMS2(cinfo, 1, JTRC_TGA, width, height); break; case 3: /* Grayscale image */ components = 1; cinfo->in_color_space = JCS_GRAYSCALE; if (source->pixel_size == 1) source->get_pixel_rows = get_8bit_gray_row; else ERREXIT(cinfo, JERR_TGA_BADPARMS); TRACEMS2(cinfo, 1, JTRC_TGA_GRAY, width, height); break; default: ERREXIT(cinfo, JERR_TGA_BADPARMS); break; } if (is_bottom_up) { /* Create a virtual array to buffer the upside-down image. */ source->whole_image = (*cinfo->mem->request_virt_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, (JDIMENSION) width * components, (JDIMENSION) height, (JDIMENSION) 1); if (cinfo->progress != NULL) { cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; progress->total_extra_passes++; /* count file input as separate pass */ } /* source->pub.buffer will point to the virtual array. */ source->pub.buffer_height = 1; /* in case anyone looks at it */ source->pub.get_pixel_rows = preload_image; } else { /* Don't need a virtual array, but do need a one-row input buffer. */ source->whole_image = NULL; source->pub.buffer = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, (JDIMENSION) width * components, (JDIMENSION) 1); source->pub.buffer_height = 1; source->pub.get_pixel_rows = source->get_pixel_rows; } while (idlen--) /* Throw away ID field */ (void) read_byte(source); if (maplen > 0) { if (maplen > 256 || GET_2B(3) != 0) ERREXIT(cinfo, JERR_TGA_BADCMAP); /* Allocate space to store the colormap */ source->colormap = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, (JDIMENSION) maplen, (JDIMENSION) 3); /* and read it from the file */ read_colormap(source, (int) maplen, UCH(targaheader[7])); } else { if (cmaptype) /* but you promised a cmap! */ ERREXIT(cinfo, JERR_TGA_BADPARMS); source->colormap = NULL; } cinfo->input_components = components; cinfo->data_precision = 8; cinfo->image_width = width; cinfo->image_height = height; }
start_input_bmp (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) { bmp_source_ptr source = (bmp_source_ptr) sinfo; U_CHAR bmpfileheader[14]; U_CHAR bmpinfoheader[64]; #define GET_2B(array,offset) ((unsigned int) UCH(array[offset]) + \ (((unsigned int) UCH(array[offset+1])) << 8)) #define GET_4B(array,offset) ((INT32) UCH(array[offset]) + \ (((INT32) UCH(array[offset+1])) << 8) + \ (((INT32) UCH(array[offset+2])) << 16) + \ (((INT32) UCH(array[offset+3])) << 24)) INT32 bfOffBits; INT32 headerSize; INT32 biWidth; INT32 biHeight; unsigned int biPlanes; INT32 biCompression; INT32 biXPelsPerMeter,biYPelsPerMeter; INT32 biClrUsed = 0; int mapentrysize = 0; /* 0 indicates no colormap */ INT32 bPad; JDIMENSION row_width; /* Read and verify the bitmap file header */ if (! ReadOK(source->pub.input_file, bmpfileheader, 14)) ERREXIT(cinfo, JERR_INPUT_EOF); if (GET_2B(bmpfileheader,0) != 0x4D42) /* 'BM' */ ERREXIT(cinfo, JERR_BMP_NOT); bfOffBits = (INT32) GET_4B(bmpfileheader,10); /* We ignore the remaining fileheader fields */ /* The infoheader might be 12 bytes (OS/2 1.x), 40 bytes (Windows), * or 64 bytes (OS/2 2.x). Check the first 4 bytes to find out which. */ if (! ReadOK(source->pub.input_file, bmpinfoheader, 4)) ERREXIT(cinfo, JERR_INPUT_EOF); headerSize = (INT32) GET_4B(bmpinfoheader,0); if (headerSize < 12 || headerSize > 64) ERREXIT(cinfo, JERR_BMP_BADHEADER); if (! ReadOK(source->pub.input_file, bmpinfoheader+4, headerSize-4)) ERREXIT(cinfo, JERR_INPUT_EOF); switch ((int) headerSize) { case 12: /* Decode OS/2 1.x header (Microsoft calls this a BITMAPCOREHEADER) */ biWidth = (INT32) GET_2B(bmpinfoheader,4); biHeight = (INT32) GET_2B(bmpinfoheader,6); biPlanes = GET_2B(bmpinfoheader,8); source->bits_per_pixel = (int) GET_2B(bmpinfoheader,10); switch (source->bits_per_pixel) { case 8: /* colormapped image */ mapentrysize = 3; /* OS/2 uses RGBTRIPLE colormap */ TRACEMS2(cinfo, 1, JTRC_BMP_OS2_MAPPED, (int) biWidth, (int) biHeight); break; case 24: /* RGB image */ TRACEMS2(cinfo, 1, JTRC_BMP_OS2, (int) biWidth, (int) biHeight); break; default: ERREXIT(cinfo, JERR_BMP_BADDEPTH); break; } break; case 40: case 64: /* Decode Windows 3.x header (Microsoft calls this a BITMAPINFOHEADER) */ /* or OS/2 2.x header, which has additional fields that we ignore */ biWidth = GET_4B(bmpinfoheader,4); biHeight = GET_4B(bmpinfoheader,8); biPlanes = GET_2B(bmpinfoheader,12); source->bits_per_pixel = (int) GET_2B(bmpinfoheader,14); biCompression = GET_4B(bmpinfoheader,16); biXPelsPerMeter = GET_4B(bmpinfoheader,24); biYPelsPerMeter = GET_4B(bmpinfoheader,28); biClrUsed = GET_4B(bmpinfoheader,32); /* biSizeImage, biClrImportant fields are ignored */ switch (source->bits_per_pixel) { case 8: /* colormapped image */ mapentrysize = 4; /* Windows uses RGBQUAD colormap */ TRACEMS2(cinfo, 1, JTRC_BMP_MAPPED, (int) biWidth, (int) biHeight); break; case 24: /* RGB image */ TRACEMS2(cinfo, 1, JTRC_BMP, (int) biWidth, (int) biHeight); break; case 32: /* RGB image + Alpha Channel */ TRACEMS2(cinfo, 1, JTRC_BMP, (int) biWidth, (int) biHeight); break; default: ERREXIT(cinfo, JERR_BMP_BADDEPTH); break; } if (biCompression != 0) ERREXIT(cinfo, JERR_BMP_COMPRESSED); if (biXPelsPerMeter > 0 && biYPelsPerMeter > 0) { /* Set JFIF density parameters from the BMP data */ cinfo->X_density = (UINT16) (biXPelsPerMeter/100); /* 100 cm per meter */ cinfo->Y_density = (UINT16) (biYPelsPerMeter/100); cinfo->density_unit = 2; /* dots/cm */ } break; default: ERREXIT(cinfo, JERR_BMP_BADHEADER); return; } if (biWidth <= 0 || biHeight <= 0) ERREXIT(cinfo, JERR_BMP_EMPTY); if (biPlanes != 1) ERREXIT(cinfo, JERR_BMP_BADPLANES); /* Compute distance to bitmap data --- will adjust for colormap below */ bPad = bfOffBits - (headerSize + 14); /* Read the colormap, if any */ if (mapentrysize > 0) { if (biClrUsed <= 0) biClrUsed = 256; /* assume it's 256 */ else if (biClrUsed > 256) ERREXIT(cinfo, JERR_BMP_BADCMAP); /* Allocate space to store the colormap */ source->colormap = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, (JDIMENSION) biClrUsed, (JDIMENSION) 3); /* and read it from the file */ read_colormap(source, (int) biClrUsed, mapentrysize); /* account for size of colormap */ bPad -= biClrUsed * mapentrysize; } /* Skip any remaining pad bytes */ if (bPad < 0) /* incorrect bfOffBits value? */ ERREXIT(cinfo, JERR_BMP_BADHEADER); while (--bPad >= 0) { (void) read_byte(source); } /* Compute row width in file, including padding to 4-byte boundary */ if (source->bits_per_pixel == 24) row_width = (JDIMENSION) (biWidth * 3); else if (source->bits_per_pixel == 32) row_width = (JDIMENSION) (biWidth * 4); else row_width = (JDIMENSION) biWidth; while ((row_width & 3) != 0) row_width++; source->row_width = row_width; /* Allocate space for inversion array, prepare for preload pass */ source->whole_image = (*cinfo->mem->request_virt_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, row_width, (JDIMENSION) biHeight, (JDIMENSION) 1); source->pub.get_pixel_rows = preload_image; if (cinfo->progress != NULL) { cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress; progress->total_extra_passes++; /* count file input as separate pass */ } /* Allocate one-row buffer for returned data */ source->pub.buffer = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, (JDIMENSION) (biWidth * 3), (JDIMENSION) 1); source->pub.buffer_height = 1; cinfo->in_color_space = JCS_RGB; cinfo->input_components = 3; cinfo->data_precision = 8; cinfo->image_width = (JDIMENSION) biWidth; cinfo->image_height = (JDIMENSION) biHeight; }
METHODDEF DATATYPE * read_freiburg(transform_info_ptr tinfo) { struct read_freiburg_storage *local_arg=(struct read_freiburg_storage *)tinfo->methods->local_storage; transform_argument *args=tinfo->methods->arguments; struct freiburg_channels_struct *in_channels=local_arg->in_channels; array myarray; FILE *infile; int i, point, channel; int trial_not_accepted; long length_of_data; short header[FREIBURG_HEADER_LENGTH/sizeof(short)]; char const *last_sep=strrchr(args[ARGS_IFILE].arg.s, PATHSEP); char const *last_component=(last_sep==NULL ? args[ARGS_IFILE].arg.s : last_sep+1); char comment[MAX_COMMENTLEN]; tinfo->nrofaverages=1; if (args[ARGS_CONTINUOUS].is_set) { /*{{{ Read an epoch from a continuous file*/ infile=local_arg->infile; if (local_arg->epochs--==0) return NULL; /*{{{ Configure myarray*/ myarray.element_skip=tinfo->itemsize=1; myarray.nr_of_vectors=tinfo->nr_of_points=local_arg->epochlength; myarray.nr_of_elements=tinfo->nr_of_channels=local_arg->nr_of_channels; if (array_allocate(&myarray)==NULL) { ERREXIT(tinfo->emethods, "read_freiburg: Error allocating data\n"); } tinfo->multiplexed=TRUE; /*}}} */ do { do { if (local_arg->segment_table.buffer_start!=NULL && local_arg->current_point%SEGMENT_LENGTH==0) { int const segment=local_arg->current_point/SEGMENT_LENGTH; long const nr_of_segments=local_arg->segment_table.current_length/sizeof(long); if (segment>=nr_of_segments) { array_free(&myarray); return NULL; } fseek(infile, ((long *)local_arg->segment_table.buffer_start)[segment], SEEK_SET); local_arg->no_last_values=TRUE; } if (freiburg_get_segment(tinfo, &myarray)!=0) { array_free(&myarray); return NULL; } } while (myarray.message!=ARRAY_ENDOFSCAN); } while (--local_arg->fromepoch>0); snprintf(comment, MAX_COMMENTLEN, "%s %s %02d/%02d/%04d,%02d:%02d:%02d", (local_arg->continuous_type==SLEEP_BT_TYPE ? "sleep_BT" : "sleep_KL"), last_component, local_arg->btfile.start_month, local_arg->btfile.start_day, local_arg->btfile.start_year, local_arg->btfile.start_hour, local_arg->btfile.start_minute, local_arg->btfile.start_second); tinfo->sfreq=local_arg->sfreq; /*}}} */ } else /*{{{ Read an epoch from a single (epoched or averaged) file*/ do { /* Return here if trial was not accepted */ trial_not_accepted=FALSE; if (local_arg->epochs--==0 || (local_arg->average_mode && local_arg->current_trigger>=1)) return NULL; if (local_arg->average_mode) { /*{{{ Prepare reading an averaged file*/ if((infile=fopen(args[ARGS_IFILE].arg.s,"rb"))==NULL) { ERREXIT1(tinfo->emethods, "read_freiburg: Can't open file %s\n", MSGPARM(args[ARGS_IFILE].arg.s)); } fseek(infile, 0, SEEK_END); length_of_data=ftell(infile)-FREIBURG_HEADER_LENGTH; local_arg->current_trigger++; snprintf(comment, MAX_COMMENTLEN, "Freiburg-avg %s", last_component); /*}}} */ } else { /*{{{ Build pathname of the single trial to read*/ /* A directory name was given. */ char const * const expnumber=args[ARGS_IFILE].arg.s+strlen(args[ARGS_IFILE].arg.s)-2; #ifdef __GNUC__ #define NEWFILENAME_SIZE (strlen(args[ARGS_IFILE].arg.s)+strlen(last_component)+20) #else #define NEWFILENAME_SIZE MAX_PATHLEN #endif char newfilename[NEWFILENAME_SIZE]; do { /* Files from which only the parameter part exists are rejected */ int div100=local_arg->current_trigger/100, mod100=local_arg->current_trigger%100; snprintf(newfilename, NEWFILENAME_SIZE, "%s%c%s%02d%c%c%s%02d%02d", args[ARGS_IFILE].arg.s, PATHSEP, last_component, div100, PATHSEP, tolower(expnumber[-1]), expnumber, div100, mod100); TRACEMS1(tinfo->emethods, 1, "read_freiburg: Constructed filename %s\n", MSGPARM(newfilename)); if((infile=fopen(newfilename,"rb"))==NULL) { if (local_arg->current_trigger==0) { ERREXIT1(tinfo->emethods, "read_freiburg: Can't open file %s\n", MSGPARM(newfilename)); } else { return NULL; } } fseek(infile, 0, SEEK_END); length_of_data=ftell(infile)-FREIBURG_HEADER_LENGTH; local_arg->current_trigger++; } while (length_of_data==0 || --local_arg->fromepoch>0); snprintf(comment, MAX_COMMENTLEN, "Freiburg-raw %s", last_component); /*}}} */ } /*{{{ Read the 64-Byte header*/ fseek(infile, 0, SEEK_SET); fread(header, 1, FREIBURG_HEADER_LENGTH, infile); for (i=0; i<18; i++) { # ifdef LITTLE_ENDIAN Intel_int16((uint16_t *)&header[i]); # endif TRACEMS2(tinfo->emethods, 3, "read_freiburg: Header %02d: %d\n", MSGPARM(i), MSGPARM(header[i])); } /*}}} */ if (local_arg->average_mode) { if ((length_of_data/sizeof(short))%local_arg->nr_of_channels!=0) { ERREXIT2(tinfo->emethods, "read_freiburg: length_of_data=%d does not fit with nr_of_channels=%d\n", MSGPARM(length_of_data), MSGPARM(local_arg->nr_of_channels)); } tinfo->nr_of_points=(length_of_data/sizeof(short))/local_arg->nr_of_channels; local_arg->sfreq=(args[ARGS_SFREQ].is_set ? args[ARGS_SFREQ].arg.d : 200.0); /* The most likely value */ } else { local_arg->nr_of_channels=header[14]; /* Note: In a lot of experiments, one point MORE is available in the data * than specified in the header, but this occurs erratically. We could only * check for this during decompression, but that's probably too much fuss. */ tinfo->nr_of_points=header[16]/header[15]; local_arg->sfreq=(args[ARGS_SFREQ].is_set ? args[ARGS_SFREQ].arg.d : 1000.0/header[15]); } tinfo->sfreq=local_arg->sfreq; /*{{{ Parse arguments that can be in seconds*/ local_arg->offset=(args[ARGS_OFFSET].is_set ? gettimeslice(tinfo, args[ARGS_OFFSET].arg.s) : 0); /*}}} */ tinfo->beforetrig= -local_arg->offset; tinfo->aftertrig=tinfo->nr_of_points+local_arg->offset; /*{{{ Configure myarray*/ myarray.element_skip=tinfo->itemsize=1; myarray.nr_of_vectors=tinfo->nr_of_points; myarray.nr_of_elements=tinfo->nr_of_channels=local_arg->nr_of_channels; if (array_allocate(&myarray)==NULL) { ERREXIT(tinfo->emethods, "read_freiburg: Error allocating data\n"); } tinfo->multiplexed=TRUE; /*}}} */ fseek(infile, FREIBURG_HEADER_LENGTH, SEEK_SET); if (local_arg->average_mode) { /*{{{ Read averaged epoch*/ for (point=0; point<tinfo->nr_of_points; point++) { #ifdef __GNUC__ short buffer[tinfo->nr_of_channels]; #else short buffer[MAX_NR_OF_CHANNELS]; #endif if ((int)fread(buffer, sizeof(short), tinfo->nr_of_channels, infile)!=tinfo->nr_of_channels) { ERREXIT1(tinfo->emethods, "read_freiburg: Error reading data point %d\n", MSGPARM(point)); } for (channel=0; channel<tinfo->nr_of_channels; channel++) { # ifdef LITTLE_ENDIAN Intel_int16((uint16_t *)&buffer[channel]); # endif array_write(&myarray, (DATATYPE)buffer[channel]); } } /*}}} */ } else { /*{{{ Read compressed single trial*/ # ifdef DISPLAY_ADJECTIVES char *adjektiv_ende=strchr(((char *)header)+36, ' '); if (adjektiv_ende!=NULL) *adjektiv_ende='\0'; printf("Single trial: nr_of_points=%d, nr_of_channels=%d, Adjektiv=%s\n", tinfo->nr_of_points, tinfo->nr_of_channels, ((char *)header)+36); # endif local_arg->infile=infile; do { if (freiburg_get_segment(tinfo, &myarray)!=0) { TRACEMS1(tinfo->emethods, 0, "read_freiburg: Decompression out of bounds for trial %d - skipped\n", MSGPARM(local_arg->current_trigger-1)); array_free(&myarray); trial_not_accepted=TRUE; break; } } while (myarray.message!=ARRAY_ENDOFSCAN); /*}}} */ } fclose(infile); } while (trial_not_accepted); /*}}} */ /*{{{ Look for a Freiburg channel setup for this number of channels*/ /* Force create_channelgrid to really allocate the channel info anew. * Otherwise, free_tinfo will free someone else's data ! */ tinfo->channelnames=NULL; tinfo->probepos=NULL; if (local_arg->channelnames!=NULL) { copy_channelinfo(tinfo, local_arg->channelnames, NULL); } else { while (in_channels->nr_of_channels!=0 && in_channels->nr_of_channels!=tinfo->nr_of_channels) in_channels++; if (in_channels->nr_of_channels==0) { TRACEMS1(tinfo->emethods, 1, "read_freiburg: Don't have a setup for %d channels.\n", MSGPARM(tinfo->nr_of_channels)); } else { copy_channelinfo(tinfo, in_channels->channelnames, NULL); } } create_channelgrid(tinfo); /* Create defaults for any missing channel info */ /*}}} */ if ((tinfo->comment=(char *)malloc(strlen(comment)+1))==NULL) { ERREXIT(tinfo->emethods, "read_freiburg: Error allocating comment memory\n"); } strcpy(tinfo->comment, comment); if (local_arg->zero_idiotism_warned==FALSE && local_arg->zero_idiotism_encountered) { TRACEMS(tinfo->emethods, 0, "read_freiburg: All-zero data points have been encountered and omitted!\n"); local_arg->zero_idiotism_warned=TRUE; } tinfo->z_label=NULL; tinfo->tsdata=myarray.start; tinfo->length_of_output_region=tinfo->nr_of_channels*tinfo->nr_of_points; tinfo->leaveright=0; tinfo->data_type=TIME_DATA; return tinfo->tsdata; }
start_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) { ppm_source_ptr source = (ppm_source_ptr) sinfo; int c, bit_width; unsigned int w, h, maxval; /* On 16-bit-int machines we have to be careful of maxval = 65535 + 1 */ long maxval_shift; boolean need_iobuffer, use_raw_buffer, need_rescale; if (getc(source->pub.input_file) != 'P') ERREXIT(cinfo, JERR_PPM_NOT); c = getc(source->pub.input_file); /* subformat discriminator character */ /* detect unsupported variants (ie, PBM) before trying to read header */ switch (c) { case '2': /* it's a text-format PGM file */ case '3': /* it's a text-format PPM file */ case '5': /* it's a raw-format PGM file */ case '6': /* it's a raw-format PPM file */ break; default: ERREXIT(cinfo, JERR_PPM_NOT); break; } /* fetch the remaining header info */ w = read_pbm_integer(cinfo, source->pub.input_file); h = read_pbm_integer(cinfo, source->pub.input_file); maxval = read_pbm_integer(cinfo, source->pub.input_file); if (w <= 0 || h <= 0 || maxval <= 0) /* error check */ ERREXIT(cinfo, JERR_PPM_NOT); /* cinfo->data_precision = BITS_IN_JSAMPLE;*/ /* we always rescale data to this */ /* Find the # of bits for maxval. */ cinfo->data_precision_other = 0; for (maxval_shift = (long)maxval + 1L ; maxval_shift > 1; maxval_shift >>= 1) cinfo->data_precision_other++; /* Set to 0 for: use input value from file */ if (cinfo->data_precision == 0) cinfo->data_precision = cinfo->data_precision_other; cinfo->image_width = (JDIMENSION) w; cinfo->image_height = (JDIMENSION) h; /* initialize flags to most common settings */ need_iobuffer = TRUE; /* do we need an I/O buffer? */ use_raw_buffer = FALSE; /* do we map input buffer onto I/O buffer? */ need_rescale = TRUE; /* do we need a rescale array? */ switch (c) { case '2': /* it's a text-format PGM file */ cinfo->input_components = 1; cinfo->in_color_space = JCS_GRAYSCALE; TRACEMS2(cinfo, 1, JTRC_PGM_TEXT, w, h); if (cinfo->data_precision <= 8) source->pub.get_pixel_rows = get_text_gray_row; else source->pub.get_pixel_rows = get_text_gray_row16; need_iobuffer = FALSE; break; case '3': /* it's a text-format PPM file */ cinfo->input_components = 3; cinfo->in_color_space = JCS_RGB; TRACEMS2(cinfo, 1, JTRC_PPM_TEXT, w, h); if (cinfo->data_precision <= 8) source->pub.get_pixel_rows = get_text_rgb_row; else source->pub.get_pixel_rows = get_text_rgb_row16; need_iobuffer = FALSE; break; case '5': /* it's a raw-format PGM file */ cinfo->input_components = 1; cinfo->in_color_space = JCS_GRAYSCALE; TRACEMS2(cinfo, 1, JTRC_PGM, w, h); if (cinfo->data_precision == cinfo->data_precision_other) { need_rescale = FALSE; if (cinfo->data_precision > 8) { source->pub.get_pixel_rows = get_corr_row16; use_raw_buffer = FALSE; } else { /* 8 bit*/ source->pub.get_pixel_rows = get_raw_row; use_raw_buffer = TRUE; } } else if (cinfo->data_precision > 8) { if (cinfo->data_precision_other > 8) source->pub.get_pixel_rows = get_word_gray_row16; else source->pub.get_pixel_rows = get_word_gray_row; } else { if (cinfo->data_precision_other > 8) source->pub.get_pixel_rows = get_scaled_gray_row16; else source->pub.get_pixel_rows = get_scaled_gray_row; } break; case '6': /* it's a raw-format PPM file */ cinfo->input_components = 3; cinfo->in_color_space = JCS_RGB; TRACEMS2(cinfo, 1, JTRC_PPM, w, h); if (cinfo->data_precision == cinfo->data_precision_other) { need_rescale = FALSE; if (cinfo->data_precision > 8) { source->pub.get_pixel_rows = get_corr_row16; use_raw_buffer = FALSE; } else { /* 8 bit*/ source->pub.get_pixel_rows = get_raw_row; use_raw_buffer = TRUE; } } else if (cinfo->data_precision > 8) { if (cinfo->data_precision_other > 8) source->pub.get_pixel_rows = get_word_rgb_row16; else source->pub.get_pixel_rows = get_word_rgb_row; } else { if (cinfo->data_precision_other > 8) source->pub.get_pixel_rows = get_scaled_rgb_row16; else source->pub.get_pixel_rows = get_scaled_rgb_row; } break; } /* Allocate space for I/O buffer: 1 or 3 bytes or words/pixel. */ if (need_iobuffer) { source->buffer_width = (size_t) w * cinfo->input_components * ((maxval<=255) ? SIZEOF(U_CHAR) : (2*SIZEOF(U_CHAR))); source->iobuffer = (U_CHAR *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, source->buffer_width); } /* Create compressor input buffer. */ bit_width = ((cinfo->data_precision<=8) ? SIZEOF(JSAMPLE) : SIZEOF(JSAMPLE16)); if (use_raw_buffer) { /* For unscaled raw-input case, we can just map it onto the I/O buffer. */ /* Synthesize a JSAMPARRAY pointer structure */ /* Cast here implies near->far pointer conversion on PCs */ source->pixrow = (JSAMPROW) source->iobuffer; source->pub.buffer = & source->pixrow; source->pub.buffer_height = 1; } else { /* Need to translate anyway, so make a separate sample buffer. */ source->pub.buffer = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, (JDIMENSION) w * cinfo->input_components * bit_width, (JDIMENSION) 1); source->pub.buffer_height = 1; } /* Compute the rescaling array if required. */ cinfo->lossless_scaling = FALSE; if (need_rescale) { INT32 val, half_maxval, maxjsample; /* On 16-bit-int machines we have to be careful of maxval = 65535 */ source->rescale = (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, (size_t) (((long) maxval + 1L) * (long)bit_width)); half_maxval = maxval / 2; maxjsample = (1 << cinfo->data_precision) - 1; if (bit_width == 1) { if (maxjsample == maxval) { for (val = 0; val <= (INT32) maxval; val++) source->rescale[val] = val; } else { for (val = 0; val <= (INT32) maxval; val++) { /* The multiplication here must be done in 32 bits to avoid overflow */ source->rescale[val] = (JSAMPLE) ((val*maxjsample + half_maxval)/maxval); } } } else { JSAMPLE16 *rescale16; rescale16 = (JSAMPLE16 *)source->rescale; if (maxjsample == maxval) { for (val = 0; val <= (INT32) maxval; val++) rescale16[val] = val; } else { for (val = 0; val <= (INT32) maxval; val++) { /* The multiplication here must be done in 32 bits to avoid overflow */ rescale16[val] = (JSAMPLE16) ((val*maxjsample + half_maxval)/maxval); } } } } }