INT_TIME decode_time_sdr (SDR_TIME st, /* SDR_TIME structure to decode. */ int wordorder) /* wordorder of time contents. */ { SDR_TIME ct = st; EXT_TIME et; if (my_wordorder < 0) get_my_wordorder(); if (my_wordorder != wordorder) { swab2 ((short int *)&ct.year); swab2 ((short int *)&ct.day); swab2 ((short int *)&ct.ticks); } #ifdef QLIB_DEBUG if (debug_option & 128) fprintf (info, "time = %02d.%02d %02d:%02d:%02d:%04d\n", ct.year, ct.day, ct.hour, ct.minute, ct.second, ct.ticks); #endif et.year = ct.year; et.doy = ct.day; et.hour = ct.hour; et.minute = ct.minute; et.second = ct.second; et.usec = ct.ticks * USECS_PER_TICK; dy_to_mdy (et.doy, et.year, &et.month, &et.day); return (normalize_time(ext_to_int(et))); }
void swabt (SDR_TIME *st) /* ptr to SDR_TIME to byteswap. */ { swab2 ((short int *)&st->year); swab2 ((short int *)&st->day); swab2 ((short int *)&st->ticks); }
void swab_hdr (struct dsr *phdr) { int i; float *fptr; swab4 ((char *) &phdr->hk.sizeof_hdr); swab4 ((char *) &phdr->hk.extents); swab2 ((char *) &phdr->hk.session_error); for (i = 0; i < 8; i++) swab2 ((char *) &phdr->dime.dim[i]); swab2 ((char *) &phdr->dime.datatype); swab2 ((char *) &phdr->dime.bitpix); swab2 ((char *) &phdr->dime.dim_un0); for (i = 0; i < 8; i++) swab4 ((char *) &phdr->dime.pixdim[i]); fptr = &phdr->dime.funused8; for (i = 0; i < 8; i++) swab4 ((char *) (fptr + i)); swab4 ((char *) &phdr->dime.compressed); swab4 ((char *) &phdr->dime.verified); swab4 ((char *) &phdr->dime.glmax); swab4 ((char *) &phdr->dime.glmin); swab4 ((char *) &phdr->hist.views); swab4 ((char *) &phdr->hist.vols_added); swab4 ((char *) &phdr->hist.start_field); swab4 ((char *) &phdr->hist.field_skip); swab4 ((char *) &phdr->hist.omax); swab4 ((char *) &phdr->hist.omin); swab4 ((char *) &phdr->hist.smax); swab4 ((char *) &phdr->hist.smin); }
int gwrite (char *imgt, size_t bytes, int n, FILE *fp, char control) { int i, swab_flag; char *imgb; /* i/o buffer */ int status; swab_flag = ((CPU_is_bigendian() != 0) && (control == 'l' || control == 'L')) || ((CPU_is_bigendian() == 0) && (control == 'b' || control == 'B')); if (0) printf ("gwrite swab_flag=%d\n", swab_flag); status = 0; if (swab_flag) { if (!(imgb = malloc (bytes*n))) errm ("gwrite"); for (i = 0; i < bytes*n; i++) imgb[i] = imgt[i]; for (i = 0; i < n; i++) switch (bytes) { case 2: swab2 (imgb + 2*i); break; case 4: swab4 (imgb + 4*i); break; default: errf ("gwrite"); } } else { imgb = imgt; } status = fwrite (imgb, bytes, n, fp) != n; if (swab_flag) free (imgb); return status; }
char *asc_sdr_time (char *str, /* string to encode time into. */ SDR_TIME st, /* SDR_TIME structure to decode. */ int wordorder) /* wordorder for encoded time contents. */ { if (my_wordorder < 0) get_my_wordorder(); if (my_wordorder != wordorder) { swab2 ((short int *)&st.year); swab2 ((short int *)&st.day); swab2 ((short int *)&st.ticks); } sprintf(str,"%04d,%03d,%02d:%02d:%02d.%04d", st.year, st.day, st.hour, st.minute, st.second, st.ticks); return (str); }
int blockettecmp (BS *bs1, /* BS* of first blockette to compare. */ BS *bs2) /* BS* of first blockette to compare. */ { int swapflag; SEED_UWORD l1, l2, type1, type2; int status; char *pbc1, *pbc2; char *p = NULL; if (my_wordorder < 0) get_my_wordorder(); if (bs1 == NULL && bs2 == NULL) return (0); if (bs1 == NULL) return (-1); if (bs2 == NULL) return (1); swapflag = (bs1->wordorder != bs2->wordorder); type1 = bs1->type; type2 = bs2->type; if (swapflag && bs1->wordorder != my_wordorder) swab2 ((short int *)&type1); if (swapflag && bs2->wordorder != my_wordorder) swab2 ((short int *)&type2); if (type1-type2) return (type1-type2); l1 = bs1->len; l2 = bs2->len; if (l1-l2) return (l1-l2); pbc1 = (char *)bs1->pb; pbc2 = (char *)bs2->pb; if (swapflag) { /* Reorder the wordorder of one of the blockettes for compare. */ p = (char *)malloc(l1-4); if (bs1->wordorder != my_wordorder) { memcpy (p, pbc1, l1); swab_blockette (type1, pbc1, l1); pbc1 = p; } else { memcpy (p, pbc2, l2); swab_blockette (type2, pbc2, l2); pbc2 = p; } } status = memcmp(pbc1+4, pbc2+4, l1-4); if (swapflag && p) free (p); return (status); }
time_t unix_time_from_sdr_time (SDR_TIME st, /* SDR_TIME structure to convert. */ int wordorder) /* wordorder for encoded time contents. */ { EXT_TIME et; if (my_wordorder < 0) get_my_wordorder(); if (my_wordorder != wordorder) { swab2 ((short int *)&st.year); swab2 ((short int *)&st.day); swab2 ((short int *)&st.ticks); } et.year = st.year; et.doy = st.day; et.hour = st.hour; et.minute = st.minute; et.second = st.second; et.usec = st.ticks * USECS_PER_TICK; dy_to_mdy (et.doy, et.year, &et.month, &et.day); return (unix_time_from_ext_time(et)); }
SDR_TIME encode_time_sdr (INT_TIME it, /* IN_TIME structure to decode. */ int wordorder) /* wordorder for encoded time contents. */ { SDR_TIME st; EXT_TIME et = int_to_ext(it); if (my_wordorder < 0) get_my_wordorder(); st.year = et.year; st.day = et.doy; st.hour = et.hour; st.minute = et.minute; st.second = et.second; st.pad = 0; st.ticks = et.usec / USECS_PER_TICK; if (my_wordorder != wordorder) { swab2 ((short int *)&st.year); swab2 ((short int *)&st.day); swab2 ((short int *)&st.ticks); } return (st); }
static void convert_pixels(unsigned char *src, int pixel_size, int count) { switch (pixel_size) { case 1: { unsigned char *end = src + count - 1; while (src < end) { unsigned char b = *src; *src++ = *end; *end-- = b; } } break; case 2: { unsigned short *start = (unsigned short *) src; unsigned short *end = start + count - 1; while (start <= end) { unsigned short startPixel = *start; unsigned short endPixel = *end; *end-- = swab2 (startPixel); *start++ = swab2 (endPixel); } } break; case 4: { unsigned long *start = (unsigned long *) src; unsigned long *end = start + count - 1; while (start <= end) { unsigned long startPixel = *start; unsigned long endPixel = *end; *end-- = swab4 (startPixel); *start++ = swab4 (endPixel); } } break; } }
int gread (char *imgt, size_t bytes, int n, FILE *fp, int isbig) { int i, swab_flag; swab_flag = (CPU_is_bigendian() != 0) != (isbig != 0); if (0) printf ("gread swab_flag=%d\n", swab_flag); if (fread (imgt, bytes, n, fp) != n) return -1; if (swab_flag) for (i = 0; i < n; i++) switch (bytes) { case 2: swab2 (imgt + 2*i); break; case 4: swab4 (imgt + 4*i); break; default: errf ("gread"); } return 0; }
int write_blockettes (DATA_HDR *hdr, /* ptr to data_hdr */ char *str) /* ptr to output SDR. */ { BS *bs = hdr->pblockettes; int offset = hdr->first_blockette; SEED_UWORD next; int alen; int swapflag; if (my_wordorder < 0) get_my_wordorder(); /* Ensure initial offset is a multiple of 4. */ if (offset%4) { memset (str+offset, 0, 4-(offset%4)); offset += 4-(offset%4); ((SDR_HDR *)str)->first_blockette = offset; } while (bs != (BS *)NULL) { /* Ensure offset to next blockette is correct. */ alen = bs->len; if (bs->len%4) alen += 4-(bs->len%4); next = (bs->next == NULL) ? 0 : offset + alen; if (my_wordorder != bs->wordorder) swab2((short int *)&next); ((BLOCKETTE_HDR *)(bs->pb))->next = next; memcpy (str+offset,bs->pb,bs->len); if (alen != bs->len) memset(str+offset+bs->len, 0, alen-bs->len); /* Ensure blockette wordorder is the same as hdr wordorder. */ swapflag = (hdr->hdr_wordorder != bs->wordorder); if (swapflag) { swab_blockette (bs->type, str+offset, bs->len); } offset += alen; bs = bs->next; } if (hdr->first_data > 0 && offset > hdr->first_data) { fprintf (stderr, "Error: blockettes won't fit between hdr and data.\n"); fflush (stderr); if (QLIB2_CLASSIC) exit(1); return (MS_ERROR); } return (0); }
int update_sdr_hdr (SDR_HDR *sh, /* ptr to space for SDR data hdr. */ DATA_HDR *hdr) /* initial DATA_HDR for SDR record. */ { int swapflag; /* flag to indicate byteswapping. */ short int stmp; if (my_wordorder < 0) get_my_wordorder(); swapflag = (my_wordorder != hdr->hdr_wordorder); if (swapflag) { stmp = hdr->num_samples; swab2 (&stmp); sh->num_samples = stmp; } else { sh->num_samples = hdr->num_samples; } if (hdr->num_samples == 0) sh->first_data = 0; return (0); }
int swab_blockette (int type, /* blockette number. */ char *contents, /* string containing blockette. */ int len) /* length of blockette (incl header). */ { int status = 0; char *p = contents; swab2 ((short int *)(p)); swab2 ((short int *)(p+2)); p += 4; len -= 4; switch (type) { case 100: swabf ((float *)(p+0)); break; case 200: case 201: swabf ((float *)(p+0)); swabf ((float *)(p+4)); swabf ((float *)(p+8)); swabt ((SDR_TIME *)(p+14)); break; case 300: swabt ((SDR_TIME *)(p+0)); swab4 ((int *)(p+12)); swab4 ((int *)(p+16)); swabf ((float *)(p+20)); if (len > 28) swabf ((float *)(p+28)); break; case 310: swabt ((SDR_TIME *)(p+0)); swab4 ((int *)(p+12)); swabf ((float *)(p+16)); swabf ((float *)(p+20)); if (len > 28) swabf ((float *)(p+28)); break; case 320: swabt ((SDR_TIME *)(p+0)); swabf ((float *)(p+12)); swabf ((float *)(p+16)); if (len > 24) swabf ((float *)(p+24)); break; case 390: swabt ((SDR_TIME *)(p+0)); swabf ((float *)(p+12)); swabf ((float *)(p+16)); break; case 395: swabt ((SDR_TIME *)(p+0)); swab2 ((short int *)(p+10)); break; case 400: swabf ((float *)(p+0)); swabf ((float *)(p+4)); swab2 ((short int *)(p+8)); swab2 ((short int *)(p+10)); break; case 405: swab2 ((short int *)(p+0)); break; case 500: swabf ((float *)(p+0)); swabt ((SDR_TIME *)(p+4)); swab4 ((int *)(p+16)); break; case 1000: case 1001: break; case 2000: /* Swap only numeric fields in opaque blockette header. */ swab2 ((short int *)(p)); swab2 ((short int *)(p+2)); swab4 ((int *)(p+4)); break; default: p -= 4; len += 4; swab2 ((short int *)(p)); swab2 ((short int *)(p+2)); status = -1; } return (status); }
/* * swab a block * flag = 0 -- convert from foreign to native * flag = 1 -- convert from native to foreign */ void swab(void *c, int flag) { uint8_t *p; Tag *t; int i, j; Dentry *d; Cache *h; Bucket *b; Superb *s; Fbuf *f; Off *l; /* swab the tag */ p = (uint8_t*)c; t = (Tag*)(p + BUFSIZE); if(!flag) { swab2(&t->pad); swab2(&t->tag); swaboff(&t->path); } /* swab each block type */ switch(t->tag) { default: print("no swab for tag=%G rw=%d\n", t->tag, flag); for(j=0; j<16; j++) print(" %.2x", p[BUFSIZE+j]); print("\n"); for(i=0; i<16; i++) { print("%.4x", i*16); for(j=0; j<16; j++) print(" %.2x", p[i*16+j]); print("\n"); } panic("swab"); break; case Tsuper: s = (Superb*)p; swaboff(&s->fbuf.nfree); for(i=0; i<FEPERBUF; i++) swaboff(&s->fbuf.free[i]); swaboff(&s->fstart); swaboff(&s->fsize); swaboff(&s->tfree); swaboff(&s->qidgen); swaboff(&s->cwraddr); swaboff(&s->roraddr); swaboff(&s->last); swaboff(&s->next); break; case Tdir: for(i=0; i<DIRPERBUF; i++) { d = (Dentry*)p + i; swab2(&d->uid); swab2(&d->gid); swab2(&d->mode); swab2(&d->muid); swaboff(&d->qid.path); swab4(&d->qid.version); swaboff(&d->size); for(j=0; j<NDBLOCK; j++) swaboff(&d->dblock[j]); for (j = 0; j < NIBLOCK; j++) swaboff(&d->iblocks[j]); swab4(&d->atime); swab4(&d->mtime); } break; case Tind1: case Tind2: #ifndef COMPAT32 case Tind3: case Tind4: /* add more Tind tags here ... */ #endif l = (Off *)p; for(i=0; i<INDPERBUF; i++) { swaboff(l); l++; } break; case Tfree: f = (Fbuf*)p; swaboff(&f->nfree); for(i=0; i<FEPERBUF; i++) swaboff(&f->free[i]); break; case Tbuck: for(i=0; i<BKPERBLK; i++) { b = (Bucket*)p + i; swab4(&b->agegen); for(j=0; j<CEPERBK; j++) { swab2(&b->entry[j].age); swab2(&b->entry[j].state); swaboff(&b->entry[j].waddr); } } break; case Tcache: h = (Cache*)p; swaboff(&h->maddr); swaboff(&h->msize); swaboff(&h->caddr); swaboff(&h->csize); swaboff(&h->fsize); swaboff(&h->wsize); swaboff(&h->wmax); swaboff(&h->sbaddr); swaboff(&h->cwraddr); swaboff(&h->roraddr); swab4(&h->toytime); swab4(&h->time); break; case Tnone: // unitialized case Tfile: // someone elses problem case Tvirgo: // bit map -- all bytes case Tconfig: // configuration string -- all bytes break; } /* swab the tag */ if(flag) { swab2(&t->pad); swab2(&t->tag); swaboff(&t->path); } }
DATA_HDR *decode_fixed_data_hdr (SDR_HDR *ihdr) /* MiniSEED header. */ { char tmp[80]; DATA_HDR *ohdr; int seconds, usecs; char *p; int swapflag; int itmp[2]; short int stmp[2]; unsigned short int ustmp[2]; int wo; if (my_wordorder < 0) get_my_wordorder(); /* Perform data integrity check, and pick out pertinent header info.*/ if (! (is_data_hdr_ind (ihdr->data_hdr_ind) || is_vol_hdr_ind (ihdr->data_hdr_ind))) { return ((DATA_HDR *)NULL); } if ((ohdr = new_data_hdr()) == NULL) return (NULL); ohdr->record_type = ihdr->data_hdr_ind; ohdr->seq_no = atoi (charncpy (tmp, ihdr->seq_no, 6) ); /* Handle volume header. */ /* Return a pointer to a DATA_HDR structure containing blksize. */ /* Save actual blockette for later use. */ if (is_vol_hdr_ind(ihdr->data_hdr_ind)) { if ((ohdr = new_data_hdr()) == NULL) return (NULL); ohdr->record_type = ihdr->data_hdr_ind; ohdr->seq_no = atoi (charncpy (tmp, ihdr->seq_no, 6) ); ohdr->blksize = 4096; /* default tape blksize. */ p = (char *)ihdr+8; /* point to start of blockette. */ ohdr->data_type = atoi(charncpy(tmp,p,3)); switch (ohdr->data_type) { case 5: case 8: case 10: ohdr->blksize = (int)pow(2.0,atoi(charncpy(tmp,p+11,2))); /* Do not add the blockette here, since we are not */ /* assured that the entire blockette is in this buffer. */ break; default: break; } return (ohdr); } /* Determine word order of the fixed record header. */ if ((wo = wordorder_from_time((unsigned char *)&(ihdr->time)))< 0) { free_data_hdr (ohdr); return ((DATA_HDR *)NULL); } ohdr->hdr_wordorder = wo; ohdr->data_wordorder = ohdr->hdr_wordorder; swapflag = (ohdr->hdr_wordorder != my_wordorder); charncpy (ohdr->station_id, ihdr->station_id, 5); charncpy (ohdr->location_id, ihdr->location_id, 2); charncpy (ohdr->channel_id, ihdr->channel_id, 3); charncpy (ohdr->network_id, ihdr->network_id, 2); trim (ohdr->station_id); trim (ohdr->location_id); trim (ohdr->channel_id); trim (ohdr->network_id); ohdr->hdrtime = ohdr->begtime = decode_time_sdr(ihdr->time, ohdr->hdr_wordorder); if (swapflag) { /* num_samples. */ ustmp[0] = ihdr->num_samples; swab2 ((short int *)&ustmp[0]); ohdr->num_samples = ustmp[0]; /* data_rate */ stmp[0] = ihdr->sample_rate_factor; stmp[1] = ihdr->sample_rate_mult; swab2 (&stmp[0]); swab2 (&stmp[1]); ohdr->sample_rate = stmp[0]; ohdr->sample_rate_mult = stmp[1]; /* num_ticks_correction. */ itmp[0] = ihdr->num_ticks_correction; swab4 (&itmp[0]); ohdr->num_ticks_correction = itmp[0]; /* first_data */ ustmp[0] = ihdr->first_data; swab2 ((short int *)&ustmp[0]); ohdr->first_data = ustmp[0]; /* first_blockette */ ustmp[1] = ihdr->first_blockette; swab2 ((short int *)&ustmp[1]); ohdr->first_blockette = ustmp[1]; } else { ohdr->num_samples = ihdr->num_samples; ohdr->sample_rate = ihdr->sample_rate_factor; ohdr->sample_rate_mult = ihdr->sample_rate_mult; ohdr->num_ticks_correction = ihdr->num_ticks_correction; ohdr->first_data = ihdr->first_data; ohdr->first_blockette = ihdr->first_blockette; } /* WARNING - may need to convert flags to independent format */ /* if we ever choose a different flag format for the DATA_HDR. */ ohdr->activity_flags = ihdr->activity_flags; ohdr->io_flags = ihdr->io_flags; ohdr->data_quality_flags = ihdr->data_quality_flags; ohdr->num_blockettes = ihdr->num_blockettes; ohdr->data_type = 0; /* assume unknown datatype. */ ohdr->pblockettes = (BS *)NULL; /* Do not parse blockettes here.*/ /* If the time correction has not already been added, we should */ /* add it to the begtime. Do NOT change the ACTIVITY flag, since */ /* it refers to the hdrtime, NOT the begtime/endtime. */ if ( ohdr->num_ticks_correction != 0 && ((ohdr->activity_flags & ACTIVITY_TIME_CORR_APPLIED) == 0) ) { ohdr->begtime = add_dtime (ohdr->begtime, (double)ohdr->num_ticks_correction * USECS_PER_TICK); } time_interval2(ohdr->num_samples - 1, ohdr->sample_rate, ohdr->sample_rate_mult, &seconds, &usecs); ohdr->endtime = add_time(ohdr->begtime, seconds, usecs); return(ohdr); }
int read_ms_bkt (DATA_HDR *hdr, /* data_header structure. */ char *buf, /* ptr to fixed data header. */ FILE *fp) /* FILE pointer for input file. */ { BS *bs, *pbs; int offset, i, bl_limit; SEED_UWORD bl_len, bl_next, bl_type; int bh_len = sizeof(BLOCKETTE_HDR); int blksize = 0; int preread = 0; /* # bytes of blockette data preread. */ if (my_wordorder < 0) get_my_wordorder(); bs = pbs = (BS *)NULL; offset = hdr->first_blockette; hdr->pblockettes = (BS *)NULL; bl_next = 0; /* Run through each blockette, allocate a linked list structure */ /* for it, and verify that the blockette structures are OK. */ /* There is a LOT of checking to ensure proper structure. */ for (i=0; i<hdr->num_blockettes; i++) { if (i > 0 && bl_next == 0) { fprintf (stderr, "Error: zero offset to next blockette\n"); fflush (stderr); if (QLIB2_CLASSIC) exit(1); return (MS_ERROR); } if ( (bs=(BS *)malloc(sizeof(BS))) == NULL ) { fprintf (stderr, "Error: unable to malloc BS\n"); if (QLIB2_CLASSIC) exit(1); return (QLIB2_MALLOC_ERROR); } bs->next = (BS *)NULL; if (i == 0) hdr->pblockettes = bs; else pbs->next = bs; pbs = bs; /* Read blockette header. */ if (fread (buf+offset, bh_len, 1, fp) != 1) return (EOF); preread = 0; /* Decide how much space the blockette takes up. If we know */ /* blockette type, then allocate the appropriate space. */ /* Otherwise, determine the required space by the offset to */ /* the next blockette, or by the offset to the first data if */ /* this is the last blockette. */ /* If there is not data, then ensure that we know the length */ /* of the blockette. If not, consider it to be a fatal error, */ /* since we have no idea how long it should be. */ /* */ /* We cannot allow it to extend to the blksize, since we use */ /* this routine to process blockettes from packed miniSEED */ /* files. Packed miniSEED files contain records that are a */ /* multiple of the packsize (currently 128 bytes) with a block */ /* whose size is specified in the b1000 blksize field. */ bl_type = ((BLOCKETTE_HDR *)(buf+offset))->type; bl_next = ((BLOCKETTE_HDR *)(buf+offset))->next; if (hdr->hdr_wordorder != my_wordorder) { swab2 ((short int *)&bl_type); swab2 ((short int *)&bl_next); } bl_limit = (bl_next) ? bl_next : (hdr->first_data) ? hdr->first_data : 0; switch (bl_type) { case 100: bl_len = sizeof (BLOCKETTE_100); break; case 200: bl_len = sizeof (BLOCKETTE_200); break; case 201: bl_len = sizeof (BLOCKETTE_201); break; case 300: bl_len = sizeof (BLOCKETTE_300); break; case 310: bl_len = sizeof (BLOCKETTE_310); break; case 320: bl_len = sizeof (BLOCKETTE_320); break; case 390: bl_len = sizeof (BLOCKETTE_390); break; case 395: bl_len = sizeof (BLOCKETTE_395); break; case 400: bl_len = sizeof (BLOCKETTE_400); break; case 405: bl_len = sizeof (BLOCKETTE_405); break; case 500: bl_len = sizeof (BLOCKETTE_500); break; case 1000: bl_len = sizeof (BLOCKETTE_1000); break; case 1001: bl_len = sizeof (BLOCKETTE_1001); break; /* Variable length blockettes. Preserve original length, */ /* even though it may not is divisible by 4. */ /* It is up to the user to ensure that that blockettes */ /* have 4 byte alignment in a SEED data record. */ case 2000: /* Length of blockette 2000 is stored in first word of blockette. */ preread = 2; if (fread (buf+offset+bh_len, preread, 1, fp) != 1) return (EOF); bl_len = ((BLOCKETTE_2000 *)(buf+offset))->blockette_len; if (hdr->hdr_wordorder != my_wordorder) { swab2 ((short int *)&bl_len); } break; default: fprintf (stderr, "Warning: unknown blockette %d\n",bl_type); bl_len = 0; break; } /* Perform integrity checks on blockette. */ if (bl_len != 0) { /* Known blockettes: */ /* Check that the presumed blockette length is correct. */ if (bl_limit > 0 && (int)bl_len > bl_limit-offset) { /* Warning only if blockette is too short. */ /* Allow padding between blockettes. */ fprintf (stderr, "Warning: short blockette %d len=%d, expected len=%d\n", bl_type, bl_limit-offset, bl_len); } /* Be safe and extend the effective length of the blockette */ /* to the limit (next blockette or first data) if there is */ /* a limit. */ bl_len = (bl_limit) ? bl_limit - offset : bl_len; /* Check that we do not run into the data portion of record.*/ if (hdr->first_data != 0 && (int)bl_len+offset > hdr->first_data) { fprintf (stderr, "Warning: blockette %d at offset=%d len=%d first_data=%d\n", bl_type, bl_limit-offset, bl_len, hdr->first_data); bl_len = bl_limit - offset; } } else { /* Unknown blockettes: */ if (bl_limit == 0) { fprintf (stderr, "Warning: unknown blockette and no length limit\n"); return (-1); } /* For unknown blockettes ensure that we have a max len. */ bl_len = bl_limit - offset; } if ((bs->pb = (char *)malloc(bl_len))==NULL) { fprintf (stderr, "unable to malloc blockettd\n"); return (-1); } /* Read the body of the blockette, and copy entire blockette. */ if (fread(buf+offset+bh_len+preread, bl_len-bh_len-preread, 1, fp) != 1) return(-1); memcpy (bs->pb,buf+offset,bl_len); bs->len = bl_len; bs->type = bl_type; bs->wordorder = hdr->hdr_wordorder; if (bl_type == 1000) { blksize = (int)pow(2., (double)((BLOCKETTE_1000 *)(buf+offset))->data_rec_len); } offset += bl_len; preread = 0; } /* Ensure there are no more blockettes. */ if (bl_next != 0) { fprintf (stderr, "extra blockette found\n"); return(-1); } return (offset); }
int init_sdr_hdr (SDR_HDR *sh, /* ptr to space for sdr data hdr. */ DATA_HDR *hdr, /* initial DATA_HDR for sdr record. */ BS *extra_bs) /* ptr to block-specific blockettes. */ { int status = 0; int blockette_space; /* # of bytes required for blockettes. */ int n_extra_bs; /* # of extra blockettes. */ BS *bs; /* ptr to blockette structure. */ BS *last_bs; /* ptr to last permanent blockette. */ int align; /* alignment in bytes required for data.*/ int swapflag; /* flag to indicate byteswapping. */ MS_ATTR attr; int blksize = hdr->blksize; if (my_wordorder < 0) get_my_wordorder(); swapflag = (my_wordorder != hdr->hdr_wordorder); /* Determine the space required for all of the blockettes. */ for (bs=hdr->pblockettes, blockette_space=0, last_bs=NULL; bs!=NULL; last_bs=bs, bs=bs->next) { blockette_space += bs->len + ((bs->len%4) ? 4-(bs->len%4) : 0); } for (bs=extra_bs, n_extra_bs=0; bs!=NULL; bs=bs->next, n_extra_bs++) { blockette_space += bs->len + ((bs->len%4) ? 4-(bs->len%4) : 0); } /* Temporarily add the list of extra blockettes to the list of */ /* permanent blockettes. */ if (extra_bs) { if (last_bs) last_bs->next = extra_bs; else hdr->pblockettes = extra_bs; hdr->num_blockettes += n_extra_bs; } /* Ensure that first_data points to appropriate offset for data. */ /* Some data formats (eg the STEIM compressed formats) require */ /* first_data to be on a frame boundary. */ attr = get_ms_attr(hdr); if (attr.alignment == 0) return (MS_ERROR); align = attr.alignment; hdr->first_data = ((sizeof(SDR_HDR)+blockette_space+align-1)/align)*align; /* Update any blockettes that have block-specific info. */ if ((bs=find_blockette(hdr, 1000))) { /* Ensure we have proper data in the blockette. */ BLOCKETTE_1000 *b1000 = (BLOCKETTE_1000 *) bs->pb; /* These are all byte values, so I can ignore wordorder. */ b1000->data_rec_len = roundoff(log2((double)blksize)); b1000->format = hdr->data_type; b1000->word_order = hdr->data_wordorder; } if ((bs=find_blockette(hdr, 1001))) { /* Ensure we have proper data in the blockette. */ /* Mark all frames as being in use. */ BLOCKETTE_1001 *b1001 = (BLOCKETTE_1001 *) bs->pb; /* These are all byte values, so I can ignore wordorder. */ b1001->frame_count = hdr->num_data_frames; b1001->usec99 = hdr->hdrtime.usec % 100; } /* Create the SDR fixed data header and data blockettes. */ /* Parts of the header that do not change from block to block. */ sh->space_1 = ' '; capnstr(sh->station_id,hdr->station_id,5); capnstr(sh->channel_id,hdr->channel_id,3); capnstr(sh->network_id,hdr->network_id,2); capnstr(sh->location_id,hdr->location_id,2); sh->sample_rate_factor = hdr->sample_rate; sh->sample_rate_mult = (hdr->sample_rate) ? hdr->sample_rate_mult : 0; /* Parts of the header that change with each block. */ sh->data_hdr_ind = hdr->record_type; capnint(sh->seq_no,hdr->seq_no,6); sh->time = encode_time_sdr(hdr->hdrtime, hdr->hdr_wordorder); sh->activity_flags = hdr->activity_flags; sh->io_flags = hdr->io_flags; sh->data_quality_flags = hdr->data_quality_flags; sh->num_samples = 0; sh->num_ticks_correction = hdr->num_ticks_correction; /* Parts of the header that depend on the blockettes. */ sh->first_data = hdr->first_data; sh->num_blockettes = hdr->num_blockettes; sh->first_blockette = hdr->first_blockette; /* Output any data blockettes. */ if (hdr->num_blockettes > 0) { write_blockettes(hdr, (char *)sh); } /* Unlink the extra blockettes from the data_hdr. */ if (extra_bs) { if (last_bs) last_bs->next = NULL; else hdr->pblockettes = NULL; hdr->num_blockettes -= n_extra_bs; } if (swapflag) { swab2 ((short int *)&sh->num_samples); swab2 ((short int *)&sh->sample_rate_factor); swab2 ((short int *)&sh->sample_rate_mult); swab2 ((short int *)&sh->first_data); swab2 ((short int *)&sh->first_blockette); swab4 ((int *)&sh->num_ticks_correction); } /* Zero any space between the end of the blockettes and first_data. */ memset ((char*)sh + (sizeof(SDR_HDR)+blockette_space), 0, hdr->first_data - (sizeof(SDR_HDR)+blockette_space)); /* Return status our SDR header creation. */ return (status); }
int main (int argc, char *argv[]) { /*******/ /* i/o */ /*******/ FILE *fpimg, *fpout; IFH ifh; struct dsr hdr; /* ANALYZE hdr */ char imgroot[MAXL], imgfile[MAXL], outfile[MAXL]; char trailer[8] = ".4dint"; /****************/ /* image arrays */ /****************/ float *imgf, cscale = 1.0; short int *imgi=NULL; unsigned char *imgu=NULL; float voxsiz[3]; int imgdim[4], vdim, orient, isbig; int imin = 32767, imax = -32768; char control = '\0'; short int origin[3]; /* used in SPM99 conversions */ /***********/ /* utility */ /***********/ int c, i, j, k; char *str, command[MAXL], program[MAXL]; /*********/ /* flags */ /*********/ int uchar = 0; int debug = 0; int spm99 = 0; int swab_flag = 0; fprintf (stdout, "%s\n", rcsid); setprog (program, argv); /************************/ /* process command line */ /************************/ for (k = 0, i = 1; i < argc; i++) { if (*argv[i] == '-') { strcpy (command, argv[i]); str = command; while ((c = *str++)) switch (c) { case '8': uchar++; strcpy (trailer, "_8bit"); break; case 'd': debug++; break; case 'c': cscale = atof (str); *str = '\0'; break; case 'S': if (!strcmp (str, "PM99")) spm99++; *str = '\0'; break; case '@': control = *str++; *str = '\0'; break; } } else switch (k) { case 0: getroot (argv[i], imgroot); k++; break; } } if (k < 1) { printf ("Usage:\t%s <(4dfp) filename>\n", program); printf ("\toption\n"); printf ("\t-c<flt>\tscale output values by specified factor\n"); printf ("\t-8\toutput 8 bit unsigned char\n"); printf ("\t-SPM99\tinclude origin and scale in hdr (http:/wideman-one.com/gw/brain/analyze/format.doc)\n"); printf ("\t-@<b|l>\toutput big or little endian (default CPU endian)\n"); exit (1); } /*****************************/ /* get input 4dfp dimensions */ /*****************************/ if (get_4dfp_dimoe (imgroot, imgdim, voxsiz, &orient, &isbig)) errr (program, imgroot); vdim = imgdim[0] * imgdim[1] * imgdim[2]; if (uchar) { if (!(imgu = (unsigned char *) malloc (vdim * sizeof (char)))) errm (program); } else { if (!(imgi = (short *) malloc (vdim * sizeof (short)))) errm (program); } if (!(imgf = (float *) malloc (vdim * sizeof (float)))) errm (program); /*************************/ /* open input and output */ /*************************/ sprintf (imgfile, "%s.4dfp.img", imgroot); printf ("Reading: %s\n", imgfile); if (!(fpimg = fopen (imgfile, "rb"))) errr (program, imgfile); sprintf (outfile, "%s%s.img", imgroot, trailer); if (!(fpout = fopen (outfile, "wb"))) errw (program, outfile); printf ("Writing: %s\n", outfile); /**********************/ /* process all frames */ /**********************/ for (k = 0; k < imgdim[3]; k++) { if (eread (imgf, vdim, isbig, fpimg)) errr (program, imgfile); switch (orient) { case 4: flipx (imgf, imgdim + 0, imgdim + 1, imgdim + 2); /* sagittal */ case 3: flipz (imgf, imgdim + 0, imgdim + 1, imgdim + 2); /* coronal */ case 2: flipy (imgf, imgdim + 0, imgdim + 1, imgdim + 2); /* transverse */ break; default: fprintf (stderr, "%s: %s image orientation not recognized\n", program, imgfile); exit (-1); break; } for (i = 0; i < vdim; i++) { j = nint (cscale*imgf[i]); if (debug) printf ("%10.6f%10d\n", imgf[i], j); if (uchar) { if (j < 0) j = 0; if (j > 255) j = 255; imgu[i] = j; } else { imgi[i] = j; } if (j > imax) imax = j; if (j < imin) imin = j; } if (uchar) { if (fwrite ( imgu, sizeof (char), vdim, fpout) != vdim) errw (program, outfile); } else { if (gwrite ((char *) imgi, sizeof (short), vdim, fpout, control)) errw (program, outfile); } } fclose (fpimg); fclose (fpout); /**************************/ /* create ANALYZE 7.5 hdr */ /**************************/ Inithdr (&hdr, imgdim, voxsiz, ""); if (uchar) { hdr.dime.datatype = 2; /* unsigned char */ hdr.dime.bitpix = 8; } else { hdr.dime.datatype = 4; /* signed integer */ hdr.dime.bitpix = 16; } hdr.dime.glmax = imax; hdr.dime.glmin = imin; hdr.hist.orient = orient - 2; swab_flag = ((CPU_is_bigendian() != 0) && (control == 'l' || control == 'L')) || ((CPU_is_bigendian() == 0) && (control == 'b' || control == 'B')); if (spm99) { if (Getifh (imgroot, &ifh)) errr (program, imgroot); for (i = 0; i < 3; i++) origin[i] = 0.4999 + ifh.center[i]/ifh.mmppix[i]; /*************************************************/ /* flip 4dfp->analyze assuming transverse orient */ /*************************************************/ origin[1] = imgdim[1] + 1 - origin[1]; /*******************************************************************/ /* origin field officially text and so not affected by swab_hdr () */ /*******************************************************************/ if (swab_flag) for (i = 0; i < 3; i++) swab2 ((char *) (origin + i)); memcpy ((char *) &hdr + 253, (char *) origin, 3*sizeof (short int)); memcpy ((char *) &hdr + 112, (char *) &cscale, sizeof (float)); hdr.hk.extents = 0; } if (swab_flag) swab_hdr (&hdr); sprintf (outfile, "%s%s.hdr", imgroot, trailer); printf ("Writing: %s\n", outfile); if (!(fpout = fopen (outfile, "wb")) || fwrite (&hdr, sizeof (struct dsr), 1, fpout) != 1 || fclose (fpout)) errw (program, outfile); /*******************/ /* create rec file */ /*******************/ sprintf (outfile, "%s%s.img", imgroot, trailer); startrece (outfile, argc, argv, rcsid, control); sprintf (command, "Voxel values scaled by %f\n", cscale); printrec (command); catrec (imgfile); endrec (); free (imgf); if (uchar) { free (imgu); } else { free (imgi); } exit (0); }
int read_blockettes (DATA_HDR *hdr, /* data_header structure. */ char *str) /* ptr to fixed data header. */ { BS *bs, *pbs; int offset, i; SEED_UWORD bl_len, bl_next, bl_type; if (my_wordorder < 0) get_my_wordorder(); bs = pbs = (BS *)NULL; offset = hdr->first_blockette; hdr->pblockettes = (BS *)NULL; bl_next = 0; /* Run through each blockette, allocate a linked list structure */ /* for it, and verify that the blockette structures are OK. */ /* There is a LOT of checking to ensure proper structure. */ for (i=0; i<hdr->num_blockettes; i++) { if (i > 0 && bl_next == 0) { fprintf (stderr, "Error: zero offset to next blockette\n"); fflush (stderr); if (QLIB2_CLASSIC) exit(1); return (MS_ERROR); } if ( (bs=(BS *)malloc(sizeof(BS))) == NULL ) { fprintf (stderr, "Error: unable to malloc BS\n"); fflush (stderr); if (QLIB2_CLASSIC) exit(1); return (QLIB2_MALLOC_ERROR); } bs->next = (BS *)NULL; /* Decide how much space the blockette takes up. */ /* In order to allow for variable blockette size for either */ /* newer SEED version or vendor-specific additions, */ /* attempt to determine the required space by the offset to */ /* the next blockette. If this is the last blockette, */ /* then just use the length of the blockette as it is defined. */ bl_type = ((BLOCKETTE_HDR *)(str+offset))->type; bl_next = ((BLOCKETTE_HDR *)(str+offset))->next; if (hdr->hdr_wordorder != my_wordorder) { swab2 ((short int *)&bl_type); swab2 ((short int *)&bl_next); } if (bl_next > 0) { bl_len = (bl_next-offset); } else { /* No further blockettes. Assume length of blockette structure.*/ switch (bl_type) { /* Fixed length blockettes. */ case 100: bl_len = sizeof (BLOCKETTE_100); break; case 200: bl_len = sizeof (BLOCKETTE_200); break; case 201: bl_len = sizeof (BLOCKETTE_201); break; case 300: bl_len = sizeof (BLOCKETTE_300); break; case 310: bl_len = sizeof (BLOCKETTE_310); break; case 320: bl_len = sizeof (BLOCKETTE_320); break; case 390: bl_len = sizeof (BLOCKETTE_390); break; case 395: bl_len = sizeof (BLOCKETTE_395); break; case 400: bl_len = sizeof (BLOCKETTE_400); break; case 405: bl_len = sizeof (BLOCKETTE_405); break; case 500: bl_len = sizeof (BLOCKETTE_500); break; case 1000: bl_len = sizeof (BLOCKETTE_1000); break; case 1001: bl_len = sizeof (BLOCKETTE_1001); break; /* Variable length blockettes. Preserve original length, */ /* even though it may not is divisible by 4. */ /* It is up to the user to ensure that that blockettes */ /* have 4 byte alignment in a SEED data record. */ case 2000: bl_len = ((BLOCKETTE_2000 *)(str+offset))->blockette_len; if (hdr->hdr_wordorder != my_wordorder) { swab2 ((short int *)&bl_len); } break; default: bl_type = 0; bl_len = 0; break; } /* Ensure that the blockette length does not exceed space */ /* available for it after the header and before first_data. */ if (hdr->first_data > 0 && hdr->first_data - offset > 0 && (int)bl_len > hdr->first_data - offset) bl_len = hdr->first_data - offset; } if (bl_next != 0 && bl_len != 0) { /* Verify length for known blockettes when possible. */ /*:: if (bl_len != bl_next-offset) { fprintf (stderr, "Error: blockette %d apparent size %d does not match known length %d\n", bl_type, bl_next-offset, bl_len); fflush (stderr); if (QLIB2_CLASSIC) exit(1); return (MS_ERROR); } ::*/ } else if (bl_len == 0 && bl_type == 0) { /* Assume the blockette reaches to first data. */ /* If first data == 0, then abort -- we don't know this blockette. */ if (hdr->first_data <= offset) { fprintf (stderr, "Unknown blockette type %d - unable to determine size\n", ((BLOCKETTE_HDR *)(str+offset))->type); fflush (stderr); free ((char *)bs); continue; } else bl_len = hdr->first_data - offset; } if ((bs->pb = (char *)malloc(bl_len))==NULL) { fprintf (stderr, "Error: unable to malloc blockette\n"); fflush (stderr); if (QLIB2_CLASSIC) exit(1); return (MS_ERROR); } memcpy (bs->pb,str+offset,bl_len); bs->len = bl_len; bs->type = bl_type; bs->wordorder = hdr->hdr_wordorder; offset += bl_len; if (i == 0) hdr->pblockettes = bs; else pbs->next = bs; pbs = bs; } /* Ensure there are no more blockettes. */ if (bl_next != 0) { fprintf (stderr, "extra blockette found\n"); fflush (stderr); return (QLIB2_CLASSIC ? 0 : MS_ERROR); } return (1); }
DATA_HDR *decode_hdr_sdr (SDR_HDR *ihdr, /* input SDR header. */ int maxbytes) /* max # bytes in buffer. */ { char tmp[80]; DATA_HDR *ohdr; BS *bs; /* ptr to blockette structure. */ char *p; char *pc; int i, next_seq; int seconds, usecs; int swapflag; int itmp[2]; short int stmp[2]; unsigned short int ustmp[2]; int wo; qlib2_errno = 0; if (my_wordorder < 0) get_my_wordorder(); /* Perform data integrity check, and pick out pertinent header info.*/ if (! (is_data_hdr_ind (ihdr->data_hdr_ind) || is_vol_hdr_ind (ihdr->data_hdr_ind))) { /* Don't have a data header. See if the entire header is */ /* composed of NULLS. If so, print warning and return NULL. */ /* Some early Quanterras output a spurious block with null */ /* header info every 16 blocks. That block should be ignored. */ if (allnull((char *)ihdr, sizeof(SDR_HDR))) { return ((DATA_HDR *)NULL); } else { qlib2_errno = 1; return ((DATA_HDR *)NULL); } } if ((ohdr = new_data_hdr()) == NULL) return (NULL); ohdr->record_type = ihdr->data_hdr_ind; ohdr->seq_no = atoi (charncpy (tmp, ihdr->seq_no, 6) ); /* Handle volume header. */ /* Return a pointer to a DATA_HDR structure containing blksize. */ /* Save actual blockette for later use. */ if (is_vol_hdr_ind(ihdr->data_hdr_ind)) { /* Get blksize from volume header. */ p = (char *)ihdr+8; ohdr->blksize = 4096; /* default tape blksize. */ /* Put volume blockette number in data_type field. */ ohdr->data_type = atoi (charncpy (tmp, p, 3)); switch (ohdr->data_type) { int ok; case 5: case 8: case 10: ohdr->blksize = (int)pow(2.0,atoi(charncpy(tmp,p+11,2))); ok = add_blockette (ohdr, p, ohdr->data_type, atoi(charncpy(tmp,p+3,4)), my_wordorder, 0); if (! ok) { qlib2_errno = 2; free_data_hdr(ohdr); return ((DATA_HDR *)NULL); } break; default: break; } return (ohdr); } /* Determine word order of the fixed record header. */ if ((wo = wordorder_from_time((unsigned char *)&(ihdr->time))) < 0) { qlib2_errno = 3; free_data_hdr (ohdr); return ((DATA_HDR *)NULL); } ohdr->hdr_wordorder = wo; ohdr->data_wordorder = ohdr->hdr_wordorder; swapflag = (ohdr->hdr_wordorder != my_wordorder); charncpy (ohdr->station_id, ihdr->station_id, 5); charncpy (ohdr->location_id, ihdr->location_id, 2); charncpy (ohdr->channel_id, ihdr->channel_id, 3); charncpy (ohdr->network_id, ihdr->network_id, 2); trim (ohdr->station_id); trim (ohdr->location_id); trim (ohdr->channel_id); trim (ohdr->network_id); ohdr->hdrtime = decode_time_sdr(ihdr->time, ohdr->hdr_wordorder); if (swapflag) { /* num_samples. */ ustmp[0] = ihdr->num_samples; swab2 ((short int *)&ustmp[0]); ohdr->num_samples = ustmp[0]; /* data_rate */ stmp[0] = ihdr->sample_rate_factor; stmp[1] = ihdr->sample_rate_mult; swab2 ((short int *)&stmp[0]); swab2 ((short int *)&stmp[1]); ohdr->sample_rate = stmp[0]; ohdr->sample_rate_mult = stmp[1]; /* num_ticks_correction. */ itmp[0] = ihdr->num_ticks_correction; swab4 (&itmp[0]); ohdr->num_ticks_correction = itmp[0]; /* first_data */ ustmp[0] = ihdr->first_data; swab2 ((short int *)&ustmp[0]); ohdr->first_data = ustmp[0]; /* first_blockette */ ustmp[1] = ihdr->first_blockette; swab2 ((short int *)&ustmp[1]); ohdr->first_blockette = ustmp[1]; } else { ohdr->num_samples = ihdr->num_samples; ohdr->sample_rate = ihdr->sample_rate_factor; ohdr->sample_rate_mult = ihdr->sample_rate_mult; ohdr->num_ticks_correction = ihdr->num_ticks_correction; ohdr->first_data = ihdr->first_data; ohdr->first_blockette = ihdr->first_blockette; } /* WARNING - may need to convert flags to independent format */ /* if we ever choose a different flag format for the DATA_HDR. */ ohdr->activity_flags = ihdr->activity_flags; ohdr->io_flags = ihdr->io_flags; ohdr->data_quality_flags = ihdr->data_quality_flags; ohdr->num_blockettes = ihdr->num_blockettes; ohdr->data_type = 0; /* assume unknown datatype. */ ohdr->pblockettes = (BS *)NULL; /* Do not parse blockettes here.*/ if (ohdr->num_blockettes == 0) ohdr->pblockettes = (BS *)NULL; else { if (read_blockettes (ohdr, (char *)ihdr) != 1) { free ((char *)ohdr); return ((DATA_HDR *)NULL); } } /* Process any blockettes that follow the fixed data header. */ /* If a blockette 1000 exists, fill in the datatype. */ /* Otherwise, leave the datatype as unknown. */ ohdr->data_type = UNKNOWN_DATATYPE; ohdr->num_data_frames = -1; if ((bs=find_blockette(ohdr, 1000))) { /* Ensure we have proper output blocksize in the blockette. */ BLOCKETTE_1000 *b1000 = (BLOCKETTE_1000 *) bs->pb; ohdr->data_type = b1000->format; ohdr->blksize = (int)pow(2.0,b1000->data_rec_len); ohdr->data_wordorder = b1000->word_order; } if ((bs=find_blockette(ohdr, 1001))) { /* Add in the usec99 field to the hdrtime. */ BLOCKETTE_1001 *b1001 = (BLOCKETTE_1001 *) bs->pb; ohdr->hdrtime = add_time (ohdr->hdrtime, 0, b1001->usec99); ohdr->num_data_frames = b1001->frame_count; } /* If the time correction has not already been added, we should */ /* add it to the begtime. Do NOT change the ACTIVITY flag, since */ /* it refers to the hdrtime, NOT the begtime/endtime. */ ohdr->begtime = ohdr->hdrtime; if ( ohdr->num_ticks_correction != 0 && ((ohdr->activity_flags & ACTIVITY_TIME_CORR_APPLIED) == 0) ) { ohdr->begtime = add_dtime (ohdr->begtime, (double)ohdr->num_ticks_correction * USECS_PER_TICK); } /* Compute endtime. Use precise sample interval in blockette 100. */ /* For client convenience convert it to my_wordorder if not already.*/ if ((bs=find_blockette(ohdr, 100))) { double actual_rate, dusecs; BLOCKETTE_100 *b = (BLOCKETTE_100 *) bs->pb; if (bs->wordorder != my_wordorder) { swab_blockette (bs->type, bs->pb, bs->len); bs->wordorder = my_wordorder; } actual_rate = b->actual_rate; dusecs = ((double)((ohdr->num_samples-1)/actual_rate))*USECS_PER_SEC; ohdr->endtime = add_dtime (ohdr->begtime, dusecs); ohdr->rate_spsec = actual_rate; } else { time_interval2(ohdr->num_samples - 1, ohdr->sample_rate, ohdr->sample_rate_mult, &seconds, &usecs); ohdr->endtime = add_time(ohdr->begtime, seconds, usecs); } /* Attempt to determine blocksize if current setting is 0. */ /* We can detect files of either 512 byte or 4K byte blocks. */ if (ohdr->blksize == 0) { for (i=1; i< 4; i++) { pc = ((char *)(ihdr)) + (i*512); if (pc - (char *)(ihdr) >= maxbytes) break; if ( allnull ( pc,sizeof(SDR_HDR)) ) continue; next_seq = atoi (charncpy (tmp, ((SDR_HDR *)pc)->seq_no, 6) ); if (next_seq == ohdr->seq_no + i) { ohdr->blksize = 512; break; } } /* Can't determine the blocksize. Assume default. */ /* Assume all non-MiniSEED SDR data is in STEIM1 format. */ /* Assume data_wordorder == hdr_wordorder. */ if (ohdr->blksize == 0) ohdr->blksize = (maxbytes >= 1024) ? 4096 : 512; if (ohdr->num_samples > 0 && ohdr->sample_rate != 0) { ohdr->data_type = STEIM1; ohdr->num_data_frames = (ohdr->blksize-ohdr->first_data)/sizeof(FRAME); ohdr->data_wordorder = ohdr->hdr_wordorder; } } /* Fill in num_data_frames, since there may not be a blockette 1001.*/ if (IS_STEIM_COMP(ohdr->data_type) && ohdr->num_samples > 0 && ohdr->sample_rate != 0 && ohdr->num_data_frames < 0) { ohdr->num_data_frames = (ohdr->blksize-ohdr->first_data)/sizeof(FRAME); } return (ohdr); }
int main (int argc, char *argv[]) { FILE *anafp; char in1root[MAXL]; char in2root[MAXL]; char outroot[MAXL]; char imgfile[MAXL]; char program[MAXL], string[MAXL], *ptr; struct dsr hdr; short *img1, *img2, *imgo; int xdim, ydim, zdim, dimension; int img1max = 0, img2max = 0; int img1min = 0, img2min = 0; int swab_img1 = 0, swab_img2 = 0, swab_imgo = 0; char orient, control = '\0'; int nbin = NBIN; int *hist, *mrg1, *mrg2; int histmax = 0; int range1, range2; int binwid1, binwid2; int grid1, grid2; short valmax = 0; float ftmp; int c, i, j, k; /*********/ /* flags */ /*********/ int status = 0; int debug = 0; int do_grid = 1; if (ptr = strrchr (argv[0], '/')) ptr++; else ptr = argv[0]; strcpy (program, ptr); printf ("%s\n", rcsid); /************************/ /* process command line */ /************************/ for (k = 0, i = 1; i < argc; i++) if (*argv[i] == '-') { strcpy (string, argv[i]); ptr = string; while (c = *ptr++) switch (c) { case 'd': debug++; break; case 'g': do_grid = 0; break; case '@': control = *ptr++; *ptr = '\0'; break; case 'r': j = atoi (ptr++); ptr++; /* skip over ":" */ switch (j) { case 1: getrangei (ptr, &img1min, &img1max); break; case 2: getrangei (ptr, &img2min, &img2max); break; default: usage (program); break; } *ptr = '\0'; break; } } else switch (k) { case 0: getroot (argv[i], in1root); k++; break; case 1: getroot (argv[i], in2root); k++; break; case 2: getroot (argv[i], outroot); k++; break; } if (k < 3) usage (program); fprintf (stdout, "img1: %s\nimg2: %s\n", in1root, in2root); sprintf (imgfile, "%s.hdr", in1root); if (!(anafp = fopen (imgfile, "rb")) || fread (&hdr, sizeof (struct dsr), 1, anafp) != 1 || fclose (anafp)) errr (program, imgfile); if (hdr.hk.sizeof_hdr != sizeof (struct dsr)) { printf ("converting %s byte order\n", in1root); swab_hdr (&hdr); swab_img1++; } if (hdr.dime.bitpix != 16) erri (program, imgfile); xdim = hdr.dime.dim[1]; ydim = hdr.dime.dim[2]; zdim = hdr.dime.dim[3]; orient = hdr.hist.orient; dimension = xdim * ydim * zdim; sprintf (imgfile, "%s.hdr", in2root); if (!(anafp = fopen (imgfile, "rb")) || fread (&hdr, sizeof (struct dsr), 1, anafp) != 1 || fclose (anafp)) errr (program, imgfile); if (hdr.hk.sizeof_hdr != sizeof (struct dsr)) { printf ("converting %s byte order\n", in2root); swab_hdr (&hdr); swab_img2++; } if (hdr.dime.bitpix != 16) erri (program, imgfile); if (xdim != hdr.dime.dim[1] || ydim != hdr.dime.dim[2] || zdim != hdr.dime.dim[3] || orient != hdr.hist.orient) { fprintf (stderr, "%s: %s %s dimension/orientation mismatch\n", program, in1root, in2root); exit (-1); } img1 = (short *) malloc (dimension * sizeof (short)); img2 = (short *) malloc (dimension * sizeof (short)); mrg1 = (int *) calloc (nbin, sizeof (int)); mrg2 = (int *) calloc (nbin, sizeof (int)); hist = (int *) calloc (nbin*nbin, sizeof (int)); imgo = (short *) malloc (nbin*nbin * sizeof (short)); if (!img1 || !img2 || !hist || !mrg1 || !mrg2 || !imgo) errm (program); sprintf (imgfile, "%s.img", outroot); startrece (imgfile, argc, argv, rcsid, control); sprintf (imgfile, "%s.img", in1root); catrec (imgfile); printf ("Reading: %s\n", imgfile); if (!(anafp = fopen (imgfile, "rb")) || fread (img1, sizeof (short), dimension, anafp) != dimension || fclose (anafp)) errr (program, imgfile); if (swab_img1) for (i = 0; i < dimension; i++) swab2 ((char *) &img1[i]); sprintf (imgfile, "%s.img", in2root); catrec (imgfile); printf ("Reading: %s\n", imgfile); if (!(anafp = fopen (imgfile, "rb")) || fread (img2, sizeof (short), dimension, anafp) != dimension || fclose (anafp)) errr (program, imgfile); if (swab_img2) for (i = 0; i < dimension; i++) swab2 ((char *) &img2[i]); if (!img1max && !img1min) { img1max -32768; img1min = 32767; for (i = 0; i < dimension; i++) { if (img1[i] > img1max) img1max = img1[i]; if (img1[i] < img1min) img1min = img1[i]; } } else { for (i = 0; i < dimension; i++) { if (img1[i] > img1max) img1[i] = img1max; if (img1[i] < img1min) img1[i] = img1min; } } range1 = img1max - img1min; if (!img2max && !img2min) { img2max -32768; img2min = 32767; for (i = 0; i < dimension; i++) { if (img2[i] > img2max) img2max = img2[i]; if (img2[i] < img2min) img2min = img2[i]; } } else { for (i = 0; i < dimension; i++) { if (img2[i] > img2max) img2[i] = img2max; if (img2[i] < img2min) img2[i] = img2min; } } range2 = img2max - img2min; fprintf (stdout, "img1: min=%6d\tmax=%6d\trange=%6d\n", img1min, img1max, range1); fprintf (stdout, "img2: min=%6d\tmax=%6d\trange=%6d\n", img2min, img2max, range2); sprintf (string, "before auto range adjust\n"); printrec (string); sprintf (string, "img1: min=%6d\tmax=%6d\trange=%6d\n", img1min, img1max, range1); printrec (string); sprintf (string, "img2: min=%6d\tmax=%6d\trange=%6d\n", img2min, img2max, range2); printrec (string); for (i = 0; i < dimension; i++) { k = (nbin * (img1[i] - img1min)) / range1; if (k < nbin && k > 0) mrg1[k]++; k = (nbin * (img2[i] - img2min)) / range2; if (k < nbin && k > 0) mrg2[k]++; } for (k = 2; k < nbin; k++) { mrg1[k] += mrg1[k - 1]; mrg2[k] += mrg2[k - 1]; } if (debug) for (k = 0; k < nbin; k++) { printf ("%6d %10.6f %10.6f\n", k, (float) mrg1[k] / (float) mrg1[nbin - 1], (float) mrg2[k] / (float) mrg2[nbin - 1]); } for (i = 1; i < nbin; i++) if (((float) mrg1[i] / (float) mrg1[nbin - 1]) > CUM_D) break; for (j = 1; j < nbin; j++) if (((float) mrg1[j] / (float) mrg1[nbin - 1]) > 1.0-CUM_D) break; if (debug) printf ("img1: first_bin=%d\tlast_bin=%d\n", i, j); img1min += (float) (range1 * i) / nbin; range1 *= (float) (j - i) / nbin; binwid1 = (float) range1 / nbin; if (!binwid1) binwid1++; range1 = binwid1 * nbin; img1min += binwid1 - (img1min + range1) % binwid1; for (i = 1; i < nbin; i++) if (((float) mrg2[i] / (float) mrg2[nbin - 1]) > CUM_D) break; for (j = 1; j < nbin; j++) if (((float) mrg2[j] / (float) mrg2[nbin - 1]) > 1.0-CUM_D) break; if (debug) printf ("img2: first_bin=%d\tlast_bin=%d\n", i, j); img2min += (float) (range2 * i) / nbin; range2 *= (float) (j - i) / nbin; binwid2 = (float) range2 / nbin; if (!binwid2) binwid2++; range2 = binwid2 * nbin; img2min += binwid2 - (img2min + range2) % binwid2; fprintf (stdout, "img1: min=%6d\tmax=%6d\trange=%6d\tbinwidth=%d\n", img1min, img1min + range1, range1, binwid1); fprintf (stdout, "img2: min=%6d\tmax=%6d\trange=%6d\tbinwidth=%d\n", img2min, img2min + range2, range2, binwid2); sprintf (string, "after auto range adjust\n"); printrec (string); sprintf (string, "img1: min=%6d\tmax=%6d\trange=%6d\tbinwidth=%d\n", img1min, img1min + range1, range1, binwid1); printrec (string); sprintf (string, "img2: min=%6d\tmax=%6d\trange=%6d\tbinwidth=%d\n", img2min, img2min + range2, range2, binwid2); printrec (string); if (!range1 || !range2) exit (-1); for (k = 0; k < dimension; k++) { i = (img1[k] - img1min) / binwid1; j = (img2[k] - img2min) / binwid2; if (i < 0 || i >= nbin || j < 0 || j >= nbin) continue; hist[nbin * j + i]++; if (!hist[nbin * j + i]) { fprintf (stderr, "2Dhist: histogram bin overflow\n"); exit (-1); } if (hist[nbin * j + i] > histmax) histmax = hist[nbin * j + i]; } fprintf (stdout, "maximum bin count=%d\n", histmax); /***************************/ /* write histogram to imgo */ /***************************/ for (k = 0; k < nbin*nbin; k++) { if (hist[k]) { ftmp = 100 * log ((double) hist[k]); imgo[k] = (short) ftmp; } else imgo[k] = 0; if (imgo[k] > valmax) valmax = imgo[k]; } if (do_grid) { grid1 = range1 / 10; grid1 /= 10; grid1 *= 10; for (i = k = 0; i < nbin; k += grid1) { i = (k - img1min) / binwid1; if (i >= 0 && i < nbin) for (j = 0; j < nbin; j++) imgo[nbin * j + i] = valmax / 2; } sprintf (string, "img1: grid interval=%d\n", grid1); printrec (string); grid2 = range2 / 10; grid2 /= 10; grid2 *= 10; for (j = k = 0; j < nbin; k += grid2) { j = (k - img2min) / binwid2; if (j >= 0 && j < nbin) for (i = 0; i < nbin; i++) imgo[nbin * j + i] = valmax / 2; } sprintf (string, "img2: grid interval=%d\n", grid2); printrec (string); } swab_imgo = ((CPU_is_bigendian() != 0) && (control == 'l' || control == 'L')) || ((CPU_is_bigendian() == 0) && (control == 'b' || control == 'B')); if (swab_imgo) for (i = 0; i < nbin*nbin; i++) swab2 ((char *) &imgo[i]); sprintf (imgfile, "%s.img", outroot); fprintf (stdout, "Writing: %s\n", imgfile); if (!(anafp = fopen (imgfile, "wb")) || fwrite (imgo, sizeof (short), nbin*nbin, anafp) != nbin*nbin || fclose (anafp)) errw (program, imgfile); hdr.dime.dim[0] = 2; hdr.dime.dim[1] = nbin; hdr.dime.dim[2] = nbin; hdr.dime.dim[3] = 1; hdr.dime.datatype = 4; hdr.dime.pixdim[1] = 1; hdr.dime.pixdim[2] = 1; hdr.dime.pixdim[3] = 1; hdr.dime.glmax = valmax; hdr.dime.glmin = 0; hdr.hist.orient = 0; if (swab_imgo) swab_hdr (&hdr); sprintf (imgfile, "%s.hdr", outroot); fprintf (stdout, "Writing: %s\n", imgfile); if (!(anafp = fopen (imgfile, "wb")) || fwrite (&hdr, sizeof (struct dsr), 1, anafp) != 1 || fclose (anafp)) errw (program, imgfile); free (img1); free (img2); free (imgo); free (mrg1); free (mrg2); free (hist); endrec (); exit (status); }
int pack_steim1 (SDF *p_sdf, /* ptr to SDR structure. */ int data[], /* unpacked data array. */ int diff[], /* unpacked diff array. */ int ns, /* num_samples. */ int nf, /* total number of data frames. */ int pad, /* flag to specify padding to nf. */ int data_wordorder, /* wordorder of data (NOT USED). */ int *pnframes, /* number of frames actually packed. */ int *pnsamples) /* number of samples actually packed. */ { int points_remaining = ns; int *minbits; /* min bytes for difference. */ int i, j; int mask; int ipt = 0; /* index of initial data to pack. */ int fn = 0; /* index of initial frame to pack. */ int wn = 2; /* index of initial word to pack. */ int itmp; short int stmp; int swapflag; int nb; /* number of minbits to compute. */ int max_samples_per_frame; if (my_wordorder < 0) get_my_wordorder(); swapflag = (my_wordorder != data_wordorder); max_samples_per_frame = 4 * VALS_PER_FRAME; /* steim1 compression. */ nb = max_samples_per_frame * nf; if (nb > points_remaining) nb = points_remaining; minbits = NULL; minbits = (int *)malloc(nb * sizeof(int)); if (minbits == NULL) { fprintf (stderr, "Error: mallocing minbits in pack_steim1\n"); fflush (stderr); if (QLIB2_CLASSIC) exit(1); return (MS_ERROR); } for (i=0; i<nb; i++) MINBITS(diff[i],minbits[i]); p_sdf->f[fn].ctrl = 0; /* Set new X0 value in first frame. */ X0 = data[0]; if (swapflag) swab4((int *)&X0); p_sdf->f[fn].ctrl = (p_sdf->f[fn].ctrl<<2) | STEIM1_SPECIAL_MASK; XN = data[ns-1]; if (swapflag) swab4((int *)&XN); p_sdf->f[fn].ctrl = (p_sdf->f[fn].ctrl<<2) | STEIM1_SPECIAL_MASK; while (points_remaining > 0) { /* Pack the next available data into the most compact form. */ if (BYTEPACK(ipt,points_remaining)) { mask = STEIM1_BYTE_MASK; for (j=0; j<4; j++) p_sdf->f[fn].w[wn].byte[j] = diff[ipt++]; points_remaining -= 4; } else if (HALFPACK(ipt,points_remaining)) { mask = STEIM1_HALFWORD_MASK; for (j=0; j<2; j++) { stmp = diff[ipt++]; if (swapflag) swab2 (&stmp); p_sdf->f[fn].w[wn].hw[j] = stmp; } points_remaining -= 2; } else { mask = STEIM1_FULLWORD_MASK; itmp = diff[ipt++]; if (swapflag) swab4 (&itmp); p_sdf->f[fn].w[wn].fw = itmp; points_remaining -= 1; } /* Append mask for this word to current mask. */ p_sdf->f[fn].ctrl = (p_sdf->f[fn].ctrl<<2) | mask; /* Check for full frame or full block. */ if (++wn >= VALS_PER_FRAME) { if (swapflag) swab4 ((int *)&p_sdf->f[fn].ctrl); /* Reset output index to beginning of frame. */ wn = 0; /* If block is full, output block and reinitialize. */ if (++fn >= nf) break; p_sdf->f[fn].ctrl = 0; } } /* Set new XN value in first frame. */ XN = data[(ns-1)-points_remaining]; if (swapflag) swab4((int *)&XN); /* End of data. Pad current frame and optionally rest of block. */ /* Do not pad and output a completely empty block. */ if (! EMPTY_BLOCK(fn,wn)) { *pnframes = pad_steim_frame(p_sdf,fn,wn,nf,swapflag,pad); } else { *pnframes = 0; } *pnsamples = ns - points_remaining; free ((char *)minbits); return(0); }