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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
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);
}
Beispiel #9
0
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;
    }
}
Beispiel #10
0
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);
}
Beispiel #14
0
Datei: sub.c Projekt: npe9/harvey
/*
 * 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);
}
Beispiel #18
0
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);
}
Beispiel #21
0
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);
}
Beispiel #22
0
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);
}